pixelkiln 0.53.4 → 0.55.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.
@@ -8,6 +8,12 @@ runs it in waves, and `pack` writes every direction and loop for the engine.
8
8
  This page is the reference for the manifest shapes; the [manifest
9
9
  reference](./MANIFEST.md) covers the fields every asset shares.
10
10
 
11
+ A prop, creature, or vehicle with no skeleton to fit — a floating rune, a
12
+ treasure chest, a turret — wants `objectPro` instead: the same base/state/
13
+ animation shapes and `asset.state`/`asset.animation` authoring described
14
+ here, minus everything template/skeleton-specific. See
15
+ [GENERATORS.md](./GENERATORS.md#objectpro).
16
+
11
17
  ## The three shapes
12
18
 
13
19
  A cast in full, with a base, a state, and two loops. This is the robot on
package/docs/ENDPOINTS.md CHANGED
@@ -237,6 +237,49 @@ Given that `color_image` is honoured on `pixflux` but silently ignored on
237
237
  `resize`, **verify the palette actually holds on a single tileset before
238
238
  committing to a set**.
239
239
 
240
+ ## Standalone isometric tile: schema documented, cost measured once
241
+
242
+ `POST /create-isometric-tile` (+ `GET`/`DELETE /isometric-tiles/{tile_id}`) is
243
+ a *third*, separate path to isometric content, distinct from both
244
+ `create-tiles-pro`'s `tile_type: "isometric"` (a full Wang/connectable set)
245
+ and the tileset family above (confirmed square-only, no isometric option at
246
+ all). This one generates a single standalone tile — no candidates, no
247
+ connectable set — and is wrapped by pixelkiln's `isometricTile` generator
248
+ (docs/GENERATORS.md).
249
+
250
+ `isometric_tile_shape` (`"thin tile"` ~15% canvas height, `"thick tile"`
251
+ ~25%, `"block"` ~50%, the default) is a direct thickness/elevation control,
252
+ more granular than anything in `tiles`/`terrain`. `isometric_tile_size` (16
253
+ or 32, default 16) is the API's own tile grid, a separate concept from
254
+ `image_size` (the generation canvas, 16-64px each side; the endpoint's own
255
+ description states "sizes above 24x24 often produce better quality
256
+ results"). `outline` defaults to `"lineless"` here specifically — unlike
257
+ `create-tiles-pro`'s `"outline"` default — with its own three-value enum
258
+ (`"single color outline"`, `"selective outline"`, `"lineless"`); `shading`
259
+ and `detail` reuse the same enums as the tileset family above.
260
+
261
+ `GET /isometric-tiles/{tile_id}` carries no `status` field either: it answers
262
+ **423 while still processing** and 200 with the image once done, matching the
263
+ tileset family's own polling contract. Unlike every other job resource here,
264
+ its response shape is `{ image: Base64Image, usage }` — the finished tile
265
+ comes back embedded as base64, not a `storage_urls` link.
266
+
267
+ **Its own OpenAPI response schema example is misleading on cost.** It shows
268
+ `{ type: "usd", usd: 0.02 }`, which reads as billing in real dollars rather
269
+ than subscription generations, unlike everything else in this file. A real
270
+ call against a live subscription account (Tier 2, "generations" balance)
271
+ billed exactly `{ type: "generations", generations: 1 }` instead — the
272
+ documented shape never actually appeared. Measured at one size/shape
273
+ combination only (32px canvas, `"block"`); the endpoint's own docs give no
274
+ size-tiering formula the way `1dir`/`tiles` do, so pixelkiln's
275
+ `isometricTileCost()` assumes flat 1-generation pricing across the whole
276
+ 16-64px range rather than guessing a tier.
277
+
278
+ `init_image`/`init_image_strength` (image-to-image) and `color_image`
279
+ (native forced-palette) both exist on this endpoint and are not modeled by
280
+ pixelkiln yet — no `style_images` concept exists here at all, unlike
281
+ `create-tiles-pro`.
282
+
240
283
  ---
241
284
 
242
285
  ## Recipes
@@ -402,8 +445,10 @@ Listed so the gaps are known rather than assumed away:
402
445
  - `image-to-pixelart-pro` takes only `image` + `description`, no size fields.
403
446
  The non-Pro version is characterised above.
404
447
  - the tileset family, with schema documented above and costs unmeasured
405
- - `create-isometric-tile`, `create-ui-asset`, `generate-font-pro`, all job-based,
406
- with response shapes not in the simple `{usage, image}` form
448
+ (the standalone isometric tile endpoint alongside it now has one real
449
+ measured data point — see above)
450
+ - `create-ui-asset`, `generate-font-pro`, both job-based, with response
451
+ shapes not in the simple `{usage, image}` form
407
452
  - the character family beyond what the `character` generator uses: portraits
408
453
  (`portrait-character-pro` both ways, `/characters/{id}/portrait`), outfit
409
454
  transfer (`transfer-outfit-v2`), lip-sync, skeleton animation, and
@@ -12,6 +12,7 @@ account; [ENDPOINTS.md](./ENDPOINTS.md) contains the detailed experiments.
12
12
  | Exact fixed palette | `pixflux` | 1 generation | 1 inline image |
13
13
  | Candidate variety, richer rendering, future rotation/animation | `1dir` | 20–40 generations | 4–64 by size |
14
14
  | Ground tiles or connectable structural sets | `tiles` | 20–40 generations | variations or complete set |
15
+ | A single elevation tile — a raised mesa, a cliff block | `isometricTile` | 1 generation | 1 |
15
16
  | Controlled pose/expression sequence in ComfyUI | `frames` | 0 `free` provider units | one atomic ordered set |
16
17
  | A character facing 4 or 8 directions, its poses, and its animations | `character` | 1 per base (standard), 20–40 per pose, 1 per template loop | one set of directions, or one ordered loop |
17
18
 
@@ -201,6 +202,94 @@ bot.dented, east"), links parent and children in the record, and counts the
201
202
  family in the style header ("3 characters, 4 states, 6 loops"). See
202
203
  [Characters](./CHARACTERS.md).
203
204
 
205
+ ## `objectPro`
206
+
207
+ `objectPro` wraps PixelLab's `/create-object-pro-flash` — the same base
208
+ → state → animation family as `character`, for PixelLab's separate,
209
+ skeleton-free "object" entity. Use it for a prop, creature, or vehicle that
210
+ needs a pose (`state`) or a directional loop (`animation`) but has no
211
+ humanoid/quadruped rig to fit: a floating rune, a treasure chest, a turret,
212
+ anything `character`'s template concept does not describe.
213
+
214
+ It reuses `character`'s own authoring shapes — `asset.state`/`asset.animation`
215
+ are the identical fields, and a `mirror` flips an animation's direction the
216
+ same way. Everything `character`'s templates/proportions/skeleton bring is
217
+ simply absent: no `mode`, `template`, `proportions`, `isometric`, `concept`,
218
+ or `styleCharacter` — `/create-object-pro-flash` is the only base-creation
219
+ path, and setting `animation.template`/`subject`/`outline`/`shading`/`detail`
220
+ on an `objectPro` animation is rejected at resolve time rather than silently
221
+ ignored, since none of them reach the API for an object.
222
+
223
+ - `objectDirections` (1 or 8, default 8, style-level) is the rotation count —
224
+ a real choice `character` does not offer (character pro-flash is always 8).
225
+ A 1-direction object's `animation.direction` must be `south`; anything else
226
+ is rejected, since the endpoint 400s if `directions` is even sent for a
227
+ 1-direction object.
228
+ - `reference` (asset-level, base only) rotates the author's own south-facing
229
+ sprite instead of drawing from the prompt, same as `character`'s reference
230
+ — but only ever reads the south image, since one frame is all
231
+ `/create-object-pro-flash` takes.
232
+ - A style image anchors the look the same way `character` pro-flash's does,
233
+ including `styleTraits` (which of the image's palette/outline/detail/shading
234
+ to carry over).
235
+ - Regenerating an already-animated direction is simpler than `character`'s:
236
+ the object endpoint has its own `replace_existing` flag, so PixelKiln
237
+ always passes it rather than fetching the object first to find and delete
238
+ a prior take (`character`'s own workaround for not having one).
239
+
240
+ **Cost is not independently measured.** `objectProCost()` assumes
241
+ `/create-object-pro-flash`/its state/its animation price identically to
242
+ `character`'s own measured pro-flash formula (`proFlashCharacterCost`),
243
+ since the request bodies are near-identical minus `template_id` — treat it
244
+ as a working assumption, not a confirmed number, until checked against a
245
+ live account.
246
+
247
+ Adoption (`pixelkiln adopt`) has not been extended for `objectPro`'s own
248
+ `<object id>#<animation group id>` remote-id scheme yet, unlike `character`'s
249
+ dedicated adoption path — a base may already be adoptable through the
250
+ generic object-matching pixelkiln already does for `1dir`/`map`, since a
251
+ pro-flash object shares that same `/objects` identity space, but this is
252
+ untested.
253
+
254
+ ## `isometricTile`
255
+
256
+ `isometricTile` wraps PixelLab's `/create-isometric-tile` — a different
257
+ endpoint from both `tiles` (which also has its own `isometric` `tileType`
258
+ for full connectable Wang/road/building sets) and `terrain` (`/create-tileset`,
259
+ confirmed square-only, no isometric option at all). This one generates a
260
+ single standalone isometric tile, no candidates, no connectable set.
261
+
262
+ Use it when a per-tile height/elevation primitive is what's needed — a raised
263
+ mesa, a cliff block, a standalone rock outcrop — rather than a connected
264
+ ground set.
265
+
266
+ - `isometricTileShape` controls vertical thickness: `"thin tile"` (~15% of
267
+ canvas height), `"thick tile"` (~25%), or `"block"` (~50%, the API
268
+ default). This is a more direct elevation control than anything in `tiles`
269
+ or `terrain`.
270
+ - `isometricTileSize` is the API's own tile grid size, 16 or 32 (default 16)
271
+ — a separate concept from `size`, the generation canvas (16–64px; the
272
+ endpoint's own guidance is that sizes above 24px "often produce better
273
+ quality results").
274
+ - `outline` defaults to `"lineless"` on this endpoint specifically, unlike
275
+ `tiles-pro`'s `"outline"` default — its own valid values are `"single
276
+ color outline"`, `"selective outline"`, or `"lineless"`.
277
+
278
+ **Cost: 1 generation flat, measured.** PixelLab's own OpenAPI response schema
279
+ example shows `{ type: "usd", usd: 0.02 }`, which reads as billing in real
280
+ dollars — but a real call against a live subscription account billed exactly
281
+ 1 generation instead (`usage: { type: "generations", generations: 1 }`), and
282
+ `costUnit` here is `"generations"` like every other generator. Only one
283
+ size/tile-shape combination (32px canvas, `"block"`) has actually been
284
+ measured; the endpoint's own docs give no size-tiering formula the way
285
+ `1dir`/`tiles` do, so this assumes flat pricing across the 16–64px range
286
+ rather than guessing a tier.
287
+
288
+ Style images, `init_image`/`init_image_strength` (image-to-image), and
289
+ `color_image` (native forced-palette) are not modeled yet — PixelKiln's own
290
+ `palette`/`enforcePalette` post-processing works generically on the
291
+ downloaded tile regardless, if a closed palette is what's actually needed.
292
+
204
293
  ## Style variants
205
294
 
206
295
  Styles are namespaces. Add another style to re-derive the same asset ids into a
package/docs/MANIFEST.md CHANGED
@@ -113,7 +113,7 @@ One asset using the fields most projects reach for:
113
113
  |---|---|---|
114
114
  | `extends` | style id | Optional parent style. The child inherits resolved settings but must declare its own `outDir`. |
115
115
  | `provider` | top-level default | Provider registry id for this style. Assets cannot override it. |
116
- | `generator` | `map` | `map`, `1dir`, `pixflux`, `tiles`, `character`, or provider-specific `animation`/`frames`. |
116
+ | `generator` | `map` | `map`, `1dir`, `pixflux`, `tiles`, `terrain`, `isometricTile`, `imagePro`, `character`, `objectPro`, or provider-specific `animation`/`frames`. See [GENERATORS.md](./GENERATORS.md). |
117
117
  | `outDir` | string, required | Output directory relative to the manifest. |
118
118
  | `promptPrefix` | `""` | Prepended to every participating asset prompt. |
119
119
  | `promptSuffix` | `""` | Appended to every participating asset prompt. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelkiln",
3
- "version": "0.53.4",
3
+ "version": "0.55.0",
4
4
  "description": "Manifest-driven pixel-art generation, review, recovery, and packaging with deterministic provenance.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -42,7 +42,9 @@
42
42
  "frames",
43
43
  "character",
44
44
  "terrain",
45
- "imagePro"
45
+ "imagePro",
46
+ "isometricTile",
47
+ "objectPro"
46
48
  ],
47
49
  "default": "map"
48
50
  },
@@ -236,6 +238,28 @@
236
238
  "high top-down"
237
239
  ]
238
240
  },
