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
@@ -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>();
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user