# M02-RND-CAMERA-001 — Third-person camera rig boundary ## Ownership - Target: M02 - Program: RND/GMP - Owner/Agent ID: sindo-main-codex - Branch: `work/sindo-main-codex/m02-camera-rig` - Lease expires UTC: 2026-07-16 - Integrator: M02 milestone integrator ## Outcome Move mouse capture, orbit yaw/pitch, zoom state and Camera3D transforms from `ThirdPersonWowController` into a reusable `ThirdPersonCameraRig`, with an explicit replaceable camera-collision policy that preserves the current no-collision sandbox baseline. ## Non-goals - Enable a new collision/raycast behavior before build-12340 comparison. - Change initial yaw/pitch, zoom limits, sensitivity, FOV, far plane or camera path. - Implement first-person, follow lag, shoulder offsets or cinematic cameras. - Change movement, terrain query, character presentation or renderer streaming focus. - Mark M02 complete or edit its checklist/Evidence. ## Paths - Exclusive: `src/scenes/player/third_person_camera_rig.gd`, `src/scenes/player/camera_collision_policy.gd`, `src/scenes/player/no_camera_collision_policy.gd`, `src/tools/verify_third_person_camera_rig.gd`, `docs/modules/third-person-camera.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/player-input.md`, `docs/modules/local-player-movement.md`, `docs/modules/README.md` - Generated/ignored: local `.godot`, native DLL, generated resources and renderer corpus ## Contracts and data - Public API: `ThirdPersonCameraRig.initialize_for_character`, `handle_camera_input`, `godot_world_flight_movement_basis`, state getters and `set_collision_policy` - Policy: `CameraCollisionPolicy.resolve_camera_distance`; default `NoCameraCollisionPolicy` returns requested distance unchanged - Scene paths and renderer camera path remain unchanged - Schema/cache/coordinate contracts: unchanged - Consumers: player composition, sandbox flight movement and renderer viewport ## Dependencies - Requires: merged TerrainQuery package on master `f5bb64e` - Blocks: character appearance/animation extraction from remaining player hotspot - External state: none; tests use asset-free camera/player scene ## Verification - Commands: dedicated orbit/zoom/clamp/policy verifier, input/movement/terrain regressions, asset-free scene, coordinate/StreamingFocus gates, renderer dry-run and repository gates - Fixtures: initial state, remappable action events, mouse deltas and fixed-distance policy - Fidelity evidence: preserve current `-18°` pitch, `8` distance, `1` zoom step, `2..18` clamp, `0.003` sensitivity and no-collision output - Performance budget: constant-time state/transform update; no raycast in baseline policy ## Documentation deliverables - Inline API/export documentation for rig and collision policies - Camera module spec with inputs/outputs, data-flow, state and sequence diagrams - Updated input/movement consumer diagrams/source maps and module registry ## Simplicity and naming - Important names: `ThirdPersonCameraRig`, `CameraCollisionPolicy`, `NoCameraCollisionPolicy` - Simplest approach: one Node3D rig on existing CameraPivot and one explicit identity policy - Rejected complexity: generic camera framework, spring arm migration and hidden physics raycast - Unavoidable complexity: rig mutates Camera3D/character Node transforms on main thread - Measured optimization evidence: not applicable ## Status - State: ready-for-review - Done: extracted rig and collision policy, migrated all three scene compositions, added regressions and completed required module documentation - Next: milestone integrator reviews and merges `8c1cf9b` - Blocked by: ## Handoff - Outcome: `ThirdPersonCameraRig` now owns capture, orbit, zoom and camera transforms; `ThirdPersonWowController` only dispatches camera events and consumes the rig basis for sandbox flight. - Public contracts: `initialize_for_character`, `handle_camera_input`, `godot_world_flight_movement_basis`, `set_collision_policy`, read-only state, and `CameraCollisionPolicy.resolve_camera_distance`. - Verification: camera `state_cases=12 policy_cases=3 scenes=3`, input `actions=12 intent_cases=6`, movement `cases=12 state_transitions=2`, terrain `contract=4 interpolation=1 cache=1 failures=2`, coordinate boundary `files=98 consumers=5`; documentation, coordination and diff checks passed. - Renderer dry-run: seven checkpoint plans and report completed; expected diagnostics only for unavailable proprietary corpus/character GLB. - Fidelity: preserves the sandbox defaults (`-18 degrees`, distance `8`, zoom `2..18` step `1`, sensitivity `0.003`, pivot `1.7`, far `50000`) and the prior no-collision behavior. No build-12340 parity claim is made. - Local ignored inputs: native extension DLL and generated ADT resource scripts were used for the renderer dry-run and are not part of the commit. - Migration: none; `ThirdPersonPlayer/CameraPivot/Camera3D` remains stable. - Risks: active collision and exact original-client camera semantics remain unverified; exported initial values are captured at ready; mouse mode is process-global. - Documentation: added the camera API/module spec plus data-flow, state and sequence diagrams; updated player-input and local-movement consumer maps.