241
+ "isometricTileSize": {
242
+ "type": "number",
243
+ "enum": [
244
+ 16,
245
+ 32
246
+ ]
247
+ },
248
+ "isometricTileShape": {
249
+ "type": "string",
250
+ "enum": [
251
+ "thin tile",
252
+ "thick tile",
253
+ "block"
254
+ ]
255
+ },
256
+ "objectDirections": {
257
+ "type": "number",
258
+ "enum": [
259
+ 1,
260
+ 8
261
+ ]
262
+ },
239
263
  "noBackground": {
240
264
  "type": "boolean",
241
265
  "default": true
@@ -469,7 +493,9 @@
469
493
  "frames",
470
494
  "character",
471
495
  "terrain",
472
- "imagePro"
496
+ "imagePro",
497
+ "isometricTile",
498
+ "objectPro"
473
499
  ],
474
500
  "default": "map"
475
501
  },
@@ -663,6 +689,28 @@
663
689
  "high top-down"
664
690
  ]
665
691
  },
692
+ "isometricTileSize": {
693
+ "type": "number",
694
+ "enum": [
695
+ 16,
696
+ 32
697
+ ]
698
+ },
699
+ "isometricTileShape": {
700
+ "type": "string",
701
+ "enum": [
702
+ "thin tile",
703
+ "thick tile",
704
+ "block"
705
+ ]
706
+ },
707
+ "objectDirections": {
708
+ "type": "number",
709
+ "enum": [
710
+ 1,
711
+ 8
712
+ ]
713
+ },
666
714
  "noBackground": {
667
715
  "type": "boolean",
668
716
  "default": true
@@ -117,7 +117,9 @@
117
117
  "frames",
118
118
  "character",
119
119
  "terrain",
120
- "imagePro"
120
+ "imagePro",
121
+ "isometricTile",
122
+ "objectPro"
121
123
  ],
