@rig-c/core 2.82.0 → 2.82.2
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 +67 -279
- package/docs/AUTHORING.md +110 -3
- package/docs/FACE.md +3 -1
- package/docs/INGEST.md +143 -4
- package/docs/MOTION.md +21 -11
- package/package.json +1 -1
- package/skills/rigc/SKILL.md +4 -2
- package/src/pose.ts +209 -147
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ name. Both remain published alongside it with the same product files.
|
|
|
26
26
|
|
|
27
27
|
<p align="center"><em>Fourteen part PNGs drawn from scratch for this repo, one rig spec, one motion spec — the assembly,
|
|
28
28
|
the breathing and the wave are all rigc-compiled Spine animations, rendered with
|
|
29
|
-
<code>rigc render</code>. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-demo@2x.gif">2x
|
|
29
|
+
<code>rigc render</code>. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-demo@2x.gif">2x assembly film</a> (1200x810) sits beside it.</em></p>
|
|
30
30
|
|
|
31
31
|
Loose part PNGs and two small JSON files in; **Spine 4.3 skeleton data out** — a
|
|
32
32
|
`skeleton.json` and a `skeleton.atlas` that load in any Spine runtime and **import
|
|
@@ -44,13 +44,29 @@ installed.
|
|
|
44
44
|
| a compiled rig and a question about its geometry | `rigc inspect` | one picture of its bones, axes, mesh edges and hulls, one bone's weights, the triangles folded over, the draw order, a world grid or a declared axis over the art — at the setup pose, one time or a sheet of several, zoomed to a bone or a slot, or beside a second build on one transform — and a legend that puts every mark back in world units |
|
|
45
45
|
| a compiled rig | `rigc preview` | one self-contained `.html` that plays it in Spine's own web player |
|
|
46
46
|
| two to four compiled rigs | `rigc vote` | one ballot page a human picks from, and the answer checked into a ledger |
|
|
47
|
-
| a picture of a key pose | `rigc pose` | where each loose part PNG sits in it, in spec coordinates — the movement between two poses is then yours to key ([
|
|
47
|
+
| a picture of a key pose | `rigc pose` | where each loose part PNG sits in it, in spec coordinates — the movement between two poses is then yours to key ([the motion recipe](docs/MOTION.md)) |
|
|
48
48
|
| the same picture, and a rig | `rigc chainfit` | the parts `pose` refuses because something is drawn over them — read through the candidate's own draw order and hierarchy, with the share of each part the answer was measured on |
|
|
49
49
|
|
|
50
50
|
Everything in that table needs Bun and this package — `preview` and `vote` also
|
|
51
51
|
`@esotericsoftware/spine-core` installed beside it (see below) — and no clone, no
|
|
52
52
|
reference art, no art pipeline, no server.
|
|
53
53
|
|
|
54
|
+
### Depth-driven rigging
|
|
55
|
+
|
|
56
|
+
Explicit depth, which a drawing alone does not state, makes facial features
|
|
57
|
+
shift by different amounts during a small head turn: [the portrait depth example](https://github.com/rig-c/core/tree/main/gallery/portrait)
|
|
58
|
+
uses per-part depths, while [the mesh-depth look example](https://github.com/rig-c/core/tree/main/gallery/look)
|
|
59
|
+
samples a depth map at the mesh vertices.
|
|
60
|
+
With [`@rig-c/parts`' depth fields](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#per-layer-depth-sheets-773),
|
|
61
|
+
See-through's per-layer sheets are bound explicitly with `near` and `zScale`,
|
|
62
|
+
then consumed by head-turn roles in `turn.roles`.
|
|
63
|
+
The [depth-yaw flow](docs/FACE.md#a-measured-alpha-aperture) shows how a turning
|
|
64
|
+
surface and its alpha clipping aperture move together.
|
|
65
|
+
The [value-driven turn](docs/FACE.md#the-turn-as-a-value-rather-than-a-time) is a
|
|
66
|
+
rig control; the consumer chooses when to move it, and
|
|
67
|
+
[getting-started](https://github.com/rig-c/getting-started) is the painting-to-rig
|
|
68
|
+
walkthrough.
|
|
69
|
+
|
|
54
70
|
### Alpha-derived clipping
|
|
55
71
|
|
|
56
72
|
Alpha-derived clipping takes a named source slot/skin/attachment plus explicit
|
|
@@ -59,7 +75,8 @@ Region, authored/resolved linked mesh and generated grid/contour depth sources u
|
|
|
59
75
|
ordinary weighted clipping, with the existing validation gate before emission.
|
|
60
76
|
See [AUTHORING: Alpha-derived clipping](docs/AUTHORING.md#alpha-derived-clipping)
|
|
61
77
|
for source-motion limits, fit reports and named refusals, and
|
|
62
|
-
[the face guide](docs/FACE.md#a-measured-alpha-aperture) for the depth-yaw flow
|
|
78
|
+
[the face guide](docs/FACE.md#a-measured-alpha-aperture) for the depth-yaw flow
|
|
79
|
+
used in depth-driven rigging.
|
|
63
80
|
|
|
64
81
|
## What rigc is, and what it is not
|
|
65
82
|
|
|
@@ -89,45 +106,7 @@ it cuts both ways:
|
|
|
89
106
|
|
|
90
107
|
### Licensing, stated plainly
|
|
91
108
|
|
|
92
|
-
|
|
93
|
-
the following is a restatement of Esoteric Software's terms, not a term of ours:
|
|
94
|
-
|
|
95
|
-
1. rigc's output **is Spine skeleton data**.
|
|
96
|
-
2. A product that plays it with **a Spine Runtime** — the official runtimes, the Web
|
|
97
|
-
Player — has integrated the Spine Runtimes. rigc also writes the model document
|
|
98
|
-
its own core poses, and a product may play that or anything else; what the terms
|
|
99
|
-
turn on is the integration.
|
|
100
|
-
3. Integrating a Spine Runtime into a product is permitted **under Section 2 of the
|
|
101
|
-
[Spine Editor License Agreement](https://esotericsoftware.com/spine-editor-license)**,
|
|
102
|
-
or otherwise on the condition that **each user of the product obtains their own
|
|
103
|
-
Spine editor licence** and the product carries the Runtimes licence and copyright
|
|
104
|
-
notice — the Runtimes licence's own two routes, in its words.
|
|
105
|
-
4. The published rigc **links no Spine runtime**. This repository does — `spine-core`
|
|
106
|
-
as a development dependency, for its own gate — and so does an install with the
|
|
107
|
-
runtime added beside it.
|
|
108
|
-
|
|
109
|
-
> **If a product integrates a Spine Runtime to play rigc's output, that integration
|
|
110
|
-
> is subject to the terms above** — rigc neither adds those terms nor removes them.
|
|
111
|
-
> Running the published rigc links no Spine runtime, and whether its output is then
|
|
112
|
-
> played by one, by rigc's own core, or by something else is the consumer's choice.
|
|
113
|
-
|
|
114
|
-
See [NOTICE.md](NOTICE.md) for the full notice.
|
|
115
|
-
|
|
116
|
-
📐 **What of Esoteric Software's is in this repository, and under what grant.** No
|
|
117
|
-
example asset is committed: `bun run fetch-examples` downloads the example projects
|
|
118
|
-
into a gitignored `examples/`. What *is* committed is `bench/reference/` — 1,293 PNG
|
|
119
|
-
frames **this project renders** from those examples' own exports, so a frame carries
|
|
120
|
-
those images' pixels and committing one **is** redistribution. Each example's own
|
|
121
|
-
`license.txt` permits exactly that, *"as long as they are accompanied by this license
|
|
122
|
-
file"*, and a verbatim copy of it sits at each example root here — all eight, written
|
|
123
|
-
there by the render script rather than left to memory. The same file's
|
|
124
|
-
**non-commercial** condition rides along with those images, and
|
|
125
|
-
[LICENSE](LICENSE) says so: rigc's MIT grant covers rigc's own code, documentation
|
|
126
|
-
and art, not this material. `7-anticipation` publishes no `license.txt` upstream, so
|
|
127
|
-
no such grant exists for it and its frames are never committed — they render only
|
|
128
|
-
into a gitignored directory, enforced by `git check-ignore`. Full reasoning:
|
|
129
|
-
[`bench/reference/README.md`](https://github.com/rig-c/core/blob/main/bench/reference/README.md)
|
|
130
|
-
(repository material, not in the npm package).
|
|
109
|
+
See [the licensing notice](NOTICE.md) for licensing and third-party terms.
|
|
131
110
|
|
|
132
111
|
The problem rigc is aimed at is narrow. An agent asked to author a rig has no way
|
|
133
112
|
to tell whether it succeeded: Spine's JSON parser accepts a great deal of nonsense
|
|
@@ -211,7 +190,7 @@ reference frames this project renders from them, which **are** committed, each
|
|
|
211
190
|
example's own `license.txt` beside them under the redistribution grant those files
|
|
212
191
|
carry; the images stay **non-commercial only**. The reasoning is in
|
|
213
192
|
[`bench/reference/README.md`](https://github.com/rig-c/core/blob/main/bench/reference/README.md)
|
|
214
|
-
and the terms in [
|
|
193
|
+
and the terms in [the reference-image notice](NOTICE.md). It needs a clone and `bun run
|
|
215
194
|
fetch-examples`, and says so by name when the corpus is absent. `check` is not one
|
|
216
195
|
of them: it reads whatever frames you point it at, so it runs from the installed
|
|
217
196
|
package on pictures of your own — which is what *Where to go next* below tells you
|
|
@@ -467,39 +446,7 @@ origin and tip in world units and in pixels, so a position read off the picture
|
|
|
467
446
|
straight back into the spec. [AUTHORING §13](docs/AUTHORING.md#13-asking-the-picture-a-question--rigc-inspect)
|
|
468
447
|
maps each question to its view.
|
|
469
448
|
|
|
470
|
-
**`render`**
|
|
471
|
-
with a `contact.png` beside them — every frame of the shot as one labelled grid,
|
|
472
|
-
which is the picture to open first, because spacing is a comparison *across*
|
|
473
|
-
frames. It draws with rigc's own rasteriser (the one `check` measures with), so
|
|
474
|
-
it needs no browser and no network, and the `frames.json` it leaves beside the
|
|
475
|
-
directories makes the result a frame set like any other — the world box every
|
|
476
|
-
frame is a picture of. `--animation <name>` narrows it to one, `--fps` and
|
|
477
|
-
`--max` change the rate and the frame size. A set drawn at any rate but the
|
|
478
|
-
default is written to `<anim>@<fps>fps/` rather than `<anim>/`, so two rates sit
|
|
479
|
-
side by side: `--fps 24` writes `<anim>@24fps/`, and the default 12 writes
|
|
480
|
-
`<anim>/`. Each set's summary line ends with the directory it wrote.
|
|
481
|
-
|
|
482
|
-
> 🚨 **`--skin <name>` if your rig has more than one.** With no `--skin` no skin
|
|
483
|
-
> is set at all, so every slot resolves through the **default** skin alone — and
|
|
484
|
-
> a slot whose art lives only in a named skin draws *nothing*. That is not a
|
|
485
|
-
> quirk of `render`: `check` compares `render`'s frames, so a multi-skin rig
|
|
486
|
-
> checked with no skin compares blank against blank and reports a perfect
|
|
487
|
-
> `0.0000` about art nobody drew. `render --skin` records the name in
|
|
488
|
-
> `frames.json`, `check --skin` poses the candidate under it, and a candidate
|
|
489
|
-
> scored against frames rendered under a *different* skin is refused by name
|
|
490
|
-
> rather than measured.
|
|
491
|
-
|
|
492
|
-
**`preview`** writes a single self-contained `.html`: your skeleton, your atlas
|
|
493
|
-
and every page's PNG bytes are embedded in it as data URIs, and it plays them in
|
|
494
|
-
the **official [Spine Web Player](https://esotericsoftware.com/spine-player)**.
|
|
495
|
-
Double-click it, or attach it to a message — the file carries the whole artifact.
|
|
496
|
-
It is also the strongest interop statement in this repository: a rig that plays
|
|
497
|
-
there has been played by Esoteric Software's own runtime rather than by ours.
|
|
498
|
-
|
|
499
|
-
> ⚖️ The player itself is **referenced, not embedded** — the page loads it from
|
|
500
|
-
> unpkg, so the first open needs a network, and rigc redistributes nothing
|
|
501
|
-
> Esoteric Software owns (see [NOTICE.md](NOTICE.md)). Everything the player
|
|
502
|
-
> draws is inside your file.
|
|
449
|
+
**`render`** writes PNG frames and a contact sheet; **`preview`** writes a playable HTML file — see [the render and preview reference](docs/AUTHORING.md#0-the-loop).
|
|
503
450
|
|
|
504
451
|
**7. Let someone choose.** Sooner or later you will have two builds that both pass
|
|
505
452
|
the gate and no instrument that can separate them. `vote` puts them in one page
|
|
@@ -519,11 +466,11 @@ that does not belong to it. See
|
|
|
519
466
|
|
|
520
467
|
**Where to go next.**
|
|
521
468
|
|
|
522
|
-
- 📘 **[
|
|
469
|
+
- 📘 **[the authoring guide](docs/AUTHORING.md)** is the real guide — both files
|
|
523
470
|
field by field, the emission rules, every named failure mapped to the file that
|
|
524
471
|
has to change, and §8–§9 for reproducing a shot you were given as pictures. It
|
|
525
472
|
ships inside the npm package too, at
|
|
526
|
-
`node_modules
|
|
473
|
+
`node_modules/@rig-c/core/docs/AUTHORING.md`.
|
|
527
474
|
- `rigc explain --rig buoy.rig.json --motion buoy.motion.json --out spine` prints
|
|
528
475
|
the compiled rig as a table — every bone with its resolved parent, the slots in
|
|
529
476
|
draw order, every timeline key by key — and writes nothing. It is what to reach
|
|
@@ -543,11 +490,11 @@ that does not belong to it. See
|
|
|
543
490
|
it, so a figure is read against that rather than against a number from a page;
|
|
544
491
|
AUTHORING.md §9.2 says what the two halves of that bound are and why the floor
|
|
545
492
|
is not zero.
|
|
546
|
-
- [
|
|
493
|
+
- [the benchmark ladder](https://github.com/rig-c/core/blob/main/docs/LADDER.md) is the benchmark: the same job, from a brief
|
|
547
494
|
and rendered frames, scored. [docs/PILOT.md](https://github.com/rig-c/core/blob/main/docs/PILOT.md) is how to run an
|
|
548
495
|
agent through it and score what comes back.
|
|
549
496
|
- 🤖 **Handing the authoring to an AI agent?**
|
|
550
|
-
[
|
|
497
|
+
[the prompting guide](docs/PROMPTING.md) is the operator's page — the six prompt
|
|
551
498
|
clauses a measured pilot run paid for, and what you can leave unsaid.
|
|
552
499
|
|
|
553
500
|
## See what you built, and let someone choose
|
|
@@ -567,7 +514,7 @@ a rig compiles green, because green says nothing at all about the picture.
|
|
|
567
514
|
conditions, <code>rigc pose</code> reads where every part sits in each picture, two
|
|
568
515
|
candidate in-betweenings are compiled from the same pair — and a real
|
|
569
516
|
<code>rigc vote</code> ballot picks the winner, because the movement between the poses
|
|
570
|
-
is the one thing no instrument here will grade. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-keypose@2x.gif">2x
|
|
517
|
+
is the one thing no instrument here will grade. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-keypose@2x.gif">2x key-pose film</a> (1200x810) sits beside it.</em></p>
|
|
571
518
|
|
|
572
519
|
Three properties of `vote` are worth stating, because they are what make its ledger
|
|
573
520
|
usable by the next agent rather than by a reader: **a tie is a recorded outcome, not a
|
|
@@ -578,7 +525,7 @@ anywhere; and **every line carries a reason code** from a closed enumeration tha
|
|
|
578
525
|
enforced, so *"tie, because this one is better"* is refused.
|
|
579
526
|
|
|
580
527
|
🎞️ **Authoring the movement those pages show you** — key poses, in-betweening, and how
|
|
581
|
-
to spread candidates so a ballot informs — is [
|
|
528
|
+
to spread candidates so a ballot informs — is [the motion authoring guide](docs/MOTION.md).
|
|
582
529
|
|
|
583
530
|
📐 **`rigc pose --images parts/ --frame poseA.png` runs the other way.** Every command
|
|
584
531
|
above takes something you authored and tells you about it; this one takes a **picture
|
|
@@ -621,7 +568,7 @@ while <code>gaze</code> and <code>turn</code> return to rest, so the hand-offs m
|
|
|
621
568
|
differing pixels — and the composing is the consumer's. Authorable on plain Spine 4.3, no
|
|
622
569
|
plugin, no runtime patch; what the turn costs is authoring rather than runtime capability,
|
|
623
570
|
and that cost is one stated expression per key. Compiled and rendered entirely by the
|
|
624
|
-
published package. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-scene@2x.gif">2x
|
|
571
|
+
published package. A <a href="https://raw.githubusercontent.com/rig-c/core/main/assets/rigc-scene@2x.gif">2x portrait film</a> (1200x810) sits beside it.</em></p>
|
|
625
572
|
|
|
626
573
|
🎞️ **How the three films on this page were made** is kept with them, one directory per
|
|
627
574
|
film in [`films/`](https://github.com/rig-c/core/tree/main/films) — a `run.sh` that
|
|
@@ -631,203 +578,44 @@ material, like the gallery: a clone runs them.
|
|
|
631
578
|
|
|
632
579
|
## Commands
|
|
633
580
|
|
|
634
|
-
|
|
635
|
-
`rigc help <command>` prints the same page — and
|
|
636
|
-
[AUTHORING.md §0](docs/AUTHORING.md) is the same list with what each flag means, which
|
|
637
|
-
commands take it and what its default is.
|
|
581
|
+
`rigc help <command>` prints the command’s flags; [AUTHORING §0](docs/AUTHORING.md#0-the-loop) is the CLI reference.
|
|
638
582
|
|
|
639
583
|
| Command | Does |
|
|
640
584
|
| --- | --- |
|
|
641
|
-
| `build
|
|
642
|
-
| `
|
|
643
|
-
| `
|
|
644
|
-
| `
|
|
645
|
-
| `
|
|
646
|
-
| `
|
|
647
|
-
| `
|
|
648
|
-
| `
|
|
649
|
-
| `
|
|
650
|
-
| `
|
|
651
|
-
| `
|
|
652
|
-
| `
|
|
653
|
-
| `
|
|
654
|
-
| `
|
|
655
|
-
| `
|
|
656
|
-
| `
|
|
657
|
-
| `
|
|
658
|
-
| `
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
ask *is this valid Spine 4.3 that any runtime plays correctly?* `--profile rig-play`
|
|
670
|
-
adds all 50: the other 14 are one renderer's policy and one canvas budget's, and they
|
|
671
|
-
fire on perfectly correct editor-produced Spine data, which is why they are opt-in.
|
|
672
|
-
⇒ **That reason is about foreign data and does not carry to a rig you are authoring
|
|
673
|
-
yourself: author under `--profile rig-play` and read the extra 14 as findings, and
|
|
674
|
-
gate the release under `--profile spine`.** A `deform` key that folds a mesh inside
|
|
675
|
-
out is written out under the default and refused by name under `rig-play`, which
|
|
676
|
-
is the shape of what that split buys you. A report always names
|
|
677
|
-
the profile it ran and lists what that profile left out.
|
|
678
|
-
|
|
679
|
-
Several cuts can also be registered in a `cuts.json` and built by name
|
|
680
|
-
(`build --cut my_cut --cuts path/to/cuts.json`); every path in that table resolves
|
|
681
|
-
relative to the `cuts.json` file itself, so the table lives with the project that owns
|
|
682
|
-
the art. Its shape is under
|
|
683
|
-
[Usage](https://github.com/rig-c/core/blob/main/docs/BENCHMARK.md#usage).
|
|
684
|
-
|
|
685
|
-
### Starting from a skeleton you already have
|
|
686
|
-
|
|
687
|
-
`rigc ingest` reads a Spine 4.3 `skeleton.json` and writes the two spec files that
|
|
688
|
-
rebuild it. It is the only command that runs against `build`'s direction, and the
|
|
689
|
-
only one whose contract is an equality rather than a rulebook:
|
|
690
|
-
|
|
691
|
-
```bash
|
|
692
|
-
rigc ingest hero.json --out specs/ --images parts/
|
|
693
|
-
rigc build --rig specs/rig.json --motion specs/motion.json --out build/
|
|
694
|
-
rigc diff build/skeleton.json hero.json
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
`--images parts/` is what makes the second line carry no flag: it writes the spec's
|
|
698
|
-
own `images` directory, spelled from `--out`, so the specs are self-contained from
|
|
699
|
-
there on. Leave it off and the `image` names resolve against `specs/` itself, which
|
|
700
|
-
holds no art — every rebuild then has to repeat `build --images parts/`.
|
|
701
|
-
|
|
702
|
-
**`build(ingest(x))` is `x`.** Over the eleven rigs this repository builds — the seven
|
|
703
|
-
gallery examples, the three generated probes and a coverage probe written for the
|
|
704
|
-
purpose — the rebuilt `skeleton.json` is byte for byte the file the decompiler read.
|
|
705
|
-
The atlas is held to a weaker
|
|
706
|
-
claim on purpose, and the weakening is measured rather than assumed: it comes back
|
|
707
|
-
equal as a **multiset of region blocks**, because the order the pages are collected in
|
|
708
|
-
is in no field of the skeleton.
|
|
709
|
-
|
|
710
|
-
**And over twelve skeletons nobody here wrote.** Every editor export in the fetched
|
|
711
|
-
example corpus, ingested, rebuilt through the pack beside it and `diff`ed against the
|
|
712
|
-
source, comes back **12 of 12, no blockers, 1.000 on every measure the report
|
|
713
|
-
carries** — and each rebuild is its export's own text in canonical form, apart from
|
|
714
|
-
the header's `hash` and `spine`: the editor's project hash and the runtime version
|
|
715
|
-
rigc stamps, the two keys the rig spec has no field for by design (12 of 12) — and
|
|
716
|
-
the header's box, which `build` computes rather than carries (issue #907): the rebuild
|
|
717
|
-
writes spine-core's `getBounds` over the export on the header's 1e-6 grid at float32, equal on all twelve,
|
|
718
|
-
where the editor wrote its own arithmetic, up to 0.0071 units away.
|
|
719
|
-
[INGEST.md §2.3](docs/INGEST.md) states that pass line and why those two are the
|
|
720
|
-
exceptions.
|
|
721
|
-
|
|
722
|
-
**What it reads is skeleton JSON and nothing else** — no `.spine` project, no binary
|
|
723
|
-
`.skel`, no atlas, no art. So it never invents, and the things it cannot get out of
|
|
724
|
-
the file are **findings** with codes rather than plausible values: a construct the
|
|
725
|
-
spec format cannot hold (`point`, a `sequence` block, an unknown field
|
|
726
|
-
on a bone, slot or constraint) is a blocker, the command exits non-zero, and both
|
|
727
|
-
specs are still written — a spec plus a list of what is missing from it beats no spec.
|
|
728
|
-
|
|
729
|
-
⚠️ **Two values are not in a skeleton at all.**
|
|
730
|
-
|
|
731
|
-
- **The stage.** `skeleton.width`/`height`. A skeleton that declares none is carried as
|
|
732
|
-
declaring none — the rig spec states `"width": null, "height": null` and the rebuild
|
|
733
|
-
carries no box either, byte for byte — and `--stage x,y,w,h` is how a
|
|
734
|
-
caller *adds* one, recorded as a judgement. It is not derivable — posing the rig gives
|
|
735
|
-
the *animated* extent, which is a different number from the setup box. ⛔ **And `--stage` beside a box the file already states is refused
|
|
736
|
-
too**, for the opposite reason: two sources for one value, where the file is the record
|
|
737
|
-
of what was measured. **All twelve exports in the example corpus carry a stage** and
|
|
738
|
-
none of them needs the flag. It is the value that costs least to get wrong, because
|
|
739
|
-
`diff` reports the box and gates nothing on it. 🔁 The box an export's header carries
|
|
740
|
-
is its setup-pose bounding box, and it becomes the rebuild's *stage*; the rebuild's own
|
|
741
|
-
header is computed again, because since issue #907 `build` writes the setup-pose
|
|
742
|
-
bounding box there — never the stage — held to spine-core's `getBounds`. 📦 A rig
|
|
743
|
-
that has to carry its stage in the Spine files asks for it as a bounding box
|
|
744
|
-
(`skeleton.stageBox`, written by `build` from the stage and held by
|
|
745
|
-
`A50_STAGE_BOX_IS_THE_STAGE`), and `ingest --stage-box <slot>` reads that box back as
|
|
746
|
-
the rebuild's stage — [AUTHORING §3.1](docs/AUTHORING.md) has the field and the
|
|
747
|
-
paragraph for a consumer of the files.
|
|
748
|
-
- **An animation's duration.** The format has no such field. The largest key time is
|
|
749
|
-
the only derivable answer and it is what a runtime plays to; it is wrong for an
|
|
750
|
-
animation that holds its last pose past its last key, so it is recorded as a finding
|
|
751
|
-
on every animation rather than chosen quietly.
|
|
752
|
-
|
|
753
|
-
Both specs carry a `note` that `ingest` writes itself, saying the file is decompiled
|
|
754
|
-
and naming the skeleton it came from — because a decompiled spec is indistinguishable
|
|
755
|
-
from an authored one by inspection, every gate here calls it green (it *is* green),
|
|
756
|
-
and no gate can catch a missing note.
|
|
757
|
-
|
|
758
|
-
[docs/INGEST.md](docs/INGEST.md) is the whole page on working from a file you were
|
|
759
|
-
handed; [docs/AUTHORING.md](docs/AUTHORING.md) §0.3 is the loop.
|
|
760
|
-
|
|
761
|
-
### The editor round trip — for a licence holder, never in CI
|
|
762
|
-
|
|
763
|
-
`tools/editor_roundtrip.ts` drives the loop the output's whole premise rests on:
|
|
764
|
-
build → **import into the Spine editor** → export back to JSON → gate, `diff`,
|
|
765
|
-
`render` and `check` the export against the build it came from.
|
|
766
|
-
|
|
767
|
-
```
|
|
768
|
-
bun cli.ts build --rig … --motion … --out build/ --copy-images
|
|
769
|
-
bun tools/editor_roundtrip.ts --build build/ --editor /Applications/Spine.app/Contents/MacOS/Spine
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
Of the editor's `--version` it records one line, the `Spine <x.y.z> …` line that
|
|
773
|
-
carries the version, and nothing else that command prints — the rest of it
|
|
774
|
-
names the licence holder — or `editor version: not found in --version output`
|
|
775
|
-
where no such line is there. That call carries the same `-u` as the import and
|
|
776
|
-
the export, so a trip pinned with `--editor-version <v>` names the editor it
|
|
777
|
-
pinned and says so on the line (`(read from --version under -u <v>, …)`); an
|
|
778
|
-
unpinned trip names the launcher's default. Once the export exists the version
|
|
779
|
-
is held against the export's own `skeleton.spine`, and a disagreement is a FAIL
|
|
780
|
-
naming both values — the line would otherwise name an editor the trip did not
|
|
781
|
-
run on. It prints the import and export exit codes, the
|
|
782
|
-
validator's verdict on the export, every `diff` measure that moved, `check`'s mean MAE and worst drift per
|
|
783
|
-
animation **for each skin the build and the export both declare** — one
|
|
784
|
-
render-and-check block per skin, with a per-skin roll-up under them, because a
|
|
785
|
-
rig's contested art lives in its named skins and a single un-skinned check draws
|
|
786
|
-
none of it; a skin only one side declares is a FAIL naming it as **lost** (or
|
|
787
|
-
**added**) **by the export**, with `diff`'s `attachments.skins` beside it, and is
|
|
788
|
-
rendered on neither side — and a
|
|
789
|
-
field-by-field list of what the editor rewrote. Every step quotes what its child
|
|
790
|
-
said when that child did not do what it was for, the renderers included — the
|
|
791
|
-
editor's words in full and in order, except its `Licensed to:` line, which names
|
|
792
|
-
the licence holder and is replaced by a line saying it was withheld; a skin
|
|
793
|
-
**neither** side can draw — a hit-box rig, say — is a **SKIP** naming that, not a
|
|
794
|
-
red, because `check` had nothing to compare and `diff` and `validate` have
|
|
795
|
-
already measured the rig. One side drawing where the other does not is the
|
|
796
|
-
divergence the trip exists to find and stays a failure. A human edit made in the
|
|
797
|
-
editor survives the trip back.
|
|
798
|
-
|
|
799
|
-
🔒 **It requires a licensed Spine editor on the machine, by construction**, and
|
|
800
|
-
drives only the [documented command line](https://esotericsoftware.com/spine-command-line-interface)
|
|
801
|
-
— never the UI, and it produces nothing the editor did not produce. With no
|
|
802
|
-
editor present it refuses by name and exits non-zero, and so does the **trial**:
|
|
803
|
-
the trial cannot save projects or export animation data, so the refusal names
|
|
804
|
-
what it found — the executable, the bundle, the `CFBundleName` that bundle
|
|
805
|
-
declares, or the banner the binary prints about itself — rather than starting it
|
|
806
|
-
and failing downstream. Both refusals point at `--exported <file>`, which
|
|
807
|
-
measures an export the editor already made and is the half of this tool that
|
|
808
|
-
needs no editor at all. A build whose `skeleton.json` is missing, is not JSON, or
|
|
809
|
-
holds JSON that is not one object is refused by name before the editor starts,
|
|
810
|
-
and so is a build with no atlas or an atlas that is a directory, or an
|
|
811
|
-
`--exported` file that is not one JSON object.
|
|
812
|
-
|
|
813
|
-
⛔ **Run the round trip by hand, on a machine that has the editor.** CI has no
|
|
814
|
-
editor, so no automated check runs it. The by-hand measurement before a landing
|
|
815
|
-
trips the production rigs and one **parts-built** rig, the exam's task-01
|
|
816
|
-
painting through `@rig-c/parts`. The production rigs were authored in the editor,
|
|
817
|
-
so they are already in the editor's own shape. A refusal that only a generated
|
|
818
|
-
rig carries cannot show up on them. Issue #1407 was such a refusal: a green build
|
|
819
|
-
whose meshes listed their bones in two orders, which the editor would not import.
|
|
820
|
-
|
|
821
|
-
⚠️ Build with `--copy-images`. An ordinary build's atlas names its pages by a
|
|
822
|
-
relative path back to the art directory, and the round trip copies that atlas to
|
|
823
|
-
a directory at another depth — the tool refuses such a build by name rather than
|
|
824
|
-
letting `A17` blame the editor for the harness's own doing.
|
|
585
|
+
| `build` | Compile, gate and write the rig. [`build` in the CLI reference](docs/AUTHORING.md#cmd-build) |
|
|
586
|
+
| `validate` | Re-gate artifacts already on disk. [`validate` in the CLI reference](docs/AUTHORING.md#cmd-validate) |
|
|
587
|
+
| `repack` | Repack a build from its output. [`repack` in the CLI reference](docs/AUTHORING.md#cmd-repack) |
|
|
588
|
+
| `ingest` | Read a skeleton back into specs. [`ingest` in the CLI reference](docs/AUTHORING.md#cmd-ingest) |
|
|
589
|
+
| `split` | Separate disconnected mesh pieces. [`split` in the CLI reference](docs/AUTHORING.md#cmd-split) |
|
|
590
|
+
| `explain` | Print the compiled rig as a table. [`explain` in the CLI reference](docs/AUTHORING.md#cmd-explain) |
|
|
591
|
+
| `render` | Write PNG frames and a contact sheet. [`render` in the CLI reference](docs/AUTHORING.md#cmd-render) |
|
|
592
|
+
| `preview` | Write a playable HTML preview. [`preview` in the CLI reference](docs/AUTHORING.md#cmd-preview) |
|
|
593
|
+
| `vote` | Make a ballot and record its answer. [`vote` in the CLI reference](docs/AUTHORING.md#cmd-vote) |
|
|
594
|
+
| `pose` | Read part placements from a picture. [`pose` in the CLI reference](docs/AUTHORING.md#cmd-pose) |
|
|
595
|
+
| `chainfit` | Read occluded parts through a candidate rig. [`chainfit` in the CLI reference](docs/AUTHORING.md#cmd-chainfit) |
|
|
596
|
+
| `diff` | Compare two skeletons structurally. [`diff` in the CLI reference](docs/AUTHORING.md#cmd-diff) |
|
|
597
|
+
| `bonedist` | Measure per-bone world-transform distance. [`bonedist` in the CLI reference](docs/AUTHORING.md#cmd-bonedist) |
|
|
598
|
+
| `check` | Compare a candidate against reference pictures. [`check` in the CLI reference](docs/AUTHORING.md#cmd-check) |
|
|
599
|
+
| `bench` | Run a rung of the benchmark ladder. [`bench` in the CLI reference](docs/AUTHORING.md#cmd-bench) |
|
|
600
|
+
| `guide` | Read a named failure or guide section. [`guide` in the CLI reference](docs/AUTHORING.md#cmd-guide) |
|
|
601
|
+
| `skills install` | Install the packaged agent skills. [`skills install` in the CLI reference](docs/AUTHORING.md#cmd-skills-install) |
|
|
602
|
+
| `review` | Hand a build to the review package. [`review` in the CLI reference](docs/AUTHORING.md#cmd-review) |
|
|
603
|
+
|
|
604
|
+
### Existing skeletons and the editor
|
|
605
|
+
|
|
606
|
+
<a id="starting-from-a-skeleton-you-already-have"></a>
|
|
607
|
+
<a id="the-editor-round-trip--for-a-licence-holder-never-in-ci"></a>
|
|
608
|
+
|
|
609
|
+
For a skeleton you already have, [the ingest-and-rebuild loop](docs/INGEST.md#starting-from-a-skeleton-you-already-have)
|
|
610
|
+
turns a Spine 4.3 export into rig and motion specs, then checks that rebuilding them reproduces it.
|
|
611
|
+
For a licence holder, [the editor round trip](docs/INGEST.md#the-editor-round-trip--for-a-licence-holder-never-in-ci)
|
|
612
|
+
imports a build into the Spine editor and checks the export against that build with the gate, structural diff and rendered frames; it never runs in CI.
|
|
825
613
|
|
|
826
614
|
## Documentation
|
|
827
615
|
|
|
828
616
|
| Document | For |
|
|
829
617
|
| --- | --- |
|
|
830
|
-
| 📘 **[docs/AUTHORING.md](docs/AUTHORING.md)** | **the format guide, and the one to read before writing a spec.** Both input files field by field with a complete minimal example each, every field with its Spine meaning, the rules that decide what is emitted, the build → read the report → fix → repeat loop, the map from every named failure to the file that has to change, and the features rigc refuses by name so you do not spend a loop discovering them. It travels **inside the npm package**, at `node_modules
|
|
618
|
+
| 📘 **[docs/AUTHORING.md](docs/AUTHORING.md)** | **the format guide, and the one to read before writing a spec.** Both input files field by field with a complete minimal example each, every field with its Spine meaning, the rules that decide what is emitted, the build → read the report → fix → repeat loop, the map from every named failure to the file that has to change, and the features rigc refuses by name so you do not spend a loop discovering them. It travels **inside the npm package**, at `node_modules/@rig-c/core/docs/AUTHORING.md` |
|
|
831
619
|
| 🦴 **[docs/RIGGING.md](docs/RIGGING.md)** | **authoring the hierarchy.** Where a bone goes and why the art is pushed out on an offset, why a pivot in the wrong place looks like a search failure and what identifies one, moving a pivot and the child row that gets forgotten, gauges, siblings-not-a-chain, what a chain can reach and how many links it needs, why a local key is not a world key, duplicate art at mirrored pivots, and constraints as structure. Every section is a stumble the run records hold more than once, ranked by how often. Ships in the package too |
|
|
832
620
|
| 🎞️ **[docs/MOTION.md](docs/MOTION.md)** | **the key-pose recipe.** How to get two poses, what a pair of poses does and does not fix, the in-betweening rules and where each comes from, and how to spread candidates so a ballot informs. Ships in the package too |
|
|
833
621
|
| 🙂 **[docs/FACE.md](docs/FACE.md)** | **authoring a face.** A blink, a gaze and a 2.5D head turn on plain Spine data: the one line of yaw arithmetic every number in a turn comes from, depth as the parameter you are actually authoring, where to put a grid's columns and the angle at which any grid folds, what foreshortens and what does not, channel allocation before the first key, and the three cliffs with their angles. Also the deform audit gap, demonstrated — a folded mesh gates green — and the differential check that works today |
|
|
@@ -836,11 +624,12 @@ letting `A17` blame the editor for the harness's own doing.
|
|
|
836
624
|
| 🔬 **[docs/SPEC_COVERAGE.md](docs/SPEC_COVERAGE.md)** | **the Spine 4.3 format, field by field.** Every key the 4.3 JSON parser and atlas reader take, what each defaults to, and the parser line it comes from — the rows rigc's refusals cite by part number. Ships in the package too |
|
|
837
625
|
| 🎓 **[the benchmark dossier](https://github.com/rig-c/core/blob/main/docs/BENCHMARK.md)** | **why you can trust the output.** The yardstick, `diff` and `check` and what neither can see, the eight-rung ladder and the spineboy graduation exam, the run viewer, the 50 named assertions with their profiles, and the selftest that has watched every one of them fire. Repository material — it is not in the npm package |
|
|
838
626
|
| 📋 [LADDER.md](https://github.com/rig-c/core/blob/main/docs/LADDER.md) · [GATE.md](https://github.com/rig-c/core/blob/main/docs/GATE.md) · [PILOT.md](https://github.com/rig-c/core/blob/main/docs/PILOT.md) | the live rung ledger, the clause statements a candidate is graded against, and how to run an agent through the ladder and score what comes back |
|
|
839
|
-
| 🔬 [SURVEY_2026-08-22.md](https://github.com/rig-c/core/blob/main/docs/SURVEY_2026-08-22.md) | the survey the ladder was climbed by: rigc and the official examples as measured on 2026-08-22, and the gap list ordered by rung. A dated record, not kept current. Repository material |
|
|
840
627
|
| 🧬 [GENERATIONS.md](https://github.com/rig-c/core/blob/main/docs/GENERATIONS.md) | **Spine data from another generation.** Why a 3.8–4.2 file read as 4.3 fails in silence, the policy that follows (detect from `skeleton.spine`, never guess, play on the matching runtime), what `A16` and `ingest` do with such a file, and the editor as the migration path. Repository material |
|
|
841
628
|
| 📓 [CASES.md](https://github.com/rig-c/core/blob/main/docs/CASES.md) | **converting a Live2D model to Spine, and verifying the conversion.** The method — the source's own player headless, parts from its texture along the drawables, motion baked as deform keys, reference frames first, `check` — run once end to end on two Live2D sample models with no editor and no converter, and verified against the source's renderer and Spine's own runtime: the three instruments, the two rigc defects verifying it led to and v1.2.1 fixed, and where the method stops. Figures only — the models' licence keeps every asset out. Repository material |
|
|
842
629
|
| 🗺️ [ROADMAP.md](https://github.com/rig-c/core/blob/main/ROADMAP.md) | where this is going, and where it has been. What 1.0 had to mean before the number was claimed, and what it was claimed on — conditions rather than a feature list, because direction here comes from what users hit |
|
|
843
|
-
| 📐 [CLAUDE.md](https://github.com/rig-c/core/blob/main/CLAUDE.md) | **the doctrine** — why the validator's messages are the product, why nothing reaches disk before green, why no number is ever invented, and what a change has to keep. [
|
|
630
|
+
| 📐 [CLAUDE.md](https://github.com/rig-c/core/blob/main/CLAUDE.md) | **the doctrine** — why the validator's messages are the product, why nothing reaches disk before green, why no number is ever invented, and what a change has to keep. [the contribution guide](https://github.com/rig-c/core/blob/main/CONTRIBUTING.md) calls it worth ten minutes before a first patch. Repository material |
|
|
631
|
+
|
|
632
|
+
[Dated survey](https://github.com/rig-c/core/blob/main/docs/SURVEY_2026-08-22.md).
|
|
844
633
|
|
|
845
634
|
## Why you can trust the output
|
|
846
635
|
|
|
@@ -862,7 +651,7 @@ attributability is **measured** to be capped below the bar reads down when every
|
|
|
862
651
|
observable about it is independently verified strict. Every other rung and the
|
|
863
652
|
graduation exam pass on the clause itself. Recompiling a stored candidate reproduces its
|
|
864
653
|
record **to the digit within one gate**; across an instrument change the digits move,
|
|
865
|
-
and [
|
|
654
|
+
and [the gate re-inspection ledger](https://github.com/rig-c/core/blob/main/docs/LADDER.md) records
|
|
866
655
|
where. The standing figures quoted above are from its *gate-v2.4 re-inspection*, which
|
|
867
656
|
is the current sweep.
|
|
868
657
|
|
|
@@ -881,13 +670,13 @@ a from-zero run is a tooling-progress measurement rather than a re-climb, which
|
|
|
881
670
|
why the certification above is scoped to tool + guide + protocol. One of those
|
|
882
671
|
attempts states the residual in its own words: *"in motion it is not at editor
|
|
883
672
|
quality."* All six, with their verdicts, are in
|
|
884
|
-
[
|
|
673
|
+
[the from-zero attempt records](https://github.com/rig-c/core/blob/main/docs/LADDER.md).
|
|
885
674
|
|
|
886
675
|
The whole dossier — the yardstick, `diff` and `check` and what neither of them can
|
|
887
676
|
see, every rung, the run viewer, the 50 assertions and the selftest behind them — is
|
|
888
677
|
[docs/BENCHMARK.md](https://github.com/rig-c/core/blob/main/docs/BENCHMARK.md).
|
|
889
678
|
Live rung status is
|
|
890
|
-
[
|
|
679
|
+
[recorded in the ladder ledger](https://github.com/rig-c/core/blob/main/docs/LADDER.md).
|
|
891
680
|
|
|
892
681
|
## Contributing
|
|
893
682
|
|
|
@@ -897,5 +686,4 @@ has to clear before it lands. Releases are cut by release-please —
|
|
|
897
686
|
|
|
898
687
|
## Licence
|
|
899
688
|
|
|
900
|
-
|
|
901
|
-
requirement that this project inherits, are in [NOTICE.md](NOTICE.md).
|
|
689
|
+
See [NOTICE.md](NOTICE.md) for licensing and third-party terms.
|