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:
Fr0zkaandClaude Opus 5.5 committed 2026-10-27 06:22:48 +01:00
1 parent 81e2452a3d
commit bd68aee1ca
16 files changed
+939 -62

No files matched your search

+1
View File
@@ -80,6 +80,7 @@ struct FStandaloneOwnerWorld
std::uint32_t CoreVoxelSizeMicrons = 250000;
std::uint32_t StrateLayoutChunkSizeMicrometres = 8000000;
std::int64_t StrateLayoutChunkWidthSubvoxels = 8192;
bool bHasUnrealResolvedCorePlan = false;
std::shared_ptr<FStandalonePassageVoidCrossingCache> PassageVoidCrossingCache =
std::make_shared<FStandalonePassageVoidCrossingCache>();
};
+34 -4
View File
@@ -1695,6 +1695,18 @@ int main(int argc,char** argv)
&&!OverrideTransitions(ownerJsonRoot,options.TransitionModeOverride,
options.TransitionWidthChunksOverride,error))
{std::fprintf(stderr,"Transition fixture override failed: %s\n",error.c_str());return 2;}
const bool hasExportedAssembly=ownerJsonRoot.Get("core_world_assembly_json").IsString();
const bool hasExportedLayout=ownerJsonRoot.Get("resolved_layout_json").IsString();
if(hasExportedAssembly!=hasExportedLayout)
{std::fprintf(stderr,"Owner export has only half of its Unreal-resolved Core plan.\n");return 2;}
const bool useExportedCorePlan=hasExportedAssembly
&&!options.HasSeedOverride
&&!options.FloatingIslandsRecipe
&&!options.CavesRecipe
&&!options.LatticeRecipe
&&options.TransitionModeOverride<0
&&options.TransitionWidthChunksOverride<0;
ownerWorld->bHasUnrealResolvedCorePlan=useExportedCorePlan;
if(!StandaloneOwnerLoader::Resolve(ownerJsonRoot,*ownerWorld,error))
{std::fprintf(stderr,"Owner data load failed: %s\n",error.c_str());return 2;}
std::printf("[ColdTimeline] stage=owner_data_load end_ms=%.3f\n",
@@ -1720,10 +1732,20 @@ int main(int argc,char** argv)
const auto planStart=Clock::now();
VoxelForgeCore::WorldAssemblyManifest worldAssembly;
if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(
if(useExportedCorePlan)
{
if(!StandaloneWorldAssemblyPrototype::ImportExportedCoreWorldAssembly(
ownerJsonRoot,worldAssembly,error))
{std::fprintf(stderr,"Unreal-resolved Core plan import failed: %s\n",error.c_str());return 2;}
std::printf("[WorldAssemblerPlanSource] source=owner_export/unreal_core_adapter manifest_hash=%016llx layout_chunk_width_q=%lld surface_strates=%zu floating_islands=%zu\n",
static_cast<unsigned long long>(worldAssembly.contentHash),
static_cast<long long>(worldAssembly.recipe.layoutChunkWidthSubvoxels),
worldAssembly.plan.strates.size(),worldAssembly.floatingIslands.size());
}
else if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(
*ownerWorld,ownerJsonRoot,error,{},&worldAssembly))
{std::fprintf(stderr,"World assembler prototype setup failed: %s\n",error.c_str());return 2;}
if(options.FloatingIslandsRecipe
if(!useExportedCorePlan&&options.FloatingIslandsRecipe
&&!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
*ownerWorld,ownerJsonRoot,worldAssembly,error))
{std::fprintf(stderr,"Floating-island assembly setup failed: %s\n",error.c_str());return 2;}
@@ -1757,9 +1779,17 @@ int main(int argc,char** argv)
?"lattice/"+std::to_string(options.LatticeStrateIndex)
:options.CavesRecipe?"caves"
:options.FloatingIslandsRecipe?"floating-islands":"surface-world";
if(!StandaloneWorldAssemblyPrototype::BuildResolvedLayoutSnapshot(
*ownerWorld,worldAssembly,variant,resolvedLayout,error))
const bool layoutResolved=useExportedCorePlan
?StandaloneWorldAssemblyPrototype::ImportExportedResolvedLayout(
ownerJsonRoot,resolvedLayout,error)
:StandaloneWorldAssemblyPrototype::BuildResolvedLayoutSnapshot(
*ownerWorld,worldAssembly,variant,resolvedLayout,error);
if(!layoutResolved)
{std::fprintf(stderr,"Resolved-layout snapshot failed: %s\n",error.c_str());return 2;}
if(useExportedCorePlan
&&!StandaloneWorldAssemblyPrototype::ValidateExportedCorePlanMatchesOwner(
*ownerWorld,worldAssembly,resolvedLayout,error))
{std::fprintf(stderr,"Unreal-resolved Core plan/owner slot validation failed: %s\n",error.c_str());return 2;}
if(!std::holds_alternative<std::nullptr_t>(ownerJsonRoot.Get("motif_family_override").Data))
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
@@ -1143,6 +1143,89 @@ namespace StandaloneWorldAssemblyPrototype
return "Unknown";
}
inline bool ImportExportedCoreWorldAssembly(const VFJson::Value& root,
VoxelForgeCore::WorldAssemblyManifest& out,std::string& error)
{
const VFJson::Value& assemblyJson=root.Get("core_world_assembly_json");
if(!assemblyJson.IsString())
{error="owner export has no Unreal-resolved Core world assembly";return false;}
auto parsed=VoxelForgeCore::WorldAssemblyManifest::FromJson(assemblyJson.String(),error);
if(!parsed)return false;
out=std::move(*parsed);
return true;
}
inline bool ImportExportedResolvedLayout(const VFJson::Value& root,
VoxelForgeCore::ResolvedLayoutSnapshotV3& out,std::string& error)
{
const VFJson::Value& layoutJson=root.Get("resolved_layout_json");
if(!layoutJson.IsString())
{error="owner export has no Unreal-resolved Core layout";return false;}
auto parsed=VoxelForgeCore::ResolvedLayoutSnapshotV3::FromJson(layoutJson.String(),error);
if(!parsed)return false;
std::vector<VoxelForgeCore::ResolvedLayoutIssueV2> issues;
if(!parsed->validate(VoxelForgeCore::ResolvedLayoutValidationModeV3::strict,issues,error))
return false;
out=std::move(*parsed);
return true;
}
inline bool ValidateExportedCorePlanMatchesOwner(const FStandaloneOwnerWorld& owner,
const VoxelForgeCore::WorldAssemblyManifest& assembly,
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,std::string& error)
{
using namespace VoxelForgeCore;
if(!owner.Manager||assembly.recipe.seed!=static_cast<std::uint32_t>(owner.Seed)
||assembly.recipe.layoutChunkWidthSubvoxels!=owner.StrateLayoutChunkWidthSubvoxels
||layout.strateLayoutChunkWidthSubvoxels!=owner.StrateLayoutChunkWidthSubvoxels
||layout.strateLayoutChunkSizeMicrometres!=owner.StrateLayoutChunkSizeMicrometres
||layout.ownerVoxelSizeMicrometres!=owner.OwnerVoxelSizeMicrons
||layout.coreVoxelSizeMicrometres!=owner.CoreVoxelSizeMicrons
||layout.strates.size()!=static_cast<std::size_t>(owner.Manager->GetLayout().Num()))
{error="Unreal-resolved Core plan metadata does not match the exported owner settings/layout";return false;}
for(const auto& island:assembly.floatingIslands)
{
if(island.manifest.recipe.layoutChunkWidthSubvoxels
!=owner.StrateLayoutChunkWidthSubvoxels)
{error="Unreal-resolved floating-island plan has a stale layout chunk width";return false;}
}
for(const FStrateSlot& slot:owner.Manager->GetLayout())
{
if(!slot.Definition)continue;
const auto type=owner.Manager->GetGeneratorTypeForChunk(FIntVector(0,0,slot.TopChunkZ));
const auto resolved=std::find_if(layout.strates.begin(),layout.strates.end(),
[&](const auto& item){return item.strateIndex==slot.StrateIndex;});
const std::int64_t expectedBottom=static_cast<std::int64_t>(slot.BottomChunkZ)
*owner.StrateLayoutChunkSizeMicrometres;
const std::int64_t expectedTop=static_cast<std::int64_t>(slot.TopChunkZ+1)
*owner.StrateLayoutChunkSizeMicrometres;
if(resolved==layout.strates.end()
||resolved->interiorBottomMicrometres!=expectedBottom
||resolved->interiorTopMicrometres!=expectedTop)
{error="Unreal-resolved Core layout bounds do not match exported slot "+std::to_string(slot.StrateIndex);return false;}
if(type==ECaveGeneratorType::SurfaceWorld)
{
const auto plan=std::find_if(assembly.plan.strates.begin(),assembly.plan.strates.end(),
[&](const auto& item){return item.strateIndex==slot.StrateIndex;});
if(plan==assembly.plan.strates.end()||plan->topChunkZ!=slot.TopChunkZ
||plan->bottomChunkZ!=slot.BottomChunkZ)
{error="Unreal-resolved SurfaceWorld plan bounds do not match exported slot "+std::to_string(slot.StrateIndex);return false;}
}
else if(type==ECaveGeneratorType::FloatingIslands)
{
const auto plan=std::find_if(assembly.floatingIslands.begin(),assembly.floatingIslands.end(),
[&](const auto& item){return item.strateIndex==slot.StrateIndex;});
// A missing FI plan is the explicit compiled-analytic dispatch path.
// Validate exact live-slot bounds whenever an imported native plan exists.
if(plan!=assembly.floatingIslands.end()&&(plan->topChunkZ!=slot.TopChunkZ
||plan->bottomChunkZ!=slot.BottomChunkZ))
{error="Unreal-resolved floating-island bounds do not match exported slot "+std::to_string(slot.StrateIndex);return false;}
}
}
return true;
}
inline bool BuildResolvedLayoutSnapshot(const FStandaloneOwnerWorld& owner,
const VoxelForgeCore::WorldAssemblyManifest& assembly,std::string_view recipeVariant,
VoxelForgeCore::ResolvedLayoutSnapshotV3& out,std::string& error)