Repository navigation
Epic: a AAA animation system any game can use (pose pipeline, clips, blending, IK, physical animation, ragdoll transitions) #853
Description
The owner, 2026-10-22: "we need AAA animation system with blending, good IK ... and if possible a good ragdoll and animation + ragdoll transition ... a proper motion system of a AAA+ game engine that any game can use."
This epic replaces the procedural-ragdoll-first direction of #790 and #572. It is the queue for all motion work from here on.
Why
Since early October the work built the top layer first: balance, staggers, catch steps, and get-ups and sits keyed in code. It was tuned tick by tick on a box man whose walk our own code generates. The layers every AAA engine stands on were never built. An audit of main 103e477 (13 modules, 20,601 lines) found:
- No pose pipeline. The scene graph is the shared pose. figure, locomotion, feet, lookat, idle, physics and motion all write the same bones in the pose phase, and detect each other by exact float equality. The result depends on attach order.
- No real blending. Clips are one per node, found by string prefix, with keys in heap lists. "Nothing is averaged between two poses" (figure/module.ae:30): there are no cross-fades, blend spaces, sync, state machine or root motion.
- Four foot systems. Three foot-contact heuristics and two foot locks, each with its own thresholds.
- Motion matching that can't turn. It sees every clip as walking straight ahead (matching/module.ae:559).
- A fixed ragdoll. A 12-bone reference human with no hands or head, held up by a 1,200 N·m pelvis-to-world anchor (motion/module.ae:129). Get-up, sit and kneel are keyframes generated in code.
- No retargeting, and skinning capped at 96 bones.
Worth keeping: inertialization (figure), the two-bone IK solver, the matching search (2,000 figures in 0.54 ms), the aephysics ragdoll with motors and muscles, and the GPU crowd banks.
The target: one pose pipeline, one writer
Every character evaluates one pipeline per frame into pose buffers, and only the pipeline writes the skeleton. Games set parameters (speed, direction, aim, a state, a hit) and never write bones.
- L0, skeleton, pose and retarget: a skeleton asset with a humanoid map to one canonical rig (the UE5 mannequin's names), up to 256 bones; per-bone local transforms in flat arrays; chain retargeting in the style of Unreal's IK Retargeter.
- L1, clips: skeleton-indexed tracks with a cursor, a root track for root motion, events, and sync and contact markers. Compression later (ACL style).
- L2, blending and graph: clip player; blend spaces 1D and 2D with sync; a state machine with inertialized transitions (Bollo, GDC 2018); layers with per-bone masks; additive and aim offsets; motion matching as a node (Clavet, GDC 2016); pose snapshot.
- L3, IK and constraints: two-bone with limits and soft reach, FABRIK, full-body IK, foot placement from contact markers, look and aim, hand IK on props.
- L4, physical animation: a physics asset per skeleton (with hands and head); each body kinematic, motor-driven toward the animated pose, or simulated; a blend weight per body, with profiles (Unreal Physical Animation, PuppetMaster pin and muscle weights).
- L5, ragdoll transitions:
- go limp with the animation's velocities;
- detect rest;
- snapshot the pose;
- choose a get-up clip by orientation and pose distance;
- place the capsule under the body;
- inertialize back.
- Partial ragdoll for hits.
- L6, behaviours (optional, last): balance, catch steps and staggers, Euphoria style, as nodes driving L4. Today's motion work moves here.
Per frame: game parameters, then L2 samples L1 into poses, then root motion moves the capsule, then L3 IK in model space, then L4 blends with the bodies, then the skeleton, then skinning.
Test figure and clips
Quality is judged on real authored and captured motion. The box man stays only as a smoke test.
- Figure: the Quaternius mannequin, male and female, on the UE5 mannequin skeleton (65 joints with fingers and toes), CC0.
- Clips:
- UAL2 Standard: 43 clips on the same rig, CC0, LayToIdle among them.
- UAL1 Standard: 46 clips on a Rigify-named rig, CC0. They include walk, jog, sprint, crouch, sit enter/idle/exit, hits, death, roll and pistol.
- 100STYLE (Ian Mason, CC BY 4.0): captured locomotion with walk, run, backwards, sidesteps, idle and transitions, in 100 styles at 60 fps, retargeted in M1.
The CC0 files are committed under tests/fixtures/people with their licenses, an exception to #342's "importers, not assets" for test fixtures only.
Milestones
Each one gets a design note on its issue, then code, then a recorded demo on the real figure, with CI tests that hold quality bars.
- M0 ground truth: a real human in CI (Quaternius mannequins, UAL clips), motion metrics, a viewer #854 M0 ground truth: the real figure in CI, the metrics, the viewer
- M1 skeleton, pose, clips, retargeting and root motion (L0, L1) #855 M1 skeleton, clips, retargeting, root motion (L0, L1)
- M2 blending and the animation graph: blend spaces, state machine, layers, additive, matching node (L2) #856 M2 blending and the graph (L2)
- M3 IK and constraints: two-bone with limits, FABRIK, full-body IK, foot placement, aim, hand IK (L3) #857 M3 IK and constraints (L3)
- M4 physics asset and physical animation with per-body weights (L4) #858 M4 physics asset and physical animation (L4)
- M5 ragdoll and get-up from a pose snapshot into a matched clip (L5) #859 M5 ragdoll and get-up (L5)
- M6 migration onto the animation pipeline; old writers retired #860 M6 migration: plaza, showcase and Siltreach on the new API; old paths retired
- M7 behaviours on physical animation, optional (L6) #861 M7 behaviours, optional (L6)
- M8 crowds and animation LOD #862 M8 crowds and animation LOD
What happens to today's code
New modules are built beside the old ones. The old ones are frozen (bug fixes only) and retired at M6.
| today | goes to |
|---|---|
| figure's inertialization | L2 transitions, and the hand-back from physics |
| ik.solve_two_bone | L3, with limits and soft reach; motion's private copy goes |
| matching search and spring | L2 node, with real trajectory and facing features |
| feet ground traces | L3 foot placement on contact markers; locomotion's second lock goes |
| lookat, idle | an L3 aim constraint and an L2 additive node |
| physics ragdoll and muscles | L4 drive layer; more bones; no world anchor by default |
| crowd, horde, handover | M8 |
| motion balance, staggers, falls, crawl, writhe | frozen; L6 in M7 |
| motion keyed get-up, sit, kneel, lie | retired for clips, IK and transitions |
| anim per-node clips | retired for skeleton-indexed clips |
How the work runs
- Bottom up, one milestone at a time. No tuning on a layer whose foundation is missing.
- Tests hold quality bars (skating, pops against the clip's own fastest, IK error, penetration), not the numbers of past incidents.
- Every layer is engine-level and clip-agnostic, documented, with a measured cost per character.
- Siltreach follows the engine's API. When it calls something in a way the engine does not intend, it is told how to call it.
Activity
nicolas-maman commentedon Oct 22, 2026
Handoff, 2026-10-22: work stops here for now, and a later session picks it up from these issues.
( ulimit -v 2000000; ... ), with BUILD_PAR=2;