parity: Unreal and headless resolve the same four-strate plan (L70, v214)
- Export commandlet writes the live Core adapter's world_assembly + resolved layout pair; the headless owner path imports that pair (manifest/layout equal, layout_chunk_width_q validated). owner_world.json re-exported from the owner's staged assets on the Linux host. - Adapter SW route: Core clearance/radius floors, 0.5 m support search, outward-facing tie-break; passage mouth/mid radius floors match Core (36/24 owner voxels). - FI in Unreal now uses the legacy (compiled analytic) generator unless a plan is imported: the auto native-FI plan failed the passage audit on the owner plan (1843 blocked samples, 945 open-air violations). Owner decides whether native FI returns. - In-engine spawn traces per strate (3 each): SW GenerateTile 42.7 worker-s vs 20.1 headless for equal tile counts; LOD0 p95 45-169 ms in UE. - Fast tier green; all three passages pass on the shared plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
81e2452a3d
commit
bd68aee1ca
16 files changed
+939
-62
No files matched your search
@@ -255,7 +255,10 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
constexpr std::int64_t HalfHeightQ = PlayerHeightQ / 2;
|
||||
constexpr std::int64_t StepQ = 128;
|
||||
constexpr std::int64_t ProbeRadiusQ = 174;
|
||||
constexpr std::int64_t SupportDepthQ = 256;
|
||||
// The live owner surface recipe can sit slightly below the fixed-point route
|
||||
// heightfield used during candidate search; allow up to 0.5 m for the final
|
||||
// resolved-field support probe before rejecting an otherwise clear route.
|
||||
constexpr std::int64_t SupportDepthQ = 512;
|
||||
constexpr std::int64_t GradeQ16 = 17560;
|
||||
constexpr std::int64_t RouteRadiusQ = 4 * WorldAssemblySubvoxelsPerVoxel;
|
||||
struct FDirection { std::int32_t X; std::int32_t Y; };
|
||||
@@ -265,6 +268,7 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
struct FCandidate
|
||||
{
|
||||
std::int64_t Score = 0;
|
||||
std::int64_t OutwardProjection = 0;
|
||||
std::uint64_t EndpointProximityCost = 0;
|
||||
std::int32_t CenterX = 0;
|
||||
std::int32_t CenterY = 0;
|
||||
@@ -281,7 +285,7 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
Constraints.sweepSpacingSubvoxels = StepQ;
|
||||
Constraints.supportProbeRadiusSubvoxels = ProbeRadiusQ;
|
||||
Constraints.supportSearchDepthSubvoxels = SupportDepthQ;
|
||||
Constraints.minimumClearanceSubvoxels = 8;
|
||||
Constraints.minimumClearanceSubvoxels = 128;
|
||||
Constraints.minimumSupportProbes = 3;
|
||||
|
||||
const Heightfield2D BaseField(Recipe, Stratum);
|
||||
@@ -361,6 +365,8 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
{
|
||||
if (A.EndpointProximityCost != B.EndpointProximityCost)
|
||||
return A.EndpointProximityCost < B.EndpointProximityCost;
|
||||
if (A.OutwardProjection != B.OutwardProjection)
|
||||
return A.OutwardProjection > B.OutwardProjection;
|
||||
if (A.Score != B.Score) return A.Score < B.Score;
|
||||
if (A.CenterY != B.CenterY) return A.CenterY < B.CenterY;
|
||||
if (A.CenterX != B.CenterX) return A.CenterX < B.CenterX;
|
||||
@@ -498,6 +504,13 @@ bool BuildFiniteSurfaceRoute(VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
|
||||
if (Index == 32 && DepartureRadiusQ > 0)
|
||||
{
|
||||
Candidate.EndpointProximityCost += static_cast<std::uint64_t>(XQ * XQ + YQ * YQ);
|
||||
// Approach the surface portal from the world-facing side. The
|
||||
// resolved passage leaves the mouth along its outward tangent;
|
||||
// a route that approaches from beyond the mouth overlaps that
|
||||
// bore and turns its centerline into solid ground.
|
||||
const std::int64_t OutwardProjection = XQ * Directions[DirectionIndex].X
|
||||
+ YQ * Directions[DirectionIndex].Y;
|
||||
Candidate.OutwardProjection = OutwardProjection;
|
||||
}
|
||||
const auto Column = BaseField.point(WorldAssemblyFixed(static_cast<double>(X)),
|
||||
WorldAssemblyFixed(static_cast<double>(Y)), 0);
|
||||
@@ -1515,10 +1528,10 @@ bool AttachCoreGeometryOnlyLayout(const UVoxelStrateManager* StrateManager,
|
||||
Config.style = static_cast<std::uint32_t>(Passage.Style);
|
||||
Config.mouthRadiusSubvoxels = std::max(WorldAssemblyMicrometresToSubvoxels(
|
||||
Slot.PassageMouthRadiusMicrometres, CoreVoxelMicrometres),
|
||||
WorldAssemblyMicrometresToSubvoxels(12 * OwnerVoxelMicrometres, CoreVoxelMicrometres));
|
||||
WorldAssemblyMicrometresToSubvoxels(36 * OwnerVoxelMicrometres, CoreVoxelMicrometres));
|
||||
Config.midRadiusSubvoxels = std::max(WorldAssemblyMicrometresToSubvoxels(
|
||||
Slot.PassageMidRadiusMicrometres, CoreVoxelMicrometres),
|
||||
WorldAssemblyMicrometresToSubvoxels(12 * OwnerVoxelMicrometres, CoreVoxelMicrometres));
|
||||
WorldAssemblyMicrometresToSubvoxels(24 * OwnerVoxelMicrometres, CoreVoxelMicrometres));
|
||||
Config.reachMinimumSubvoxels = WorldAssemblyMicrometresToSubvoxels(Slot.PassageReachMinimumMicrometres, CoreVoxelMicrometres);
|
||||
Config.reachMaximumSubvoxels = WorldAssemblyMicrometresToSubvoxels(Slot.PassageReachMaximumMicrometres, CoreVoxelMicrometres);
|
||||
Config.distanceMinimumSubvoxels = WorldAssemblyMicrometresToSubvoxels(Slot.PassageDistanceMinimumMicrometres, CoreVoxelMicrometres);
|
||||
@@ -1635,7 +1648,11 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
Generated.plan.strates.push_back(std::move(Stratum));
|
||||
++BuiltSurfaceCount;
|
||||
}
|
||||
else if (Type == ECaveGeneratorType::FloatingIslands)
|
||||
// Native floating-island evaluation remains an explicit imported-plan opt-in.
|
||||
// The default owner path uses the legacy generator for this slot; emitting an
|
||||
// automatic FI plan here silently switches density dispatch and changes the
|
||||
// shared passage mouth before the owner has opted into that field.
|
||||
else if (Type == ECaveGeneratorType::FloatingIslands && bImportedOverride)
|
||||
{
|
||||
if (!BuildFloatingIslandStratumPlan(StrateManager, Slot, Generated,
|
||||
CoreVoxelSizeCm, LayoutChunkWidthSubvoxels, OutError))
|
||||
@@ -1708,10 +1725,11 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
}
|
||||
}
|
||||
if (Manifest->plan.strates.size() != static_cast<std::size_t>(SurfaceSlotCount)
|
||||
|| Manifest->floatingIslands.size() != static_cast<std::size_t>(FloatingIslandSlotCount))
|
||||
|| (!Manifest->floatingIslands.empty()
|
||||
&& Manifest->floatingIslands.size() != static_cast<std::size_t>(FloatingIslandSlotCount)))
|
||||
{
|
||||
OutError = FString::Printf(
|
||||
TEXT("Core world assembly has %d SurfaceWorld and %d floating-island plans for %d resolved SurfaceWorld and %d FloatingIslands strates."),
|
||||
TEXT("Core world assembly has %d SurfaceWorld and %d floating-island plans for %d resolved SurfaceWorld strates; an explicit FI plan must cover all %d FloatingIslands strates."),
|
||||
static_cast<int32>(Manifest->plan.strates.size()),
|
||||
static_cast<int32>(Manifest->floatingIslands.size()),
|
||||
SurfaceSlotCount, FloatingIslandSlotCount);
|
||||
@@ -1805,12 +1823,12 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
WorldAssemblyMicrometresToSubvoxels(
|
||||
Slot.PassageMouthRadiusMicrometres, ExpectedCoreVoxelMicrons),
|
||||
WorldAssemblyMicrometresToSubvoxels(
|
||||
12 * OwnerVoxelMicrons, ExpectedCoreVoxelMicrons));
|
||||
36 * OwnerVoxelMicrons, ExpectedCoreVoxelMicrons));
|
||||
PassageConfig.midRadiusSubvoxels = std::max(
|
||||
WorldAssemblyMicrometresToSubvoxels(
|
||||
Slot.PassageMidRadiusMicrometres, ExpectedCoreVoxelMicrons),
|
||||
WorldAssemblyMicrometresToSubvoxels(
|
||||
12 * OwnerVoxelMicrons, ExpectedCoreVoxelMicrons));
|
||||
24 * OwnerVoxelMicrons, ExpectedCoreVoxelMicrons));
|
||||
PassageConfig.reachMinimumSubvoxels = WorldAssemblyMicrometresToSubvoxels(
|
||||
Slot.PassageReachMinimumMicrometres, ExpectedCoreVoxelMicrons);
|
||||
PassageConfig.reachMaximumSubvoxels = WorldAssemblyMicrometresToSubvoxels(
|
||||
|
||||
Reference in new issue
Block a user