pixelclaw 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/dist/LICENSE +21 -0
- package/dist/THIRD_PARTY_LICENSES.txt +545 -0
- package/dist/pixelclaw.js +666 -0
- package/dist/skill/SKILL.md +255 -0
- package/dist/skill/commands.md +840 -0
- package/dist/skill/manifest.md +64 -0
- package/dist/ui/assets/index-DacOg_uL.css +1 -0
- package/dist/ui/assets/index-DxowuS_Y.js +53 -0
- package/dist/ui/index.html +14 -0
- package/package.json +50 -4
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixelclaw
|
|
3
|
+
description: Make pixel art for a game with PixelClaw, an indexed-colour editor driven by commands through its MCP tools (project, run, seeds, view, check, changes, history, plan, work, review, export, import), while a person watches, edits and asks for work in the browser. Use when asked to draw or fix tiles, sprites, autotile families, maps or a game's whole art set, to plan a set from a theme (manifest and style guide), to review pixel art blind, or to export it to a game.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PixelClaw
|
|
7
|
+
|
|
8
|
+
You draw pixel art by writing commands. Every pixel is a palette entry; every command goes on the
|
|
9
|
+
asset's tape, so a document is its tape replayed and every edit (yours and the person's) can be
|
|
10
|
+
read back. You see your work through `view` (images and exact text grids) and `check` (numbers
|
|
11
|
+
with pixel coordinates). The person watches the same document live, and can draw, leave notes and
|
|
12
|
+
approve work in the dashboard.
|
|
13
|
+
|
|
14
|
+
If the tools are missing, the server is not connected:
|
|
15
|
+
`claude mcp add pixelclaw -- npx pixelclaw serve --project <folder>.pclaw` (then restart Claude Code).
|
|
16
|
+
|
|
17
|
+
## Every session
|
|
18
|
+
|
|
19
|
+
1. `project` (with `path` to open or create a project). Give the person the watch link it prints,
|
|
20
|
+
and the dashboard (`…&tab=dashboard`) when there is a plan.
|
|
21
|
+
2. `changes` at the start of every turn while someone watches, and whenever they say they did
|
|
22
|
+
something. Carry on from their edits; never silently redo their pixels. Close a note you have
|
|
23
|
+
dealt with: `note done <id>`.
|
|
24
|
+
3. `plan` at the start of the session and again after each finished asset: it lists the
|
|
25
|
+
**requests** people made in the dashboard first, then what is left and what is failing.
|
|
26
|
+
4. **Requests before planned work.** `work` claims the next open request and says what is asked
|
|
27
|
+
(draw a planned asset, change a drawn one, or a new asset the person added to the manifest).
|
|
28
|
+
Do it, then `work(action="done", text=<what changed>)`. If you cannot go on without the person
|
|
29
|
+
(a choice only they can make), `work(action="blocked", text=<one clear question>)` and move on;
|
|
30
|
+
their answer opens the request again. Post `work(action="progress", text=…)` on long ones: the
|
|
31
|
+
person sees it on the card.
|
|
32
|
+
|
|
33
|
+
## House rules
|
|
34
|
+
|
|
35
|
+
- **Look, then verify.** After each meaningful batch, look once at an image (`render`, `tile3x3`
|
|
36
|
+
for tiles, `game` for sprites, `map` for families and maps), then use `grid` (or a region of it)
|
|
37
|
+
to confirm exact pixels. Never judge a tile alone when it will be seen tiled; never judge a sprite
|
|
38
|
+
away from its ground.
|
|
39
|
+
- **Small exact shapes as `paint` blocks** (up to about 32x32), outlines and silhouettes from
|
|
40
|
+
primitives, `mirror … live` for symmetric shapes. Count and quote coordinates.
|
|
41
|
+
- **Texture by generators, not by hand:** `noise` (clustered, on a ramp), `scatter`, `voronoi`,
|
|
42
|
+
`bricks`; tiles are `wrap=on` so they tile by construction. Another seed is another variant.
|
|
43
|
+
- **Structure by generators too:** `pebbles ramp=<stone ramp>` (stones with a shadow side and a lit
|
|
44
|
+
pixel) and `tufts ramp=<grass ramp>` (blades) are lit from the style guide's light, never
|
|
45
|
+
overlap, and keep the tile's rows and columns even, so they pass `repetition`, `seam` and
|
|
46
|
+
`jaggies` at 16, 24 and 48 px with their defaults. Lay them over a calm `noise` ground.
|
|
47
|
+
- **Choose seeds by the checks, not by hand:** `seeds(asset, line, count=8)` tries a generator
|
|
48
|
+
line with N seeds as dry runs and ranks them (fewest failing, least over, most room);
|
|
49
|
+
`apply=true` keeps the best. **Try before you keep:** `run(…, dry=true)` applies to a copy,
|
|
50
|
+
checks it, and keeps nothing (a pebble, a walkable flag, a `family cut`).
|
|
51
|
+
- **Helpers apply the style guide exactly:** `outline` (the style guide's ink when you leave out
|
|
52
|
+
`c=`), `shade` (its light when you leave out `light=`), `clean orphans`, pixel-perfect lines,
|
|
53
|
+
`shadow` (an ellipse under a sprite, away from the light, in `style.shadow.c`). On maps, set
|
|
54
|
+
`style.shadow` (`{"c": "darker"}`) and every objects layer casts shadows on the ground (`layer add
|
|
55
|
+
props objects` writes `shadow=darker shadowdir=se`); do not also bake a shadow into those objects.
|
|
56
|
+
- **Keep the checks green, but do not stop at green.** Look at the 3x3 or the game view and judge
|
|
57
|
+
it as a player would. Fix by coordinates from `check`, not by redrawing.
|
|
58
|
+
- **Keep art inside its cell and in one piece:** `margin` fails a sprite touching the top or sides
|
|
59
|
+
of its cell (it stands on the bottom), `pieces` a part floating apart (a lamp room above its
|
|
60
|
+
tower: join it). Colours meant for one thing only (a lantern's glow, a gem) go in
|
|
61
|
+
`style.reserved` (`{"glow": ["lantern"]}`); `palette` then flags them anywhere else.
|
|
62
|
+
- **One light, one outline rule, one level of detail across a set.** The `consistency` check
|
|
63
|
+
compares each asset with its set; a recolour (palette swap) is recognised and not compared with
|
|
64
|
+
its source.
|
|
65
|
+
- **Never fake a pass.** If a check is wrong for an asset, say so and turn it off for that asset in
|
|
66
|
+
the style guide (`style.assets.<name>.checks`) with the reason in style.md; do not draw to
|
|
67
|
+
satisfy a number.
|
|
68
|
+
- Native grid 24 px is fully verifiable; 48 px needs regions and helpers; 96 px needs an underlay
|
|
69
|
+
and region work, with a hand-made 24 px copy beside it.
|
|
70
|
+
|
|
71
|
+
## Per-size defaults
|
|
72
|
+
|
|
73
|
+
Set the project's grid first (`project(grid=48)`, or `pixelclaw new <dir> --grid 48`): the project
|
|
74
|
+
summary's second line says what follows from it.
|
|
75
|
+
|
|
76
|
+
| | 16 px | 24 px (default) | 48 px |
|
|
77
|
+
|---|---|---|---|
|
|
78
|
+
| `new map` without `tile=` | 16 (grid 16) | 24 | 48 |
|
|
79
|
+
| camera (`style.camera` unset) | 256x144 | 384x216 | 768x432 (16x9 cells) |
|
|
80
|
+
| draw scale (`style.drawScale` unset) | 2x | 2x | 1x (the game view shows the scene once) |
|
|
81
|
+
| `noise` specks (no `cluster=`) | 1..3 | 1..3 | 2..6 |
|
|
82
|
+
| tile `jaggies` allowance | 2 | 2 | 8 (per 24x24 px) |
|
|
83
|
+
| `repetition` band widths | 1..4 lines | 1..6 | 1..12, counted in lines of 24 px |
|
|
84
|
+
| map `lattice`: a mark is at least | 2 px | 5 px | 18 px, ±2 px counts as the same spot |
|
|
85
|
+
| icon stroke / centre limits | 1 / 1.5 px | 1.5 / 2.25 px on 24 px icons | 3 / 4.5 px on 48 px icons |
|
|
86
|
+
|
|
87
|
+
At 48 px: look with `view grid region=` (a whole 48x48 grid is long), `render` comes back at 4x
|
|
88
|
+
(192 px) and `tile3x3` at 4x (576 px). Make texture variants by **forking the base and changing
|
|
89
|
+
only its inside** (`fork moor moor_b`, `variant of=moor`, then `noise 4,4 40x40 … base=keep
|
|
90
|
+
wrap=off` and your own marks): two independent noise tiles side by side show a seam where their
|
|
91
|
+
bigger specks are cut at the border. With the structure generators the fork can lay the same
|
|
92
|
+
ground again and only change the generator's seed, keeping its `edges=` (`examples/ember-moor.pclaw`
|
|
93
|
+
uses three looks of noise and `tufts edges=2`, map seam 0.17, lattice 12%).
|
|
94
|
+
Expect more `jaggies` from long curves: a big ellipse is fine alone, but where a second shape meets
|
|
95
|
+
its outline the step runs go uneven; let one shape make the silhouette and shade inside it.
|
|
96
|
+
|
|
97
|
+
## Workflows
|
|
98
|
+
|
|
99
|
+
### A theme → a whole set (the project pipeline)
|
|
100
|
+
|
|
101
|
+
1. **Write the style guide**: `style.md` (palette and ramps, light direction, outline rule,
|
|
102
|
+
dithering, cluster size, sizes, what each material looks like) and the matching settings in
|
|
103
|
+
`project.json` `style` (`palettes`, `outline`, `light`, `ground`, `drawScale`, `sizes`,
|
|
104
|
+
`checks`, `sets`). The palette goes in `palettes/<name>.json` (keys, names, hex, ramps).
|
|
105
|
+
2. **Write the manifest** with `plan(manifest=…)`: the theme paragraph, the sets, and every asset
|
|
106
|
+
with its kind, size, set, a one-line description (what it is meant to read as), and as needed
|
|
107
|
+
scheme, inside/outside and band (families), frames and views (sprites), cells (objects), the
|
|
108
|
+
drawn height in pixels (props and figures: this is what keeps a chest smaller than a person),
|
|
109
|
+
`recolourOf`/`variantOf`, and `flat` (its colour in templates). See manifest.md. The tool
|
|
110
|
+
checks it against its schema and writes nothing if it has problems.
|
|
111
|
+
3. **Flat templates**: `plan(templates=true)` draws a mockup screen and a coverage map per family
|
|
112
|
+
in `templates/`. Show the person the mockup; adjust sizes and sets before drawing.
|
|
113
|
+
4. **Author** each asset. A planned asset's `new` line can leave out its size, palette and scheme
|
|
114
|
+
(`new sprite urn`): the manifest fills them in and the line records them.
|
|
115
|
+
5. **Derive** the families, **compose** sample maps (`view map`), run every check.
|
|
116
|
+
6. **Review**: the blind review below, then `mark reviewed "<what was found and fixed>"` on each
|
|
117
|
+
asset; the person approves in the dashboard (`mark approved`) or asks for changes
|
|
118
|
+
(`mark rejected "…"`: read it with `changes`, fix, review again).
|
|
119
|
+
7. **Export** with the game's profile (`export(profile=…, dest=…)`); `plan` shows `exported`.
|
|
120
|
+
|
|
121
|
+
Statuses are worked out, never set by hand: planned → drafted (exists) → checked (every check
|
|
122
|
+
passes) → reviewed → approved → exported. A change to the art after a mark or an export sends the
|
|
123
|
+
asset back down, and `plan` says why.
|
|
124
|
+
|
|
125
|
+
### Requests from the dashboard
|
|
126
|
+
|
|
127
|
+
People ask for work without talking to you: "Draw this" on a planned card, "Ask for changes" on
|
|
128
|
+
a drawn one (also a `mark rejected "…"` on its tape), "Add an asset" (a new manifest entry). They
|
|
129
|
+
wait in `requests.jsonl`; `plan` lists them first and `work` hands them out one at a time.
|
|
130
|
+
|
|
131
|
+
1. `work` → read what is asked, the asset's plan entry and status, and any answer to an earlier
|
|
132
|
+
question.
|
|
133
|
+
2. Draw or change it as for any asset (the house rules, the checks, a look at the game view).
|
|
134
|
+
For a change, `changes` shows the person's own edits and notes on it.
|
|
135
|
+
3. `work(action="done", text="…")` with what you did in a sentence the person can check against
|
|
136
|
+
the card; or `blocked` with a question. `done` is refused while the asset fails a check: the
|
|
137
|
+
reply lists them; fix them, or block with a question when only the person can decide. Then `plan`, and `work` again until it says there are
|
|
138
|
+
no open requests; then carry on with planned work.
|
|
139
|
+
|
|
140
|
+
A headless worker (`pixelclaw work`, or Start Claude in the dashboard when the project enables
|
|
141
|
+
it) follows the same routine with no one at the keyboard: never ask in chat, ask with `blocked`.
|
|
142
|
+
It has only the PixelClaw tools (no shell, files or web; files outside the project are refused),
|
|
143
|
+
its system prompt ends with every command of the language, and a session that makes no tool call
|
|
144
|
+
for a while is stopped (docs/worker.md).
|
|
145
|
+
|
|
146
|
+
### Importing existing art
|
|
147
|
+
|
|
148
|
+
`import(path=<sheet.png>, slice="24x24", set=…)` cuts a sheet into one asset per non-empty cell
|
|
149
|
+
(names by `pattern`, a `names` list, or `namesFrom="manifest"` for the planned entries of a set);
|
|
150
|
+
a folder imports every PNG and .aseprite in it. New assets get manifest entries and every check
|
|
151
|
+
is run; fix what fails by coordinates like any drafted asset.
|
|
152
|
+
|
|
153
|
+
### A tile
|
|
154
|
+
|
|
155
|
+
`new tile <name> 24x24 bg=<base>` → `seeds` on its `noise`/`scatter` line (apply the best) →
|
|
156
|
+
`view tile3x3` → fix stripes and repeated marks (`check` repetition, seam; one mark on a calm
|
|
157
|
+
tile is fine: the limit rises with the band's spread) → a variant or two by `seeds` from another
|
|
158
|
+
`from=` (`new tile <name>_b …`, `variant of=<name>`) so maps do not weave.
|
|
159
|
+
|
|
160
|
+
A structured ground (shingle, grass with tufts): the calm ground, then `pebbles`/`tufts` (its line
|
|
161
|
+
says `edges=<n>`); each look is a fork of it (`fork shingle shingle_b`, `variant of=shingle`), the
|
|
162
|
+
ground laid again and the same generator with **the same `edges=` and another seed** (rank it with
|
|
163
|
+
`seeds`): every look then has the same stones across its edges and its own inside, so a map can
|
|
164
|
+
`fill mix=` them in any order with no seam and no lattice.
|
|
165
|
+
|
|
166
|
+
### A sprite or prop
|
|
167
|
+
|
|
168
|
+
Silhouette first (`paint` or primitives), then materials in ramp steps, `shade`, `outline`,
|
|
169
|
+
`clean orphans`; `view game` on its ground beside its set; `check` readability (edge contrast,
|
|
170
|
+
distinct silhouette, lightness spread) and consistency. Animation: frames with ticks, `view S
|
|
171
|
+
frames=…`, `view W mirror=E`, `view anim`; the anim check (8-35 % change per frame, no drift).
|
|
172
|
+
|
|
173
|
+
### An autotile family
|
|
174
|
+
|
|
175
|
+
`new family <name> 24x24 scheme=blob47` (or the manifest's), `family texture inside|outside
|
|
176
|
+
from=<tile>`, `family band 3:outside 1:foam 2:sand1 radius=3 jitter=2` (jitter: edges that are not
|
|
177
|
+
ruler-straight; pick its seed with `seeds`), then hand-detail the pieces on the band layer (`paint
|
|
178
|
+
@cell(o) …`); every variant follows. Judge on `view map` (seam ≤ 1, ideally ≤ 0.5) and `view
|
|
179
|
+
family`. The family follows the tiles its textures came `from=`: fix the tile, and the family is
|
|
180
|
+
copied again. Rounder corners: `scheme=blob47-round` (built in; fillets). Cliffs: `scheme=face`, paint
|
|
181
|
+
the faces on the band layer: south faces `@cell(face_o)` (ends), `@cell(face_ew)` (the middle),
|
|
182
|
+
`@cell(face_ie_iw)` (inner corners, where the face meets the terrain beside it); side faces
|
|
183
|
+
`@cell(side_e)`/`@cell(side_e_ns)` on the cell's west half (the terrain's east side) and
|
|
184
|
+
`side_w`/`side_w_ns` on its east half; `@cell(corner_ew)` where a side meets the south face's end.
|
|
185
|
+
Give a long cliff other looks: `family detach face_ew_b` (and `face_ew_c`, `side_e_ns_b`,
|
|
186
|
+
`side_w_ns_b`) and draw them; a map spreads them by cell. Roads and rivers that widen or step
|
|
187
|
+
diagonally: `scheme=lane` (a wide lane has a plain middle; a diagonal step draws a strip to the
|
|
188
|
+
corner). A texture variant that should follow later band fixes:
|
|
189
|
+
`fork <f> <f>_b`, `variant of=<f> band=inherit`, then change only its textures. After a `family
|
|
190
|
+
cut`, heed the seam warning.
|
|
191
|
+
|
|
192
|
+
### A map
|
|
193
|
+
|
|
194
|
+
`new map <name> 40x30 tile=24`, `tiles floor fill <ground tile>` (the floor in one line; `tiles floor fill mix=bed:2,bed_b:1,bed_c:1`
|
|
195
|
+
scatters several looks by weight, the cure for a failing `lattice`), terrain
|
|
196
|
+
layers per family (`walkable=on` when a layer's filled ground is ground objects stand on, not sea;
|
|
197
|
+
terrain that runs off the map has no band along the border unless `border=not`; `mix=meadow:2,clover:1`
|
|
198
|
+
draws the terrain's inside as a scatter of tiles that match its inside texture, a clean border and a
|
|
199
|
+
varied inside),
|
|
200
|
+
`terrain … rect|ellipse|brush`, `place`, `road`, `scatter`; look at it with `view map camera=x,y` (a player's screen); fix
|
|
201
|
+
repetition hot spots with texture variants, and a failing `lattice` (one mark at the same spot of
|
|
202
|
+
most cells, a grid of dots at map scale) with variants that move or leave out the mark; consistency on a map compares the objects standing on
|
|
203
|
+
it.
|
|
204
|
+
|
|
205
|
+
### A mockup underlay, snapped (optional; costs money with a real provider)
|
|
206
|
+
|
|
207
|
+
On a sheet the size of the scene (`new sheet yard 144x96 cell=24x24`):
|
|
208
|
+
`underlay generate "<the theme, the scene, top-down pixel art>" layout=templates/mockup.png`
|
|
209
|
+
(OpenAI, the person's `OPENAI_API_KEY`; about $0.05 an image at the default; a cost cap per call,
|
|
210
|
+
every call in `logs/underlay-costs.jsonl`; ask before spending) or `underlay import <file.png>
|
|
211
|
+
layout=…`. Show the person the underlay; then `snap`. Read its line: block R² ≥ 0.8 and material
|
|
212
|
+
≥ 0.85, else reroll (another prompt) or trace over the underlay by hand instead. Cut tiles from the
|
|
213
|
+
draft (`new tile <t>` then `import 0,0 asset=yard region=<x,y>,24x24 layer=draft`), clean them by
|
|
214
|
+
coordinates (`clean orphans size=2`, then what `check` flags) until every check passes, and hold
|
|
215
|
+
them to the set (`consistency`). Never ship a snapped draft unchecked; small fixes are commands,
|
|
216
|
+
not another generation.
|
|
217
|
+
|
|
218
|
+
### A font
|
|
219
|
+
|
|
220
|
+
`new font <name> 5x7 chars="ABC…"` (or the manifest's), a `glyph <c> << rows >>` per character
|
|
221
|
+
(letters and digits as themselves, others as `U+0021`), `font set line= spacing=`. The `font` check
|
|
222
|
+
holds cap height, x-height, the baseline and advances; the preview's text tab sets it. Export with
|
|
223
|
+
`export(asset, format=strip|bmfont)` or the profile's `fonts`.
|
|
224
|
+
|
|
225
|
+
### Icons
|
|
226
|
+
|
|
227
|
+
`new icon <name> 16x16`, `icon mode=tone|full|channel` (tone: roles, recoloured by the game; full:
|
|
228
|
+
as drawn; channel: pure-RGB masks), then as a small sprite. Plan the icons as one manifest set:
|
|
229
|
+
`consistency` holds them to one stroke weight and box fill, each optically centred.
|
|
230
|
+
|
|
231
|
+
## The blind review hand-off
|
|
232
|
+
|
|
233
|
+
The tool calls no model. You hand its bundle to a fresh agent and bring the findings back:
|
|
234
|
+
|
|
235
|
+
1. `review(set=<set>)` (or `assets=[…]`) writes `reviews/<date>-<set>/`: each asset at game scale
|
|
236
|
+
and enlarged with rulers, tiles 3x3, sprites on their ground, maps, scenes, the palette, the
|
|
237
|
+
style guide, the brief (the theme and what each piece is meant to be) and `rubric.md`. It names
|
|
238
|
+
no author and no method, so the reviewer judges the art alone.
|
|
239
|
+
2. Start a **fresh-context** agent (the Agent tool, no conversation history) with only:
|
|
240
|
+
*"Review the pixel art in <folder> by following rubric.md in it. Report as rubric.md asks."*
|
|
241
|
+
Do not tell it who made the art, how, or what you think of it.
|
|
242
|
+
3. Save its answer as `reviews/<date>-<set>/findings.md`.
|
|
243
|
+
4. Pin each finding on its pixels: `note <x>,<y> [<W>x<H>] "<finding>"` on that asset (scene
|
|
244
|
+
findings by cell, map findings by tile and pixel). Fix them by coordinates and close each note
|
|
245
|
+
(`note done <id>`), or leave it open with a reason the person can read.
|
|
246
|
+
5. `mark reviewed "<n> findings; fixed …; left open …"` on each reviewed asset.
|
|
247
|
+
|
|
248
|
+
## Tools in one line each
|
|
249
|
+
|
|
250
|
+
`project` open/list · `run` a batch (one undo group; any error applies nothing; ends with a check
|
|
251
|
+
summary; `dry=true` keeps nothing) · `seeds` rank a generator line's seeds by the checks · `view` render, grid, diff, tile3x3, game, recolour, anim, map, family, density ·
|
|
252
|
+
`check` the full table with coordinates · `changes` the person's edits and notes · `history` the
|
|
253
|
+
tape · `plan` the manifest and statuses (write a manifest, draw templates) · `review` a blind
|
|
254
|
+
bundle · `export` / `import` through profiles. The command language: commands.md beside this
|
|
255
|
+
file, or `docs/commands.md` in the PixelClaw repo.
|