Hello Devforum, I need help creating a global leaderboard without the use of an ordered datastore.
I do not know if I should convert to an ordered datastore just for this as my game saves other things besides just leaderstats as well. What should I do from here?
Thanks.
One option is to calculate the leaderboard on demand. This means fetching all the necessary data from your normal datastore, sorting it based on the leaderboard criteria, and returning the results whenever a leaderboard request is made. While this method may be slower than using an ordered datastore, it eliminates the need for additional data storage. Another approach is to implement caching. You can store the leaderboard results temporarily in a cache and update it whenever a player’s stats change or when a new player joins. By serving leaderboard requests from the cache, you can reduce the frequency of calculations. However you’ll need to handle cache invalidation and updates accurately to keep the leaderboard up to date
Alternatively, you can create a separate data structure alongside your normal datastore. This structure can be optimized for leaderboard operations, such as a sorted list or a binary heap. Whenever a player’s stats change, you update this separate data structure accordingly. While this approach requires additional storage and maintenance, it can provide efficient leaderboard calculations without converting your entire datastore Xx
I tried using ordered datastores and got very confused. I attempted to follow this tutorial here. https://devforum.roblox.com/t/how-to-make-a-simple-global-leaderboard/256754
I tried editing the script to fit what i need but it seems to have not worked. I am completely lost here and have no clue what to do as this is not erroring.
local sg = script.Parent
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("SadRockLeaderboardData")
local mainData = dataStoreService:GetDataStore("GameData")
--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 sdaroc = plr.leaderstats.SadRocks.Value --Get point balance
if sdaroc then
pcall(function()
--Wrap in a pcall so if Roblox is down, it won't error and break.
dataStore:UpdateAsync(plr.UserId,plr.leaderstats.SadRocks.Value) --Set new value 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 = 10 --(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 sadrocks = 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
--Make a image of them
table.insert(data,{username,sadrocks})--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 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.Player = name--Set name for better recognition and debugging
new.LayoutOrder = number--UIListLayout uses this to sort in the correct order
new.Rank.Text = number--Set the place
new.Rank.TextColor3 = color--Set the place color (Gold = 1st)
new.Player.Text = name--Set the username
new.amt.Text = val--Set the amount of points
new.amt.TextColor3 = color--Set the place color (Gold = 1st)
new.Player.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(20)
end
(i did not understand how to link the two datastores either in order to get the “sadrocks” value.)
It is also not even going onto the leaderboard either.
There are a few issues and missing parts in the code that could be causing problems. You mentioned that you’re unsure how to link the two datastores to get the “SadRocks” value. To link the two datastores, you’ll need to fetch the player’s “SadRocks” value from the main datastore and update it in the ordered datastore X
Thank you! I never worked with ordered datastores so I just read some of the documentation and just made the solution of getting the players leaderstat value whenever they are in game.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.