Obstacle courses are one of Roblox’s most proven formats. The core loop — attempt, fail, learn, succeed, move on — creates a tight mastery-based engagement cycle that works for all ages. The genre is deceptively simple to expand: adding more stages is purely additive. This template covers the entire backbone: server-authoritative checkpoint persistence with DataStore saving, a stage completion pipeline that advances players to the next stage, five distinct obstacle types with configurable attributes, a per-player speedrun timer synced to the client, and anDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/brockmartin/roblox-game-skill/llms.txt
Use this file to discover all available pages before exploring further.
OrderedDataStore-backed global leaderboard for fastest times.
Core Systems
Checkpoint System
Saves stage and checkpoint number to DataStore on every new checkpoint hit. On join, players respawn at their saved position. On death,
CharacterAdded teleports to the last saved CFrame.Stage Progression
StageClear trigger parts detect stage completion and teleport players to the first checkpoint of the next stage. Stage and checkpoint are always ahead-only — no regression.Five Obstacle Types
Kill bricks, moving platforms, disappearing platforms, spinning obstacles, and conveyor belts — all driven by a single
ObstacleManager that scans stage folders on startup.Speedrun Timer
Per-player stage and overall timers tracked server-side with
os.clock(). Synced to client every second via TimerSync remote. Stage time recorded on completion.Global Leaderboard
OrderedDataStore per stage for fastest times. UpdateAsync only writes if the new time beats the player’s personal best. Top 10 fetched via GetSortedAsync.DataStore Persistence
Progress saves on
PlayerRemoving and loads on PlayerAdded. New players start at Stage 1, Checkpoint 0.Key Code: Checkpoint System
The checkpoint server script handles loading saved progress, wiring up all checkpoint touch events across every stage folder, and detecting stage clears — all in one self-contained module.Key Code: Five Obstacle Types
All five obstacle types are initialised byObstacleManager scanning stage folders. Parts are identified by name prefix (e.g. Kill_, Moving_, Disappear_, Spin_, Conveyor_) or a KillBrick attribute.
Key Code: Global Leaderboard
Times are stored in milliseconds in anOrderedDataStore. UpdateAsync ensures only personal-best times are written, and GetSortedAsync fetches the top 10 in ascending order (lowest time = fastest).
Architecture
- ServerScriptService
- Workspace Layout
- ReplicatedStorage
- StarterPlayer
| Script | Purpose |
|---|---|
CheckpointSystem.server.luau | Checkpoint touch detection, DataStore save/load, respawn positioning |
ObstacleManager.server.luau | All five obstacle type behaviours — scans Workspace on start |
TimerSystem.server.luau | Per-player stage and overall timers, periodic TimerSync remote fires |
LeaderboardManager.server.luau | OrderedDataStore reads/writes for stage and overall fastest times |
StageManager.server.luau | Stage completion detection, advancing players, tracking current stage |
Stage Difficulty Curve
| Stage Range | Difficulty | Mechanics Introduced |
|---|---|---|
| 1–10 | Beginner | Basic jumps, simple gaps |
| 11–25 | Easy | Kill bricks (stationary), longer jumps |
| 26–50 | Medium | Moving platforms, disappearing platforms |
| 51–80 | Hard | Spinning obstacles, conveyors, combinations |
| 81–100 | Expert | Multi-mechanic gauntlets, precision timing |
| 100+ | Master/Bonus | Secret stages, extreme difficulty |
Streaming tip: Enable
Workspace.StreamingEnabled = true for obbys with many stages. Set ModelStreamingMode to Opportunistic on non-adjacent stage folders and Persistent for the current and next stage. Players only need to load the stage they are on — this dramatically reduces memory and load times on mobile.How to Use This Template
See the New Game workflow for the complete 8-step build process.