122
124
  "default": "map"
123
125
  },
@@ -311,6 +313,28 @@
311
313
  "high top-down"
312
314
  ]
313
315
  },
316
+ "isometricTileSize": {
317
+ "type": "number",
318
+ "enum": [
319
+ 16,
320
+ 32
321
+ ]
322
+ },
323
+ "isometricTileShape": {
324
+ "type": "string",
325
+ "enum": [
326
+ "thin tile",
327
+ "thick tile",
328
+ "block"
329
+ ]
330
+ },
331
+ "objectDirections": {
332
+ "type": "number",
333
+ "enum": [
334
+ 1,
335
+ 8
336
+ ]
337
+ },
314
338
  "noBackground": {
315
339
  "type": "boolean",
316
340
  "default": true
@@ -54,6 +54,39 @@ which tutorial(s) demonstrated real (not hypothetical) demand for it.
54
54
  `pixellab.md`. Reference images and a style image
55
55
  (`reference_images`/`style_image`) remain unmodeled, and the completed
56
56
  job's response shape has not itself been exercised live yet.
57
+ - **A standalone single isometric tile** (`/create-isometric-tile`, a third,
58
+ separate path to isometric content distinct from both `tiles`'
59
+ `tileType: "isometric"` and `terrain`'s `/create-tileset`, which is
60
+ confirmed square-only with no isometric option at all) — a real gap: no
61
+ per-tile elevation primitive existed for a raised mesa or a cliff block
62
+ outside a connected ground set. Found via direct API/schema investigation,
63
+ not a tutorial (real downstream demand: a Godot game's terrain-verticality
64
+ work). Closed by the `isometricTile` generator; see `pixellab.md`. Its
65
+ `isometricTileShape` (thin/thick/block) is a direct thickness control
66
+ `tiles`/`terrain` do not have. **Cost measured once, and it corrected a
67
+ wrong assumption**: the endpoint's own OpenAPI response schema example is
68
+ `{ type: "usd", usd: 0.02 }`, which reads as real-dollar billing, but a
69
+ live call against a subscription account billed exactly 1 generation
70
+ instead — `costUnit` is `"generations"` here, not `"usd"`. Only one
71
+ size/shape combination (32px, `"block"`) has actually been measured; no
72
+ size-tiering formula is documented the way `1dir`/`tiles` have one. Style
73
+ images, `init_image`/`init_image_strength`, and `color_image` remain
74
+ unmodeled.
75
+ - **Object Creator's rotation/state/animation family** (`/create-object-pro-flash`,
76
+ a skeleton-free entity distinct from both `character` and the generic
77
+ `/objects` polling resource `1dir`/`map` already use) — demonstrated in
78
+ "Object Creator" and used throughout "GBA-Style Sprites" and "Build a Game
79
+ with AI"; `map` (one generation, no direction/state concept) and `1dir`
80
+ (one direction only) were the closest analogs, and neither modeled
81
+ rotation, states, or animation for a plain object. Closed by the
82
+ `objectPro` generator; see `pixellab.md`. It reuses `character`'s own
83
+ `asset.state`/`asset.animation` authoring shapes and mirror handling
84
+ rather than inventing parallel ones. **Cost is not independently
85
+ measured**: assumed identical to `character` pro-flash's own measured
86
+ formula, since the request bodies are near-identical minus `template_id` —
87
+ a real assumption pending a live check, not a confirmed number the way
88
+ `isometricTile`'s now is. Batch "pack" generation (N distinct objects from
89
+ one call) remains unmodeled — see above.
57
90
 
