Three defects, two of them mine.
1. The anchor was a guess. LargestComponentAnchor() returned a hardcoded
point near the (0,0) spine and the comment admitted it, so
NOT_CONNECTED meant "not connected to a guessed point". The flood fill
already knows the answer; it now returns LargestComponentPoint (tie-
broken by lowest cell index, so it stays deterministic),
LargestComponentCells and NumComponentsAtLeast1Pct.
2. "Connected to the largest component" is NOT the primordial law. The
law is that a player must not descend into a place they cannot leave
-- a question about MOUTHS. A strate can be 57 disconnected shafts and
be fine, provided the shaft you arrive in is the shaft you leave from.
The test now asks arrival -> departure per strate: the LowerPoint of
the passage arriving, to the UpperPoint of the passage departing.
3. A false verdict and a true one were indistinguishable. VF_AreConnected
returned false both when no route existed and when the endpoint's own
coarse cell sampled solid -- and a passage mouth is a carved tube whose
cell centre lands in adjacent rock easily. It now returns
EVoxelConnectivityResult and snaps to an adjacent air cell first,
reporting the repair.
RESULT: the earlier "5 of 15 endpoints disconnected" was an ARTIFACT of
the guessed anchor plus the wrong question. Corrected: 13 of 15 connected,
0 StartCellSolid, 0 GoalCellSolid.
One real finding survives. arrival -> departure passes for 5 of 6
applicable strates; VerticalShafts FAILS -- its arrival mouth is in the
largest component, its departure mouth is not. NOT yet reported as a bug:
a coarse grid can falsely SEPARATE as well as falsely join, and a
connecting corridor thinner than SampleStep vanishes. Next task settles
it at a finer step.
Also noted: GetPassages() contains a self-referential surface entry
(0 -> 0), excluded from the chain law.
Build clean, 18 succeeded / 0 warnings / 0 failed, verified in VoxelM.log.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bp7FxoQcSoiuhxjuLr6aBM