feat: TunnelNetwork stage A — the SDF spine, wrapping BuildChunkCache
The last archetype is ~1080 lines with 13 detail modifiers, a two-region cache and a per-room op override. Porting it whole before anything can be verified is ~600 unverified lines on top of ~200 — the pattern this refactor has dodged six times. So: three stages. Stage A = vertical scale, base rock, cave warp, room graph (+ pits and chimneys), carve, worms, structural post. 6 ops. It is verifiable NOW because every detail modifier is amplitude-gated and FStrateGenerationParams already defaults them all to zero — zeroing SurfaceRoughness sends the ORIGINAL down exactly the path stage A ported. TunnelNetwork stays OFF in UsesOperatorStackForChunk until stage C. The decision that matters: FRoomGraphSource CALLS BuildChunkCache and EvaluateSDFCached rather than transcribing them. That is where §8.4's two-region window-invariance discipline lives; a transcription would fork it, and the fork would be "validated" by a test comparing it to the original. Only the ~60 lines of glue are transcribed. FRAME ops are retired. All three candidates are now ported and none needed one: CaveWarp's scope is exactly one operator (pits/chimneys read unwarped coords), VerticalScale is a one-line pure function, and the island warp was already local. Not missing infrastructure — one idea seen three times from a distance. Also: check 3 was going to compare two interleaved param sets against the original, which would have FAILED — the original's SDF cache key has no params, so it serves B the rooms it built for A. Comparing there measures its bug, not the port. Rewritten against each stack evaluated alone. The same reasoning suggests a live production staleness across Gradient transitions; filed in AUDIT §C2 as SUSPECTED with the check that would confirm it, since it rests on a premise I have not verified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -182,6 +182,30 @@ Seed) **are** seed-guarded, and the strate-index memo **is** version-guarded (`S
|
||||
`ChangeSeed` mostly survives; **live-edit is where this bites**. Symptom: "I tweaked the strate asset,
|
||||
regenerated, and one patch kept the old shape."
|
||||
|
||||
#### ⚠️ SUSPECTED, NOT PROVEN, 2026-07-28 — the SDF cache may serve stale rooms *within* a strate
|
||||
|
||||
Found while porting TunnelNetwork, and stated as a suspicion on purpose: I have reasoned it, not
|
||||
measured it.
|
||||
|
||||
`GetDensityWithParams`' SDF cache key is `(XY search box, StrateIndex, Seed)`. It contains **no
|
||||
params and no chunk Z**. Meanwhile `GetGenerationParams` *blends* params between neighbouring strates
|
||||
across a Gradient transition — so two chunks at different Z **inside the same strate** can carry
|
||||
different `RoomSpacing`/`RoomDensity`/… while sharing an XY box, a strate index and a seed.
|
||||
|
||||
If that is right, a worker descending a transition band gets **no rebuild** and evaluates the lower
|
||||
chunk against the upper chunk's room layout. Same family as `§C2` above and as the overhang
|
||||
regression of 2026-07-27; the difference is that this one needs no live edit to trigger.
|
||||
|
||||
**What would confirm it:** call `GetGenerationParams` for two adjacent chunk Zs inside a
|
||||
Gradient-transitioned strate and compare the room-placement fields. If they differ, the cache is
|
||||
being reused across a real param change. **Do that before acting** — the whole thing rests on
|
||||
"Gradient blending actually varies within a strate", which I have not verified.
|
||||
|
||||
The operator-stack port does **not** inherit this: `FRoomGraphSource` folds a `FCrc::MemCrc32`
|
||||
fingerprint of the params (plus `LayoutVersion`) into its key, so differing params force a rebuild.
|
||||
`VoxelForge.OpStack.TunnelNetworkSpineEquivalence` check 3 exercises exactly that — and deliberately
|
||||
does *not* compare against the original there, because the original would fail it.
|
||||
|
||||
**Fix:** the getter already exists and is already used elsewhere —
|
||||
```cpp
|
||||
const uint32 LV = StrateManager->GetLayoutVersion();
|
||||
|
||||
Reference in New Issue
Block a user