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).
This commit is contained in:
2026-08-03 21:15:25 -04:00
parent 1d23c187ad
commit c297b20aed
34 changed files with 2206 additions and 46 deletions
+146
View File
@@ -0,0 +1,146 @@
-- CLIP PROBE v3 -- INVERTED SCOPE.
--
-- v2 tested drivable parts against a HARDCODED WHITELIST of 16 building
-- names (Building, TokyoTower, GinzaBlock, ...). It reported CLIPPING=0 with
-- a passing control, and I reported that as fact. The user can see ramps
-- going through buildings, so the zero was false.
--
-- The bug is the whitelist: any obstacle whose name isn't one of those 16 is
-- invisible to the test. The PA structures (shops, kiosks, canopies) are the
-- prime suspect -- they sit exactly where the ramp ends land.
--
-- v3 inverts the scope: an obstacle is ANY part that is not drivable and not
-- infrastructure (pier/rail/sign/ground). No name list to go stale.
-- It also reports offenders GROUPED BY OBSTACLE NAME, so the answer names
-- the thing being speared instead of just counting.
local ws = game:GetService("Workspace")
local map = ws:FindFirstChild("Map")
if not map then
return "NO MAP"
end
local function isDrivable(n)
return n:match("^Road_")
or n:find("Ramp")
or n == "PAFloor"
or n:match("^Apron")
or n:match("^Slip")
or n:match("^Merge")
end
-- things that are ALLOWED to intersect a road (structure, decor, markings)
local function isInfra(n)
return n:find("Pier")
or n:find("Pillar")
or n:find("Column")
or n:find("Support")
or n:find("Beam")
or n:find("Rail")
or n:find("Guard")
or n:find("Barrier")
or n:find("Sign")
or n:find("Light")
or n:find("Lamp")
or n:find("Line")
or n:find("Mark")
or n:find("Stripe")
or n:find("Deck")
or n:find("Water")
or n == "Ground"
or n:find("Grounds")
or n:find("Median")
or n:find("Curb")
or n:find("Wall")
end
local drive, obst = {}, {}
for _, d in ipairs(map:GetDescendants()) do
if d:IsA("BasePart") then
local n = d.Name
if isDrivable(n) then
table.insert(drive, d)
elseif not isInfra(n) then
table.insert(obst, d)
end
end
end
if #obst == 0 or #drive == 0 then
return ("SCOPE FAIL drive=%d obst=%d"):format(#drive, #obst)
end
local op = OverlapParams.new()
op.FilterType = Enum.RaycastFilterType.Include
op.FilterDescendantsInstances = obst
op.MaxParts = 12
-- POSITIVE CONTROL: probe dead-centre of a known obstacle must report a hit.
local target = obst[math.floor(#obst / 2)]
local ctrl = ws:GetPartBoundsInBox(CFrame.new(target.Position), Vector3.new(4, 4, 4), op)
local controlOK = #ctrl > 0
-- SECOND CONTROL: a box far out in empty sky must report ZERO. Guards the
-- opposite failure -- a filter so broad everything "hits".
local negCtrl = ws:GetPartBoundsInBox(CFrame.new(0, 40000, 0), Vector3.new(8, 8, 8), op)
local negOK = #negCtrl == 0
local hits = 0
local byObst, byRamp = {}, {}
local samples = {}
for _, p in ipairs(drive) do
local probe = p.Size - Vector3.new(1.5, 1.5, 1.5)
if probe.X > 0.5 and probe.Y > 0.5 and probe.Z > 0.5 then
local h = ws:GetPartBoundsInBox(p.CFrame, probe, op)
if #h > 0 then
hits += 1
local on = h[1].Name
byObst[on] = (byObst[on] or 0) + 1
local rn = p.Name:gsub("_%d+$", "")
byRamp[rn] = (byRamp[rn] or 0) + 1
if #samples < 10 then
table.insert(
samples,
("%s@%.0f,%.0f,%.0f IN %s"):format(p.Name, p.Position.X, p.Position.Y, p.Position.Z, on)
)
end
end
end
end
local out = {}
table.insert(
out,
("CONTROL+=%s(%d) CONTROL-=%s(%d) -> probe %s"):format(
controlOK and "PASS" or "FAIL",
#ctrl,
negOK and "PASS" or "FAIL",
#negCtrl,
(controlOK and negOK) and "TRUSTWORTHY" or "BROKEN-IGNORE-RESULTS"
)
)
table.insert(out, ("drivable=%d obstacles=%d CLIPPING=%d"):format(#drive, #obst, hits))
local function dump(t, label)
local l = {}
for k, v in pairs(t) do
table.insert(l, ("%s=%d"):format(k, v))
end
table.sort(l, function(a, b)
return a > b
end)
local keep = {}
for i = 1, math.min(#l, 12) do
table.insert(keep, l[i])
end
table.insert(out, label .. ": " .. table.concat(keep, " "))
end
if hits > 0 then
dump(byObst, "speared obstacles")
dump(byRamp, "offending road groups")
for _, s in ipairs(samples) do
table.insert(out, " " .. s)
end
end
return table.concat(out, "\n")