JamChip
Pixel art and chiptune, inside Godot. One dock, a pin rail of editors.
| Tab | What it is |
|---|---|
| Pixel | A sprite editor: layers, frames, onion skin, palette, animation tags, its own undo history. Documents are .jcsprite; exports are PNG, SpriteFrames and Aseprite. |
| Palette | The style’s palettes one row each, a column per slot, edited with a hex field and a wheel. Documents are .jcpalette. |
| SFX | A generator for game sound effects. Documents are .sfx.tres; exports are .wav. |
| Tracker | Songs written on a pattern grid, played by the same synth. Documents are .music.tres; exports are .wav. |
| Font | A pixel font, one glyph per character in one cell. Documents are .font.tres; exports are a PNG atlas with a FontFile beside it. |
| Tiles | A tileset editor: one sheet, tiles with names, collision, data and terrain, and a scratch map to try them on. Documents are .tiles.tres. |
Everything exports to formats Godot already understands, so a shipped game
needs none of this at runtime. Or skip the export: PixelSprite2D,
PixelTileMapLayer and ChiptuneAudioStream hold a document and follow
it as you edit.
Every editor has a pin on the rail: Pixel, Palette, SFX, Tracker, Font and Tiles. Hide the ones you don’t use from the Project pin, the jar at the top of the rail: ≡ ▸ Preferences ▸ Editors.
Tag a sprite’s frames idle, run or hit and each tag becomes a
SpriteFrames animation of that name, so play("run") works the way it
does on any AnimatedSprite2D.
This guide’s on the site too, at jamchip.com/guide.
Install
Copy addons/jamchip/ into your project, then enable JamChip under
Project → Project Settings → Plugins.
Godot 4.7 or newer. Every suite runs on 4.7.2, and that is the oldest version this is tested against. Anything below 4.7 is unsupported: it may load and it is not something to report. Newer 4.x releases are expected to work and are not all tested.
If the project is in git, commit the blobs/ folder beside
project.godot, and the .gdignore inside it. A sprite is a .jcsprite,
a small JSON file you can read and diff, and each of its cels is a PNG in
blobs/. Drawing writes a new PNG and leaves the old one alone, so two
people drawing on the same sprite only conflict on the lines that name its
cels: pick one side, and redo the other’s strokes in the editor. A sprite
downloaded from the web app carries its cels inside it, so it opens in any
project; its first save there puts them in that project’s blobs/. Sounds,
songs and palettes are plain numbers and names and merge as text does. A
.pixel.tres from before still opens; Save As a .jcsprite to move it
over.
Shipping. Export as you would any project: with the plugin enabled,
an export carries the runtime half of each module and leaves the dock, the
command line, the editors, the glyphs, the fonts and the suites behind, with nothing to set
in the preset. The runtime half is runtime, model, paint, format,
palettes and icons from pixel/, runtime, model, synth,
format and icons from chiptune/, and twelve scripts from kit/: what a
game opens, and nothing else from addons/jamchip/. An exported Linux
build runs on every merge to prove it. The exclude_filter a preset would
carry to skip the same files:
addons/jamchip/cli/*, addons/jamchip/dock/*, addons/jamchip/host/*, addons/jamchip/tests/*, addons/jamchip/kit/fonts/*, addons/jamchip/kit/icons/*, addons/jamchip/kit/themes/*, addons/jamchip/kit/tests/*, addons/jamchip/pixel/bar/*, addons/jamchip/pixel/font/*, addons/jamchip/pixel/host/*, addons/jamchip/pixel/lane/*, addons/jamchip/pixel/palette/*, addons/jamchip/pixel/panel/*, addons/jamchip/pixel/rack/*, addons/jamchip/pixel/stage/*, addons/jamchip/pixel/strip/*, addons/jamchip/pixel/tests/*, addons/jamchip/pixel/tiles/*, addons/jamchip/chiptune/host/*, addons/jamchip/chiptune/sfx/*, addons/jamchip/chiptune/tests/*, addons/jamchip/chiptune/tracker/*What is inside
cli/ the command line over palettes and stylesdock/ the dock and the panel behind the pinshost/ what the plugin adds to the editor on its own behalfpixel/ the sprite, font and tileset editors — pixel/README.mdchiptune/ the tracker and the SFX generator — chiptune/README.mdkit/ what both of them need — kit/README.mdtests/ the suites about the plugin as a whole; not in the zipClick a pin to switch editors, or press Ctrl+1 for the first pin, Ctrl+2 for the second and so on. In Godot they work from anywhere in the editor. The keys count the pins you have: hide SFX and Ctrl+3 is the Tracker.
Each editor opens on an untitled document: a Bright sound in SFX, a blank 32×32 in Pixel, and eight by four blank 16×16 tiles in Tiles. You can draw, type or drag straight away; hover the Pixel canvas for the keys.
What you can put in a scene
RUNTIME.md, beside this file, has these classes and what holds in any
game; EXAMPLE-GAME.md walks the example game and meets each of them
where a game uses it. Nothing here needs the dock open, and nothing
needs the plugin enabled at run time; Shipping, under Install, says
what an export carries. Every class below but three
has a job in the example game, examples/game/ in the repository, a
village and four rooms off it: the village has the signs in a
PixelFontFile; every place has its backdrop through
PixelSpriteTexture; the meadow has the sprites, their tags and the
sounds with no position; the cave has the tile data, a
ChiptuneSfxPlayer2D on a bat and a ChiptuneAudioStream on a plain player; the
workshop has machines on ChiptuneSfxPlayer2D heard from the player, a scale
through play_at and the song’s mixer by zone; the castle, the finale,
has the song’s transport. A 3D sound is a ChiptuneAudioStream on Godot’s
own AudioStreamPlayer3D, in examples/cases/chiptune_cases.tscn; PixelPalette and
ChiptuneInstrumentPalette are files the dock reads, and the game
carries what was picked from them inside its documents.
Nodes
| Node | Extends | What it is for |
|---|---|---|
PixelSprite2D |
AnimatedSprite2D |
The front door for artwork. Give it a PixelDocument and it draws it, animates it, and follows the document as you draw. It runs its own clock in the editor. |
PixelTileMapLayer |
TileMapLayer |
The ground of a level. Give it a .tiles.tres and paint with Godot’s tile editor; the tiles’ art, collision, data and terrains follow the tileset as you draw. |
ChiptuneSfxPlayer |
AudioStreamPlayer |
The front door for sound. Give it a .sfx.tres and it plays it. |
ChiptuneSfxPlayer2D |
AudioStreamPlayer2D |
The same, positioned in 2D. For 3D, put a ChiptuneAudioStream on Godot’s own AudioStreamPlayer3D. |
ChiptuneSongPlayer |
AudioStreamPlayer |
The same for music, from the Tracker. Give it a .music.tres and it loops it on the beat, or turn loop off for a one-shot. |
ChiptuneSongPlayer2D |
AudioStreamPlayer2D |
The same music, positioned in 2D. |
Resources you author
| Resource | File | Holds |
|---|---|---|
PixelDocument |
.jcsprite |
A sprite: layers, frames, per-frame timing, a palette, named frame ranges with a loop flag each. |
ChiptuneSfxSpec |
.sfx.tres |
One sound: a waveform, an envelope, the synth’s parameters. |
ChiptuneSong |
.music.tres |
A song: patterns, an arrangement, instruments, and the mix. |
Two more are libraries you build up and reuse. A document keeps its own copy of what it uses, so changing a library later does not reach back.
| Resource | File | Holds |
|---|---|---|
PixelPalette |
.jcpalette |
A named set of colours. GIMP .gpl files import into this. |
ChiptuneInstrumentPalette |
.instruments.tres |
A named set of instruments. |
Resources you attach
For when a node is the wrong shape.
| Resource | Extends | What it is for |
|---|---|---|
PixelSpriteTexture |
ImageTexture |
One frame of a document, kept in step. Anywhere a Texture2D goes. |
PixelSpriteFrames |
SpriteFrames |
Every frame of a document, one animation per tag. |
PixelTileSet |
TileSet |
A tileset document as a TileSet, kept in step. For a TileMapLayer you already have. |
PixelFontFile |
FontVariation |
A font document as a Godot font. Anywhere a Font goes. |
ChiptuneAudioStream |
AudioStreamWAV |
A document rendered as a stream, for any AudioStreamPlayer. |
Put a PixelFontFile in a Label’s Theme Overrides ▸ Fonts ▸ Font, set
its document to your .font.tres, and the label sets its text in that
font. Set the label’s font size to the cell’s height or a
multiple of it: an 8 pixel font at 24 is drawn three times over, pixel for
pixel, and a size in between drops to the multiple under it.
Other Pixel* and Chiptune* classes are machinery and may change shape
without warning.
The project’s style
A style is your game’s palettes, sprite size, grid, sound channels and waves, picked and changed on the Project pin, the jar at the top of the pin rail, Ctrl+0. What a style does, the presets and how to pick one are on jamchip.com/project.
In Godot a style is a .jcstyle in your project, saved where you choose when you press Use on a preset or
New, and a palette it needs is saved beside it. It’s a small JSON file you can read and edit by hand. The
project setting jamchip/style names it, so a team shares it the way it shares project.godot, and an exported
game carries it. No Limits is no file. An older .style.tres still opens, and the first change you make writes
its .jcstyle beside it.
In the inspector, the style your project uses shows Open in JamChip and its sound rows, the music and sound levels among them; its palettes, grid and sizes are changed on the Project pin. Double-clicking its file opens the Project pin too. Any other style file shows all its rows.
Command line
Make and change palettes (.gpl, .hex or .jcpalette, swatches counted from 1), sprites, tilesets, fonts, styles, sounds and songs from a
terminal, an agent or a CI job. From your project’s folder, run the launcher (jamchip.cmd on Windows)
with the command after it; help lists every command:
addons/jamchip/cli/jamchip palette show art/hero.jcpaletteIt finds Godot from GODOT or your PATH, imports a fresh checkout first
and never asks anything. If it says permission denied, run sh addons/jamchip/cli/jamchip ….
CI can run Godot itself: godot --headless --path . --import, then
godot --headless --no-header --path . -s res://addons/jamchip/cli/cli.gd -- COMMAND.
-
palette show,create,edit(set, add, insert, remove, move or--sort hue|brightnessthe swatches),export(to.gpl,.hexor a PNG),convert, anddefault FILE, which is Save palette as project default. -
palette rampmakes a run of colours that look evenly spaced, from one to another or--between 2:7.palette nudgemoves lightness, chroma (how vivid) or hue, or tints toward a colour.palette mutategives new hues to the swatches you don’t--lock, the same for the same--seed. -
palette switch DOC FILE|Nswitches a sprite, tileset or font to one of your style’s palettes and recolours it, as its strip does;--customdrops the link, and a.jcpaletteoutside the style comes in as Custom. To give Custom colours to the style:palette create, thenstyle edit --link, thenpalette switch. -
sprite show DOCprints a sprite’s size, palette, layers, frames, tags, grid and exports.sprite create OUTis File ▸ New, at--sizeor your style’s sprite size, on--palette FILE|Nor the palette new documents open on;--from DOCis Save As.sprite resize DOC --size 32x24is Resize canvas, with--anchor centreor another side, or--scaleto stretch the drawing:addons/jamchip/cli/jamchip sprite create art/hero.jcsprite --size 16x16Wrote art/hero.jcsprite, 16x16, on JamChip. -
sprite cel DOC --dumpprints a cel as swatch numbers,.clear, or with--legendas letters,afor 1.--from-indices FILEwrites one back, and reads a legend first if you give one, likeo=3.--from FILE.png --at X,Ypastes,--to OUT.png --scale 8copies. A colour your palette lacks is refused unless--nearest.--dump --frame 2:5(orall) prints each frame under a line like--- frame 2, with--legendone legend for them all, and a file in that shape writes every frame it names in one run:addons/jamchip/cli/jamchip sprite cel art/spark.jcsprite --from-indices spark.txtWrote layer 1 of art/spark.jcsprite, frames 1, 2, 3. -
sprite paint DOC --layer 1 --frame 1runs the drawing tools:--pencilor--erase 'X,Y;X,Y',--line,--rector--ellipse X,Y:X,Y,--polygon 'X,Y;X,Y;X,Y', the last three with--filled, and--fill X,Ywith--tolerance Nor--everywhere. A filled polygon fills what the lasso selects. An ellipse also takes--thickness N, a ring that many pixels thick, and--arc DEG:DEG, only that part of it, clockwise from the right. Every tool but the eraser takes--color N|HEXand--dither bayer2|bayer4|bayer8[:D]|tile:N|'#./.#';--brush N,--round,--pixel-perfectand--symmetry h|v|both [--axis X,Y]are the bar’s. Each paints only inside the selectionsprite celtakes, below;--select-layer Nmakes it on layer N, kept to what’s drawn there, and--rectwith a colon is still the Rectangle tool.--smoothcurves the pencil’s, eraser’s, polygon’s or lasso’s points:addons/jamchip/cli/jamchip sprite paint art/bat.jcsprite --layer 1 --frame 1 --rect 0,0:7,7 --color 2Wrote layer 1, frame 1 of art/bat.jcsprite. -
sprite cel DOCalso takes the Edit menu’s--clear,--flip h|vand--turn left|right, and--move DX,DY, the select tool’s drag, with--all-layersas the bar’s All layers. Each acts on the whole cel, or on what--rect X,Y,W,H,--lasso 'X,Y;X,Y;X,Y' [--smooth]or--wand X,Y [--tolerance N] [--everywhere]selects, and on a--frame 2:5range too.--pick X,Ynames the colour under a point, or with--compositeas the frame shows it:addons/jamchip/cli/jamchip sprite cel art/witch.jcsprite --frame all --flip h --out art/witch_right.jcspriteWrote layer 1 of art/witch_right.jcsprite, frames 1, 2, 3, 4. -
sprite frames DOCadds, duplicates, moves and removes frames and sets their holds and markers;sprite layers DOCadds, moves, removes, renames, shows, hides, fades and locks layers;sprite tags DOCadds, removes, renames and re-ranges tags and sets how they play. Each runs its options in the order typed:addons/jamchip/cli/jamchip sprite tags art/dust.jcsprite --add puff=1:3 --loops puff=noWrote art/dust.jcsprite.Tags:puff: frames 1 to 3, forward, plays once -
sprite export DOC OUT.pngis File ▸ Export: one--frame, or--sheetfor the sprite sheet and itsSpriteFrames, or--tilesetwith--cell 16x16for a tile sheet and itsTileSet;OUT.asepritewrites an Aseprite file. Each writes what the tab’s Export writes and is kept with the sprite, so a scene showing it follows the drawing.--scale 8makes a bigger PNG to look at instead.sprite import OUT FILEis File ▸ Import: an Aseprite file, a sheet with its.frames.tresbeside it, or any sheet cut on--cell 16x16 --offset X,Y --spacing X,Y:addons/jamchip/cli/jamchip sprite export art/bat.jcsprite art/bat.png --sheetExported art/bat.jcsprite to art/bat.png, with bat.frames.tres beside it holding its 2 frames.art/bat.jcsprite remembers it, so a save from the tab or a command writes it again. -
sprite board OUT.png DOC...lays frames of one sprite or several side by side in one PNG, to look over an animation or set options against each other: every frame, orDOC@2,DOC@2:5,DOC@allor a tag,DOC@fly.--columns Nwraps,--stripsgives each sprite its own row,--gap Nand--scale Nspace and grow it.--tiles TILESET@grass,dirtlays tiles under the cells, in turn along each row, to see sprites on their ground. A board isn’t remembered. -
sprite cel --toandsprite boardtake--viewto draw the piece again beside itself:value, each colour as its brightness in grey;ramps, the same with a line where two colours meet;silhouette, its shape in one colour, or with--per-layera colour a layer;thumb, its true size; andgrid, rulers every 8 pixels and a faint line between them, so a spot you see is a spot--recttakes.--notes FILEprints your list of what the piece has to show beside the answer. With--with-referencethe rough sits under the piece and its thumb, and the views read the drawing alone. Nothing a view draws changes the sprite:addons/jamchip/cli/jamchip sprite cel art/bat.jcsprite --to bat_look.png --scale 8 --view value,silhouette,grid -
sprite lint DOCfinds faults you can measure in each frame as it shows, or one--layer N, each with its pixels:jaggies, a run stepping out of line,orphans, a lone pixel,doubles, a line two pixels thick at a step,banding, two colours running side by side, andcontrast, two touching colours too close in brightness.--onlypicks the rules,--banding-rowsand--contrast-marginset how strict two of them are, and--to OUT.pngdraws the frames with what was found marked. It exits 1 when it finds something, so your own check can run it:addons/jamchip/cli/jamchip sprite lint art/bat.jcsprite --only orphans,doublesFound 1 in art/bat.jcsprite: orphans 1.frame 1 as shown, orphans: no pixel of its colour touches 5,2. -
style list,show,create(from a preset),use,edit, andcheck, which lists each document outside your style and exits 1.style edit FILE --instruments SETmakes a set of instruments your sound palette,--home-key G:majorsets the key new songs start in, and--motif "Bubble=0,0,2;2,2,2;6,4,2,1"adds a tune any song can quote in its own key, each note a row, a step up the scale, a length and an alter;showprints them with the mix, the loudness target and the spaces. -
sfx create OUT --action jump --seed 4is Generate;sfx showprints a sound as text--from-textreads back. -
song create OUTis the Tracker’s New on every channel your style has, where the tab starts on four;--channels Nasks for fewer, and the answer says which it got. A song or sound with its own instruments can live anywhere on disk, a scratch folder for one render; one on your style’s sound palette stays in the project, and the refusal says so.song create OUT --custommakes a new song with its own instruments. -
tiles create OUT --cell 16x16 --cells 8x4is a tileset’s File ▸ New, andtiles show DOCprints its grid, tiles, terrains and scratch.tiles cel DOCissprite celover its sheet, or one--cell X,Y, cells counted from 0,0; a cell drawn on declares its tile.tiles tile DOC TILE, by number or name, takes--name,--solid,--points,--data kind=wall,--undata,--terrain,--peering,--removeand Edit’s--copy flip-hand--wrap-shift, as the Tiles tab does.tiles terrain DOC --add grass=cornerslays a terrain, andtiles grid DOC [--cell WxH] [--offset X,Y]is View ▸ Grid Size and Offset, either one given and the other kept; tiles keep their cells, so one can cover other pixels after. -
tiles export DOC OUT.pngis File ▸ Export, the sheet with a.tileset.tresbeside it carrying each tile’s collision, data and terrain. Over a PNG or a set already there it takes--force, merging into a set with an atlas and replacing one without whole.tiles import OUT FILEis File ▸ Import: an.asepritefile’s tileset, a Godot TileSet’s.tres, or a sheet with--cell 16x16and--offsetor--spacing. -
tiles scratch DOCandtiles layer SCENE.tscnlay tiles on the scratch or aPixelTileMapLayerwith--place 2,0=tree,--fill,--eraseor--from-grid FILE, a character a cell and.empty, and read them back with--dumpor--to OUT.png;tiles layer --create --tiles DOCmakes a new scene:addons/jamchip/cli/jamchip tiles layer rooms/hall.tscn --node Forest --place "6,5=bare soil"Wrote Forest in rooms/hall.tscn, 1728 cells with a tile. -
font create OUT --cell 8x8is a font’s File ▸ New, andfont show DOCprints its cell, guides, glyphs and advances.font edit DOCchanges the characters, the cell and the guides.font glyph DOC CHAR, the character orU+0041, issprite celover one glyph, and--advance Nsets how far the pen moves after it.font export DOC OUT.pngis File ▸ Export as a Font, the atlas with a.fontfile.tresbeside it.font import OUT FILEis File ▸ Import: a sheet with--cell 8x8, or a TTF or OTF. With neither--size Nnor--cell, a face is drawn at the size its pixels land whole at, in a cell that holds it. -
song create OUTis the Tracker tab’s New, or Generate Loop’s song or a jingle from a seed;song showprints a song as text andsong create --from-textwrites it back.song edit,song instruments,song pattern,song orderandsong exportare the tab’s fields, its instruments, the grid, the order and Export WAV.song motif FILE NAME --pattern 1 --channel 1is Add a tune from the style: one of your style’s motifs, by its name or id, written in the song’s own key and scale from--row, on--instrument, and recorded in the song’s quotes;--key Dwrites it as if the song were in D.
run FILE, or run - for standard input, runs a file of commands in one launch of Godot, one a line,
and stops at the first line that’s refused.
Add --json for an answer a script can read. A command exits 0 when it works, 1 when it refuses and 2
when it’s typed wrong, and never writes inside the addon. A palette your style uses keeps its number of
colours, and changing one that sprites, tilesets or fonts use takes --force.
Preferences and themes
The first start asks what you’re here for: art, sound or both. Press Start to see only the editors you picked, or Skip to see them all. Choose editors asks again.
Preferences is a window with a section list down the left; its Theme
page lists the themes: Editor, which is Godot’s own, JamChip, and
one row per theme file, each led by four chips in its own colours. A choice is kept in
user://jamchip/preferences.cfg, per user, and is the same in every
project you open.
To make a theme of your own, press Duplicate on the row closest to what you want, give it a name, and the Theme page turns to editing it: eight swatches named for what they colour, Background, Canvas and lists, Lanes, Selection, Playing, OK, Warning and Danger, each with its key in the file under it. The rest of the theme is worked out from those. Every change is saved as you make it, and the dock follows if the theme is the one in use. A swatch that drops below the contrast floor says so beside itself; the theme stays saved, and the Theme page won’t offer it until it’s fixed. Edit on a theme file’s row reopens it; the Editor and JamChip rows have no Edit. ‹ Themes over the swatches goes back to the list.
The Saving page sets how often unsaved work is copied to the recovery file: every thirty seconds by default, five at the least. Every tab uses it.
The Editors page has a box for each editor. Untick the ones you don’t use and they lose their pin and their key, in every project. Opening one of their files still opens them, until you restart. One box always stays ticked.
A theme is a file: user://jamchip/themes/<name>.cfg, one [roles]
section, one key per role, colours as "#rrggbb". Hover the line under
the themes for the folder’s full path; Show Folder opens it. The
editor writes only its eight keys, so the other roles are yours to set in
a text editor; a role you leave out is filled in from your surface. The
roles:
surface surface_alt surface_raised laneink ink_dim ink_faint borderaccent accent_ink playheadok warning dangeronion_previous onion_nextA theme whose text, borders or status colours do not clear a contrast floor is listed greyed, with what fell short in its tooltip. Fix it with Edit, or in the file and open Preferences again.
If something goes wrong
Email hello@jamchip.com. Say which tab you were in, what you did, what you expected and what happened instead, and add the version from About JamChip on the project page’s ≡.
In Godot, press Ctrl+Shift+P and run JamChip: Copy Diagnostics, then
paste what it copies into the email. It’s a short block: plugin and engine
versions, platform, what the tabs were holding, and the last failures the
plugin recorded. It carries no path from outside your project and nothing
you drew or wrote.
Copy the red lines out of Godot’s Output panel too. Godot catches a script error before the plugin’s own code runs, so it isn’t in the block.
Licence
The code is MIT, copyright Glitter Snack LLC. The full text is
LICENSE, in this folder beside plugin.cfg. Use it in
anything, commercial included, and keep the notice. The two fonts under
kit/fonts/ are under the SIL Open Font License, each with its text
beside it. The JamChip name, the jar and the wordmark are trademarks and
not under the MIT licence; TRADEMARK.md, beside
LICENSE, says what a fork may call itself.
JamChip, by GlitterSnack. MIT licence. Built from the source on every merge. Its artwork and screenshots are made with JamChip.