Files
VoxelForge/Docs/archive/CODEX-TASK-005-tile-scan-sampler-extent.md
T
Claude 1de44af7cc chore(repo): archive historical docs under Docs/archive, drop tracked pycache
Move closed audits, task briefs, design rounds, perf reports, the OPSTACK
plan/progress logs and WORK-NEXT.md into Docs/archive/ (git mv, history kept).
Whitelist Docs/ in the strict .gitignore, ignore Tools/**/__pycache__/, and
remove the tracked .pyc. Repoint references in the kept docs and in non-test
source comments to the new paths.
2026-09-28 13:46:17 +00:00

5.4 KiB

Codex task 005 — three box-verdict tile scans sample less than one lattice period

Owner: Codex (Model Luna, xHigh) · Orchestrator: Claude · Branch: experimental Status: specified, not started Kind: test coverage. Zero risk to the game — no non-test file may change.


Why this exists

This project has already found and fixed this exact defect twice:

"A sampler must cover at least one period of what it samples. The tunnel test drew tile XY from ±32 voxels with RoomSpacing 80 — it measured the spine hub and called it the world. The shaft test had the identical bug (±48 against ShaftSpacing 55)." — OPSTACK-HANDOFF.md

Both were fixed to SpanCells = 55 ⇒ ±440 voxels, and both now print their own extent in units of the pattern's period so it cannot silently regress.

Three box-verdict tile scans were never fixed, because the fix was applied where the bug was noticed rather than to the class. All three still use the original Rng.RandRange(-6, 6) * Extent with Step = 1, Cells = 8 ⇒ Extent = 8 ⇒ half-extent ±48 voxels:

test half-extent lattice period (default, unchanged by the fixture) coverage
VoxelForgeOpStackIslandTest.cpp ~244 ±48 IslandSpacing 95 0.51 periods ⛔ worse than either bug already fixed
VoxelForgeOpStackSlabTest.cpp ~289 ±48 ColumnSpacing 60 0.80 periods ⛔
VoxelForgeOpStackMazeTest.cpp ~276 ±48 CellSize 40 1.20 periods ⚠️ marginal

Verified: none of EnableIslandFeatures / the slab tuning / the maze setup overrides the spacing, so the header defaults are what these tests actually run against.

Why it matters right now, specifically. Two commits just changed the box verdicts these very tests are supposed to guard — 7dbdf51 (the ExtraReach bound, which touches islands, maze and shafts) and eaa44bf (the radius envelope, which touches slab columns and shafts). The tests that would catch a mistake in those changes currently sample about half a lattice cell.

The rule the two fixed tests already encode

Extent = Step * Cells = 8 voxels, so SpanVoxels = SpanCells * 8. To get 8 periods of half-extent you set:

SpanCells = the lattice spacing (55 for ShaftSpacing 55 — that is where the shaft test's 55 comes from, and it is not a coincidence).

Apply the same:

test SpanCells resulting half-extent periods
Island 95 ±760 8.0
Slab 60 ±480 8.0
Maze 40 ±320 8.0

What to build

For each of the three tests, mirror exactly what VoxelForgeOpStackShaftTest.cpp (~212) does:

  1. Hoist const int32 SpanCells and const int32 SpanVoxels = SpanCells * 8; outside the tile loop — the report needs them and Extent is loop-local. (That scoping slip has already happened once in this file family; the shaft test's comment records it.)
  2. Draw Rng.RandRange(-SpanCells, SpanCells) * Extent for X and Y. Leave the Z draw exactly as it is — it is clamped to the strate slot and is not part of this defect.
  3. Extend the existing report line to print SpanVoxels, the live ratio (float)SpanVoxels / FMath::Max(<the spacing param>, 1.0f), and the spacing itself — so the extent is stated in units of the pattern's own period and a future narrowing is visible.

⚠️ Invariants

  1. This is NOT "widen until it passes." The comment already in the tunnel test says it best and the same reasoning applies here: every proved tile is still brute-forced voxel by voxel below, so a wider sampler that produced a FALSE verdict fails exactly as before. We are changing what the measurement looks at, not what it demands. Do not touch the brute-force loop, its tolerance, or any AddError.
  2. Do not adjust an assertion to accommodate a moved number. Widening will change the proved / Mixed counts — that is the point. If an existing assertion would now fail, report it and stop; do not retune it. ("Don't assert a number you want to improve" is a written lesson here.)
  3. No file outside Source/VoxelForge/Private/Tests/ may change. git diff --stat must list only those three test files.
  4. Do not change Step, Cells, the tile count (60), or the RNG seeds — a changed seed makes the before/after incomparable, and comparability is the whole point of touching this now.
  5. Comments are French + English; match the surrounding file.

Acceptance

  • Three test files changed, nothing else.
  • Each of the three now prints its extent and that extent in periods of its own spacing param.
  • After the build, each ratio line reads ≥ 8 periods.
  • The proved counts will move. That is expected. What must NOT move: violations / NumUnsound stays 0 in all three. If it becomes non-zero, the wider sampler has found a genuine hole that the narrow one was hiding — which would be this task paying for itself immediately, and must be reported loudly rather than tuned away.

Notes for the reviewer (Claude)

  • Confirm SpanCells/SpanVoxels are outside the tile loop in all three.
  • Confirm the Z draw is untouched.
  • Confirm the ratio is computed live from the params struct, not hardcoded — a hardcoded "8.0 periods" in a format string would be a success message that asserts coverage while measuring nothing, which is a named failure mode in this project.