# Handoff: runtime FLAT hand pose in ariki-game (2026-08-17) > **STATUS 2026-08-17 (session "flatpose"): DONE — all 3 acceptance criteria verified.** > Implementation (uncommitted, in ariki-game): `src/Animation/HandPoseLayer.cs` > (SkeletonModifier3D, per-hand 0..1 slerp blend, Mako/MixamoSkin excluded, missing bones > skipped), PlayerController wiring (`SetFlatHands`, attached to `AnimatedSkeleton`), > DanceTeam/DancerRig plumbing, bed hotkeys **H** (toggle, active team) + **J** (hand cam), > HUD `hands=FLAT` flag, pose copied to `assets/quaternius/hand-poses/pose_flat.json`. > Verified in the dance bed (agent API screenshots): exp01 body fingers visibly flatten > mid-dance with no spikes; shipped mitt body = silent no-op, zero console errors; nothing > committed. Test body copy `derived-bodies/lena_leafbikini_quatskin_fingers_glb_exp01.glb` > is untracked/test-only — do not ship it from here. One Vulkan device-lost crash occurred > during testing (RX 5700 XT TDR) — unrelated to this code, relaunch cured it. **Goal:** the female player character can hold a FLAT hand (fingers straight, together) at runtime, applied as a layer on top of any playing animation. Flat only — fist and grip are blocked on a weight repair that is running in a parallel lane (see "Scope fence" below). ## Why this works at all - ~70–100% of finger tracks in the shipped dance clips are frozen at rest, so a per-frame finger override loses nothing from the animations. - Hand poses were harvested from the Kevin packs into `animation/hand-poses/`: `pose_flat.json`, `pose_relaxed.json`, `pose_fist.json`, `pose_grip.json`. - Format: `{"bones": {"": [x, y, z, w], ...}}` — glTF node-local quaternions on the **canonical Quaternius skeleton**, which is exactly Godot bone-pose space for these bodies. Apply directly: `skeleton.SetBonePoseRotation(skeleton.FindBone(name), new Quaternion(x, y, z, w))`. No rest-relative correction on canonical rigs (that hack is only for Mako, out of scope here). - 40 bones per pose file, including `*_04_leaf_*` tip bones. Some bodies lack the leaf bones — **skip bones that FindBone returns -1 for**, never error. ## Body situation (the trap that makes testing confusing) - The SHIPPED female body `assets/quaternius/derived-bodies/Ariki_Female_QuatSkin.glb` has **zero finger weights** (the converter deliberately folds fingers into the hand bone — "rigid mitt"). Applying the pose to her is correct code but shows NOTHING. - A finger-weighted candidate exists and the flat pose is validated on it (max displacement 1.8 cm, clean QA renders in `animation/characters/work/lena_leafbikini/v02/review/`): `animation/characters/work/lena_leafbikini/v02/lena_leafbikini_quatskin_fingers_glb_exp01.glb` Use it as the TEST body. - Mako (`Ariki_Male_Mako.glb`) has corrupt cross-hand finger weights — do NOT enable the pose layer on him; a finger curl throws verts metres. Female/canonical only. ## Implementation pointers - Pattern to copy: `ariki-game/src/Animation/PlayerIKRig.cs` — post-animation bone modification. The hand-pose layer is the same idea: after the AnimationTree/Player updates, write the pose quats onto the finger bones each frame while the layer is active. Keep an on/off (and ideally a blend weight 0..1 slerping from the animated pose) per hand. - Test bed: `ariki-game/src/Testing/Dance/DanceTestBed.cs`. `DANCE_BODY_GLB` env var swaps the bed's body — point it at the exp01 GLB above (see comment near line 82). Run with `MOCK_ONLY=1`. - ENGINE TRAP: the S3 engine is v1.0.0 (Godot 4.6.2) and the repo is on SDK 4.7. If you locally downgrade `csproj`/`project.godot` to launch, **NEVER commit those lines**. ## Verification tools (animation repo) - `tools/handpose_bake_preview.py body.glb pose.json out.glb` — bakes a pose into a GLB's rest rotations (what the runtime layer should reproduce). - `tools/skin_displacement_check.py posed.glb original.glb` — Godot-exact LBS math; flat on exp01 reads max 1.8 cm / median 0.27 cm. Meter-scale numbers = broken. - `tools/handpose_skin_to_obj.py posed.glb l|r out.obj` + `tools/handpose_render_objs.py` (blender --background) — the only honest VISUAL check. **Do not judge by importing a baked-pose GLB into Blender and rendering: the importer ignores the rest-vs-bind rewrite and draws false shards.** ## Scope fence - Do not swap or re-export any shipped body (`Ariki_Female_QuatSkin.glb`, `characters/female/lena_leafbikini_base_v01/` is frozen). The finger-weighted body ships from the parallel weight-repair lane, not from this task. - Do not touch `ariki-game/tools/make_lena_fullres_quatskin.py`; its `LENA_RIGID_FINGERS` default must stay `"1"`. - Flat pose only. Fist/grip activation waits for the repaired weights. ## Acceptance 1. In the dance test bed with `DANCE_BODY_GLB` = exp01, toggling the layer while a dance plays visibly straightens/flattens the fingers, no vertex spikes, and the rest of the animation is unaffected. 2. On the shipped mitt-handed body the layer is a silent no-op (no errors). 3. Nothing committed in either repo changes any shipped asset or engine version.