My datastore is not working

1.I want to save the data in a game of mine

2.There appears to be an error the a numbervalue can’t be converted to a number

3.I have tried lots of solutions but none worked

here’s the script:

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")

local function saveData(player)
	local tableToSave = {
		player.leaderstats.Level.Value;
		player.leaderstats.Exp.Value;
		player.leaderstats.RequiredExp.Value;
	}
	
	local success, errorMessage = pcall(dataStore.SetAsync, dataStore, player.UserId, tableToSave)
	
	if success then
		print("Data has been saved")
	else
		print("Data has not been saved")
	end
end

--Variables
game.Players.PlayerAdded:Connect(function(Player)
	--Leaderstats
	local leaderstats = Instance.new("Folder", Player)
	leaderstats.Name = "leaderstats"

	local Level = Instance.new("NumberValue", leaderstats)
	Level.Name = "Level"
	Level.Value = 1

	local Exp = Instance.new("NumberValue", leaderstats)
	Exp.Name = "Exp"
	Exp.Value = 0

	local RequiredExp = Instance.new("NumberValue", leaderstats)
	RequiredExp.Name = "RequiredExp"
	RequiredExp.Value = Level.Value ^ 10
	-- Level up and Exp --

	Exp.Changed:Connect(function(Changed)
		if Exp.Value >= RequiredExp.Value then
			Exp.Value = 0

			Level.Value += 1
			RequiredExp.Value = Level.Value ^ 10
			print(RequiredExp.Value)
		end
		
	local data = nil
	
	local success, errorMessage = pcall(function()
		data = dataStore:GetAsync(Player.UserId)
	end)
	
	if success and data then
			Player.leaderstats.Level.Value = data[1]
			Player.leaderstats.Exp.Value = data[2]
			Player.leaderstats.RequiredExp.Value = data[3]
	else
		print("Data has not been loaded")
	end
	
end)
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		task.spawn(saveData, player)
	end
end)

You’re using the DataStore’s SetAsync() function wrong. It should be:

local success, err = pcall(function()
    dataStoreName:SetAsync(key, data)
end)
  • dataStoreName is the name of your data store.
  • key is what you use to access the data store. Also the arguement passed to GetAsync().
  • data is the data to be saved.

No no, he is using it correctly.

local success, errorMessage = pcall(dataStore.SetAsync, dataStore, player.UserId, tableToSave)

This is equivalent to what you sent, without creating an anonymous function.


Which line is the error happening on?

My bad, someone told me that was the wrong way to use it.

1 Like

I can explain more in depth on why it is the same if you want. Just DM me!


Also, the OP should use ProfileService to reliably save data. It uses DatastoreService, but it wraps the whole system nicely so you have no problems. I like it.

Also, I found out the hard way that going with Datastore2 is a bad idea. It is simpler, but lacks key features you’ll need in the future, unlike ProfileService. If you’re not going to be making a full game out of this, you can go with the simplier Datastore2, but I wouldn’t recommend it anymore.

If you’re going to be using a module for your datastore then you might as well go with Suphi’s Datastore Module already.

There is not an error, it simply does not work, the data isn’t saving

If anyone else can help here pls do … if this don’t work out, (it should).
I got it to load and save right. But ran into that request to queue warning …
It was from PlayerRemoving firing a save then also firing a save on BindToClose, as that was the only player there … So I just set up a return off the PlayerRemoving, if going to BindToClose save anyways. That took away the queue warning. I hope this is it … many prints you may want to remove.

tested attempt
local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")
local saveQueue = {}

local function saveData(player)
	local leaderstats = player:FindFirstChild("leaderstats")
	if not leaderstats then
		warn("Leaderstats not found for player " .. player.Name)
		return
	end

	local dataToSave = HttpService:JSONEncode({
		Level = leaderstats.Level.Value,
		Exp = leaderstats.Exp.Value,
		RequiredExp = leaderstats.RequiredExp.Value
	})

	if not dataToSave then
		warn("Failed to encode data for player " .. player.Name)
		return
	end

	local success, errorMessage = pcall(dataStore.SetAsync, dataStore, player.UserId, dataToSave)
	if success then
		print("Data has been saved for player " .. player.Name)
	else
		warn("Failed to save data for player " .. player.Name .. ": " .. errorMessage)
	end
end

local function saveAllData()
	if #saveQueue == 0 then
		return
	end

	local success, errorMessage
	local batch = {}
	for _, playerData in ipairs(saveQueue) do
		table.insert(batch, {
			key = playerData.Player.UserId,
			value = playerData.Data
		})
	end

	success, errorMessage = pcall(dataStore.SetAsync, dataStore, batch)
	if not success then
		warn("Failed to save data: " .. errorMessage)
	end

	saveQueue = {}
end

local function loadData(player)
	local success, data = pcall(dataStore.GetAsync, dataStore, player.UserId)
	if success and data then
		local decodedData = HttpService:JSONDecode(data)
		if type(decodedData) == "table" then
			player.leaderstats.Level.Value = decodedData.Level or 1
			player.leaderstats.Exp.Value = decodedData.Exp or 0
			player.leaderstats.RequiredExp.Value = decodedData.RequiredExp or (player.leaderstats.Level.Value ^ 10)
			print("Data loaded for player " .. player.Name)
		else
			warn("Data for player " .. player.Name .. " is invalid")
		end
	else
		warn("Failed to load data for player " .. player.Name)
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	local Level = Instance.new("NumberValue", leaderstats)
	Level.Name = "Level"
	Level.Value = 1

	local Exp = Instance.new("NumberValue", leaderstats)
	Exp.Name = "Exp"
	Exp.Value = 0

	local RequiredExp = Instance.new("NumberValue", leaderstats)
	RequiredExp.Name = "RequiredExp"
	RequiredExp.Value = Level.Value ^ 10

	Exp.Changed:Connect(function()
		if Exp.Value >= RequiredExp.Value then
			Exp.Value = 0
			Level.Value += 1
			RequiredExp.Value = Level.Value ^ 10
			print("Player " .. player.Name .. " leveled up!")
		end
	end)

	loadData(player)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local players = game.Players:GetPlayers()
	if #players == 1 then
		return
	end

	saveData(player)
	print("Player " .. player.Name .. " is leaving. Saving data...")
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		saveData(player)
	end
	saveAllData()
	print("Server is shutting down. Saving data for all players...")
end)
delete data
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Test")

local function deleteAllData()
	local success, errorMessage = pcall(dataStore.RemoveAsync, dataStore, "All")
	if success then
		print("All data has been deleted")
	else
		print("Failed to delete all data: " .. errorMessage)
	end
end

deleteAllData()

You have to have a few things set up in Game Setting / Security
Allow HTTP Requests / on and Enable Studio Access to API Service / on
and also, Save to Roblox done after you add the script.
Run the delete data script once to clean all messed up data.
So you can start fresh …

2 Likes

No thanks, I don’t like that module’s interface. Also, the same person who made that makes thumbnails like these:

image

Which… eh.

Rating someone’s scripting skills based on their thumbnails is wild.

I’d just like to point out you don’t need JSONEncode and JSONDecode when saving a dictionary/table to the DataStore. As long as the item consists only of booleans, numbers or strings, it will save just fine anyway.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.