Files
jesse 6e50f9718d
CI / quality (push) Failing after 1m9s
Aux-lane suppression + PA geometry fixes; probe/verify tooling
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
2026-08-06 08:27:47 -04:00

56 lines
2.0 KiB
Luau

local HttpService = game:GetService("HttpService")
local RS = game:GetService("ReplicatedStorage")
local Circuit = require(RS:WaitForChild("Shared"):WaitForChild("Circuit"))
local map = workspace:FindFirstChild("Map")
if not map then return "no Map" end
-- Aggregate PA parts EXCLUDING the slips we just built, so we can see the lot.
local agg = { xMin = math.huge, xMax = -math.huge, zMin = math.huge, zMax = -math.huge }
local names = {}
local biggest, biggestArea = nil, 0
for _, d in ipairs(map:GetDescendants()) do
if d:IsA("BasePart") and d.Name:sub(1, 2) == "PA" and not d.Name:find("Slip") then
names[d.Name] = (names[d.Name] or 0) + 1
agg.xMin = math.min(agg.xMin, d.Position.X - d.Size.X / 2)
agg.xMax = math.max(agg.xMax, d.Position.X + d.Size.X / 2)
agg.zMin = math.min(agg.zMin, d.Position.Z - d.Size.Z / 2)
agg.zMax = math.max(agg.zMax, d.Position.Z + d.Size.Z / 2)
local area = d.Size.X * d.Size.Z
if area > biggestArea then
biggestArea = area
biggest = ("%s size=(%d,%d,%d) pos=(%d,%d,%d) yTop=%.1f"):format(
d.Name, d.Size.X, d.Size.Y, d.Size.Z,
d.Position.X, d.Position.Y, d.Position.Z,
d.Position.Y + d.Size.Y / 2)
end
end
end
local nameList = {}
for n, c in pairs(names) do
table.insert(nameList, n .. "x" .. c)
end
table.sort(nameList)
-- cap the list so the payload can't truncate
local head = {}
for i = 1, math.min(#nameList, 40) do head[i] = nameList[i] end
local s = Circuit.samples
local function probe(i)
local a, b = s[i], s[i + 1]
local d = (b.pos - a.pos)
local fwd = Vector3.new(d.X, 0, d.Z).Unit
local right = fwd:Cross(Vector3.yAxis)
return ("s%d pos=(%d,%d) fwd=(%.2f,%.2f) right=(%.2f,%.2f)"):format(
i, a.pos.X, a.pos.Z, fwd.X, fwd.Z, right.X, right.Z)
end
return HttpService:JSONEncode({
pa_nonslip_bounds = { x = { math.floor(agg.xMin), math.floor(agg.xMax) }, z = { math.floor(agg.zMin), math.floor(agg.zMax) } },
biggest_pa_part = biggest,
distinct_pa_names = #nameList,
sample_names = head,
pa_center = tostring(Circuit.PA_CENTER),
joins = { probe(525), probe(537), probe(551), probe(539) },
})