Data Saving Problem

I was making a saving system with booleans and leaderstats and such, and the script has a weird error inside of it that I can’t seem to make go away.

here is the script:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("playerInstances")

game.Players.PlayerAdded:Connect(function(Player)
	local SticksOwnedFolder = Instance.new("Folder", Player)
	SticksOwnedFolder.Name = "SticksOwned"

	local Ice = Instance.new("BoolValue", SticksOwnedFolder)
	Ice.Name = "Ice"
	Ice.Value = false

	local Fire = Instance.new("BoolValue", SticksOwnedFolder)
	Fire.Name = "Fire"
	Fire.Value = false

	local Sparkly = Instance.new("BoolValue", SticksOwnedFolder)
	Sparkly.Name = "Sparkly"
	Sparkly.Value = false

	local Default = Instance.new("BoolValue", SticksOwnedFolder)
	Default.Name = "Default"
	Default.Value = true

	-- // Leaderstats 

	local Leaderstats = Instance.new("Folder", Player)
	Leaderstats.Name = "leaderstats"

	local Cash= Instance.new("IntValue", Leaderstats)
	Cash.Name = "Cash"
	Cash.Value = 0

	local Kills= Instance.new("IntValue", Leaderstats)
	Kills.Name = "Kills"
	Kills.Value = 0

	local gotData
	local Success,Errormsg = pcall(function()
		gotData = DataStore:GetAsync(Player.UserId)
	end)
	if gotData then
		Kills.Value = gotData.Kills
		Cash.Value = gotData.Cash
		Fire.Value = gotData.Fire
		Ice.Value = gotData.Ice
		Sparkly.Value = gotData.Sparkly
		Default.Value = gotData.Default
	else
		print("New Player Joined / No Data")
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Success,Errormsg = pcall(function()
		DataStore:SetAsync(Player.UserId, {
			["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
			["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
			["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
			["Default"] = Player.SticksOwnedFolder.Default.Value;
			["Cash"] = Player.leaderstats.Cash.Value;
			["Kills"] = Player.leaderstats.Kills.Value;
			
		})
		if Success then 
			return; 
		else
			warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
		end
	end)
end)

game:BindToClose(function()
	if game:GetService("RunService"):IsStudio() then
		wait(1.25)
	else
		for _, localplayer in pairs(game:GetService("Players"):GetPlayers()) do
			local Success, Error = pcall(function()
				DataStore:SetAsync(localplayer.UserId, {
					["Ice"] = localplayer.SticksOwnedFolder.Ice.Value; 
					["Fire"] = localplayer.SticksOwnedFolder.Fire.Value; 
					["Sparkly"] = localplayer.SticksOwnedFolder.Sparkly.Value;
					["Default"] = localplayer.SticksOwnedFolder.Default.Value;
					["Cash"] = localplayer.leaderstats.Cash.Value;
					["Kills"] = localplayer.leaderstats.Kills.Value;
				})
			end)
		end
	end
end)

The script error is in this line of code:

if Success then 
			return; 
		else

it is where it says “Success” and the error message says there is no Global “Success” when just a couple lines above there was a Success defined. No misspells or anything.

Move the “if Success then” line outside of the pcall:

local Success, Errormsg = pcall(function()
	DataStore:SetAsync(Player.UserId, {
		["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
		["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
		["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
		["Default"] = Player.SticksOwnedFolder.Default.Value;
		["Cash"] = Player.leaderstats.Cash.Value;
		["Kills"] = Player.leaderstats.Kills.Value;

	})
end)

if Success then 
	return; 
else
	warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
end

Or if you want to get fancy you can use xpcall:

xpcall(function()
	DataStore:SetAsync(Player.UserId, {
		["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
		["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
		["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
		["Default"] = Player.SticksOwnedFolder.Default.Value;
		["Cash"] = Player.leaderstats.Cash.Value;
		["Kills"] = Player.leaderstats.Kills.Value;

	})
end, function(errorMessage)
	warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
end)

Additionally I would suggest looking into using :UpdateAsync() rather than :SetAsync() GlobalDataStore:UpdateAsync

You put it inside your pcall:

local Success,Errormsg = pcall(function()
		DataStore:SetAsync(Player.UserId, {
			["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
			["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
			["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
			["Default"] = Player.SticksOwnedFolder.Default.Value;
			["Cash"] = Player.leaderstats.Cash.Value;
			["Kills"] = Player.leaderstats.Kills.Value;
			
		})
		if Success then 
			return; 
		else
			warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
		end
	end)

Should be:

local Success,Errormsg = pcall(function()
		DataStore:SetAsync(Player.UserId, {
			["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
			["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
			["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
			["Default"] = Player.SticksOwnedFolder.Default.Value;
			["Cash"] = Player.leaderstats.Cash.Value;
			["Kills"] = Player.leaderstats.Kills.Value;
			
		})
	end)
	if Success then 
		return; 
	else
		warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
	end

you cant put it inside of the pcall because Success and Errormsg are referenced outside of the function and are therefore unknown variables

notice how both success and err are underlined in yellow since they cannot be referenced:

the one exception to this is if you define success and err outside of the pcall and then reference them in a new thread but there’s really no point

local success, err
success, err = pcall(function()
	task.defer(function()
		print(success, err)
	end)
end)

I didn’t mean it that way. I meant that they put it inside their pcall as the problem. Mabye I just worded it weird…

1 Like

That stopped the error but now nothing is saving anymore, it just gives me the warn that I had set, even when testing it on actual servers and not Roblox Studio it does not save. And by the way I do have API services enabled.

On Studio, it shuts down the game server instead of doing .PlayerRemoving all the time. To work around this, implement a game:BindToClose() function to save all the players’ data:

game:BindToClose(function()
	for _, player in pairs(game.Players:GetChildren()) do
		--save data
	end
end)

I don’t know it game.Players:GetPlayers() and game.Players:GetChildren() work the same, so I just put one in there. The rest is up to you!

Plus, using game:BindToClose() is a good practice, in the event of the game shutting down.

I just implemented it and it didn’t change anything, data still does not save.

just for another reference here’s my UPDATED script:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("playerInstances")

game.Players.PlayerAdded:Connect(function(Player)
	local SticksOwnedFolder = Instance.new("Folder", Player)
	SticksOwnedFolder.Name = "SticksOwned"

	local Ice = Instance.new("BoolValue", SticksOwnedFolder)
	Ice.Name = "Ice"
	Ice.Value = false

	local Fire = Instance.new("BoolValue", SticksOwnedFolder)
	Fire.Name = "Fire"
	Fire.Value = false

	local Sparkly = Instance.new("BoolValue", SticksOwnedFolder)
	Sparkly.Name = "Sparkly"
	Sparkly.Value = false

	local Default = Instance.new("BoolValue", SticksOwnedFolder)
	Default.Name = "Default"
	Default.Value = true

	-- // Leaderstats 

	local Leaderstats = Instance.new("Folder", Player)
	Leaderstats.Name = "leaderstats"

	local Cash= Instance.new("IntValue", Leaderstats)
	Cash.Name = "Cash"
	Cash.Value = 0

	local Kills= Instance.new("IntValue", Leaderstats)
	Kills.Name = "Kills"
	Kills.Value = 0

	local gotData
	local Success,Errormsg = pcall(function()
		gotData = DataStore:GetAsync(Player.UserId)
	end)
	if gotData then
		Kills.Value = gotData.Kills
		Cash.Value = gotData.Cash
		Fire.Value = gotData.Fire
		Ice.Value = gotData.Ice
		Sparkly.Value = gotData.Sparkly
		Default.Value = gotData.Default
	else
		print("New Player Joined / No Data")
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Success,Errormsg = pcall(function()
		DataStore:SetAsync(Player.UserId, {
			["Ice"] = Player.SticksOwnedFolder.Ice.Value; 
			["Fire"] = Player.SticksOwnedFolder.Fire.Value; 
			["Sparkly"] = Player.SticksOwnedFolder.Sparkly.Value;
			["Default"] = Player.SticksOwnedFolder.Default.Value;
			["Cash"] = Player.leaderstats.Cash.Value;
			["Kills"] = Player.leaderstats.Kills.Value;
			
		})
	end)
	if Success then 
		return; 
	else
		warn("Uh oh! There was an error saving data for " .. Player.Name .. ", maybe ROBLOX datastores are down?") 
	end
end)



game:BindToClose(function()
	if game:GetService("RunService"):IsStudio() then
		wait(1.25)
	else
		for _, localplayer in pairs(game:GetService("Players"):GetPlayers()) do
			local Success, Error = pcall(function()
				DataStore:SetAsync(localplayer.UserId, {
					["Ice"] = localplayer.SticksOwnedFolder.Ice.Value; 
					["Fire"] = localplayer.SticksOwnedFolder.Fire.Value; 
					["Sparkly"] = localplayer.SticksOwnedFolder.Sparkly.Value;
					["Default"] = localplayer.SticksOwnedFolder.Default.Value;
					["Cash"] = localplayer.leaderstats.Cash.Value;
					["Kills"] = localplayer.leaderstats.Kills.Value;
				})
			end)
		end
	end
end)

game:BindToClose(function()
	for _, player in pairs(game.Players:GetChildren()) do
		local Success, Error = pcall(function()
			DataStore:SetAsync(player.UserId, {
				["Ice"] = player.SticksOwnedFolder.Ice.Value; 
				["Fire"] = player.SticksOwnedFolder.Fire.Value; 
				["Sparkly"] = player.SticksOwnedFolder.Sparkly.Value;
				["Default"] = player.SticksOwnedFolder.Default.Value;
				["Cash"] = player.leaderstats.Cash.Value;
				["Kills"] = player.leaderstats.Kills.Value;
			})
		end)
	end
end)

0 Errors in the script and the output when testing. Just gives me the "Uh oh! There was an error saving data for " … Player.Name … “, maybe ROBLOX datastores are down?” message in studio and doesn’t save on actual roblox servers

You don’t have anything printing to show the BindToClose() is running. It should be working as it should!

Add the Errormsg to your warn so you can see what’s actually happening.

	if Success then 
		return; 
	else
		warn("Uh oh! There was an error saving data for " .. Player.Name .. ". Error: "..Errormsg) 
	end

Also, you have 2 game:BindToClose() in your script

Did that, and it gave me a specific error so I fixed it and I don’t get the error message anymore, but it still does not save any changes I make to the Cash, Kills, etc. on anything. Am I missing something?

How are you changing the values? If you’re manually setting them through explorer, make sure you’re doing it in Server mode and not Client, see what I mean here.

I was missing something, I was using a localscript to add money to my character instead of a serverscript. fixed it and it works fine now.

1 Like