Rework the PA junction to match the reference drawing: yellow = PA -> highway
(entry), red = highway -> PA (exit). Entry and exit swap sides (entry now
EAST, exit WEST) and both trunks hug the PA perimeter instead of running
concentric spirals.
The simplification: both carriageways sit at the same deck level, adjacent,
so the median opening IS the far-side access path. The under-deck crossing
and merge runs are deleted outright -- 8 runs collapse to 4, and the
girder-soffit ceiling logic that constrained the crossing goes with them.
Part count 24,210 -> 21,691.
The median opening is now load-bearing rather than cosmetic (it is the only
route from the far carriageway to the ramps), so it widens from 6 to 9
samples per junction.
Orientation is a single flip-able constant (ORIENT) so a mirrored result is
a one-line correction, not a rewrite.
Measured on the built map (not asserted):
- 600 entry + 600 exit ramp parts
- max grade 8.00% / 8.27%, under the 9% limit
- 0 collisions with piers/masts/girders (558 structural parts)
- segment continuity <= 2.5 studs; trunk->merge handoff <= 1.7 studs
- merge lands at dY 0.0 (exact deck level), 33 studs lateral
- median open at junctions: 0 parts vs. control ~7 on plain mainline
Two traps worth recording, both caught by controls:
1. Studio's require() cache silently rebuilt STALE code. The first "passing"
build reported 17,575 parts and zero ramps, and the map contained
PAOffRamp/PAOnRamp parts whose names exist nowhere in the current source.
Every measurement taken before this was describing an old map. Added
tools/rebuild_fresh.luau, which clones the module to bust the cache; use
it rather than requiring MapBuilder directly.
2. A reported "median never opens" bug was a bad probe, not a defect. It
counted `Barrier` (the outer edge parapet, which must NEVER open) instead
of `Median_<i>`. Re-run against the right name: control 7, junctions 0.
Both were only visible because the probes carry controls -- a 0-hit result
with no control is vacuous. The verification harnesses are kept in tools/
with their controls built in.
Four fidelity fixes, all verified in a live Studio datamodel (not just built):
1. Wire up the dead `bridge` flag. Circuit.luau marks 474 samples as bridge
spans but nothing ever read the field, so every elevated metre rendered as
the same slab on square columns. Flagged spans now get a steel box girder
(鋼箱桁橋) with stiffener ribs under the deck, carried on a transverse pier
cap and round columns at a wider pitch than the viaduct pillars.
2. Ginza 跨道橋. The Ginza section sits below street level in the filled-in
楓川・築地川 river beds and the surviving city bridges cross over it, their
piers landing in the median. Adds the crossing decks, parapets and centre
piers -- which is the physical reason lane changes are banned there, not
just a paint choice.
3. Junction speed plates. 江戸橋JCT内 / 浜崎橋JCT内 / 京橋JCT-旧白魚橋乗継所 are
posted 40 km/h, not the 50 km/h mainline limit; plates repeat more often
through the short restricted stretches.
4. Shiodome JCT -> Hamazakibashi JCT widened to 3+3 lanes via widthAt(), with
a taper (max ~1.7 studs/sample) instead of a step. Every fixed-width
consumer -- deck, median, parapets, lane marks, signage offsets, skyline
setback, finish line -- now reads widthAt() so nothing floats or clips.
Verified headlessly (tools/verify_c1_fixes*.luau):
girders 488 / 474 flagged samples, pier caps 85, columns 80
Ginza overpasses 7, piers 7, lateral offset from centreline 0.000 studs
speed plates 40km/h x7, 50km/h x8
deck width Shiodome 81.5 vs Kasumigaseki 60.0
seam lip max 0.0006, road-surface raycast step max 0.260, 0 deck holes
Two earlier "failures" were bad tests, not bad geometry, and the fixed
harnesses document the traps: deck parts are pitched by CFrame.lookAt so
Position.Y+Size.Y/2 is not the surface height (and LookVector is -Z, so the
end faces are easy to swap), and a seam raycast must filter to the Expressway
folder or it hits TunnelCeiling/MedianFence and reports a phantom 19-stud step.