wip(assembler): round L22 -- one 8 m layout chunk for every strate; real ceiling -> content -> bedrock

StrateLayoutChunkSizeMeters (world setting, default 8 m; owner decision) is resolved once in
the director/adapter and standalone loader; every generator reads the resolved width (no
CHUNK_SIZE / Core-tile inference). Every strate gets solid ceiling and bedrock bands from its
BoundarySealThickness in the shared composition path (diggable by default); faces come from the
shared boundary path. Owner world: FloatingIslands +8..-120 m (128 m, now with a bedrock floor),
SurfaceWorld -120..-632 m (unchanged; full-detail and exact-query hashes equal L21); the 60 m gap is
gone. The strict layout validator passes on the real world, with 0 endpoint dispatch
disagreements. Spawn/benchmark camera derived from route.front. Ledges under the islands gone
(reviewer capture). Evaluator 7, recipe schema 2, layout snapshot 2, FI geometry 4.
Open: SW cap profiles exceed the ceiling band (owner call); transitions still Hard; Unreal
setting/manager/adapter edits 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:
Fr0zkaandClaude Opus 5.5 committed 2026-10-20 12:03:14 +02:00
1 parent 8753f6dbe4
commit 55c26a05a7
28 files changed
+1432 -579

No files matched your search

+148 -34
View File
@@ -17,6 +17,7 @@
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <string_view>
@@ -66,6 +67,7 @@ namespace
std::filesystem::path ResolvedLayoutOutputPath;
bool ResolvedLayoutOnly=false;
bool AuditResolvedLayoutBoundaries=false;
bool AuditSurfaceClearance=false;
};
bool ParseInteger(std::string_view text,int& output)
@@ -123,6 +125,7 @@ namespace
" --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"
" --audit-surface-clearance (sample biome terrain/caps against the resolved ceiling)\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"
@@ -142,6 +145,7 @@ namespace
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=="--audit-surface-clearance")options.AuditSurfaceClearance=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;
@@ -313,7 +317,11 @@ int main(int argc,char** argv)
FVector cameraVoxels=ownerWorld->ViewerStartVoxels;
if(options.HasCamera)
cameraVoxels=FVector(options.CameraMeters.X*4.0f,options.CameraMeters.Y*4.0f,options.CameraMeters.Z*4.0f);
{
const float VoxelsPerMetre=1000000.0f/std::max<std::uint32_t>(1,ownerWorld->CoreVoxelSizeMicrons);
cameraVoxels=FVector(options.CameraMeters.X*VoxelsPerMetre,
options.CameraMeters.Y*VoxelsPerMetre,options.CameraMeters.Z*VoxelsPerMetre);
}
const auto planStart=Clock::now();
VoxelForgeCore::WorldAssemblyManifest worldAssembly;
@@ -324,22 +332,19 @@ 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)
VoxelForgeCore::ResolvedLayoutSnapshotV2 resolvedLayout;
{
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();
const auto roundTrip=VoxelForgeCore::ResolvedLayoutSnapshotV2::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.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);
@@ -347,12 +352,16 @@ int main(int argc,char** argv)
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;
const auto controls=VoxelForgeCore::AuditResolvedLayoutValidatorV2();
std::vector<VoxelForgeCore::ResolvedLayoutIssueV2> compatibilityIssues;
std::string compatibilityError;
const bool compatibilityAccepted=resolvedLayout.validate(
VoxelForgeCore::ResolvedLayoutValidationModeV1::compatibility,
VoxelForgeCore::ResolvedLayoutValidationModeV2::compatibility,
compatibilityIssues,compatibilityError);
std::vector<VoxelForgeCore::ResolvedLayoutIssueV2> strictIssues;
std::string strictError;
const bool strictAccepted=resolvedLayout.validate(
VoxelForgeCore::ResolvedLayoutValidationModeV2::strict,strictIssues,strictError);
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",
@@ -362,12 +371,124 @@ int main(int argc,char** argv)
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("[ResolvedLayoutStrict] accepted=%s issues=%zu error=%s\n",
strictAccepted?"true":"false",strictIssues.size(),strictError.c_str());
for(const auto& issue:strictIssues)
std::printf("[ResolvedLayoutStrictIssue] code=%s detail=%s\n",issue.code.c_str(),issue.detail.c_str());
if(!strictAccepted)
{std::fprintf(stderr,"Resolved-layout strict validation failed: %s\n",strictError.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(auto* root=std::get_if<VFJson::Value::Object>(&ownerJsonRoot.Data))
{VFJson::Value layoutText;layoutText.Data=layoutJson;(*root)["resolved_layout_json"]=std::move(layoutText);}
else
{std::fprintf(stderr,"Owner snapshot root cannot carry its resolved layout.\n");return 2;}
if(options.AuditSurfaceClearance)
{
if(options.FloatingIslandsRecipe)
{std::fprintf(stderr,"--audit-surface-clearance requires --recipe=surface-world\n");return 2;}
const auto surface=std::find_if(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[](const auto& Stratum){return Stratum.generatorKind=="SurfaceWorld";});
const auto plan=surface==resolvedLayout.strates.end()?worldAssembly.plan.strates.end()
:std::find_if(worldAssembly.plan.strates.begin(),worldAssembly.plan.strates.end(),
[&](const auto& Stratum){return Stratum.strateIndex==surface->strateIndex;});
if(surface==resolvedLayout.strates.end()||plan==worldAssembly.plan.strates.end()
||!surface->ceiling.presentInCurrentField)
{std::fprintf(stderr,"SurfaceWorld clearance audit could not resolve its plan/ceiling\n");return 2;}
const VoxelForgeCore::Heightfield2D Field(worldAssembly.recipe,*plan);
if(!Field.isValid())
{std::fprintf(stderr,"SurfaceWorld clearance audit field is invalid\n");return 2;}
constexpr std::int64_t HalfExtentMetres=2048,StepMetres=1;
const double CoreMicrometres=std::max<std::uint32_t>(1,ownerWorld->CoreVoxelSizeMicrons);
const double MetresPerSubvoxel=CoreMicrometres
/(1000000.0*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
double CenterX=0.0,CenterY=0.0;
if(!plan->route.empty())
{CenterX=plan->route.front().positionSubvoxels[0]*MetresPerSubvoxel;
CenterY=plan->route.front().positionSubvoxels[1]*MetresPerSubvoxel;}
const std::int64_t CenterXQ=static_cast<std::int64_t>(std::llround(
CenterX/MetresPerSubvoxel));
const std::int64_t CenterYQ=static_cast<std::int64_t>(std::llround(
CenterY/MetresPerSubvoxel));
const std::int64_t StepQ=static_cast<std::int64_t>(std::llround(
StepMetres/MetresPerSubvoxel));
struct FBiomeClearance
{
std::uint64_t Samples=0;
double MaximumGround=-std::numeric_limits<double>::infinity();
double MaximumCap=-std::numeric_limits<double>::infinity();
double MaximumSurface=-std::numeric_limits<double>::infinity();
double MinimumClearance=std::numeric_limits<double>::infinity();
double AtX=0.0,AtY=0.0,AtHeight=0.0;
std::int64_t MaximumCapQ=std::numeric_limits<std::int64_t>::min();
};
std::map<std::uint32_t,FBiomeClearance> ByBiome;
const double CeilingFace=static_cast<double>(surface->ceiling.bottomMicrometres)/1000000.0;
for(std::int64_t Y=-HalfExtentMetres;Y<=HalfExtentMetres;Y+=StepMetres)
for(std::int64_t X=-HalfExtentMetres;X<=HalfExtentMetres;X+=StepMetres)
{
const auto Sample=Field.point(CenterXQ+(X/StepMetres)*StepQ,
CenterYQ+(Y/StepMetres)*StepQ,0);
const double Ground=Sample.groundHeightSubvoxels*MetresPerSubvoxel;
const double Cap=Sample.capHeightSubvoxels*MetresPerSubvoxel;
const double SurfaceHeight=std::max(Ground,Cap);
auto& Stats=ByBiome[Sample.biomeId];
++Stats.Samples;
Stats.MaximumGround=std::max(Stats.MaximumGround,Ground);
Stats.MaximumCap=std::max(Stats.MaximumCap,Cap);
Stats.MaximumCapQ=std::max(Stats.MaximumCapQ,Sample.capHeightSubvoxels);
Stats.MaximumSurface=std::max(Stats.MaximumSurface,SurfaceHeight);
const double Clearance=CeilingFace-SurfaceHeight;
if(Clearance<Stats.MinimumClearance)
{Stats.MinimumClearance=Clearance;Stats.AtX=CenterX+X;Stats.AtY=CenterY+Y;
Stats.AtHeight=SurfaceHeight;}
}
double MaximumRouteZ=-std::numeric_limits<double>::infinity();
for(const auto& Point:plan->route)
MaximumRouteZ=std::max(MaximumRouteZ,Point.positionSubvoxels[2]*MetresPerSubvoxel);
const auto CapBounds=Field.capHeightBounds();
const auto RouteSample=plan->route.empty()?VoxelForgeCore::HeightfieldPointSample{}
:Field.point(plan->route.front().positionSubvoxels[0],
plan->route.front().positionSubvoxels[1],0);
std::printf("[SurfaceClearancePlan] has_recipe_override=%s layout_chunk_q=%lld plan_cap_q=%lld cap_bounds_q=(%lld,%lld)\n",
plan->hasRecipeOverride?"true":"false",
static_cast<long long>(worldAssembly.recipe.layoutChunkWidthSubvoxels),
static_cast<long long>(plan->capHeightSubvoxels),
static_cast<long long>(CapBounds[0]),static_cast<long long>(CapBounds[1]));
for(const auto& Profile:worldAssembly.recipe.biomes)
std::printf("[SurfaceClearanceProfile] biome_id=%u has_cap=%s cap_q=%lld undulation_q=%lld detail_q=%lld ridge_q=%lld\n",
Profile.stableId,Profile.hasCapProfile?"true":"false",
static_cast<long long>(Profile.capHeightSubvoxels),
static_cast<long long>(Profile.capUndulationSubvoxels),
static_cast<long long>(Profile.capDetailAmplitudeSubvoxels),
static_cast<long long>(Profile.capRidgeAmplitudeSubvoxels));
std::printf("[SurfaceClearanceAudit] box_m=4096x4096 step_m=%lld samples=%lld ceiling_inner_face_m=%.3f unmodified_field=true\n",
static_cast<long long>(StepMetres),
static_cast<long long>((2*HalfExtentMetres/StepMetres+1)*(2*HalfExtentMetres/StepMetres+1)),
CeilingFace);
std::printf("[SurfaceClearanceCapRange] plan_min_m=%.3f plan_max_m=%.3f spawn_cap_m=%.3f spawn_ground_m=%.3f\n",
CapBounds[0]*MetresPerSubvoxel,CapBounds[1]*MetresPerSubvoxel,
RouteSample.capHeightSubvoxels*MetresPerSubvoxel,
RouteSample.groundHeightSubvoxels*MetresPerSubvoxel);
for(const auto& Feature:plan->features)
std::printf("[SurfaceClearanceFeature] type=%u params_q=(%lld,%lld,%lld,%lld)\n",
Feature.type,static_cast<long long>(Feature.parametersSubvoxels[0]),
static_cast<long long>(Feature.parametersSubvoxels[1]),
static_cast<long long>(Feature.parametersSubvoxels[2]),
static_cast<long long>(Feature.parametersSubvoxels[3]));
for(const auto& [BiomeId,Stats]:ByBiome)
std::printf("[SurfaceClearanceBiome] biome_id=%u samples=%llu max_ground_m=%.3f max_cap_m=%.3f max_cap_q=%lld max_surface_m=%.3f min_clearance_m=%.3f at_m=(%.1f,%.1f,%.3f)\n",
BiomeId,static_cast<unsigned long long>(Stats.Samples),Stats.MaximumGround,
Stats.MaximumCap,static_cast<long long>(Stats.MaximumCapQ),Stats.MaximumSurface,Stats.MinimumClearance,
Stats.AtX,Stats.AtY,Stats.AtHeight);
std::printf("[SurfaceClearanceRoute] route_points=%zu max_route_z_m=%.3f clearance_m=%.3f status=%s\n",
plan->route.size(),MaximumRouteZ,CeilingFace-MaximumRouteZ,
MaximumRouteZ<CeilingFace?"PASS":"COLLISION");
}
if(options.ResolvedLayoutOnly)return 0;
}
if(options.AutoSurfaceCamera)
@@ -391,25 +512,17 @@ int main(int argc,char** argv)
}
else
{
const auto xSubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.X*UnitsPerVoxel));
const auto ySubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.Y*UnitsPerVoxel));
const auto currentZSubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.Z*UnitsPerVoxel));
std::int64_t selectedGround=0,bestDistance=std::numeric_limits<std::int64_t>::max();
for(const auto& stratum:worldAssembly.plan.strates)
{
VoxelForgeCore::Heightfield2D field(worldAssembly.recipe,stratum);
if(!field.isValid())continue;
const auto column=field.point(xSubvoxels,ySubvoxels,0);
const std::int64_t distance=std::abs(column.groundHeightSubvoxels-currentZSubvoxels);
if(distance<bestDistance)
{bestDistance=distance;selectedGround=column.groundHeightSubvoxels;}
}
if(bestDistance==std::numeric_limits<std::int64_t>::max())
{std::fprintf(stderr,"[SeedSurfacePlacement] FAIL: no valid SurfaceWorld heightfield\n");return 2;}
cameraVoxels.Z=static_cast<float>(static_cast<double>(selectedGround)/UnitsPerVoxel);
std::printf("[SeedSurfacePlacement] recipe=surface-world seed=%d ground_voxel=%.6f camera_voxel=(%.6f,%.6f,%.6f) status=PASS\n",
seed,static_cast<double>(selectedGround)/UnitsPerVoxel,
cameraVoxels.X,cameraVoxels.Y,cameraVoxels.Z);
if(worldAssembly.plan.strates.empty()||worldAssembly.plan.strates.front().route.empty())
{std::fprintf(stderr,"[SeedSurfacePlacement] FAIL: route-derived spawn is missing\n");return 2;}
const auto& spawn=worldAssembly.plan.strates.front().route.front();
cameraVoxels={static_cast<float>(static_cast<double>(spawn.positionSubvoxels[0])/UnitsPerVoxel),
static_cast<float>(static_cast<double>(spawn.positionSubvoxels[1])/UnitsPerVoxel),
static_cast<float>(static_cast<double>(spawn.positionSubvoxels[2])/UnitsPerVoxel)};
std::printf("[SeedSurfacePlacement] recipe=surface-world seed=%d source=route.front position_voxel=(%.6f,%.6f,%.6f) position_m=(%.3f,%.3f,%.3f) status=PASS\n",
seed,cameraVoxels.X,cameraVoxels.Y,cameraVoxels.Z,
cameraVoxels.X*ownerWorld->CoreVoxelSizeMicrons/1000000.0f,
cameraVoxels.Y*ownerWorld->CoreVoxelSizeMicrons/1000000.0f,
cameraVoxels.Z*ownerWorld->CoreVoxelSizeMicrons/1000000.0f);
}
}
std::printf("[WorldAssemblerPlanTiming] total_ms=%.3f status=PASS\n",
@@ -422,8 +535,9 @@ int main(int argc,char** argv)
FStandaloneCoreScheduler scheduler;
const FVector cameraStepVoxels=options.HasCameraStep
?FVector(options.CameraStepMeters.X*4.0f,options.CameraStepMeters.Y*4.0f,
options.CameraStepMeters.Z*4.0f):FVector::ZeroVector;
?FVector(options.CameraStepMeters.X*1000000.0f/std::max<std::uint32_t>(1,ownerWorld->CoreVoxelSizeMicrons),
options.CameraStepMeters.Y*1000000.0f/std::max<std::uint32_t>(1,ownerWorld->CoreVoxelSizeMicrons),
options.CameraStepMeters.Z*1000000.0f/std::max<std::uint32_t>(1,ownerWorld->CoreVoxelSizeMicrons)):FVector::ZeroVector;
return StandaloneStreamBenchmark::RunPipelinedStreamingBenchmark(ownerWorld,snapshot,
cameraVoxels,options.WorkerCount,options.MaxLevel,VoxelForgeCore::DetailVariant::coherent,
scheduler,options.StreamHash,false,false,false,false,coldStart,
@@ -434,5 +548,5 @@ int main(int argc,char** argv)
options.RegionCrossing,options.AuditTileShapeReadiness,
options.DiagnosticSlowShapeCompileMs,options.AuditBasePageEquivalence,
options.AuditRouteParity,options.AuditResolvedLayoutBoundaries,
buildResolvedLayout?&resolvedLayout:nullptr);
&resolvedLayout);
}