How to make a racing game in Roblox Studio
A track, a car, a countdown and laps that can't be cheated — the parts of a Roblox racing game, the order to build them, and a complete race script.
Updated November 2, 20269 min read
Racing games are short rounds with a clear winner, which makes them easy to understand and easy to replay. The car is only half of it: the race system (start, laps, checkpoints, results) is what turns driving around into a game.
The core loop
Every racing game comes down to one loop that players repeat. Build this first, in grey blocks:
- Join the lobby and pick a car
- Countdown, then race
- Pass every checkpoint, finish the laps
- See the results and earn coins for the next car
Systems you need
Track
A closed loop with wide turns, walls or barriers, and invisible checkpoint parts across the road.
Cars
A VehicleSeat that reads the driver's input, plus wheels attached with constraints. The Creator Store has car kits — check every script inside before using one.
Race system
Countdown, a start gate, ordered checkpoints, lap count and finish order — all on the server.
Results and rewards
Coins by finishing position, saved with DataStoreService, spent on new cars or colors.
Leaderboard
Best lap time per player — the number people come back to beat.
Build order
- 1
One car that drives well
Test the car alone on a flat baseplate first: speed, turning, not flipping. Everything else depends on it feeling good.
- 2
The track
Block out one loop. Drive it a dozen times and widen every corner where you hit the wall.
- 3
Race script
Checkpoints and the script below. Test with a local server and two players in Studio.
- 4
Car spawning
Spawn a car for each racer behind the start gate at the start of a round, and remove it after.
- 5
UI and rewards
Show the countdown, lap and position; pay coins at the finish.
The key script: Race with countdown, laps and checkpoints
Where it goes: ServerScriptService > Race (Script).
- In Workspace make a Folder
Racewith a FolderCheckpointsinside. Add invisible, anchored,CanCollide-off parts across the road named1,2,3… in driving order.1is the start/finish line. - Add an anchored part
StartGatein theRacefolder, just behind line 1, blocking the road. Racers line up behind it, so they cross line 1 only after a full lap. - Show the status on screen with a LocalScript that reads
workspace.Race:GetAttribute("Status").
local Players = game:GetService("Players")
local race = workspace:WaitForChild("Race")
local checkpoints = race:WaitForChild("Checkpoints")
local gate = race:WaitForChild("StartGate")
local LAPS = 3
local MAX_RACE_SECONDS = 300
local COUNT = #checkpoints:GetChildren()
local running = false
local startTime = 0
local progress = {} -- [player] = { next = 2, lap = 0, finished = false }
local finishers = 0
local function status(text)
race:SetAttribute("Status", text)
end
-- The player touching a checkpoint, on foot or driving a car.
local function playerFromHit(hit)
local model = hit:FindFirstAncestorOfClass("Model")
while model do
local player = Players:GetPlayerFromCharacter(model)
if player then
return player
end
local seat = model:FindFirstChildWhichIsA("VehicleSeat", true)
if seat and seat.Occupant then
return Players:GetPlayerFromCharacter(seat.Occupant.Parent)
end
model = model:FindFirstAncestorOfClass("Model")
end
return nil
end
for _, part in checkpoints:GetChildren() do
local index = tonumber(part.Name)
part.Touched:Connect(function(hit)
if not running then
return
end
local player = playerFromHit(hit)
local state = player and progress[player]
-- Only the next checkpoint counts, so shortcuts don't work.
if not state or state.finished or index ~= state.next then
return
end
if index == 1 then
state.lap += 1
if state.lap >= LAPS then
state.finished = true
finishers += 1
status(string.format("%s finished #%d in %.2f s", player.DisplayName, finishers, os.clock() - startTime))
return
end
end
state.next = index % COUNT + 1
end)
end
local function racersLeft()
local left = 0
for player, state in progress do
if player.Parent and not state.finished then
left += 1
end
end
return left
end
while true do
running = false
gate.CanCollide = true
gate.Transparency = 0.5
while #Players:GetPlayers() == 0 do
status("Waiting for players")
task.wait(2)
end
for seconds = 10, 1, -1 do
status("Race starts in " .. seconds)
task.wait(1)
end
progress, finishers = {}, 0
for _, player in Players:GetPlayers() do
progress[player] = { next = 2, lap = 0, finished = false }
end
gate.CanCollide = false
gate.Transparency = 1
status("GO!")
startTime = os.clock()
running = true
repeat
task.wait(0.5)
until racersLeft() == 0 or os.clock() - startTime > MAX_RACE_SECONDS
running = false
status("Race over")
task.wait(8)
endHow it works
- Checkpoints count only in order, so driving across the grass to line 1 does nothing until the player has passed every checkpoint before it.
- Times come from the server clock, so a player can't report a faster lap than they drove.
- Players who join mid-race wait for the next round; players who leave stop counting toward the end of the race.
How racing games make Robux
- New cars and colors bought with coins earned by racing, with some cosmetic cars for Robux.
- Cosmetic trails, horns and nameplates.
- Avoid selling faster cars for Robux in ranked races: paid speed ruins the race for everyone else.
You receive 70% of what players spend on game passes and developer products; Roblox keeps 30%.
Common mistakes
A car that flips at every bump
Lower the car's center of mass (heavier base, lighter top), widen the wheelbase, and keep the track smooth.
Checkpoints players can skip
One finish line with no checkpoints lets players drive backwards over it. Use ordered checkpoints like the script above.
Lap detection on the client
A LocalScript can report any lap time it wants. Count laps and times on the server.
FAQ
How do I make a car in Roblox Studio?
A car is a VehicleSeat on a body, with wheels attached by constraints (for example HingeConstraints set to Motor). The seat's Throttle and Steer values come from the driver; a script turns them into wheel speed and steering. Car kits from the Creator Store are a faster start — check their scripts first.
How do I count laps in a Roblox racing game?
Place numbered checkpoint parts around the track and track each player's next checkpoint on the server. When they cross line 1 after the last checkpoint, add a lap.
How do I stop players from cutting corners in a race?
Only accept checkpoints in order, as this page's script does. A skipped checkpoint means the finish line won't count for that player.