Excavation: intervals are absolute Z, the elevation section is BaseZ-relative - settle the conversion before digging #289

Open
opened 2026-08-08 19:21:05 +02:00 by panda · 0 comments
Collaborator

Found by digging a real tunnel into the authored world, and caught by
LegacyProjectionGoldenTests.Every_authored_cell_projects_to_its_pre_F1_answer:

GridPosition { X = 2198, Y = 4106 }: ground was 197 before F1, is 192 now

The mismatch

Two reference frames meet in the chunk and nothing states which is which:

  • the elevation section stores a height that the legacy projection reads as
    terrain.BaseZ + storedmountain_rock declares BaseZ 5, so a stored 192 means a surface at 197;
  • the interval section stores absolute Z, which is what the volume model means everywhere else
    (TerrainZ.Floor, SurfaceResolver, Excavation).

ChunkedEditModel.Excavate synthesises a column for an undug cell from ZAt, which returns the STORED
elevation, so the column it writes is 5 too low for that terrain. WorldChunk.GroundZAt then answers the
top of the topmost span directly and the BaseZ is silently lost.

Nothing was corrupted on disk — the authored world has been restored from backup and the suite is green —
but no cell may be dug until this is settled, or every dug cell's surface drops by its terrain's BaseZ.

What has to be decided

  1. Which frame do intervals use? Absolute is the only answer consistent with the rest of the volume
    model, so the conversion belongs at the authoring boundary: [Floor, BaseZ + stored) going in, and
    TopZ - BaseZ going back to the elevation section.
  2. Where does BaseZ come from? ChunkedEditModel works in catalog indices and does not know tiledata
    today. It needs the per-terrain BaseZ, or the conversion has to move to a layer that has it.
  3. What does BaseZ even mean for a column that has been dug? A cell's terrain can be repainted after
    it was excavated; if the surface height is derived from the terrain's BaseZ, repainting would move a
    cave's roof. That suggests an extended column should carry absolute Z and the elevation section should
    be a projection of it, not a second source of truth.

Already in place

Excavation.Dig, TerrainInteriors, the renderer pass and the harness dig verb are merged and
unit-tested; the gap is only this conversion. A gallery dug through the authored chain read back
correctly in the interval data (34 cells, void 14 high, roof thickening 38 -> 188) — the surface
projection is the one thing that was wrong.

Blocks the mountain-road galleries; related to #268 and the volume model spec.

Found by digging a real tunnel into the authored world, and caught by `LegacyProjectionGoldenTests.Every_authored_cell_projects_to_its_pre_F1_answer`: > `GridPosition { X = 2198, Y = 4106 }: ground was 197 before F1, is 192 now` ## The mismatch Two reference frames meet in the chunk and nothing states which is which: - the **elevation section** stores a height that the legacy projection reads as `terrain.BaseZ + stored` — `mountain_rock` declares `BaseZ 5`, so a stored 192 means a surface at 197; - the **interval section** stores **absolute** Z, which is what the volume model means everywhere else (`TerrainZ.Floor`, `SurfaceResolver`, `Excavation`). `ChunkedEditModel.Excavate` synthesises a column for an undug cell from `ZAt`, which returns the STORED elevation, so the column it writes is 5 too low for that terrain. `WorldChunk.GroundZAt` then answers the top of the topmost span directly and the BaseZ is silently lost. Nothing was corrupted on disk — the authored world has been restored from backup and the suite is green — but no cell may be dug until this is settled, or every dug cell's surface drops by its terrain's BaseZ. ## What has to be decided 1. **Which frame do intervals use?** Absolute is the only answer consistent with the rest of the volume model, so the conversion belongs at the authoring boundary: `[Floor, BaseZ + stored)` going in, and `TopZ - BaseZ` going back to the elevation section. 2. **Where does BaseZ come from?** `ChunkedEditModel` works in catalog indices and does not know tiledata today. It needs the per-terrain BaseZ, or the conversion has to move to a layer that has it. 3. **What does BaseZ even mean for a column that has been dug?** A cell's terrain can be repainted after it was excavated; if the surface height is derived from the terrain's BaseZ, repainting would move a cave's roof. That suggests an extended column should carry absolute Z and the elevation section should be a *projection* of it, not a second source of truth. ## Already in place `Excavation.Dig`, `TerrainInteriors`, the renderer pass and the harness `dig` verb are merged and unit-tested; the gap is only this conversion. A gallery dug through the authored chain read back correctly in the interval data (34 cells, void 14 high, roof thickening 38 -> 188) — the surface projection is the one thing that was wrong. Blocks the mountain-road galleries; related to #268 and the volume model spec.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo#289
No description provided.