--[[ verify_convention.luau -- prove the forward convention is now consistent. Deliberately NOT measuring anything derived from a constant. The previous harness read Wheel_* positions, which come straight from Chassis.WHEELBASE_HALF (5.9) -- identical for every car whether or not any fix applied, so it passed vacuously. Here every assertion is a RELATIONSHIP that genuinely differs between the broken and fixed builds: 1. The steering servo must sit on the axle that LEADS under throttle. Broken build: servos on the trailing axle (shopping-cart caster). 2. The shell nose must point the same way the seat drives. Broken build: 180 degrees opposed. 3. DRIVE_SIGN must spin the wheels toward the direction of travel. Builds each car via the real path (Chassis.tuningFor + _buildForDiag) in the Edit datamodel, where require() is fresh. ]] local SSS = game:GetService("ServerScriptService") local RS = game:GetService("ReplicatedStorage") 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 function findModule(name: string): ModuleScript? for _, root in ipairs({ SSS, RS }) do local hit = root:FindFirstChild(name, true) if hit and hit:IsA("ModuleScript") then return hit end end return nil end local cmMod = findModule("CarManager") local carsMod = findModule("Cars") local chassisMod = findModule("Chassis") if not (cmMod and carsMod and chassisMod) then return "FATAL: missing module(s)" end local CarManager = require(cmMod) local Cars = require(carsMod) local Chassis = require(chassisMod) if typeof(CarManager._buildForDiag) ~= "function" then return "FATAL: _buildForDiag absent -- stale CarManager, refusing to report" end log(string.format("Chassis.DRIVE_SIGN = %s", tostring(Chassis.DRIVE_SIGN))) log("") local carList = Cars.List or Cars.All if typeof(carList) ~= "table" or #carList == 0 then return "FATAL: empty car list" end log(string.format("%-11s %-22s %-24s %s", "car", "steered axle", "shell nose vs drive", "verdict")) log(string.rep("-", 78)) local tested, failed = 0, 0 for _, car in ipairs(carList) do if typeof(car) ~= "table" or not car.Id then continue end local tuning = Chassis.tuningFor(car) local ok, model = pcall(CarManager._buildForDiag, car, tuning) if not ok or typeof(model) ~= "Instance" then log(string.format("%-11s BUILD FAILED: %s", car.Id, tostring(model))) failed += 1 continue end local body = model:FindFirstChild("Body") local seat for _, d in ipairs(model:GetDescendants()) do if d:IsA("VehicleSeat") then seat = d break end end if not (body and body:IsA("BasePart") and seat) then log(string.format("%-11s NO BODY/SEAT", car.Id)) failed += 1 model:Destroy() continue end tested += 1 local inv = body.CFrame:Inverse() -- Direction of travel under positive throttle, in body-local space. local driveZ = inv:VectorToObjectSpace(seat.CFrame.LookVector).Z local drivePos = driveZ > 0 -- (1) Which axle carries the steering servos? local servoZ, servoN = 0, 0 for _, d in ipairs(model:GetDescendants()) do if d:IsA("HingeConstraint") and d.ActuatorType == Enum.ActuatorType.Servo then local host = d.Parent if host and host:IsA("BasePart") then servoZ += (inv * host.CFrame).Z servoN += 1 end end end local steerLeads, steerTxt = false, "no servos" if servoN > 0 then local sm = servoZ / servoN steerLeads = (drivePos and sm > 0) or (not drivePos and sm < 0) steerTxt = string.format("z=%+.2f %s", sm, steerLeads and "LEADS" or "TRAILS") end -- (2) Shell nose vs direction of travel. local shell for _, c in ipairs(model:GetChildren()) do if c:IsA("Model") then shell = c break end end local shellOk, shellTxt = true, "no shell" if shell then local shellLook = shell:GetPivot().LookVector local seatLook = seat.CFrame.LookVector local a = Vector3.new(shellLook.X, 0, shellLook.Z) local b = Vector3.new(seatLook.X, 0, seatLook.Z) if a.Magnitude > 1e-4 and b.Magnitude > 1e-4 then local deg = math.deg(math.acos(math.clamp(a.Unit:Dot(b.Unit), -1, 1))) shellOk = deg < 30 shellTxt = string.format("%.1f deg %s", deg, shellOk and "OK" or "FLIPPED") end end local pass = (servoN == 0 or steerLeads) and shellOk if not pass then failed += 1 end log(string.format("%-11s %-22s %-24s %s", car.Id, steerTxt, shellTxt, pass and "PASS" or "FAIL")) model:Destroy() end log("") if tested == 0 then log(">>> NOTHING TESTED -- this is a FAILURE, not a pass.") elseif failed > 0 then log(string.format(">>> %d/%d FAILED", failed, tested)) else log(string.format(">>> ALL %d CARS PASS: steered axle leads, shell faces travel", tested)) end return table.concat(out, "\n")