Introduction
If you have worked on a simulator, then there is a pretty likely chance that the leaderboards will have a 9.223 quintillion limit, and all the players are stuck on it with no way to get higher up. What would you do?
You decide to take this tutorial. Firstly, you DO NOT need to only save the number, that will result in a barrier. You need to do some extra algorithms to put the leaderboard and result in competition having higher!
What a normal person does Divides the number by a very huge amount to extend the limit, but not to it's highest potential. That will also result in a leaderboard reset, at some point, they will hit the limit again.
What this tutorial does So, let's assume this is your leaderboard script:
local function Handler()
local Success, Err = pcall(function()
local Data = CashODS:GetSortedAsync(false, 100)
local TotalWheatPage = Data:GetCurrentPage()
for Rank, Data in ipairs(TotalWheatPage) do
local Name = Data.key
local Cash = Data.value
local NewObj = game.ReplicatedStorage:WaitForChild("lbFrame"):Clone()
NewObj.Player.Text = Name
NewObj.TotalWheat.Text = Cash
NewObj.Rank.Text = "#"..Rank
NewObj.Position = UDim2.new(0, 0, NewObj.Position.Y.Scale + (0.01 * #game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()), 0)
NewObj.Parent = game.Workspace.StatCoinBoard.lbGUI.Holder
end
end)
if not Success then
error(Err)
end
end
while true do
for _,Player in pairs(game.Players:GetPlayers()) do
CashODS:SetAsync(Player.Name, Player.leaderstats.Money.Value)
end
for _,v in pairs(game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()) do
if v.Name == "lbFrame" then
wait()
v:Destroy()
end
end
Handler()
wait(10)
end
As you can see, it's a standard leaderboard script. You might have noticed one line:
CashODS:SetAsync(Player.Name, Player.leaderstats.Money.Value)
That is just the standard leaderboard script. If you work on a simulator, that will result in the money on the leaderboard being capped to 9,223,372,036,854,775,808. How do we fix this?
Save it differently, utilizing math.log10. First, take the value:
local SavedStat = Player.leaderstats.Money.Value
Next, add the value by 1 to prevent errors while saving 0:
local SavedStat = Player.leaderstats.Money.Value
SavedStat = SavedStat + 1
Next, you must use the math.log10 and do this:
local SavedStat = Player.leaderstats.Money.Value
SavedStat = SavedStat + 1
SavedStat = math.log10(SavedStat)
You might be wondering We are just gonna store the log10 and that's it? No. You must multiply the log10 by this magic number to allow maximum accuracy: 29921268260572600.
local SavedStat = Player.leaderstats.Money.Value
SavedStat = SavedStat + 1
SavedStat = math.log10(SavedStat) * 29921268260572600
Then save it as that. Always note that there will be accuracy problems no matter how you set it, it may be off by 0.0000000000000444 %.
Now, the script should look like this: (Note that we are still not done yet)
local function Handler()
local Success, Err = pcall(function()
local Data = CashODS:GetSortedAsync(false, 100)
local TotalWheatPage = Data:GetCurrentPage()
for Rank, Data in ipairs(TotalWheatPage) do
local Name = Data.key
local Cash = Data.value
local NewObj = game.ReplicatedStorage:WaitForChild("lbFrame"):Clone()
NewObj.Player.Text = Name
NewObj.TotalWheat.Text = Cash
NewObj.Rank.Text = "#"..Rank
NewObj.Position = UDim2.new(0, 0, NewObj.Position.Y.Scale + (0.01 * #game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()), 0)
NewObj.Parent = game.Workspace.StatCoinBoard.lbGUI.Holder
end
end)
if not Success then
error(Err)
end
end
while true do
for _,Player in pairs(game.Players:GetPlayers()) do
local SavedStat = Player.leaderstats.Money.Value
SavedStat = SavedStat + 1
SavedStat = math.log10(SavedStat) * 29921268260572600
CashODS:SetAsync(Player.Name, math.floor(SavedStat))
end
for _,v in pairs(game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()) do
if v.Name == "lbFrame" then
wait()
v:Destroy()
end
end
Handler()
wait(10)
end
If we load it right now, then the values will be all over the place, ranging from 9.007e+15 to 9.223e+18! To fix that, you must decode the saved value:
Divide the saved value by the same magic number.
local Cash = Data.value
Cash = Cash / 29921268260572600
Now, raise the current value to the power of 10, then substract it by 1.
local Cash = Data.value
Cash = Cash / 29921268260572600
Cash = 10 ^ Cash
Cash = Cash - 1
Now, your script should look something like this:
local CashODS = game:GetService("DataStoreService"):GetOrderedDataStore("ODS1")
local function Handler()
local Success, Err = pcall(function()
local Data = CashODS:GetSortedAsync(false, 100)
local TotalWheatPage = Data:GetCurrentPage()
for Rank, Data in ipairs(TotalWheatPage) do
local Name = Data.key
local Cash = Data.value
Cash = Cash / 29921268260572600
Cash = 10 ^ Cash
Cash = Cash - 1
local NewObj = game.ReplicatedStorage:WaitForChild("lbFrame"):Clone()
NewObj.Player.Text = Name
NewObj.TotalWheat.Text = Cash
NewObj.Rank.Text = "#"..Rank
NewObj.Position = UDim2.new(0, 0, NewObj.Position.Y.Scale + (0.01 * #game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()), 0)
NewObj.Parent = game.Workspace.StatCoinBoard.lbGUI.Holder
end
end)
if not Success then
error(Err)
end
end
while true do
for _,Player in pairs(game.Players:GetPlayers()) do
local SavedStat = Player.leaderstats.Money.Value
SavedStat = SavedStat + 1
SavedStat = math.log10(SavedStat) * 29921268260572600
CashODS:SetAsync(Player.Name, math.floor(SavedStat))
end
for _,v in pairs(game.Workspace.Leaderboard1.lbGUI.Holder:GetChildren()) do
if v.Name == "lbFrame" then
wait()
v:Destroy()
end
end
Handler()
wait(10)
end
Step By Step Let's assume someone is saving 250$ on the leaderboard: 250$ gets added by 1 and it gets 251, it gets put onto math.log10 and it becomes 2.399673721, it gets multiplied by the magic number and becomes 7.18012811e+16.
Now, to load it: Divide 7.18012811e+16 by the magic number and it becomes 2.399673721, it gets put onto 10^2.399673721 and becomes 251.00000000001 (remember the accuracy?), 251.00000000001 - 1 = 250.00000000001. This is a effect of floating-point precision. Now, let's assume someone is saving something that is over the limit, let's say, 480Sp in most games. 480Sp + 1 = 480Sp, log10(480Sp) = 26.681, 26.681 * multiplier = 7.9833e+17, not over the leaderboard limit. We can decode this by: 7.9833e+17 / multiplier = 26.681, 10 ^ 26.681 = 4.8000000000011e+26. Also the effect of floating-point precision. 4.8000000000011e+26 - 1 = 4.8000000000011e+26. Over the leaderboard limit, saved in 7.9833e+17.
Pros Being able to save numbers over the limit is always a good thing. It is a good use for simulators, espically those simulators that you click a sword and buy ranks.
If you do not have a leaderboard that breaks the limit but needs to painstakingly save decimal numbers, this is also the leaderboard for you! This also supports decimals, meaning this can also save decimal numbers, meaning that time played saving can be precisely saved in miliseconds.
Cons If you use this leaderboard on something like a roleplay game where those normal limit will be never achieved, it can do pretty much nothing. Choose wisely which games you include it on, and make sure to include it in thinga you know will break the limit or use decimals.
And there you have it! A leaderboard that breaks the normal ROBLOX limit!