58
91
  ## Generic (non-character) animation and interpolation
59
92
 
@@ -69,17 +102,13 @@ PixelLab"). Pixelkiln's only interpolation concept is the `character` v3
69
102
  loop's `startFrame`/`endFrame`, scoped strictly inside a `character` asset —
70
103
  there is no way to animate a `map`, `pixflux`, or `tiles` output at all.
71
104
 
72
- ## Object Creator
73
-
74
- Generic 8-direction object rotation, object "states" (prompted variations of
75
- an existing object), object animation (with a pro-vs-V3 model choice), and
76
- batch "pack" generation (one prompt or style reference → N distinct objects,
77
- each with an optional per-item text override) — all scoped to a standalone
78
- object, not a `character`. Demonstrated in "Object Creator" and used
79
- throughout "GBA-Style Sprites" and "Build a Game with AI." Pixelkiln's
80
- closest generator is `map` (single prop, one generation, no direction or
81
- state concept at all) and `1dir` (implies one direction). Neither models
82
- rotation, states, or animation for a plain object.
105
+ ## Object Creator: batch generation only
106
+
107
+ Object Creator's "pack" generation — one prompt or style reference → N
108
+ distinct objects in one call, each with an optional per-item text override —
109
+ remains unmodeled. Demonstrated in "Object Creator" and used throughout
110
+ "GBA-Style Sprites" and "Build a Game with AI." The rest of Object Creator
111
+ (8-direction rotation, states, pro/v3 animation) is closed; see below.
83
112
 
