Global Leaderstats in a Player's GUI

Hello developers,

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.

Thanks a lot if anyone is able to help me.

Explorer:
image
(Ignore the red, not important)

1 Like

you want to make a custom one or just the default one?

Custom, forgot to mention but global leaderboard.

Btw I absolutely do not know how to do it.

Hello? May you respond? It has been 3 days…

What have you tried so far? [ char ]

I have tried the tutorial in the link below but it hasn’t worked at all.

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?

When did i state anything ab a “global leaderboard”? I dont understand you want. Do you want this:
image
but custom?

I took the get children() into account and made it a variable instead.
local children = folder:GetChildren()

What my code prints:
image

This means that we can now create labels.

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

Sorry for not responding, I fell asleep.

Anyways, with custom I mean this.

image

Like the top 100 players of the entire game.

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

Gave me this error:

Yep, that’s on me. I got the parameter order wrong because I did it from memory. I’ve updated my post. Sorry!

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)

Did you save the data to the OrderedDataStore? Any data entered into an OrderedDataStore must be a number.

Nope, just regular DataStore, never worked with OrderedDataStore before. Gonna make a DataStore for the leaderboard real quick

I attempted to make an OrderedDataStore but it did not work as it gave me the following error:

Script:
image

image

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)