Leaderstats sorting is cursed

i made a leaderstats script with datastore and some more things, i tested it in game an found out something really wired

the sorting didnt work i dont know why
here is my full leaderstats scripts and all if needed it has some more things not related to the leaderstats but i will keep them there

local datastoreService = game:GetService("DataStoreService")
local Datastore = datastoreService:GetDataStore("fffffffffffffff")

local RunService = game:GetService("RunService")

local HttpService = game:GetService("HttpService")

local ZoneRequirements = {
	50000,
	200000
}

local Digits = {
	"",
	"K", -- 4 digits 
	"M", -- 7 eigits
	"B", -- 10 digits
	"T", -- 13 digits
	"Qu", -- 16 digits
	"Qi", -- 19 digits
	"Sx", -- 22 digits
	"Se", -- 25 digits
	"Oc", -- 28 digits
	"No", -- 31 digits
	"De", -- 34 digits
	"Un", -- 37 digits
	"Duo", -- 40 digits
	"Tre", -- 43 digits
	"Qua", -- 46 digits
	"Qui", -- 49 digits
}

local function Abrieviate(val)
	for i=1, #Digits do
		if i >= 10 then
			local digit = math.floor(math.log10(val)) + 1
			local index = math.min(#Digits, math.floor((digit - 1) / 3))
			local front = val / math.pow(10, index * 3)

			return string.format("%i%s", front, Digits[index + 1])
		else
			if tonumber(val) < 10^(i*3) then
				return math.floor(val/((10^((i-1)*3))/100))/(100)..Digits[i]
			end
		end
	end
end


local function comma_value(amount)
	local formatted = amount
	while true do  
		formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
		if (k==0) then
			break
		end
	end
	return formatted
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Values = Instance.new("Folder")
	Values.Name = "Values"
	Values.Parent = player
	
	local realStats = Instance.new("Folder")
	realStats.Name = "realStats"
	realStats.Parent = player
	
	local Gifts = Instance.new("StringValue")
	Gifts.Parent = leaderstats
	Gifts.Name = "Gifts"
	Gifts.Value = 0
	
	local Damge = Instance.new("StringValue")
	Damge.Parent = leaderstats
	Damge.Name = "Damge"
	Damge.Value = 0
	
	local Gems = Instance.new("StringValue")
	Gems.Parent = leaderstats
	Gems.Name = "Gems"
	Gems.Value = 0
	
	local Coins = Instance.new("StringValue")
	Coins.Parent = leaderstats
	Coins.Name = "Coins"
	Coins.Value = 0

	local realGifts = Instance.new("IntValue")
	realGifts.Parent = realStats
	realGifts.Name = "Gifts"
	realGifts.Value = 0
	
	local realCoins = Instance.new("NumberValue")
	realCoins.Parent = realStats
	realCoins.Name = "Coins"
	realCoins.Value = 0

	local realGems = Instance.new("NumberValue")
	realGems.Parent = realStats
	realGems.Name = "Gems"
	realGems.Value = 0
	
	local realDamge = Instance.new("NumberValue")
	realDamge.Parent = Values
	realDamge.Name = "Damge"
	realDamge.Value = 1
	
	local TimePlayed = Instance.new("IntValue")
	TimePlayed.Parent = Values
	TimePlayed.Name = "TimePlayed"
	TimePlayed.Value = 0
	
	local AttackSpeed = Instance.new("NumberValue")
	AttackSpeed.Parent = Values
	AttackSpeed.Name = "AttackSpeed"
	AttackSpeed.Value = 1

	local AttackSpeed = Instance.new("IntValue")
	AttackSpeed.Parent = Values
	AttackSpeed.Name = "EggsHatched"
	AttackSpeed.Value = 0
	
	local HatBonus = Instance.new("IntValue")
	HatBonus.Parent = Values
	HatBonus.Name = "HatBonus"
	HatBonus.Value = 0
	
	local ZonesUnlocked = Instance.new("IntValue")
	ZonesUnlocked.Parent = Values
	ZonesUnlocked.Name = "ZonesUnlocked"
	ZonesUnlocked.Value = 0
	
	local char = player.CharacterAppearanceLoaded:Wait()
	
	local tool = char:FindFirstChildOfClass("Tool")
	
	local data
	local success, errormessage = pcall(function()
		data = HttpService:JSONDecode(Datastore:GetAsync(player.UserId))
	end)
	
	if success then
		realGifts.Value = data["Gifts"]
		realCoins.Value = data["Coins"]
		realGems.Value = data["Gems"]
		ZonesUnlocked.Value = data["Zones"]
		
		print(ZonesUnlocked)
		
		game.ReplicatedStorage.Remotes.UnlockZones:FireClient(player, ZonesUnlocked)
		
		realDamge.Value = (HatBonus.Value) * tool:FindFirstChild("Damge").Value + 1
		Damge.Value = realDamge.Value
		Coins.Value = Abrieviate(realCoins.Value)
		if realGifts.Value >= 100000 then
			Gifts.Value = Abrieviate(realGifts.Value)
		else
			Gifts.Value = comma_value(realGifts.Value)
		end
		Gems.Value = Abrieviate(realGems.Value)
	end
	realDamge.Value = (HatBonus.Value) * tool:FindFirstChild("Damge").Value + 1
	Damge.Value = realDamge.Value
	realGifts:GetPropertyChangedSignal("Value"):Connect(function()
		if realGifts.Value >= 100000 then
			Gifts.Value = Abrieviate(realGifts.Value)
		else
			Gifts.Value = comma_value(realGifts.Value)
		end
	end)
	realCoins:GetPropertyChangedSignal("Value"):Connect(function()
		Coins.Value = Abrieviate(realCoins.Value)
	end)
	realGems:GetPropertyChangedSignal("Value"):Connect(function()
		Gems.Value = Abrieviate(realGems.Value)
	end)
	ZonesUnlocked:GetPropertyChangedSignal("Value"):Connect(function()
		game.ReplicatedStorage.Remotes.UnlockZones:FireClient(player, ZonesUnlocked)
	end)
	HatBonus:GetPropertyChangedSignal("Value"):Connect(function()
		realDamge.Value = (HatBonus.Value) * tool:FindFirstChild("Damge").Value + 1
	end)
	realDamge:GetPropertyChangedSignal("Value"):Connect(function()
		Damge.Value = Abrieviate(realDamge.Value)
	end)
	player:WaitForChild("PlayerGui"):WaitForChild("CoinsNGems").coins.Frame.Coins.Text = tostring(Coins.Value)
	player:WaitForChild("PlayerGui"):WaitForChild("CoinsNGems").gems.Frame.Gems.Text = tostring(Gems.Value)

	local zonesGui = player:WaitForChild("PlayerGui"):WaitForChild("Zones")
	
	local zonesButton = zonesGui.GotEnough.Frame.Frame.Frame.TextButton
	
	zonesButton.MouseButton1Click:Connect(function()
		if realCoins.Value >= ZoneRequirements[ZonesUnlocked.Value + 1] then
			print("Wokring")
			ZonesUnlocked.Value += 1
			realCoins.Value -= ZoneRequirements[ZonesUnlocked.Value]
		end
	end)
end)



