feat(composer): lateral REGIONS -- built, measured, and gated OFF

Jahni's own idea: "archetype could even mix within the same strate at some
point, tunnel network leading to a big chamber". An archetype becomes a
spatial REGION inside a strate, not a label on it.

Built by extending the mechanism that already exists rather than inventing
one: the stack blends VERTICALLY between strates, so regions blend the same
way LATERALLY. Deterministic jittered Voronoi sites on a 256-voxel lattice,
1-3 regions per strate from (seed, strateIndex), 24-voxel symmetric blend
band, per-chunk lookup cache. Parameters are never blended -- a shaft's
ShaftSpacing means nothing to a slab -- only the resulting DENSITY is.
Structural posts stay global and unconditional, so an invented region
cannot switch off the primordial law.

  single-region path   BIT-IDENTICAL to legacy, 256 probes, native + recipe
  cross-boundary boxes 20 of 40, 199,800 voxels brute-forced, 0 VIOLATIONS
                       (every seam-spanning box correctly returned Mixed)
  blend-band cost      663 ns vs 338 ns per voxel, over 16.0% of voxels
                       ~1.15x field-weighted
  survival             16/16 valid, non-vacuous, largest share >= .50

⛔ AND IT IS GATED OFF, because the seam breaks the one law that matters:
arrival -> departure across a region boundary passes 9/16 seeds, against
11/16 same-region controls in the same harness. Density blending alone does
not guarantee a player can cross a seam. A strate that mixes archetypes and
strands you at the boundary is strictly worse than one that does not mix.

VF_LateralRegionsAreShippable() returns false and the test ASSERTS THE GATE
IS SHUT while the rate is imperfect -- so flipping it without fixing
connectivity turns the suite red by design. The rate is a warning, not an
assertion: it is the measured state of an off-by-default feature, not a
regression in a live world, and a permanently red suite stops being read,
which is how real failures get missed.

Everything that ships is still hard-guarded: single-region bit-identity,
zero cross-boundary box violations, and every shipping-path law test
untouched.

The fix is an explicit CROSS-SEAM CORRIDOR CONTRACT -- a design decision,
recorded rather than made unilaterally. Codex diagnosed this correctly and
declined to tune the threshold, which was the right call.

Build clean, 29 succeeded / 0 failed, run and verified by me.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJiTcTSDNkKBtnNdiBtdaU
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-05 05:06:32 +02:00
1 parent 42e1f0ec8c
commit dd38832bb6
14 files changed
+3040 -48

No files matched your search

+42 -4
View File
@@ -194,6 +194,7 @@ namespace
const FVoxelStrateComposerCandidate& Candidate,
const UVoxelGenerator& Generator,
const UVoxelStrateManager& StrateManager,
int32 TargetStrateIndex,
int32 TargetTopChunkZ,
int32 TargetBottomChunkZ,
FVoxelOpStack& OutStack,
@@ -206,7 +207,24 @@ namespace
VF_SetComposerRuntimeBounds(Params, TopWorldZ, BottomWorldZ);
bool bBuilt = false;
if (Candidate.bStructureRoll)
if (Candidate.Regions.RegionCount > 1)
{
FVoxelStrateRegionManifest RegionManifest = Candidate.Regions;
VF_RekeyStrateRegionManifest(RegionManifest, Candidate.Seed,
TargetStrateIndex);
RegionManifest.StrateTopWorldZ = TopWorldZ;
RegionManifest.StrateBottomWorldZ = BottomWorldZ;
RegionManifest.bHasGlobalStructuralParams = true;
for (FVoxelStrateRegion& Region : RegionManifest.Regions)
{
VF_SetStrateArchetypeRuntimeBounds(Region.ArchetypeParams,
TopWorldZ, BottomWorldZ);
}
bBuilt = VF_BuildStrateRegionStack(
RegionManifest, Generator.OriginSpineRadius, &StrateManager,
OutStack, OutContext, &OutError);
}
else if (Candidate.bStructureRoll)
{
bBuilt = VF_BuildStackFromRecipe(
Candidate.Recipe, Params, Generator.Seed, Generator.OriginSpineRadius,
@@ -573,7 +591,25 @@ void AVoxelWorld::ApplyComposerCandidate()
FVoxelOpContext PreflightContext;
FString PreflightError;
bool bPreflightBuilt = false;
if (Candidate.bStructureRoll)
FVoxelStrateRegionManifest PreflightRegions;
if (Candidate.Regions.RegionCount > 1)
{
PreflightRegions = Candidate.Regions;
VF_RekeyStrateRegionManifest(PreflightRegions, Candidate.Seed,
ComposerTargetStrateIndex);
PreflightRegions.StrateTopWorldZ = TargetTopWorldZ;
PreflightRegions.StrateBottomWorldZ = TargetBottomWorldZ;
PreflightRegions.bHasGlobalStructuralParams = true;
for (FVoxelStrateRegion& Region : PreflightRegions.Regions)
{
VF_SetStrateArchetypeRuntimeBounds(Region.ArchetypeParams,
TargetTopWorldZ, TargetBottomWorldZ);
}
bPreflightBuilt = VF_BuildStrateRegionStack(
PreflightRegions, Generator->OriginSpineRadius, StrateManager,
PreflightStack, PreflightContext, &PreflightError);
}
else if (Candidate.bStructureRoll)
{
bPreflightBuilt = VF_BuildStackFromRecipe(
Candidate.Recipe, PreflightParams, Generator->Seed, Generator->OriginSpineRadius,
@@ -615,7 +651,8 @@ void AVoxelWorld::ApplyComposerCandidate()
if (!StrateManager->SetComposerOverrideForStrate(
ComposerTargetStrateIndex, Candidate.Seed, Candidate.Archetype,
Candidate.ArchetypeParams, Candidate.bStructureRoll,
Candidate.bStructureRoll ? &Candidate.Recipe : nullptr, ApplyError))
Candidate.bStructureRoll ? &Candidate.Recipe : nullptr, ApplyError,
Candidate.Regions.RegionCount > 1 ? &Candidate.Regions : nullptr))
{
UE_LOG(LogTemp, Error,
TEXT("[VoxelWorld] ApplyComposerCandidate: seed=%d index=%d was not applied: %s"),
@@ -638,7 +675,8 @@ void AVoxelWorld::ApplyComposerCandidate()
FVoxelOpContext ReferenceContext;
FString ReferenceError;
const bool bReferenceBuilt = VF_BuildComposerReferenceStack(
Candidate, *Generator, *StrateManager, TargetTopChunkZ, TargetBottomChunkZ,
Candidate, *Generator, *StrateManager, ComposerTargetStrateIndex,
TargetTopChunkZ, TargetBottomChunkZ,
ReferenceStack, ReferenceContext, ReferenceError);
FString ComparableReason;