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.
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.
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
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.
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.
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?
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:
The player joins
The server checks the newest ODS first
If nothing is in the new one, get the the number from the old one, divide, and update the new one
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.
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