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.
Tokyo Wangan Racing
A Roblox game where you cruise a neon Tokyo expressway at night in cool cars —
starting with a real 1993 Mazda RX-7. The driving feel comes first; everything
else layers on top of it. See docs/ROADMAP.md for what comes next.
Status: Playable. Spawn → drive → switch cars → respawn, plus the full three-mode Wangan loop. CI green on a self-hosted Gitea runner. Built code-first — nothing to hand-build in Studio.
The Daikoku loop (how you play)
Daikoku Futo PA is the hub, exactly like Tokyo Xtreme Racer. You are never "joining a match" — you park, pick how you want to run, and drive out.
IN THE PA ──► pick a mode ──► cross the exit gate ──► RUNNING
▲ │
└──────────────── pull back into the PA ─────────────────┘
| Mode | 日本語 | What it is |
|---|---|---|
| CRUISE | 流し | Free roam. Bank kilometres, meet other drivers. Rivals can pull alongside and challenge you. |
| DUEL | バトル | Hunt rivals. First to open a ~350-stud gap and hold it for 3s wins. No laps, no checkpoints — who breaks first. |
| TIME ATTACK | タイムアタック | Solo flying lap with 4 sector splits and a saved personal best. Rivals can't interrupt you. |
Cruise and Duel both allow challenges, so a cruise can turn into a battle organically — pull alongside someone and the prompt appears for both of you. Time Attack deliberately opts out so a hot lap is never ruined.
Kilometres, lap times and duel records all persist via ProfileStore.
Prerequisites
Toolchain is managed by Rokit. With Rokit on
your PATH:
rokit install # rojo, wally, selene, stylua at pinned versions
wally install # restores ProfileStore into ServerPackages/
| Tool | Purpose |
|---|---|
| rojo | Sync/build code ↔ Roblox place |
| wally | Package manager (ProfileStore) |
| selene | Static analysis / linter |
| stylua | Code formatter |
Build & run
rojo build --output build.rbxl # standalone place file to open in Studio
# OR live-sync into an open Studio place (install the Rojo Studio plugin):
rojo serve
In Studio press Play. You spawn on the expressway in your car. Bottom bar: CARS (switch car) and RESPAWN (re-spawn if you flip). The RX-7 only appears for allowlisted accounts.
Quality gates (CI enforces these on every push)
stylua --check src/ # formatting
selene src/ # lint
rojo build --output build.rbxl # must compile
CI runs on a self-hosted Gitea Actions runner on UNRAID-1 (Ubuntu 24.04 job
container — rojo's binary needs glibc 2.39). Workflow: .gitea/workflows/ci.yml.
Architecture (server-authoritative)
Clients request, the server decides. The RX-7 allowlist and anti-cheat are server-side.
ReplicatedStorage/Shared GameConfig, Cars, ProfileTemplate, Remotes
ServerScriptService/Server init.server + managers (below)
ServerScriptService/ServerPackages ProfileStore (Wally)
StarterPlayerScripts/Client init.client (HUD + car picker)
| Module | Responsibility |
|---|---|
DataManager |
Wraps ProfileStore — session locking, reconcile, Studio mock. Remembers your last car. |
CarManager |
Spawns the equipped car (VehicleSeat-driven placeholder) and enforces the RX-7 allowlist. |
MapBuilder |
Procedurally builds the expressway, spawn pad, neon pylons, kill walls. |
AntiCheat |
Movement sanity check (speed/teleport) — a speed bump, not a fortress. |
The RX-7 demo-lock: GameConfig.RX7AllowedUserIds holds the owner's + son's
Roblox UserIds; only they can select/drive the RX-7 (enforced in CarManager and
the EquipCar remote).
Replacing the placeholder RX-7 with the real mesh
One function changes: CarManager.buildCarModel. Full step-by-step in
docs/MESH_SWAP.md. Reference photos live on the NAS at
unraid-1:/mnt/user/data/yy-roblox-games/0-tokyo-wangan-racing/001-1993 Mazda RX-7/.