spine-rigc 0.8.0 β 0.9.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 +125 -716
- package/cli.ts +118 -7
- package/docs/AUTHORING.md +524 -97
- package/docs/SPEC_COVERAGE.md +27 -12
- package/package.json +4 -1
- package/src/check.ts +552 -29
- package/src/compile.ts +674 -48
- package/src/mesh.ts +832 -3
- package/src/render.ts +300 -7
- package/src/rig.ts +448 -20
- package/src/transform.ts +13 -0
- package/src/types.ts +82 -7
- package/src/validate.ts +347 -38
- package/tools/contact.ts +126 -0
- package/tools/measure_contact_depth.ts +105 -0
- package/tools/png_probe.mjs +72 -0
package/docs/SPEC_COVERAGE.md
CHANGED
|
@@ -10,7 +10,7 @@ Reproduce the measurements with `bun run fetch-examples && bun run bench:usage`
|
|
|
10
10
|
|
|
11
11
|
> πΌ **This note is dated and does not move; the measurements below are the corpus as it
|
|
12
12
|
> stood on 2026-08-22 and stay as written. Its statements about what rigc *does* have gone
|
|
13
|
-
> stale in
|
|
13
|
+
> stale in six places, and the live ledger is [LADDER.md](https://github.com/firejune/rigc/blob/main/docs/LADDER.md):**
|
|
14
14
|
>
|
|
15
15
|
> - **B2 is fixed** β A16 accepts `4.3`, `4.3.N` and `4.3.N-<suffix>`, so all twelve example
|
|
16
16
|
> exports pass it.
|
|
@@ -19,6 +19,12 @@ Reproduce the measurements with `bun run fetch-examples && bun run bench:usage`
|
|
|
19
19
|
> renderer-policy assertions of Β§2.2 no longer apply to foreign data, and no longer apply
|
|
20
20
|
> unasked. That closes the validator half of B3; the emitter half (no packer, no atlas
|
|
21
21
|
> importer) is untouched.
|
|
22
|
+
> - **Part 4-2's β rows for `path`, `slider` and per-skin members are gone (issues #2, #7)** β
|
|
23
|
+
> rigc emits path attachments and path constraints, sliders in both of their models, per-skin
|
|
24
|
+
> `bones` and constraint lists, and the `path` / `slider` timeline groups. Three assertions came
|
|
25
|
+
> with them (A36, A37, A38). The **corpus** measurements in part 3 are untouched and still true:
|
|
26
|
+
> none of these features appears in any of the twelve example files, which is why they were
|
|
27
|
+
> off the ladder and why nothing in it moved.
|
|
22
28
|
> - **`walkTimelines` reaches all eleven groups** β Β§2.3 item 1 and Β§4.3 item 4 are done, so
|
|
23
29
|
> A05 is no longer blind to `ik` / `transform` / `path` / `slider` / `drawOrder` /
|
|
24
30
|
> `drawOrderFolder` / `events`.
|
|
@@ -561,8 +567,12 @@ Legend: β
emits Β· π‘ partial Β· β not emitted Β· π« deliberately exclud
|
|
|
561
567
|
| `visible` | β |
|
|
562
568
|
| draw order = slots array order | β
, and **A26_SLOT_DRAW_ORDER** pins it to the archetype's `slotOrder` table |
|
|
563
569
|
|
|
564
|
-
**Skins** β β
|
|
565
|
-
|
|
570
|
+
**Skins** β β
named skins, each `{ name, bones?, ik?, transform?, path?, physics?, slider?, attachments }`
|
|
571
|
+
in the parser's own reading order; `default` is always emitted even when empty. β
per-skin `bones` and
|
|
572
|
+
per-type constraint lists (issue #7), which a rig spec writes in a skin entry's long form and rigc pairs
|
|
573
|
+
with the member's own `skin: true` β either half alone is refused, because `Skeleton.updateCache` starts a
|
|
574
|
+
`skinRequired` object inactive and activates only what the applied skin names (**A38_SKIN_MEMBERS_ARE_SKIN_REQUIRED**).
|
|
575
|
+
β `color` (JSON-inexpressible).
|
|
566
576
|
|
|
567
577
|
**Attachments**
|
|
568
578
|
|
|
@@ -572,14 +582,18 @@ Legend: β
emits Β· π‘ partial Β· β not emitted Β· π« deliberately exclud
|
|
|
572
582
|
| `mesh` | π‘ | emits `type`, `uvs`, `triangles`, `vertices` (**weighted encoding only**), `hull`, `width`, `height`, `edges` (`compile.ts:1343`, and part 4's rung-6 entry measures it byte-identical to the reference), `path`, `color`. β `sequence`. Unweighted meshes are π« **A20_MESH_WEIGHTS_COHERENT** (`validate.ts:430-433`) |
|
|
573
583
|
| `linkedmesh` | β | deliberately deferred β never appears in the corpus (part 3-1) |
|
|
574
584
|
| `boundingbox` | β
| `vertexCount` (required and cross-checked), `vertices` **or** by-name `weights`, `color`. **A33_VERTEX_ATTACHMENT_GEOMETRY** |
|
|
575
|
-
| `path` |
|
|
585
|
+
| `path` | β
| `vertexCount` (required, and checked as a multiple of 3 β the parser's own `vertexCount / 3` takes a fractional size in silence), `vertices` **or** by-name `weights`, `closed`, `constantSpeed`, `color`, and a **measured** `lengths`: the cumulative setup arc length of each curve, taken through each influence's own bone, refused if authored. **A33_VERTEX_ATTACHMENT_GEOMETRY** re-checks the structure and the array's monotonicity. β a `deform` timeline on one |
|
|
576
586
|
| `point` | β | deliberately deferred β never appears in the corpus (part 3-1) |
|
|
577
587
|
| `clipping` | β
under `--profile spine` Β· π« under `spine-html` | `end` (refused when it names no slot), `convex`, `inverse`, `vertexCount`, geometry, `color`. **A33**, and **A11_NO_CLIPPING_ATTACHMENTS** is the renderer-profile refusal |
|
|
578
588
|
| `sequence` block | β | |
|
|
579
589
|
|
|
580
|
-
Mesh geometry is generated by exactly
|
|
581
|
-
(three concentric rings + hub, outer two pinned)
|
|
582
|
-
chain)
|
|
590
|
+
Mesh geometry is generated by exactly three procedural generators (`mesh.ts`): `buildRingMesh`
|
|
591
|
+
(three concentric rings + hub, outer two pinned), `buildRibbonMesh` (a two-wide strip along a bone
|
|
592
|
+
chain) and `buildContourMesh` (marching-squares trace of the part's own alpha β Douglas-Peucker β
|
|
593
|
+
mitred outset β ear clipping, every vertex pinned to the slot bone). The triangulator takes a
|
|
594
|
+
**simple** polygon only: holes are enclosed rather than cut out, and a self-intersecting or
|
|
595
|
+
diagonally pinched silhouette is refused by name (AUTHORING Β§3.4). There is still no importer for
|
|
596
|
+
editor-made meshes β those arrive as authored `uvs`/`triangles`/`weights`.
|
|
583
597
|
|
|
584
598
|
**Constraints** (`compile.ts:526-568`)
|
|
585
599
|
|
|
@@ -588,8 +602,8 @@ chain). There is **no triangulator for arbitrary art** and no importer for edito
|
|
|
588
602
|
| `physics` | β
β full field set: `bone`, the five components `x`/`y`/`rotate`/`scaleX`/`shearX`, `scaleY` (ScaleYMode), `inertia`/`strength`/`damping`/`mass`/`wind`/`gravity`/`mix`/`fps`/`limit`, the seven `*Global` flags and `skin` (`compile.ts:1522-1548`). A field the rig spec does not give is **omitted**, never guessed (`compile.ts:1463-1468`), so the parser's own default stands. The motion spec's `physics` tuning table is the second path into this same array and is narrower: no `scaleY`, no `*Global`, no `skin`, and it drops a value that equals the parser default even when the table gives it (`compile.ts:758-761`) |
|
|
589
603
|
| `ik` | β
β `bones`, `target`, `scaleY`/`mix`/`softness`/`bendPositive`/`compress`/`stretch`/`skin` (`compile.ts:1425-1430`, landed in `c5eda3b`) |
|
|
590
604
|
| `transform` | β
β `bones`, `source`, the 4.3 `properties{fromβto}` model, and the full field set (`compile.ts:1431-1462`, landed in `c5eda3b`) |
|
|
591
|
-
| `path` |
|
|
592
|
-
| `slider` |
|
|
605
|
+
| `path` | β
β `bones`, `slot`, `positionMode`/`spacingMode`/`rotateMode` (checked against the enum names `Utils.enumValue` can resolve, where only the first letter's case is free), `rotation`, `position`, `spacing`, `mixRotate`/`mixX`/`mixY`, `skin`. The slot must carry a path attachment in some skin: `PathConstraint.update` returns on its first line otherwise, so the constraint loads and moves nothing (**A36_PATH_CONSTRAINT_EFFECTIVE**) |
|
|
606
|
+
| `slider` | β
β `animation` (an animation the MOTION spec declares; the parser resolves it in a second pass and throws on a miss), `mix`, `additive`, `loop`, and one of the two models `bone` switches between: `bone` + `property`/`from`/`to`/`scale`/`max`/`local`, or the bone-less `time`. The losing model's fields are refused rather than emitted, because the parser reads each set only inside its own branch (**A37_SLIDER_CONSTRAINT_EFFECTIVE** covers the rest) |
|
|
593
607
|
| flat `constraints[]` shape | β
β and **A01_NO_LEGACY_TOPLEVEL_CONSTRAINT_ARRAYS** actively rejects the 4.1/4.2 shape (`validate.ts:225-235`), which is the machine form of case 6a |
|
|
594
608
|
|
|
595
609
|
**Timelines** (`compile.ts:570-631`, `:877-936`, `:981-1041`)
|
|
@@ -604,7 +618,8 @@ chain). There is **no triangulator for arbitrary art** and no importer for edito
|
|
|
604
618
|
| `slots.rgba2`, `rgb2` | π« **A12_NO_DARK_COLOR** (`validate.ts:257-261`) |
|
|
605
619
|
| `physics.mix`, `physics.reset` | β
(`PHYSICS_TRACKS`, `compile.ts:87-90`) |
|
|
606
620
|
| `physics.inertia/strength/damping/mass/wind/gravity` | β |
|
|
607
|
-
| `ik`, `transform
|
|
621
|
+
| `ik`, `transform` | β
β one unnamed timeline per constraint, keyed by the motion spec's `ik` / `transform` arrays |
|
|
622
|
+
| `path.position/spacing/mix`, `slider.time/mix` | β
(`PATH_TRACKS` / `SLIDER_TRACKS`) β authored as `tracks` entries naming `path` or `slider`, the same shape as `physics`, since both groups put named timelines under a constraint name. `path.mix` is one timeline of three channels |
|
|
608
623
|
| `attachments.<skin>.β¦deform` | β (validator knows it: 1 channel, `validate.ts:104-107`) |
|
|
609
624
|
| `attachments.β¦sequence` | β |
|
|
610
625
|
| `drawOrder` | β
β the motion spec's per-animation `drawOrder` array of `{ t, offsets: [{ slot, offset }] }` (`compile.ts:823`, `:850`, `compileDrawOrder` `:1918-1970`). A key with no `offsets`, and a key with an empty one, both emit the parser's reset-to-setup encoding, so two spellings cannot make two files. An unknown slot, a slot offset twice in one key, a non-whole offset and a landing outside the emitted slots are each refused by name, and **A31_DRAW_ORDER_OFFSETS_RESOLVE** re-checks the emitted file |
|
|
@@ -663,7 +678,7 @@ This is the split Part 4(c) needs. **Spine-validity** = the file is wrong for an
|
|
|
663
678
|
| `A14_NO_FULL_FRAME_MESH` | **renderer-profile** | a mesh spanning the whole stage |
|
|
664
679
|
| `A19_OVERLAY_PNGS_HAVE_ALPHA` | **renderer-profile** | an overlay page that can never be transparent β no alpha channel and no `tRNS` chunk |
|
|
665
680
|
| `A20_MESH_WEIGHTS_COHERENT` | **renderer-profile / archetype** | **unweighted meshes**, weights not summing to 1, out-of-range bone indices |
|
|
666
|
-
| `A21_MESH_RIM_PINNED` | archetype | ring/ribbon rim not pinned |
|
|
681
|
+
| `A21_MESH_RIM_PINNED` | archetype | ring/ribbon/contour rim not pinned |
|
|
667
682
|
| `A22_MESH_UVS_IN_UNIT_RANGE` | validity-ish | UVs outside 0..1 |
|
|
668
683
|
| `A15_IDLE_NO_MESH_BONE_KEYS` | archetype | `idle` keying a mesh-driving bone |
|
|
669
684
|
| `A23_PHYSICS_CONSTRAINT_EFFECTIVE` | validity-ish | a physics constraint that parses and does nothing |
|
|
@@ -1058,7 +1073,7 @@ rung 6. `pro-pendulum` is region-only and is effectively a rung-3-class file.
|
|
|
1058
1073
|
| Bounding box | **spineboy** | `spineboy-ess` and `-pro` (1 each) |
|
|
1059
1074
|
| Events | **spineboy** | both spineboy files (1 def, 5 keys) |
|
|
1060
1075
|
| Unweighted meshes | **spineboy** | `spineboy-pro` (2) |
|
|
1061
|
-
| **Skins** | **never** | π΅ **no example in the ladder uses a non-default skin.** Every one of the 12 files has exactly one skin, named `default`. Named skins, per-skin bones, and per-skin constraint lists are **not on this ladder at all** and
|
|
1076
|
+
| **Skins** | **never** | π΅ **no example in the ladder uses a non-default skin.** Every one of the 12 files has exactly one skin, named `default`. Named skins, per-skin bones, and per-skin constraint lists are **not on this ladder at all** and were scheduled by some other justification: they landed with issues #2 and #7, off the ladder, and no rung's status depends on them. |
|
|
1062
1077
|
| Path constraints, sliders, sequences, linked meshes, dark colour, `drawOrderFolder` | **never** | absent from the entire corpus |
|
|
1063
1078
|
|
|
1064
1079
|
### 4.3 (c) The validator changes, consolidated
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spine-rigc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Rig compiler for Spine β declarative rig specs in, Spine 4.3 skeleton data out, verified by a spine-core round-trip. Built so AI agents can author rigs and check their own work; the output imports into the Spine editor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
"src",
|
|
37
37
|
"tools/plate.ts",
|
|
38
38
|
"tools/font5x7.ts",
|
|
39
|
+
"tools/contact.ts",
|
|
40
|
+
"tools/png_probe.mjs",
|
|
41
|
+
"tools/measure_contact_depth.ts",
|
|
39
42
|
"docs/AUTHORING.md",
|
|
40
43
|
"docs/SPEC_COVERAGE.md",
|
|
41
44
|
"docs/PROMPTING.md",
|