Global leaderboard with ProfileService?

I just switched the data system in my game to use ProfileService and I was wondering how I would use it for a global leaderboard, replacing what I had before using the default methods (:GetOrderedDataStore(), :GetSortedAsync(), :GetCurrentPage(), etc). I am new to ProfileService so my understanding isn’t great yet so if this is a dumb question I’m sorry.

Hey @R_alatch , did you end up figuring out how to use ProfileService for your global leaderboard?

I don’t know. Maybe he solved it

Hopefully he can share his solution.

Good tutorial to look at about it : Global Updates: ProfileService Tutorial Part 2 (Roblox Studio) - YouTube

1 Like

Thank you, I managed to work it out.

Sorry for the bump, but may I know how you solved it? I watched the video but couldn’t come to a solution.

Apologies for the late response, hopefully this is still useful to you.

First of all this is the leaderboard model containing the script I used when I figured out this particular solution. Global Leaderboard Explained - Roblox

What I did first was create an object data profile in my DataManager (the module that does stuff with ProfileService). I convert the players profile data table to an object data table using this module:


local Module = {}

Module.Types = {
	['boolean'] = 'BoolValue',
	['string'] = 'StringValue',
	['number'] = 'IntValue'
}

function Module.TableToObject(Tbl, Prnt, Nst)
	Nst = (Nst or 1)
	if Nst > 30 then return end
	for k,v in pairs(Tbl) do
		if typeof(v) == 'table' then
			local Fold = Instance.new('Folder')
			Fold.Name = tostring(k)
			Module.TableToObject(v, Fold, Nst + 1)
			Fold.Parent = Prnt
		else
			local val = Instance.new(Module.Types[typeof(v)] or Module.Types['string'])
			val.Name = tostring(k)
			val.Value = v
			val.Parent = Prnt
		end
	end
end

function Module.ObjectToTable(Prnt, Tbl)
	Tbl = Tbl or {}
	for _,val in pairs(Prnt:GetChildren()) do
		if val:IsA('Folder') then
			Tbl[val.Name] = Module.ObjectToTable(val, {})
		else
			Tbl[val.Name] = val.Value
		end
	end
	return Tbl
end

return Module

So in your data manager, when you’ve retrieved a users profile (upon entering the game) you can create a tangible copy to refer to later in your leaderboard script.

And here’s how you’d want to create your object table:

local DataFolder = Instance.new("Folder")
DataFolder.Name = FolderName
ObjectTable.TableToObject(profile.Data, DataFolder)
DataFolder.Parent = player

You must also include this loop which updates the object values as the ProfileService data dynamically changes:

task.spawn(function()
	while true do
		local profile = Profiles[player]

		if profile ~= nil then
			player[FolderName].Cash.Value = profile.Data.Cash
			player[FolderName].Gems.Value = profile.Data.Gems
            -- etc
		else
			break
		end

		task.wait(0.1)
	end
end)

Now that’s all set up. In the leaderboard script you’re going to wanna refer to the object value from the players profile you just created when you fire :UpdateAsync().

I’m going to assume you know how to work your way around the leaderboard script but let me know if you still need help.

12 Likes

I haven’t tried this, but, my friend came up with an idea possibly similar to this (?). The idea was to save player’s data to a separate DataStore every 1-3 minutes, and then load the leaderboards from that. His solution worked like a charm.

1 Like

I would recommend using my suggested method above rather than your friends idea. Only because the data is dynamically updating, and does not need to redundantly save player data once again which saves you from sending more DataStore requests as well.

There may also be issues presented with your leaderboard if you haven’t made sure the data is handled reliably. What I mean by this is since you’re only saving every 1 - 3 minutes, if players were to leave your game in-between an autosave, it would most likely cause a variance with the leaderboard results and the players actual data.

Although if you believe you shouldn’t fix what’s not broken, then I’m glad to hear you’ve found a solution!

Good luck!

Alright so, from looking at your solution, I don’t understand how it would possibly work? Honestly, it looks more like a server leaderboard than a global leaderboard, since you’re just updating object values inside the local server, not any DataStore for sharing it across.

It is indeed global. If you take a look inside the leaderboard model I shared above, it contains the leaderboard script which includes the DataStore stuff.

I’m on mobile currently, could you send me the code over here?

Does it work globally or Server only?

Globally.

Extra text to meet word count

1 Like

Awesome, but can you go into details when sending updates and handle it?

Marvelous!. Great explanation! very easy to implement. but above all thanks for the module that converts the tables!

even if you have the stats in folder inside the player , how is that going to let you make a global leaderboard ? what if not all players are in the game right now ? i didn’t see your logic yet. explain thank you .