wip(assembler): round L21 -- resolved strate layout snapshot + validator (no world change)
Core ResolvedLayoutSnapshotV1 (canonical JSON, stable identity): per strate stable ID, generator, recipe, interior bounds in metres, ceiling/bedrock bands as Core really applies them, transition mode/width, dispatch provenance. Validator: compat mode reports today's deviations; strict mode enforces ceiling -> content -> bedrock -> next ceiling (owner rule), two separate bands, nominal contiguity, interpenetration only within the declared EVoxelStrateTransition width; 7 negative controls rejected. Findings: SW built at -120..-632 m although the params say -60 m; a 60 m unowned gap filled by analytic FI fallback; no active bedrock bands; transitions ignored by Core. All L19 hashes unchanged (28 + 14 crossing runs). The Unreal adapter exports resolved_layout (uncompiled here). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
1 parent
5d5447dc32
commit
8753f6dbe4
12 files changed
+1347
-3
No files matched your search
@@ -63,6 +63,9 @@ namespace
|
||||
float CameraYawDegrees=0.0f;
|
||||
float CameraPitchDegrees=0.0f;
|
||||
std::filesystem::path MeshExportPath;
|
||||
std::filesystem::path ResolvedLayoutOutputPath;
|
||||
bool ResolvedLayoutOnly=false;
|
||||
bool AuditResolvedLayoutBoundaries=false;
|
||||
};
|
||||
|
||||
bool ParseInteger(std::string_view text,int& output)
|
||||
@@ -117,6 +120,9 @@ namespace
|
||||
" --mesh-export=FILE (write the exact generated tile meshes for offline rendering)\n"
|
||||
" --profile-column-overlap --far-horizon-lod8-step=N --force-generate\n"
|
||||
" --seed=N --recipe=surface-world|floating-islands\n"
|
||||
" --resolved-layout-output=FILE (canonical plan-time layout snapshot)\n"
|
||||
" --resolved-layout-only (exit after plan and snapshot validation)\n"
|
||||
" --audit-resolved-layout-boundaries (query Core at each recorded endpoint)\n"
|
||||
" --auto-surface-camera (place the 27-tile cube on this seed's surface)\n"
|
||||
" --mesh-coverage (report non-empty tiles and indexed triangles)\n"
|
||||
" --screen-space-gate (measure display error and historical negative controls)\n"
|
||||
@@ -134,6 +140,8 @@ namespace
|
||||
return false;
|
||||
}
|
||||
if(arg=="--world-assembler-prototype")options.WorldAssemblerPrototype=true;
|
||||
else if(arg=="--resolved-layout-only")options.ResolvedLayoutOnly=true;
|
||||
else if(arg=="--audit-resolved-layout-boundaries")options.AuditResolvedLayoutBoundaries=true;
|
||||
else if(arg=="--stream-benchmark")options.StreamBenchmark=true;
|
||||
else if(arg=="--stream-pipeline")options.StreamPipeline=true;
|
||||
else if(arg=="--stream-hash")options.StreamHash=true;
|
||||
@@ -155,6 +163,8 @@ namespace
|
||||
else if(recipe=="floating-islands")options.FloatingIslandsRecipe=true;
|
||||
else {std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(recipe.size()),recipe.data());return false;}
|
||||
}
|
||||
else if(arg.starts_with("--resolved-layout-output="))
|
||||
options.ResolvedLayoutOutputPath=std::string(arg.substr(std::string_view("--resolved-layout-output=").size()));
|
||||
else if(arg.starts_with("--seed="))
|
||||
{if(!readInt("--seed=",options.SeedOverride))return false;options.HasSeedOverride=true;}
|
||||
else if(arg.starts_with("--render-distance-chunks="))
|
||||
@@ -314,6 +324,52 @@ int main(int argc,char** argv)
|
||||
&&!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
|
||||
*ownerWorld,ownerJsonRoot,worldAssembly,error))
|
||||
{std::fprintf(stderr,"Floating-island assembly setup failed: %s\n",error.c_str());return 2;}
|
||||
VoxelForgeCore::ResolvedLayoutSnapshotV1 resolvedLayout;
|
||||
const bool buildResolvedLayout=!options.ResolvedLayoutOutputPath.empty()
|
||||
||options.AuditResolvedLayoutBoundaries||options.ResolvedLayoutOnly;
|
||||
if(buildResolvedLayout)
|
||||
{
|
||||
const std::string_view variant=options.FloatingIslandsRecipe?"floating-islands":"surface-world";
|
||||
if(!StandaloneWorldAssemblyPrototype::BuildResolvedLayoutSnapshot(
|
||||
*ownerWorld,worldAssembly,variant,resolvedLayout,error))
|
||||
{std::fprintf(stderr,"Resolved-layout snapshot failed: %s\n",error.c_str());return 2;}
|
||||
const std::string layoutJson=resolvedLayout.ToJson();
|
||||
if(!options.ResolvedLayoutOutputPath.empty())
|
||||
{
|
||||
const auto roundTrip=VoxelForgeCore::ResolvedLayoutSnapshotV1::FromJson(layoutJson,error);
|
||||
if(!roundTrip||roundTrip->ToJson()!=layoutJson||roundTrip->stableIdentity!=resolvedLayout.stableIdentity)
|
||||
{if(error.empty())error="resolved-layout canonical serialization did not round-trip";
|
||||
std::fprintf(stderr,"Resolved-layout round trip failed: %s\n",error.c_str());return 2;}
|
||||
if(!options.ResolvedLayoutOutputPath.parent_path().empty())
|
||||
std::filesystem::create_directories(options.ResolvedLayoutOutputPath.parent_path());
|
||||
std::ofstream output(options.ResolvedLayoutOutputPath,std::ios::binary);
|
||||
if(!output){std::fprintf(stderr,"Could not write resolved-layout snapshot: %s\n",options.ResolvedLayoutOutputPath.c_str());return 2;}
|
||||
output.write(layoutJson.data(),static_cast<std::streamsize>(layoutJson.size()));
|
||||
if(!output){std::fprintf(stderr,"Resolved-layout snapshot write failed: %s\n",options.ResolvedLayoutOutputPath.c_str());return 2;}
|
||||
}
|
||||
const auto controls=VoxelForgeCore::AuditResolvedLayoutValidatorV1();
|
||||
std::vector<VoxelForgeCore::ResolvedLayoutIssueV1> compatibilityIssues;
|
||||
std::string compatibilityError;
|
||||
const bool compatibilityAccepted=resolvedLayout.validate(
|
||||
VoxelForgeCore::ResolvedLayoutValidationModeV1::compatibility,
|
||||
compatibilityIssues,compatibilityError);
|
||||
std::printf("[ResolvedLayoutSnapshot] schema=%u stable_identity=%s strata=%zu bytes=%zu round_trip=PASS\n",
|
||||
resolvedLayout.schemaVersion,resolvedLayout.stableIdentity.c_str(),resolvedLayout.strates.size(),layoutJson.size());
|
||||
std::printf("[ResolvedLayoutCompatibility] accepted=%s issues=%zu error=%s\n",
|
||||
compatibilityAccepted?"true":"false",compatibilityIssues.size(),compatibilityError.c_str());
|
||||
for(const auto& issue:compatibilityIssues)
|
||||
std::printf("[ResolvedLayoutCompatibilityIssue] code=%s detail=%s\n",
|
||||
issue.code.c_str(),issue.detail.c_str());
|
||||
if(!compatibilityAccepted)
|
||||
{std::fprintf(stderr,"Resolved-layout compatibility validation failed: %s\n",compatibilityError.c_str());return 2;}
|
||||
std::printf("[ResolvedLayoutValidatorControls] rejected=%u/%u status=%s\n",
|
||||
controls.controlsRejectedAsExpected,controls.controlsRun,controls.passed?"PASS":"FAIL");
|
||||
if(!controls.passed)
|
||||
{for(const auto& failure:controls.failures)std::printf("[ResolvedLayoutValidatorControlFailure] %s %s\n",failure.code.c_str(),failure.detail.c_str());return 2;}
|
||||
if(!options.ResolvedLayoutOutputPath.empty())
|
||||
std::printf("[ResolvedLayoutSnapshotOutput] path=%s\n",options.ResolvedLayoutOutputPath.c_str());
|
||||
if(options.ResolvedLayoutOnly)return 0;
|
||||
}
|
||||
if(options.AutoSurfaceCamera)
|
||||
{
|
||||
constexpr std::int64_t UnitsPerVoxel=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||
@@ -377,5 +433,6 @@ int main(int argc,char** argv)
|
||||
cameraStepVoxels,options.AuditUniformBlockProofs,options.ProfileLodWork,
|
||||
options.RegionCrossing,options.AuditTileShapeReadiness,
|
||||
options.DiagnosticSlowShapeCompileMs,options.AuditBasePageEquivalence,
|
||||
options.AuditRouteParity);
|
||||
options.AuditRouteParity,options.AuditResolvedLayoutBoundaries,
|
||||
buildResolvedLayout?&resolvedLayout:nullptr);
|
||||
}
|
||||
Reference in new issue
Block a user