How to make global leaderboard goes over 2^63 scores?

I Don’t Know How to Make It.

local ds = game:GetService("DataStoreService"):GetDataStore("CoinsStats4")
local page = 50
local seconds = 5
local times = seconds
local datasaves = {}

while wait(1) do
	times -= 1
    script.Parent.Parent.ResetTime.Text = "Resetting in ".. times .." seconds..."
	if times <= 0 then
		times = seconds
		local order = 0
		for i,plr in pairs(game.Players:GetChildren()) do
			datasaves[plr.UserId] = plr.Rebirths.Value
			ds:SetAsync(1,datasaves)
		end
		for i,leaderboard in pairs(script.Parent:GetChildren()) do
			if leaderboard.ClassName == "Frame" then
				leaderboard:Destroy()
			end
		end
		datasaves = ds:GetAsync(1)
		table.sort(datasaves, function(a, b)
			return a < b
		end)
		for i,v in pairs(datasaves) do
			if order < page then
				order += 1
				local name = game.Players:GetNameFromUserIdAsync(tonumber(i))
				local template = script.Template:Clone()
				template.LayoutOrder = order
				template.Name = name .." Leaderboard"
				template.Rank.Text = "#".. order
				template.PlrName.Text = name
				template.Coins.Text = v
				template.Parent = script.Parent
			end	
		end
	end
end

link here! Uncopylocked

That’s the 64 bit integer limit

should be goes up to 2^1024 or more.

Lua numbers are double-precision floats, which means the higher your values are the less precision they have. Technically the last precise integer is 2^53 (because the mantissa has 53 bits), and trying to go over will just round down.

If you need to do arbitrarily large integer operations, you’ll have to use some software implementation like a BigInt.

Just capture the exponent in a different variable, and you can measure as high as you like. There’s no point in being precise beyond 6 digits-ish, so occasionally just divide the score by 1000 and add 3 to the exponent.

1 Like

If it goes over a trillion divide it by a billion and print that number followd by a string with “Trillion” at the end. Then do it every again every increase of 1000 then call it Quadrillion, then Quinillion, and so on.
That way your max number value will always be capped at 1 trillion and the rest is just a string.

1 Like

how to make numbers abbreviate to not be limited?
like 1M 1B 1T 1Qd 1Qn 1Sx 1Sp 1Oc And More

I’ve made a system like this in the past, this is essentially the rundown of how. I believe the code is at least somewhat interpretable, so let me know if you want me to elaborate on this.

Here’s an example of the one I was talking about:

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Leaderstats = Player:WaitForChild("leaderstats")
local Money = Leaderstats:WaitForChild("Money")

local Formats = {
	Thousand = {
		Remove = 4,
		Values = {4, 5, 6},
		Symbol = 'K',
	},

	Million = {
		Remove = 7,
		Values = {7, 8, 9},
		Symbol = 'M',
	},

	Billion = {
		Remove = 10,
		Values = {10, 11, 12},
		Symbol = 'B',
	},

	Trillion = {
		Remove = 13,
		Values = {13, 14, 15},
		Symbol = 'T',
	},
}

local function FormatAndSet()
	local Value = Money.Value
	local Formatted = '$'
	local Format = ''
	local Values = 3

	for i, name in pairs(Formats) do
		for j, value in pairs(name.Values) do
			if #tostring(Value) == value then
				Format = name.Symbol
				Values = name.Remove
				break
			end
		end
	end

	if Values > 3 then
		for i = 1, Values - 1 do
			Value /= 10
		end
	end
	
	local Split = string.split(tostring(Value), '.')
	
	local NumbersRemoved = string.sub(tostring(Value), 1, Values)
	
	if Split[1] then
		local Value2 = math.round(Value * 100)
		
		Value2 /= 100
		
		NumbersRemoved = Value2
	end

	Formatted = Formatted .. NumbersRemoved .. Format

	script.Parent.Text = Formatted
end

Money:GetPropertyChangedSignal("Value"):Connect(FormatAndSet)

FormatAndSet()

Hope this helps!

1 Like

As many others have explained, 2^63 - 1 is the integer limit in Lua, which means that IntValue objects cannot store numbers larger than 9,223,372,036,854,775,807 (like @index_self has stated, 2^53 is realistically the limit of precision, but that doesn’t really matter anyways since 2^63 - 1 is truly the limiting value here; the loss of precision isn’t noticeable in this situation).

For a further explanation into why, 9,223,372,036,854,775,807 is the largest number you can represent using 64 bits, which is how most computers store integers.

Side note: if you’re not familiar with binary, a bit is the base-2 version of a digit (which is base-10). Digits in the decimal system can take on values from 0 to 9, while bits can only take on the values 0 and 1. As a consequence of this, a number in binary is built of powers of 2 rather than powers of 10.

009 223 372 036 854 775 807 is thus equal to *1111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 in binary, which has the value 1^1 + 2^1 + 4^1 + 8^1 + … + 63^1. Because integers are always signed in an IntValue, the leftmost bit is used to determine the sign of the value (if it’s positive or negative), so it doesn’t get factored into this equation; so, I’ve starred it out, but it could be a 0 or a 1.

To answer your question: leaderstats can’t display NumberValues. To make them display what you want, you’ll have to store whatever score the player has internally and use a StringValue to make it show on the global leaderboard. You won’t need to worry about the precision, most likely.

There’s zero chance that your game score actually has 2^63 possible states, more likely it has different scales of scores(for example million, billion, etc) and it can best be described through floating point arithmetic(aka scientific notation instead of discrete values).

So if you want to be sneaky, you can solve this the following way:

  1. Take the player score
  2. Convert it into a floating point approximation that uses 64 bits(or less)
  3. Encode the floating point approximation into an integer and save it to the datastore(the integer is the encoded floating point, so it should not be the same value visually, only its bit representation should be the same)
  4. When loading the data into the leaderboard, convert the score integers to bits by reversing the encode process, then convert the bits to the floating point approximation
  5. After you have the floating point pass it into a function that converts it into a string and show it to the leaderboard(so for example the final result appears to the user eyes as 123.45B, even though the actual stored value has more precision)

The only issue I can think of when doing this is implementing it in such a way so the scores remain sorted when returned by the API, perhaps you can play with least and most significant bits to achieve this. Additionally you can try different encodings but the main idea remains the same.

Best of luck.

Actually while reading through the posts here you may want to do the reverse if you need precise values at the lower end.
Once your value gets above 1 trillion (or whatever you choose) you just add 1 to a second value.
For example you have 999,999,900 in your lower range value and the players score goes up by 1000 which would equal 1,000,000,900.
Add 1 to your higher range number and leave the lower range as 000,000,900.
When the player’s leaderstat adds another trillion or 5 or 10, add that to the higher range number.
That way you can print the high range value followed by the lower range value to get your greater values.

Why the heck do you need leaderstats that high anyway? Are you giving players a quadrillion leaderboard points just for joining the game? :thinking: