--[[ diag_bootcheck.luau -- decide facing using the BOOT/SPOILER cue, which is directly interpretable, and verify it survives the build. Findings so far: * gtr_r34 template: wheels -10.27, hood -6.22, boot +6.64 -> all three cues AGREE, nose at -Z. So wheel labels are NOT swapped. * bodywork "asym" gave gtr_r34 -0.37 while rx7_fc/silv_s15 were positive, yet all three have boot at +Z. asym is therefore a poor proxy (it is dominated by whichever big slab a given shell happens to have) and its verdicts must be discarded. The boot/spoiler is unambiguous: it belongs at the TAIL. On a correctly faced car (chassis forward = -Z) the boot must land at POSITIVE body-local Z. Measure that on the BUILT car, per shell, and compare to the template. Shells with no named boot get a fallback: the tail is the end furthest from the front wheels, per that shell's own wheel cue. ]] local ServerScriptService = game:GetService("ServerScriptService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local out = {} local function log(...) local parts = {} for i = 1, select("#", ...) do parts[#parts + 1] = tostring((select(i, ...))) end table.insert(out, table.concat(parts, " ")) end local Shared = ReplicatedStorage:FindFirstChild("Shared") local Cars = require(Shared.Cars) local Chassis = require(Shared.Chassis) local orig = ServerScriptService:FindFirstChild("Server", true):FindFirstChild("CarManager") local cm = orig:Clone() cm.Parent = orig.Parent local CarManager = require(cm) local TAIL = { boot = true, spoiler = true, trunk = true, taillight = true, exhaust = true, diffuser = true } local NOSE = { hood = true, windshield = true, bonnet = true, grille = true, headlight = true, splitter = true } local function cueZ(root: Instance, frame: CFrame) local inv = frame:Inverse() local tS, tN, nS, nN = 0, 0, 0, 0 for _, p in ipairs(root:GetDescendants()) do if p:IsA("BasePart") then local nm = p.Name:lower() local z = (inv * p.Position).Z if TAIL[nm] then tS, tN = tS + z, tN + 1 elseif NOSE[nm] then nS, nN = nS + z, nN + 1 end end end return (tN > 0 and tS / tN or nil), (nN > 0 and nS / nN or nil), tN, nN end log("chassis forward = -Z, so TAIL parts must land at POSITIVE body-local Z.") log("") log(string.format("%-14s %22s %30s", "car", "TEMPLATE (tail/nose)", "BUILT (tail/nose) verdict")) log(string.rep("-", 74)) for _, t in ipairs(ReplicatedStorage.CarModels:GetChildren()) do local id = t.Name local tT, tNz, tCount, nCount = cueZ(t, t:GetPivot()) local bT, bN = nil, nil local car = Cars.Get(id) if car then local m = CarManager._buildForDiag(car, Chassis.tuningFor(car)) m.Parent = workspace m:PivotTo(CFrame.new(0, 5010, 0)) for _ = 1, 3 do RunService.Heartbeat:Wait() end local sh = m:FindFirstChild("Shell") if sh then bT, bN = cueZ(sh, m.PrimaryPart.CFrame) end m:Destroy() end local verdict if bT then verdict = bT > 0 and "CORRECT" or "*** BACKWARDS ***" elseif bN then verdict = bN < 0 and "CORRECT" or "*** BACKWARDS ***" else verdict = "no named cue - cannot judge" end log( string.format( "%-14s tail %8s nose %7s tail %8s nose %7s %s", id, tT and string.format("%+.2f", tT) or "n/a", tNz and string.format("%+.2f", tNz) or "n/a", bT and string.format("%+.2f", bT) or "n/a", bN and string.format("%+.2f", bN) or "n/a", verdict ) ) end cm:Destroy() return table.concat(out, "\n")