# M02-GMP-TERRAIN-QUERY-001 — Player terrain query boundary ## Ownership - Target: M02 - Program: GMP/RND - Owner/Agent ID: sindo-main-codex - Branch: `work/sindo-main-codex/m02-terrain-query` - Lease expires UTC: 2026-07-16 - Integrator: M02 milestone integrator ## Outcome Introduce a typed `TerrainQuery` boundary and move ADT loading, caching, chunk selection and height interpolation out of `ThirdPersonWowController` without changing current spawn/ground-snap behavior. ## Non-goals - Change ADT topology, coordinate formulas, terrain mesh or renderer caches. - Add physics collision, slopes, water, jump/fall/swim or server movement. - Reuse the streaming renderer cache before its public terrain-query contract exists. - Extract camera or character presentation. - Mark M02 complete or edit its checklist/Evidence. ## Paths - Exclusive: `src/gameplay/terrain/`, `src/tools/verify_terrain_query.gd`, `docs/modules/terrain-query.md`, this claim - Shared/hotspots: `src/scenes/player/third_person_wow_controller.gd`, `src/tools/verify_player_input.gd`, `src/tools/verify_coordinate_conversion_boundaries.gd`, `docs/modules/local-player-movement.md`, `docs/modules/README.md` - Generated/ignored: local `.godot`, native DLL, generated ADT resources and renderer corpus ## Contracts and data - Public API: `TerrainQuery.sample_ground_height(GodotWorldPosition)` returning immutable `TerrainGroundSample` - Production adapter: `AdtTerrainQuery` with owned per-tile parse cache - Test/data-source seam: optional ADT tile loader callable at construction - Coordinate contract version, ADT format, renderer cache and persistence: unchanged - Consumers: current player scene; future movement/collision policies ## Dependencies - Requires: merged movement controller on master `5206c42` - Blocks: camera/presentation extraction from the player hotspot - External state: production uses existing native `ADTLoader`; synthetic tests need no proprietary data ## Verification - Commands: synthetic height/cache/failure verifier, player input/movement regressions, asset-free scene, coordinate/StreamingFocus gates, renderer dry-run and repository gates - Fixtures: synthetic 145-height chunk payload and injected flat terrain query - Fidelity evidence: preserves existing outer-grid bilinear interpolation, spawn ground offset and per-tick snap formula only - Performance budget: one cached tile lookup and local interpolation per ground query; no new I/O after first tile load ## Documentation deliverables - Inline public API docs for query, sample and ADT adapter - Terrain-query module spec with inputs/outputs, data-flow, cache lifecycle and sequence diagrams - Updated movement/coordinate consumer boundaries, source maps and module registry ## Simplicity and naming - Important names: `TerrainQuery`, `TerrainGroundSample`, `AdtTerrainQuery` - Simplest approach: one narrow query contract, one typed result and one existing-format adapter - Rejected complexity: general collision framework, terrain service locator and renderer-cache coupling - Unavoidable complexity: ADT 145-height layout and chunk lookup stay isolated in adapter - Measured optimization evidence: existing per-tile cache retained; no new optimization ## Status - State: ready-for-review - Done: typed query/sample contract, cached ADT adapter, player migration, synthetic interpolation/cache/failure tests, injected scene regression and documentation - Next: M02 integrator reviews and merges before camera-rig extraction - Blocked by: ## Handoff - Commit: `a45d521` - Branch: `work/sindo-main-codex/m02-terrain-query` - Outcome: `ThirdPersonWowController` no longer loads ADTs, caches tile dictionaries, selects chunks or interpolates height grids. It consumes a replaceable typed `TerrainQuery` and retains only existing offset/snap policy. - Public contracts: additive immutable `TerrainGroundSample`, replaceable `TerrainQuery`, cached `AdtTerrainQuery` and player `set_terrain_query`. Coordinate contract version, ADT/native format and renderer caches are unchanged. - Verification: `TERRAIN_QUERY PASS contract=4 interpolation=1 cache=1 failures=2 player_injection=1`; player-input and local-movement regressions passed; asset-free scene exited `0`; coordinate boundary passed with five required consumers and StreamingFocus passed; renderer dry-run passed eight pre-capture gates and seven checkpoint plans; coordination/documentation/diff gates passed. - Fidelity: synthetic fractional-grid fixture locks the inherited 145-height outer-grid bilinear result within `0.002` Godot units; injected scene locks spawn offset `0.05` and physics snap. This is sandbox-regression evidence, not build-12340 triangle/hole/collision parity. - Local verification inputs: isolated worktree reused the existing ignored native DLL and generated ADT resource scripts. Proprietary extracted data and character GLB were absent, so renderer dry-run logged expected missing-corpus diagnostics while all contract steps returned success. - Rebuild/migration: none; caches are transient and existing formats remain unchanged. - Remaining risks: first ADT parse remains synchronous as before; unavailable tiles cache until query replacement; player still owns snap policy; exact ADT triangle choice, holes, slopes, liquids and collision remain open. - Documentation: inline public APIs plus `docs/modules/terrain-query.md` with inputs/outputs, data-flow, cache state and cross-boundary sequence diagrams, ownership, failure/recovery, capability status and source map. Coordinate and movement consumer specifications were updated.