--[[ diag_seatdir.luau -- decide, empirically, which way the car DRIVES. The contradiction: CarManager:158 says `isFront = zSign < 0 -- car forward is -Z`, so the front axle is built at local -Z. But the VehicleSeat's LookVector points +Z (measured: seatLook.dot(bodyLook) = 1.00). In Roblox a VehicleSeat applies throttle along its OWN +Z LookVector, so positive throttle drives the car toward +Z -- i.e. toward the axle the code labels REAR. If that holds, every car drives "backwards" and the shell, which is aligned to the chassis convention, renders nose-first into the direction of travel... backwards on screen. This does not guess: it reads the seat's actual Throttle/steer wiring and compares the seat basis against the wheel labels, then reports which axle leads under positive throttle. It also checks whether the steering servo lives on the axle that leads, because a car steering with its TRAILING axle is the classic shopping-cart castering symptom the user reported. ]] 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 for _, model in ipairs(workspace:GetDescendants()) do if not (model:IsA("Model") and model.Name:match("^Car_")) then continue end local body = model:FindFirstChild("Body") local seat = nil 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 continue end log("=== " .. model.Name .. " ===") local inv = body.CFrame:Inverse() -- Seat look expressed in BODY-LOCAL coords: which local axis does the car -- drive along under positive throttle? local seatLookLocal = inv:VectorToObjectSpace(seat.CFrame.LookVector) log( string.format( " seat look in body-local = (%.2f, %.2f, %.2f)", seatLookLocal.X, seatLookLocal.Y, seatLookLocal.Z ) ) local drivesTowardPosZ = seatLookLocal.Z > 0 log(string.format(" => positive throttle drives toward local %sZ", drivesTowardPosZ and "+" or "-")) -- Where are the labelled axles, and which one has the steering servo? local fZ, fN, rZ, rN = 0, 0, 0, 0 local steerAxleZ, steerCount = 0, 0 for _, d in ipairs(model:GetDescendants()) do if d:IsA("BasePart") and d.Name:match("^Wheel_") then local z = (inv * d.CFrame).Z if d.Name:sub(7, 7):upper() == "F" then fZ, fN = fZ + z, fN + 1 else rZ, rN = rZ + z, rN + 1 end end -- servo is parented to the HUB, not the wheel -- find it by name if d:IsA("HingeConstraint") and d.ActuatorType == Enum.ActuatorType.Servo then local host = d.Parent if host and host:IsA("BasePart") then steerAxleZ = steerAxleZ + (inv * host.CFrame).Z steerCount = steerCount + 1 end end end if fN > 0 and rN > 0 then local fm, rm = fZ / fN, rZ / rN log(string.format(" labelled FRONT axle localZ=%.2f | REAR axle localZ=%.2f", fm, rm)) local leadingIsFront = (drivesTowardPosZ and fm > rm) or (not drivesTowardPosZ and fm < rm) log( string.format( " => the axle LEADING under throttle is the one labelled %s", leadingIsFront and "FRONT (correct)" or "REAR (car drives backwards!)" ) ) end if steerCount > 0 then local sm = steerAxleZ / steerCount log(string.format(" steering servos=%d, mean host localZ=%.2f", steerCount, sm)) local steerLeads = (drivesTowardPosZ and sm > 0) or (not drivesTowardPosZ and sm < 0) log( string.format( " => steered axle %s under throttle %s", steerLeads and "LEADS" or "TRAILS", steerLeads and "(normal car)" or "(SHOPPING-CART castering)" ) ) else log(" no steering servos found by name scan") end log("") end if #out == 0 then return "No live cars with a Body + VehicleSeat." end return table.concat(out, "\n")