Review findings: the mesa forced rock onto the canyon bed, two runners
declared the wrong TEST_COUNT, and the escarpment check could pass on the
slope alone. Canyon gains floor_material, the showcase is re-baked with sand
beds, the contract measures the step across the crest band, counts distinct
ledges, and probes the crevasse against the open plateau. Degenerate recipe
parameters now fail an assert.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The bake order is now primitive sum, modifiers (with the local gradient),
floor clamp, slope material, primitive materials, material patches. A
regression test checks the Banc du Vigilant still bakes byte for byte.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Building the 64 tiles of the Banc du Vigilant cost about 1.9 s through
per-vertex cell_world_position/normal_at_cell calls, leaving the 3 s
load budget with too little headroom (2.1-2.9 s measured, one 4.8 s
outlier). TerrainHeightField now returns positions and normals of a
cell block in one call, with normal_at_cell sharing the same formula;
the tile build drops to about 0.5 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DiveSite.configure() builds the height field once (TerrainHeightField
validates the data) instead of running the definition validation and
then the field construction again; the composition root relies on the
error returned by configure(). The collision shape takes the field's
row-major elevations directly instead of copying 263k cells one by one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>