-- Re-verify after un-pinning index 2, and settle the 4 "bare" samples: -- 525L/526L/549L/550L sit at the ramp MOUTHS (west join=525, east join=551). -- An open parapet at a mouth is correct -- that is the doorway cars drive -- through, and the ramp deck's own walls take over. So check whether ramp deck -- + ramp wall actually cover those samples. If yes: not a hole. If no: a hole. local SS = game:GetService("ServerScriptService") local out = {} local function say(s) table.insert(out, s) end local mod = SS:FindFirstChild("MapBuilder", true) if not mod then return "MapBuilder NOT FOUND" end local fresh = mod:Clone() fresh.Name = "MB_fresh_" .. tostring(math.random(1e6)) fresh.Parent = SS local ok, MB = pcall(require, fresh) if not ok then fresh:Destroy() return "require FAILED: " .. tostring(MB) end local ok2, err = pcall(function() MB.build() end) fresh:Destroy() if not ok2 then return "build ERROR: " .. tostring(err) end say("build OK") local map = workspace:FindFirstChild("Map") local parts = 0 for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then parts += 1 end end say(("parts=%d"):format(parts)) local deck, bars, slipAll = {}, {}, {} for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then local k = d.Name:match("^Road_(%d+)$") or d.Name:match("^Deck_(%d+)$") if k then deck[tonumber(k)] = d end if d.Name == "Barrier" or d.Name == "EdgeRail" then table.insert(bars, d) end if d.Name:match("^PA[EW][ae]stSlip") then table.insert(slipAll, d) end end end local UP = Vector3.new(0, 1, 0) local function flat(v) return Vector3.new(v.X, 0, v.Z) end local function nearest(list, p, ytol) local best = math.huge for _, b in ipairs(list) do if math.abs(b.Position.Y - p.Y) < (ytol or 14) then local dd = (flat(b.Position) - flat(p)).Magnitude if dd < best then best = dd end end end return best end say("--- edge audit 520..555 (L side) ---") local realHoles = {} for i = 520, 555 do local d = deck[i] if d then local right = d.CFrame.LookVector:Cross(UP).Unit local edge = d.Position - right * (d.Size.X / 2 + 2) local bd = nearest(bars, edge) local sd = nearest(slipAll, edge, 20) local covered = bd < 12 or sd < 30 if not covered then table.insert(realHoles, i) end if bd >= 12 then say((" %d: barrier=%.1f slipStruct=%.1f -> %s"):format( i, bd, sd, covered and "OK (ramp mouth)" or "HOLE")) end end end say(("REAL holes: %d %s"):format(#realHoles, #realHoles > 0 and table.concat(realHoles, ",") or "(none)")) say("--- smoothness ---") for _, s in ipairs({ "PAWestSlip", "PAEastSlip" }) do local segs = {} for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then local k = d.Name:match("^" .. s .. "_Deck_(%d+)$") if k then table.insert(segs, { i = tonumber(k), p = d.Position, cf = d.CFrame }) end end end table.sort(segs, function(a, b) return a.i < b.i end) local total, worst, worstAt, over = 0, 0, -1, 0 for j = 2, #segs do local a, b = segs[j - 1].cf.LookVector, segs[j].cf.LookVector local dth = math.deg(math.acos(math.clamp(a:Dot(b), -1, 1))) total += dth if dth > worst then worst = dth; worstAt = segs[j].i end if dth > 5 then over += 1 end end local topY, level = segs[1].p.Y, 0 for _, sg in ipairs(segs) do if math.abs(sg.p.Y - topY) < 0.5 then level += 1 else break end end say(("%s: total=%.1fdeg worst=%.1f@%d over5=%d level=%d"):format( s, total, worst, worstAt, over, level)) say((" start=(%.0f,%.0f,%.0f) end=(%.0f,%.0f,%.0f)"):format( segs[1].p.X, segs[1].p.Y, segs[1].p.Z, segs[#segs].p.X, segs[#segs].p.Y, segs[#segs].p.Z)) end local aux = 0 for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") and d.Name:match("^AuxLane_%d+$") then aux += 1 end end say(("AuxLane total=%d (want 30)"):format(aux)) return table.concat(out, "\n")