# Skeletal Animation (rig + keyframe clips)

Give a generated mark, mascot, or creature **motion** — as on-chain **data**, not an imported object. A skeletal
animation is a **rig** (a kinematic tree of joints) plus **clips** (per-joint keyframes). A forward-kinematics (FK)
player draws it as an SVG "vector puppet" with pure math — the deterministic **floor** (Grade A, no GPU). An optional
GPU-skinned mesh is an **enhancement** that fails closed to that floor. It's the `brand.ts` principle applied to motion:
*a clip is a seed, not a program.*

## How it works

1. **Author as data.** The builder (or the AI) emits a rig + clips — `walk`, `idle`, `wave`, … — as a compact `CRCL`
   pack. Motion is deterministic, content-addressed data.
2. **Store like a library.** The pack is stored with ChainRender's existing ownerless library mechanism — split into
   `SourceStore` parts and registered in the content-addressed `DependencyRegistry`, hash-verified end-to-end. The
   **exact** path p5.js/three.js use, with one twist: a clip library is stored **raw** (not gzipped) so the resolver
   can reassemble and slice it *on-chain* (the EVM can't gunzip, and at a few KB there's nothing to compress). Per-part
   size comes from `ChainProfile.maxChunkPayload()` (never a hardcoded number), so it tracks the chain's contract-size
   ceiling.
3. **Bind a clip.** A component binds one clip via the `clip-slice` resolver (`registry`, pinned `depHash`, `index`).
   The client FK player (`@chainrender/client` → `chainc/skeletalanim.ts`) decodes it and plays the SVG puppet floor.

## Robust, modular, expandable

- **Modular** — a per-clip directory means every clip is individually addressable; multiple **heterogeneous rigs**
  (humanoid, quadruped, avian…) live in one pack.
- **Expandable** — one part holds hundreds of clips, and a library spans as many parts as needed; a bigger or new
  library is simply a **new** content-addressed Dependency (additive, nothing edited). Old pins work forever.
- **Robust** — versioned (`CRCL` + version byte, fail-closed on unknown), content-addressed, ownerless, hash-verified.

## The honest floor + the GPU enhancement

The clip bytes + FK player are the floor: **reproducible math, Grade A.** The optional GPU enhancement
(`skeletalanim-three.ts`) binds the **same** rig/clip and plays the **same** FK as three.js meshes — it is the floor
rendered richer, never different motion — and it **fails closed**: no WebGL2/three (or any error) → the exact SVG
puppet floor. three.js is injected (the on-chain hash-verified library), never npm-imported. There is **no neural
model, no diffusion, no dataset, and no imported `.glb`** — motion is a seed you (or the AI) author. Marketing ≤ code.

Five reference morphologies ship as data — **humanoid, quadruped, avian, insectoid, marine** — proving one
representation animates many skeletons; adding another is just appending a rig.

## For developers
`chainc/skeletalanim.ts`: `encodePack`/`decodePack`, `evalPose` (FK), `renderPuppetSVG`, `buildReferenceLibrary`,
`packReport`. On-chain: `ClipLibraryResolver` (`clip-count`, `clip-slice`) over a caller-supplied `DependencyRegistry`.
Deploy a library with `scripts/pack-clip-library.ts`.

## Related
- **[The Floor](./the-floor.md)** · **[Visual & Media](./visual-media.md)** · **[Brand & Identity](../about/brand.md)**
