feat(core): native lattice generator, slice 1 -- helix-ramp spine + small maze (L58); research R27

Core.Lattice.PrimitiveField v1, opt-in per strate (legacy Maze/VerticalShaft stay legacy): resolves the real
arrival and departure mouths first, plans a mandatory spine, then maze cells and two dead ends (9 rooms,
9 edges, stable IDs). The spine descends 20 m through four helix turns (6 m radius, 3 m clear width, 5 m
pitch, 2.6 m clearance; max grade 10.0 deg); each feature is one filleted void (0.57 m measured). Final-field
reachability passes at 883 stations; an orphaned shaft control is rejected; exact intervals (0 misses) and
a whole-surface audit with 0 flags. Whole view 1.69 s (above the 1 s target). fast/medium/full PASS.
Research R27 (self-checked): static stream-to-pool water design.

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-25 15:45:32 +01:00
1 parent 1e3e04bbac
commit 6c6cc37e1d
25 files changed
+280497 -117

No files matched your search

+328 -11
View File
@@ -64,6 +64,8 @@ namespace
int RenderDistanceOverride=0;
bool FloatingIslandsRecipe=false;
bool CavesRecipe=false;
bool LatticeRecipe=false;
int LatticeStrateIndex=-1;
bool AuditHeightfieldProfile=false;
bool LandmarkChamberDemo=false;
bool LandmarkL45RampControl=false;
@@ -71,6 +73,8 @@ namespace
bool AuditOreVeinYield=false;
bool AuditLandmarkReachability=false;
bool AuditNativeCaves=false;
bool AuditNativeLattice=false;
bool LatticeOrphanControl=false;
bool AuditMotifIntervals=false;
bool TlsProbeRequested=false;
int TlsProbeWorkers=0;
@@ -946,6 +950,283 @@ namespace
return true;
}
bool MakeNativeLatticeSpine(const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
std::int32_t seed,std::int32_t latticeStrateIndex,bool orphanControl,
std::vector<VoxelForgeCore::ResolvedCavernRoomV1>& rooms,
std::vector<VoxelForgeCore::ResolvedCavernEdgeV1>& edges,std::string& error)
{
using namespace VoxelForgeCore;
rooms.clear();edges.clear();error.clear();
const auto lattice=std::find_if(layout.strates.begin(),layout.strates.end(),
[latticeStrateIndex](const auto& value)
{return value.strateIndex==latticeStrateIndex
&&IsNativeLatticeFieldStratum(value);});
if(lattice==layout.strates.end())
{error="native lattice recipe does not name an opt-in Maze or VerticalShafts strate";return false;}
std::vector<const ResolvedLayoutPassageV1*> arrivals,departures;
for(const auto& passage:layout.passages)
{
if(passage.lowerStrateIndex==latticeStrateIndex)arrivals.push_back(&passage);
if(passage.upperStrateIndex==latticeStrateIndex)departures.push_back(&passage);
}
const auto byStableId=[](const auto* left,const auto* right)
{return left->stableId<right->stableId;};
std::sort(arrivals.begin(),arrivals.end(),byStableId);
std::sort(departures.begin(),departures.end(),byStableId);
if(arrivals.size()!=1||departures.size()!=1)
{error="native lattice spine requires exactly one resolved arrival and one departure mouth";return false;}
if(layout.coreVoxelSizeMicrometres==0)
{error="native lattice spine requires a resolved Core voxel size";return false;}
const double micrometresPerSubvoxel=static_cast<double>(layout.coreVoxelSizeMicrometres)
/WorldAssemblySubvoxelsPerVoxel;
const auto toMicrometres=[&](const std::array<std::int64_t,3>& point)
{
std::array<std::int64_t,3> result{};
for(std::size_t axis=0;axis<3;++axis)
result[axis]=static_cast<std::int64_t>(std::llround(
point[axis]*micrometresPerSubvoxel));
return result;
};
const auto toMetres=[](const std::array<std::int64_t,3>& point)
{return std::array<double,3>{point[0]/1.0e6,point[1]/1.0e6,point[2]/1.0e6};};
const auto micronPoint=[](const std::array<double,3>& point)
{
std::array<std::int64_t,3> result{};
for(std::size_t axis=0;axis<3;++axis)
result[axis]=static_cast<std::int64_t>(std::llround(point[axis]*1.0e6));
return result;
};
const auto tangentAt=[&](const ResolvedLayoutPassageV1& passage,bool lower,
std::array<double,2>& direction)
{
if(passage.controlPoints.size()<2)return false;
const std::size_t index=lower?std::min(passage.lowerMouthControlIndex,
passage.controlPoints.size()-1):0;
const std::size_t other=lower?(index>0?index-1:passage.controlPoints.size()-2)
:std::min<std::size_t>(1,passage.controlPoints.size()-1);
const auto& a=passage.controlPoints[lower?other:index].positionSubvoxels;
const auto& b=passage.controlPoints[lower?index:other].positionSubvoxels;
const double dx=static_cast<double>(b[0]-a[0]);
const double dy=static_cast<double>(b[1]-a[1]);
const double length=std::hypot(dx,dy);
if(!(length>1.0e-9))return false;
direction={dx/length,dy/length};
return true;
};
std::array<double,2> arrivalTangent{},departureTangent{};
if(!tangentAt(*arrivals.front(),true,arrivalTangent)
||!tangentAt(*departures.front(),false,departureTangent))
{error="native lattice mouth has no finite resolved passage tangent";return false;}
const auto arrival=toMetres(toMicrometres(arrivals.front()->lowerMouthSubvoxels));
const auto departure=toMetres(toMicrometres(departures.front()->upperMouthSubvoxels));
constexpr double MouthPlayerCenterHeight=1.13;
const double arrivalFloor=arrival[2]-MouthPlayerCenterHeight;
const double departureFloor=departure[2]-MouthPlayerCenterHeight;
const std::array<double,3> helixStart={arrival[0]+arrivalTangent[0]*3.0,
arrival[1]+arrivalTangent[1]*3.0,arrivalFloor};
constexpr double Pi=3.1415926535897932384626433832795;
constexpr double CenterlineRadius=6.0;
constexpr double ClearWidth=3.0;
constexpr double FloorToSoffit=2.6;
constexpr double Pitch=5.0;
constexpr int Turns=4;
constexpr double FloorBlend=1.9;
constexpr double FeatureUnionBlend=0.05;
constexpr double CorridorSpacing=14.0;
constexpr double MazeCellSpan=16.0;
constexpr double RouteGradeLimit=13.0;
const std::array<double,2> lateral={-arrivalTangent[1],arrivalTangent[0]};
const std::array<double,2> helixCenter={
helixStart[0]+lateral[0]*CenterlineRadius,
helixStart[1]+lateral[1]*CenterlineRadius};
const double helixEndFloor=arrivalFloor-Pitch*Turns;
const std::array<double,3> helixEnd={helixStart[0],helixStart[1],helixEndFloor};
const double mouthEndX=departure[0]-departureTangent[0]*3.0;
const double mouthEndY=departure[1]-departureTangent[1]*3.0;
const auto featureRoll=[&](std::string_view stableId)
{
std::uint64_t hash=14695981039346656037ull;
const auto addWord=[&](std::uint64_t word)
{for(int byte=0;byte<8;++byte){hash^=static_cast<std::uint8_t>(word>>(byte*8));hash*=1099511628211ull;}};
addWord(static_cast<std::uint32_t>(seed));
addWord(static_cast<std::uint32_t>(latticeStrateIndex));
addWord(1);
for(unsigned char value:stableId){hash^=value;hash*=1099511628211ull;}
hash^=hash>>30;hash*=0xbf58476d1ce4e5b9ull;
hash^=hash>>27;hash*=0x94d049bb133111ebull;
return hash^(hash>>31);
};
const auto addRoom=[&](std::string id,const std::array<double,3>& floorCenter)
{
ResolvedCavernRoomV1 room;room.stableId=std::move(id);
room.strateIndex=latticeStrateIndex;
room.centerMicrometres=micronPoint({floorCenter[0],floorCenter[1],
floorCenter[2]+FloorToSoffit*0.5});
room.halfExtentsMicrometres={2000000,2000000,
static_cast<std::int64_t>(std::llround(FloorToSoffit*500000.0))};
room.floorMicrometres=static_cast<std::int64_t>(std::llround(floorCenter[2]*1.0e6));
room.smoothWidthMicrometres=static_cast<std::int64_t>(std::llround(FloorBlend*1.0e6));
room.unionWidthMicrometres=static_cast<std::int64_t>(
std::llround(FeatureUnionBlend*1.0e6));
room.irregularitySeed=featureRoll(room.stableId);
rooms.push_back(std::move(room));
};
const auto addEdge=[&](std::string id,std::string startAnchor,std::string endRoom,
std::vector<std::array<double,3>> path)
{
ResolvedCavernEdgeV1 edge;edge.stableId=std::move(id);
edge.startAnchorStableId=std::move(startAnchor);
edge.endRoomStableId=std::move(endRoom);edge.strateIndex=latticeStrateIndex;
edge.boreRadiusMicrometres=1500000;
edge.boreHeightMicrometres=static_cast<std::int64_t>(
std::llround(FloorToSoffit*1.0e6));
edge.floorSupportDepthMicrometres=1000000;
edge.smoothWidthMicrometres=static_cast<std::int64_t>(std::llround(FloorBlend*1.0e6));
edge.unionWidthMicrometres=static_cast<std::int64_t>(
std::llround(FeatureUnionBlend*1.0e6));
edge.irregularitySeed=featureRoll(edge.stableId);
if(path.size()<2)return edge;
for(const auto& point:path)edge.polylineMicrometres.push_back(micronPoint(point));
const auto& first=path.front();const auto& last=path.back();
for(std::size_t control=0;control<4;++control)
{
const double t=static_cast<double>(control)/3.0;
for(std::size_t axis=0;axis<3;++axis)
edge.controlPointsMicrometres[control][axis]=static_cast<std::int64_t>(
std::llround(std::lerp(first[axis],last[axis],t)*1.0e6));
}
return edge;
};
const std::string arrivalRoomId="lattice/spine/arrival-room-v1";
const std::string mazeCellZeroId="lattice/spine/maze-cell-00-v1";
const std::string helixEntryRoomId=orphanControl
?"lattice/control/orphan-shaft-entry-room-v1"
:arrivalRoomId;
const std::string helixEndRoomId=orphanControl
?"lattice/control/orphan-shaft-end-room-v1":mazeCellZeroId;
const std::array<double,3> orphanOffset=orphanControl
?std::array<double,3>{lateral[0]*20.0,lateral[1]*20.0,0.0}
:std::array<double,3>{0.0,0.0,0.0};
addRoom(arrivalRoomId,helixStart);
if(orphanControl)
addRoom(helixEntryRoomId,{helixStart[0]+orphanOffset[0],
helixStart[1]+orphanOffset[1],helixStart[2]});
addRoom(mazeCellZeroId,helixEnd);
if(orphanControl)
addRoom(helixEndRoomId,{helixEnd[0]+orphanOffset[0],
helixEnd[1]+orphanOffset[1],helixEnd[2]});
const std::string departureRoomId="lattice/spine/departure-room-v1";
addRoom(departureRoomId,{departure[0],departure[1],departureFloor});
edges.push_back(addEdge("lattice/spine/00-arrival-portal-v1",
arrivals.front()->stableId+"/lower-mouth",arrivalRoomId,
{{arrival[0],arrival[1],arrivalFloor},helixStart}));
std::vector<std::array<double,3>> helixPath;
constexpr double HelixSampleArcLength=0.5;
const double helixLength=std::hypot(2.0*Pi*CenterlineRadius*Turns,
Pitch*Turns);
const int helixSteps=std::max(64,static_cast<int>(std::ceil(
helixLength/HelixSampleArcLength)));
helixPath.reserve(static_cast<std::size_t>(helixSteps)+1);
for(int sample=0;sample<=helixSteps;++sample)
{
const double u=static_cast<double>(sample)/helixSteps;
const double angle=2.0*Pi*Turns*u;
helixPath.push_back({
helixCenter[0]-lateral[0]*CenterlineRadius*std::cos(angle)
+arrivalTangent[0]*CenterlineRadius*std::sin(angle)+orphanOffset[0],
helixCenter[1]-lateral[1]*CenterlineRadius*std::cos(angle)
+arrivalTangent[1]*CenterlineRadius*std::sin(angle)+orphanOffset[1],
arrivalFloor-Pitch*Turns*u});
}
edges.push_back(addEdge("lattice/spine/01-helix-ramp-v1",
helixEntryRoomId,helixEndRoomId,std::move(helixPath)));
double dx=mouthEndX-helixEnd[0],dy=mouthEndY-helixEnd[1];
double horizontal=std::hypot(dx,dy);
double routeX=horizontal>1.0e-9?dx/horizontal:arrivalTangent[0];
double routeY=horizontal>1.0e-9?dy/horizontal:arrivalTangent[1];
double routeSideX=-routeY,routeSideY=routeX;
const double vertical=departureFloor-helixEndFloor;
const int routeEdges=4;
const double requiredRun=std::abs(vertical)/std::tan(RouteGradeLimit*Pi/180.0);
const double sideSpan=std::max(MazeCellSpan,
(requiredRun-horizontal)/3.0);
if(sideSpan>24.0)
{error="native lattice maze spine requires more than 24 m cells to preserve its grade";return false;}
std::vector<std::array<double,2>> mazeXY={
{helixEnd[0],helixEnd[1]},
{helixEnd[0]+routeX*sideSpan,helixEnd[1]+routeY*sideSpan},
{helixEnd[0]+routeX*sideSpan+routeSideX*sideSpan,
helixEnd[1]+routeY*sideSpan+routeSideY*sideSpan},
{mouthEndX+routeSideX*sideSpan,mouthEndY+routeSideY*sideSpan},
{mouthEndX,mouthEndY}};
std::array<double,5> routeDistance{};
for(std::size_t index=1;index<mazeXY.size();++index)
routeDistance[index]=routeDistance[index-1]
+std::hypot(mazeXY[index][0]-mazeXY[index-1][0],
mazeXY[index][1]-mazeXY[index-1][1]);
const double mazeRun=routeDistance.back();
if(!(mazeRun>=requiredRun))
{error="native lattice maze spine cannot satisfy the 13 degree grade limit";return false;}
std::vector<std::array<double,3>> cells(mazeXY.size());
for(std::size_t index=0;index<mazeXY.size();++index)
cells[index]={mazeXY[index][0],mazeXY[index][1],
helixEndFloor+vertical*(routeDistance[index]/mazeRun)};
std::vector<std::string> cellIds(static_cast<std::size_t>(routeEdges)+1);
cellIds[0]=mazeCellZeroId;
for(int index=1;index<=routeEdges;++index)
{
char suffix[16]{};std::snprintf(suffix,sizeof(suffix),"%02d",index);
cellIds[static_cast<std::size_t>(index)]=std::string("lattice/spine/maze-cell-")
+suffix+"-v1";
addRoom(cellIds[static_cast<std::size_t>(index)],cells[static_cast<std::size_t>(index)]);
}
for(int index=0;index<routeEdges;++index)
{
char suffix[16]{};std::snprintf(suffix,sizeof(suffix),"%02d",index);
edges.push_back(addEdge("lattice/spine/maze-edge-"+std::string(suffix)+"-v1",
cellIds[static_cast<std::size_t>(index)],
cellIds[static_cast<std::size_t>(index+1)],
{cells[static_cast<std::size_t>(index)],cells[static_cast<std::size_t>(index+1)]}));
}
const int branchIndices[2]={1,routeEdges-1};
for(int branch=0;branch<2;++branch)
{
const int index=branchIndices[branch];
const auto& base=cells[static_cast<std::size_t>(index)];
const std::string roomId=branch==0?"lattice/branch/dead-end-a-room-v1"
:"lattice/branch/dead-end-b-room-v1";
const std::string edgeId=branch==0?"lattice/branch/dead-end-a-edge-v1"
:"lattice/branch/dead-end-b-edge-v1";
const int sign=branch==0?-1:1;
const std::array<double,3> branchEnd={base[0]+routeSideX*sign*CorridorSpacing,
base[1]+routeSideY*sign*CorridorSpacing,base[2]};
addRoom(roomId,branchEnd);
edges.push_back(addEdge(edgeId,cellIds[static_cast<std::size_t>(index)],
roomId,{base,branchEnd}));
}
edges.push_back(addEdge("lattice/spine/99-departure-portal-v1",
departures.front()->stableId+"/upper-mouth",departureRoomId,
{cells.back(),{departure[0],departure[1],departureFloor}}));
const double innerEdgeGrade=std::atan(Pitch/(2.0*Pi*(CenterlineRadius-ClearWidth*0.5)))
*180.0/Pi;
const double centerlineGrade=std::atan(Pitch/(2.0*Pi*CenterlineRadius))*180.0/Pi;
std::printf("[LatticeResolvedMouths] arrival=%s side=lower xyz_m=(%.3f,%.3f,%.3f) departure=%s side=upper xyz_m=(%.3f,%.3f,%.3f) binding=actual-resolved status=PASS\n",
arrivals.front()->stableId.c_str(),arrival[0],arrival[1],arrival[2],
departures.front()->stableId.c_str(),departure[0],departure[1],departure[2]);
std::printf("[LatticeSpinePlan] recipe=Core.Lattice.PrimitiveField version=1 strate=%d stable_key=seed,strate,recipe_version,stable_id spine_first=true arrival=%s departure=%s helix_id=lattice/spine/01-helix-ramp-v1 centerline_radius_m=%.3f clear_width_m=%.3f pitch_m=%.3f turns=%d floor_to_soffit_m=%.3f centerline_grade_deg=%.3f inner_edge_grade_deg=%.3f floor_blend_m=%.3f union_envelope_m=%.3f maze_cells=%d dead_ends=2 orphan_control=%s status=PASS\n",
latticeStrateIndex,arrivals.front()->stableId.c_str(),departures.front()->stableId.c_str(),
CenterlineRadius,ClearWidth,Pitch,Turns,FloorToSoffit,centerlineGrade,innerEdgeGrade,
FloorBlend,FeatureUnionBlend,routeEdges+1,orphanControl?"enabled":"disabled");
return true;
}
bool MakeOreVeinDemoRequests(
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
std::vector<VoxelForgeCore::ResolvedLayoutOreVeinRequestV1>& requests,
@@ -1131,7 +1412,8 @@ namespace
" --mesh-export=FILE (write the exact generated tile meshes for offline rendering)\n"
" --world-assembler-manifest-output=FILE (write the canonical Core recipe and plan)\n"
" --profile-column-overlap --far-horizon-lod8-step=N --force-generate\n"
" --seed=N --recipe=surface-world|floating-islands|caves\n"
" --seed=N --recipe=surface-world|floating-islands|caves|lattice\n"
" --lattice-strate=N (opt one Maze or VerticalShafts strate into Core.Lattice)\n"
" --landmark-chamber-demo (opt-in SW cavern room and swept tunnel)\n"
" --ore-veins-demo (opt-in material-only SW capsule veins)\n"
" --audit-ore-vein-yield (measure one deterministic sphere carve)\n"
@@ -1146,6 +1428,8 @@ namespace
" --audit-motif-intervals (brute-force motif bounds, BVH and shape-free guards)\n"
" --audit-landmark-reachability (capsule, support, grade and buried-L43 control)\n"
" --audit-native-caves (arrival-to-departure capsule flood fill and interval oracle)\n"
" --audit-native-lattice (mouth-to-mouth capsule, grade, support and interval proof)\n"
" --lattice-orphan-control (disconnect a required edge for the negative control)\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"
@@ -1179,6 +1463,8 @@ namespace
else if(arg=="--audit-resolved-layout-passages")options.AuditResolvedLayoutPassages=true;
else if(arg=="--audit-landmark-reachability")options.AuditLandmarkReachability=true;
else if(arg=="--audit-native-caves")options.AuditNativeCaves=true;
else if(arg=="--audit-native-lattice")options.AuditNativeLattice=true;
else if(arg=="--lattice-orphan-control")options.LatticeOrphanControl=true;
else if(arg=="--audit-surface-clearance")options.AuditSurfaceClearance=true;
else if(arg=="--audit-strate-transitions")options.AuditStrateTransitions=true;
else if(arg.starts_with("--transition-mode="))
@@ -1233,13 +1519,21 @@ namespace
{
const std::string_view recipe=arg.substr(std::string_view("--recipe=").size());
if(recipe=="surface-world")
{options.FloatingIslandsRecipe=false;options.CavesRecipe=false;}
{options.FloatingIslandsRecipe=false;options.CavesRecipe=false;options.LatticeRecipe=false;}
else if(recipe=="floating-islands")
{options.FloatingIslandsRecipe=true;options.CavesRecipe=false;}
{options.FloatingIslandsRecipe=true;options.CavesRecipe=false;options.LatticeRecipe=false;}
else if(recipe=="caves")
{options.FloatingIslandsRecipe=false;options.CavesRecipe=true;}
{options.FloatingIslandsRecipe=false;options.CavesRecipe=true;options.LatticeRecipe=false;}
else if(recipe=="lattice")
{options.FloatingIslandsRecipe=false;options.CavesRecipe=false;options.LatticeRecipe=true;}
else {std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(recipe.size()),recipe.data());return false;}
}
else if(arg.starts_with("--lattice-strate="))
{
if(!readInt("--lattice-strate=",options.LatticeStrateIndex)
||options.LatticeStrateIndex<0)
{std::fprintf(stderr,"--lattice-strate must be a non-negative strate index\n");return false;}
}
else if(arg=="--landmark-chamber-demo")options.LandmarkChamberDemo=true;
else if(arg=="--landmark-l45-ramp-control")options.LandmarkL45RampControl=true;
else if(arg=="--ore-veins-demo")options.OreVeinsDemo=true;
@@ -1330,6 +1624,10 @@ namespace
{std::fprintf(stderr,"--landmark-l45-ramp-control requires --landmark-chamber-demo\n");return false;}
if(options.AuditOreVeinYield&&!options.OreVeinsDemo)
{std::fprintf(stderr,"--audit-ore-vein-yield requires --ore-veins-demo\n");return false;}
if(options.LatticeRecipe&&options.LatticeStrateIndex<0)
{std::fprintf(stderr,"--recipe=lattice requires an explicit --lattice-strate=N selection\n");return false;}
if((options.AuditNativeLattice||options.LatticeOrphanControl)&&!options.LatticeRecipe)
{std::fprintf(stderr,"native lattice audits require --recipe=lattice\n");return false;}
if(options.TlsProbeRequested)return true;
if(!options.WorldAssemblerPrototype||!options.StreamBenchmark||!options.StreamPipeline)
{
@@ -1427,8 +1725,10 @@ int main(int argc,char** argv)
}
VoxelForgeCore::ResolvedLayoutSnapshotV3 resolvedLayout;
{
const std::string_view variant=options.CavesRecipe?"caves"
:options.FloatingIslandsRecipe?"floating-islands":"surface-world";
const std::string variant=options.LatticeRecipe
?"lattice/"+std::to_string(options.LatticeStrateIndex)
:options.CavesRecipe?"caves"
: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;}
@@ -1515,6 +1815,18 @@ int main(int argc,char** argv)
resolvedLayout,seed,rooms,edges,error))
{std::fprintf(stderr,"Native caves spine resolution failed: %s\n",error.c_str());return 2;}
}
if(options.LatticeRecipe)
{
if(options.LatticeStrateIndex<0)
{std::fprintf(stderr,"--recipe=lattice requires an explicit --lattice-strate=N selection\n");return 2;}
std::vector<VoxelForgeCore::ResolvedCavernRoomV1> rooms;
std::vector<VoxelForgeCore::ResolvedCavernEdgeV1> edges;
if(!MakeNativeLatticeSpine(resolvedLayout,seed,options.LatticeStrateIndex,
options.LatticeOrphanControl,rooms,edges,error)
||!VoxelForgeCore::ResolveResolvedCavernGraphV1(
resolvedLayout,seed,rooms,edges,error))
{std::fprintf(stderr,"Native lattice graph resolution failed: %s\n",error.c_str());return 2;}
}
if(options.OreVeinsDemo)
{
std::vector<VoxelForgeCore::ResolvedLayoutOreVeinRequestV1> requests;
@@ -1609,7 +1921,8 @@ int main(int argc,char** argv)
slot.StrateIndex,resolvedStrate->generatorKind.c_str(),
static_cast<std::uint32_t>(slot.Definition->PassageConfig.Style));
}
const auto requestedRecipe=options.CavesRecipe?std::string_view("caves")
const auto requestedRecipe=options.LatticeRecipe?std::string_view("lattice")
:options.CavesRecipe?std::string_view("caves")
:options.FloatingIslandsRecipe?std::string_view("floating-islands")
:std::string_view("surface-world");
const auto topStratum=std::max_element(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
@@ -1626,10 +1939,13 @@ int main(int argc,char** argv)
[&](const auto& plan){return plan.strateIndex==stratum.strateIndex;});
});
const bool hasNativeCavesRecipe=std::any_of(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[](const auto& stratum){return stratum.generatorKind=="Caves"
&&stratum.recipeId=="Core.Caves.PrimitiveField"&&stratum.recipeVersion==1
[](const auto& stratum){return VoxelForgeCore::IsNativeCaveFieldStratum(stratum)
&&stratum.passageCapabilities.hasNativeCaveField;});
const auto actualRecipe=hasNativeCavesRecipe?std::string_view("caves")
const bool hasNativeLatticeRecipe=std::any_of(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[](const auto& stratum){return VoxelForgeCore::IsNativeLatticeFieldStratum(stratum)
&&stratum.passageCapabilities.hasNativeLatticeField;});
const auto actualRecipe=hasNativeLatticeRecipe?std::string_view("lattice")
:hasNativeCavesRecipe?std::string_view("caves")
:hasFloatingIslands?std::string_view("floating-islands")
:hasSurfaceWorldPlan?std::string_view("surface-world")
:std::string_view("missing");
@@ -1834,5 +2150,6 @@ int main(int argc,char** argv)
options.AuditMotifIntervals,
options.ExactMidpointDensityMemo,options.ActiveLaneBatching,
options.ProofBlockCells,options.HasSignEdgeRepairOverride
?options.ParallelSignEdgeRepair:options.FloatingIslandsRecipe);
?options.ParallelSignEdgeRepair:options.FloatingIslandsRecipe,
options.AuditNativeLattice,options.LatticeOrphanControl);
}