Files
jeremy e08ad2f3e9 docs(animations): naming conventions, wiring audit, unwired catalogue + claude-desktop context brief
NAMING.md/AUDIT.md/UNWIRED.md are the conventions-doc pivot after the
mass-rename was killed; committing so the bridge repo tree is clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 16:07:41 -07:00

9.3 KiB

Animation Naming Conventions

Decision (Ozan, 2026-07-24): do NOT mass-rename existing animations. Renaming clip strings inside purchased vendor packs (Quaternius UAL, Kevin Iglesias) breaks the vendor re-download/upgrade path, forces a risky full-pack re-export through Blender, and buys only cosmetic consistency. Instead: document the conventions that already exist, keep each source's native names, and name new files to conform going forward. Provenance and status are tracked in the registry catalogue, not by renaming.

This file is the source of truth for how animations are named. .agents/wiki/dances/REGISTRY.md remains the source of truth for the dance/boat clip roster.


1. The three name-spaces

Animation naming spans three independent layers. They are joined by explicit mappings, not by making the strings equal. You almost never need them to match.

Layer What it is Case style Example Who reads it
Pack file the .glb basename on disk lowercase snake_case kevin_male_movement.glb, UAL1.glb, war_dance_01.glb filesystem, ClipCatalog (discovers by basename)
Clip name the animation string baked inside the GLB source-dependent (see §3) Swim01_Forward, TreeChopping_Loop, WarDance01 GLB metadata, dance JSON clip field, SetupAnimations() mapping
Game key the logical id the game code plays lowercase snake_case swim, chop, war_dance_01 PlayerAnimController, PlayerAnimationLogic, AnimationTree, AI, dance JSON name

Key fact: the game controller speaks only game keys — it never references a raw clip name. The single place the clip-name layer meets the game-key layer is the mapping arrays in ariki-game/src/Viewer/PlayerController.cs → SetupAnimations() (clip name → game key). That indirection is why we can keep vendor clip names untouched: the game key is our stable API, the vendor clip name is just what that key happens to bind to.


2. Game keys — the one namespace we fully own

Game keys are the cleanest, most important naming layer, because they are the game's actual vocabulary and we control them 100%. Rules:

  • lowercase snake_case, matching the game's item-id convention (ceremonial_garb, dance_platform).
  • Semantic, not source-derived. Name the action, never the vendor clip it currently points at: chop, not treechopping. If we later swap the underlying clip, the key is stable.
  • Directional suffixes use short forms: _fwd, _bwd, _l, _r, and diagonals _fwd_l, _fwd_r, _bwd_l, _bwd_r.
  • State suffixes: _idle, _enter, _exit, _start, _land.
  • Examples in use: idle, walk, run, sprint, crouch_idle, crouch_walk, swim, swim_idle, swim_up, swim_down, swim_strafe_left, chop, mine, fish, gathering, farm, carry, eat, sleep, skin, pray, weapon_attack, shield_block, turn90_l.

When you wire a new animation, the game key is what you invent — pick a semantic snake_case key and add the clip → key row in SetupAnimations(). The clip name stays whatever the source produced.


3. Current clip-name conventions, by source

We keep each source's native convention. Recognise them; don't fight them.

3a. Quaternius UAL (anim/UAL1.glb, anim/UAL2.glb) — VENDOR, keep as-is

  • PascalCase, _-separated. Climb_Idle_Loop, Jog_Fwd_Loop, TreeChopping_Loop.
  • Looping clips end _Loop (or _Idle_Loop).
  • Directions: _Fwd / _Bwd / _Left / _Right; diagonals _Fwd_L / _Fwd_R / _Bwd_L / _Bwd_R.
  • Transitions: _Enter / _Exit; jumps _Start / _Land; variants numbered 01, 02.
  • Root-motion twins carry _RM (in the *_RM.glb packs; game loads non-RM only).

3b. Kevin Iglesias (kevin/kevin_{male,female}_*.glb) — VENDOR, keep as-is

  • PascalCase, action + zero-padded number, then full-word direction. Walk01_ForwardLeft, Swim01_Forward, Crouch01_Walk_BackwardRight.
  • Looping clips end _Loop; handedness uses _L / _R (SkinningGround01_R_Loop, ThrowSpear02_R); root-motion uses a trailing RM (Walk01_ForwardRM).
  • Packs are split by theme: combat, movement, work, social, idles, misc.

3c. Our authored clips — the convention WE apply to new content

This is the part you actively control. Two sub-cases:

