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.
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/.