I am trying to make Global leaderstats in a Screen GUI though I do not know how to do that. I have looked through several tutorials but they did not work for me.
Well,
You can make a gui, when done designing, add a ui grid layout i believe, and then loop through every player in the game and make a label for everything inside the leaderstats folder, do that for 1 player.
When thats done you wanna make a table for every stat, so local stats = {}
and then throw every player in there with theyre stats.
To get the stats we can use this script:"
local players = game:GetService("Players")
local localplr = players.LocalPlayer
local updateFrequentie = 1
local plrsFrame = script.Parent.Players
local title = plrsFrame.Parent.Title
local statS = {}
local function updateStats()
for _, plr in players:GetPlayers() do
for _, folder in plr:GetChildren() do
if folder and folder.Name == "leaderstats" then
for _, stat in folder:GetChildren() do
statS[plr] = folder:GetChildren()
local amount = #folder:GetChildren()
for i = 1, amount do
if folder:GetChildren()[i]:IsA("IntValue") or folder:GetChildren()[i]:IsA("NumberValue") then
statS[plr][i] = {
Name = folder:GetChildren()[i];
Value = folder:GetChildren()[i].Value;
}
end
end
end
end
end
end
end
while task.wait(updateFrequentie) do
updateStats()
print(statS)
end
Basically what it does it loops through every singe item in the leaderstats folder of each individual player. Then we will store that in a table.
I’m not too sure what you’re asking, can you provide a bit more information? For now, I’ll do my best with my interpretation.
You talked about a “global leaderboard”. Do you mean a leaderboard across all servers?
Anyway for displaying stats in a GUI you can have a TextLabel with the following:
local player = game:GetService("Players").LocalPlayer
local value = --[[path to your leaderstat value here]]
local label = script.Parent
label.Text = value.." Some Suffix"
local function update()
label.Text = value.." Some Suffix"
end
value:GetPropertyChangedSignal("Value"):Connect(update)
For a global leaderboard, you need an OrderedDataStore.
Write to this store whenever player’s data is saved
Update at a certain interval using OrderedDataStore:GetSortedAsync()
Use a RemoteEvent to send this data to each client so they can display it
If it’s local to the server, you can do something like:
local players = game:GetService("Players")
local function update()
local raw = players:GetPlayers()
local sortedPlayers = table.sort(raw, function(a, b)
return a.leaderstats.Something.Value > b.leaderstats.Something.Value
end)
--pass data to clients as appropriate
end
while task.wait(120) do update() end --update every 2 mins
just wondering why you called GetChildren() so much, wouldn’t it be better on memory to just call it once and refer to that table of children?
You didn’t. I was replying to @Hyruledude992 . Only the bottom hidden part was my reply to you.
But the OP mentioned a global leaderboard idk what they need, its confusing
So for that I’d recommend saving stats to an OrderedDataStore like I said above. Save player stats to it (using SetAsync as leaderboards only need to mimic data) when other data saving takes place. Then, you can load it in a seperate script.
local players = game:GetService("Players")
local store = game:GetService("DataStoreService"):GetOrderedDataStore("StoreNameGoesHere")
--then, to update...
local success, pages = pcall(
store.GetSortedAsync, --the method to call
store, --this method is normally called with colon notation. We must pass it manually because we are using dot notation.
false, --ascending
100 --page size
)
if not success then --failed to fetch data, pages will be set to the error message but it is unlikely to fail
warn(pages)
return nil
end
local page = pages:GetCurrentPage() --the first page of data (the top one)
for rank, entry in next, page, nil do --iterate over the page
local raw = page[rank] --we need this to read other data
--example where key is player's UserId
local data = entry.value --data entered
local userId = raw.key --key used to save
local success, name = pcall(players.GetNameFromUserIdAsync, players, userId)
if not success then continue end
print(`Player @{name} has a data entry of {data}! They are at rank {rank} in the leaderboard.`)
end
I dunno why but it isn’t printing anything. What data is it looking for? Because there is quite a lot of different data and I just need 2; Level and Blocks. (Well, the rank too)
Yes. That is because an OrderedDataStore can only accept one number for the value to be saved. You might need 2 leaderboards because of this. Using a normal DataStore will not work for the leaderboard, or will work at an incredibly inefficient rate, impacting the rest of your game.
Like I said, this should be added to data saving and should not substitute it. For example:
--save player's data
local success, result = pcall(dataStore.UpdateAsync, dataStore, key, function(oldData)
--checks and stuff go here
return newData
end)
--now save the leaderboard data
local success2, result2 = pcall(leaderboard.SetAsync, leaderboard, player.UserId, player.Data.Blocks.Value)