Files
jesse c297b20aed Disable PA on/off ramps; restore mainline to pre-ramp state
Three iterations of the Daikoku PA ramps never read as a real
interchange. Measured why, rather than tuning further:

  * the entry and exit decks INTERSECTED -- 2547 sample pairs within
    30 studs horizontally at <12 studs dY, worst case 0.5 studs apart
    at dY=0.0. On screen that is the bowtie tangle of white rails.
  * both real Daikoku ramps turn the SAME way (clockwise; the guide
    video says "right, right"). This build mirrored them into each
    other.
  * the real arc wraps OUTSIDE the lot and forms its north/east
    boundary. This build cut across the apron interior.

Gated behind BUILD_PA_RAMPS=false rather than deleted -- the radius
was already correct (470 studs vs an OSM-measured mean of 469) and
the merge lands tangent at 0.1-0.2 deg divergence. Both worth keeping.

Also removed two leftovers that would have outlived the ramps:

  * rampOpen punched holes in the mainline's outer parapet, railing
    and kill wall for ramps that no longer exist -- a barrier gap with
    a drop behind it. Sealed via RAMP_EDGE_OPENINGS=false. Verified:
    Barrier/EdgeRail/KillWall = 1646 each = 823 samples x 2 edges,
    0 road samples without a guard within 90 studs.
  * gore zebra hatching painted 1024 bars + 64 boundary lines marking
    a junction that is not there. Sealed via RAMP_GORE_MARKINGS=false.

Verified after a cache-busting fresh rebuild (Studio's require() cache
otherwise serves the previous map and reports a false pass):
  parts 22628 -> 15988
  all ramp part classes = 0
  Road = 823 (unchanged), spawn pad + PASpawn intact
  clip probe TRUSTWORTHY (control +11/-0), CLIPPING=0

Research and rebuild spec kept for when this is revisited:
reference/ramps/BUILD_SPEC.md, INDEX.md (10 CC-licensed Commons
photos), docs/daikoku-reference-spec.md (OSM circle fits).
2026-08-03 21:15:25 -04:00

105 lines
3.4 KiB
Luau

-- FLYOVER PROBE. Two things the connectivity check cannot tell you:
--
-- 1. Does the crossing actually pass OVER the mainline deck, with real
-- vertical clearance? A "flyover" that intersects the deck is just a
-- wall. Measured as: for every Cross part, find mainline Road parts
-- directly beneath it in plan, and report the worst (smallest) gap
-- between the ramp underside and the road topside.
--
-- 2. Does the descent land tangent and flush on the FAR carriageway?
-- Reported as the dY at the last descent part vs the road beneath it.
--
-- Every metric carries a CONTROL that must come back non-zero, because a
-- silent 0 from a mis-scoped query is indistinguishable from a genuine pass
-- -- that exact trap produced two phantom "defects" earlier in this build.
local ws = game:GetService("Workspace")
local map = ws:FindFirstChild("Map")
if not map then
return "NO MAP"
end
local cross, descent, roads = {}, {}, {}
for _, d in ipairs(map:GetDescendants()) do
if d:IsA("BasePart") then
local nm = d.Name
if nm:find("RampCross_") then
table.insert(cross, d)
elseif nm:find("RampNear_") then
table.insert(descent, d)
elseif nm:sub(1, 5) == "Road_" then
table.insert(roads, d)
end
end
end
-- plan-view overlap (ignores Y entirely)
local function planOverlap(a, b)
return math.abs(a.Position.X - b.Position.X) < (a.Size.X + b.Size.X) / 2
and math.abs(a.Position.Z - b.Position.Z) < (a.Size.Z + b.Size.Z) / 2
end
local out = {}
-- CONTROL 1: a road part must plan-overlap itself.
local ctlSelf = (#roads > 0 and planOverlap(roads[1], roads[1])) and 1 or 0
table.insert(out, ("CONTROL planOverlap-self=%d (want 1)"):format(ctlSelf))
-- CLEARANCE over the deck.
local worst, worstAt, nOver = 1e9, "none", 0
for _, cp in ipairs(cross) do
for _, rd in ipairs(roads) do
if planOverlap(cp, rd) then
nOver += 1
-- ramp underside minus road topside
local gap = (cp.Position.Y - cp.Size.Y / 2) - (rd.Position.Y + rd.Size.Y / 2)
if gap < worst then
worst, worstAt = gap, cp.Name .. " over " .. rd.Name
end
end
end
end
if nOver == 0 then
table.insert(out, "CROSSING: 0 road parts under any Cross part -- ramp does NOT span the deck")
else
table.insert(out, ("CROSSING: %d overlaps | worst vertical gap=%.1f at %s"):format(nOver, worst, worstAt))
end
-- LANDING: last descent part of each ramp vs the road under it.
local function tailOf(prefix)
local best, bestIdx = nil, -1
for _, p in ipairs(descent) do
if p.Name:sub(1, #prefix) == prefix then
local i = tonumber(p.Name:match("_(%d+)$")) or 0
if i > bestIdx then
best, bestIdx = p, i
end
end
end
return best
end
for _, pre in ipairs({ "PAEntryRampNear", "PAExitRampNear" }) do
local t = tailOf(pre)
if not t then
table.insert(out, pre .. ": no tail part")
else
local bestGap, bestNm = 1e9, "none"
for _, rd in ipairs(roads) do
if planOverlap(t, rd) then
local dy = (t.Position.Y - t.Size.Y / 2) - (rd.Position.Y + rd.Size.Y / 2)
if math.abs(dy) < math.abs(bestGap) then
bestGap, bestNm = dy, rd.Name
end
end
end
if bestNm == "none" then
table.insert(out, ("%s LANDING: tail is over NO road -- lands off the carriageway"):format(pre))
else
table.insert(out, ("%s LANDING: dY=%.1f onto %s"):format(pre, bestGap, bestNm))
end
end
end
table.insert(out, ("counts cross=%d descent=%d roads=%d"):format(#cross, #descent, #roads))
return table.concat(out, "\n")