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
121 lines
4.2 KiB
Luau
121 lines
4.2 KiB
Luau
-- User's picture marks TWO defects on the slip ramps:
|
|
-- (A) left tall oval -> a stretch of ramp edge with NO barrier at all
|
|
-- (B) right circle -> the OUTER barrier "sticks out" / juts, not smooth
|
|
-- Earlier measurement hinted at (A): PAEastSlip had walls=119 where west had
|
|
-- 120, i.e. one wall segment short. Find the truth for both slips now.
|
|
--
|
|
-- Method:
|
|
-- 1. Index every <slip>_Wall_<k> by k and by side (left/right of centreline).
|
|
-- Missing k on a side = a hole in that parapet.
|
|
-- 2. For each wall, compute SIGNED lateral offset from its own deck segment
|
|
-- centre. Walls are built at +/-(WIDTH/2 - 0.6); any outlier is a jut.
|
|
-- 3. Measure end-to-end gaps between consecutive walls on the same side --
|
|
-- a protruding corner shows as a large lateral step between neighbours.
|
|
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)
|
|
|
|
for _, s in ipairs({ "PAWestSlip", "PAEastSlip" }) do
|
|
local decks, walls = {}, {}
|
|
for _, d in ipairs(map:GetDescendants()) do
|
|
if d:IsA("BasePart") then
|
|
local dk = d.Name:match("^" .. s .. "_Deck_(%d+)$")
|
|
if dk then decks[tonumber(dk)] = d end
|
|
local wk = d.Name:match("^" .. s .. "_Wall_(%d+)$")
|
|
if wk then
|
|
local k = tonumber(wk)
|
|
walls[k] = walls[k] or {}
|
|
table.insert(walls[k], d)
|
|
end
|
|
end
|
|
end
|
|
|
|
local idx = {}
|
|
for k in pairs(decks) do table.insert(idx, k) end
|
|
table.sort(idx)
|
|
if #idx == 0 then say(s .. ": no decks") continue end
|
|
|
|
say(("=== %s: decks=%d (idx %d..%d) ==="):format(s, #idx, idx[1], idx[#idx]))
|
|
|
|
-- (1) missing walls
|
|
local missing, oneSided = {}, {}
|
|
for _, k in ipairs(idx) do
|
|
local w = walls[k]
|
|
if not w then
|
|
table.insert(missing, k)
|
|
elseif #w < 2 then
|
|
table.insert(oneSided, k)
|
|
end
|
|
end
|
|
say((" walls: missing-both=%d %s | only-one-side=%d %s"):format(
|
|
#missing, #missing > 0 and table.concat(missing, ",") or "-",
|
|
#oneSided, #oneSided > 0 and table.concat(oneSided, ",") or "-"))
|
|
|
|
-- (2) signed lateral offset of each wall from its deck centre
|
|
local offs = {}
|
|
local worstOut, worstAt, worstSide = 0, -1, ""
|
|
for _, k in ipairs(idx) do
|
|
local dk = decks[k]
|
|
local w = walls[k]
|
|
if dk and w then
|
|
local right = dk.CFrame.LookVector:Cross(UP).Unit
|
|
for _, wp in ipairs(w) do
|
|
local rel = wp.Position - dk.Position
|
|
local lat = rel:Dot(right)
|
|
table.insert(offs, { k = k, lat = lat, side = lat < 0 and "L" or "R" })
|
|
end
|
|
end
|
|
end
|
|
-- expected magnitude = median |lat|
|
|
local mags = {}
|
|
for _, o in ipairs(offs) do table.insert(mags, math.abs(o.lat)) end
|
|
table.sort(mags)
|
|
local med = mags[math.max(1, math.floor(#mags / 2))] or 0
|
|
say((" median |lateral offset| = %.2f (walls sit this far off centre)"):format(med))
|
|
local juts = {}
|
|
for _, o in ipairs(offs) do
|
|
local dev = math.abs(o.lat) - med
|
|
if dev > 1.5 then
|
|
table.insert(juts, ("%d%s+%.1f"):format(o.k, o.side, dev))
|
|
if dev > worstOut then worstOut = dev; worstAt = o.k; worstSide = o.side end
|
|
end
|
|
end
|
|
say((" walls deviating >1.5 from median: %d %s"):format(#juts,
|
|
#juts > 0 and table.concat(juts, " ") or "(none)"))
|
|
if worstAt > 0 then
|
|
say((" worst jut: seg %d side %s, +%.1f studs outboard"):format(worstAt, worstSide, worstOut))
|
|
end
|
|
|
|
-- (3) lateral step between consecutive walls on the SAME side
|
|
local bySide = { L = {}, R = {} }
|
|
for _, o in ipairs(offs) do table.insert(bySide[o.side], o) end
|
|
for _, sd in ipairs({ "L", "R" }) do
|
|
local a = bySide[sd]
|
|
table.sort(a, function(x, y) return x.k < y.k end)
|
|
local bigStep, stepAt = 0, -1
|
|
for j = 2, #a do
|
|
local st = math.abs(math.abs(a[j].lat) - math.abs(a[j - 1].lat))
|
|
if st > bigStep then bigStep = st; stepAt = a[j].k end
|
|
end
|
|
say((" side %s: n=%d largest lateral step=%.2f at seg %d"):format(sd, #a, bigStep, stepAt))
|
|
end
|
|
|
|
-- world position of any missing/one-sided spot so I can match it to the pic
|
|
for _, k in ipairs(oneSided) do
|
|
local dk = decks[k]
|
|
if dk then
|
|
local w = walls[k][1]
|
|
local right = dk.CFrame.LookVector:Cross(UP).Unit
|
|
local sd = (w.Position - dk.Position):Dot(right) < 0 and "L" or "R"
|
|
say((" >> seg %d has ONLY side %s, at (%.0f,%.0f,%.0f)"):format(
|
|
k, sd, dk.Position.X, dk.Position.Y, dk.Position.Z))
|
|
end
|
|
end
|
|
end
|
|
|
|
return table.concat(out, "\n")
|