pixelkiln 0.46.0 → 0.47.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 +5 -5
- package/dist/cli.js +14 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +14 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/docs/AGENTS.md +1 -1
- package/docs/ARCHITECTURE.md +21 -10
- package/docs/CHARACTERS.md +309 -0
- package/docs/CLI.md +24 -3
- package/docs/COMFYUI.md +68 -0
- package/docs/ENDPOINTS.md +33 -2
- package/docs/GENERATORS.md +6 -6
- package/docs/GETTING_STARTED.md +25 -1
- package/docs/MANIFEST.md +144 -437
- package/docs/PIXELLAB.md +8 -5
- package/docs/README.md +3 -2
- package/docs/RETRO_DIFFUSION.md +96 -2
- package/docs/SCENARIO.md +46 -0
- package/package.json +1 -1
- package/skills/pixelkiln/SKILL.md +7 -0
- package/skills/pixelkiln/references/pixellab.md +1 -1
package/docs/AGENTS.md
CHANGED
|
@@ -67,7 +67,7 @@ not a replacement:
|
|
|
67
67
|
| PixelLab MCP | Agent-facing access to PixelLab generation capabilities. |
|
|
68
68
|
| PixelKiln skill | Agent guidance for safe project-level operations. |
|
|
69
69
|
| PixelKiln library/CLI | Budgets, state, provenance, review, recovery, audit, and packaging. |
|
|
70
|
-
| PixelLab adapter | The current production and live-tested generation backend. |
|
|
70
|
+
| PixelLab adapter | The current production and live-tested generation backend: stills, tiles, and the character family (four engines, states, loops, mirrors, adoption). |
|
|
71
71
|
| Retro Diffusion adapter | Experimental backend; authenticated paid single-still lifecycle plus mocked advanced-workflow tests. |
|
|
72
72
|
| ComfyUI adapter | Experimental self-hosted still, controlled-revision, and atomic frame-set backend; PixelKiln automates lineage and mechanical quality checks while a person retains visual approval. |
|
|
73
73
|
| Scenario adapter | Experimental hosted still-image backend; BFL Flux 2 Dev quote, paid single/two-output generation, human review, and durable recovery live-tested. |
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -55,19 +55,30 @@ named approval. Planning and doctor inspect the record without changing it.
|
|
|
55
55
|
Pack and mount require current approval and include the record downstream.
|
|
56
56
|
Tiles and provider-native animation remain outside this contract.
|
|
57
57
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
## Dependency graph
|
|
59
|
+
|
|
60
|
+
Four kinds of asset draw from another asset's generated bytes, and all four
|
|
61
|
+
are edges from a child spec to a parent spec in the same style: a
|
|
62
|
+
`revision` (image-to-image or inpaint from a still), a character `state` or
|
|
63
|
+
`animation` (drawn by PixelLab from the character it holds, so the edge is
|
|
64
|
+
to the parent's south-facing file), a `mirror` (a local left-to-right flip
|
|
65
|
+
of the parent's files), and a pro base's `styleCharacter` (the look it
|
|
66
|
+
follows). Manifest loading rejects missing parents, self-references, and
|
|
67
|
+
cycles. Resolution includes transitive parents even when `--only` selects
|
|
68
|
+
just the child, chooses the parent's approved quality output when one
|
|
69
|
+
exists, and hashes the parent's bytes (and a revision's optional mask) into
|
|
70
|
+
the child identity, so a regenerated parent makes its children stale rather
|
|
71
|
+
than silently mismatched.
|
|
65
72
|
|
|
66
73
|
Planning walks the graph from the child and reports `blocked` unless each
|
|
67
74
|
parent is committed source, an intact current download, or a current approved
|
|
68
|
-
quality output. Blocked work is not actionable and has zero planned spend.
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
quality output. Blocked work is not actionable and has zero planned spend. A
|
|
76
|
+
child whose parent is actionable in the same plan is deferred, and `gen`
|
|
77
|
+
runs the plan in waves until nothing new becomes actionable. The submit
|
|
78
|
+
boundary repeats the walk after queue and rate-limit waits, closing the gap
|
|
79
|
+
between a printed plan and provider work. A mirror is the one edge with no
|
|
80
|
+
provider on the far side: submit flips the files itself and records the
|
|
81
|
+
parent's output hashes, and the plan compares those directly.
|
|
71
82
|
|
|
72
83
|
Providers opt into revision modes through `supportsRevision`. The first
|
|
73
84
|
implementation is ComfyUI: it uploads content-addressed inputs, binds only the
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Characters
|
|
2
|
+
|
|
3
|
+
A `character` style holds one PixelLab character as three kinds of asset: a
|
|
4
|
+
base drawn facing 4 or 8 directions, states that apply a pose or an outfit
|
|
5
|
+
to every direction at once, and loops, one direction each. Each is an asset
|
|
6
|
+
with its own lockfile record and files, so `plan` prices the cast, one `gen`
|
|
7
|
+
runs it in waves, and `pack` writes every direction and loop for the engine.
|
|
8
|
+
This page is the reference for the manifest shapes; the [manifest
|
|
9
|
+
reference](./MANIFEST.md) covers the fields every asset shares.
|
|
10
|
+
|
|
11
|
+
## The three shapes
|
|
12
|
+
|
|
13
|
+
A cast in full, with a base, a state, and two loops. This is the robot on
|
|
14
|
+
the [site](https://pixelkiln.griffen.codes/#characters), drawn the way the
|
|
15
|
+
example says:
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"styles": {
|
|
22
|
+
"cast": {
|
|
23
|
+
"generator": "character",
|
|
24
|
+
"outDir": "art/characters",
|
|
25
|
+
"view": "side",
|
|
26
|
+
"size": 96,
|
|
27
|
+
"mode": "pro-flash",
|
|
28
|
+
"template": "custom"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"assets": {
|
|
32
|
+
"bot": {
|
|
33
|
+
"prompt": "small round orange robot with one blue eye, short jointed legs"
|
|
34
|
+
},
|
|
35
|
+
"bot.dented": {
|
|
36
|
+
"prompt": "shell dented and scuffed, one arm hanging loose, eye dim",
|
|
37
|
+
"state": { "of": "bot", "paletteFromReference": true }
|
|
38
|
+
},
|
|
39
|
+
"bot.walk": {
|
|
40
|
+
"prompt": "walking forward in place, short legs stepping, body bobbing slightly",
|
|
41
|
+
"animation": { "of": "bot", "direction": "south", "frames": 12, "fps": 12 }
|
|
42
|
+
},
|
|
43
|
+
"bot.jump": {
|
|
44
|
+
"prompt": "crouching down, springing up into the air with legs tucked, landing with a small bounce",
|
|
45
|
+
"animation": { "of": "bot", "direction": "south", "frames": 8, "fps": 12 }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
The robot is round, so its style names the `custom` skeleton template and
|
|
54
|
+
its loops come from a sentence each on the v3 engine; a biped on the
|
|
55
|
+
`mannequin` template could take a template loop instead
|
|
56
|
+
(`"animation": { "of": "bot", "template": "walk" }`), one generation per
|
|
57
|
+
direction. See [Animations](#animations).
|
|
58
|
+
|
|
59
|
+
### The base
|
|
60
|
+
|
|
61
|
+
A base is a prompt, wrapped in the style's prefix and suffix like any other
|
|
62
|
+
asset, that PixelLab draws facing 4 or 8 directions. `mode` picks the
|
|
63
|
+
engine: `standard` (1 generation, the skeleton template, `outline`,
|
|
64
|
+
`shading`, and `detail` as soft guidance, and `palette` sent as a colour
|
|
65
|
+
reference), `v3` (2 to 9 by size, the highest quality, up to 256px),
|
|
66
|
+
`pro` (20 to 40 by size), or `pro-flash` (6 to 17 by size: PixelLab's
|
|
67
|
+
newest image model draws the south sprite and v3 rotates it; sizes are
|
|
68
|
+
multiples of 4 up to 256, `template` may be `custom`, and a `reference`
|
|
69
|
+
pays for the rotations only, 1 at 64px). `size` is the character's size;
|
|
70
|
+
`view` is `low top-down` (the default), `high top-down`, or `side`;
|
|
71
|
+
`template` picks the body. Each direction lands as
|
|
72
|
+
`<asset>-<direction>.png`, south first.
|
|
73
|
+
Standard mode draws on a canvas 28px larger than `size`, 14px of room on
|
|
74
|
+
each side for animation (a 64px character comes back as 92px files, a
|
|
75
|
+
104px one as 132px); the lock records the size asked for, and the files
|
|
76
|
+
are what PixelLab drew.
|
|
77
|
+
|
|
78
|
+
### Proportions, guidance, and isometric view
|
|
79
|
+
|
|
80
|
+
Three more knobs shape a `standard` base. `proportions` is a preset
|
|
81
|
+
(`chibi`, `heroic`, and so on) or multipliers on the mannequin's head,
|
|
82
|
+
arms, legs, shoulders, and hips; it lives on the style and any base may
|
|
83
|
+
override it, and only the mannequin template has proportions to set.
|
|
84
|
+
`textGuidanceScale` (1 to 20, PixelLab's default 8) is how closely the text
|
|
85
|
+
is followed, and applies to template loops as well. `isometric` draws the
|
|
86
|
+
base and every loop in isometric view. The v3 and pro engines take none of
|
|
87
|
+
the three for a base; a v3 style may still set the last two for its loops.
|
|
88
|
+
A `v3` base takes `enhancePrompt` instead, which has PixelLab expand the
|
|
89
|
+
prompt into a fuller one before drawing.
|
|
90
|
+
|
|
91
|
+
### Starting from your own sprite
|
|
92
|
+
|
|
93
|
+
A base can also start from your own sprite. `reference` names a
|
|
94
|
+
manifest-relative PNG or JPEG of the character facing south, and PixelLab
|
|
95
|
+
draws the other directions from it, with the prompt as guidance:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
"bot": { "prompt": "small round orange robot with one blue eye", "reference": "refs/bot-south.png" }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
That is how the robot above was made the second time: its own south
|
|
102
|
+
sprite handed back to pro-flash, which rotated it for 2 generations at 96px
|
|
103
|
+
and left the south file pixel for pixel as it was.
|
|
104
|
+
|
|
105
|
+
`standard` uses each image as it is, centred on its larger canvas, and
|
|
106
|
+
generates the rest, so the image must be the style's `size` exactly; it
|
|
107
|
+
accepts one image per direction
|
|
108
|
+
(`{ "south": ..., "east": ... }`), and a quadruped template needs south and
|
|
109
|
+
east. `v3` rotates one south image of up to 256px (its `template` must
|
|
110
|
+
match the body in the image). `pro` rotates one south image of up to 168px
|
|
111
|
+
through its `rotate_character` method. The reference's bytes are part of
|
|
112
|
+
the base's identity, so a redrawn file makes the base stale, and the file
|
|
113
|
+
is read again at submit time and refused if it changed since `plan`.
|
|
114
|
+
States, animations, and mirrors take their look from their parent and
|
|
115
|
+
cannot carry a reference.
|
|
116
|
+
|
|
117
|
+
### Concept images and style anchors (pro)
|
|
118
|
+
|
|
119
|
+
The pro engine has two more ways in. `concept` on a base names a concept
|
|
120
|
+
image (a painting, a photo, a sketch, up to 1024px) that seeds the design
|
|
121
|
+
in place of the prompt alone (PixelLab's `create_from_concept`); the
|
|
122
|
+
prompt still guides it. `styleCharacter`, on the style or a base, names a
|
|
123
|
+
generated 8-direction character in the same style whose look the base
|
|
124
|
+
follows (`style_character_id`); its south sprite becomes the style image
|
|
125
|
+
unless a style image is also given. The anchor is a dependency like a
|
|
126
|
+
loop's character: the base is `blocked` until the anchor is downloaded and
|
|
127
|
+
current, `gen` runs it in the wave after the anchor lands, and a
|
|
128
|
+
regenerated anchor makes every base drawn in its style `stale`. The anchor
|
|
129
|
+
itself ignores the setting, so a style can name its own first character.
|
|
130
|
+
PixelLab wants the base at least as large as the anchor's visible sprite
|
|
131
|
+
and fails the job fast otherwise. A base rotating its own `reference`
|
|
132
|
+
takes neither: the rotate method has one image slot and it is the
|
|
133
|
+
character.
|
|
134
|
+
|
|
135
|
+
### Style images (pro and pro-flash)
|
|
136
|
+
|
|
137
|
+
Style images on a `character` style are a pro input: one image of up to
|
|
138
|
+
168px that anchors the look of a `pro` base drawn from text or a concept
|
|
139
|
+
(`create_with_style` and `create_from_concept` both take it), or one of
|
|
140
|
+
up to 256px that a `pro-flash` base copies its look from, no larger than
|
|
141
|
+
the character's `size` on either side (crop it to its subject), with
|
|
142
|
+
`styleTraits` (`palette`, `outline`, `detail`, `shading`, each on by
|
|
143
|
+
default) choosing which traits it lends. `standard` and `v3` have no such
|
|
144
|
+
slot and refuse them; a base with a `reference` refuses them too, in
|
|
145
|
+
either engine.
|
|
146
|
+
|
|
147
|
+
### States
|
|
148
|
+
|
|
149
|
+
A state is a text edit of an existing character, `state.of`, applied to
|
|
150
|
+
every direction at once: a pose, an outfit, a held object. The prompt is
|
|
151
|
+
the edit and goes to PixelLab as written, without the style's prefix and
|
|
152
|
+
suffix, since the character already carries the look.
|
|
153
|
+
`paletteFromReference` snaps the result to the parent's colours; `canvas`
|
|
154
|
+
asks for a larger frame when the edit adds something big. A state costs 20
|
|
155
|
+
to 40 by canvas and keeps the parent's directions. A state may be a state
|
|
156
|
+
of another state.
|
|
157
|
+
|
|
158
|
+
### Animations
|
|
159
|
+
|
|
160
|
+
A template loop moves a skeleton, so it wants a body the skeleton fits: a
|
|
161
|
+
biped on `mannequin`, or one of the quadruped templates. A character that
|
|
162
|
+
is neither (a round robot, a slime) gets a walk from text on the v3
|
|
163
|
+
engine instead; a template on it either fails upstream (`custom`
|
|
164
|
+
template) or redraws the character as the biped it expected.
|
|
165
|
+
|
|
166
|
+
An animation is one loop of one character (`animation.of`, a base or a
|
|
167
|
+
state) in one `direction`. With a `template` (PixelLab's `walk`,
|
|
168
|
+
`breathing-idle`, `running-8-frames`, and so on) it costs 1 and the
|
|
169
|
+
template decides the frame count; without one the prompt is the motion and
|
|
170
|
+
PixelLab's v3 engine draws `frames` frames (4 to 16, even, default 8) for
|
|
171
|
+
`ceil(size² × frames / 65536)` generations, one at 64px. `keepFirstFrame`
|
|
172
|
+
(on by default) stores the resting pose as frame 0, so 8 frames land as 9
|
|
173
|
+
files, `<asset>-frame-00.png` onwards. `fps` is recorded with the frames
|
|
174
|
+
for the gallery, `pack`, and the Godot and Aseprite formats; PixelLab does
|
|
175
|
+
not keep one. An animation lands in review as an ordered set: `pick` shows
|
|
176
|
+
the loop and accepts or rejects it whole. One asset per direction; declare
|
|
177
|
+
another asset for another direction, or a [mirror](#mirrors) of this one
|
|
178
|
+
for the direction that faces the other way.
|
|
179
|
+
|
|
180
|
+
### Pose frames and other loop controls
|
|
181
|
+
|
|
182
|
+
A v3 loop can start and end where you say. `startFrame` is a
|
|
183
|
+
manifest-relative image of the pose to begin from instead of the
|
|
184
|
+
character's rotation; `endFrame` is a pose to reach, and with it the loop
|
|
185
|
+
interpolates from the start frame to that image (both up to 256px, and the
|
|
186
|
+
end frame the same size as the start frame or, without one, as the
|
|
187
|
+
character's rotation, which `plan` checks once the parent is on disk; the
|
|
188
|
+
frames can still come back on a taller canvas when the motion needs it, as
|
|
189
|
+
a 92px crouch did at 92×104). `subject` replaces the character's own description for this loop when it
|
|
190
|
+
would mislead the model (a state that took the armour off), and
|
|
191
|
+
`enhancePrompt` lets PixelLab expand the action into a fuller motion
|
|
192
|
+
description first. A template loop takes none of those; it takes
|
|
193
|
+
`outline`, `shading`, and `detail` overrides instead, over the character's
|
|
194
|
+
own. The style's `palette` goes to every loop as a colour reference, as it
|
|
195
|
+
does to a `standard` base, and `enforcePalette` still snaps the frames
|
|
196
|
+
afterwards. Pose images hash into the loop's identity and are read again
|
|
197
|
+
at submit time, like a base's `reference`.
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
"bot.crouch": {
|
|
201
|
+
"prompt": "folding down onto its legs until it rests on the ground",
|
|
202
|
+
"animation": { "of": "bot", "direction": "south", "frames": 6, "endFrame": "poses/bot-crouched.png" }
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### How the family depends on the base
|
|
207
|
+
|
|
208
|
+
States and animations depend on their parent the way a revision does. The
|
|
209
|
+
parent must be downloaded and current before the child is actionable;
|
|
210
|
+
`plan` reports the child as `blocked` and names the parent until then, and
|
|
211
|
+
one `gen` runs the waves in order: bases, then states, then animations,
|
|
212
|
+
under one budget. The
|
|
213
|
+
child's identity includes the parent's generated south-facing file, so
|
|
214
|
+
regenerating the parent makes every state and animation of it `stale`. A
|
|
215
|
+
hand edit of the parent does not, because PixelLab draws the child from the
|
|
216
|
+
character it holds, not from local bytes.
|
|
217
|
+
|
|
218
|
+
Regenerating an animation clears PixelKiln's own earlier take of that
|
|
219
|
+
direction on the character first, since PixelLab skips a direction that
|
|
220
|
+
already exists. The lock records the animation and group ids PixelLab
|
|
221
|
+
assigned, and the delete goes by those (PixelLab keeps the name PixelKiln
|
|
222
|
+
gives a loop only for text animations, not template ones). Nothing else on
|
|
223
|
+
the character is touched, and a base or state is never deleted by
|
|
224
|
+
PixelKiln.
|
|
225
|
+
|
|
226
|
+
### Palette and packing
|
|
227
|
+
|
|
228
|
+
`enforcePalette` snaps every direction and every frame. `pack --style cast
|
|
229
|
+
--format godot` writes a `SpriteFrames` with each direction of a base or
|
|
230
|
+
state as a still and each animation as a looping set at its fps;
|
|
231
|
+
`--format aseprite` does the same with `frameTags`.
|
|
232
|
+
|
|
233
|
+
### Adopting a character from the account
|
|
234
|
+
|
|
235
|
+
Characters that already exist on the account come under the manifest with
|
|
236
|
+
`adopt`. Declare the asset with `remoteId` (the character id, or
|
|
237
|
+
`<character id>#<animation group id>` for a loop; `get_character` in
|
|
238
|
+
PixelLab's own tools shows both) and run `pixelkiln adopt`: it records the
|
|
239
|
+
character, writes every direction and frame that is not on disk, and costs
|
|
240
|
+
nothing. A base can also be matched by the bytes of its south-facing file.
|
|
241
|
+
See [`adopt`](CLI.md#adopt).
|
|
242
|
+
|
|
243
|
+
## Mirrors
|
|
244
|
+
|
|
245
|
+
Each direction of a loop is its own generation, and a sprite walking east
|
|
246
|
+
is the sprite walking west flipped. A `mirror` asset is that flip, made
|
|
247
|
+
locally from the source asset's downloaded files:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
"bot.walk.west": {
|
|
251
|
+
"prompt": "walking forward in place, short legs stepping, body bobbing slightly",
|
|
252
|
+
"animation": { "of": "bot", "direction": "west", "frames": 12, "fps": 12 }
|
|
253
|
+
},
|
|
254
|
+
"bot.walk.east": { "mirror": "bot.walk.west" }
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
A full 8-direction set of one loop is then 5 generations (south, north,
|
|
258
|
+
west, south-west, north-west) and 3 mirrors; a 4-direction set is 3 and 1.
|
|
259
|
+
The mirror takes its shape from the source (a loop of the same character,
|
|
260
|
+
facing the other way, at the same fps), needs no prompt, and costs
|
|
261
|
+
nothing: `plan` lists it under the provider with a cost of 0 and `gen`
|
|
262
|
+
flips it in the wave after the source lands. It has its own lock entry and
|
|
263
|
+
files (`bot.walk.east-frame-00.png` onwards), so `pack`, the gallery, and
|
|
264
|
+
an engine see an ordinary loop. Nothing is sent to the provider, and the
|
|
265
|
+
account holds no east animation.
|
|
266
|
+
|
|
267
|
+
The lock records a hash over the source's output hashes when the flip was
|
|
268
|
+
made. A source that is regenerated, restored, or re-snapped makes its
|
|
269
|
+
mirrors `stale`, and the next `gen` flips them again for free. A mirror
|
|
270
|
+
whose files went missing is `stale` too; one that was hand-edited is
|
|
271
|
+
`orphaned`, like generated art. A source that is not downloaded, current,
|
|
272
|
+
and untouched blocks its mirrors.
|
|
273
|
+
|
|
274
|
+
A loop facing south or north cannot be mirrored: the flip would be the same
|
|
275
|
+
direction with its asymmetries swapped, not a new one. A single image or a
|
|
276
|
+
frame set from any generator can be mirrored, and so can a base or state
|
|
277
|
+
(every direction flipped and relabelled, so west becomes east). A tile set
|
|
278
|
+
cannot; its edges carry meaning. Mirroring swaps handedness, so a character
|
|
279
|
+
who holds a sword in the right hand holds it in the left when facing the
|
|
280
|
+
mirrored way. Most games accept that; if yours does not, generate both
|
|
281
|
+
sides. `adopt` skips mirrors, since there is nothing upstream to adopt.
|
|
282
|
+
|
|
283
|
+
Engines that flip sprites at draw time (Godot's `flip_h`, Unity's
|
|
284
|
+
`flipX`) do not need mirrored files at all. Declare only the directions
|
|
285
|
+
you generate and flip in the engine; mirrors are for pipelines that want
|
|
286
|
+
every direction on disk.
|
|
287
|
+
|
|
288
|
+
## Working with a cast
|
|
289
|
+
|
|
290
|
+
- `pixelkiln plan` shows a state or loop as `blocked` until its parent is
|
|
291
|
+
downloaded and current, and one `pixelkiln gen` runs the waves in order
|
|
292
|
+
(bases, then states, then loops and mirrors) under one budget; see
|
|
293
|
+
[`gen`](./CLI.md#gen).
|
|
294
|
+
- Loops land in review as ordered sets; `pixelkiln pick` accepts or rejects
|
|
295
|
+
a set whole.
|
|
296
|
+
- Characters that already exist on the account come under the manifest with
|
|
297
|
+
[`adopt`](./CLI.md#adopt), by `remoteId` or by the bytes of a south file.
|
|
298
|
+
- A character edited in PixelLab's own editor comes back with
|
|
299
|
+
[`fetch --refresh`](./CLI.md#fetch), which re-resolves the character's
|
|
300
|
+
current URLs first.
|
|
301
|
+
- `pixelkiln gallery` shows the family: states under their base, loops with
|
|
302
|
+
their direction, mirrors with their source; see
|
|
303
|
+
[`gallery`](./CLI.md#gallery).
|
|
304
|
+
- `pack --format godot` and `--format aseprite` write each direction as a
|
|
305
|
+
still and each loop as a looping set at its fps; see
|
|
306
|
+
[engine formats](./ARTIFACTS.md).
|
|
307
|
+
- Costs per engine are in the [generator table](./GENERATORS.md#character),
|
|
308
|
+
and what the live runs measured is in [Measured
|
|
309
|
+
endpoints](./ENDPOINTS.md#characters-measured).
|
package/docs/CLI.md
CHANGED
|
@@ -17,7 +17,7 @@ work. The experimental `comfyui` adapter runs committed API-format `map` and
|
|
|
17
17
|
ordered still-frame workflows on a self-hosted server. The experimental `scenario` adapter runs
|
|
18
18
|
hosted still models with Compute Unit preflight and durable asset recovery.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Which command:
|
|
21
21
|
|
|
22
22
|
| I want to | Run |
|
|
23
23
|
|---|---|
|
|
@@ -25,6 +25,8 @@ hosted still models with Compute Unit preflight and durable asset recovery.
|
|
|
25
25
|
| generate everything the manifest still needs | `pixelkiln gen --budget 40` |
|
|
26
26
|
| hold every generated file to the style's palette | set `"enforcePalette": true` on the style, then `pixelkiln fetch` |
|
|
27
27
|
| draw a character in 8 directions, then its poses and loops | a `character` style with `state` and `animation` assets; one `pixelkiln gen` runs the waves |
|
|
28
|
+
| rotate your own sprite into 8 directions | `"reference": "refs/bot-south.png"` on the base; `mode: pro-flash` does it for 1 generation at 64px |
|
|
29
|
+
| get the east-facing loop without paying for it | `"bot.walk.east": { "mirror": "bot.walk.west" }` |
|
|
28
30
|
| generate one asset, or one style | `pixelkiln gen --only anvil --budget 2`, `pixelkiln gen --style neon --budget 20` |
|
|
29
31
|
| finish a run that was interrupted | `pixelkiln plan`, then the `next:` command it prints (`poll`, `pick`, or `fetch`) |
|
|
30
32
|
| choose among candidates the provider returned | `pixelkiln pick` |
|
|
@@ -113,8 +115,9 @@ PixelKiln validates the complete budget set before submitting the first group.
|
|
|
113
115
|
|
|
114
116
|
`gen` runs in waves. A wave is the whole lifecycle for everything the plan
|
|
115
117
|
can act on now. Once its downloads land, assets that were `blocked` on a
|
|
116
|
-
parent (a character's states, then their animations
|
|
117
|
-
|
|
118
|
+
parent (a character's states, then their animations and the mirrors of
|
|
119
|
+
those; a pro base drawn in another character's style; a revision of a
|
|
120
|
+
still that was just made) become actionable, and the next wave takes them under
|
|
118
121
|
what is left of the same budget, asking the same "Spend ...?" question each
|
|
119
122
|
time unless `--yes`. It stops when a wave finds nothing new, when a wave
|
|
120
123
|
submits nothing, or when the remaining budget cannot cover the next wave; in
|
|
@@ -416,6 +419,8 @@ pixelkiln gallery --style environment --port 4180 --no-open
|
|
|
416
419
|
pixelkiln gallery --json > generations.json
|
|
417
420
|
```
|
|
418
421
|
|
|
422
|
+
#### What it shows
|
|
423
|
+
|
|
419
424
|
The gallery is lock-first. A lock entry the manifest no longer declares still
|
|
420
425
|
appears, marked `undeclared`, so paid work is never hidden; a declared asset
|
|
421
426
|
with no entry appears as a placeholder so the page also shows what has not
|
|
@@ -431,10 +436,14 @@ provider, and never writes anything. Stop it with Ctrl+C. See the
|
|
|
431
436
|
[Getting started guide](GETTING_STARTED.md#start-a-new-project) for a
|
|
432
437
|
screenshot.
|
|
433
438
|
|
|
439
|
+
#### `--json`: the snapshot as data
|
|
440
|
+
|
|
434
441
|
`--json` prints the same snapshot to stdout without starting a server. It is
|
|
435
442
|
the offline, machine-readable answer to "what has this project generated?" for
|
|
436
443
|
scripts and agents; `--style` and `--only` narrow it the same way.
|
|
437
444
|
|
|
445
|
+
#### `--edit`: change prompts and style fields
|
|
446
|
+
|
|
438
447
|
`--edit` lets the page change *intent*: an asset's prompt (for every style or
|
|
439
448
|
only the one being viewed), width, height, size, category, and tags; a style's
|
|
440
449
|
prompt prefix, prompt suffix, palette, whether downloaded art is snapped to
|
|
@@ -462,6 +471,8 @@ pixelkiln gallery --edit
|
|
|
462
471
|
pixelkiln gallery --edit --workspace pixelkiln.workspace.json
|
|
463
472
|
```
|
|
464
473
|
|
|
474
|
+
#### Restore and regenerate from a record
|
|
475
|
+
|
|
465
476
|
An `orphaned` record, one whose file is gone or changed after download, offers
|
|
466
477
|
**Restore** (the recorded bytes back from the cache or the provider, no cost)
|
|
467
478
|
and, for a changed file, **Regenerate**; both replacements say what they
|
|
@@ -476,6 +487,8 @@ no cost, the page's form of [`restore --generation`](#restore). Any `--budget`
|
|
|
476
487
|
enables it, `0` included, and the current generation moves into the list so
|
|
477
488
|
the restore can be undone.
|
|
478
489
|
|
|
490
|
+
#### `--budget`: generate from the page
|
|
491
|
+
|
|
479
492
|
`--budget <n|provider=n>` enables generation from the page under that session
|
|
480
493
|
ceiling. It is the same `--budget` `gen` takes: one unkeyed amount when a run
|
|
481
494
|
involves a single provider, or one keyed amount per provider for a mixed run,
|
|
@@ -494,6 +507,8 @@ out over the gallery, **Apply selections** writes the lockfile and downloads
|
|
|
494
507
|
the chosen art, and unchosen rows stay in review exactly as with `pick`. A
|
|
495
508
|
regeneration's sheet shows the current art beside the candidates.
|
|
496
509
|
|
|
510
|
+
#### Compare records side by side
|
|
511
|
+
|
|
497
512
|
**Compare** puts two to four records side by side at one shared zoom with
|
|
498
513
|
their fields in rows (provider, generator, candidates, size, cost, prompt,
|
|
499
514
|
dates, quality, hashes) and tints every row whose values differ. Shift-click
|
|
@@ -519,6 +534,8 @@ says how many. PixelLab's count follows the generator and size (`map` and
|
|
|
519
534
|
`pixflux` return one image; a `1dir` style returns 4–64), so the header
|
|
520
535
|
explains that instead of offering a number.
|
|
521
536
|
|
|
537
|
+
#### Hand edits, in your editor or the browser
|
|
538
|
+
|
|
522
539
|
With `--edit`, a record also gains **Edit by hand**, the page's form of
|
|
523
540
|
[`pixelkiln edit`](#edit): it creates the edit file, declares it, and opens
|
|
524
541
|
it in `PIXELKILN_EDITOR` or the OS default. The record then shows the generated
|
|
@@ -556,6 +573,8 @@ on the same file. The editor page runs same-origin under its own
|
|
|
556
573
|
content-security policy and never sees the gallery's session token; the page
|
|
557
574
|
does the write. `--no-editor` hides all of it and serves none of its routes.
|
|
558
575
|
|
|
576
|
+
#### Pull changes made in PixelLab's editor
|
|
577
|
+
|
|
559
578
|
A PixelLab `map` or `1dir` record also links to its account object (**Open in
|
|
560
579
|
pixellab ↗**), where PixelLab's own editor can change it; with `--budget`
|
|
561
580
|
(any amount; `--budget 0` allows provider contact and no spend) the record
|
|
@@ -568,6 +587,8 @@ pixelkiln gallery --edit --budget 80
|
|
|
568
587
|
pixelkiln gallery --budget pixellab=40 --budget retrodiffusion=1.25 --workspace pixelkiln.workspace.json
|
|
569
588
|
```
|
|
570
589
|
|
|
590
|
+
#### `--workspace`: every project in one gallery
|
|
591
|
+
|
|
571
592
|
`--workspace <catalog>` shows every project the catalog registers in one
|
|
572
593
|
gallery, the way `workspace status` reads them: no manifest is needed in the
|
|
573
594
|
current directory, each project gets its own section and filter chip, and a
|
package/docs/COMFYUI.md
CHANGED
|
@@ -619,6 +619,74 @@ PixelKiln refuses missing nodes and inputs during the offline plan. It also
|
|
|
619
619
|
clones the workflow before applying bindings, so one asset cannot mutate the
|
|
620
620
|
next asset's request.
|
|
621
621
|
|
|
622
|
+
## Manifest fields
|
|
623
|
+
|
|
624
|
+
ComfyUI runs a committed API-format workflow on a self-hosted server. The
|
|
625
|
+
workflow file is resolved relative to the manifest and its parsed content is
|
|
626
|
+
part of the spec hash. Adapter success proves transport and output structure,
|
|
627
|
+
not pixel-art quality. Use provider-neutral `pixelkiln refine` for native-grid,
|
|
628
|
+
final-palette, and recorded audit checks. Prompt coverage and human 1× approval
|
|
629
|
+
still require a person.
|
|
630
|
+
|
|
631
|
+
```jsonc
|
|
632
|
+
{
|
|
633
|
+
"name": "my-game",
|
|
634
|
+
"provider": "comfyui",
|
|
635
|
+
"styles": {
|
|
636
|
+
"local": {
|
|
637
|
+
"generator": "map",
|
|
638
|
+
"outDir": "assets/generated/local",
|
|
639
|
+
"seed": 31415,
|
|
640
|
+
"providerOptions": {
|
|
641
|
+
"comfyui": {
|
|
642
|
+
"workflowFile": "workflows/pixel-api.json",
|
|
643
|
+
"outputNodeId": "9",
|
|
644
|
+
"numImages": 4,
|
|
645
|
+
"bindings": {
|
|
646
|
+
"prompt": { "nodeId": "6", "input": "text" },
|
|
647
|
+
"width": { "nodeId": "5", "input": "width" },
|
|
648
|
+
"height": { "nodeId": "5", "input": "height" },
|
|
649
|
+
"batchSize": { "nodeId": "5", "input": "batch_size" },
|
|
650
|
+
"seed": { "nodeId": "3", "input": "seed" },
|
|
651
|
+
"composition": { "nodeId": "19", "input": "image" },
|
|
652
|
+
"controlStrength": { "nodeId": "20", "input": "strength" }
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
"assets": {
|
|
659
|
+
"mountain": {
|
|
660
|
+
"prompt": "a snowbound mountain pass",
|
|
661
|
+
"width": 768,
|
|
662
|
+
"height": 512,
|
|
663
|
+
"providerInputs": {
|
|
664
|
+
"composition": "controls/mountain-layout.png",
|
|
665
|
+
"controlStrength": 0.7
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
Node IDs come from the exported workflow; they are not stable across unrelated
|
|
673
|
+
workflows. Binding names beyond PixelKiln's built-ins are project-defined and
|
|
674
|
+
an asset overrides one with a matching `providerInputs` value. A custom
|
|
675
|
+
binding aimed at `LoadImage.image` or `LoadImageMask.image` treats its string as
|
|
676
|
+
a manifest-relative PNG/JPEG, hashes it, and uploads it at submission. Other
|
|
677
|
+
custom inputs accept a string, number, or boolean matching the workflow's
|
|
678
|
+
placeholder type. Local paths never enter stable provenance.
|
|
679
|
+
|
|
680
|
+
The current adapter supports `map` and ordered still-image `frames`, PNG output
|
|
681
|
+
from one node, 1–16 `map` candidates, and dimensions from 16–4096px. A frame
|
|
682
|
+
style uses `numImages: 1`; the varying input supplies 2–64 renders. It rejects
|
|
683
|
+
manifest `styleImages` and `palette`;
|
|
684
|
+
use custom image bindings for per-asset ControlNet or reference images, and keep
|
|
685
|
+
shared model/LoRA/palette controls inside the workflow. See
|
|
686
|
+
[Set up ComfyUI](COMFYUI.md) for the complete procedure, safe workflow, and
|
|
687
|
+
quality limits. The 4096px adapter ceiling is not a recommended generation or
|
|
688
|
+
native-art size.
|
|
689
|
+
|
|
622
690
|
## Plan, generate, and review
|
|
623
691
|
|
|
624
692
|
```bash
|
package/docs/ENDPOINTS.md
CHANGED
|
@@ -325,8 +325,39 @@ Listed so the gaps are known rather than assumed away:
|
|
|
325
325
|
- the tileset family, with schema documented above and costs unmeasured
|
|
326
326
|
- `create-isometric-tile`, `create-ui-asset`, `generate-font-pro`, all job-based,
|
|
327
327
|
with response shapes not in the simple `{usage, image}` form
|
|
328
|
-
- the character family beyond what the `character` generator uses
|
|
329
|
-
|
|
328
|
+
- the character family beyond what the `character` generator uses: portraits
|
|
329
|
+
(`portrait-character-pro` both ways, `/characters/{id}/portrait`), outfit
|
|
330
|
+
transfer (`transfer-outfit-v2`), lip-sync, skeleton animation, and
|
|
331
|
+
`source_image_id` on Pro Flash. The four creation engines, states, and
|
|
332
|
+
`animate-character` are covered in full; see the September 2026 measurements
|
|
333
|
+
below.
|
|
334
|
+
|
|
335
|
+
## Characters, measured
|
|
336
|
+
|
|
337
|
+
- Standard bases draw on a canvas 28px larger than `image_size` (64 → 92,
|
|
338
|
+
104 → 132). A `directions` reference is placed on it as is, centred, pixel
|
|
339
|
+
for pixel.
|
|
340
|
+
- Pro Flash returns exactly the requested canvas, and refuses a `style_image`
|
|
341
|
+
larger than it ("Style image must fit the native canvas"). Its
|
|
342
|
+
`/pro-flash/cost` answer for `operation=character` was `image` 5 up to 96px,
|
|
343
|
+
6 from 100 to 208px, 9 at 224px and above, plus `rotations` equal to v3's
|
|
344
|
+
`ceil(side² × 8 / 65536)` on the padded square canvas; two live jobs (7 and
|
|
345
|
+
2) billed exactly the estimate. `first_frame` bills the rotations only.
|
|
346
|
+
- A 64px `create-character-state` moved the balance by about 22 against the
|
|
347
|
+
20 to 40 tier documented; other jobs were running on the account, so it is a
|
|
348
|
+
rough number.
|
|
349
|
+
- `animate-character` with `custom_start_frame` and `end_frame` may return
|
|
350
|
+
frames taller than the rotation (92 × 104 for a crouch). `enhance_prompt`
|
|
351
|
+
writes the expanded text into the animation's `animation_type`. A v3 text
|
|
352
|
+
loop on a 96px pro-flash base came back at 108 × 108.
|
|
353
|
+
- Template loops need a skeleton template. On a pro-flash base with
|
|
354
|
+
`template_id: custom` a `walking-8-frames` job failed upstream at once; on
|
|
355
|
+
a round robot fitted to `mannequin` the same template returned a different,
|
|
356
|
+
humanoid character standing nearly still. A v3 text loop ("walking forward
|
|
357
|
+
in place, short legs stepping") kept the robot and walked. For anything
|
|
358
|
+
that is not a biped or one of the four quadrupeds, animate from text.
|
|
359
|
+
- Request validation is strict: an unknown body field is a 422 listing every
|
|
360
|
+
problem at once, which is a free way to check a body's shape.
|
|
330
361
|
|
|
331
362
|
---
|
|
332
363
|
|
package/docs/GENERATORS.md
CHANGED
|
@@ -189,13 +189,13 @@ onwards, with the resting pose as frame 0 unless `keepFirstFrame` is off.
|
|
|
189
189
|
`enforcePalette` snaps all of them. Since each direction of a loop is its
|
|
190
190
|
own generation, declare the east-facing loop as a `mirror` of the west one
|
|
191
191
|
(and each diagonal as a mirror of the other) and PixelKiln flips it locally
|
|
192
|
-
for nothing; see [Mirrors](./
|
|
192
|
+
for nothing; see [Mirrors](./CHARACTERS.md#mirrors). `pack --format godot`
|
|
193
193
|
writes each base direction as a still and each animation as a looping set.
|
|
194
194
|
The gallery
|
|
195
|
-
labels a state or loop with its parent ("state of
|
|
196
|
-
|
|
195
|
+
labels a state or loop with its parent ("state of bot", "loop of
|
|
196
|
+
bot.dented, east"), links parent and children in the record, and counts the
|
|
197
197
|
family in the style header ("3 characters, 4 states, 6 loops"). See
|
|
198
|
-
[Characters](./
|
|
198
|
+
[Characters](./CHARACTERS.md).
|
|
199
199
|
|
|
200
200
|
## Style variants
|
|
201
201
|
|
|
@@ -208,8 +208,8 @@ separate output directory and separate lock keys:
|
|
|
208
208
|
"neon": {
|
|
209
209
|
"generator": "1dir",
|
|
210
210
|
"size": 64,
|
|
211
|
-
"promptPrefix": "
|
|
212
|
-
"promptSuffix": "
|
|
211
|
+
"promptPrefix": "neon-noir game icon",
|
|
212
|
+
"promptSuffix": "magenta/cyan rim light, transparent background",
|
|
213
213
|
"styleImages": [{ "path": "art/style-refs/neon.png" }],
|
|
214
214
|
"outDir": "art/neon"
|
|
215
215
|
}
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -69,7 +69,7 @@ implemented. Authenticated single-candidate RD Fast and RD Plus stills have
|
|
|
69
69
|
passed from quote through validated download, provenance, and cache.
|
|
70
70
|
Multi-candidate, tileset, GIF, and spritesheet live runs remain, so PixelLab
|
|
71
71
|
remains the production adapter. See
|
|
72
|
-
[Manifest reference](
|
|
72
|
+
[Manifest reference](RETRO_DIFFUSION.md#manifest-fields) for
|
|
73
73
|
provider options and current limits, or
|
|
74
74
|
[provider comparison](../PROVIDERS.md) for selection guidance.
|
|
75
75
|
|
|
@@ -260,6 +260,30 @@ Repeated `--style`, `--only`, `--claims`, and `--output-role` flags accumulate;
|
|
|
260
260
|
comma-separated values also work. Unknown flags are errors, so a misspelled
|
|
261
261
|
filter cannot accidentally widen a paid run.
|
|
262
262
|
|
|
263
|
+
## A character and its loops
|
|
264
|
+
|
|
265
|
+
A `character` style holds a base drawn facing 4 or 8 directions, states (a
|
|
266
|
+
pose, an outfit) applied to every direction at once, and loops, one
|
|
267
|
+
direction each. Each is an asset with its own record and files:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"styles": { "cast": { "generator": "character", "outDir": "art/cast", "size": 64, "mode": "pro-flash", "template": "custom" } },
|
|
272
|
+
"assets": {
|
|
273
|
+
"bot": { "prompt": "small round orange robot with one blue eye", "reference": "refs/bot-south.png" },
|
|
274
|
+
"bot.walk.west": { "prompt": "walking forward in place, short legs stepping", "animation": { "of": "bot", "direction": "west", "frames": 12, "fps": 12 } },
|
|
275
|
+
"bot.walk.east": { "mirror": "bot.walk.west" }
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
`pixelkiln plan` prices it (1 generation to rotate the sprite, 1 for the
|
|
281
|
+
loop, 0 for the mirror) and one `pixelkiln gen` runs the waves: the base,
|
|
282
|
+
then the loop, then the flip. `pixelkiln pack --style cast --format godot`
|
|
283
|
+
writes a `SpriteFrames` with every direction as a still and both loops.
|
|
284
|
+
Regenerate the base and everything under it goes `stale`. See
|
|
285
|
+
[Characters](./CHARACTERS.md) and [Mirrors](./CHARACTERS.md#mirrors).
|
|
286
|
+
|
|
263
287
|
## Automation
|
|
264
288
|
|
|
265
289
|
Use machine-readable planning and auditing as build gates:
|