game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		local tbl = {
			["Coins"] = player.realStats.Coins.Value,
			["Gifts"] = player.realStats.Gifts.Value,
			["Gems"] = player.realStats.Gems.Value,
			["Zones"] = player.Values.ZonesUnlocked.Value
		}

		local data = HttpService:JSONEncode(tbl)
		Datastore:SetAsync(player.UserId, data)
	end)
	if not success then
		print("theres an error")
		warn(errormessage)
	end
end)

game:BindToClose(function()
	if RunService:IsStudio() then
		wait(1)
	end
	for i, player in ipairs(game.Players:GetPlayers()) do
		local success, errormessage = pcall(function()
			local tbl = {
				["Coins"] = player.realStats.Coins.Value,
				["Gifts"] = player.realStats.Gifts.Value,
				["Gems"] = player.realStats.Gems.Value,
				["Zones"] = player.Values.ZonesUnlocked.Value
			}

			local data = HttpService:JSONEncode(tbl)
			Datastore:SetAsync(player.UserId, data)
		end)
		if not success then
			print("theres an error")
			warn(errormessage)
		end
	end
end)

here is a picture of how its looking


is there something i can do that the value “Gifts” will sort the leaderboard? thanks

I don’t think the default leaderstats script will sort it because it now has commas (I think that makes it a string which makes it unable to sort it properly.)

I don’t think we can modify the leaderstats / playerlist order so were out of luck. You can try making your own system with table.sort(). and a custom function.

local someTable = {} -- put leaderstats in here

local function sort(a,b)
   return a > b -- or a < b, I forgot which one is greatest to least.
end

table.sort(someTable,sort)

does other games with abbreviation system uses custom leaderstats? because i dont think every small simulator does that

I honestly do not know. Probably not.

I doubt they do, but as I said, I don’t know. Maybe something in the leaderstat script broke recently causing this. I have never attempted to shorten leaderstats or numbers before so I can’t really think of a solution. Maybe wait and see if others respond?

If no one does, consider making a new topic (Idk if this is allowed.)
Or go with the custom playerlist idea. There has to be a way to sort them since other games do this, I’ll try to look for some resources if I can find any.

This is the only relevant topic I found:

It seems that one of the replies said they forked the playerlist a while back, I guess thats how you would do it but it probably isn’t possible now. Forking it allows you to make your own sorting functions.

i got a module named FormatNumber and it sorts fine if the player have more than 1000 of the value
you know how to like make it for all values ?
its like that

player        value
name          800
name          1,520
name          1,150

the int values is always above the strings how can i fix it?
here is the format number module

The built-in player list already formats numbers for you.

1 Like

not with comma tho and after 100T it stops…

Actually…
leaderboardcomma

yea but when its lets say 1000 its not 1,000 its 1000