Datastore script not saving

I’ve tried multiple different ways to create data stores and none of them has worked so far, so I decided to post my script here and see if anyone can spot the problem. The script can assign default values but it doesn’t save or load properly. I can’t know which one it is.

game.Players.PlayerAdded:Connect(function(player)	
	data = Instance.new("Folder")
	data.Parent = player
	data.Name = "data"

	exp = Instance.new("NumberValue")
	exp.Parent = data
	exp.Name = "exp"

	expNeed = Instance.new("NumberValue")
	expNeed.Parent = data
	expNeed.Name = "expNeed"

	level = Instance.new("NumberValue")
	level.Parent = data
	level.Name = "level"

	spins = Instance.new("NumberValue")
	spins.Parent = data
	spins.Name = "spins"

	element = Instance.new("NumberValue")
	element.Parent = data
	element.Name = "element"

	healthMaxValue = Instance.new("NumberValue")
	healthMaxValue.Value = 100
	healthMaxValue.Parent = data
	healthMaxValue.Name = "healthMaxValue"

	healthValue = Instance.new("NumberValue")
	healthValue.Value = 100
	healthValue.Parent = data
	healthValue.Name = "healthValue"
end)

dss = game:GetService("DataStoreService")
playerData = dss:GetDataStore("playerData")
success = nil
errormsg = nil
local updatedValue
attempt = 1


function Save(player)
	stuff = {Exp = exp.Value, ExpNeed = expNeed.Value, Level = level.Value, Spins = spins.Value, Element = element.Value}
	success, errormsg = pcall(function()
		playerData:SetAsync(player.UserId, stuff)
		if success then
			print("Saved")
		end
		if not success then
			print(errormsg)
		end
	end)
end

function Load(player)
	repeat success, updatedValue = pcall(function()
			is = playerData:GetAsync(player.UserId)
			playerData:GetAsync(player.UserId)
		end)
		if success then
			if updatedValue then
				print("Yes")
				exp.Value = is.Exp
				expNeed.Value = is.ExpNeed
				level.Value = is.Level
				spins.Value = is.Spins
				element.Value = is.Element
			else
				print("Doing")

				game.ReplicatedStorage.dataInfo:FireClient(player)
			end
		end
		if not success then
			print("Sorry")
		end
		attempt += 1
		task.wait(5)
	until success or attempt == 6
end

game.Players.PlayerRemoving:Connect(Save)
game.Players.PlayerAdded:Connect(Load)

It outputs Doing when loading in and Saved when exiting.

I don’t use data store at all, but have you tried using a data store editor instead?

Like I said, I’m not sure if this will work.

1 | StudioAccessToApis must be enabled
2 | Your in the script assigning GLOBALS (meaning its publicly available in the script for anyone to modify and in turn, won’t save per player if its multiplayer) to the values, which isn’t a good idea. I suggest cutting out

	data = Instance.new("Folder")
	data.Parent = player
	data.Name = "data"

	exp = Instance.new("NumberValue")
	exp.Parent = data
	exp.Name = "exp"

	expNeed = Instance.new("NumberValue")
	expNeed.Parent = data
	expNeed.Name = "expNeed"

	level = Instance.new("NumberValue")
	level.Parent = data
	level.Name = "level"

	spins = Instance.new("NumberValue")
	spins.Parent = data
	spins.Name = "spins"

	element = Instance.new("NumberValue")
	element.Parent = data
	element.Name = "element"

	healthMaxValue = Instance.new("NumberValue")
	healthMaxValue.Value = 100
	healthMaxValue.Parent = data
	healthMaxValue.Name = "healthMaxValue"

	healthValue = Instance.new("NumberValue")
	healthValue.Value = 100
	healthValue.Parent = data
	healthValue.Name = "healthValue"
end)

And in turn add the contents of that function to the other onJoin (load) function. (and make them LOCAL)
3 | Move your calls for success, errormsg, updatedValue, and attempt into the onJoin function, or load.
4 | When saving, look in the player for these objects, your not saving them correctly. If you implement the changes I mentioned above you will need to do player:WaitForChild("data"):WaitForChild("WhateverValueItIs").Value to get the value

If it dosen’t just say it dosen’t and I’m sure someone will help.

1 Like

Here’s what the DataStore script that I use look’s like, if I’m right you are missing a few important things…

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

local module = {}
function saveData(player)

	local tableToSave = {
		player.leaderstats.Money.Value,
		player.leaderstats.Bank.Value,
		player.leaderstats.Repuation.Value
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave)
	end)

	if success then
		print("Data has been saved!")
	else
		print("Data hasn't been saved!")
		warn(err)		
	end
end

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

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

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

local table = {a, b, c}
for index, value in pairs(table) do
	print(index)
	print(value)
end

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

game.Players.PlayerAdded:Connect(function(player)

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Money = Instance.new("IntValue")
	Money.Name = "Money"
	Money.Parent = leaderstats

	local Bank = Instance.new("IntValue")
	Bank.Name = "Bank"
	Bank.Parent = leaderstats

	local Reputation = Instance.new("IntValue")
	Reputation.Name = "Reputation"
	Reputation.Parent = leaderstats

	local data
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId)

	end)

	if success and data then

		Money.Value = data[1]
		Bank.Value = data[2]

	else
		print("The player has no data!")	
	end

	local data

	data = dataStore:GetAsync(player.UserId)

	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId)

	end)

	if success then	
		Money.Value = data[1]
		Bank.Value = data[2]

	else
		print("The player has no data!")
	end

	local table = {
		"a",
		"b",
		"c"
	}

	local firstValue = table[1]
	print(firstValue)

	if success then	
		Money.Value = data[1]
		Bank.Value = data[2]
	else
		print("The player has no data!")	

		Money.Value = 50
		Bank.Value = 30
		Reputation.Value = 0
	end
