How to make a simple global leaderboard

Joins is just an example. All you would have to do increase their player points every minute, or pull it from a different source such as a value object.

5 Likes

@ThatTimothy Awesome tutorial! It helped me a lot. I have one question though. If I want it to update the leaderboard more frequently, how do I do that? So the leaderboard updates by it’s self without having to rejoin. Thanks.

3 Likes

The leaderboard by default updates every two minutes, or 120 seconds. You can simply change that value in the wait in the while loop, i.e. wait(90) instead. The first update is delayed by 10 seconds for the purpose of being able to easily test it (otherwise you’d have to wait two minutes).

However, do to Roblox OrderedDataStore limits, doing it more often will limit the amount of leaderboards you can have. More information

6 Likes

Thanks for the help, if I want to remove someone from the leaderboard for exploiting, is that possible?

2 Likes

Just set their data to 0, or :RemoveAsync it. OrderedDataStores can be used the same way as regular ones. Just make sure you reset their actual data as well as their leaderboard data (if they are seperate).

5 Likes

Sorry for the amount of questions I ask, does something in the code prevent it from working in games that are paid access? For some reason the leaderboard didn’t work for me on a paid access game.

2 Likes

No, it functions as is. You can have a look at the working place if you’re having trouble.

3 Likes

Theres a Weird Bug happening with My leaderboard it was acting Normal but now its getting more and more streched and i took it out again and it was all scrunched together on one side and the actual image was still were it was can someone pls tell me how to fix this bug ive tryed everything and nothins working… :confused: https://gyazo.com/e556b0d83a46a1d9f78ebad8f2c82f09 and https://gyazo.com/539a0bb89160a71aaf6b11121cc15c18 pls help thx!

1 Like

This is because you changed the scale of the Sample folder. It must use a y offset, not scale for size, as scrolling frames consider scale as the full frame.

You can also reference the template to see what is wrong.

4 Likes

Trying to connect it to display my kill points but failing so badly.

1 Like

https://gyazo.com/a30623e4e05a477d9c07f2f5f872ca18 I added two Leaderboards and the Coins is showing up on both… I changed there values but its still doing this… https://gyazo.com/5d05fdcebbf2f64be7fcc593127249c5 local sg = script.Parent --Surface GUI local sample = script:WaitForChild("SampleW") --Our Sample frame local sf = sg:WaitForChild("ScrollingFrameW") --The scrolling frame local ui = sf:WaitForChild("UIw") --The UI list layout I also changed the Value name as well…

2 Likes

also is there a way i can reset the Leaderboard because there was a problem with the Datastore script and everyone lost there data but it still shows on the leaderboard but if they join itll update im wondering if theres a way to reset the leaderboard or if the problem will slowly solve itself…?

1 Like

You can only use player points for storing one value, which is why it’s recommended to have your own custom data stores to store the data and then use that data to update the leaderboards.

You can’t reset data easily, but you can pull it from different scope. For example, :GetDataStore(“Test”) instead of :GetDataStore(“Broken”).

How would you make a global leaderboard appear as a frame when you press a screen button?

You’d have to send the data from the server to the client when the leaderboard updates, using remote events. Then the client would display said information in the same way you do from the server, just onto a different frame instead.

1 Like

Hello how would you make the leaderboard display lowest gold first?

I am using the model+Script black version.

1 Like

This is discussed in the FAQ section, please read that before asking a question.

The gist of it is you have to pull a value from somewhere (gold). Then by saving it, you can sort the saved data.

As for making the lowest value appear first, that can be done at the settings above where the GetSortedSsync request is made.

3 Likes

Thank for the information.
Have found what I was looking for.

Thanks for taking the time to create this tutorial.

Cheers

3 Likes

Hi! Thank you for the tutorial!

I encountered a problem with the leaderboards.

I did one leaderboard first. Exactly as you specified, and everything worked great. After I did the first one (for the rebirths) I duplicated it, changed the names and in the scripts I changed the Datastore names (“Leaderboard1” and “Leaderboard2”). After a little while I decided to change the sample too (the text color) as it was hard to read.

