Root cause: Windows OpenSSH kills the whole process tree when the SSH
session exits, so rojo started over SSH died seconds later. Proven:
1 proc inside the session, 0 from a fresh session.
Guard now calls 'schtasks /Run /TN RojoTWR' instead of Start-Process.
Verified unattended: killed rojo, scheduler restored it (Last Result: 0).
MapBuilder.luau
- Suppress the aux lane across samples 525-550 (AUX_SUPPRESS_FROM/TO),
honoring the user's hand deletion in Studio so a rebuild no longer
regenerates it.
- Smoothstep the width ramp over AUX_BLEND=5 samples on each side. A hard
cut produced a 26-stud lateral fence jog; the blend removes it.
- DO NOT remove this suppression. Re-enabling it resurrects geometry the
user deleted by hand.
rokit.toml
- rojo 7.5.1 -> 7.7.0 to match the auto-updating Studio plugin.
Server older than plugin fails the handshake with
"attempt to index number with 'protocolVersion'".
tools/
- 34 read-only probe/verify/capture scripts used to measure the datamodel
instead of reasoning from source.
Verified-good baseline at this commit:
total parts 16788
PAWestSlip 60 segs, 34.4 deg total bend, worst 1.4, 0 kinks >5
PAEastSlip 60 segs, 30.7 deg total bend, worst 1.3, 0 kinks >5
AuxLane parts 30 (samples 525-550 deliberately absent)
barrier coverage 823 samples, 0 unguarded
fence jogs >10st 0
Three iterations of the Daikoku PA ramps never read as a real
interchange. Measured why, rather than tuning further:
* the entry and exit decks INTERSECTED -- 2547 sample pairs within
30 studs horizontally at <12 studs dY, worst case 0.5 studs apart
at dY=0.0. On screen that is the bowtie tangle of white rails.
* both real Daikoku ramps turn the SAME way (clockwise; the guide
video says "right, right"). This build mirrored them into each
other.
* the real arc wraps OUTSIDE the lot and forms its north/east
boundary. This build cut across the apron interior.
Gated behind BUILD_PA_RAMPS=false rather than deleted -- the radius
was already correct (470 studs vs an OSM-measured mean of 469) and
the merge lands tangent at 0.1-0.2 deg divergence. Both worth keeping.
Also removed two leftovers that would have outlived the ramps:
* rampOpen punched holes in the mainline's outer parapet, railing
and kill wall for ramps that no longer exist -- a barrier gap with
a drop behind it. Sealed via RAMP_EDGE_OPENINGS=false. Verified:
Barrier/EdgeRail/KillWall = 1646 each = 823 samples x 2 edges,
0 road samples without a guard within 90 studs.
* gore zebra hatching painted 1024 bars + 64 boundary lines marking
a junction that is not there. Sealed via RAMP_GORE_MARKINGS=false.
Verified after a cache-busting fresh rebuild (Studio's require() cache
otherwise serves the previous map and reports a false pass):
parts 22628 -> 15988
all ramp part classes = 0
Road = 823 (unchanged), spawn pad + PASpawn intact
clip probe TRUSTWORTHY (control +11/-0), CLIPPING=0
Research and rebuild spec kept for when this is revisited:
reference/ramps/BUILD_SPEC.md, INDEX.md (10 CC-licensed Commons
photos), docs/daikoku-reference-spec.md (OSM circle fits).
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.
screen_capture DOES work via the bridge (capture_id='ScreenCapture_1');
the prior assumption that the Studio viewport couldn't be captured from
this box was wrong. capture_shots.py sets the Edit camera per shot and
pulls a jpg for each angle.
rebuild_cachebust.luau documents the require() cache trap: pushing new
.Source does not invalidate the per-instance module cache, so a rebuild
silently runs the OLD code and the diagnostic reports already-fixed
failures. Swapping in Clone()s at the same paths forces a fresh compile.
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.
The PA was a placeholder: 9 painted stripes and 4 lights on a slab.
Rebuilt it against sourced figures rather than recollection.
Sources:
* OpenStreetMap way 59608205 (大黒ふ頭パーキングエリア) -- the apron is
181 m x 174 m / 1.6 ha, i.e. essentially SQUARE, not circular.
* ja.wikipedia 大黒パーキングエリア -- 首都高速で最大のPA, opened
1989-09-27. Capacity 小型 341 + 大型 59 + 身障者用 4 = 404, now
reproduced EXACTLY (11 rows x 31, 20/20/19, 1 row x 4).
* 本館 on the west side, ベイサイドテラス二番館 on the north, per the
same article. EV rapid charger (first on a Japanese expressway,
2008-10-10) and the 段差 bumps retrofitted to deter lowered cars.
Stall dimensions (小型 2.5x5.0 m, 大型 3.3x12 m, 6 m aisles) are
conventional JP parking-design values and are commented as NOT
primary-sourced, unlike the 全標協 road markings. Building footprints
are art-directed to the aerial and flagged as such.
tools/verify_daikoku_pa.luau asserts capacity, containment, block
separation and building placement in-engine: 20 passed, 0 failed.
Two bugs found and fixed by that harness:
* The hand-placed 小型 Z origin overlapped the 大型 bays by 42 studs.
The origin is now DERIVED from the 二番館 frontage; clearance is
61.4 studs. The first version of the overlap test compared
consecutive head lines (always 0 for back-to-back rows), which was
meaningless and hid this.
* push_mapbuilder.py lost a byte whenever a chunk began with a
newline -- Lua long-bracket literals swallow a newline directly
after the opening bracket (assembled=65158 vs 65159). It now emits
a deliberate leading newline; the push verifies match=true.
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.