end)

Let me know if it help’s.(Obviously change all the stat name’s to what you want)

Hi, I tried copy pasting your script and changing the values. No errors show up in the output, although data is still not being saved. Thank you so much for offering help anyway!
Here is the script:

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

local module = {}
function saveData(player)

	local tableToSave = {
		player.data.exp.Value,
		player.data.expNeed.Value,
		player.data.level.Value,
		player.data.spins.Value,
		player.data.element.Value,
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave)
	end)

	if success then
		print("Data has been saved!")
	else
		print("Data hasn't been saved!")
		warn(err)		
	end
end

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

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

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

local table = {a, b, c}
for index, value in pairs(table) do
	print(index)
	print(value)
end

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

game.Players.PlayerAdded:Connect(function(player)

	local data = Instance.new("Folder")
	data.Name = "data"
	data.Parent = player

	local exp = Instance.new("IntValue")
	exp.Name = "exp"
	exp.Parent = data

	local expNeed = Instance.new("IntValue")
	expNeed.Name = "expNeed"
	expNeed.Parent = data

	local level = Instance.new("IntValue")
	level.Name = "level"
	level.Parent = data
	
	local spins = Instance.new("IntValue")
	spins.Name = "spins"
	spins.Parent = data
	
	local element = Instance.new("IntValue")
	element.Name = "element"
	element.Parent = data
	
	local healthValue = Instance.new("IntValue")
	healthValue.Name = "healthValue"
	healthValue.Parent = data
	
	local healthMaxValue = Instance.new("IntValue")
	healthMaxValue.Name = "healthMaxValue"
	healthMaxValue.Parent = data
	
	local movesR = Instance.new("BoolValue")
	movesR.Name = "movesR"
	movesR.Parent = data

	local data
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId)

	end)

	if success and data then

		exp.Value = data[1]
		expNeed.Value = data[2]
		level.Value = data[3]
		spins.Value = data[4]
		element.Value = data[5]

	else
		print("The player has no data!")	
	end

	local data

	data = dataStore:GetAsync(player.UserId)

	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId)

	end)

	if success then	
		exp.Value = data[1]
		expNeed.Value = data[2]
		level.Value = data[3]
		spins.Value = data[4]
		element.Value = data[5]

	else
		print("The player has no data!")
	end

	local table = {
		"a",
		"b",
		"c"
	}

	local firstValue = table[1]
	print(firstValue)

	if success then	
		exp.Value = data[1]
		expNeed.Value = data[2]
		level.Value = data[3]
		spins.Value = data[4]
		element.Value = data[5]
	else
		print("The player has no data!")	

		exp.Value = 0
		expNeed.Value = 50
		level.Value = 1
		spins.Value = 10
		element.Value = 0
	end
end)

Hi, I tried following your instructions and I don’t really understand what you mean by moving my calls for the stuff to load, but I tried my best. Thank you so much for answering though!
Here’s the updated code:

dss = game:GetService("DataStoreService")
playerData = dss:GetDataStore("playerData")
success = nil
errormsg = nil
local updatedValue
attempt = 1


function Save(player)
	data = player:WaitForChild("data")
	local stuff = {Exp = data:WaitForChild("exp").Value, ExpNeed = data:WaitForChild("expNeed").Value, Level = data:WaitForChild("level").Value, Spins = data:WaitForChild("spins").Value, Element = data:WaitForChild("element").Value}
	success, errormsg = pcall(function()
		playerData:SetAsync(player.UserId, stuff)
		if success then
			print("Saved")
		end
		if not success then
			print(errormsg)
		end
	end)
end

function Load(player)
	repeat success, updatedValue = pcall(function()
			is = playerData:GetAsync(player.UserId)
			playerData:GetAsync(player.UserId)
		end)
		if success then
			if updatedValue then
				print("Yes")
				data:WaitForChild("exp").Value = is.Exp
				data:WaitForChild("expNeed").Value = is.ExpNeed
				data:WaitForChild("level").Value = is.Level
				data:WaitForChild("spins").Value = is.Spins
				data:WaitForChild("element").Value = is.Element
			else
				print("Doing")
				local data = Instance.new("Folder")
				data.Parent = player
				data.Name = "data"

				local exp = Instance.new("NumberValue")
				exp.Parent = data
				exp.Name = "exp"

				local expNeed = Instance.new("NumberValue")
				expNeed.Parent = data
				expNeed.Name = "expNeed"

				local level = Instance.new("NumberValue")
				level.Parent = data
				level.Name = "level"

				local spins = Instance.new("NumberValue")
				spins.Parent = data
				spins.Name = "spins"

				local element = Instance.new("NumberValue")
				element.Parent = data
				element.Name = "element"

				local healthMaxValue = Instance.new("NumberValue")
				healthMaxValue.Value = 100
				healthMaxValue.Parent = data
				healthMaxValue.Name = "healthMaxValue"

				local healthValue = Instance.new("NumberValue")
				healthValue.Value = 100
				healthValue.Parent = data
				healthValue.Name = "healthValue"

				local movesR = Instance.new("BoolValue")
				movesR.Value = false
				movesR.Name = "movesR"
				movesR.Parent = data
			end
		end
		if not success then
			print("Sorry")
		end
		attempt += 1
		task.wait(5)
	until success or attempt == 6
end

game.Players.PlayerRemoving:Connect(Save)
game.Players.PlayerAdded:Connect(Load)

Move this into Save & load so each one has it inside of it. Put local before everything, please. It’s overall a better coding practice as the variables for that statement are only being used in that function