How to Make a Leaderboard in Roblox Studio (Coins + Saving)
Learn how to make a leaderboard in Roblox Studio that shows each player's coins, gives coins when they touch a coin part, and saves them with a DataStore so they are still there next time.
- leaderstats folder and a Coins IntValue
- Collectable coins with a debounce and respawn
- Optional saving with DataStoreService and pcall
Step by step
Create the leaderboard script
In the Explorer, hover over ServerScriptService, click the plus button and insert a Script. Rename it Leaderboard, delete the print line and paste the first script. It creates leaderstats and Coins for every player who joins.
Check the leaderboard
Press Play (F5). In the top-right player list you should now see a Coins column with 0 next to your name. If not, check the spelling of leaderstats and look in the Output window.
Build a coin
Insert a Part, change its Shape to Cylinder, make it small and gold, and name it Coin. Turn Anchored on and CanCollide off so players can run through it without being pushed.
Add the coin script
Insert a Script inside the Coin part and paste the coin script. Press Play and touch the coin: Coins should go up by 1, the coin disappears, and it comes back after 5 seconds.
Fill your map with coins
Select the finished coin and press Ctrl+D (Cmd+D on Mac) to duplicate it with its script. Spread copies around the map, and try giving rare coins a higher COIN_VALUE.
Turn on saving
Publish your game with File, Publish to Roblox. Then open File, Experience Settings, Security and enable Studio Access to API Services. Replace the Leaderboard script's code with the DataStore version.
Test that coins save
Play, collect a few coins and stop. Press Play again: your coins should load from the DataStore. If you see a warning in the Output, read it, because it tells you whether loading or saving failed.
The script
-- Script inside ServerScriptService, named Leaderboard
local Players = game:GetService("Players")
local function setupLeaderstats(player: Player)
-- The folder MUST be named "leaderstats" (all lowercase)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
-- Every value inside the folder becomes a column on the leaderboard
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
end
-- Run setupLeaderstats for every player who joins
Players.PlayerAdded:Connect(setupLeaderstats)
-- Script inside a Coin part (Anchored = true, CanCollide = false)
local Players = game:GetService("Players")
local coin = script.Parent
local COIN_VALUE = 1 -- coins given per pickup
local RESPAWN_TIME = 5 -- seconds until the coin comes back
local collected = false -- debounce: one pickup at a time
coin.Touched:Connect(function(otherPart)
if collected then
return
end
-- Was it a player's character that touched the coin?
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then
return
end
-- Find this player's Coins value inside leaderstats
local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins")
if not (coins and coins:IsA("IntValue")) then
return
end
collected = true
coins.Value += COIN_VALUE
-- Hide the coin, wait, then bring it back
coin.Transparency = 1
coin.CanTouch = false
task.wait(RESPAWN_TIME)
coin.Transparency = 0
coin.CanTouch = true
collected = false
end)
-- Script inside ServerScriptService (use INSTEAD of the first Leaderboard script)
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local coinStore = DataStoreService:GetDataStore("PlayerCoins")
Players.PlayerAdded:Connect(function(player: Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
-- Load saved coins. pcall catches errors if Roblox servers are busy
local success, savedCoins = pcall(function()
return coinStore:GetAsync("Player_" .. player.UserId)
end)
if success then
coins.Value = savedCoins or 0 -- nil means a brand-new player
player:SetAttribute("CoinsLoaded", true)
else
warn("Could not load coins for " .. player.Name)
end
end)
local function saveCoins(player: Player)
-- Never save if loading failed, or real coins could be replaced by 0
if not player:GetAttribute("CoinsLoaded") then
return
end
local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins")
if coins and coins:IsA("IntValue") then
local success, err = pcall(function()
coinStore:SetAsync("Player_" .. player.UserId, coins.Value)
end)
if not success then
warn("Could not save coins for " .. player.Name .. ": " .. tostring(err))
end
end
end
Players.PlayerRemoving:Connect(saveCoins)
-- If the server shuts down, save everyone who is still in the game
game:BindToClose(function()
for _, player in Players:GetPlayers() do
saveCoins(player)
end
end)
Not working? Common mistakes
Rename the folder to exactly leaderstats (all lowercase) and make sure the script is a Script in ServerScriptService.
Keep the collected debounce: set collected = true before adding coins and only reset it after the respawn wait.
Publish the game first, then enable Studio Access to API Services under File, Experience Settings, Security. Use a test copy rather than your live game.
Use one script to create one leaderstats folder and put both the Stage and Coins values inside it.
How to make a leaderboard in Roblox Studio: the leaderstats trick
Roblox already has a leaderboard built in: the player list in the top-right corner. To show your own stats in it, you do not draw any UI. That is the secret of how to make a leaderboard in Roblox Studio: give each player a Folder named exactly leaderstats, and Roblox adds a column for every value inside that folder.
The first script runs on the server in ServerScriptService. It listens to Players.PlayerAdded, which fires every time someone joins. For each player it creates the leaderstats Folder and an IntValue named Coins. An IntValue holds a whole number, which is perfect for coins, kills or stages.
The name of the value is the column title players see, so Coins shows up as Coins. Want more stats? Add another IntValue, for example Wins, to the same folder. Stats appear in the order you add them.
Remember the folder name is case-sensitive: Leaderstats or LeaderStats will not appear on the board.
Giving coins on touch with a Roblox coin script
A leaderboard is only fun if the numbers change. The coin script sits inside a coin part. When a player's character touches it, Players:GetPlayerFromCharacter turns the touching body part's parent into a Player. If it is not a player (a falling part, an NPC), the script stops.
Next the script looks inside that player's leaderstats for Coins and checks it really is an IntValue. Checks like this stop errors if a player touches a coin in the split second before their leaderstats exist.
Then comes the debounce. Touched fires many times while a foot rests on a coin, so the collected flag makes sure one coin gives exactly one reward. The coin turns invisible, CanTouch switches off, and after RESPAWN_TIME seconds it comes back.
Make the coin a gold Cylinder, turn CanCollide off so players run through it, and turn Anchored on. Duplicate it around your map and you have a collecting game. Combine it with a door that costs coins to open.
Saving coins with DataStoreService
The leaderstats values reset when a player leaves. The final part of how to make a leaderboard in Roblox Studio is saving: the third script uses DataStoreService, Roblox's cloud storage for your game.
- GetAsync loads coins when a player joins, using a key like Player_12345 built from their UserId.
- SetAsync saves coins when they leave, and BindToClose saves everyone if the server shuts down.
- Every DataStore call is wrapped in pcall. These are network calls that can fail, and pcall catches the error instead of crashing the script.
The CoinsLoaded attribute is an important safety net. If loading fails, the script does not save, so a temporary error can never overwrite a player's real coins with 0.
To test saving in Studio, publish the game, then open File, Experience Settings, Security and turn on Enable Studio Access to API Services. Roblox recommends doing this on a test copy, not on a live game with real players.
Next step: Roblox also offers Friends and Global leaderboard views powered by an ordered data store you register in Creator Hub. That feature is in beta.
Parent note: the first taste of real data
Learning how to make a leaderboard in Roblox Studio introduces ideas that professional programmers use every day. The leaderstats script shows how a server reacts to events (a player joining). The coin script shows validation (is this really a player? is this really an IntValue?). The DataStore script is your child's first contact with saving data in the cloud and error handling.
Error handling is the part many self-taught kids skip, because code usually works in Studio. Real games have thousands of players and busy servers, so the pcall pattern and the do-not-overwrite rule protect players' progress. Learning this early builds good habits.
Everything here is free to build and test. Data stores only store what the game saves, such as a coin number linked to a Roblox user ID.
Want your child to build full games like this?
Want your child to build full games like this? First 1-on-1 lesson free.
Coins, leaderboards and saving are the core of almost every popular Roblox game. In our 1-on-1 Zoom lessons, Vlad Pomazanets guides students aged 8–17 through building their own game economy: collectables, shops, upgrades and data that persists.
Each lesson is 60 minutes and the first one is free. After that it is CA$280 for 4 lessons, with a refund on unused lessons within 14 days. Lessons run in English, Ukrainian or Russian, and we will match a time in your time zone.
Book a free Roblox class or see the Roblox course overview.
Questions parents ask
Why is my leaderboard not showing in Roblox Studio?
The folder must be named leaderstats in all lowercase and it must be parented to the Player object, not the character. The script must be a Script in ServerScriptService. Check the Output window for errors and make sure the values are inside the folder.
Can I show more than one stat on the leaderboard?
Yes. Add more value objects to the same leaderstats folder, for example an IntValue named Wins or a StringValue named Rank. Each one becomes its own column. They appear in the order you add them, and you can also control order with an IsPrimary BoolValue.
Why do my coins not save between play sessions?
Leaderstats alone never save. Use the DataStore version, publish the game and turn on Enable Studio Access to API Services in Experience Settings, Security, to test in Studio. Also check the Output for warnings from the pcall about loading or saving.
Should coins be given by a Script or a LocalScript?
Always by a server Script. If a LocalScript changed coins, only that player's screen would change, the server would not know, and the value would never save. Keeping rewards on the server also makes it much harder for cheaters to give themselves coins.
What is pcall and why do DataStores need it?
pcall means protected call. It runs a function and catches any error instead of stopping your script. Data store calls travel over the internet to Roblox servers and can occasionally fail, so the Roblox docs recommend wrapping them in pcall and handling the failure.
Want your child to build full games like this?
Get a free first 1-on-1 Roblox lesson with Vlad: 60 minutes on Zoom for ages 8–17, in English, Ukrainian or Russian. We'll match a time in your time zone.
Book a free lessonBook a free lesson
No commitment. No payment. Just your child's first coding class.
5 / 5 · 1 review
“We were looking for coding classes for kids in Hamilton and a friend recommended Exclusive-IT. My 11-year-old started the Roblox course one-on-one and built his first real game in a few weeks. The mentor is patient, the lessons are in plain English, and my son actually looks forward to them. Highly recommend for any parent who wants their child to learn to code.”
Or message us directly
Tap a messenger — the chat opens with a ready greeting.
- +1 (289) 44-28-698
- excklusiveit@gmail.com
-
Working hours — Hamilton, Ontario (ET) Mon–Fri: 9:00–18:00 Sat–Sun: 8:00–16:00
- Online worldwide · classroom in Hamilton: 170 Parkdale Ave N, Hamilton, ON L8H 5X2