But now, only the first leaderboard works and has the old sample (old text color) and the second one is an old version of the first leaderboard (second leaderboard never worked). I made sure that variables that are to be shown exist where I refference them and that the names of the leaderboards are changed. (Both in the explorer and the Datastore name).

The values shown are loaded into the game through DS2 in a script in ServerScriptService.

I don’t know if the different color is a problem as I saw that the first 3 people have different colors.

Images:

image

  • Leaderboards in explorer:

image

image

  • roughly the new sample (both look the same, but are named differently for each)

image

  • code for first one
local sg = script.Parent
local sample = script:WaitForChild("Sample1") --Our Sample frame
local sf = sg:WaitForChild("ScrollingFrame") --The scrolling frame
local ui = sf:WaitForChild("UI") --The UI list layout

local dataStoreService = game:GetService("DataStoreService")
--The data store service
local dataStore = dataStoreService:GetOrderedDataStore("Leaderboard1")
--Get the data store with key "Leaderboard"

wait(10)
while true do
   for i,plr in pairs(game.Players:GetChildren()) do--Loop through players
   	if plr.UserId>0 then--Prevent errors
   		local ps = game:GetService("PointsService")--PointsService
   		local w = plr.Rebirth.Value--Get point balance
   		if w then
   			pcall(function()
   				--Wrap in a pcall so if Roblox is down, it won't error and break.
   				dataStore:UpdateAsync(plr.UserId,function(oldVal)
   					--Set new value
   					return tonumber(w)
   				end)
   			end)
   		end
   	end
   end    
   local smallestFirst = false--false = 2 before 1, true = 1 before 2
   local numberToShow = 100--Any number between 1-100, how many will be shown
   local minValue = 1--Any numbers lower than this will be excluded
   local maxValue = 10e30--(10^30), any numbers higher than this will be excluded
   local pages = dataStore:GetSortedAsync(smallestFirst, numberToShow, minValue, maxValue)
   --Get data
   local top = pages:GetCurrentPage()--Get the first page
   local data = {}--Store new data
   for a,b in ipairs(top) do--Loop through data
   	local userid = b.key--User id
   	local points = b.value--Points
   	local username = "[Failed To Load]"--If it fails, we let them know
   	local s,e = pcall(function()
   		username = game.Players:GetNameFromUserIdAsync(userid)--Get username
   	end)
   	if not s then--Something went wrong
   		warn("Error getting name for "..userid..". Error: "..e)
   	end
   	local image = game.Players:GetUserThumbnailAsync(userid, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
   	--Make a image of them
   	table.insert(data,{username,points,image})--Put new data in new table
   end
   ui.Parent = script
   sf:ClearAllChildren()--Remove old frames
   ui.Parent = sf
   for number,d in pairs(data) do--Loop through our new data
   	local name = d[1]
   	local val = d[2]
   	local image = d[3]
   	local color = Color3.new(1,1,1)--Default color
   	if number == 1 then
   		color = Color3.new(1,1,0)--1st place color
   	elseif number == 2 then
   		color = Color3.new(0.9,0.9,0.9)--2nd place color
   	elseif number == 3 then
   		color = Color3.fromRGB(166, 112, 0)--3rd place color
   	end
   	local new = sample:Clone()--Make a clone of the sample frame
   	new.Name = name--Set name for better recognition and debugging
   	new.LayoutOrder = number--UIListLayout uses this to sort in the correct order
   	new.Image.Image = image--Set the image
   	new.Image.Place.Text = number--Set the place
   	new.Image.Place.TextColor3 = color--Set the place color (Gold = 1st)
   	new.PName.Text = name--Set the username
   	new.Value.Text = val--Set the amount of points
   	new.Value.TextColor3 = color--Set the place color (Gold = 1st)
   	new.PName.TextColor3 = color--Set the place color (Gold = 1st)
   	new.Parent = sf--Parent to scrolling frame
   end
   wait()
   sf.CanvasSize = UDim2.new(0,0,0,ui.AbsoluteContentSize.Y)
   --Give enough room for the frames to sit in
   wait(120)
end
  • code for second one
local sg = script.Parent
local sample = script:WaitForChild("Sample2") --Our Sample frame
local sf = sg:WaitForChild("ScrollingFrame") --The scrolling frame
local ui = sf:WaitForChild("UI") --The UI list layout

local dataStoreService = game:GetService("DataStoreService")
--The data store service
local dataStore = dataStoreService:GetOrderedDataStore("Leaderboard2")
--Get the data store with key "Leaderboard"

wait(10)
while true do
   for i,plr in pairs(game.Players:GetChildren()) do--Loop through players
   	if plr.UserId>0 then--Prevent errors
   		local w = plr.TotalCash.Value --Get point balance
   		if w then
   			pcall(function()
   				--Wrap in a pcall so if Roblox is down, it won't error and break.
   				dataStore:UpdateAsync(plr.UserId,function(oldVal)
   					--Set new value
   					return tonumber(w)
   				end)
   			end)
   		end
   	end
   end    
   local smallestFirst = false--false = 2 before 1, true = 1 before 2
   local numberToShow = 100--Any number between 1-100, how many will be shown
   local minValue = 1--Any numbers lower than this will be excluded
   local maxValue = 10e30--(10^30), any numbers higher than this will be excluded
   local pages = dataStore:GetSortedAsync(smallestFirst, numberToShow, minValue, maxValue)
   --Get data
   local top = pages:GetCurrentPage()--Get the first page
   local data = {}--Store new data
   for a,b in ipairs(top) do--Loop through data
   	local userid = b.key--User id
   	local points = b.value--Points
   	local username = "[Failed To Load]"--If it fails, we let them know
   	local s,e = pcall(function()
   		username = game.Players:GetNameFromUserIdAsync(userid)--Get username
   	end)
   	if not s then--Something went wrong
   		warn("Error getting name for "..userid..". Error: "..e)
   	end
   	local image = game.Players:GetUserThumbnailAsync(userid, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
   	--Make a image of them
   	table.insert(data,{username,points,image})--Put new data in new table
   end
   ui.Parent = script
   sf:ClearAllChildren()--Remove old frames
   ui.Parent = sf
   for number,d in pairs(data) do--Loop through our new data
   	local name = d[1]
   	local val = d[2]
   	local image = d[3]
   	local color = Color3.new(1,1,1)--Default color
   	if number == 1 then
   		color = Color3.new(1,1,0)--1st place color
   	elseif number == 2 then
   		color = Color3.new(0.9,0.9,0.9)--2nd place color
   	elseif number == 3 then
   		color = Color3.fromRGB(166, 112, 0)--3rd place color
   	end
   	local new = sample:Clone()--Make a clone of the sample frame
   	new.Name = name--Set name for better recognition and debugging
   	new.LayoutOrder = number--UIListLayout uses this to sort in the correct order
   	new.Image.Image = image--Set the image
   	new.Image.Place.Text = number--Set the place
   	new.Image.Place.TextColor3 = color--Set the place color (Gold = 1st)
   	new.PName.Text = name--Set the username
   	new.Value.Text = val--Set the amount of points
   	new.Value.TextColor3 = color--Set the place color (Gold = 1st)
   	new.PName.TextColor3 = color--Set the place color (Gold = 1st)
   	new.Parent = sf--Parent to scrolling frame
   end
   wait()
   sf.CanvasSize = UDim2.new(0,0,0,ui.AbsoluteContentSize.Y)
   --Give enough room for the frames to sit in
   wait(120)
end
1 Like

Ok, so someone helped me out in the end with this:))

I was unaware that you can’t store double variables in a datastore.

Changes I made that made this work:

  • instead of the line:
local w = plr.TotalCash.Value --Get point balance

I put:

local w = math.floor(plr.TotalCash.Value) --it just rounds the value
3 Likes