PAX — pixel art as text

Every pixel is a character. Every tile is readable. Your art lives in plain text files that diff in Git, work with any editor, and fit in an LLM’s context window.

PAXsource format

TOML syntax. Human-readable. Version-controlled. The file you edit and commit.

[pax]
version = "2.1"
name = "dungeon"

[palette.dungeon]
"." = "#00000000"
"#" = "#2a1f3d"
"+" = "#4a3a6d"
"h" = "#8070a8"

[tile.wall]
size = "8x8"
grid = '''
########
#++++++#
#+#++#+#
#++++++#
########
'''
PAX-Lcompact wire format

40% fewer tokens. Same data. What the AI actually sees.

@pax dungeon 2.1 L1
@pal dungeon
  . #00000000  # #2a1f3d
  + #4a3a6d    h #8070a8

@tile wall 8x8[8] e=solid
  ########
  #++++++#
  #+#++#+#
  =2
  ########

=2 means “same as row 2” — duplicate rows compressed automatically

PAX — your art, readable forever

One character, one pixel

Each character in the grid maps to a color in the palette. Open any .pax file in a text editor and you can see the tile — no special tools needed. The format uses TOML, an open standard.

Six ways to encode a tile

Grid
Raw character matrix — one char per pixel
RLE
Run-length encoded rows for larger tiles
Compose
Assemble from reusable stamp blocks
Fill
Repeat a small pattern to fill the tile
Delta
Inherit a base tile + patch specific pixels
Row refs
=N references for duplicate rows

Everything in one file

Palettes, tiles, sprites, animations, color cycling, composite characters, tilemaps, backdrop scenes, WFC rules, atlas config, and style fingerprints. One .pax file is a complete game art package.

Git-native

When you change a tile, the diff shows exactly which pixels moved. No binary conflicts, no merge nightmares. Code review your art the same way you review your code.

same data, fewer tokens

PAX-L — built for LLMs

40% fewer tokens, zero data loss

PAX-L is a compact representation of PAX data designed for LLM context windows. It strips TOML ceremony, compresses duplicate rows, omits defaults, and uses single-line directives. The result: the same tileset in 40% fewer tokens.

2,602
PAX tokens
1,607
PAX-L tokens

Measured on dungeon.pax with cl100k_base tokenizer

Not a file format — a wire format

PAX-L is what the MCP server sends to the AI and what the AI sends back. You never see it — Studio and the CLI convert transparently. Your files on disk stay as readable PAX TOML.

pixl compact dungeon.pax    # PAX → PAX-L (stdout)
pixl expand < input.paxl    # PAX-L → PAX (stdout)

# Round-trips losslessly:
pixl compact f.pax | pixl expand > f2.pax
# f.pax and f2.pax render identically

Smart compression

The converter analyzes your tiles and picks the most token-efficient encoding for each one:

  • Row references — duplicate rows become =N (one token instead of 16 characters)
  • Pattern fill — a 4x4 repeating texture replaces a 16x16 grid (16 pixels instead of 256)
  • Delta encoding — tile variants store only the pixels that differ from the base
  • Auto-stamps (BPE) — repeating 4x4 blocks discovered automatically and named as reusable stamps
  • Default omission — weight=1.0, collision=full for obstacles, single-palette files skip pal= everywhere

The AI reads and writes it

When the AI creates a tile, it writes PAX-L:

@tile moss_floor 16x16[16] e=floor walkable
  @delta stone_floor
  +3,1 g  +4,1 G  +10,1 g  +11,1 G
  +2,2 g  +3,2 G  +4,2 G

Instead of writing 256 pixels, the AI says “start from stone_floor and add moss at these 7 positions.” Fewer decisions, fewer mistakes, better tiles.

Try it now

Create a PAX file, connect the MCP server, and let the AI generate tiles. PAX-L compression happens automatically.