# AGENTS.md — animation repo Guidance for AI agents working in `local.repo/animation`. This repo is Jeremy's animation-pipeline hub **and** the Mac↔PC bridge that carries iClone exports into `ariki-game`. iClone 8 + Video Mocap live on the PC; Blender 5, the retarget tools, and the game repo live on both machines. Deeper knowledge lives in the repo skills (`.claude/skills/`): use **`animation`** for the operator's playbook and hard-won lessons, **`animation-creation`** for authoring new clips, **`iclone-video-mocap`** for iClone-side "how do I X", and **`pose-estimation`** for video→pose extraction. `docs/dances/REGISTRY.md` is the source of truth for clip names. This file is the fast orientation; the skills and registry are authoritative. ## The batch workflow ("process the incoming animations") 1. **Pull first** — `tinqs pull` (raw `git pull` hangs on LFS in tinqs.com repos). Incoming FBX + textures + JSON land in `exchange/incoming-fbx/`. 2. **Retarget each FBX** → GLB in `exchange/converted-glb/` (command below). Every dance ships as a **pair**: also bake its loop variant with `tools/pingpong_bake.py` → `exchange/pingpong-glb/_pp.glb` (clip `PP`). 3. **Commit + push the GLBs in this repo** with `tinqs push` (self-heals auth, uploads LFS direct-to-S3). Report the commit hash. 4. **Copy GLBs into ariki-game** `assets/quaternius/dancegen/`, write one dance JSON per clip in `ariki-game/assets/dances/`. 5. **Loop QC gate** — run `loop_qc.py` on each GLB; flag anything not smooth *before* it ships. 6. **Import** so Godot generates sidecars: `bash tools/game.sh import` (ariki root). 7. **Verify** clip names, then commit in ariki-game. 8. **Launch the test bed only after asking Jeremy.** 9. Leave `exchange/` cleanup until Jeremy confirms the batch looks right in-game. ### Canonical retarget command ```bash /Applications/Blender.app/Contents/MacOS/Blender --background --python tools/cc_retarget.py -- \ --src exchange/incoming-fbx/.fbx \ --out exchange/converted-glb/.glb --name \ --target "/Users/jeremykashkett/Tinqs/local.repo/ariki-game/assets/quaternius/base-characters/Universal Base Characters[Standard]/Base Characters/Godot - UE/Superhero_Male_FullBody.gltf" ``` Blender is **5.1.2**. `--target` is **required** when running from this repo (the tool's default target path is ariki-relative and won't resolve here). Other retargeters: `mixamo_retarget.py` (Mixamo), `kevin_retarget.py` (Kevin Iglesias `B-*` rig, hardcoded target), `mocap_retarget.py` (MediaPipe pose JSON). ## Naming (see `docs/dances/REGISTRY.md`) Lowercase snake_case, matching the game's item-id convention. **New takes get a provisional `nd_##` id, never a content name** — pack `nd_08`, clip `ND08`, JSON `nd_08.json`, variants `nd_08_pp` / `ND08PP`. Only when Jeremy **adopts** a take for a ceremony is it renamed to its dance code (snake_case of the sim's `DanceType` enum + index, e.g. `war_dance_01` / `WarDance01`). Never guess the ceremony — Jeremy assigns it. Rename via `tools/rename_clip.py` + JSON + registry update. Rejected takes are **archived, never deleted**; numbers are never reused. Update the registry row on every convert/adopt/archive. - Pack name = GLB basename (lowercase); clip name = `--name` baked into the GLB. - Clip ref in JSON = `/` (e.g. `nd08/ND08`). - ClipCatalog auto-discovers anything in `dancegen/` (also `kevin/`, `mixamo/`) — no code change needed. ## Loop QC The game loops with Godot `LoopMode.Linear` (last keyframe → frame 0). A clip only looks right if pose, motion velocity, and root position are continuous across the seam — raw takes rarely are. QC every clip: ```bash /Applications/Blender.app/Contents/MacOS/Blender --background --python tools/loop_qc.py -- \ --src exchange/converted-glb/.glb # exit 0 = SMOOTH, 1 = NOT SMOOTH, 2 = error ``` Fixers (no iClone round-trip): `tools/loop_fix.py` (de-drift + trim + seam blend → `exchange/looped-glb/`) and `tools/pingpong_bake.py` (palindrome bake, seam-perfect but motion reverses at the turn — prefer for sway-heavy dances). Re-run `loop_qc.py` to confirm exit 0. Or use the `loop-qc` agent. ## Gotchas that have actually bitten - **2-frame `_TempMotion` FBX = no motion.** The tool rejects by frame count, not name; that's the guard working. Re-export from iClone with Include/Export Motion. - **A-pose arms.** CC/iClone bind in A-pose. Eyeball arm orientation in the test bed on the first clip of any new source; re-export with *Use T-Pose As Bind Pose* if wrong. - **Verify GLB `animations[].name` == JSON clip ref** before shipping — a mismatch is a silent no-play. - **Commit the `.glb.import` sidecar with the GLB** (Godot embeds `uid://` there; no separate `.uid`). GLB + `.import` + JSON go together. - **`game.sh import` warnings are pre-existing noise** — only `errors` matter. - **Green verify ≠ correct.** An agent-authored gate once passed an upside-down boat export. Always render and eyeball a new visual asset before shipping. ## Repo etiquette - **Don't touch unrelated uncommitted work.** ariki-game often has in-flight files; stage only this batch's files **by explicit path**, never `git add -A`. - Use **`tinqs push` / `tinqs pull`**, not raw git — this repo uses Git LFS for `.fbx/.glb/.mp4/.task`. Report the commit hash after pushing. - Commit co-author line: `Co-Authored-By: Claude Fable 5 `. - **ariki-game commits stay local until Jeremy asks to push** — pushing the game repo is not part of the bridge steps. - **Ask before launching the game.** `SCENE=dance_test_bed bash tools/game.sh spawn` (from ariki root); `animation_showcase` pages every clip. Never use `*RM` / `*RootMotion` variants — everything is in-place. If you pipe spawn through `tail`, the log stays 0 bytes until exit — confirm via the lease file + `pgrep`, don't assume it failed. ## Layout - `.claude/skills/` — repo skills (see intro); `.claude/agents/loop-qc.md`. - `tools/` — Blender-headless retargeters, loop tools, prop export, `rename_clip.py`. - `exchange/` — files in flight: `incoming-fbx/`, `converted-glb/`, `looped-glb/`, `pingpong-glb/`, `outgoing-props/`, `reference-video/`, `INBOX/`. - `docs/` — `dances/REGISTRY.md`, `iclone-bridge.md`. - `plans/` — pipeline design docs. `archive/` — retired takes. `devops-reports/`.