wip: opt-in landing-pad contract + Core.Liminal.Field v2 pads (L145)

Layers may publish certified arrival/departure pads; the passage planner binds endpoints and tangents to them;
no-pad layouts serialize unchanged (owner canonical hashes match v227). Pads removed the endpoint grade failures;
seeds 0-4 passed at a 45 m margin, but seed 5 still has 289 blocked passage-capsule samples ~29 m before the
departure pad, where the composed field stays solid (-0.162) inside the tube over native ground (-3.6). Ripple
audit now keeps true route distance across masked gaps (with a synthetic control).

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-11-01 12:19:30 +01:00
1 parent a45ba9bb10
commit 7d654ff861
14 files changed
+1228 -66

No files matched your search

+398 -1
View File
@@ -542,7 +542,8 @@ namespace world_assembly_detail
const auto& liminal = stratum.liminalField;
if (liminal.version != 0)
{
if (liminal.version != CoreLiminalFieldRecipeVersionV1
if ((liminal.version != CoreLiminalFieldRecipeVersionV1
&& liminal.version != CoreLiminalFieldRecipeVersionV2)
|| static_cast<std::uint32_t>(liminal.variant) >= CoreLiminalFieldVariantCountV1
|| liminal.seed != effectiveRecipe.seed
|| liminal.variant != SelectCoreLiminalFieldVariantV1(liminal.seed)
@@ -2719,6 +2720,402 @@ bool PlanCoreLiminalFieldV1(WorldAssemblyRecipeV1& recipe,
return true;
}
std::array<std::array<std::int64_t,2>,6> CoreLiminalRouteXYV2(
std::int64_t startX,std::int64_t startY,std::int64_t finishX,
std::int64_t finishY,std::int64_t qPerMetre)
{
return {{{{startX,startY}},{{-40*qPerMetre,40*qPerMetre}},
{{-40*qPerMetre,-40*qPerMetre}},{{40*qPerMetre,-40*qPerMetre}},
{{40*qPerMetre,40*qPerMetre}},{{finishX,finishY}}}};
}
std::vector<WorldAssemblyRoutePointV1> BuildCoreLiminalRouteV2(
const WorldAssemblySurfaceProfileV1& profile,
const ResolvedLayoutLandingPadV1& arrivalPad,
const ResolvedLayoutLandingPadV1& departurePad,
const WorldAssemblyLiminalVariantDefinitionV1& definition,
std::uint32_t seed,std::int32_t strateIndex,std::int64_t coreMicrons,
std::int64_t qPerMetre,
std::uint64_t& totalHorizontal,std::string& error)
{
error.clear();totalHorizontal=0;
const auto groundHeightAt=[&](std::int64_t x,std::int64_t y)
{
if(profile.kind==WorldAssemblySurfaceProfileKindV1::flatField)
return profile.h0Subvoxels;
const std::int64_t turnX=world_assembly_detail::SurfaceProfileTurnAtCoordinate(
x,profile.wavelengthXSubvoxels,profile.phaseXTurnsQ32);
const std::int64_t turnY=world_assembly_detail::SurfaceProfileTurnAtCoordinate(
y,profile.wavelengthYSubvoxels,profile.phaseYTurnsQ32);
return profile.h0Subvoxels
+world_assembly_detail::MulQ30(profile.amplitudeXSubvoxels,
world_assembly_detail::CosineQ30(turnX))
+world_assembly_detail::MulQ30(profile.amplitudeYSubvoxels,
world_assembly_detail::CosineQ30(turnY));
};
const auto horizontalLengthQ=[](std::int64_t dx,std::int64_t dy)
{return world_assembly_detail::IntegerSqrt(static_cast<std::uint64_t>(dx*dx+dy*dy));};
const auto micrometresToQ=[&](std::int64_t micrometres)
{return (micrometres*WorldAssemblySubvoxelsPerVoxel+coreMicrons/2)/coreMicrons;};
const auto routeXY=CoreLiminalRouteXYV2(arrivalPad.positionSubvoxels[0],
arrivalPad.positionSubvoxels[1],departurePad.positionSubvoxels[0],
departurePad.positionSubvoxels[1],qPerMetre);
std::vector<WorldAssemblyRoutePointV1> route;
const std::int64_t pointSpacing=12*qPerMetre;
const std::int64_t routeRadius=std::max<std::int64_t>(
micrometresToQ(definition.routeHalfWidthMicrometres),micrometresToQ(500000));
const auto routeId=[&](std::size_t ordinal)
{
std::uint64_t id=14695981039346656037ull;
const auto add=[&](std::uint64_t value,std::uint32_t bytes)
{for(std::uint32_t byte=0;byte<bytes;++byte)
{id^=static_cast<std::uint8_t>(value>>(byte*8));id*=1099511628211ull;}};
add(seed,4);add(static_cast<std::uint32_t>(strateIndex),4);add(ordinal,4);
return id?id:1;
};
const auto appendRoutePoint=[&](std::int64_t x,std::int64_t y)
{
WorldAssemblyRoutePointV1 point;
point.positionSubvoxels={x,y,groundHeightAt(x,y)};
point.radiusSubvoxels=routeRadius;
point.stableFeatureId=routeId(route.size());
route.push_back(point);
};
const auto interpolate=[](std::int64_t start,std::int64_t delta,
std::uint64_t step,std::uint64_t steps)
{
const std::int64_t numerator=delta*static_cast<std::int64_t>(step);
const std::int64_t divisor=static_cast<std::int64_t>(steps);
return start+(numerator>=0?(numerator+divisor/2)/divisor
:(numerator-divisor/2)/divisor);
};
appendRoutePoint(routeXY.front()[0],routeXY.front()[1]);
for(std::size_t segment=1;segment<routeXY.size();++segment)
{
const std::int64_t dx=routeXY[segment][0]-routeXY[segment-1][0];
const std::int64_t dy=routeXY[segment][1]-routeXY[segment-1][1];
const std::uint64_t length=horizontalLengthQ(dx,dy);
if(length==0){error="Core.Liminal.Field v2 route contains a zero-horizontal segment";return {};}
totalHorizontal+=length;
const std::uint64_t steps=std::max<std::uint64_t>(1,
(length+static_cast<std::uint64_t>(pointSpacing)-1)
/static_cast<std::uint64_t>(pointSpacing));
for(std::uint64_t step=1;step<=steps;++step)
appendRoutePoint(interpolate(routeXY[segment-1][0],dx,step,steps),
interpolate(routeXY[segment-1][1],dy,step,steps));
}
if(route.size()<2||totalHorizontal<300*static_cast<std::uint64_t>(qPerMetre)
||route.front().positionSubvoxels[2]!=arrivalPad.floorHeightSubvoxels
||route.back().positionSubvoxels[2]!=departurePad.floorHeightSubvoxels)
{error="Core.Liminal.Field v2 pad-to-pad route is incomplete or too short";return {};}
return route;
}
bool PrepareCoreLiminalLandingPadsV2(WorldAssemblyRecipeV1& recipe,
WorldAssemblyStratumPlanV1& stratum,ResolvedLayoutSnapshotV3& layout,
std::string& error)
{
error.clear();
if(layout.coreVoxelSizeMicrometres==0||stratum.strateIndex<0
||stratum.topChunkZ<stratum.bottomChunkZ)
{error="Core.Liminal.Field v2 needs a finite stratum and resolved Core voxel size";return false;}
auto resolved=std::find_if(layout.strates.begin(),layout.strates.end(),
[&](const auto& value){return value.strateIndex==stratum.strateIndex
&&value.generatorKind=="SurfaceWorld";});
if(resolved==layout.strates.end()||!resolved->content.presentInCurrentField)
{error="Core.Liminal.Field v2 must target a resolved SurfaceWorld content band";return false;}
constexpr std::int64_t Q=WorldAssemblySubvoxelsPerVoxel;
const std::int64_t coreMicrons=layout.coreVoxelSizeMicrometres;
const auto micrometresToQ=[&](std::int64_t micrometres)
{
const std::int64_t numerator=micrometres*Q;
return numerator>=0?(numerator+coreMicrons/2)/coreMicrons
:(numerator-coreMicrons/2)/coreMicrons;
};
const std::int64_t qPerMetre=micrometresToQ(1000000);
if(qPerMetre<=0){error="Core.Liminal.Field v2 could not resolve fixed-scale metres";return false;}
const std::uint32_t seed=recipe.seed;
const WorldAssemblyLiminalVariantV1 variant=SelectCoreLiminalFieldVariantV1(seed);
const auto& definition=CoreLiminalFieldVariantsV1[static_cast<std::size_t>(variant)];
const std::int64_t bottom=static_cast<std::int64_t>(stratum.bottomChunkZ)
*recipe.layoutChunkWidthSubvoxels;
const std::int64_t top=(static_cast<std::int64_t>(stratum.topChunkZ)+1)
*recipe.layoutChunkWidthSubvoxels;
const std::int64_t contentBottom=micrometresToQ(resolved->content.bottomMicrometres);
const std::int64_t profileRelief=variant==WorldAssemblyLiminalVariantV1::repeatingHills
?2*micrometresToQ(definition.hillAmplitudeMicrometres):0;
const std::int64_t deckSweepRadius=static_cast<std::int64_t>(std::ceil(std::hypot(
static_cast<double>(definition.routeHalfWidthMicrometres+250000),
static_cast<double>(definition.routeHalfThicknessMicrometres+250000))));
const std::int64_t floorClearance=definition.routeHalfThicknessMicrometres
+deckSweepRadius+250000;
// Keep the field above the lower tunnel's mouth transition so the routed
// departure has a clean open section before it reaches the cave wall.
constexpr std::int64_t MinimumFieldGroundMarginMicrometres=20000000;
const std::int64_t fieldGroundMargin=std::max(floorClearance,
MinimumFieldGroundMarginMicrometres);
const std::int64_t floorHeight=contentBottom+profileRelief
+micrometresToQ(fieldGroundMargin);
if(floorHeight<=bottom||top<=floorHeight+8*qPerMetre)
{error="Core.Liminal.Field v2 has no room for its supported field and cap";return false;}
WorldAssemblySurfaceProfileV1 profile;
profile.version=1;
profile.kind=definition.surfaceKind;
profile.h0Subvoxels=floorHeight;
if(profile.kind==WorldAssemblySurfaceProfileKindV1::periodicHills)
{
profile.amplitudeXSubvoxels=micrometresToQ(definition.hillAmplitudeMicrometres);
profile.amplitudeYSubvoxels=profile.amplitudeXSubvoxels;
profile.wavelengthXSubvoxels=micrometresToQ(definition.hillWavelengthMicrometres);
profile.wavelengthYSubvoxels=profile.wavelengthXSubvoxels;
ResolveWorldAssemblySurfaceProfilePhasesV1(profile,seed);
}
if(!world_assembly_detail::ValidateSurfaceProfile(profile,seed,error))return false;
stratum.hasRecipeOverride=true;
stratum.recipeOverride=recipe;
stratum.recipeOverride.surfaceProfile=profile;
stratum.recipeOverride.contentHash=0;
stratum.surfaceProfile=profile;
stratum.capHeightSubvoxels=top-4*qPerMetre;
stratum.capUndulationSubvoxels=0;
stratum.capDetailAmplitudeSubvoxels=0;
stratum.capRidgeAmplitudeSubvoxels=0;
stratum.waterEnabled=false;
stratum.waterSurfaceSubvoxels=0;
const auto groundHeightAt=[&](std::int64_t x,std::int64_t y)
{
if(profile.kind==WorldAssemblySurfaceProfileKindV1::flatField)
return profile.h0Subvoxels;
const std::int64_t turnX=world_assembly_detail::SurfaceProfileTurnAtCoordinate(
x,profile.wavelengthXSubvoxels,profile.phaseXTurnsQ32);
const std::int64_t turnY=world_assembly_detail::SurfaceProfileTurnAtCoordinate(
y,profile.wavelengthYSubvoxels,profile.phaseYTurnsQ32);
return profile.h0Subvoxels
+world_assembly_detail::MulQ30(profile.amplitudeXSubvoxels,
world_assembly_detail::CosineQ30(turnX))
+world_assembly_detail::MulQ30(profile.amplitudeYSubvoxels,
world_assembly_detail::CosineQ30(turnY));
};
const auto routeXY=CoreLiminalRouteXYV2(-12*qPerMetre,0,12*qPerMetre,0,qPerMetre);
const auto squareRoot=[](std::uint64_t value)
{return world_assembly_detail::IntegerSqrt(value);};
const auto directionQ16=[&](std::int64_t dx,std::int64_t dy)
{
const std::uint64_t length=squareRoot(static_cast<std::uint64_t>(dx*dx+dy*dy));
if(length==0)return std::array<std::int32_t,2>{{0,0}};
const auto rounded=[&](std::int64_t value)
{return value>=0?(value+static_cast<std::int64_t>(length/2))
/static_cast<std::int64_t>(length)
:(value-static_cast<std::int64_t>(length/2))
/static_cast<std::int64_t>(length);};
return std::array<std::int32_t,2>{{
static_cast<std::int32_t>(rounded(dx*65536)),
static_cast<std::int32_t>(rounded(dy*65536))}};
};
const auto arrivalDirection=directionQ16(routeXY[1][0]-routeXY[0][0],
routeXY[1][1]-routeXY[0][1]);
const auto departureDirection=directionQ16(routeXY.back()[0]-routeXY[routeXY.size()-2][0],
routeXY.back()[1]-routeXY[routeXY.size()-2][1]);
const std::int64_t playerCenterAboveFloor=micrometresToQ(1130000);
const std::int64_t landingClearance=micrometresToQ(6000000);
const std::int64_t supportDepth=micrometresToQ(2000000);
const auto makePad=[&](std::string id,ResolvedLayoutLandingPadRoleV1 role,
const std::array<std::int64_t,2>& xy,const std::array<std::int32_t,2>& direction)
{
ResolvedLayoutLandingPadV1 pad;
pad.stableId=std::move(id);pad.role=role;
pad.floorHeightSubvoxels=groundHeightAt(xy[0],xy[1]);
pad.positionSubvoxels={xy[0],xy[1],pad.floorHeightSubvoxels+playerCenterAboveFloor};
pad.approachDirectionQ16=direction;
pad.clearanceSubvoxels=landingClearance;
pad.supportDepthSubvoxels=supportDepth;
pad.certifiedWalkableWithSupport=true;
return pad;
};
resolved->recipeId=std::string(CoreLiminalFieldRecipeIdV1);
resolved->recipeVersion=CoreLiminalFieldRecipeVersionV2;
resolved->landingPads.clear();
resolved->landingPads.push_back(makePad("core/liminal-field/landing/arrival/000",
ResolvedLayoutLandingPadRoleV1::arrival,routeXY.front(),arrivalDirection));
resolved->landingPads.push_back(makePad("core/liminal-field/landing/departure/000",
ResolvedLayoutLandingPadRoleV1::departure,routeXY.back(),departureDirection));
std::uint64_t routeLength=0;
stratum.route=BuildCoreLiminalRouteV2(profile,resolved->landingPads[0],
resolved->landingPads[1],definition,seed,stratum.strateIndex,coreMicrons,
qPerMetre,routeLength,error);
if(!error.empty())return false;
stratum.routeConstraints={1,micrometresToQ(340000),micrometresToQ(1760000),
17560,micrometresToQ(125000),micrometresToQ(250000),
micrometresToQ(1000000),micrometresToQ(120000),3};
resolved->anchors.erase(std::remove_if(resolved->anchors.begin(),resolved->anchors.end(),
[](const auto& anchor){return anchor.kind=="route_point"
||anchor.kind=="liminal_route_point"||anchor.kind=="liminal_variant"
||anchor.kind=="heightfield_profile";}),resolved->anchors.end());
ResolvedLayoutAnchorV2 profileAnchor;
profileAnchor.kind="heightfield_profile";
profileAnchor.stableId="heightfield-profile/liminal/"
+std::to_string(static_cast<std::uint32_t>(profile.kind));
profileAnchor.units="profile kind enum";
profileAnchor.values={1,static_cast<std::int64_t>(profile.kind)};
resolved->anchors.push_back(std::move(profileAnchor));
std::uint64_t routeAnchorDistance=0,lastRouteAnchorDistance=0;
for(std::size_t pointIndex=0;pointIndex<stratum.route.size();++pointIndex)
{
if(pointIndex>0)
{
const auto& previous=stratum.route[pointIndex-1].positionSubvoxels;
const auto& current=stratum.route[pointIndex].positionSubvoxels;
const auto dx=static_cast<std::uint64_t>(current[0]-previous[0]);
const auto dy=static_cast<std::uint64_t>(current[1]-previous[1]);
routeAnchorDistance+=world_assembly_detail::IntegerSqrt(dx*dx+dy*dy);
}
const bool first=pointIndex==0;
const bool last=pointIndex+1==stratum.route.size();
const bool spaced=routeAnchorDistance-lastRouteAnchorDistance
>=static_cast<std::uint64_t>(8*qPerMetre);
if(!first&&!last&&!spaced)continue;
const auto& point=stratum.route[pointIndex];
ResolvedLayoutAnchorV2 routeAnchor;
routeAnchor.kind="route_point";
routeAnchor.stableId="route/"+std::to_string(pointIndex);
routeAnchor.units="1/256 Core voxel";
routeAnchor.values={point.positionSubvoxels[0],point.positionSubvoxels[1],
point.positionSubvoxels[2]+playerCenterAboveFloor,point.radiusSubvoxels};
resolved->anchors.push_back(std::move(routeAnchor));
lastRouteAnchorDistance=routeAnchorDistance;
}
if(!layout.finalize(error))return false;
const auto reportPad=[&](const ResolvedLayoutLandingPadV1& pad)
{
std::printf("[ResolvedLandingPad] strate=%d id=%s role=%s position_m=(%.3f,%.3f,%.3f) "
"floor_m=%.3f approach_q16=(%d,%d) clearance_m=%.3f support_m=%.3f "
"certified_walkable_with_support=true status=PASS\n",stratum.strateIndex,
pad.stableId.c_str(),pad.role==ResolvedLayoutLandingPadRoleV1::arrival?"arrival":"departure",
pad.positionSubvoxels[0]/static_cast<double>(qPerMetre),
pad.positionSubvoxels[1]/static_cast<double>(qPerMetre),
pad.positionSubvoxels[2]/static_cast<double>(qPerMetre),
pad.floorHeightSubvoxels/static_cast<double>(qPerMetre),
pad.approachDirectionQ16[0],pad.approachDirectionQ16[1],
pad.clearanceSubvoxels/static_cast<double>(qPerMetre),
pad.supportDepthSubvoxels/static_cast<double>(qPerMetre));
};
reportPad(resolved->landingPads[0]);reportPad(resolved->landingPads[1]);
std::printf("[LiminalPadRoute] points=%zu path_length_m=%.3f spacing_max_m=4.000 "
"profile_ground_following=true status=PASS\n",stratum.route.size(),
routeLength/static_cast<double>(qPerMetre));
return true;
}
bool PlanCoreLiminalFieldV2(WorldAssemblyRecipeV1& recipe,
WorldAssemblyStratumPlanV1& stratum,const ResolvedLayoutSnapshotV3& layout,
std::string& error)
{
error.clear();
if(layout.coreVoxelSizeMicrometres==0||stratum.strateIndex<0
||stratum.topChunkZ<stratum.bottomChunkZ)
{error="Core.Liminal.Field v2 needs a finite stratum and resolved Core voxel size";return false;}
const auto resolved=std::find_if(layout.strates.begin(),layout.strates.end(),
[&](const auto& value){return value.strateIndex==stratum.strateIndex
&&value.recipeId==CoreLiminalFieldRecipeIdV1
&&value.recipeVersion==CoreLiminalFieldRecipeVersionV2;});
if(resolved==layout.strates.end()||!resolved->content.presentInCurrentField
||stratum.surfaceProfile.version!=1)
{error="Core.Liminal.Field v2 needs its prepared profile and resolved landing pads";return false;}
const ResolvedLayoutLandingPadV1* arrivalPad=nullptr;
const ResolvedLayoutLandingPadV1* departurePad=nullptr;
for(const auto& pad:resolved->landingPads)
{
if(pad.role==ResolvedLayoutLandingPadRoleV1::arrival)
{if(arrivalPad){error="Core.Liminal.Field v2 has multiple arrival pads";return false;}arrivalPad=&pad;}
if(pad.role==ResolvedLayoutLandingPadRoleV1::departure)
{if(departurePad){error="Core.Liminal.Field v2 has multiple departure pads";return false;}departurePad=&pad;}
}
if(!arrivalPad||!departurePad||!arrivalPad->certifiedWalkableWithSupport
||!departurePad->certifiedWalkableWithSupport)
{error="Core.Liminal.Field v2 requires certified arrival and departure pads";return false;}
const ResolvedLayoutPassageV1* arrival=nullptr;
const ResolvedLayoutPassageV1* departure=nullptr;
for(const auto& passage:layout.passages)
{
if(passage.lowerStrateIndex==stratum.strateIndex)
{if(arrival){error="Core.Liminal.Field v2 requires one arrival passage";return false;}arrival=&passage;}
if(passage.upperStrateIndex==stratum.strateIndex)
{if(departure){error="Core.Liminal.Field v2 requires one departure passage";return false;}departure=&passage;}
}
if(!arrival||!departure||arrival->lowerMouthSubvoxels!=arrivalPad->positionSubvoxels
||departure->upperMouthSubvoxels!=departurePad->positionSubvoxels)
{error="Core.Liminal.Field v2 passage mouths are not bound to the certified layer pads";return false;}
constexpr std::int64_t Q=WorldAssemblySubvoxelsPerVoxel;
const std::int64_t coreMicrons=layout.coreVoxelSizeMicrometres;
const auto micrometresToQ=[&](std::int64_t micrometres)
{
const std::int64_t numerator=micrometres*Q;
return numerator>=0?(numerator+coreMicrons/2)/coreMicrons
:(numerator-coreMicrons/2)/coreMicrons;
};
const std::int64_t qPerMetre=micrometresToQ(1000000);
const std::int64_t playerCenterAboveFloor=micrometresToQ(1130000);
if(qPerMetre<=0||arrivalPad->positionSubvoxels[2]
!=arrivalPad->floorHeightSubvoxels+playerCenterAboveFloor
||departurePad->positionSubvoxels[2]
!=departurePad->floorHeightSubvoxels+playerCenterAboveFloor)
{error="Core.Liminal.Field v2 pad floor and capsule-center heights differ";return false;}
const std::uint32_t seed=recipe.seed;
const WorldAssemblyLiminalVariantV1 variant=SelectCoreLiminalFieldVariantV1(seed);
const auto& definition=CoreLiminalFieldVariantsV1[static_cast<std::size_t>(variant)];
const auto& profile=stratum.surfaceProfile;
std::uint64_t totalHorizontal=0;
std::vector<WorldAssemblyRoutePointV1> route=BuildCoreLiminalRouteV2(profile,
*arrivalPad,*departurePad,definition,seed,stratum.strateIndex,coreMicrons,
qPerMetre,totalHorizontal,error);
if(!error.empty())return false;
if(route.size()!=stratum.route.size())
{error="Core.Liminal.Field v2 route differs from the path used to certify its pads";return false;}
for(std::size_t index=0;index<route.size();++index)
if(route[index].stableFeatureId!=stratum.route[index].stableFeatureId
||route[index].positionSubvoxels!=stratum.route[index].positionSubvoxels
||route[index].radiusSubvoxels!=stratum.route[index].radiusSubvoxels)
{error="Core.Liminal.Field v2 route differs from the path used to certify its pads";return false;}
WorldAssemblyLiminalFieldPlanV1 liminal;
liminal.version=CoreLiminalFieldRecipeVersionV2;
liminal.variant=variant;liminal.seed=seed;
liminal.arrivalMouthSubvoxels=arrivalPad->positionSubvoxels;
liminal.departureMouthSubvoxels=departurePad->positionSubvoxels;
liminal.floorHeightSubvoxels=profile.h0Subvoxels;
liminal.routeHalfWidthSubvoxels=micrometresToQ(definition.routeHalfWidthMicrometres);
liminal.routeHalfThicknessSubvoxels=micrometresToQ(definition.routeHalfThicknessMicrometres);
liminal.routeOffsetSubvoxels=150*qPerMetre;
liminal.supportSpacingSubvoxels=micrometresToQ(definition.supportSpacingMicrometres);
liminal.supportRadiusSubvoxels=micrometresToQ(definition.supportRadiusMicrometres);
liminal.mouthFloorOffsetSubvoxels=playerCenterAboveFloor;
stratum.route=std::move(route);
stratum.routeConstraints={1,micrometresToQ(340000),micrometresToQ(1760000),
17560,micrometresToQ(125000),micrometresToQ(250000),
micrometresToQ(1000000),micrometresToQ(120000),3};
stratum.liminalField=liminal;
std::string validationError;
if(!world_assembly_detail::ValidateSurfaceProfile(stratum.surfaceProfile,seed,validationError)
||!world_assembly_detail::ValidateStratum(stratum,recipe,validationError))
{error=validationError.empty()?"Core.Liminal.Field v2 produced an invalid plan":validationError;return false;}
std::printf("[CoreLiminalFieldPlan] recipe=%.*s version=%u variant=%.*s seed=%u "
"arrival_pad=%s departure_pad=%s route_points=%zu path_length_m=%.3f "
"profile_ground_following=true route_grade_limit_deg=15.000 status=PASS\n",
static_cast<int>(CoreLiminalFieldRecipeIdV1.size()),CoreLiminalFieldRecipeIdV1.data(),
liminal.version,static_cast<int>(definition.name.size()),definition.name.data(),seed,
arrivalPad->stableId.c_str(),departurePad->stableId.c_str(),stratum.route.size(),
totalHorizontal/static_cast<double>(qPerMetre));
return true;
}
std::string WorldAssemblyManifest::ToJson() const
{
std::string error;