How to Save numbers over 9.223 Quintillion to OrderedDataStore?

I’m using OrderedDataStore for the Leaderboard, please do not suggest saving other data types as it can only save Integers.

(OrderdDataStore and DataStore is not the same)

Does anyone have a cleaver way of compressing big numbers so it can be used with OrderedDataStore?

  • You can’t save a float, double, ONLY Integers to OrderedDataStore
  • You run out of bits at 9.223 Quintillion, if you pass anything larger than 9.223 Quintillion it get’s stuck there.
  • more details in the reply of this bug report

Thank you in advance!

12 Likes

9.223 Quintilian is the 64-bit integer limit so this can’t really be fixed as long as Roblox is in 64bit

Read more about it here: Power of two - Wikipedia

1 Like

why not save them in a table to Datastore then do the sorting after the data is loaded?

1 Like

I know the limit, I know the reason why it’s stuck, I’m asking for a solution “to compress the number

4 Likes

You should just reduce the scale of the numbers that you’re trying to save to the leaderboard. For example, save how many millions of points a player has (so if someone has 5,000,000 points, save that in the ODS as 5 instead)
The slight loss in precision shouldn’t matter if people at the top of the leaderboard are able to obtain such massive scores.

I’m assuming that players’ actual save data is separate from the data that’s saved to the leaderboards.

4 Likes

because you can’t save a Table to OrderedDataStore nor the idea using Datastore as a replacement sounds unpleasing.

1 Like

Thank you for replying,

Yes I get the idea of compressing and decompressing the number upon use when displayed, but I don’t have a cleaver way to do it Automatically and Scaleable with much larger numbers, however I’m not too good with math henceforth asking for assistant from experts to assure the best results.

If you played or at least heard of Simulators, you’d know that player progression is pretty much limitless and infinite and to support that I need the ability to store any number any value a player can acquire to be displayed on the Leaderboards.

1 Like

For example if you divide the number 10 by x
then when you the value is returned you multiply it by x again

the value should be scaled to what you want.But for higher numbers you can increase the value x, to be multiplied with all values , so the resulting value should be same.An increment in the value x to be multiplied with v must be considered when your number gets increasingly larger, so basically just set your value to be multiplied with a huge number depending on how high you values can go.
And also a script that uses tostring like :

local num = 1e19
local str = tostring(num)
dataStore:SetAsync(key, num)
--Loading:
local num = 0
local result = dataStore:GetAsync(key)
if result then 
    num = tonumber(result)
end

or num x from the divided value ,or you could serialize this lua code for your game

euler/BigNum.lua at master · ennorehling/euler · GitHub

and to save the string

game.Players.PlayerAdded:Connect(function(plyr)
    local a=Instance.new("StringValue")
    a.Parent=plyr
    a.Name="Characters"
    for i=1,#stats do
        local stat=Instance.new("StringValue")
        stat.Parent=a
        stat.Value = "None"
        stat.Name=stats[i]
    end

    for i , v in pairs(plyr.Characters:GetChildren()) do
        local success , value = pcall(function ()
            return ds:GetAsync(plyr.userId..v.Name)
        end)
        if success then
            if value then
                v.Value = value
            else

            end
        

        end
    end
end)

Thank you, yes I did that in my older games but it’s not reliable at some put you’ll have to change your divide value to something larger than before, thus not being automated nor scaleable.

not only that but for new Leaderboards the value will be 0 until the save value exceeds x which will confuse players and degrade UX.

not something I want for a Front page game.

Seems like all this can be solved if you just reduce the scaling on ur game. Don’t have to make it so people can achieve over quintillion in value

That’s pretty much the only possible solution in this case. There’s no other way to compress data in an ODS, since it requires the raw numbers to be able to sort the data.

2 Likes

Yeah other games can do it, but doesn’t mean you have to if you don’t know how. Seems ur having trouble over something that can easily be fixed by changing how high ur numbers go

I just need more information before being able to give an answer to this.
Are you using OrderedDataStore only to get the “top” players, not the lowest ones right?

Edit: Is it also only used for a leaderboard kind of thing?

Yes, of course only for top players and yes a leadeboard.

but there are issues like setting up a new leaderboard

values exceeding limits and such

Alright, that’s good.

Now, since it only serves as a leaderboard, what you can do alternatively, is to slowly transition from the old ODS to a new one. Basically, create a new instance of ODS where you keep the new information of the players.

And now, since it’s only being used for leaderboard, you can divide the number with for example 100,000,000. Since only the top players matter (assuming you have millions), it doesn’t matter who is at the bottom.

The integration will be like the following:

  1. The player joins
  2. The server checks the newest ODS first
  3. If nothing is in the new one, get the the number from the old one, divide, and update the new one
  4. Everything works, or?
3 Likes

okay, now we are getting somewhere,

I could automate the process of creating new ODS based of the top player’s value then divide and multiply it by the numbers of digits if that makes sense so

if the number 1 player has 7 figures I could use 1000000 as x, the divider and multiplier

now the hard part is automation and scalability

my idea of how the code should be is set there once and never touched again, I don’t have time to maintenance it.

Just carry the overflowing bits into another OrderedDataStore.

what how?

please explain your genuineness


I should go to sleep it’s mid night, I’ll be back

For example if you divide the number 10 by x
then when you the value is returned you multiply it by x again

the value should be scaled to what you want.But for higher numbers you can increase the value x, to be multiplied with all values , so the resulting value should be same.An increment in the value x to be multiplied with v must be considered when your number gets increasingly larger, so basically just set your value to be multiplied with a huge number depending on how high you values can go.
And also a script that uses tostring like :

local num = 1e19
local str = tostring(num)
dataStore:SetAsync(key, num)
--Loading:
local num = 0
local result = dataStore:GetAsync(key)
if result then 
    num = tonumber(result)
end

or num x from the divided value ,or you could serialize this lua code for your game

and to save the string

game.Players.PlayerAdded:Connect(function(plyr)
    local a=Instance.new("StringValue")
    a.Parent=plyr
    a.Name="Characters"
    for i=1,#stats do
        local stat=Instance.new("StringValue")
        stat.Parent=a
        stat.Value = "None"
        stat.Name=stats[i]
    end

    for i , v in pairs(plyr.Characters:GetChildren()) do
        local success , value = pcall(function ()
            return ds:GetAsync(plyr.userId..v.Name)
        end)
        if success then
            if value then
                v.Value = value
            else

            end
        

        end
    end
end)

Multiple methods exist for what you’re trying to achieve,as aforementioned
and implementation of BigNum,for instance

function decr( bnum1 )
   local temp = {} ;
   temp = BigNum.new( "1" ) ;
   BigNum.sub( bnum1 , temp , bnum1 ) ;
   return 0 ;
end--this one's just a part of the whole module needed to be serialized
1 Like

sorry, I don’t think BigNum is compatible with OrderedDataStore as it only accepts Integers not Tables nor Strings;

not sure if I fully understand what you are suggesting but I am not using regular DataStore

I’m using OrderdDataStore NOT DataStore, they are not the same @XxELECTROFUSIONxX