Hey devs,
We all probably know how to make a leaderboard. You use a sorted Datastore etc.
Problem for me is that when I want many leaderboards I would also need many sorted datastores, which is not good. My question: how to make a global leaderboard for any value you want to display on a leaderboard?
The script should basically save every value in ONE datastore. Is this somehow possible?
My current attempt:
I am basically putting every value in one big table. BUUt it does not quite work yet
local StatsPaths = {
Wins = "leaderstats.Wins",
HighestStage = "Challenges.HighestStage",
SpeedrunFolder = "ChallengesFolder",
}
local MaxItems = 100
local MinValueDisplay = 1
local MaxValueDisplay = 10e15
local UpdateEvery = 120
local DataStoreService = game:GetService("DataStoreService")
-- Function to retrieve all stats for a player and combine them into one table
local function GetPlayerStats(Player)
local playerStats = {}
-- Retrieve all stats for the player (Wins, HighestStage, Speedrun, etc.)
for StatName, StatPath in pairs(StatsPaths) do
local statValue = Player:FindFirstChild(StatPath)
if statValue and not statValue:IsA("Folder") then
playerStats[StatName] = statValue.Value
else
playerStats[StatName] = 0 -- Default value if stat doesn't exist
end
end
-- Add Speedrun stats if it's a folder
if StatsPaths.SpeedrunFolder then
local SpeedrunFolder = game:WaitForChild(StatsPaths.SpeedrunFolder)
for _, stat in pairs(SpeedrunFolder:GetChildren()) do
if stat:IsA("NumberValue") then
playerStats[stat.Name] = stat.Value -- Add each Speedrun stat to the table
end
end
end
return playerStats
end
-- Function to get leaderboard items dynamically based on stat type
local function GetItems()
local allStats = {}
-- Retrieve all players' stats and combine them into a table
for _, player in pairs(game.Players:GetPlayers()) do
local playerStats = GetPlayerStats(player)
local combinedScore = 0 -- The combined score that you want to use for sorting
-- Calculate the combined score by adding up all stats (you could apply weights here)
for StatName, statValue in pairs(playerStats) do
combinedScore = combinedScore + statValue
end
-- Store the combined score with UserId as key, and also store the player's stats
table.insert(allStats, {UserId = player.UserId, Score = combinedScore, Stats = playerStats})
end
-- Sort players by combined score (descending order)
table.sort(allStats, function(a, b)
return a.Score > b.Score
end)
-- Print the leaderboard data for testing
for i, data in ipairs(allStats) do
local UserId = data.UserId
local Score = data.Score
local Stats = data.Stats
print("Rank:", i)
print("UserId:", UserId)
print("Score:", Score)
for statName, statValue in pairs(Stats) do
print(statName .. ": " .. statValue)
end
end
end
-- Function to update the leaderboard every 2 minutes
local function UpdateLeaderboards()
-- Retrieve and display the leaderboard items
GetItems() -- This will print the leaderboard data to the output
end
-- Periodically update the leaderboard
while true do
-- Update leaderboard for all stats
UpdateLeaderboards()
-- Wait for the next update cycle
task.wait(UpdateEvery)
end
This is the stuff I want to save: (SpeedrunFolder being a Folder x values in it)
local StatsPaths = {
Wins = "leaderstats.Wins",
HighestStage = "Challenges.HighestStage",
SpeedrunFolder = "ChallengesFolder",
}
I would then (after the GetItems() function got all the items in the table) SOMEHOW sort everything. Problem here is that I do not know what in this big sorted table belongs to which leaderboard…
Any help appreciated!