feat(shafts): the spine joins its neighbours -- necessary, not sufficient
Jahni chose: make the (0,0) column join the shafts it passes, so VerticalShafts behaves like the other seven archetypes. Built, and it works as far as it goes -- the spine is now the LARGEST air component in 13 of 16 seeds (share up to 0.81, was 0.096 and never largest). ⚠️ IT DOES NOT MEET THE ACCEPTANCE CRITERION. arrival->departure is still 1/16. Reported as a failure rather than dressed up, because the criterion was the measured law, not "the code was written". The test now prints ACCEPTANCE arrival->departure: FAIL (1/16 seeds pass) so it cannot be quietly forgotten. Why it is insufficient, and it is structural: the spine only joins its own 3x3 cell neighbourhood, while passage mouths land 60-200 voxels from (0,0). The departure network is unreachable from the spine in all 16 seeds. Joining the hub to its neighbours does not help if the rest of the graph never reaches the hub. Part A diagnosis (seed 1337, margin 0, step 2, radius 192): baseline 30 components, largest .220 roughness 0 17 components, largest .226 connector radius 8 29 components, largest .229 H1 is real but partial: roughness fragments the space (13 of the 30 components are noise pockets), yet widening connectors past the proven roughness bound barely moves it. So roughness is NOT what severs the network -- the largest component sits at ~0.22 in every variant, which is the signature of a graph below its percolation threshold. The lever is topology, not radius. H2 (the hardcoded 1.6 pair cutoff) went untested. Implementation notes: the spine is added ONLY as a connector endpoint, not as a carving shaft -- VF_ApplyOriginSpine remains sole owner -- and is excluded from ledge placement. Spine connectors use radius 6.625, above the proven roughness supremum of 5.625 (sup|FBM| = 1.5, not 1.0). SpineRadius is threaded through BuildVerticalShaftStack, not hardcoded. Op-stack mirror bit-identical over 20,000 samples, 0 box-verdict violations. LayoutOrderIndependence green. Build clean, 19 succeeded / 0 warnings / 0 failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bp7FxoQcSoiuhxjuLr6aBM
This commit is contained in:
1 parent
5519b323c8
commit
58e61cdefa
5 files changed
+147
-40
No files matched your search
@@ -45,12 +45,25 @@ what the world IS, and both paths compute it.
|
||||
column at XY (0,0) in every strate's **interior** (seals untouched). Radius =
|
||||
`UVoxelGenerator::OriginSpineRadius` ← `VoxelSettings::OriginSpineRadius`. Called before
|
||||
every `ApplyBoundarySeal`.
|
||||
- `VerticalShafts` treats that structural column as a **connector endpoint**, not as a second
|
||||
density primitive: while rebuilding its memoised 3×3 shaft neighbourhood, an origin-adjacent
|
||||
query adds `(0,0,OriginSpineRadius)` to the local shaft set for pair generation only. The
|
||||
existing `VoxelHash::Pair` gate and `Spacing*1.6` neighbour cutoff remain in force, so the link
|
||||
is a pure function of the shaft cell and seed and is independent of evaluation order. Spine
|
||||
links use a radius above the proven `sup|FBM|=1.5` roughness envelope (`max(ConnectorRadius,
|
||||
SurfaceRoughness*VOXEL_NOISE_SCALE*1.5 + 1)`); the ordinary connector radius and ordinary shaft
|
||||
roughness are unchanged. `BuildVerticalShaftStack` receives the same runtime spine radius and
|
||||
mirrors this source rule; `VF_ApplyOriginSpine` remains the sole owner of the column itself.
|
||||
- Descent is **player-dug** through the thin seals at (0,0). The single auto-opened
|
||||
connection is the **surface entry shaft** at (0,0) through the top of strate 0
|
||||
(`GeneratePassages`, `bOpenSurfaceEntry`).
|
||||
- **Hybrid extras:** auto-carved *shortcut* passages per boundary, placed away from (0,0).
|
||||
Now fully **per-strate** — see §8.8 (the upper strate's `PassageConfig` drives count/style/shape).
|
||||
|
||||
This connector is local topology, not a promise that independently placed shortcut mouths are
|
||||
globally connected. The acceptance measurement for `VerticalShafts` remains the actual
|
||||
arrival→departure flood-fill at the passage endpoints.
|
||||
|
||||
### 8.3 Disturbance layer (the "wow" post-process)
|
||||
`FStrateDisturbanceParams` (on the definition, all archetypes). `ApplyDisturbances`
|
||||
(VoxelGenerator.cpp static, **MC convention**) runs in `GetDensityAt` after dispatch:
|
||||
@@ -324,6 +337,10 @@ driven by `EditorBrush*` props.
|
||||
no loads AND no LOD mismatches outstanding.
|
||||
- **SDF cache** (`GetDensityWithParams`): search-BOX validity, not chunk-key — gradient ±1
|
||||
sampling must not thrash the (expensive) rebuild.
|
||||
- **VerticalShafts field cache**: shaft rolls and pair decisions, including the structural-spine
|
||||
connector endpoint, are rebuilt only when the thread-local centre cell or a geometry-affecting
|
||||
parameter changes. They must not be re-hashed in the per-voxel loop; the operator-stack source
|
||||
follows the same cache contract.
|
||||
- **Per-chunk param cache** in `GetDensityAt`: GenType + param struct + disturbance cached
|
||||
thread-locally by `(DensityCacheOwnerId, ChunkCoord, LayoutVersion)`; the process-unique owner ID
|
||||
prevents cross-world reuse while adding only one `uint64` compare per voxel. Don't remove the owner
|
||||
|
||||
Reference in new issue
Block a user