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
This commit is contained in:
+29
-43
@@ -1,52 +1,38 @@
|
||||
# Game Design Document — Fast & Furious: Tokyo Expressway (MVP)
|
||||
|
||||
## Vision
|
||||
A progression-fantasy street racer. You start in a humble-but-iconic 1993 Mazda
|
||||
RX-7 and claw your way up to hypercars on a neon-drenched Tokyo expressway at night.
|
||||
Easy to pick up, satisfying to grind, fair to spend on.
|
||||
A neon Tokyo expressway you can cruise at night in cool cars — starting with a
|
||||
real 1993 Mazda RX-7. The long-term dream is a full street-racing simulator, but
|
||||
the **MVP is deliberately tiny: just drive.**
|
||||
|
||||
## The one-sentence pitch
|
||||
"Start in the RX-7, own the expressway."
|
||||
## MVP scope (what's built) — JUST DRIVING
|
||||
- Spawn on a neon Tokyo expressway at night.
|
||||
- Drive a car around the highway (built on Roblox's reliable VehicleSeat).
|
||||
- Switch between cars via a simple "CARS" picker.
|
||||
- Respawn your car if you flip or fall off.
|
||||
- The **RX-7 is demo-locked** to the owner + son (Roblox UserId allowlist,
|
||||
enforced server-side). Everyone else drives the public cars.
|
||||
- Your last car is remembered between sessions (ProfileStore).
|
||||
|
||||
## Core loop (the addictive 60 seconds)
|
||||
1. **Spawn** on the expressway in your equipped car.
|
||||
2. **Race** the time-trial down the highway to the finish line.
|
||||
3. **Earn** cash + reputation for finishing.
|
||||
4. **Spend** in the Garage: upgrade your current car or buy the next tier.
|
||||
5. A faster car / better tune makes the next race feel better → back to step 1.
|
||||
That's it. No racing, no money, no rep, no upgrades, no daily rewards. The point
|
||||
of the MVP is to get the car feeling good on the road and be testable fast.
|
||||
|
||||
Daily rewards + rising rep gates give a reason to come back tomorrow.
|
||||
## Why this cut
|
||||
Driving feel is the hardest, most important part of a car game. Everything else
|
||||
(racing, economy, progression) is worthless if the car isn't fun to drive. So the
|
||||
MVP nails driving first; the rest is layered on later once it feels right.
|
||||
|
||||
## Pillars
|
||||
- **Progression fantasy** — junker → hypercar, always a visible next goal.
|
||||
- **Nighttime Tokyo vibe** — neon, speed, style.
|
||||
- **Fair monetization** — spending accelerates the grind, never buys wins.
|
||||
- **Server-authoritative** — no exploiting money or unlocking cars.
|
||||
## Pillars (for the eventual full game)
|
||||
- Progression fantasy — junker → hypercar (LATER).
|
||||
- Nighttime Tokyo vibe — neon, speed, style (NOW: the map).
|
||||
- Fair monetization (LATER).
|
||||
- Server-authoritative — no exploiting (NOW: allowlist + anti-cheat foundations).
|
||||
|
||||
## MVP feature set (what's built)
|
||||
- 5-tier car catalogue; **RX-7 is the free starter** (Tier 2).
|
||||
- Drivable cars via VehicleSeat (proven, swap-in real mesh later).
|
||||
- Procedural expressway map with kill-walls (can't leave the road).
|
||||
- Garage + Dealership UI: view / buy / equip / upgrade.
|
||||
- Upgrade system: Engine / Tires / Nitro, cost-scaled with diminishing returns.
|
||||
- Solo time-trial race with server-validated payouts.
|
||||
- Reputation gates on higher-tier cars.
|
||||
- Daily login reward.
|
||||
- Robust saving via ProfileStore (session-locked, reconciling).
|
||||
- Basic movement anti-cheat.
|
||||
## Deferred (see ROADMAP)
|
||||
Racing, checkpoints, money/economy, reputation, upgrades, customization, daily
|
||||
rewards, traffic AI, leaderboards, monetization, crews/PvP, full city map.
|
||||
|
||||
## Deliberately deferred (see ROADMAP)
|
||||
Traffic AI, head-to-head/drag racing, car customization cosmetics, crews/PvP,
|
||||
full city map, mobile-tuned optimization pass, monetization products.
|
||||
|
||||
## Economy first-pass numbers (tune freely in `GameConfig`)
|
||||
- Start: $1,500, 0 rep, own the RX-7.
|
||||
- Race finish: +$650 (base+win) and +15 rep.
|
||||
- Daily: +$300, +10 rep.
|
||||
- Upgrades: base $500, ×1.6 per level, cap level 5 per part.
|
||||
- Car tiers: Junk $800 → S15 $12k (50 rep) → R34 $45k (180 rep) → Hyper $250k (600 rep).
|
||||
|
||||
## Win condition / retention
|
||||
No hard "end" — the chase up the tiers plus daily rewards and (future) leaderboards
|
||||
supply the long tail. First-session goal: earn enough to feel one upgrade land
|
||||
inside the first 10 minutes.
|
||||
## Cars in the picker
|
||||
RX-7 (restricted), City Runabout (public default), Silvia S15, Skyline GT-R R34,
|
||||
and a stylized hypercar. Stats (Speed/Accel/Handling, 0-100) only affect driving
|
||||
feel — there are no prices or unlocks in the MVP.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Swapping the placeholder RX-7 for the real mesh (M1)
|
||||
|
||||
Right now every car is a coloured block + a `VehicleSeat` so the game is drivable
|
||||
today. This is the **one file** you touch to make the RX-7 a real model:
|
||||
`src/server/CarManager.luau` → the `buildCarModel` function.
|
||||
|
||||
Nothing else (saving, the allowlist, car switching, the map, anti-cheat) needs to
|
||||
change. That's the whole point of isolating model-building in one function.
|
||||
|
||||
## Reference photos
|
||||
The real car's reference photos live on the NAS (too large to commit to git):
|
||||
|
||||
```
|
||||
unraid-1:/mnt/user/data/yy-roblox-games/0-fast-n-furious-sim/001-1993 Mazda RX-7/
|
||||
```
|
||||
|
||||
A single downscaled reference is included at `assets/reference/rx7-reference.png`
|
||||
for quick lookups.
|
||||
|
||||
## Step 1 — Get a model into Roblox
|
||||
Options, easiest first:
|
||||
1. **Buy or find a free RX-7 FD model** on the Roblox Creator Marketplace/toolbox,
|
||||
or
|
||||
2. **Model it** in Blender from the reference photos and import the mesh
|
||||
(`.fbx`/`.obj`) via Studio's 3D importer, or
|
||||
3. Commission one.
|
||||
|
||||
You want a single `Model` whose parts are welded together, with a clear "body"
|
||||
part you can drive. Keep the part count low (mobile perf).
|
||||
|
||||
## Step 2 — Store it where Rojo/Studio can clone it
|
||||
Put the finished `Model` under `ReplicatedStorage` (e.g. a `CarModels` folder).
|
||||
Two ways to manage it:
|
||||
- **Simple:** keep it in the Studio place file as a real Instance (not synced by
|
||||
Rojo). Fine for a single hero car.
|
||||
- **Version-controlled:** export the model to a `.rbxm` and reference it from the
|
||||
Rojo project so it lives in git. See Rojo's `$path` docs for `.rbxm` model files.
|
||||
|
||||
## Step 3 — Rewrite `buildCarModel` to clone the real mesh
|
||||
Replace the block-building body of `buildCarModel(car, maxSpeed, torque, turnSpeed)`
|
||||
with something like:
|
||||
|
||||
```lua
|
||||
local CAR_MODELS = ReplicatedStorage:WaitForChild("CarModels")
|
||||
|
||||
local function buildCarModel(car, maxSpeed, torque, turnSpeed)
|
||||
-- Look up a real model by car id; fall back to the block builder if missing.
|
||||
local template = CAR_MODELS:FindFirstChild(car.Id)
|
||||
if not template then
|
||||
return buildBlockCar(car, maxSpeed, torque, turnSpeed) -- keep the old code as a fallback
|
||||
end
|
||||
|
||||
local model = template:Clone()
|
||||
|
||||
-- Ensure it has a VehicleSeat named "DriveSeat" welded to the driving body.
|
||||
local seat = model:FindFirstChild("DriveSeat")
|
||||
if not seat then
|
||||
seat = Instance.new("VehicleSeat")
|
||||
seat.Name = "DriveSeat"
|
||||
-- weld seat to model.PrimaryPart, position it in the cabin...
|
||||
seat.Parent = model
|
||||
end
|
||||
seat.MaxSpeed = maxSpeed
|
||||
seat.Torque = torque
|
||||
seat.TurnSpeed = turnSpeed
|
||||
|
||||
assert(model.PrimaryPart, "Car model needs a PrimaryPart set")
|
||||
return model
|
||||
end
|
||||
```
|
||||
|
||||
Keep the current block-builder renamed as `buildBlockCar` so any car without a
|
||||
real mesh still works. That way you can import cars one at a time.
|
||||
|
||||
## Step 4 (recommended, M1) — Move to a real chassis
|
||||
The `VehicleSeat` is great for "it drives today" but for real suspension/grip,
|
||||
adopt a proven **constraint chassis** (A-Chassis or a modern equivalent). At that
|
||||
point `buildCarModel` clones the chassis rig and attaches the RX-7 body to it.
|
||||
Still one function; still no changes elsewhere.
|
||||
|
||||
## Verify
|
||||
- `rojo build --output build.rbxl` compiles.
|
||||
- In Studio: Play → you spawn in the real RX-7 → it drives → it saves.
|
||||
- Non-allowlisted test account still can't select the RX-7 (server enforced).
|
||||
+40
-42
@@ -1,62 +1,60 @@
|
||||
# Roadmap — realistic solo-dev plan
|
||||
|
||||
This replaces the original doc's optimistic 12-week timeline. It assumes **one
|
||||
part-time developer learning as they go**. Ship the vertical slice, then layer
|
||||
polish. Each milestone is independently playable/testable.
|
||||
Assumes **one part-time developer learning as they go**. The MVP is intentionally
|
||||
tiny — *just driving* — so there's a fun, testable thing FAST. Everything else is
|
||||
layered on only after the driving feels good.
|
||||
|
||||
> Rule of thumb: the original guide's "weeks" are really "milestones." Expect
|
||||
> **4–8 months** of part-time work to a polished, launch-ready MVP. That's normal.
|
||||
> The goal of this order is that you always have something that *runs*.
|
||||
> Expect **months, not weeks** to a polished full game. That's normal. This order
|
||||
> guarantees you always have something that runs.
|
||||
|
||||
---
|
||||
|
||||
## ✅ M0 — Vertical slice (DONE — this repo)
|
||||
Drive → race → earn → buy/upgrade → **save**. Server-authoritative. Placeholder
|
||||
RX-7 block car, procedural expressway. Proves the whole stack end to end.
|
||||
## ✅ M0 — Drive-only MVP (DONE — this repo)
|
||||
Spawn on the neon expressway, drive a car, switch cars, respawn. RX-7 demo-locked
|
||||
to owner + son. Cars persist between sessions. CI green on a self-hosted runner.
|
||||
|
||||
## M1 — Make it feel good (the real work)
|
||||
## M1 — Make driving feel GOOD (the real work, do this next)
|
||||
- [ ] Import the **real RX-7 mesh**; swap `CarManager.buildCarModel` only.
|
||||
- [ ] Adopt a proven **constraint chassis** (A-Chassis or modern equivalent) for
|
||||
real suspension/grip instead of the raw VehicleSeat. Do NOT hand-roll physics.
|
||||
- [ ] Tune driving feel: acceleration curve, grip, camera.
|
||||
- [ ] Sound: engine loop, boost, tire screech.
|
||||
**Exit test:** the RX-7 is genuinely fun to just drive around.
|
||||
See `docs/MESH_SWAP.md` for the exact steps.
|
||||
- [ ] Adopt a proven **constraint chassis** (A-Chassis or a modern equivalent)
|
||||
for real suspension/grip instead of the raw VehicleSeat. Do NOT hand-roll
|
||||
physics.
|
||||
- [ ] Tune acceleration curve, grip, and the chase camera.
|
||||
- [ ] Sound: engine loop, tire screech, boost.
|
||||
**Exit test:** the RX-7 is genuinely fun to just drive around. Ship nothing else
|
||||
until this is true.
|
||||
|
||||
## M2 — Race depth
|
||||
- [ ] Checkpoints + lap/segment timing (extend `RaceManager`).
|
||||
- [ ] Personal best times saved to profile.
|
||||
- [ ] A second race type (drag / point-to-point).
|
||||
- [ ] Countdown + results screen.
|
||||
## M2 — More cars + polish (still no racing)
|
||||
- [ ] Import a few more real car meshes.
|
||||
- [ ] Better map: more expressway sections, ramps, tunnels, scenery.
|
||||
- [ ] Day/night, weather mood.
|
||||
|
||||
## M3 — Content & progression polish
|
||||
- [ ] Flesh out the 25-car catalogue across tiers.
|
||||
- [ ] Car customization cosmetics (rims, wraps, neon) — visual only for MVP.
|
||||
- [ ] Daily missions (not just login): "win 3 races", "earn $5k".
|
||||
- [ ] Tutorial for the first 10 minutes.
|
||||
## M3 — Racing (the first "game" layer)
|
||||
- [ ] Checkpoints + timing (a new RaceManager — the old one was removed in M0).
|
||||
- [ ] Personal best times.
|
||||
- [ ] Simple point-to-point and drag modes.
|
||||
|
||||
## M4 — Systems hardening
|
||||
- [ ] Leaderboards (OrderedDataStore: top rep, fastest times).
|
||||
- [ ] Anti-cheat pass 2 (validate race times against car stats).
|
||||
- [ ] DataStore stress test / backup-version restore drill.
|
||||
- [ ] Performance pass: StreamingEnabled tuning, part budget, mobile test.
|
||||
## M4 — Progression & economy (only once racing is fun)
|
||||
- [ ] Money from races, a garage, buying/unlocking cars, upgrades, reputation.
|
||||
(These systems existed as scaffolding and were cut for the MVP; reintroduce
|
||||
them deliberately when they have a purpose.)
|
||||
|
||||
## M5 — Monetization (only after it's fun)
|
||||
- [ ] 2× Cash gamepass (the classic first product).
|
||||
- [ ] VIP membership (daily bonus, cosmetic-only exclusives).
|
||||
- [ ] Nitro/boost dev-products — **never** pay-to-win on ranked races.
|
||||
- [ ] Receipt handling via ProfileStore `LastSavedData`.
|
||||
## M5 — Systems hardening & monetization
|
||||
- [ ] Leaderboards, anti-cheat pass 2, DataStore backup drill.
|
||||
- [ ] Performance pass (StreamingEnabled, part budget, mobile).
|
||||
- [ ] Fair gamepasses/products — never pay-to-win.
|
||||
|
||||
## M6 — Traffic AI (deferred hardest system)
|
||||
- [ ] Start with **spline-following** dummy cars on fixed paths (cheap, no lag).
|
||||
Only attempt true pathfinding AI if performance allows.
|
||||
- [ ] Spawn/despawn by distance to keep part count sane.
|
||||
- [ ] Spline-following dummy cars first (cheap). True AI only if perf allows.
|
||||
|
||||
---
|
||||
|
||||
## Standing engineering rules
|
||||
- Every change must pass `stylua --check`, `selene`, and `rojo build` (CI enforces).
|
||||
- Keep the client dumb: it requests, the server decides. No exceptions for money.
|
||||
- Add new tunables to `GameConfig`, not scattered magic numbers.
|
||||
- Every change must pass `stylua --check`, `selene`, and `rojo build` — CI on the
|
||||
self-hosted Gitea runner enforces all three on every push.
|
||||
- Keep the client dumb: it requests, the server decides. The RX-7 allowlist and
|
||||
anti-cheat live server-side.
|
||||
- Add tunables to `GameConfig`, not scattered magic numbers.
|
||||
- Add a save key by adding it to `ProfileTemplate` (auto-reconciles); never remove
|
||||
a key without a migration.
|
||||
a key without a migration (bump `ProfileStoreName` `_vN` in dev to wipe).
|
||||
- Test in Studio after every server change (ProfileStore uses a mock store there).
|
||||
|
||||
Reference in New Issue
Block a user