# D-239 (REVISED post-verification): Tile derivation contract — coarse→fine refinement chain (Q-101) domain: architecture · type: confirmed · date: 2026-06-07 · resolves: Q-101 **Decision.** The walkable tile is materialised by a **three-carrier refinement chain**, each stage a pure deterministic function of `(seed, atlas, body-params, position)` per D-227: `RegionProfile` (~1 km) → `ChunkContext` (64 m) → `VoxelColumn` (1 m). Each scale boundary is its own derivation with its own failure modes. ### Determinism — no authoring at the derivation layers, ever L1–L5 derivation has **zero per-body override hooks**. All authorial control lives **upstream** at the body-parameter / atlas / system-specialization layer; the gating params (`GlaciationGrade`, `precipitation_class`, `RIVER_THRESHOLD`, `tectonic_class`) are **derived** from body params (stellar type / orbit / hydrosphere / lithology), never authored. `RIVER_THRESHOLD` specifically is a derived **per-body-class** value `(hydrosphere, tectonic_activity, precipitation_class) → threshold`, not the global constant `200`. Lore-anchored bodies are honoured by **setting params** and stand as **validation cases** — if a body reads wrong, fix its params, never patch the derivation. **Validation caveat:** derived terrain can only honour a lore body if its params *permit* it — e.g. tidal flats require a moon param (the D-228 tidal term); confirm each validation body's params before treating its terrain as a contract (Velen's tidal-flat coast presumes Velen has a moon — verify). ### Anti-"squaring" (warp) A global position-keyed **domain-warp field** suppresses grid/seam artifacts. The warp is a **stateless, hash-based pure function of `(seed, body_id, position)`** — no lookup table, no thread-local cache (so it's order-independent across threads/platforms). It keeps **f64 sub-metre precision through to the final voxel coordinate, then quantises by truncation to the integer voxel address** — a cast, not a comparison, so IEEE-754-deterministic across targets. The ±8 m warp range makes FMA-contraction ULP variance (~1e-15 m) unable to shift the rounded voxel, so no platform guards are needed. The warp is *position math*, not a structural decision — D-010 integer discipline on all material/morphology decisions is preserved. ### Morphology — 8 families Selected by a strict **decision tree over integer `RegionProfile` inputs**: LavaField · FjordWall · CliffCoast · BraidedDelta · DuneStrand · IncisedGorge · MeanderReach · AlluvialPlain (fallback). Requires adding `tectonic_class` to `RegionProfile`. MountainPass is a zone label sharing IncisedGorge geometry. **Hard gates (boolean, applied pre-selection in tree order):** fjord requires `GlaciationGrade ≥ 2`; LavaField requires `tectonic_class = Volcanic`; lithology bounds slope/form (see laws below). ### Frozen 17-zone `MorphologyZone` display vocabulary Derived labels per D-228, **enum→label map frozen at authoring time**. The canonical freeze point is the Rust `MorphologyZone` enum; **adding/renaming a zone requires a D-record amendment** (a code reviewer enforces this). The 17: open ocean, lake, tidal flat, dune strand, cliff coast, fjord, delta, estuarine, alluvial plain, river bank, meander reach, braided plain, valley floor, mountain pass, alpine, volcanic, wetland. **Note — zones ≠ families:** four zones (tidal flat, estuarine, alpine, wetland) have no distinct generator family; they are derived sub-classifications from family + elevation/water-height conditions (e.g. tidal flat = BraidedDelta at the tidal margin; alpine = AlluvialPlain/IncisedGorge above the treeline-elevation threshold). ### Zone seams — prevent incompatible, allow valid (don't patch) The boolean gates are discontinuities on continuous inputs, so "continuous→continuous" is NOT the mechanism. The mechanism is the **decision-tree gate ordering + a build-time compatibility matrix**: *incompatible* family pairs (e.g. MeanderReach↔Volcanic — geomorphically incoherent) cannot be adjacent classifier outputs; the matrix is a **build-time invariant test**, never a runtime override. *Valid* geomorphic seams (cliff↔fjord at the glaciation threshold, lithology faults) are **permitted sharp transitions** — kept sharp (real geology is sharp), made non-grid/organic by the warp; no modulation feathering. The warp also guarantees seams don't produce degenerate slivers at chunk scale (preserving the per-chunk tactical-content rule below). ### Believability laws (binding — inline, not just titles) - **Drainage monotonicity:** channels descend; respect the D8 thalweg (D-208); tributaries join from upstream; river mouths sit at sea level. - **Lithology → landform:** Rock → vertical faces/cliffs; Sand → ≤ angle of repose (~32°), dunes not cliffs; Gravel → braided channels/fans, not single-thread meander; Soil → rolling/floodplain; Wetland → ≤5° flats; Lava → sheets/shield slopes + lava tubes, immature drainage. - **Glaciation → form:** fjord requires GlaciationGrade ≥ 2; U-valleys ≥ 1; moraine ridges ≥ 1; cirques ≥ 2. GlaciationGrade 0 high-relief is V-ridges (fluvial), never glacial U-profiles. - **Climate → vegetation:** treeline transitions Forest → Scrub → Barren (no Forest→Barren skip); riparian Thicket/Scrub band 1–3 tiles along every perennial waterway; boundaries follow contours/moisture, not chunk edges. ### Game-feel constraints Every chunk carries ≥1 tactical decision point; cover ≠ concealment (mechanically distinct); high-ground asymmetric-but-not-dominant; chokepoints narrow enough to matter (river crossings 3–15 m, gorge floors 2–8 m); **seasonal/tidal state must produce real passability changes, not cosmetic ones** — BraidedDelta/MeanderReach `ElevationDelta` calibrated so channels fall below the Q-105 high-water threshold and levees stay above it (flood = genuinely impassable, not recoloured). ### Mechanics - No per-tile `flow_direction[64×64]` in `ChunkContext` (D8 ≈ 152 m/cell — coarser than a chunk) → one basin-direction + global meander-curve params. Features with wavelength > 64 m (meanders, dunes, cliff continuations) seed from **Region-or-higher**, not the chunk seed. - **Caching:** `RegionProfile` is stored in `BodyWorldState` (D-203) (~6k/body, populated in the D-206 background pass) so the Atlas reads zone labels without triggering voxel derivation; voxel derivation is on-demand + cached, never persisted (D-227). Budget ~2.2–4.2 ms/chunk **(validate per-family in Phase 4 — FjordWall/IncisedGorge are far costlier than the AlluvialPlain fallback).** **Resolves:** Q-101. **Touches:** Q-102 (cohesion = the warp). **Leaves open:** Q-103 (mutator op schema), Q-105 (region seasonal/clock state — the ElevationDelta calibration above is a forward contract to it). **Cross-refs:** D-227, D-228, D-203, D-206, D-208/209/210, D-010, D-234, D-142, D-217. **Raised by:** tile-derivation-contract workshop (Tyre, Gestalt, Troblum, Miri) + lead-interviewed decisions, 2026-06-07; verified by an adversarial pass from the same four. **Dissent:** Tyre's initial cross-family elevation-blend was resolved against (prevent-at-source). Early-integer-truncation of the warp (raised against Gestalt's `ElevationDelta` ranges and by Tyre) was resolved against in favour of f64-to-voxel.