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_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")