Real-world numbers gathered from OSM (Overpass), Esri aerial imagery, and
frame-sampled onboard video. Replaces estimation with measurement.
Key findings:
* Loop radii MEASURED via Kasa circle fit on OSM ways: 27.5-204 m,
mean 131 m (469 studs). Two cleanest fits (rms<1.5) are the true
helixes at 147 m (525 studs) and 124 m (441 studs).
* 6 of 8 curved ramps turn CLOCKWISE - matches the video captions
'right, right and you will reach the PA'.
* FIVE deck layers in the interchange (OSM layer 1-5). Current
PA_LIFT=56 models only one; faithful build wants 3+ overhead.
* Real PA footprint 181x174 m (parking) / 203x227 m (rest_area).
Current APRON 210x200 m already matches well - the divergence is
SHAPE (square vs rounded wedge), not extent.
* Scale clarified: PA work uses M=3.571 studs/m, NOT the 4.3 in
c1_georeference.json (different mapping, 366 m median error).
Video reference archived to NAS 004-video-reference/ (364 MB, 4 routes).
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.
Road markings now follow the 全標協 (Japan Road Marking Association) 2012/2018
standard rather than eyeballed values:
- Lane dividers: 8 m painted / 12 m gap on a continuous 20 m cycle carried
across segment boundaries (previously each segment restarted its own dash
phase, so the rhythm broke at every joint).
- Line widths corrected to 0.15 m lane / 0.20 m edge. The 0.45 m width often
quoted for expressways applies only to the boundary against a 変速車線
(accel/decel lane) -- now used at ramps only, where it belongs.
- Yellow SOLID no-lane-change lines through tunnels and tight curves, per the
standard's rule that the boundary goes solid where overtaking is undesirable.
- 導流帯 gore zebra at ramp junctions: 45 cm bars at 1.0 m pitch.
Signage:
- Guide-sign green corrected to the official #005D35; route badges #007F1F.
- Bilingual Japanese + romaji layout (JP above, romaji below).
- Added 規制標識 speed limit plates posted at 50 km/h -- the C1 Inner Circular
limit. (80 km/h is the Bayshore Route; the two are not the same.)
- Added キロポスト distance markers every 0.5 km.
Lighting/furniture:
- Tunnel lighting changed from blue/teal neon to warm sodium + cool LED runs,
and made continuous rather than every-other-segment.
- Deck lamps on a ~34 m pitch; added reflective delineator posts.
Verified in-engine by headless measurement, not by inspection: 14/14 geometric
assertions pass (dash length/width, edge width, yellow count, zebra pitch,
light colour, sign colour/bilingual, speed+km posts, markings flush with deck).
Sources and the corrections to widely-repeated wrong figures are recorded in
docs/japanese-road-standards.md.
Car meshes:
- CarManager: clone ReplicatedStorage/CarModels/<carId> as a visual Shell,
weld to Body, hide placeholder blocks. Falls back to procedural CarBody
when no mesh exists, so cars can be converted one at a time.
- Shell parts are Massless/CanCollide=false/CanQuery=false: the constraint
chassis and driving feel are untouched. Verified 0 violating parts live.
- 5 catalogue cars mapped from the 67-model ServerStorage/CarLibrary import.
Suspension (ref docs/CAR_PHYSICS_REFERENCE.txt, devforum 3915628):
- BUG: old k=9000 gave 1.10 studs static sag against 0.90 studs total travel,
i.e. the suspension sat permanently bottomed out and the spring did no work.
- Stiffness now solved from a sag target (70%% of half travel); damping now
derived as a damping ratio c = zeta*2*sqrt(k*m) instead of an unrelated
constant. Old pair worked out to zeta=0.31 (floaty); now 0.55-0.63.
- Measured after fix: ride height 1.97 studs, bounce 0.000, body roll 0.002.
Also: Circuit.inPA square test (PAFloor is 520x520, test was a r=260 circle,
corners falsely reported outside and spuriously armed runs), and void-fall
recovery now moves the character to the spawn pad BEFORE building the car.
Daikoku Futo PA becomes the hub (Tokyo Xtreme Racer structure): park, pick a
mode, drive out the exit gate to start the run, pull back into the PA to end it.
Modes:
- CRUISE free roam, banks session + lifetime kilometres
- DUEL gap-based battle: hold 350 studs for 3s to win
- TIME ATTACK solo flying lap, 4 sector splits, saved personal best
New shared modules:
- Circuit.luau one source of truth for loop geometry. progressOf(pos) gives
lap distance, which drives lap detection, sectors and duel gaps
alike, so the map and gameplay can never drift apart.
- Modes.luau mode definitions + duel/time-attack tuning constants
Server-authoritative throughout: ModeManager samples the car real position on
Heartbeat and the client never reports distance, lap time or gap. Teleport and
respawn jumps are rejected from distance accumulation.
ProfileTemplate v3 adds DistanceStuds, BestLapTime, BestSectors, DuelsWon and
DuelsLost; ProfileStore Reconcile migrates existing saves.
Rename: repo, wally package, local dir and stale NAS asset paths all move off
the old fnf-sim name. NAS folder was already 0-tokyo-wangan-racing, so those
doc paths were broken before this.
The straight strip becomes a closed rounded-rect loop (~7,400 studs/lap)
built from centerline samples, Shuto-C1 style. Landmark zones:
- Daikoku Futo PA: drivable meet lot off the south straight (guardrail
gap entrance), painted bays, flood-light towers, bilingual sign —
cars now SPAWN at Daikoku like a proper meet
- Rainbow Bridge over the east straight: white suspension towers with
beacons, cross beams, rainbow-colored rail lights
- Odaiba beyond the bridge: blocky Unicorn Gundam (glowing eyes, horn,
pink psycho-frame strips) + 16-cabin neon ferris wheel
- Yamate-style tunnel enclosing the whole north straight
- Tokyo Tower replica (orange/white tiers, two lit decks, antenna) west
- Tatsumi PA overlook pad NE
- City-core skyline inside the loop + outer ring skipping landmark zones
- Bilingual green highway signs via SurfaceGui (JP + EN)
Gameplay contract preserved: SpawnPad/FinishLine/KillWall names intact,
kill walls hug every road edge except the Daikoku entrance.
- Scanned b-action-cam-footage/clipchamp (99GB, 5 videos of the FD):
extracted audio NAS-side via linuxserver/ffmpeg container (stream-copy),
scanned 69min return drive per-second for engine tonality + whistle
prominence (1.5-9kHz peak vs band median)
- New rev loop: 985-993s highway pull — 0.0Hz pitch drift over 8s,
whistle ~1.7kHz at +33dB, exhaust + turbo captured together (seam 0.001)
- New whistle-only loop: same pull high-passed 1.2kHz — isolated spool
- SoundController: optional per-car Whistle layer that rides boost
(throttle held at speed): fades in past 25% speed, pitch 0.9->1.35
- ROTARY_SOUND.md updated; three .ogg uploads needed in Studio now
- SoundController rebuilt around idle+rev loop crossfading (real racing
game approach): idle layer barely pitch-shifts (keeps engine character),
rev layer carries the speed range; crossfade window 5%-45% of top speed
- Per-car CAR_SOUNDS table so the RX-7 gets real 13B rotary loops while
other cars keep the generic set
- docs/ROTARY_SOUND.md: full record->loop->upload pipeline for capturing
the owner's REAL RX-7 (extract audio from video, zero-crossing cut +
equal-power crossfade seam, normalize, ogg, Studio upload, wire IDs)
- Toolbox rotary rips evaluated and rejected: unauditionabe off-platform,
short/unloopable, murky rights; the real car beats any rip
SoundController (client):
- Looping engine sound on the car body: pitch 0.7->1.9 tracks speed
(curved so low speed feels torquey), volume swells with throttle
- Tyre squeal loop faded by lateral slip (velocity along body RightVector)
and hard braking from speed; always playing at 0 volume to avoid pops
- 3D sounds with rolloff so other players hear cars pass
- Asset IDs from safe sources (Roblox Resources engine loop,
ProSoundEffects squeal); swap in SOUNDS table after audition
Ambience (server):
- Atmosphere (purple-grey haze, glare) so neon reads in the air
- BloomEffect for neon pop + subtle cool ColorCorrection
- Slow ClockTime ping-pong 22:00->03:00 over 10 min: always night,
but the sky breathes
CameraController (client):
- Scriptable chase cam only while in the DriveSeat; restores default on exit
- Frame-rate independent damped follow with look-ahead aim point
- Flat horizon (ignores car pitch/roll) so bumps don't shake the view
- Speed-based FOV kick (quadratic ramp) for sense of pace
- Cleans up on Died/despawn
MapBuilder v2:
- Highway extended 2400 -> 3200 studs with distinct feature zones
- Gantry arches (seg 2), enclosed neon-lit tunnel (seg 3), jump ramp +
landing pair on the right lane (seg 4, left lane stays flat)
- Procedural neon skyline towers flanking both sides (deterministic seed,
same city every server)
- End kill-wall so you can't sail off the far edge
- New shared Chassis.luau: geometry constants + per-car tuning from stats
- CarManager.buildCarModel rebuilt: prismatic+spring suspension per corner,
servo-hinge steering on front knuckles, motor-hinge driven wheels,
hidden dense ballast for anti-roll; VehicleSeat kept as input device only
- New client ChassisController: drives motors/servos from seat
ThrottleFloat/SteerFloat per Heartbeat; speed-sensitive steering lock;
engine braking on throttle release
- Driver gets network ownership of every unanchored part (constraint
assemblies are separate; missing one causes stuttery physics)
- Docs: MESH_SWAP.md rewritten for shell-on-chassis workflow; ROADMAP updated
Per user direction, the MVP is now simply driving cars on the expressway.
- Removed RaceManager and Economy modules entirely
- Slimmed Remotes to DataUpdated / SpawnCar / EquipCar
- ProfileTemplate now just remembers the last driven car (v2)
- Cars: dropped price/rep/upgrade fields; kept identity + driving stats
- CarManager: stat-based tuning only; RX-7 allowlist via GameConfig.canDrive
- DataManager: assign default car on join; downgrade RX-7 if de-allowlisted
- Client: replaced garage/economy UI with a simple car picker + respawn
- Docs: GDD/ROADMAP/README rewritten for drive-only; added docs/MESH_SWAP.md
- Gates: stylua clean, selene 0/0, rojo builds