Stat saving not working

Hello, i made a stat saving system by following a tutorial and it doesnt seem to work, any idea why that is?

local dss = game:GetService("DataStoreService")
local levelDS = dss:GetDataStore("Levels")



function saveData(player)
	
	pcall(function()
		
		local level = player.Stats.Level.Value
		local exp = player.Stats.Experience.Value
		local p = player.Stats.Points.Value
		local pwr = player.Stats.Power.Value
		local f = player.Stats.Fruit.Value
		local s = player.Stats.Stand.Value
		local w = player.Stats.Weapon.Value
		local he = player.Stats.Health.Value
		
		levelDS:SetAsync(player.UserId .. "Level", {level, exp, p, pwr, f, s, w, he})
	end)
end


game.Players.PlayerAdded:Connect(function(player)
	
	
	local statsFolder = Instance.new("Folder", player)
	statsFolder.Name = "Stats"
	
	local levelVal = Instance.new("IntValue", statsFolder)
	levelVal.Name = "Level"
	levelVal.Value = 1
	
	local expVal = Instance.new("IntValue", statsFolder)
	expVal.Name = "Experience"
	
	local Points = Instance.new("IntValue", statsFolder)
	Points.Name = "Points"
	
	local Power = Instance.new("IntValue", statsFolder)
	Power.Name = "Power"
	
	local Fruit = Instance.new("IntValue", statsFolder)
	Fruit.Name = "Fruit"
	
	local Stand = Instance.new("IntValue", statsFolder)
	Stand.Name = "Stand"
	

	local Weapon = Instance.new("IntValue", statsFolder)
	Weapon.Name = "Weapon"


	local Health = Instance.new("IntValue", statsFolder)
	Health.Name = "Health"

	
	pcall(function()
		
		local data = levelDS:GetAsync(player.UserId .. "Level")
		
		if data then
			
			levelVal.Value = data[1]
			expVal.Value = data[2]
			Points.Value = data[3]
			Power.Value = data[4]
			Fruit.Value = data[5]
			Stand.Value = data[6]
			Weapon.Value = data[7]
			Health.Value = data[8]
		end
	end)
	
	
	expVal:GetPropertyChangedSignal("Value"):Connect(function()
		
		local neededExp = math.floor(levelVal.Value ^ 1.5 + 0.5) * 500
		
		if expVal.Value >= neededExp then
			
			levelVal.Value += 1
		end
	end)
	

	
end)


game.Players.PlayerRemoving:Connect(saveData)

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

I found a few errors in your code and re-wrote the code for ya.
By the way you cant use a “player” parameter in a normal function! you should make the function local to use that!

Changed:
I made the pcall functions variables to make stuff work possibly better:

the bindtoclose function was looping through every player in the game so i made it just for the leaving player:

also for future datastore testing go into the real server because it wont save in studio!

Code:

local dss = game:GetService("DataStoreService")
local levelDS = dss:GetDataStore("Levels")


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


	local statsFolder = Instance.new("Folder", player)
	statsFolder.Name = "Stats"

	local levelVal = Instance.new("IntValue", statsFolder)
	levelVal.Name = "Level"
	levelVal.Value = 1

	local expVal = Instance.new("IntValue", statsFolder)
	expVal.Name = "Experience"

	local Points = Instance.new("IntValue", statsFolder)
	Points.Name = "Points"

	local Power = Instance.new("IntValue", statsFolder)
	Power.Name = "Power"

	local Fruit = Instance.new("IntValue", statsFolder)
	Fruit.Name = "Fruit"

	local Stand = Instance.new("IntValue", statsFolder)
	Stand.Name = "Stand"


	local Weapon = Instance.new("IntValue", statsFolder)
	Weapon.Name = "Weapon"


	local Health = Instance.new("IntValue", statsFolder)
	Health.Name = "Health"

	
	local data = nil -- Has no value
	
	local Success = pcall(function() -- Changed this to a variable
		
		data = levelDS:GetAsync(player.UserId .. "Level")
		
	end)
	
	
	if Success and data then

		levelVal.Value = data[1]
		expVal.Value = data[2]
		Points.Value = data[3]
		Power.Value = data[4]
		Fruit.Value = data[5]
		Stand.Value = data[6]
		Weapon.Value = data[7]
		Health.Value = data[8]
		
	else
		
		local Items = {
			
			levelVal.Value, 
			expVal.Value, 
			Points.Value, 
			Power.Value, 
			Fruit.Value, 
			Stand.Value, 
			Weapon.Value, 
			Health.Value}
		
		levelDS:SetAsync(player.UserId .. "Level", Items)

	end
	


expVal:GetPropertyChangedSignal("Value"):Connect(function()

	local neededExp = math.floor(levelVal.Value ^ 1.5 + 0.5) * 500

	if expVal.Value >= neededExp then

			levelVal.Value += 1
	end
end)
end)

local function saveData(player) -- this is changed to local to use the player parameter (Local Player)

	local level = player.Stats.Level.Value
	local exp = player.Stats.Experience.Value
	local p = player.Stats.Points.Value
	local pwr = player.Stats.Power.Value
	local f = player.Stats.Fruit.Value
	local s = player.Stats.Stand.Value
	local w = player.Stats.Weapon.Value
	local he = player.Stats.Health.Value

	local Items_to_Save = {level, exp, p, pwr, f, s, w, he} -- Add every new piece of data here for now on!

	local Success, ErrorMessage = pcall(function()

		levelDS:SetAsync(player.UserId .. "Level", Items_to_Save)

	end)
	
	if Success then
		
		print("Saved Data!")
	else
		
		warn(ErrorMessage)
		print("Error Found!")
		
	end
end


game.Players.PlayerRemoving:Connect(function(Player)
	
	game:BindToClose(function()
		wait()
		
		saveData(Player)

	end)
	
end)

Bindtoclose is not always necessary because the script can see when a player leaves

1 Like