pixelkiln 0.89.6 → 0.91.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/dist/cli.js +194 -29
- package/dist/cli.js.map +1 -1
- package/dist/client/gallery.css +1 -0
- package/dist/client/gallery.js +54 -17
- package/dist/index.cjs +196 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +282 -14
- package/dist/index.d.ts +282 -14
- package/dist/index.js +195 -29
- package/dist/index.js.map +1 -1
- package/docs/CHARACTERS.md +73 -3
- package/docs/ENDPOINTS.md +12 -1
- package/docs/MANIFEST.md +2 -2
- package/docs/PIXELLAB.md +46 -0
- package/docs/REVISIONS.md +8 -5
- package/package.json +1 -1
- package/schema/manifest.schema.json +5 -1
- package/skills/pixelkiln/references/pixellab-roadmap.md +16 -15
- package/skills/pixelkiln/references/pixellab.md +11 -0
package/docs/CHARACTERS.md
CHANGED
|
@@ -222,6 +222,75 @@ single direction before a batch.
|
|
|
222
222
|
"mira.walk": { "animation": { "of": "mira", "template": "walk", "mode": "skeleton-v3", "directions": ["south", "west", "north"] } }
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
### Loops from a sentence
|
|
226
|
+
|
|
227
|
+
`mode: "skeleton-v3"` with **no `template`** animates the asset's `prompt`
|
|
228
|
+
instead: PixelLab writes the sentence into one 3D motion and draws the
|
|
229
|
+
character from it, with no template to pick. `frames` takes PixelLab's own
|
|
230
|
+
3 to 15 for this combination (odd counts included, default 8); a template
|
|
231
|
+
`skeleton-v3` loop still takes none.
|
|
232
|
+
|
|
233
|
+
```jsonc
|
|
234
|
+
"mira.swing": {
|
|
235
|
+
"prompt": "swinging a sword in a wide arc",
|
|
236
|
+
"animation": { "of": "mira", "mode": "skeleton-v3", "frames": 8, "directions": ["south", "west"] }
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
- **A v3 base is required.** The sentence is written onto the character's
|
|
241
|
+
stored 3D skeleton, which a `standard` base lacks, so `plan` and `validate`
|
|
242
|
+
refuse the pairing and name the engine. `pro` and `pro-flash` bases are
|
|
243
|
+
not refused but are unverified. An `objectPro` has no skeleton at all.
|
|
244
|
+
- **The prompt is the sentence**, sent as written as `action_description`
|
|
245
|
+
(a loop's prompt never takes the style's prefix or suffix, same as a v3
|
|
246
|
+
loop). It is required; `startFrame`, `endFrame`, `enhancePrompt`,
|
|
247
|
+
`subject`, and the template style hints are refused.
|
|
248
|
+
- **The canvas can grow.** The measured 64px loop came back at 96×96. The
|
|
249
|
+
frames are saved as PixelLab returns them; a mirror flips them locally like
|
|
250
|
+
any other loop.
|
|
251
|
+
- **Cost**: the plan budgets 4 per direction, the same ceiling as a template
|
|
252
|
+
`skeleton-v3` loop. Measured live on a v3 character: 8 frames at 64px billed
|
|
253
|
+
exactly 3 generations for one direction, about 15 seconds before the jobs
|
|
254
|
+
start. `billed` in the lock records the real amount.
|
|
255
|
+
- **Directions share the first direction's motion.** PixelLab draws every
|
|
256
|
+
direction of an animation from one 3D motion, and `animation_group_id`
|
|
257
|
+
adds a direction to an existing animation so it moves the same way. The
|
|
258
|
+
first direction listed in `directions` leads and is submitted as a new
|
|
259
|
+
animation; every later direction follows in the next wave and is sent into
|
|
260
|
+
the leader's group (with the group's own name as `animation_name`, since
|
|
261
|
+
PixelLab does not inherit it). Each direction is still its own asset and
|
|
262
|
+
request, billed separately; mirrors flip a direction and join nothing. The
|
|
263
|
+
expansion writes `animation.motionFrom: "<leader id>"` on each later
|
|
264
|
+
direction, and you can write it yourself when declaring the loops
|
|
265
|
+
explicitly. It is part of the asset's identity; the leader's hash, a single
|
|
266
|
+
direction's, and every template or other loop's are unchanged.
|
|
267
|
+
- **Adding a direction later**: append it to `directions` (new directions
|
|
268
|
+
at the end, so the leader stays the same). The leader is already
|
|
269
|
+
downloaded and current, so the new direction goes straight into its
|
|
270
|
+
recorded group, with no regeneration of the others. Putting a new
|
|
271
|
+
direction first makes it the leader and the old one a follower, which
|
|
272
|
+
regenerates both.
|
|
273
|
+
- **Regenerating**: a regenerated leader is a new animation with a new group,
|
|
274
|
+
so followers drawn into the old group show `stale` ("shares motion with
|
|
275
|
+
`<leader>`, which was regenerated") and are redrawn into the new one.
|
|
276
|
+
Restoring an older generation brings back the group it was drawn into.
|
|
277
|
+
The lock keeps it as `motionShare: { sourceAssetId, animationGroupId }`.
|
|
278
|
+
- **Replacing**: only an asset's own direction is ever deleted, from the
|
|
279
|
+
group it is in, so redrawing a follower never removes the leader's
|
|
280
|
+
animation or the reverse. This relies on PixelLab keeping a group alive
|
|
281
|
+
while any direction remains, and on a follower keeping its motion after
|
|
282
|
+
the leader's direction is deleted; neither is verified.
|
|
283
|
+
- **Fallback**: a leader with no recorded `animationGroupId` (generated
|
|
284
|
+
before groups were recorded, or adopted without one) does not block its
|
|
285
|
+
followers. Each is drawn as its own request and animation, as before, and
|
|
286
|
+
`plan` says so; its `motionShare.animationGroupId` is `null`. If the
|
|
287
|
+
leader's recorded group is gone from the character, the follower fails
|
|
288
|
+
before spending and asks you to regenerate the leader.
|
|
289
|
+
- Verified against mocked HTTP only; not yet run live. A single south
|
|
290
|
+
direction was verified live through PixelKiln on an adopted v3 character:
|
|
291
|
+
"jumping with joy and pumping both fists", 8 frames at 96×96, billed 3,
|
|
292
|
+
with `animationId` and `animationGroupId` saved in the lock.
|
|
293
|
+
|
|
225
294
|
### Pose frames and other loop controls
|
|
226
295
|
|
|
227
296
|
A v3 loop can start and end where you say. `startFrame` is a
|
|
@@ -489,11 +558,12 @@ reference image change alone also makes it stale.
|
|
|
489
558
|
style (engine, size, directions, body, view, folder) or an existing one,
|
|
490
559
|
the base with an optional sprite of your own (uploaded into `refs/`, so
|
|
491
560
|
only the rotations are billed), any number of loops (each a template
|
|
492
|
-
posed by `skeleton-v3` by default,
|
|
561
|
+
posed by `skeleton-v3` by default, a `skeleton-v3` loop described in words
|
|
562
|
+
with a 3 to 15 frame count, or a plain template, v3, or pro loop,
|
|
493
563
|
in the directions you tick, mirrors added free), and a portrait. A
|
|
494
564
|
`standard` base has no 3D skeleton for `skeleton-v3` to pose, so its loops
|
|
495
|
-
start on `template` and
|
|
496
|
-
form on an existing base does the same. The
|
|
565
|
+
start on `template` and both skeleton-v3 choices are greyed out; the
|
|
566
|
+
new-loop form on an existing base does the same. The
|
|
497
567
|
sheet prices the draft live, the way `plan` would. Pro Flash bases are
|
|
498
568
|
priced by PixelLab's own quote (`/pro-flash/cost`, a free call) when the
|
|
499
569
|
project has a key; those rows are marked live, and the offline estimate
|
package/docs/ENDPOINTS.md
CHANGED
|
@@ -920,7 +920,18 @@ generations and finished in about two minutes:
|
|
|
920
920
|
the top-level amount is a dollar zero. PixelLab says the action is written
|
|
921
921
|
into one 3D motion that every direction is drawn from, so later directions
|
|
922
922
|
added with `animation_group_id` move the same way (humanoids). pixelkiln
|
|
923
|
-
|
|
923
|
+
sends this mode for a character loop with `mode: "skeleton-v3"`, a prompt,
|
|
924
|
+
and no template (docs/CHARACTERS.md, "Loops from a sentence"), one request
|
|
925
|
+
per direction asset. The first direction of a `directions` loop is sent
|
|
926
|
+
without `animation_group_id`; each later one is sent after it with the
|
|
927
|
+
leader's recorded `animation_group_id` and the group's own `animation_name`
|
|
928
|
+
(not inherited, so omitting it would rename the group). That append is
|
|
929
|
+
**mock-verified only**: the request shape follows the tool's documentation
|
|
930
|
+
and a live append has not been run. Verified live twice
|
|
931
|
+
with one south direction on a v3 character, once by a direct call and once
|
|
932
|
+
through `pixelkiln gen` (a manifest loop on an `adopt`ed character, 8
|
|
933
|
+
frames at 96×96, billed 3, then `pick` and `fetch`); a standard-engine
|
|
934
|
+
character is refused (`has no stored 3D skeleton`).
|
|
924
935
|
|
|
925
936
|
## Characters, measured
|
|
926
937
|
|
package/docs/MANIFEST.md
CHANGED
|
@@ -56,7 +56,7 @@ not merely a label edit.
|
|
|
56
56
|
|
|
57
57
|
| Field | Type/default | Meaning |
|
|
58
58
|
|---|---|---|
|
|
59
|
-
| `prompt` | string, required unless `mirror`, `portrait`, `outfit`, or a template loop (`animation.template`) | The subject wording wrapped by the selected style's prompt prefix and suffix. A template loop is described by its template; a v3 or
|
|
59
|
+
| `prompt` | string, required unless `mirror`, `portrait`, `outfit`, or a template loop (`animation.template`) | The subject wording wrapped by the selected style's prompt prefix and suffix. A template loop is described by its template; a v3, pro, or sentence (`skeleton-v3` with no template) loop still needs the motion in words. |
|
|
60
60
|
| `width` / `height` | integer 16–8192 | Per-asset dimensions for generators that accept rectangular output. Provider limits may be lower. |
|
|
61
61
|
| `size` | integer 16–8192 | Per-asset square size where the generator uses one dimension. |
|
|
62
62
|
| `file` | string | Output path below the style's `outDir`; defaults to `<category>/<assetId>.png`. |
|
|
@@ -66,7 +66,7 @@ not merely a label edit.
|
|
|
66
66
|
| `remoteId` | string | The provider's own id for art that already exists on the account, so `adopt` maps it without matching bytes: an object id, a character id, or `<character id>#<animation group id>`. Not part of the spec's identity. |
|
|
67
67
|
| `revision` | object | Controlled dependency on another asset: `image-to-image`, `inpaint`, or `outpaint`; on PixelLab also `reduce-colors`, `correct-pixelart`, `remove-background`, `normal-map`, the animate modes (`animate`, `animate-pixminimax`, `animate-skeleton`), `interpolate`, and `edit-animation`. `engine: "pro-flash"` selects PixelLab's Pro Flash tier for `image-to-image`/`inpaint`. See [controlled revisions](REVISIONS.md). |
|
|
68
68
|
| `state` | object | `character` styles: a pose or outfit of another character asset. See [Characters](./CHARACTERS.md). |
|
|
69
|
-
| `animation` | object | `character` styles: a loop of another character asset in one direction. `directions` (a list, instead of `direction`) declares the loop for several directions at once and fills the unnamed flips with mirrors; see [One loop, several directions](./CHARACTERS.md#one-loop-several-directions). |
|
|
69
|
+
| `animation` | object | `character` styles: a loop of another character asset in one direction. `directions` (a list, instead of `direction`) declares the loop for several directions at once and fills the unnamed flips with mirrors; see [One loop, several directions](./CHARACTERS.md#one-loop-several-directions). `mode: "skeleton-v3"` with no `template` animates the asset's `prompt` as a sentence (3–15 `frames`, default 8; a v3 base); see [Loops from a sentence](./CHARACTERS.md#loops-from-a-sentence). `motionFrom` (an asset id) makes a sentence loop follow another direction's loop and share its motion; `directions` writes it for you. |
|
|
70
70
|
| `portrait` | object | `character` styles: a bust of a base or state's south sprite, `{ "of": "<asset>", "size": 64 }`; `size` is 16, 32, 48, 64 (default), 128, or 160. See [Portraits](./CHARACTERS.md#portraits). |
|
|
71
71
|
| `outfit` | object | `character` styles: an existing loop's frames re-clothed from an outfit image, `{ "of": "<loop asset>", "reference": "<image>" }`, with optional `additionalInstructions`. See [Outfit transfer](./CHARACTERS.md#outfit-transfer). |
|
|
72
72
|
| `mirror` | string | Another asset of the same style flipped left to right, made locally at no cost. See [Mirrors](./CHARACTERS.md#mirrors). |
|
package/docs/PIXELLAB.md
CHANGED
|
@@ -100,6 +100,52 @@ beside the submit-time `cost` estimate a wave budget spends against;
|
|
|
100
100
|
`pixelkiln history`, `plan --json`, and the gallery show both when they
|
|
101
101
|
differ (docs/ENDPOINTS.md, "Limits and billing").
|
|
102
102
|
|
|
103
|
+
## Custom animation on skeleton v3
|
|
104
|
+
|
|
105
|
+
PixelLab's character creator can now animate a character on its skeleton v3
|
|
106
|
+
model from a sentence or from skeletons you pose, and the same two paths are
|
|
107
|
+
in the API. PixelKiln sends both from a manifest.
|
|
108
|
+
|
|
109
|
+
A loop with `mode: "skeleton-v3"` and no `template` animates its `prompt`:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
"hero.cheer": {
|
|
113
|
+
"prompt": "cheerfully waving both arms overhead",
|
|
114
|
+
"animation": { "of": "hero", "mode": "skeleton-v3", "frames": 8, "directions": ["south"] }
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
An `animate-skeleton` revision poses the sprite along skeletons you give it.
|
|
119
|
+
`pixelkiln estimate-skeleton` writes the file from an image, you edit the
|
|
120
|
+
joints, and `skeleton-preview` draws them over the sprite before you spend:
|
|
121
|
+
|
|
122
|
+
```jsonc
|
|
123
|
+
"hero-wave": {
|
|
124
|
+
"prompt": "wave",
|
|
125
|
+
"styles": ["rig"],
|
|
126
|
+
"revision": {
|
|
127
|
+
"mode": "animate-skeleton", "from": "hero",
|
|
128
|
+
"keypointsFile": "poses/wave.json", "direction": "south",
|
|
129
|
+
"description": "cheerful adventurer with short auburn hair, blue tunic"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- Both need a v3 character. A `standard` base has no 3D skeleton for the model
|
|
135
|
+
to pose, so `plan` refuses the loop and names the engine.
|
|
136
|
+
- The revision's `prompt` is the motion ("wave") and its `description` is how
|
|
137
|
+
the character looks. PixelLab requires both, and `plan` refuses a revision
|
|
138
|
+
without a description.
|
|
139
|
+
- Each billed exactly 3 generations for 8 frames, measured live. The sentence
|
|
140
|
+
loop came back at 96×96 from a 64px character; the posed one stayed 64×64.
|
|
141
|
+
[The home page](https://pixelkiln.griffen.codes/#updates) shows both.
|
|
142
|
+
- Each direction of a sentence loop is its own request for now, so a loop with
|
|
143
|
+
several directions can move a little differently in each. PixelLab can draw
|
|
144
|
+
every direction from one motion, but PixelKiln does not send that yet.
|
|
145
|
+
|
|
146
|
+
See [Loops from a sentence](./CHARACTERS.md#loops-from-a-sentence) and
|
|
147
|
+
[Skeleton-driven animation](./REVISIONS.md#skeleton-driven-animation).
|
|
148
|
+
|
|
103
149
|
## What changed in PixelLab 0.4.130
|
|
104
150
|
|
|
105
151
|
PixelLab 0.4.130 (October 2026) added four things. PixelKiln covers each:
|
package/docs/REVISIONS.md
CHANGED
|
@@ -492,7 +492,8 @@ a supplied 18-joint skeleton per frame instead of a text motion description:
|
|
|
492
492
|
"mode": "animate-skeleton",
|
|
493
493
|
"from": "hero-idle",
|
|
494
494
|
"keypointsFile": "poses/hero-swing.json",
|
|
495
|
-
"direction": "south"
|
|
495
|
+
"direction": "south",
|
|
496
|
+
"description": "a knight in steel armour holding a sword"
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
499
|
}
|
|
@@ -522,8 +523,8 @@ over the source image, locally and for free.
|
|
|
522
523
|
`direction` is **required** for this mode (unlike `animate-pixminimax`,
|
|
523
524
|
where it is optional). `frames`/`fps`/`lastFrame`/`enhancePrompt` are all
|
|
524
525
|
rejected — the frame count comes from the keypoints file itself
|
|
525
|
-
(`frames.length`), never a manifest number. `description` (
|
|
526
|
-
character *looks like* — colours, clothing, held items) is a new field
|
|
526
|
+
(`frames.length`), never a manifest number. `description` (**required**: what
|
|
527
|
+
the character *looks like* — colours, clothing, held items) is a new field
|
|
527
528
|
distinct from the asset's own `prompt`, which this mode sends as the motion's
|
|
528
529
|
short label (PixelLab's `action`) — the same `prompt`-as-motion convention
|
|
529
530
|
`animate`/`animate-pixminimax` already use, just under this endpoint's own
|
|
@@ -560,8 +561,10 @@ anchor, and returned 8 frames at the sprite's own 64×64 size. The endpoint
|
|
|
560
561
|
**requires both `description` and `action`**: the asset's `prompt` is sent as
|
|
561
562
|
`action` (a short motion label such as "wave"), and `revision.description`
|
|
562
563
|
(what the character looks like) is sent as `description`. Without a
|
|
563
|
-
`description` PixelLab answers `422` with `description: Field required`,
|
|
564
|
-
|
|
564
|
+
`description` PixelLab answers `422` with `description: Field required`, so
|
|
565
|
+
`plan` refuses an `animate-skeleton` revision without a non-empty
|
|
566
|
+
`revision.description` (or an empty `prompt`) and the gallery's form asks for
|
|
567
|
+
one.
|
|
565
568
|
|
|
566
569
|
ComfyUI does not support this mode either, for the same structural reason as
|
|
567
570
|
`animate`/`animate-pixminimax`.
|
package/package.json
CHANGED
|
@@ -1305,9 +1305,13 @@
|
|
|
1305
1305
|
},
|
|
1306
1306
|
"minItems": 1
|
|
1307
1307
|
},
|
|
1308
|
+
"motionFrom": {
|
|
1309
|
+
"type": "string",
|
|
1310
|
+
"minLength": 1
|
|
1311
|
+
},
|
|
1308
1312
|
"frames": {
|
|
1309
1313
|
"type": "integer",
|
|
1310
|
-
"minimum":
|
|
1314
|
+
"minimum": 3,
|
|
1311
1315
|
"maximum": 16
|
|
1312
1316
|
},
|
|
1313
1317
|
"fps": {
|
|
@@ -31,6 +31,21 @@ and which tutorial(s) demonstrated real (not hypothetical) demand for it.
|
|
|
31
31
|
|
|
32
32
|
## Already closed since this catalog's research began
|
|
33
33
|
|
|
34
|
+
- **Sentence-driven skeleton-v3 loops** — a character loop with
|
|
35
|
+
`mode: "skeleton-v3"`, no `template`, and a `prompt` animates the sentence
|
|
36
|
+
on `/characters/animations` (`action_description`, 3 to 15 `frames`). Billed
|
|
37
|
+
exactly 3 generations for 8 frames at 64px, frames back at 96×96; the plan
|
|
38
|
+
budgets 4. See `docs/CHARACTERS.md`, "Loops from a sentence".
|
|
39
|
+
- **Shared motion across the directions of a sentence loop** — the first
|
|
40
|
+
direction of `directions` is submitted as a new animation; each later one
|
|
41
|
+
follows in the next wave with the leader's recorded `animation_group_id` and
|
|
42
|
+
the group's `animation_name`, so every direction is drawn from one 3D motion
|
|
43
|
+
(`animation.motionFrom`, lock `motionShare`). Adding a direction to a
|
|
44
|
+
generated loop appends into its group, a regenerated leader marks followers
|
|
45
|
+
stale, and a leader with no recorded group falls back to one request per
|
|
46
|
+
direction. **Mock-verified only; live proof pending** (a live append, and that
|
|
47
|
+
deleting one direction leaves the group and the others' motion intact).
|
|
48
|
+
|
|
34
49
|
- **Skeleton-v3 template loops** — `/characters/animations`'
|
|
35
50
|
`mode: "skeleton-v3"` poses a template with the skeleton video model
|
|
36
51
|
(2 to 4 generations and 3 to 5 minutes per direction, beta, Tier 1 and
|
|
@@ -299,7 +314,7 @@ and which tutorial(s) demonstrated real (not hypothetical) demand for it.
|
|
|
299
314
|
`resolveSpecs`/`estimate()`-time call — so `animate-skeleton`'s submission
|
|
300
315
|
composes exactly one PixelLab endpoint, not two chained together. Both
|
|
301
316
|
endpoints have since run live once (8 frames billed exactly 3), and the
|
|
302
|
-
run found that `description` is required
|
|
317
|
+
run found that `description` is required, which `plan` now enforces. **Correcting this catalog's own prior research**: this entry
|
|
303
318
|
used to also claim a distinct "animation to animation" endpoint existed,
|
|
304
319
|
for transferring an existing walk cycle's motion onto a different
|
|
305
320
|
character. Checked against the live `animate_with_skeleton_v3` MCP tool
|
|
@@ -517,20 +532,6 @@ missing:
|
|
|
517
532
|
Aseprite. pixelkiln has no frame-set concatenation; `lastFrame` can pin a
|
|
518
533
|
clip's ending to another clip's frame file, but the two sets stay separate.
|
|
519
534
|
|
|
520
|
-
## Sentence-driven skeleton-v3 loops
|
|
521
|
-
|
|
522
|
-
PixelLab's October 2026 character-creator update adds custom animation on the
|
|
523
|
-
skeleton v3 model: a sentence becomes one 3D motion that every direction of
|
|
524
|
-
the animation is drawn from, so a direction added later moves the same way.
|
|
525
|
-
It is `POST /characters/animations` with `mode: "skeleton-v3"`, an
|
|
526
|
-
`action_description`, and no `template_animation_id` (3 to 15 frames, humanoid
|
|
527
|
-
v3 characters). **Measured once**: an 8-frame south loop billed exactly 3 and
|
|
528
|
-
came back at 96×96 (docs/ENDPOINTS.md, "Skeleton-driven motion, measured").
|
|
529
|
-
Still a gap: a character loop's `mode: "skeleton-v3"` needs a `template`,
|
|
530
|
-
and the request never sends `action_description` for it. Closing it means a
|
|
531
|
-
loop that names `skeleton-v3` and a `prompt` without a template, a
|
|
532
|
-
`frames` count from 3 to 15, and adding a direction to an existing group.
|
|
533
|
-
|
|
534
535
|
## Map Workshop (scene composition)
|
|
535
536
|
|
|
536
537
|
PixelLab's actual scene-building surface: lay out a tile floor, place
|
|
@@ -394,6 +394,17 @@ stored 3D skeleton: a `v3` base has one (measured, 3 generations); a
|
|
|
394
394
|
refuses the loop at `plan`/`validate`, pointing at `mode: "template"`. `pro`
|
|
395
395
|
and `pro-flash` bases are not refused but are unverified.
|
|
396
396
|
|
|
397
|
+
`"mode": "skeleton-v3"` with **no** `template` animates the asset's `prompt`
|
|
398
|
+
as a sentence (`frames` 3 to 15, default 8; a v3 base): PixelLab writes it
|
|
399
|
+
into one 3D motion. Measured: 8 frames at 64px billed exactly 3 generations
|
|
400
|
+
and came back at 96×96, so the canvas can grow. The plan still budgets 4. One
|
|
401
|
+
request goes out per direction asset: the first direction of `directions`
|
|
402
|
+
leads, and each later one follows in the next wave, sent into the leader's
|
|
403
|
+
`animation_group_id` so every direction moves the same way (`animation.motionFrom`,
|
|
404
|
+
lock `motionShare`; mock-verified only, docs/CHARACTERS.md, "Loops from a
|
|
405
|
+
sentence"). The
|
|
406
|
+
`prompt` is required and gets no style prefix or suffix.
|
|
407
|
+
|
|
397
408
|
A named `template` loop (`walk`, `breathing-idle`, and similar) is trained
|
|
398
409
|
mostly on characters with empty hands, and reliably struggles once a
|
|
399
410
|
character holds an item — a weapon, a tool, anything gripped. For a
|