The tuned pass warned: 121/20000 differ, 6 over the bound, worst 1.72e-05, still 0
isosurface crossings. The port is fine; the bound was wrong.
It was 16 * max(|Old|, 1) * FLT_EPSILON — ULPs on the OUTPUT density. But density is
min(Z - Floor, Ceil - Z), so near the isosurface the output tends to 0 while the
intermediates are in the hundreds. Rounding born at scale ~400 judged against a
yardstick of scale 1: 400x too tight, and tightest exactly where the test looks
hardest. Large amplitudes are what expose it, which is why the tuned pass earned
its place immediately.
Measured rather than assumed: amplitudes rose x2.25-3.33 and the deltas rose x4.5,
with the worst delta at 0.345 ULP of |Z| — sub-ULP at the scale it is born in. Error
proportional to amplitude is ordinary rounding. A wrong noise offset or a missing
abs() would move the surface by voxels, four orders of magnitude above this.
The bound now scales with max(|Old|, |Z|, strate Z bounds), and the warning prints
the discriminator instead of just the alarm: the density at the offending sample and
the delta in ULPs of the working scale. A few ULP at near-zero density is
cancellation; thousands is drift. That distinction is now readable rather than
re-derivable at a build apiece.
The box verdicts held under the worst case: 32/60 proved uniform, 0 unsound, under
tripled ceiling roughness and 3x the columns — exactly the case that stresses the
Max(CeilZ - noise, FloorSurface + 2) clamp.
Also recorded in DECOMPOSITION section 3: FlatPlain and CrystalChamber render
identical in the live world because nothing in the content distinguishes them. The
merge loses no distinction; it reveals there was none.
UNVERIFIED: the corrected bound.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jahni closed OPSTACK-DECOMPOSITION 3.1: the slab noise Z term was not
intentional character. Phase 1 also closed — the visual A/B on Maze passed.
Two changes, deliberately together, kept attributable by the test:
1. Design: GetSlabDensity's floor and ceiling noise lose their Z terms. A floor
height no longer depends on the altitude you sample it from. The ceiling keeps
its + 3000.0f, which is a decorrelation offset, not a Z term. The world
re-tunes once — a different slice of the noise field, not a worse one.
2. Refactor: the now-XY-pure function ports to FSlabVoidSource + FGridColumnMod
plus the three structural ops. BuildSlabStack has NO branch on archetype
because GetSlabDensity never had one — CrystalChamber is FlatPlain with a
bigger CeilingRoughness. 8 archetypes -> 7.
SlabEquivalence compares against the reference AS IT IS NOW and runs the whole
battery on both slots, so green means the port is a pure refactor and any visual
delta is attributable to the Z-term removal alone. The attribution comes from the
test, not from splitting it across two builds.
The payoff 3.1 was actually about: FSlabVoidSource::ClassifyBox is exact and needs
no sampling. FBM is contractually [-1,1], so both surfaces live in Z bands with
known bounds — a tile below the floor band is provably solid, a tile between the
bands provably air. ClassifyTile proves zero tiles for these archetypes today.
FGridColumnMod answers Identity when no column reaches the box, which is what lets
the source's AllAir verdict survive the fold.
UNVERIFIED: not compiled.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All 8 archetypes read line by line and broken into field source / combiners /
detail modifiers / structural post, with every FStrateGenerationParams field
traced to the op that will own it.
Three findings that change the sequencing:
- The op contract needs an SDF channel alongside density. Rooms, pits and
chimneys are SmoothMin'd in SDF space before a single carve, and three of the
four SDF archetypes add roughness to the SDF rather than to density. A
single-channel Eval can only overwrite, which is also why cross-source
SmoothUnion -- 'a maze inside a mountain that looks like it belongs' -- is not
expressible without it. Recommended before the Maze port; not applied, it is
Jahni's call.
- Worm tunnels are why TunnelNetwork can never skip a tile. A fielded 3D-noise
carve with no bounds forces CarveOnly everywhere, killing AllSolid for the
most-used archetype. But its amplitude is trivially bounded by WormStrength,
so a scalar cap recovers deep-rock skipping -- suggests one numeric bound
belongs in Phase 2, not Phase 3 as the plan has it.
- Disturbances already carry lattice bounds that ClassifyTile discards (it only
tests ChasmDensity > 0 strate-wide). Making them ops with real Identity tests
is a tile-skipping win for SurfaceWorld available independently of everything
else.
Q2 param audit: every field claimed except WaterLevelRelative, which is a
render/water property misfiled in the density struct and Lerp'd across strate
boundaries. Also flags three op names that mean different things in the cave and
surface structs and will collide the moment ops become assets.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>