Daikoku PA: lift mainline over the apron, rebuild both ramps

The PA ring road and the expressway mainline were both at ground level, so
the ring parapet stood INSIDE the carriageway (measured -10.0 studs of
vertical overlap: a wall in the middle of the road).

Reference photos of the real Daikoku Futo PA show the expressway flying
OVER the parking apron on pillars, with the PA at ground level and ramps
climbing up to meet it. Rebuilt to match:

- mainline lifted 38 studs through the junction, eased in/out (max 5.26%
  grade, within real expressway limits)
- PA ring + apron stay at ground level; legacy PARingPillar props removed
- both on/off ramps regraded over the full rise with smoothstep easing,
  segments overlapped 3 studs so wheels can't catch a seam, plus support
  pillars and edge kerbs where the deck is high

Verified in-engine against built parts (tools/diag_daikoku.luau), not just
source: clearance now +28.0 studs, both ramps continuous (max step 5.62,
no gaps). tools/plot_daikoku.py renders the plan/section for comparison.
This commit is contained in:
2026-08-02 15:56:13 -04:00
parent 8808b919c3
commit c8dabea53a
51 changed files with 6558 additions and 65 deletions
+109
View File
@@ -0,0 +1,109 @@
--[[
diag_shellbuilt.luau -- does the solved yaw actually reach the built car?
diag_shellyaw2 proved the aligner SEES the problem: hatch_junk and hyper_x
are authored nose-toward +Z and solve to yaw ~180, the other three to ~0.
That is exactly the "at least two cars are backwards" the user reports, so
the cue is right and the question is whether the rotation survives to the
built model.
The earlier attempt measured -11.80 for every car -- that is the CHASSIS
wheelbase, i.e. it matched the chassis Wheel_* parts, not the shell's own
Wheels folder. This one scopes the search strictly INSIDE the Shell model
and skips anything named Wheel_* (the chassis convention), so it can only
ever read shell wheels.
]]
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 clone = orig:Clone()
clone.Parent = orig.Parent
local CarManager = require(clone)
local pad = Instance.new("Part")
pad.Size = Vector3.new(400, 8, 400)
pad.Position = Vector3.new(0, 5000, 0)
pad.Anchored = true
pad.Parent = workspace
log("chassis forward = -Z. Shell nose must land at NEGATIVE body-local Z.")
log("")
for _, template in ipairs(ReplicatedStorage.CarModels:GetChildren()) do
local id = template.Name
local car = Cars.Get(id)
if not car then
log(string.format("%-14s <no car def for this shell id>", id))
else
local model = CarManager._buildForDiag(car, Chassis.tuningFor(car))
model.Parent = workspace
model:PivotTo(CFrame.new(0, 5010, 0))
for _ = 1, 5 do
RunService.Heartbeat:Wait()
end
local body = model.PrimaryPart
local shell = model:FindFirstChild("Shell")
if not shell then
log(string.format("%-14s <no Shell child -- using procedural CarBody>", id))
else
local inv = body.CFrame:Inverse()
-- Only look at wheels INSIDE the shell, and never at chassis Wheel_*.
local wf = shell:FindFirstChild("Wheels")
local fSum, fN, rSum, rN = Vector3.zero, 0, Vector3.zero, 0
if wf then
for _, w in ipairs(wf:GetChildren()) do
if w.Name:sub(1, 6) ~= "Wheel_" then
local part = w:IsA("BasePart") and w or w:FindFirstChildWhichIsA("BasePart", true)
if part then
local h = w.Name:sub(1, 1):upper()
local lp = inv * part.Position
if h == "F" then
fSum, fN = fSum + lp, fN + 1
elseif h == "R" then
rSum, rN = rSum + lp, rN + 1
end
end
end
end
end
if fN > 0 and rN > 0 then
local f, r = fSum / fN, rSum / rN
local dz = f.Z - r.Z
log(
string.format(
"%-14s shell wheels: frontZ %+6.2f rearZ %+6.2f dZ %+6.2f -> %s",
id,
f.Z,
r.Z,
dz,
dz < 0 and "CORRECT" or "*** STILL BACKWARDS ***"
)
)
else
log(string.format("%-14s <shell has no usable F/R wheels after build (F=%d R=%d)>", id, fN, rN))
end
end
model:Destroy()
end
end
pad:Destroy()
clone:Destroy()
return table.concat(out, "\n")