How should i fix my leaderboard filtering? (Use Brackets)

We currently have an issue with our leaderboard where i believe there might be 2 root causes

  • table.sort() isn’t working on brackets
  • brackets gets reclasseds automatically when getting the stat


image

local function ActualiseLevelleaderboard()
	local store = DataStoreServ:GetDataStore("LevelLeaderboard")

	-- Destroy others frames
	for _, frame in LevelLeaderboard.SurfaceGui.Background:GetChildren() do
		if frame:IsA("Frame") and frame.Name ~= "Loading" then
			frame:Destroy()
		end
	end

	leaderboardusers = {}

	local success,data = pcall(function()
		return store:GetAsync("LevelLederboardStats")
	end)

	if success and data then
		for i,v in data do
			leaderboardusers[i] = v
		end
	end

	print(leaderboardusers)

	if not success then
		warn("LEADERBOARD LOAD FAILLURE: "..data)
	end

    local entry = 0

	for i, leaderboarduser in leaderboardusers do
		local success,playername = pcall(function()
			return game.Players:GetNameFromUserIdAsync(tonumber(i))
		end)

        entry += 1

		local template = LevelLeaderboard.SurfaceGui.Background.Loading:Clone()

		if success then
			if not tonumber(i) then
				print("Not a number")
			end
			
			if tonumber(i) < 1 then
				playername = "Test account"
			end
			
			template.Name = playername
		else
			template.Name = "Unknow user"
		end

		-- Adress the info to the template
		template.Username.Text = playername
		template.Value.Text = leaderboarduser
		template.Place.Text = "#"..entry

		success,playerPicture = pcall(function()
			return game.Players:GetUserThumbnailAsync(tonumber(i), Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
		end)

		if success then
			template.ProfilePicture.Image = playerPicture
		end

		if not success then
			warn("COULDNT GET USER THUMBNAIL: "..playername)
		end

		template.Parent = LevelLeaderboard.SurfaceGui.Background
		template.Visible = true
	end

	for _, player in game.Players:GetPlayers() do
		local filteringtable = {[tostring(player.UserId)] = player.Data.Level.Value}

		for i,v in leaderboardusers do
			filteringtable[tostring(i)] = v
		end

		table.sort(filteringtable,function(a,b)
			return filteringtable[a] < filteringtable[b]
		end)

		local entrys = 0
		local lastentry = nil

		for i,_ in filteringtable do
			entrys += 1
			lastentry = i
		end

		if entrys > amountofplaces then
			print("removing last place")
			filteringtable[lastentry] = nil
		end

		for i,v in filteringtable do
			leaderboardusers[i] = filteringtable[i]
		end
	end

	local succ,err = pcall(function()
		return store:SetAsync("LevelLederboardStats",leaderboardusers)
	end)

	if not succ then
		warn("COULDNT UPDATE LEADERBOARD DATASTORE: "..err)
	end
end

Negative IDs are used when you are testing your game with multiple clients. If that’s what you are trying to fix then just check if the ID is a positive value.

The id isn’t a problem, its mostly the value sorting. As you can see the lower upper and the highest at lowest.

1 Like

Ah my bad, I think I understand now. The way you are filtering the entire leaderboard is a bit weird, but I’d recommend just using ordered datastores that will filter it for you. If you want to keep on using your current system then changing

table.sort(filteringtable,function(a,b)
	return filteringtable[a] < filteringtable[b]
end)

to

table.sort(filteringtable, function(a, b)
	return a > b
end)

should work.

sort doesn’t work or brackets just infect it.

It appears that your table is associating the players ID with their points, sorting it would result in the mix and matching of each player’s points.
To be able to sort the players ID along with their points, you could try creating a pair/table:
{points, ID} for each player in the original list, and then sort the new list using a custom filter
(like @cakeycocoa was suggesting) function that checks the first index of the pair/table.

table.sort(filteringtable, function(a, b)
	return a[1] > b[1]
end)

attempted, seems like a brackets issue. Wondering what i can try to get around with the following.

I think it was your first suspected root cause, although I think it appears table sort only works on number indexes. so if you input the players ID as a number instead it might work. It appears that when you print a string indexed table, that it will be sorted by the ascending value of the indexing strings characters because the value of the character ('-') is (45) which is less than the value of the characters ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') being (48, 49, 50, 51, 52, 53, 54, 55, 56) respectively.

any other ways to go to replace brackets?

I just want to make sure I understand what your goal is. Your trying to make your leader board look like this, right?:

Player 1   8pts  #1
Player 3   6pts  #2
Player 5   3pts  #3
Player 2   2pts  #4
Player 4   1pts  #5

exactly, its why im trying to debug since this afternoon.

Since you cannot sort filteringtable you could create a table, lets say indextable, that contains the indexes of filteringtable :

for i,_ in pairs(filteringtable) do
	table.insert(indextable, i)
end

and sort indextable by comparing the values of filteringtable for each of the indexes like:

table.sort(indextable, function(a, b) 
	return filteringtable[a] < filteringtable[b]
end)

This would result in a sorted table of the players IDs.