Docs

The .px format

  • Palette: one line per key: a single character, then #rrggbb, #rrggbbaa, or transparent. . is always transparent and needs no line. Keys can be any printable ASCII except # @ . " \.
  • Grid: rows of palette keys, all the same width. The sprite's size is the grid's size; nothing is declared or counted.
  • Comments: lines starting with #. A comment right above a line is that line's (a key's comment); a file's header is the comments above pxart 1, or separated from its first line by a blank line.
  • Version line (optional): a first line of pxart 1.

Frames and animation

Several grids can live in one file. Name each with @frame. A frame id is a path, and frames that share a parent path form an animation:

pxart 1
@palette dungeon.px
@anim walk/down direction=pingpong ms=125

@frame walk/down/0
..kk..
.kggk.
@frame walk/down/1 ms=250
..kk..
.kgrk.
  • @anim: sets a group's direction (forward, reverse, pingpong, pingpong_reverse, the same words Aseprite uses), repeat and default ms.
  • @frame … ms=: overrides the duration for that frame.
  • pivot=x,y on @frame or @anim (optional; a frame's own wins): the frame's anchor pixel from its top-left, say the feet. anim and onion line frames up by pivot instead of bottom-centre, and export writes it (--aseprite as Aseprite's own slice keys, --frames as pivots.json). anim-set hero.px:walk pivot=8,23 sets it. flip, rotate and transpose move a pivot with its pixel (x -> w-1-x); across an even width a note says that a pivot meant as the point between the two middle pixels ends 1px off it, since pivots are whole pixels.
  • anim-set writes both: anim-set hero.px:walk/down ms=125 direction=pingpong updates (or adds) the @anim line, and anim-set hero.px:walk/down/1 ms=250 sets one frame's ms (or pivot). Only that line changes; ms= with no value clears it.
  • @palette file.px: imports keys from a palette-only file, so a whole sprite set shares one palette. Keys defined locally win. A path inside a file (@palette, a map's legend) is read from that file's directory; a path typed on the command line (--match, --palette, --labels, ...) from the current directory, and an E_FILE says so.
  • @variant night: followed by key lines, defines a recolor, rendered with --variant night. A variant a sprite gets only from its @palette can't know the sprite's own keys and leaves them at their base colors (a white wick at dusk): every command that renders it prints a WARNING naming them, check says so too, and palette wick.px --variant dusk --derive-from base --match pal.px --keep-lit M,m gives the sprite a dusk of its own, fitted to the palette's, with its lights kept lit: the WARNING prints that command, the lights inferred from the file's other variants (a key one leaves at base or brightens: M left at base in night).
  • Slots, f #e0ac69 | #f5cfa0 | #c68642: a key's alternatives, for a game that recolors sprites at runtime. The first is the key's base color, the one every command draws and exports; render/sheet --slots 6 show combinations, and export --indexed keys.json writes the frames as key grids with the palette and its slots. A @variant gives a slot one color or a list, one per slot color. pxart help slots has the rules and the JSON shape.
  • @still ui/life: a frame group that isn't an animation; @still * marks every frame, top-level ids included (a parts file). anim-set ui.px:ui/life --still writes it (--no-still removes it, and a plain ui.px means *); new ui.px:ui/life/0 --still starts a still group.

Any command that takes a file also takes file.px:walk/down (a whole group) or file.px:walk/down/0 (one frame); 'file.px:*' (quoted for the shell) is every frame, as a plain file.px is. Pixel coordinates need you to say which frames they go to, so on a file of several frames set, fill --region, line, rect, poly, ellipse, arc, flood, paste --at, mask --keep and a --region of shift, recolor or shade want one of these, and the E_SELECT lists the frames. An edit that changes several frames names them before wrote (all of them, up to 8): edited 16 frames: walk/down/0, walk/down/1, walk/down/2 and 13 more. A file with one unnamed grid calls it by the file's name (ant.px:ant, as frames lists it); writing a named frame into it (compose -o ant.px:ant) first turns the grid into @frame ant. In zsh write "${F}:walk/down": "$F:walk/down" applies a modifier, and a missing input like hero.pxalk/down is reported as that mistake.

This page is built from README.md in the repository.Edit on GitHub