"double is not allowed in datastores"

I am attempting to store a double value such as 14.7 in an ordered data store but I get the error “double is not allowed in datastores”. To fix this I multiplied the decimal by 10000 and then stored it. For some reason I still get the error evne though When i print out the value before setting it the value is clearly not a double.

local MainStore = game:GetService("DataStoreService"):GetDataStore("MainStore")

local BestTimeODS = game:GetService("DataStoreService"):GetOrderedDataStore("BestTimeOrderedStore")

local loadedPlayers = {}

local StartingParts = workspace.StartingParts:GetChildren()

local RemoteEvents = game:GetService("ReplicatedStorage").RemoteEvents

local TimerObject = require(script.TimerObject)

local GlobalLeaderboard = workspace:FindFirstChild("GlobalLeaderboard", true)

local playerTimers = {}

local function onPlayerAdded(player)
	if loadedPlayers[player.UserId] == nil then
		loadedPlayers[player.UserId] = true
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player
		
		local sessionstats = Instance.new("Folder")
		sessionstats.Name = "sessionstats"
		sessionstats.Parent = player

		local BestTime = Instance.new("NumberValue")
		BestTime.Name = "BestTime"
		BestTime.Value = 100
		BestTime.Parent = leaderstats

		local Level = Instance.new("IntValue")
		Level.Name = "Level"
		Level.Value = 1
		Level.Parent = leaderstats
		
		local XP = Instance.new("IntValue")
		XP.Name = "XP"
		XP.Value = 0
		XP.Parent = leaderstats
		
		local debounce = Instance.new("BoolValue")
		debounce.Value = false
		debounce.Name = "Debounce"
		debounce.Parent = sessionstats
		
		local currentTime = Instance.new("NumberValue")
		currentTime.Value = 0
		currentTime.Name = "CurrentTime"
		currentTime.Parent = sessionstats
		
		playerTimers[player.UserId] = TimerObject.new(player)
		
		local success, response = pcall(function()
			for i = 0,3,1 do
				local data = MainStore:GetAsync("Player-"..player.UserId)

				if data then
					BestTime.Value = data.BestTime
					Level.Value = data.Level
					XP.Value = data.XP
					break
				end
			end
		end)

		if not success then
			print(response)
		end
	end
end

game.Players.PlayerAdded:Connect(onPlayerAdded)

for _,player in ipairs(game.Players:GetPlayers()) do
	onPlayerAdded(player)
end

if game:GetService("RunService"):IsStudio() == false then
	game.Players.PlayerRemoving:Connect(function(player)
		loadedPlayers[player.UserId] = nil
		
		local success, response = pcall(function()
			
			local data = {
				["BestTime"] = player.leaderstats.BestTime.Value,
				["Level"] = player.leaderstats.Level.Value,
				["XP"] = player.leaderstats.XP.Value
			}
			
			MainStore:SetAsync("Player-"..player.UserId, data)
		end)

		if not success then
			print(response)
		end
	end)
end

game:BindToClose(function()
	for _,player in ipairs(game.Players:GetPlayers()) do
		local success, response = pcall(function()

			local data = {
				["BestTime"] = player.leaderstats.BestTime.Value,
				["Level"] = player.leaderstats.Level.Value,
				["XP"] = player.leaderstats.XP.Value
			}

			MainStore:SetAsync("Player-"..player.UserId, data)
		end)

		if not success then
			print(response)
		end
	end
end)

for _,part in ipairs(StartingParts) do
	part.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			if player then
				if player.sessionstats.Debounce.Value == false then
					player.sessionstats.Debounce.Value = true
						
					local TimerObject = playerTimers[player.UserId]
					TimerObject:startTracking()
					
					RemoteEvents.ToggleTracker:FireClient(player, "Start")
					
					local connection
	
					connection = workspace.EndingParts[part.Name].Touched:Connect(function(hit)
						if hit.Parent.Name == player.Name then
							TimerObject:stopTracking()
							connection:Disconnect()
							RemoteEvents.ToggleTracker:FireClient(player, "Stop")
							player:WaitForChild("sessionstats").Debounce.Value = false
							
							if TimerObject:getLastTime() < player.leaderstats.BestTime.Value then
								player.leaderstats.BestTime.Value = TimerObject:getLastTime()
							end
						end
					end)
				end
			end
		end
	end)
end

while true do
	
	--local success, response = pcall(function()
		for _,player in ipairs(game.Players:GetPlayers()) do
			print(player.leaderstats.BestTime.Value * 10000)
			BestTimeODS:SetAsync(player.UserId, player.leaderstats.BestTime.Value * 10000)
		end
		
		for _,v in ipairs(GlobalLeaderboard.SurfaceGui.ScrollingFrame:GetChildren()) do
			if v.ClassName == "Frame" then
				v:Destroy()
			end
		end
		
		local page = BestTimeODS:GetSortedAsync(false, 10):GetCurrentPage()
		
		for k,entry in ipairs(page) do
			local Slot = GlobalLeaderboard.BoardSlot:Clone()
			Slot.BestTime.Text = tostring(entry.value / 10000)
			Slot.Rank.Text = "#"..k
			Slot.PlayerName = game.Players:GetPlayerByUserId(entry.key).Name
			Slot.Parent = GlobalLeaderboard.SurfaceGui.ScrollingFrame
		end
	--end)
	
	--if not success then
	--	warn(response)
	--end
	wait(5)
end
2 Likes

Is your BestTime.Value giving a value like 3.53235 sometimes? If it can give a decimal with greater precision than your multiplier by 10,000 It’ll still try to throw a double in. Perhaps try multiplying and dividing by a much larger number first to see if that fixes it.

nope, the value is exactly 1.8

1 Like

Looks like you are not able to store doubles, but integers:

Sometimes Roblox has rounding errors when dealing with decimals, which could mean after you multiply by 10,000 you could get numbers like 49,9999.9999. Maybe try using math.floor on the rounded number?

1 Like

You cannot have numbers with decimals in your datastore, so like:

3.1 wont work,

you would need a math.floor() to floor the number to 3

Thanks! I always forget roblox deals with decimals weirldy sometimes.

1 Like

If you want to preserve the decimals but don’t want the error, just do

math.floor(num * 100) -- replace 100 with your precision

And then when you access it you could do

local value = num / 100