As far as I can tell, it means that the datastore can’t save decimals. How would I make it so that it can save decimals, or is there another way for it to save it? (This is for a leaderboard for my game)
The game contains pets which have multipliers with decimals. Would I have to make them not have decimal multipliers?
Say the decimal is 6.3, you could save 63 to the datastore. Then when you load them back in divide 63 back by 10 to get 6.3 again. Basically when saving data, multiply all the pet’s multipliers by 10, and then divide it by 10 when you load the pets in.
Alright. I dont have much experience with datastores, is there a way i could do that with the leaderboard instead of with the pets? this is the script.
local ds = game:GetService("DataStoreService")
local gemsODS = ds:GetOrderedDataStore("LeaderData")
local timeUntilReset = 5
while wait(1) do
timeUntilReset = timeUntilReset - 1
script.Parent.Parent.ResetTime.Text = "Updating in " .. timeUntilReset .. " seconds..."
if timeUntilReset == 0 then
timeUntilReset = 120
for i, plr in pairs(game.Players:GetPlayers()) do
gemsODS:SetAsync(plr.UserId, plr.leaderstats.Gems.Value)
end
for i, leaderboardRank in pairs(script.Parent:GetChildren()) do
if leaderboardRank.ClassName == "Frame" then
leaderboardRank:Destroy()
end
end
local success, errorMsg = pcall(function()
local data = gemsODS:GetSortedAsync(false, 50)
local gemsPage = data:GetCurrentPage()
for rankInLB, dataStored in ipairs(gemsPage) do
local name = game.Players:GetNameFromUserIdAsync(tonumber(dataStored.key))
local gems = dataStored.value
local template = script.Template:Clone()
template.Name = name .. "Leaderboard"
template.PlrName.Text = name
template.Rank.Text = "#" .. rankInLB
template.Gems.Text = gems
template.Parent = script.Parent
end
end)
end
end
local ds = game:GetService("DataStoreService")
local gemsODS = ds:GetDataStore("LeaderData") -- We'll have to use a regular DataStore, as we are saving strings
local timeUntilReset = 5
while wait(1) do
timeUntilReset = timeUntilReset - 1
script.Parent.Parent.ResetTime.Text = "Updating in " .. timeUntilReset .. " seconds..."
if timeUntilReset == 0 then
timeUntilReset = 120
for i, plr in pairs(game.Players:GetPlayers()) do
gemsODS:SetAsync(plr.UserId, tostring(plr.leaderstats.Gems.Value))
end
for i, leaderboardRank in pairs(script.Parent:GetChildren()) do
if leaderboardRank.ClassName == "Frame" then
leaderboardRank:Destroy()
end
end
local success, errorMsg = pcall(function()
local data = gemsODS:GetSortedAsync(false, 50)
local gemsPage = data:GetCurrentPage()
for rankInLB, dataStored in ipairs(gemsPage) do
local name = game.Players:GetNameFromUserIdAsync(tonumber(dataStored.key))
local gems = dataStored.value
local template = script.Template:Clone()
template.Name = name .. "Leaderboard"
template.PlrName.Text = name
template.Rank.Text = "#" .. rankInLB
template.Gems.Text = gems
template.Parent = script.Parent
end
end)
end
end
I am unsure why, but when i applied the script with these changes, and tested it, I didn’t get that same issue with the output, but it wasn’t loading the players on the leaderboard
This completely defeats the purpose of what OP wants, an OrderedDataStore, and will introduce other issues such as :GetSortedAsync() not being available for normal datastores. There is a simple way around, assuming that “gems” are a sort of currency. A simple round, floor, or ceil, would solve the issue as currency is generally in integer increments. This also assumes that OP has integer-based pricing.
This seems to be an OrderedDataStore for a gems currency? If so, currency is generally stored as integers in games, a simple round, ceil, or floor of the value could solve the issue?
Yes, but the issue is that OP wants doubles, and OrderedDataStores only support integers, so using a DataStore would solve the double issue, and there would only be a little more code to get the values for a list of players, push to a list, and sort that list, and display the leaderboard with those values