- .sprite format: single-char palette keys (hex/rgb()/CSS names/none), grid rows, '.' transparent by default, max 256x256 per sprite - render/sheet/info/preview subcommands; sheets name themselves <base>_<cellW>x<cellH>_<cols>x<rows>.<ext> (row-major) - SVG output RLE-merges pixel runs; JPG composites over --bg - go tests for parser, colors, scaling, svg, sheet layout Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmdG9GqfSWCzts7AkDwRDh
87 lines
2.9 KiB
Markdown
87 lines
2.9 KiB
Markdown
# pixel-sprite-maker (`spritec`)
|
|
|
|
Turns human/agent-readable `.sprite` text files into pixel art (**PNG, JPG, SVG**)
|
|
and combines several sprites into **sprite sheets / animation strips**.
|
|
Written in Go, zero dependencies, single static binary.
|
|
|
|
## Build
|
|
|
|
```bash
|
|
# Arch/Garuda: sudo pacman -S go
|
|
cd pixel-sprite-maker
|
|
go build -o build/spritec . # or run the VS Code task "build pixel-sprite-maker"
|
|
go test ./...
|
|
```
|
|
|
|
## The `.sprite` format
|
|
|
|
One file = one sprite. Designed so an agent can *see* the result in the text:
|
|
|
|
```
|
|
# comment lines start with '#'
|
|
sprite: coin # optional name
|
|
palette:
|
|
k = #1A1205 dark outline
|
|
y = #FFD700 gold
|
|
Y = gold CSS names work too — text after the color is a comment
|
|
grid:
|
|
..kkkk..
|
|
.kyyyYk.
|
|
kyyyYYyk
|
|
..kkkk..
|
|
```
|
|
|
|
Rules:
|
|
|
|
- **One character = one pixel.** Every grid row must be the same width.
|
|
- Palette keys are exactly one character (any unicode). `#`, `=`, `:` and
|
|
whitespace are not allowed as keys — so the number of colors is
|
|
practically unlimited (a-z, A-Z, 0-9, `!@%&*`, unicode…).
|
|
- `.` is **transparent by default**; override it in the palette if you want.
|
|
- Colors: `#RGB`, `#RGBA`, `#RRGGBB`, `#RRGGBBAA`, `rgb(r,g,b)`,
|
|
`rgba(r,g,b,a)` (alpha 0-255 or 0.0-1.0), all CSS named colors, `none`.
|
|
- Max **256x256** pixels per sprite. Sheets may exceed this; single frames may not.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
spritec render coin.sprite -o coin.png --scale 8 # png/jpg/svg from extension
|
|
spritec render coin.sprite --format svg # -> coin.svg
|
|
spritec render heart.sprite -o heart.jpg --bg '#222034' # jpg has no alpha: pick bg
|
|
spritec info coin.sprite # validate + palette stats
|
|
spritec preview coin.sprite # draw in the terminal (truecolor)
|
|
|
|
# Sprite sheets / animations — row-major (left→right, then top→bottom):
|
|
spritec sheet walk_1.sprite walk_2.sprite walk_3.sprite walk_4.sprite -o walk # 1 row
|
|
spritec sheet walk_*.sprite --cols 2 -o walkgrid # 2D: 2 columns x 2 rows
|
|
```
|
|
|
|
Flags: `-o` output, `--format png|jpg|svg`, `--scale n` (integer nearest-neighbour
|
|
upscale), `--bg color` + `--quality 1-100` (jpg only), `--cols n` (sheet only).
|
|
|
|
## Sheet output naming — read the layout from the file name
|
|
|
|
```
|
|
<name>_<cellW>x<cellH>_<cols>x<rows>.<ext>
|
|
|
|
walk_8x8_4x1.png = 8x8 px per frame, 4 columns, 1 row (animation strip)
|
|
tiles_16x16_4x2.png = 16x16 px per frame, 4 columns, 2 rows
|
|
```
|
|
|
|
Frame order is always **row-major**: index = `row * cols + col`, frame 0 is
|
|
top-left. If the frame count doesn't fill the grid, trailing cells are
|
|
transparent. In game code:
|
|
|
|
```
|
|
frameX = (index % cols) * cellW
|
|
frameY = (index / cols) * cellH
|
|
```
|
|
|
|
## Exit codes & errors
|
|
|
|
`0` on success, `1` on any error, `2` on missing command. Parse errors name
|
|
the exact line/row/column and what was expected, so an agent can fix the
|
|
file without guessing.
|
|
|
|
Examples live in [`examples/`](examples/); generated output in `examples/out/`.
|