# M02-RND-CHARACTER-PRESENTATION-001 — Character presentation boundary ## Ownership - Target: M02 - Program: RND/GMP - Owner/Agent ID: sindo-main-codex - Branch: `work/sindo-main-codex/m02-character-presentation` - Lease expires UTC: 2026-07-16 - Integrator: M02 milestone integrator ## Outcome Move character GLB composition, geoset/texture/outfit setup and locomotion animation selection from `ThirdPersonWowController` into independently replaceable `CharacterAppearancePresenter` and `CharacterAnimationPresenter` components without changing the current sandbox presentation. ## Non-goals - Add new model, equipment, animation or build-12340 behavior. - Change character asset formats, DBC parsing, texture composition or geoset rules. - Add network-driven appearance/movement snapshots. - Change input, movement, terrain, camera or renderer streaming behavior. - Mark M02 complete or edit its checklist/Evidence. ## Paths - Exclusive: `src/scenes/character/character_appearance_presenter.gd`, `src/scenes/character/character_animation_presenter.gd`, `src/tools/verify_character_presentation.gd`, `docs/modules/character-presentation.md`, this claim - Shared/hotspots: `src/scenes/player/third_person_wow_controller.gd`, runtime streaming scenes, player regression scene, `src/tools/verify_player_input.gd`, `docs/modules/local-player-movement.md`, `docs/modules/README.md` - Reused unchanged: geoset controller, texture compositor and outfit resolver - Generated/ignored: local `.godot`, native DLL, generated resources and renderer corpus ## Contracts and data - Appearance API loads/replaces one character root under the existing `Visual` node. - Animation API binds an `AnimationPlayer` from that root and accepts a typed moving/stationary presentation state. - Scene paths, model defaults, DBC/cache/coordinate contracts remain unchanged. - Consumers: player scene composition and renderer viewport only. ## Dependencies - Requires: merged camera package on master `68e6f60`. - Blocks: final M02 sandbox-profile gate and target integration audit. - External state: asset-free tests use a synthetic mesh and AnimationPlayer. ## Verification - Dedicated appearance composition, replacement, grounding and failure regression. - Dedicated animation discovery, fallback, looping, blend and state regression. - Player source-boundary and three-scene wiring checks. - Existing input/movement/terrain/camera regressions, coordinate gates and renderer dry-run. - Fidelity evidence: preserve current sandbox model path, scale, yaw, outfit, Stand/Idle and Run/Walk selection only; no original-client parity claim. ## Documentation deliverables - Inline public API/export documentation for both presenters. - Module specification with inputs/outputs, data-flow, lifecycle/state and sequence diagrams. - Updated movement consumer/source map and module registry. ## Simplicity and naming - Important names: `CharacterAppearancePresenter`, `CharacterAnimationPresenter`. - Simplest approach: two small scene components on the existing `Visual` subtree. - Rejected complexity: generic presenter framework, async asset scheduler and duplicated character systems. - Unavoidable complexity: scene-tree composition and AnimationPlayer discovery run on the main thread. - Measured optimization evidence: not applicable. ## Status - State: ready-for-review - Done: extracted both presenters, migrated all runtime/regression scenes, added asset-free regressions and completed required module documentation - Next: milestone integrator reviews and merges `97bb53f` - Blocked by: ## Handoff - Branch/commit: `work/sindo-main-codex/m02-character-presentation` at `97bb53f`. - Outcome: `CharacterAppearancePresenter` owns model/geoset/compositor/outfit composition and `CharacterAnimationPresenter` owns AnimationPlayer discovery, loop preparation and moving/stationary playback. The player is now only the composition and horizontal-velocity adapter. - Changed composition: both runtime scenes and the player regression scene keep `ThirdPersonPlayer/Visual`; they add `Visual/AnimationPresenter`. - Public contracts: appearance load/read-root/ready signal and animation bind/present/read-state APIs documented in the module specification. - Verification: presentation `appearance_cases=9 animation_cases=10 scenes=3`, input `actions=12 intent_cases=6`, movement `cases=12 state_transitions=2`, terrain `contract=4 interpolation=1 cache=1 failures=2`, camera `state_cases=12 policy_cases=3`, coordinate boundaries `files=99 consumers=5`, and StreamingFocus `runtime_scenes=2 capture_tools=3` passed. - Renderer: dry-run passed project/material/dedupe/cache/manifest/calibration/ coordinate/server-spawn gates and planned all seven checkpoints. Missing proprietary HumanMale GLB, DBC and ADT corpus produced expected diagnostics. - Repository gates: documentation `module_specs=8`, coordination `fallback_claims=29`; five unrelated expired M00 claim warnings remain. - Fidelity: current model path, scale `1`, yaw `90 degrees`, class `1`, blend `0.15 seconds`, starter outfit and Stand/Idle/Run/Walk selection are preserved. No build-12340 appearance or animation parity claim is made. - Migration: repository scenes are migrated. External/custom scenes must move model/class/scale/yaw exports from the player node to the scripted `Visual` node and add `Visual/AnimationPresenter`. No cache/database rebuild is needed. - Local ignored inputs: native extension DLL, UID cache and generated ADT resource scripts supported the dry-run and are not committed. - Risks: synchronous model load may hitch; first descendant AnimationPlayer wins; moving state is a sandbox threshold boolean; complete equipment/animation fidelity remains open. - Recommended merge order: merge this package after camera (already on master), then implement the sandbox profile gate and perform the final M02 integration audit. - Documentation: added character-presentation API, inputs/outputs, data-flow, lifecycle/state, sequence, ownership/failure and source-map sections; updated the module registry and movement presentation consumer map.