test(measure): the spine is the backbone in 7 of 8 strates -- and not in

VerticalShafts

Diagnosis only. No generation or placement changed.

The hypothesis was that the (0,0) spine (OriginSpineRadius 14) is the
universal connector, so "can this mouth reach the spine" would be the
real primordial-law test. Measured at margin 0, step 2, radius 192:

  strate           spine share  largest?  arr->spine   dep->spine
  TunnelNetwork      0.979        YES     CONNECTED    not connected
  FlatPlain          1.000        YES     CONNECTED    CONNECTED
  CrystalChamber     1.000        YES     CONNECTED    CONNECTED
  Maze               0.997        YES     coarse-lied  CONNECTED
  SurfaceWorld       1.000        YES     CONNECTED    CONNECTED
  VerticalShafts     0.096        NO      not conn.    not connected
  FloatingIslands    1.000        YES     CONNECTED    CONNECTED
  Underwater         0.999        YES     CONNECTED    n/a

The spine forms one uninterrupted open interior run in 8/8 strates, and
holds essentially ALL the air in 7 of them. VerticalShafts is the lone
anomaly: the spine punches through as an isolated column holding 9.6% of
the air and is NOT the largest component.

So the archetype has three mutually unreachable things -- the spine, the
arrival network, the departure network. It has no lateral connectivity at
all. Over 16 seeds: spine open 16/16, spine largest only 8/16,
arrival->spine 1 connected, departure->spine 0 connected.

Neither extreme was right. The spine is not a universal connector, but it
is far from irrelevant: it is the de-facto backbone everywhere except
here, which reframes the bug as an ANOMALY to bring in line rather than a
missing feature to invent.

Ordering hazard confirmed on the record: making passage i depend on
passage i-1 would break LayoutOrderIndependence. Both candidate fixes
avoid it, because the spine is a fixed deterministic anchor that two
mouths can target independently.

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:
Fr0zkaandClaude Opus 5 committed 2026-08-30 15:10:00 +02:00
1 parent 0bbfdeb7a7
commit 5519b323c8
4 files changed
+903 -146

No files matched your search

