wip(assembler): round L37 -- FI mouth carve-fade fix, no raised bridge (style 0); research R1

The passage mouth fade multiplied the signed carve distance by zero, which turned native rock into an
open surface (the reason earlier rounds stamped walk pads at mouths); it now blends between the
uncarved field and the full signed carve. The FI style-0 route followed a lifted grade envelope over
the crater (the "bridge"); it now runs on the rim and follows the native surface. New built-shape and
crease audits with thresholds frozen before the fix (L36 and box controls fail). 24/24 passage rows,
30/30 determinism, 16/16 invariants, 18/18 interface/ring. Unreal: one recipe setter (uncompiled).
Research R1 (read-only, web): ranked proposals for natural walkable mouths, floor-limited carve first.

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-23 05:51:50 +02:00
1 parent 8be1c4d9ef
commit 3e443bf81c
33 files changed
+2767 -86

No files matched your search

+69 -9
View File
@@ -221,6 +221,7 @@ namespace
out<<"{\"stable_id\":"<<LayoutEscape(p.stableId)
<<",\"upper_strate_index\":"<<p.upperStrateIndex
<<",\"lower_strate_index\":"<<p.lowerStrateIndex
<<",\"style\":"<<p.style
<<",\"placement_radius_q\":"<<p.placementRadiusSubvoxels
<<",\"upper_mouth_q\":["<<p.upperMouthSubvoxels[0]<<','
<<p.upperMouthSubvoxels[1]<<','<<p.upperMouthSubvoxels[2]
@@ -683,6 +684,8 @@ std::optional<ResolvedLayoutSnapshotV3> ResolvedLayoutSnapshotV3::FromJson(
ResolvedLayoutPassageV1 p;p.stableId=LayoutString(v,"stable_id");
p.upperStrateIndex=static_cast<std::int32_t>(LayoutInt(v,"upper_strate_index"));
p.lowerStrateIndex=static_cast<std::int32_t>(LayoutInt(v,"lower_strate_index"));
if(v.Get("style").IsNumber())
p.style=static_cast<std::uint32_t>(LayoutInt(v,"style"));
p.placementRadiusSubvoxels=LayoutInt(v,"placement_radius_q");
p.mouthRadiusSubvoxels=LayoutInt(v,"mouth_radius_q");p.midRadiusSubvoxels=LayoutInt(v,"mid_radius_q");
const auto& upper=v.Get("upper_mouth_q").AsArray();
@@ -808,6 +811,7 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
for(std::uint32_t connection=0;connection<connectionCount;++connection)
{
ResolvedLayoutPassageV1 passage;
passage.style=style;
passage.stableId="passage/"+std::to_string(upper.strateIndex)+"-"
+std::to_string(lower.strateIndex)+"/"+std::to_string(connection);
passage.upperStrateIndex=upper.strateIndex;passage.lowerStrateIndex=lower.strateIndex;
@@ -886,22 +890,45 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
std::max(ringRadius,clearRingRadius));
}
if(anchoredIslandPassage)
ringRadius=std::min(ringRadius,mouthRadius+qPerMetre/2);
{
const std::int64_t craterRimRouteRadius=VoxelForgeCore::WorldAssemblyEvaluatorVersion>=185
&&style==0&&!anchoredSpiral&&passageAnchor&&passageAnchor->values.size()>3
?std::max<std::int64_t>(midRadius,
passageAnchor->values[3]+2*qPerMetre)
:mouthRadius+qPerMetre/2;
ringRadius=std::min(ringRadius,anchoredSpiral
?mouthRadius+qPerMetre/2:craterRimRouteRadius);
}
std::uint32_t phase=static_cast<std::uint32_t>(PassageSeed(seed,
upper.strateIndex,lower.strateIndex,connection,0x50484153u)%16);
if(hasUpperRoute)
{
std::int64_t bestAlignment=std::numeric_limits<std::int64_t>::min();
const std::uint32_t hashedPhase=phase;
const std::int64_t phaseX=style==0&&anchoredIslandPassage
&&!anchoredSpiral&&passageAnchor
?upperMouth[0]-passageAnchor->values[0]
:(hasUpperTangent?upperTangent[0]:upperMouth[0]);
const std::int64_t phaseY=style==0&&anchoredIslandPassage
&&!anchoredSpiral&&passageAnchor
?upperMouth[1]-passageAnchor->values[1]
:(hasUpperTangent?upperTangent[1]:upperMouth[1]);
for(std::uint32_t offset=0;offset<16;++offset)
{
const std::uint32_t candidate=static_cast<std::uint32_t>(
(hashedPhase+offset)%16);
const std::int64_t alignment=(hasUpperTangent?upperTangent[0]:upperMouth[0])
*directions[candidate][0]
+(hasUpperTangent?upperTangent[1]:upperMouth[1])
*directions[candidate][1];
if(alignment>bestAlignment)
const std::int64_t alignment=phaseX*directions[candidate][0]
+phaseY*directions[candidate][1];
if(style==0&&anchoredIslandPassage&&!anchoredSpiral&&passageAnchor)
{
const std::int64_t targetProjection=ringRadius*65536;
if(alignment<=0)continue;
const std::int64_t tangentError=std::abs(alignment-targetProjection);
if(tangentError<bestAlignment
||bestAlignment==std::numeric_limits<std::int64_t>::min())
{bestAlignment=tangentError;phase=candidate;}
}
else if(alignment>bestAlignment)
{bestAlignment=alignment;phase=candidate;}
}
}
@@ -924,7 +951,18 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
}
bool clockwise=(PassageSeed(seed,upper.strateIndex,lower.strateIndex,
connection,0x44495245u)&1u)!=0;
if(anchoredSpiral&&passageAnchor&&hasUpperTangent)
if(style==0&&anchoredIslandPassage&&!anchoredSpiral&&passageAnchor)
{
const auto& ringDirection=directions[phase];
const double radiusX=static_cast<double>(ringRadius)*ringDirection[0]/65536.0;
const double radiusY=static_cast<double>(ringRadius)*ringDirection[1]/65536.0;
const double anchorX=static_cast<double>(passageAnchor->values[0]);
const double anchorY=static_cast<double>(passageAnchor->values[1]);
const double connectorX=anchorX+radiusX-upperMouth[0];
const double connectorY=anchorY+radiusY-upperMouth[1];
clockwise=connectorX*(-radiusY)+connectorY*radiusX>=0.0;
}
else if(anchoredSpiral&&passageAnchor&&hasUpperTangent)
{
const double radialX=static_cast<double>(upperMouth[0]-passageAnchor->values[0]);
const double radialY=static_cast<double>(upperMouth[1]-passageAnchor->values[1]);
@@ -1068,7 +1106,8 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
hasAnchorHelix=helixEndIndex>0;
}
const std::int64_t routeGradeQ16=hasAnchorHelix
&&lower.generatorKind=="SurfaceWorld"?8000:TargetGradeQ16;
&&lower.generatorKind=="SurfaceWorld"?8000
:style==0&&anchoredIslandPassage&&!anchoredSpiral?15500:TargetGradeQ16;
const std::array<std::int64_t,2> firstRing=ringPoint(phase);
if(hasAnchorHelix&&pathStyle==1u)
{
@@ -1168,7 +1207,7 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
pushXY(ringPoint(lowerPhase));
}
pushXY({lowerMouth[0],lowerMouth[1]});totalHorizontal=measurePath();
const std::size_t lowerMouthIndex=xy.size()-1;
std::size_t lowerMouthIndex=xy.size()-1;
std::vector<std::array<std::int64_t,3>> lowerLandingPoints;
if(hasLowerTangent)
{
@@ -1202,6 +1241,27 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
if(lowerLandingPoints.empty())
{error=passage.stableId+" lower route has no landing length inside PassageConfig.DistanceMax";return false;}
}
if(VoxelForgeCore::WorldAssemblyEvaluatorVersion>=188
&&style==0&&anchoredIslandPassage&&!anchoredSpiral&&xy.size()>4)
{
std::vector<std::array<std::int64_t,2>> refined;
refined.reserve(xy.size()*2);
for(std::size_t index=0;index+1<xy.size();++index)
{
refined.push_back(xy[index]);
if(index<3)continue;
refined.push_back({
static_cast<std::int64_t>(std::llround(0.5*(
static_cast<double>(xy[index][0])
+static_cast<double>(xy[index+1][0])))),
static_cast<std::int64_t>(std::llround(0.5*(
static_cast<double>(xy[index][1])
+static_cast<double>(xy[index+1][1]))))});
}
refined.push_back(xy.back());
if(lowerMouthIndex>3)lowerMouthIndex+=lowerMouthIndex-3;
xy.swap(refined);
}
totalHorizontal=measurePath();
if(loops>=256||totalHorizontal==0)
{error=passage.stableId+" could not fit a supported grade inside the resolved placement radius";return false;}