Resolves Q-101 — how a coarse Layer-1 cell + seed becomes coherent ~1m voxel geometry across the scale jumps. The tile-derivation-contract workshop output: - three-carrier refinement chain RegionProfile -> ChunkContext -> VoxelColumn, pure deterministic, no authoring at the derivation layers - district-temperature climate primitive (2x2 km, C, nullable) + separate moisture; everything climatic derives from temperature(+moisture) - scattered, transient freeze/snow model (freshwater +5..-10, sea ice own band, snow moisture-gated; forms cold phase / melts warm phase) - stateless f64-to-voxel domain warp (anti-squaring) - 8 morphology families over a frozen 17-zone vocabulary, gated decision tree - seams prevented at source (gate ordering + build-time matrix); valid geomorphic seams kept sharp + warped Includes workshop brief, round-1 positions, and workshop-outcomes.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.2 KiB
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]inChunkContext(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:
RegionProfileis stored inBodyWorldState(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.