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:
@@ -9,8 +9,6 @@
|
||||
the most reliable, least-buggy way to get a car moving on day one. When you
|
||||
later import the real RX-7 mesh + a constraint chassis (A-Chassis style),
|
||||
you swap out `buildCarModel` and keep everything else.
|
||||
|
||||
Upgrades scale MaxSpeed / Torque / TurnSpeed so the upgrade economy is real.
|
||||
]]
|
||||
|
||||
local Players = game:GetService("Players")
|
||||
@@ -20,10 +18,8 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
local Shared = ReplicatedStorage.Shared
|
||||
local Cars = require(Shared.Cars)
|
||||
local GameConfig = require(Shared.GameConfig)
|
||||
local ProfileTemplate = require(Shared.ProfileTemplate)
|
||||
local DataManager = require(script.Parent.DataManager)
|
||||
|
||||
type ProfileData = ProfileTemplate.ProfileData
|
||||
type Car = Cars.Car
|
||||
|
||||
local CarManager = {}
|
||||
@@ -31,17 +27,11 @@ local CarManager = {}
|
||||
local activeCars: { [Player]: Model } = {}
|
||||
local carsFolder: Folder
|
||||
|
||||
-- Convert a car's 0-100 stats + upgrade levels into VehicleSeat tuning --------
|
||||
local function computeTuning(car: Car, upgrades: { Engine: number, Tires: number, Nitro: number })
|
||||
local engineLvl = upgrades.Engine or 0
|
||||
local tiresLvl = upgrades.Tires or 0
|
||||
-- Base values derived from stats; upgrades add a percentage on top.
|
||||
-- Convert a car's 0-100 stats into VehicleSeat tuning ------------------------
|
||||
local function computeTuning(car: Car)
|
||||
local maxSpeed = 60 + car.Stats.Speed * 1.6 -- studs/sec-ish target
|
||||
maxSpeed *= (1 + engineLvl * 0.08) -- +8% top speed per engine level
|
||||
local torque = 8000 + car.Stats.Acceleration * 220
|
||||
torque *= (1 + engineLvl * 0.10)
|
||||
local turnSpeed = 20 + car.Stats.Handling * 0.35
|
||||
turnSpeed *= (1 + tiresLvl * 0.06) -- tires help turn-in
|
||||
return maxSpeed, torque, turnSpeed
|
||||
end
|
||||
|
||||
@@ -126,26 +116,14 @@ function CarManager.spawn(player: Player, carId: string?)
|
||||
if not car then
|
||||
return
|
||||
end
|
||||
-- Defense in depth: never spawn the restricted RX-7 for a non-allowlisted user,
|
||||
-- even if their save somehow contained it.
|
||||
if car.Id == GameConfig.RestrictedStarterCarId and not GameConfig.isRX7Allowed(player.UserId) then
|
||||
return
|
||||
end
|
||||
-- Only spawn cars the player owns (anti-cheat: no spawning unowned exotics).
|
||||
local owned
|
||||
for _, o in ipairs(data.OwnedCars) do
|
||||
if o.Id == id then
|
||||
owned = o
|
||||
break
|
||||
end
|
||||
end
|
||||
if not owned then
|
||||
-- Restricted car (RX-7) can only be driven by allowlisted UserIds.
|
||||
if not GameConfig.canDrive(player.UserId, car.Id, car.Restricted) then
|
||||
return
|
||||
end
|
||||
|
||||
CarManager.despawn(player)
|
||||
|
||||
local maxSpeed, torque, turnSpeed = computeTuning(car, owned.Upgrades)
|
||||
local maxSpeed, torque, turnSpeed = computeTuning(car)
|
||||
local model = buildCarModel(car, maxSpeed, torque, turnSpeed)
|
||||
model:PivotTo(spawnCFrame())
|
||||
model.Parent = carsFolder
|
||||
|
||||
Reference in New Issue
Block a user