Three changes, all behind flags rather than deletions so the surveyed geometry is recoverable: 1. Stall paint off (DRAW_STALL_PAINT=false). Row placement math and the PACapacity record still compute; they just emit no parts. 2. PARing deck removed. It laid a 44-wide circular band of road deck around the PA, measured flush with the apron (both tops y=47.00) and entirely inside the apron footprint -- redundant pavement reading as a leftover ring where the old barriers were. The arc loop still runs; junctions, ramps and flares are still positioned off it. 3. Generated PA structures off (DRAW_PA_STRUCTURES=false): PAHonkan, PANibankan, PAToiletNorth, PAKioskWest, PAHutWest + glazing, and the props (Lawson, toilet block, fountain, smoking shelters, motorcycle bay, EV chargers) and their two signs. OSM survey positions preserved in code as the placement reference for the store assets. Kept: PALowCarBump (gameplay, the 段差 anti-車高短 bumps) and the main 大黒PA sign. Verified in live Edit datamodel after rebuild: all 13 removed part names plus *Glazing report absent; PAFloor=1, PAPerimeter=78, PALowCarBump=3, PARampFlare=2 remain; apron continuity 361/361 raycast sample points hit solid ground, holes=0 -- no gap left where the ring deck was. 17385 -> 17277.
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/.