⚠️ Alpha · testnets only. ChainRender is in active alpha and deployed on testnets only — Ethereum Sepolia, the Robinhood Chain Testnet, and the Circle Arc Testnet — not on any mainnet. Contracts, addresses, and APIs may change. Do not use with real funds or production assets.
Concepts

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