CI / quality (push) Failing after 1m9s
MapBuilder.luau
- Suppress the aux lane across samples 525-550 (AUX_SUPPRESS_FROM/TO),
honoring the user's hand deletion in Studio so a rebuild no longer
regenerates it.
- Smoothstep the width ramp over AUX_BLEND=5 samples on each side. A hard
cut produced a 26-stud lateral fence jog; the blend removes it.
- DO NOT remove this suppression. Re-enabling it resurrects geometry the
user deleted by hand.
rokit.toml
- rojo 7.5.1 -> 7.7.0 to match the auto-updating Studio plugin.
Server older than plugin fails the handshake with
"attempt to index number with 'protocolVersion'".
tools/
- 34 read-only probe/verify/capture scripts used to measure the datamodel
instead of reasoning from source.
Verified-good baseline at this commit:
total parts 16788
PAWestSlip 60 segs, 34.4 deg total bend, worst 1.4, 0 kinks >5
PAEastSlip 60 segs, 30.7 deg total bend, worst 1.3, 0 kinks >5
AuxLane parts 30 (samples 525-550 deliberately absent)
barrier coverage 823 samples, 0 unguarded
fence jogs >10st 0
108 lines
4.0 KiB
Luau
108 lines
4.0 KiB
Luau
-- Slip walls measured CLEAN (0 missing, 0 deviation, 0.00 lateral step), so
|
|
-- neither marked defect is on the ramp decks themselves. Prime suspect is the
|
|
-- suppression boundary I introduced: across 527..548 the parapet is forced back
|
|
-- to the mainline edge, while 510..526 and 549..565 still carry it relocated
|
|
-- OUT on the aux lane's outer edge (~26 studs further). At samples 527 and 549
|
|
-- that is a ~26-stud lateral JOG -- a barrier that visibly sticks out and ends
|
|
-- in a stub. And the gore between mainline barrier and ramp wall start may be
|
|
-- open -- the missing-barrier oval.
|
|
--
|
|
-- Measure signed lateral offset of every Barrier from the mainline centreline,
|
|
-- walk 505..570, and report steps + gaps.
|
|
local out = {}
|
|
local function say(s) table.insert(out, s) end
|
|
|
|
local map = workspace:FindFirstChild("Map")
|
|
if not map then return "Map MISSING" end
|
|
local UP = Vector3.new(0, 1, 0)
|
|
local function flat(v) return Vector3.new(v.X, 0, v.Z) end
|
|
|
|
local deck, aux = {}, {}
|
|
local bars = {}
|
|
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
|
|
local a = d.Name:match("^AuxLane_(%d+)$")
|
|
if a then aux[tonumber(a)] = d end
|
|
if d.Name == "Barrier" then table.insert(bars, d) end
|
|
end
|
|
end
|
|
|
|
-- For each mainline sample, find the barrier nearest to that sample's plane on
|
|
-- the LEFT side, and report its lateral offset from the centreline.
|
|
say("sample | auxW | barrier lateral offset from centreline | step")
|
|
local prevLat = nil
|
|
local jogs, gaps = {}, {}
|
|
for i = 505, 570 do
|
|
local d = deck[i]
|
|
if d then
|
|
local right = d.CFrame.LookVector:Cross(UP).Unit
|
|
local c = d.Position
|
|
-- gather barriers within half a sample spacing along the road axis
|
|
local best, bestLat = math.huge, nil
|
|
for _, b in ipairs(bars) do
|
|
if math.abs(b.Position.Y - c.Y) < 14 then
|
|
local rel = b.Position - c
|
|
local along = math.abs(rel:Dot(d.CFrame.LookVector))
|
|
local lat = rel:Dot(right)
|
|
if along < 22 and lat < 0 then -- LEFT side only
|
|
if along < best then best = along; bestLat = lat end
|
|
end
|
|
end
|
|
end
|
|
local auxW = aux[i] and aux[i].Size.X or 0
|
|
if bestLat then
|
|
local step = prevLat and math.abs(math.abs(bestLat) - math.abs(prevLat)) or 0
|
|
if step > 6 then
|
|
table.insert(jogs, ("%d(step %.1f)"):format(i, step))
|
|
end
|
|
if i % 4 == 0 or step > 6 then
|
|
say((" %d | aux=%.0f | lat=%.1f | step=%.1f%s"):format(
|
|
i, auxW, bestLat, step, step > 6 and " <<< JOG" or ""))
|
|
end
|
|
prevLat = bestLat
|
|
else
|
|
table.insert(gaps, i)
|
|
say((" %d | aux=%.0f | NO BARRIER FOUND on left <<< GAP"):format(i, auxW))
|
|
prevLat = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
say(("JOGS (lateral step >6): %d %s"):format(#jogs, #jogs > 0 and table.concat(jogs, " ") or "(none)"))
|
|
say(("GAPS (no left barrier): %d %s"):format(#gaps, #gaps > 0 and table.concat(gaps, ",") or "(none)"))
|
|
|
|
-- Gore check: distance from each slip's FIRST wall to the nearest mainline
|
|
-- barrier. A large value means an open mouth corner -- the missing-barrier oval.
|
|
say("--- gore / mouth junction ---")
|
|
for _, s in ipairs({ "PAWestSlip", "PAEastSlip" }) do
|
|
local first, firstK = nil, math.huge
|
|
local last, lastK = nil, -1
|
|
for _, d in ipairs(map:GetDescendants()) do
|
|
if d:IsA("BasePart") then
|
|
local wk = d.Name:match("^" .. s .. "_Wall_(%d+)$")
|
|
if wk then
|
|
local k = tonumber(wk)
|
|
if k < firstK then firstK = k; first = d end
|
|
if k > lastK then lastK = k; last = d end
|
|
end
|
|
end
|
|
end
|
|
if first then
|
|
local bd = math.huge
|
|
for _, b in ipairs(bars) do
|
|
if math.abs(b.Position.Y - first.Position.Y) < 16 then
|
|
local dd = (flat(b.Position) - flat(first.Position)).Magnitude
|
|
if dd < bd then bd = dd end
|
|
end
|
|
end
|
|
say(("%s: first wall seg %d at (%.0f,%.0f,%.0f) -> nearest mainline barrier %.1f"):format(
|
|
s, firstK, first.Position.X, first.Position.Y, first.Position.Z, bd))
|
|
say((" last wall seg %d at (%.0f,%.0f,%.0f)"):format(
|
|
lastK, last.Position.X, last.Position.Y, last.Position.Z))
|
|
end
|
|
end
|
|
|
|
return table.concat(out, "\n")
|