refactor(core): boundary policy as resolved capabilities, not generator-name tests (L42, step 6); R9

ResolvedLayoutSnapshotV3::finalize maps each strate's generator and interface once into capability
records (FI gradient air-gap, surface/FI landing support, passage-anchor columns, SW-to-TN floor);
ApplyResolvedStrateBoundaryBand and passage composition read those instead of generator kinds. Derived
records stay out of canonical JSON, so layout identity is unchanged. Owner hashes identical to L41;
fast/medium/full PASS on clean Clang and GCC builds; cost within noise.
Research R9 (read-only): player-visible roadmap refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-23 20:22:49 +02:00
1 parent 1abee91721
commit 2566f53734
8 files changed
+204 -15

No files matched your search

@@ -729,6 +729,22 @@ namespace VoxelForgeCore
std::int64_t solidDensityQ16 = 1ll << 16;
};
// Runtime policy resolved once from the director's immutable strate/interface
// description. These derived capabilities are deliberately omitted from canonical
// JSON: their source fields are already hashed and the records preserve that identity.
struct ResolvedLayoutStratePassageCapabilitiesV1
{
bool hasSurfaceLanding = false;
bool hasFloatingIslandLanding = false;
bool usePassageAnchorForColumns = false;
};
struct ResolvedLayoutInterfaceCapabilitiesV1
{
bool preserveUpperBedrockAirGap = false;
bool surfaceToTunnelLandingSupport = false;
};
struct ResolvedLayoutStratumV2
{
std::string stableId;
@@ -758,6 +774,8 @@ namespace VoxelForgeCore
std::int64_t managerChunkWidthMicrometres = 0;
std::int64_t dispatchChunkWidthMicrometres = 0;
std::vector<ResolvedLayoutAnchorV2> anchors;
ResolvedLayoutStratePassageCapabilitiesV1 passageCapabilities;
ResolvedLayoutInterfaceCapabilitiesV1 lowerInterfaceCapabilities;
};
/** Per-column resolved bands for one adjacent bedrock/ceiling interface.
@@ -409,6 +409,26 @@ bool ResolvedLayoutSnapshotV3::finalize(std::string& error)
if(x.bedrock.kind.empty())x.bedrock.kind="bedrock";
if(x.interiorTopMicrometres<=x.interiorBottomMicrometres||x.voxelSizeMicrometres==0)
{error="resolved layout contains an invalid interior interval or voxel size";return false;}
// Materialize generator-specific composition policy at layout resolution. The
// sampling/composition path consumes these capabilities without examining names.
x.passageCapabilities={};
x.lowerInterfaceCapabilities={};
if(x.generatorKind=="SurfaceWorld")
x.passageCapabilities.hasSurfaceLanding=true;
else if(x.generatorKind=="FloatingIslands")
{
x.passageCapabilities.hasFloatingIslandLanding=true;
x.passageCapabilities.usePassageAnchorForColumns=true;
}
if(i+1<strates.size())
{
const auto& lower=strates[i+1];
x.lowerInterfaceCapabilities.preserveUpperBedrockAirGap=
x.generatorKind=="FloatingIslands"&&x.transitionMode=="Gradient";
x.lowerInterfaceCapabilities.surfaceToTunnelLandingSupport=
x.generatorKind=="SurfaceWorld"&&lower.generatorKind=="TunnelNetwork";
}
}
const std::int64_t playerCenterAboveFloorQ=static_cast<std::int64_t>(std::llround(
1.13*WorldAssemblySubvoxelsPerVoxel*1000000.0/coreVoxelSizeMicrometres));
+9 -11
View File
@@ -807,8 +807,7 @@ public:
solidTop-zMicrometres));
const std::int64_t seam=transitionUpper->bedrock.bottomMicrometres;
const bool floatingIslandAirGap=
transitionUpper->generatorKind=="FloatingIslands"
&&transitionUpper->transitionMode=="Gradient"
transitionUpper->lowerInterfaceCapabilities.preserveUpperBedrockAirGap
&&bands.upperBedrockTopMicrometres<seam
&&zMicrometres>=bands.upperBedrockTopMicrometres
&&zMicrometres<seam;
@@ -876,8 +875,8 @@ public:
:-static_cast<double>(std::min(zMicrometres-solidBottom,
solidTop-zMicrometres));
const std::int64_t seam=upper->bedrock.bottomMicrometres;
const bool floatingIslandAirGap=upper->generatorKind=="FloatingIslands"
&&upper->transitionMode=="Gradient"
const bool floatingIslandAirGap=
upper->lowerInterfaceCapabilities.preserveUpperBedrockAirGap
&&resolvedBands.upperBedrockTopMicrometres<seam
&&zMicrometres>=resolvedBands.upperBedrockTopMicrometres
&&zMicrometres<seam;
@@ -1015,10 +1014,9 @@ public:
const auto* supportUpper=supportStratum(passage.upperStrateIndex);
const auto* supportLower=supportStratum(passage.lowerStrateIndex);
const bool floatingIslandPassage=supportUpper
&&supportUpper->generatorKind=="FloatingIslands";
&&supportUpper->passageCapabilities.hasFloatingIslandLanding;
const bool surfaceToTunnelSupport=supportUpper&&supportLower
&&supportUpper->generatorKind=="SurfaceWorld"
&&supportLower->generatorKind=="TunnelNetwork";
&&supportUpper->lowerInterfaceCapabilities.surfaceToTunnelLandingSupport;
const double firstFloorQ=passage.controlPoints.front().positionSubvoxels[2]
-passage.controlPoints.front().radiusSubvoxels+playerCenterAboveFloorQ;
const double lastFloorQ=passage.controlPoints.back().positionSubvoxels[2]
@@ -3466,7 +3464,7 @@ private:
ResolvedLayout->strates.end(),[strate](const auto& value)
{return value.strateIndex==strate;});
surfaceWorldUpper=upper!=ResolvedLayout->strates.end()
&&upper->generatorKind=="SurfaceWorld";
&&upper->passageCapabilities.hasSurfaceLanding;
}
const std::size_t shortSpanPadding=!crossing.needsColumn
&&surfaceWorldUpper&&!flags.empty()?2:0;
@@ -3737,7 +3735,7 @@ private:
ResolvedLayout->strates.end(),[&passage](const auto& value)
{return value.strateIndex==passage.upperStrateIndex;});
const bool surfaceWorldUpper=upperStratum!=ResolvedLayout->strates.end()
&&upperStratum->generatorKind=="SurfaceWorld";
&&upperStratum->passageCapabilities.hasSurfaceLanding;
const double ax=static_cast<double>(a.positionSubvoxels[0]);
const double ay=static_cast<double>(a.positionSubvoxels[1]);
const double dx=static_cast<double>(b.positionSubvoxels[0])-ax;
@@ -3949,7 +3947,7 @@ private:
ResolvedLayout->strates.end(),[&passage](const auto& value)
{return value.strateIndex==passage.upperStrateIndex;});
const bool surfaceWorldUpper=upperStratum!=ResolvedLayout->strates.end()
&&upperStratum->generatorKind=="SurfaceWorld";
&&upperStratum->passageCapabilities.hasSurfaceLanding;
if(passage.controlPoints.size()<2)continue;
std::vector<FPathSample> samples;
samples.reserve(passage.controlPoints.size()*2);
@@ -4029,7 +4027,7 @@ private:
?static_cast<std::int64_t>(std::llround(static_cast<double>(sumY)/centerSamples)):0;
for(const auto& stratum:ResolvedLayout->strates)
if(stratum.strateIndex==passage.upperStrateIndex
&&stratum.generatorKind=="FloatingIslands")
&&stratum.passageCapabilities.usePassageAnchorForColumns)
for(const auto& anchor:stratum.anchors)
if(anchor.kind=="passage_anchor"&&anchor.values.size()>=2)
{