How to get player's rank in Ordered Datastore leaderboard?

Hey guys, working with ordered datastores. Now, I understand how to fetch the top ten of an ordered datastore using getsortedasync() - but how do I get the actual rank of a player that’s far down the list? If a player’s rank was 535, would I have to loop through all of the pages to find where they sit or is there another, quicker way?

just loop through the data so like

for i, player in ipairs(data) do
      -- code
end

in this for loop i is the rank of the player as the data is in order

Well, I understand that can be done, but won’t that get laggy once there’s thousands of players in the leaderboard?

as long as you include a wait() in it, it should be fine because the laggy part is doing a lot at once. Also the thing that slows down a leaderboard the most is doing :GetPlayerNameFromUserIdAsync so a wait() shouldn’t be needed. i got 11 leaderboards with 100 players and there’s no lag at all

Again, with enough players that would just make the leader boards take an extremely long time.

This is actually for a game that used to use that method, but started running into lag because of lots of players (likely over 100k).

But still, it’s pretty important to show what rank the player sits at. So - are there any other methods around this that you know of?

As i said the thing that makes it the slowest is not the player count it is the code inside the loop that does it making a wait statement tells the program to pause for a very short time allowing the data it has processed to be shown and then continue making it less laggy

Also this is a part of a script i use and there’s no lag at all

local success, errorMsg = pcall(function()

			local data = statODS:GetSortedAsync(false,Max_Players)
			local statsPage = data:GetCurrentPage()

			for rankInLb, datastored in ipairs(statsPage) do

				local name = game.Players:GetNameFromUserIdAsync(tonumber(datastored.key))
				local stat = datastored.value

				local clone = mainFrame.Cloned:Clone()

				clone.Name = name .. "Leaderboard"
				clone.Player_Name.text.Text = name
				clone.Number.text.Text = "#" .. rankInLb
				clone.Stat_Value.text.Text = mod.short(mod.sub(mod.lbdecode(stat), {1,0,2}))
				clone.Parent = mainFrame.Folder
				clone.Visible = true
			end
		end)

Also what excatly do you need so many players to show on a leaderboard if it is too slow for you then why not lower the max player count?

I understand how a loop works.

If you are looping through a table with 100k+ keys(players) inside of it, you need to do 100k+ loops. I can add waits, but this means over time the leaderboards will take longer and longer to work, and it isn’t a future-proof solution.

It isn’t that I’m showing all of those players on a leaderboard, it’s that I show the top ten, and then also want to show the rank of the player who is viewing the leaderboard. The question is about retrieving the rank of that player without looping through every player’s data.

I’m assuming that using the minValue/maxValue on getsortedasync might be a way to get at this.

2 Likes

but why do you need a leaderboard that can show 100k players it doesn’t need to show 100k players as that would just be bad

I’m not showing 100k+ players. That’s just the amount of data I would have to sort through in order to find the one player’s rank.

The leaderboard itself only shows 10 players, and then the user that is looking at the leaderboard.

1 Like

but it is not how much data you get you get the amount of players you give the function so you give it 10 and it returns 10 players data

This is a misleading example, as well as incorrect. GetNameFromUserIdAsync most definitely runs slowly as it makes a network call (which should also be wrapped in a pcall). OP is asking how to get a player’s rank out of hundreds of thousands of players, not the top hundred or so.

Right now, there’s not much that can be done about it. The only real way to make this work is to have an external server automatically sort the stat you’re trying to find the player’s rank for. You can then make an HTTP request to that server for a specific player ID. Maybe this will change with the data store API updates Roblox is making.

5 Likes

Thank you! That’s all I wanted haha.

Still, I wonder if there’s a certain algorithm I could use to search through the pages more efficiently.

Something like jumping x pages ahead based on how the values on the page you’re at compare to your player’s value.

Sounds like a whole lot of network throttling to achieve that though.

2 Likes

how would i detect if a player in the top 10 list moves down, or another one goes up