test: the slab test proved less than it claimed — add the pass that varies CeilingRoughness
SlabEquivalence came back green (FlatPlain 36/60 and CrystalChamber 40/60 tiles proved uniform, vs zero for today's ClassifyTile; 52/20000 ULP-scale diffs, 0 isosurface crossings). But both archetypes reported the SAME 52 and the same worst delta, which pointed at the fixture: FTestWorld::Build sets only GeneratorType, so both slots carry DEFAULT slab params. So the two passes were the same configuration at two depths. The test claimed to demonstrate "one op, two archetypes" while never varying CeilingRoughness — the only field that actually distinguishes CrystalChamber. The differing tile counts come from the slots' Z ranges, not from the archetypes. Third pass added: CrystalChamber(tuned), CeilingRoughness 6 -> 20, rougher floor, 3x the columns. It varies what matters and doubles as the worst case for the ClassifyBox amplitude bounds — a large CeilingRoughness widens the ceiling band and makes the FloorSurface + 2 clamp far more likely to bind, which is precisely where a false verdict would be a hole. The default params were too gentle to stress it. The ULP residue is left alone: deterministic, 0 isosurface crossings, and the same shape C10 already cost six builds to prove not worth chasing. UNVERIFIED: the third pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -942,3 +942,51 @@ a FlatPlain or CrystalChamber strate for the visual A/B. Expect the floor/ceilin
|
||||
changed from the Z-term removal; the question is whether it still reads as the same *kind* of place.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-27 — SlabEquivalence GREEN. The §3.1 payoff is measured: 36 and 40 of 60 tiles.
|
||||
|
||||
```
|
||||
FlatPlain box verdicts over 60 tiles: 36 proved uniform, 24 Mixed
|
||||
CrystalChamber box verdicts over 60 tiles: 40 proved uniform, 20 Mixed
|
||||
both: 52 of 20000 samples differ, ALL at ULP scale, 0 cross the isosurface
|
||||
```
|
||||
|
||||
**This is the number the whole §3.1 question was about, and it is better than Maze's.** Maze proved
|
||||
23 of 60; the slab archetypes prove **36 and 40** — 60-67 % of tiles, where `ClassifyTile` proves
|
||||
**zero** for these two today. The reason is structural rather than lucky: a slab strate is mostly
|
||||
solid rock below its floor, and now that both surfaces are XY-pure their Z bands are known exactly,
|
||||
so "this tile is entirely below the floor band" is a comparison rather than a sample.
|
||||
|
||||
**The ULP residue is the known C10 floor** — 52/20000, 0 isosurface crossings, worst delta 2⁻¹⁸
|
||||
(exactly 1 ULP at a density magnitude of ~32). **Not investigated, on purpose.** Same shape as C10:
|
||||
deterministic, ULP-scale, zero consequence, and six builds were already spent proving that shape is
|
||||
not worth chasing.
|
||||
|
||||
### The output exposed a real weakness in my own test — fixed
|
||||
|
||||
Both archetypes reported **the same 52 and the same worst delta**. The explanation is in the
|
||||
fixture: `FTestWorld::Build` sets only `GeneratorType`, so **FlatPlain and CrystalChamber both get
|
||||
DEFAULT `FSlabGenerationParams`.** They are the same configuration at two depths.
|
||||
|
||||
So the test's claim #2 was overstated. It demonstrated "the slab stack works at two depths", not
|
||||
"one op serves two archetypes with different defaults" — **`CeilingRoughness`, the one field that
|
||||
actually distinguishes CrystalChamber, was never varied.** The differing tile counts (36 vs 40)
|
||||
come from the two slots' Z ranges, not from the archetypes differing.
|
||||
|
||||
**A third pass added: `CrystalChamber(tuned)`** — `CeilingRoughness` 6 → 20, plus a rougher floor
|
||||
and 3× the columns. It varies what actually matters, and it is deliberately the **worst case for
|
||||
`ClassifyBox`**: a large `CeilingRoughness` widens the ceiling band and makes the
|
||||
`Max(CeilZ - noise, FloorSurface + 2)` clamp far more likely to bind, which is exactly where a
|
||||
false verdict — a HOLE — would appear. The default params were too gentle to stress that bound.
|
||||
|
||||
**UNVERIFIED:** the third pass. Its box-verdict brute force is the part that matters; expect fewer
|
||||
tiles proved uniform than the gentle passes (wider bands ⇒ more Mixed), and **zero** unsound
|
||||
verdicts. If `NumUnsound > 0` here, the `CeilHi` bound in `FSlabVoidSource::ClassifyBox` is the
|
||||
first suspect, not the noise contract.
|
||||
|
||||
**Next single action:** rebuild, confirm the tuned pass is green, then the visual A/B on a FlatPlain
|
||||
or CrystalChamber strate. The floor/ceiling shape WILL differ from before (the Z-term removal); the
|
||||
question is whether it still reads as the same kind of place. Then `SurfaceWorld`
|
||||
(OPSTACK-DECOMPOSITION §5) — biggest payoff, most care.
|
||||
|
||||
---
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
// 2. UN OPÉRATEUR, DEUX ARCHÉTYPES — la MÊME pile est vérifiée contre FlatPlain ET
|
||||
// CrystalChamber. `GetSlabDensity` ne les distingue par aucun branchement ; si la pile a
|
||||
// besoin d'en faire un, la fusion est fausse et ce test le dit.
|
||||
// ⚠️ La fixture ne règle que `GeneratorType`, donc les deux slots portent des params PAR
|
||||
// DÉFAUT : à eux seuls ils exécutent la même configuration à deux profondeurs. C'est la
|
||||
// TROISIÈME passe (`CrystalChamber(tuned)`, `CeilingRoughness` 6 → 20) qui fait réellement
|
||||
// varier ce qui distingue les deux archétypes — et qui sert en même temps de pire cas aux
|
||||
// bornes d'amplitude de `ClassifyBox`. Voir le bloc en bas de fichier.
|
||||
// 3. LE VERDICT DE BOÎTE — et c'est ici que §3.1 se paie. `ClassifyTile` prouve ZÉRO tuile pour
|
||||
// FlatPlain et CrystalChamber aujourd'hui. Depuis que les deux surfaces sont XY-PURES, leurs
|
||||
// bornes en Z sont connues exactement (contrat [-1,1] de FBM), donc toute tuile entièrement
|
||||
@@ -76,21 +81,10 @@ bool FVoxelForgeOpStackSlabTest::RunTest(const FString& Parameters)
|
||||
//=========================================================================
|
||||
// Exécutée à l'identique sur FlatPlain et CrystalChamber. Si les deux passent avec la MÊME
|
||||
// pile et la MÊME fabrique, la fusion des deux archétypes est démontrée plutôt qu'affirmée.
|
||||
auto RunForSlot = [&](int32 SlotIndex, const TCHAR* SlotName)
|
||||
auto RunBattery = [&](const FSlabGenerationParams& SlabParams,
|
||||
int32 TopVoxelZ, int32 BottomVoxelZ,
|
||||
int32 SlotIndex, const TCHAR* SlotName)
|
||||
{
|
||||
int32 TopVoxelZ = 0, BottomVoxelZ = 0;
|
||||
if (!World.GetSlotVoxelZRange(SlotIndex, TopVoxelZ, BottomVoxelZ))
|
||||
{
|
||||
AddError(FString::Printf(
|
||||
TEXT("The fixture layout has no %s slot. Check FTestWorld::Build's Archetypes[] ")
|
||||
TEXT("against FTestWorld::Slot%s."), SlotName, SlotName));
|
||||
return;
|
||||
}
|
||||
|
||||
const int32 MidChunkZ = ((TopVoxelZ + BottomVoxelZ) / 2) / CHUNK_SIZE;
|
||||
const FSlabGenerationParams SlabParams =
|
||||
World.StrateManager->GetSlabParamsForChunk(FIntVector(0, 0, MidChunkZ));
|
||||
|
||||
// `GetSlabDensity` court-circuite sur une strate dégénérée (`return 1.0f`). Cette garde
|
||||
// appartient à la fonction d'archétype, pas à un opérateur ; la pile suppose une strate
|
||||
// valide, et `GetDensityAt` retombe sur le `switch` dans ce cas.
|
||||
@@ -303,8 +297,66 @@ bool FVoxelForgeOpStackSlabTest::RunTest(const FString& Parameters)
|
||||
}
|
||||
};
|
||||
|
||||
RunForSlot(FTestWorld::SlotFlatPlain, TEXT("FlatPlain"));
|
||||
RunForSlot(FTestWorld::SlotCrystalChamber, TEXT("CrystalChamber"));
|
||||
//=========================================================================
|
||||
// LES TROIS PASSES
|
||||
//=========================================================================
|
||||
auto ResolveSlot = [&](int32 SlotIndex, const TCHAR* SlotName,
|
||||
FSlabGenerationParams& OutParams, int32& OutTop, int32& OutBottom) -> bool
|
||||
{
|
||||
if (!World.GetSlotVoxelZRange(SlotIndex, OutTop, OutBottom))
|
||||
{
|
||||
AddError(FString::Printf(
|
||||
TEXT("The fixture layout has no %s slot. Check FTestWorld::Build's Archetypes[] ")
|
||||
TEXT("against FTestWorld::Slot%s."), SlotName, SlotName));
|
||||
return false;
|
||||
}
|
||||
const int32 MidChunkZ = ((OutTop + OutBottom) / 2) / CHUNK_SIZE;
|
||||
OutParams = World.StrateManager->GetSlabParamsForChunk(FIntVector(0, 0, MidChunkZ));
|
||||
return true;
|
||||
};
|
||||
|
||||
FSlabGenerationParams FlatParams, CrystalParams;
|
||||
int32 FlatTop = 0, FlatBottom = 0, CrystalTop = 0, CrystalBottom = 0;
|
||||
|
||||
if (ResolveSlot(FTestWorld::SlotFlatPlain, TEXT("FlatPlain"), FlatParams, FlatTop, FlatBottom))
|
||||
{
|
||||
RunBattery(FlatParams, FlatTop, FlatBottom, FTestWorld::SlotFlatPlain, TEXT("FlatPlain"));
|
||||
}
|
||||
|
||||
if (ResolveSlot(FTestWorld::SlotCrystalChamber, TEXT("CrystalChamber"),
|
||||
CrystalParams, CrystalTop, CrystalBottom))
|
||||
{
|
||||
RunBattery(CrystalParams, CrystalTop, CrystalBottom,
|
||||
FTestWorld::SlotCrystalChamber, TEXT("CrystalChamber"));
|
||||
|
||||
//=====================================================================
|
||||
// LA PASSE QUI FAIT VRAIMENT LA DÉMONSTRATION
|
||||
//=====================================================================
|
||||
// ⚠️ La fixture ne règle QUE `GeneratorType` : FlatPlain et CrystalChamber y reçoivent des
|
||||
// `FSlabGenerationParams` PAR DÉFAUT, donc identiques. Les deux passes ci-dessus exécutent
|
||||
// en réalité la même configuration à deux profondeurs — ce qui est un test utile, mais qui
|
||||
// ne démontre PAS « un opérateur, deux jeux de défauts » : `CeilingRoughness`, la seule
|
||||
// chose qui distingue réellement CrystalChamber, n'y varie jamais.
|
||||
//
|
||||
// Cette passe-ci fait varier ce qui compte, et elle est aussi le PIRE CAS pour les bornes
|
||||
// d'amplitude de `ClassifyBox` : un `CeilingRoughness` élevé élargit la bande du plafond et
|
||||
// rend le clamp `Max(CeilZ - bruit, FloorSurface + 2)` beaucoup plus susceptible de mordre.
|
||||
// Si un verdict de boîte est faux quelque part, c'est ici qu'il apparaît.
|
||||
//
|
||||
// The fixture only sets GeneratorType, so both slots get DEFAULT slab params — the two
|
||||
// passes above are the same configuration at two depths. This pass varies what actually
|
||||
// distinguishes CrystalChamber, and is simultaneously the worst case for the ClassifyBox
|
||||
// amplitude bounds: a large CeilingRoughness widens the ceiling band and makes the
|
||||
// FloorSurface + 2 clamp far more likely to bind.
|
||||
FSlabGenerationParams Tuned = CrystalParams;
|
||||
Tuned.CeilingRoughness = 20.0f; // vs 6.0 par défaut — de vraies stalactites
|
||||
Tuned.CeilingRoughnessFrequency = 0.09f;
|
||||
Tuned.FloorRoughness = 9.0f;
|
||||
Tuned.ColumnDensity = 0.25f; // beaucoup plus de colonnes ⇒ FillOnly plus souvent
|
||||
Tuned.ColumnMaxRadius = 11.0f;
|
||||
|
||||
RunBattery(Tuned, CrystalTop, CrystalBottom, 64, TEXT("CrystalChamber(tuned)"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user