@ThatTimothy Do you have any idea on how I can achieve something similar to the circled part of this leaderboard?
It’s just different ui styling. If the position is equal to 1, then use a different sample frame. This can be customized however you want, with different layouts like the one above.
Since my leaderstat value is a decimal, how would I make it work with that? Will it work the same if I use :GetDataStore instead of :GetOrderedDataStore?
OrderedDataStores
only accept integers, which means that you would need to use math.floor
or math.ceil
(documentation for that can be found here) in order to convert the decimal into a whole number.
You wouldn’t be able to use :GetDataStore
for this kind of leaderboard because the values are not sorted in regular DataStores
.
I tried them both but the value on the leaderboard is still nil.
(Error)
Could you provide the code you’re using?
The OrderedDataStore can only store numerical integers, so you need to make sure you’re saving valid values.
Several solutions:
local someValue = 931.3819199293
--Just make it an integer
math.floor(someValue) --> 931
local someValue = 931.3819199293
--Store a certain number of decimal places:
local storedValue = math.floor( someValue * 1000 ) --> 931381
--And then convert is back when displaying:
storedValue / 1000 --> 931.381
Thanks very useful it helps a lot of new developers like me
How do I make it so that it shows people who are not in the server?
That’s the entire point of it being a global leaderboard. Please explain what you mean?
Ignore what I wrote I just realised how it works lol sorry for bothering you.
I realized that the issue I was having was with
I printed b.Value and it came as nil.
How do I make it the actual value?
Whole script
local sg = script.Parent
local sample = script:WaitForChild("Sample")
local sf = sg:WaitForChild("ScrollingFrame")
local ui = sf:WaitForChild("UI")
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetOrderedDataStore("Leaderboard")
wait(5)
while true do
for i,plr in pairs(game.Players:GetPlayers()) do
if plr.UserId>0 then
local w = plr.leaderstats.Highscore.Value
if w then
pcall(function()
dataStore:UpdateAsync(plr.UserId,function(oldVal)
return tonumber(w)
end)
end)
end
end
end
local smallestFirst = false
local numberToShow = 10
local minValue = 1
local maxValue = 10e30
local pages = dataStore:GetSortedAsync(smallestFirst, numberToShow, minValue, maxValue)
local top = pages:GetCurrentPage()
local data = {}
for a,b in ipairs(top) do
local userid = b.key
local highscore = b.value
local username = "[Failed To Load]"
local s,e = pcall(function()
username = game.Players:GetNameFromUserIdAsync(userid)
end)
if not s then
warn("Error getting name for "..userid..". Error: "..e)
end
local image = game.Players:GetUserThumbnailAsync(userid, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
table.insert(data,{username,highscore,image})
end
ui.Parent = script
sf:ClearAllChildren()
ui.Parent = sf
for number,d in pairs(data) do
local name = d[1]
local val = d[2]
local image = d[3]
local color = Color3.new(1,1,1)
if number == 1 then
color = Color3.new(1,1,0)
elseif number == 2 then
color = Color3.new(0.9,0.9,0.9)
elseif number == 3 then
color = Color3.fromRGB(166, 112, 0)
end
local new = sample:Clone()
new.Name = name
new.LayoutOrder = number
new.Image.Image = image
new.Image.Place.Text = number
new.Image.Place.TextColor3 = color
new.PName.Text = name
new.Value.Text = val
new.Value.TextColor3 = color
new.PName.TextColor3 = color
new.Parent = sf
end
wait()
sf.CanvasSize = UDim2.new(0,0,0,ui.AbsoluteContentSize.Y)
wait(120)
end
That’s weird. b.value
should never be nil, regardless if data is stored are not. Make sure you are using b.value
and not b.Value
.
Could you show the code you’re using to print the value?
In your example,
isn’t
The same as 931*1000 (= 931000)
How is it
?
Lol I was using b.Value it worked when I changed it.
I have another question, will it work the same if I change the wait(120)
to:
for i = 120,1,-1 do
updateTimer.Text = "Updating in "..i.." seconds"
wait(1)
end
Just so it tells the player when it will update?
Yes, as long as the total wait is long enough. Experiment around with it, depending on the game lower intervals can work. However, I tend to suggest keeping it above 2 minutes because saving a player’s data should be more important than updating the leaderboard.
I clarified the example to make it clearer, there are two solutions, one which just floors the value, and one which saves a few decimal places by storing the decimal places as an integer. The original example didn’t have a separation between the two, which I can see why that would be confusing.
I have another problem. @ThatTimothy
It displays the info of the top 3 people but after that it only shows the image of the other players and nothing else.
local sg = script.Parent --Surface GUI
local sample = script:WaitForChild(“Sample”) --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("TotalTime")
--Get the data store with key "Leaderboard"
--Want to make different leaderboards?
--Change this key to a different string ("Leaderboard2", ect.), and you can have multiple leaderboards!
wait(5)
while true do
--will add wait(120) at the end
--loop that runs every 2 minutes
for i,plr in pairs(game.Players:GetChildren()) do--Loop through players
if plr.UserId>0 then--Prevent errors
local w = plr.leaderstats["Time Played"].Value
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(.8,.6,0)--1st place color
elseif number == 2 then
color = Color3.new(0.7,0.8,0.6)--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--End the while loop
Here is the script.
If you’re using the same code, you have to update it if you change the hierarchy of your text labels. Make sure you check the output for more information, as there likely is an error.
For an example of how you should setup the ui, see the OP. There is also a download and demo for more information.
Are you talking about the variables?
the error is occurring here?
If you’ve changed the layout of the ui elements, then you have to modify the code to compensate for it.
If you dont understand what that means, you’ll want to use the copy provided in the demo that works and modify it from there.
If the text isn’t displaying, it’s either the same color as the background, or the script is referencing the wrong items. If it’s the later, you should see errors in your ouput.
I can’t help you much more with just an image. I’d need to know your object hierarchy as well.