test(opstack): three tile scans sampled <1 lattice period; fix the CLASS this time
The "a sampler must cover at least one period" bug was found in the tunnel test (+/-32 vs RoomSpacing 80) and again in the shaft test (+/-48 vs ShaftSpacing 55). Both were fixed. The class was not: three box-verdict scans still ran the original RandRange(-6,6)*Extent at Step 1 / Cells 8, i.e. +/-48 voxels. Island +/-48 vs IslandSpacing 95 = 0.51 periods (worse than either fix) Slab +/-48 vs ColumnSpacing 60 = 0.80 periods Maze +/-48 vs CellSize 40 = 1.20 periods Verified the fixture does not override any of those spacings, so the header defaults are what these tests really ran against. This matters now specifically:7dbdf51changed the island and maze verdicts andeaa44bfchanged the slab column verdict, and these are the tests that guard them. Widening before the build is what makes that build's green mean anything. The rule the fixed tests already encoded, now explicit: Extent = 8, so SpanCells = the lattice spacing gives exactly 8 periods -- which is where the shaft test's 55 came from. Island 95, Slab 60, Maze 40, each printing the ratio computed LIVE from the params struct so a future narrowing cannot be silent. No assertion, tolerance, AddError, brute-force loop, seed, Step, Cells or tile count was touched: this changes what the measurement looks at, never what it demands. Proved counts will move (expected); NumUnsound must stay 0. Test-only -- git diff lists three files under Private/Tests/. Not built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -235,14 +235,18 @@ bool FVoxelForgeOpStackIslandTest::RunTest(const FString& Parameters)
|
||||
{
|
||||
int32 NumProvedSolid = 0, NumProvedAir = 0, NumMixed = 0, NumUnsound = 0;
|
||||
FRandomStream Rng(24680);
|
||||
// Hors de la boucle : la ligne de rapport en a besoin. Une étendue d'échantillonnage qu'on
|
||||
// ne peut pas citer dans le rapport est une étendue que personne ne surveille.
|
||||
const int32 SpanCells = 95;
|
||||
const int32 SpanVoxels = SpanCells * 8; // Extent = Step * Cells = 1 * 8
|
||||
|
||||
for (int32 t = 0; t < 60; ++t)
|
||||
{
|
||||
const int32 Step = 1, Cells = 8;
|
||||
const int32 Extent = Step * Cells;
|
||||
const FIntVector Origin(
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
FMath::Clamp(Rng.RandRange(BottomVoxelZ / Extent, TopVoxelZ / Extent), -4096, 4096) * Extent);
|
||||
|
||||
const int32 GridDim = Cells + 1;
|
||||
@@ -289,10 +293,12 @@ bool FVoxelForgeOpStackIslandTest::RunTest(const FString& Parameters)
|
||||
TestEqual(TEXT("every box verdict the island stack emits survives brute force"), NumUnsound, 0);
|
||||
|
||||
AddInfo(FString::Printf(
|
||||
TEXT("Box verdicts over 60 FloatingIslands tiles: %d proved AllSolid, %d proved AllAir, ")
|
||||
TEXT("Box verdicts over 60 FloatingIslands tiles (XY sampled from +/- %d voxels = %.1f x ")
|
||||
TEXT("IslandSpacing %.0f): %d proved AllSolid, %d proved AllAir, ")
|
||||
TEXT("%d Mixed. Today's ClassifyTile proves ZERO of these. The AllAir count is the new ")
|
||||
TEXT("thing: no cave archetype has ever been able to prove 'all air', and a floating-")
|
||||
TEXT("island strate is mostly exactly that (OPSTACK-DECOMPOSITION 7)."),
|
||||
SpanVoxels, (float)SpanVoxels / FMath::Max(P.IslandSpacing, 1.0f), P.IslandSpacing,
|
||||
NumProvedSolid, NumProvedAir, NumMixed));
|
||||
|
||||
if (NumProvedAir == 0)
|
||||
|
||||
@@ -267,14 +267,18 @@ bool FVoxelForgeOpStackMazeTest::RunTest(const FString& Parameters)
|
||||
{
|
||||
int32 NumProved = 0, NumMixed = 0, NumUnsound = 0;
|
||||
FRandomStream Rng(24680);
|
||||
// Hors de la boucle : la ligne de rapport en a besoin. Une étendue d'échantillonnage qu'on
|
||||
// ne peut pas citer dans le rapport est une étendue que personne ne surveille.
|
||||
const int32 SpanCells = 40;
|
||||
const int32 SpanVoxels = SpanCells * 8; // Extent = Step * Cells = 1 * 8
|
||||
|
||||
for (int32 t = 0; t < 60; ++t)
|
||||
{
|
||||
const int32 Step = 1, Cells = 8; // petites tuiles : force brute tenable
|
||||
const int32 Extent = Step * Cells;
|
||||
const FIntVector Origin(
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
FMath::Clamp(Rng.RandRange(BottomVoxelZ / Extent, TopVoxelZ / Extent), -4096, 4096) * Extent);
|
||||
|
||||
const int32 GridDim = Cells + 1; // le MÊME treillis que le mesher, marge ±1 comprise
|
||||
@@ -319,9 +323,11 @@ bool FVoxelForgeOpStackMazeTest::RunTest(const FString& Parameters)
|
||||
NumUnsound, 0);
|
||||
|
||||
AddInfo(FString::Printf(
|
||||
TEXT("Box verdicts over 60 Maze tiles: %d proved uniform, %d Mixed. Today's ClassifyTile ")
|
||||
TEXT("Box verdicts over 60 Maze tiles (XY sampled from +/- %d voxels = %.1f x ")
|
||||
TEXT("CellSize %.0f): %d proved uniform, %d Mixed. Today's ClassifyTile ")
|
||||
TEXT("proves ZERO of these -- every cave archetype falls through to \"pas prouvable en ")
|
||||
TEXT("v1\". Any number above zero here is tile-skipping Maze has never had."),
|
||||
SpanVoxels, (float)SpanVoxels / FMath::Max(MazeParams.CellSize, 1.0f), MazeParams.CellSize,
|
||||
NumProved, NumMixed));
|
||||
|
||||
if (NumProved == 0)
|
||||
|
||||
@@ -280,14 +280,18 @@ bool FVoxelForgeOpStackSlabTest::RunTest(const FString& Parameters)
|
||||
{
|
||||
int32 NumProved = 0, NumMixed = 0, NumUnsound = 0;
|
||||
FRandomStream Rng(24680 + SlotIndex);
|
||||
// Hors de la boucle : la ligne de rapport en a besoin. Une étendue d'échantillonnage qu'on
|
||||
// ne peut pas citer dans le rapport est une étendue que personne ne surveille.
|
||||
const int32 SpanCells = 60;
|
||||
const int32 SpanVoxels = SpanCells * 8; // Extent = Step * Cells = 1 * 8
|
||||
|
||||
for (int32 t = 0; t < NumSlabTiles; ++t)
|
||||
{
|
||||
const int32 Step = 1, Cells = 8;
|
||||
const int32 Extent = Step * Cells;
|
||||
const FIntVector Origin(
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-6, 6) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
Rng.RandRange(-SpanCells, SpanCells) * Extent,
|
||||
FMath::Clamp(Rng.RandRange(BottomVoxelZ / Extent, TopVoxelZ / Extent), -4096, 4096) * Extent);
|
||||
|
||||
const int32 GridDim = Cells + 1; // le MÊME treillis que le mesher, marge ±1 comprise
|
||||
@@ -335,10 +339,13 @@ bool FVoxelForgeOpStackSlabTest::RunTest(const FString& Parameters)
|
||||
NumUnsound, 0);
|
||||
|
||||
AddInfo(FString::Printf(
|
||||
TEXT("%s box verdicts over %d tiles: %d proved uniform, %d Mixed. Today's ")
|
||||
TEXT("%s box verdicts over %d tiles (XY sampled from +/- %d voxels = %.1f x ")
|
||||
TEXT("ColumnSpacing %.0f): %d proved uniform, %d Mixed. Today's ")
|
||||
TEXT("ClassifyTile proves ZERO of these. This number is the whole point of making ")
|
||||
TEXT("the slab surfaces XY-pure (OPSTACK-DECOMPOSITION 3.1)."),
|
||||
SlotName, NumSlabTiles, NumProved, NumMixed));
|
||||
SlotName, NumSlabTiles, SpanVoxels,
|
||||
(float)SpanVoxels / FMath::Max(SlabParams.ColumnSpacing, 1.0f), SlabParams.ColumnSpacing,
|
||||
NumProved, NumMixed));
|
||||
|
||||
if (NumProved == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user