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>
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, nottreechopping. 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 numbered01,02. - Root-motion twins carry
_RM(in the*_RM.glbpacks; 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 trailingRM(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/filend_08, clipND08, dance JSONnd_08.json. Variants keep the base id + suffix:nd_08_pp/ND08PP. - On adoption to a ceremony → dance code = snake_case of the sim
DanceTypeenum + index: packwar_dance_01, clipWarDance01(PascalCase, matches the enum), JSONwar_dance_01.json. - Loop-pair rule: every adopted dance ships base + ping-pong
_ppvariant (war_dance_01_pp/WarDance01PP), baked withtools/pingpong_bake.py, must passloop_qc.py. - Boat actions get direct
boat_*codes (no provisional stage):boat_dive,boat_row_loop, clipBoatDive/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
- 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 keyrow inSetupAnimations()and a catalogue entry in the registry. Do not re-export or rename. - Is it a dance or boat action? → Follow
.agents/wiki/dances/REGISTRY.md(nd_##→ ceremony code; boatboat_*; loop-pair rule). - 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,
_pploop. - 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_idis just our stable handle for the catalogue;clipstays the vendor string. Nothing on disk changes. not_startedrows 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) andarchive/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.