+177 -103
View File
@@ -891,6 +891,148 @@ namespace VoxelStrateMeasurePrivate
? -1.0f
: FMath::Sqrt(static_cast<float>(BestDistanceSquared));
}
void PopulateConnectivityDiagnostics(
const FSampleGrid& Grid,
int32 Start,
int32 Goal,
EVoxelConnectivityResult ConnectivityResult,
bool bStartSnapped,
bool bGoalSnapped,
FVoxelConnectivityDiagnostics& OutDiagnostics)
{
OutDiagnostics = FVoxelConnectivityDiagnostics();
OutDiagnostics.Result = ConnectivityResult;
OutDiagnostics.bStartSnapped = bStartSnapped;
OutDiagnostics.bGoalSnapped = bGoalSnapped;
OutDiagnostics.bValid = ConnectivityResult != EVoxelConnectivityResult::OutOfWindow
|| (Start >= 0 && Goal >= 0);
if (Start < 0 || Goal < 0)
{
return;
}
TArray<int32> Components;
int32 NumComponents = 0;
int64 LargestComponentCells = 0;
int32 LargestComponentLowestCell = INDEX_NONE;
int32 NumComponentsAtLeast1Pct = 0;
int64 NumAir = 0;
for (const uint8 bAir : Grid.Air)
{
NumAir += bAir != 0u ? 1 : 0;
}
FloodFillAir(
Grid,
Components,
NumComponents,
NumAir,
LargestComponentCells,
LargestComponentLowestCell,
NumComponentsAtLeast1Pct);
const int32 StartComponent = Components[Start];
const int32 GoalComponent = Components[Goal];
if (StartComponent < 0 || GoalComponent < 0)
{
return;
}
TArray<int32> ComponentCells;
ComponentCells.Init(0, NumComponents);
for (const int32 Component : Components)
{
if (Component >= 0)
{
++ComponentCells[Component];
}
}
OutDiagnostics.NumAirCells = NumAir;
OutDiagnostics.StartComponentCells = ComponentCells[StartComponent];
OutDiagnostics.GoalComponentCells = ComponentCells[GoalComponent];
OutDiagnostics.LargestComponentCells = LargestComponentCells;
if (NumAir > 0)
{
OutDiagnostics.StartComponentShare = static_cast<float>(
static_cast<double>(OutDiagnostics.StartComponentCells)
/ static_cast<double>(NumAir));
OutDiagnostics.GoalComponentShare = static_cast<float>(
static_cast<double>(OutDiagnostics.GoalComponentCells)
/ static_cast<double>(NumAir));
OutDiagnostics.LargestComponentShare = static_cast<float>(
static_cast<double>(LargestComponentCells)
/ static_cast<double>(NumAir));
}
OutDiagnostics.bStartComponentIsLargest =
OutDiagnostics.StartComponentCells == LargestComponentCells;
OutDiagnostics.bGoalComponentIsLargest =
OutDiagnostics.GoalComponentCells == LargestComponentCells;
OutDiagnostics.StartToGoalComponentDistanceCells = DistanceToComponent(
Grid, Start, GoalComponent, Components);
OutDiagnostics.GoalToStartComponentDistanceCells = DistanceToComponent(
Grid, Goal, StartComponent, Components);
}
EVoxelConnectivityResult QueryConnectivity(
const UVoxelGenerator& Generator,
const UVoxelStrateManager& Manager,
int32 StrateIndex,
const FVector& AVoxel,
const FVector& BVoxel,
const FVoxelStrateMeasureSettings& Settings,
bool& bOutStartSnapped,
bool& bOutGoalSnapped,
FVoxelConnectivityDiagnostics* OutDiagnostics)
{
bOutStartSnapped = false;
bOutGoalSnapped = false;
if (!FMath::IsFinite(AVoxel.X) || !FMath::IsFinite(AVoxel.Y)
|| !FMath::IsFinite(AVoxel.Z) || !FMath::IsFinite(BVoxel.X)
|| !FMath::IsFinite(BVoxel.Y) || !FMath::IsFinite(BVoxel.Z))
{
if (OutDiagnostics != nullptr)
{
*OutDiagnostics = FVoxelConnectivityDiagnostics();
}
return EVoxelConnectivityResult::OutOfWindow;
}
FSampleGrid Grid;
FString RefusalReason;
if (!BuildSampleGrid(Generator, Manager, StrateIndex, Settings, Grid, RefusalReason))
{
if (OutDiagnostics != nullptr)
{
*OutDiagnostics = FVoxelConnectivityDiagnostics();
}
return EVoxelConnectivityResult::OutOfWindow;
}
int32 Start = -1;
int32 Goal = -1;
const EVoxelConnectivityResult Result = EvaluateConnectivityOnGrid(
Generator,
Grid,
AVoxel,
BVoxel,
Start,
Goal,
bOutStartSnapped,
bOutGoalSnapped);
if (OutDiagnostics != nullptr)
{
PopulateConnectivityDiagnostics(
Grid,
Start,
Goal,
Result,
bOutStartSnapped,
bOutGoalSnapped,
*OutDiagnostics);
}
return Result;
}
}
FVoxelStrateMetrics VF_MeasureStrate(
@@ -929,33 +1071,39 @@ EVoxelConnectivityResult VF_AreConnected(
bool& bOutStartSnapped,
bool& bOutGoalSnapped)
{
bOutStartSnapped = false;
bOutGoalSnapped = false;
if (!FMath::IsFinite(AVoxel.X) || !FMath::IsFinite(AVoxel.Y) || !FMath::IsFinite(AVoxel.Z)
|| !FMath::IsFinite(BVoxel.X) || !FMath::IsFinite(BVoxel.Y) || !FMath::IsFinite(BVoxel.Z))
{
return EVoxelConnectivityResult::OutOfWindow;
}
VoxelStrateMeasurePrivate::FSampleGrid Grid;
FString RefusalReason;
if (!VoxelStrateMeasurePrivate::BuildSampleGrid(
Generator, Manager, StrateIndex, Settings, Grid, RefusalReason))
{
return EVoxelConnectivityResult::OutOfWindow;
}
int32 Start = -1;
int32 Goal = -1;
return VoxelStrateMeasurePrivate::EvaluateConnectivityOnGrid(
return VoxelStrateMeasurePrivate::QueryConnectivity(
Generator,
Grid,
Manager,
StrateIndex,
AVoxel,
BVoxel,
Start,
Goal,
Settings,
bOutStartSnapped,
bOutGoalSnapped);
bOutGoalSnapped,
nullptr);
}
EVoxelConnectivityResult VF_AreConnected(
const UVoxelGenerator& Generator,
const UVoxelStrateManager& Manager,
int32 StrateIndex,
const FVector& AVoxel,
const FVector& BVoxel,
const FVoxelStrateMeasureSettings& Settings,
bool& bOutStartSnapped,
bool& bOutGoalSnapped,
FVoxelConnectivityDiagnostics& OutDiagnostics)
{
return VoxelStrateMeasurePrivate::QueryConnectivity(
Generator,
Manager,
StrateIndex,
AVoxel,
BVoxel,
Settings,
bOutStartSnapped,
bOutGoalSnapped,
&OutDiagnostics);
}
FVoxelConnectivityDiagnostics VF_DiagnoseConnectivity(
@@ -967,89 +1115,15 @@ FVoxelConnectivityDiagnostics VF_DiagnoseConnectivity(
const FVoxelStrateMeasureSettings& Settings)
{
FVoxelConnectivityDiagnostics Result;
if (!FMath::IsFinite(AVoxel.X) || !FMath::IsFinite(AVoxel.Y) || !FMath::IsFinite(AVoxel.Z)
|| !FMath::IsFinite(BVoxel.X) || !FMath::IsFinite(BVoxel.Y) || !FMath::IsFinite(BVoxel.Z))
{
return Result;
}
VoxelStrateMeasurePrivate::FSampleGrid Grid;
FString RefusalReason;
if (!VoxelStrateMeasurePrivate::BuildSampleGrid(
Generator, Manager, StrateIndex, Settings, Grid, RefusalReason))
{
return Result;
}
int32 Start = -1;
int32 Goal = -1;
Result.Result = VoxelStrateMeasurePrivate::EvaluateConnectivityOnGrid(
VoxelStrateMeasurePrivate::QueryConnectivity(
Generator,
Grid,
Manager,
StrateIndex,
AVoxel,
BVoxel,
Start,
Goal,
Settings,
Result.bStartSnapped,
Result.bGoalSnapped);
Result.bValid = Result.Result != EVoxelConnectivityResult::OutOfWindow
|| (Start >= 0 && Goal >= 0);
if (Start < 0 || Goal < 0)
{
return Result;
}
TArray<int32> Components;
int32 NumComponents = 0;
int64 LargestComponentCells = 0;
int32 LargestComponentLowestCell = INDEX_NONE;
int32 NumComponentsAtLeast1Pct = 0;
int64 NumAir = 0;
for (const uint8 bAir : Grid.Air)
{
NumAir += bAir != 0u ? 1 : 0;
}
FloodFillAir(
Grid,
Components,
NumComponents,
NumAir,
LargestComponentCells,
LargestComponentLowestCell,
NumComponentsAtLeast1Pct);
const int32 StartComponent = Components[Start];
const int32 GoalComponent = Components[Goal];
if (StartComponent < 0 || GoalComponent < 0)
{
return Result;
}
TArray<int32> ComponentCells;
ComponentCells.Init(0, NumComponents);
for (const int32 Component : Components)
{
if (Component >= 0)
{
++ComponentCells[Component];
}
}
Result.NumAirCells = NumAir;
Result.StartComponentCells = ComponentCells[StartComponent];
Result.GoalComponentCells = ComponentCells[GoalComponent];
if (NumAir > 0)
{
Result.StartComponentShare = static_cast<float>(
static_cast<double>(Result.StartComponentCells) / static_cast<double>(NumAir));
Result.GoalComponentShare = static_cast<float>(
static_cast<double>(Result.GoalComponentCells) / static_cast<double>(NumAir));
}
Result.StartToGoalComponentDistanceCells =
VoxelStrateMeasurePrivate::DistanceToComponent(
Grid, Start, GoalComponent, Components);
Result.GoalToStartComponentDistanceCells =
VoxelStrateMeasurePrivate::DistanceToComponent(
Grid, Goal, StartComponent, Components);
Result.bGoalSnapped,
&Result);
return Result;
}