84
113
  ## UI elements and RPG UI kits
85
114
 
@@ -125,6 +125,63 @@ response shape has not been exercised against a live account — see
125
125
  `pollImagePro` in `src/providers/pixellab.ts` if a real call ever
126
126
  contradicts what it assumes.
127
127
 
128
+ `objectPro` wraps `/create-object-pro-flash` — the same base → state →
129
+ animation family `character` uses (`docs/CHARACTERS.md`), for PixelLab's
130
+ separate, skeleton-free "object" entity, distinct from the generic
131
+ `/objects` polling resource `1dir`/`map` already share. It reuses
132
+ `character`'s own `asset.state`/`asset.animation` authoring fields and
133
+ mirror handling verbatim rather than inventing parallel ones — an
134
+ `objectPro` asset's `state`/`animation` are validated identically, since an
135
+ object's state is a strict subset of a character's (no `paletteFromReference`/
136
+ `canvas` equivalent on the API, always inherits the parent's exact canvas)
137
+ and its animation is the same minus the template/skeleton concept objects
138
+ have none of: `template`, `subject`, `outline`, `shading`, `detail` on an
139
+ `objectPro` animation are rejected at resolve time rather than silently
140
+ dropped. `objectDirections` (1 or 8, default 8) is a real choice `character`
141
+ pro-flash does not offer (always 8); a 1-direction object's animation must
142
+ target `south` — passing any other direction, or `directions` at all to the
143
+ API for a 1-direction object, is what the endpoint itself 400s on.
144
+ Regenerating an already-animated direction is simpler than `character`'s
145
+ own "find and delete the prior take" dance: `/objects/{id}/animations` has
146
+ its own `replace_existing` flag, which PixelKiln always passes. **Cost is
147
+ not independently measured** — `objectProCost()` assumes it prices
148
+ identically to `character` pro-flash's own measured formula
149
+ (`proFlashCharacterCost`), since the request bodies are near-identical minus
150
+ `template_id`; treat it as a working assumption pending a live check.
151
+ Batch "pack" generation (PixelLab's Object Creator can make N distinct
152
+ objects from one call) and `objectPro`'s own place in `pixelkiln adopt` are
153
+ not modeled yet.
154
+
155
+ `isometricTile` wraps a *third*, separate path to isometric content:
156
+ `/create-isometric-tile`, distinct from both `tiles`' own `tileType:
157
+ "isometric"` (a full connectable set) and `terrain`'s `/create-tileset`
158
+ (confirmed square-only — no isometric option exists there at all). It
159
+ generates one standalone tile, no candidates, no connectable set — the
160
+ shape for a per-tile elevation primitive (a raised mesa, a cliff block) when
161
+ a connected ground set is not what's needed. `isometricTileShape` controls
162
+ vertical thickness — `"thin tile"` (~15% canvas height), `"thick tile"`
163
+ (~25%), or `"block"` (~50%, the API default) — the most direct
164
+ height/elevation knob of any generator here. `isometricTileSize` is the
165
+ API's own tile grid (16 or 32, default 16), separate from `size` (the 16–64px
166
+ generation canvas; the endpoint's own guidance is that sizes above 24px
167
+ "often produce better quality results"). `outline` defaults to `"lineless"`
168
+ on this endpoint specifically (`tiles-pro`'s own default is `"outline"`),
169
+ with its own three-value enum (`"single color outline"`, `"selective
170
+ outline"`, `"lineless"`); `shading`/`detail` reuse the same enums `terrain`
171
+ does. **Cost: 1 generation flat, measured** — PixelLab's own OpenAPI response
172
+ example shows `{ type: "usd", usd: 0.02 }`, which reads as real-dollar
173
+ billing, but a real call against a live subscription account billed exactly
174
+ 1 generation instead (`usage: { type: "generations", generations: 1 }`);
175
+ `costUnit` here is `"generations"` like every other generator, not `"usd"`.
176
+ Only one size/shape combination (32px, `"block"`) has actually been
177
+ measured, and the endpoint documents no size-tiering formula, so
178
+ `isometricTileCost()` assumes flat pricing across the 16–64px range rather
179
+ than guessing a tier. Style images, `init_image`/`init_image_strength`
180
+ (image-to-image), and `color_image` (native forced-palette) exist on this
181
+ endpoint and are not modeled yet; pixelkiln's own `palette`/`enforcePalette`
182
+ post-processing already works generically on the downloaded tile if a
183
+ closed palette is what's actually needed.
184
+
128
185
  Do not confuse pixelkiln's `map` generator with PixelLab's own "Map
129
186
  Workshop": `map` returns one static prop, icon, or building in a single
130
187
  generation with no scene, canvas, or placement concept. Map Workshop (scene