Numbers reaching a cap?

I’m having issues where player scores aren’t going above 9.2 quintillion

function Library:SuffixNumber(number)
	if number == 0 then
		return 0
	end

	local Suffixes = { "K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc", "Ud", "Dd", "Td", "Qad", "Qu", "Sd", "St" }

	local i = math.floor(math.log(number, 1e3))
	local v = math.pow(10, i * 3)

	return string.gsub(string.format("%.1f", number / v), "%.?0+$", "") .. (Suffixes[i] or ""), Suffixes
end

It stops at 9.2 Qi, regardless of how much a players number gets higher on the leaderboard
image
These players have more than 9.2Qi, but the leaderboard only goes this high? I’m using ordereddatastores and storing their numbers whole numbers, which is capping at
image
so numbers can’t go higher than this??

Yeah, so you’re hitting the integer overflow. The highest number you can store in an IntValue is 9.2q.

Ref:

How are games able to store numbers that are much larger than this??

Use a library like BigNum - RoStrap

cool tophat :sunglasses: :+1:

1 Like

Well, you reached the limit of 2 ^ 63 above which you can’t store numbers in OrderedDataStore. But you can compress this number when you save the data and decompress it when you want to display it.

local function compress(num)
	return math.log10(num) / math.log10(2) 
end 

local function decompress(num) 
	return math.round(math.pow(2, num)) 
end 
OrderedDataStore:SetAsync(UserId, compress(value)) -- when you're saving data


for _, data in ipairs(CurrentPage) do -- when you want to display
	local value = decompress(data.value)
end

This is the method I use in my game and it works fine.

You can also take a look at this: https://en.wikipedia.org/wiki/Power_of_two

1 Like

This didn’t seem to work for me :confused: Unsure if it’s because of my values being low?? Do I only compress if numbers are large?

Is what my code looks like

function LeaderboardService:Load(player)
	local LeaderboardData = Instance.new("Configuration")
	LeaderboardData.Name = "LeaderboardData"

	local GetPromises = {}
	for dataName, store in self.DataStores do
		table.insert(
			GetPromises,
			Promise.new(function(resolve)
				local Data = Decompress(store:GetAsync(player.UserId) or 0)

				LeaderboardData:SetAttribute(dataName, Data)

				resolve()
			end)
		)
	end

	return Promise.all(GetPromises):andThen(function()
		LeaderboardData.Parent = player
	end)
end

function LeaderboardService:Save(player)
	local LeaderboardData = player:FindFirstChild("LeaderboardData")
	if not LeaderboardData then
		return
	end

	-- Set data
	local Success, Message = pcall(function()
		for dataName, data in self.DataStores do
			local Data = LeaderboardData:GetAttribute(dataName)

			data:SetAsync(player.UserId, Compress(Data))
		end
	end)

	if not Success then
		warn(Message)
	end
end

In the case of a 64-bit signed integer, the maximum value is 9,223,372,036,854,775,807.

I don’t think so. How small are your values? If they’re like 150, 7300, 500000 then it’s ok.

No, you can compress small numbers too.

local number = 1029388 -- this is an example


local function compress(value)
	return math.log10(value) / math.log10(2)
end


local function decompress(value)
	return math.round(math.pow(2, value))
end


local compressed = compress(number)
local decompressed = decompress(compressed)

print(number, decompressed)
-- Output: 1029388, 1029388

If you mean numbers like this lol

It seems like you’re running into an issue with the data type you’re using to store the player scores in the OrderedDataStore. If you’re storing the scores as whole numbers, you’re likely hitting the upper limit of the Lua data type you’re using to store the scores.

In Lua, the largest integer that can be represented is 2^63 - 1, which is approximately 9.2 quintillion. If you’re storing player scores as whole numbers, any score above this limit will not be accurately represented and may cause unexpected behavior in your code, such as the issue you’re experiencing with the leaderboard.

One solution to this issue is to store player scores as floats instead of integers. Floats can represent much larger numbers than integers, so you can avoid hitting the upper limit of the data type. You can use the Lua number data type to store floats in your OrderedDataStore.

Another solution is to store player scores as strings instead of numbers. This will allow you to represent very large numbers as strings, which can be sorted correctly by the OrderedDataStore. However, you will need to convert the string scores back to numbers in your code when you need to perform arithmetic operations on them.

I hope this helps you resolve the issue with your leaderboard!

1 Like

By small numbers, I mean like 0, 1, 2, 3, etc…