Dances & boat actions — follow .agents/wiki/dances/REGISTRY.md exactly:

  • New dance take → provisional id nd_## (never a content-guessed name): pack/file nd_08, clip ND08, dance JSON nd_08.json. Variants keep the base id + suffix: nd_08_pp / ND08PP.
  • On adoption to a ceremony → dance code = snake_case of the sim DanceType enum + index: pack war_dance_01, clip WarDance01 (PascalCase, matches the enum), JSON war_dance_01.json.
  • Loop-pair rule: every adopted dance ships base + ping-pong _pp variant (war_dance_01_pp / WarDance01PP), baked with tools/pingpong_bake.py, must pass loop_qc.py.
  • Boat actions get direct boat_* codes (no provisional stage): boat_dive, boat_row_loop, clip BoatDive / BoatRowLoop.

Other authored one-offs (Mixamo, iClone mocap, composites):

  • Pack file = lowercase snake_case: run_to_dive.glb, northern_soul.glb, Run_Punch.glb.
  • Clip name = PascalCase of the file: RunToDive, NorthernSoulFloorCombo, Run_Punch.
  • Game key = semantic snake_case: run_to_dive, dance_soul, run_punch.

The general rule for a NEW authored clip

pack file:  <category>_<descriptor>_<##>.glb     (lowercase snake_case)   e.g. work_haul_01.glb
clip name:  PascalCase of the file                                         e.g. WorkHaul01
game key:   <semantic snake_case>                                          e.g. haul

Categories (closed set): loco, swim, work, combat, dance, boat, emote, misc. Variants numbered, never reused. Looping authored clips ship a _pp (or _loop) variant that passes loop_qc.py.


4. Suffix & direction quick-reference

Meaning Game key (ours) UAL (vendor) Kevin (vendor)
looping _idle / (implicit) _Loop _Loop
forward / back _fwd / _bwd _Fwd / _Bwd _Forward / _Backward
left / right _l / _r _Left / _Right _Left / _Right
diagonal _fwd_l _Fwd_L _ForwardLeft
transition _enter / _exit _Enter / _Exit
ping-pong loop _pp
root motion (not loaded) _RM RM
variant index _01 01 01

5. Decision tree — naming a future file

  1. Is it a vendor clip (UAL/Kevin/other purchased pack)? → Keep the vendor's clip name and pack layout untouched. To use it, add a clip → game key row in SetupAnimations() and a catalogue entry in the registry. Do not re-export or rename.
  2. Is it a dance or boat action? → Follow .agents/wiki/dances/REGISTRY.md (nd_## → ceremony code; boat boat_*; loop-pair rule).
  3. Is it another clip we author (Mixamo/iClone/composite)? → Apply the §3c general rule: snake_case file, PascalCase clip, semantic snake_case game key, closed-set category, _pp loop.
  4. In all cases: add/update the registry row (§6) in the same commit, and — if the game plays it — the SetupAnimations() mapping.

6. The registry catalogue (provenance & status — no renaming)

The catalogue records, per clip we care about, the fields Jeremy asked for — without changing any names:

canonical_id (our snake_case handle) · clip (actual name in GLB, vendor or ours) · pack · category · game_keys · source · created · method · status (approved / wip / not_started) · notes.

  • For vendor clips, canonical_id is just our stable handle for the catalogue; clip stays the vendor string. Nothing on disk changes.
  • not_started rows capture animations the game needs but doesn't have yet (the 13 dance ceremony slots, the 6 boat actions awaiting takes, any gap from the removals audit).
  • Kept machine-readable (YAML/JSON) with a generated Markdown view; see the audit doc for the build plan. This is the deliverable that survives Ozan's no-rename decision.

7. Maintenance

  • Every convert / adopt / archive updates the registry row in the same commit — the rule already in .agents/wiki/dances/REGISTRY.md, generalized to all categories.
  • Archive, never delete; numbers never reused. Rejected/superseded takes move to archive/ (this repo) and archive/dances/ (ariki-game), keeping their names.
  • Sync via tinqs push / tinqs pull (raw git pull hangs on LFS). Report commit hashes.

8. Why this shape (rationale, for future readers)

The game controller is decoupled from asset names by the game-key layer, so the valuable outcomes — provenance, status, a "what do we still need" list, and a stable controller vocabulary — come from the registry + game-key discipline, not from mutating vendor clip strings. Renaming purchased packs would cost a full-pack Blender re-export (risking rig-pose drift, caught only by rig_pose_gate.py), permanent vendor-upgrade friction, and LFS bloat, for cosmetic gain. Hence: document the conventions, name new files to fit, catalogue everything, rename nothing that already ships.