My DataStore script will not save data and crashes my Roblox Studio when the session is ended

  1. What do you want to achieve?
    I made this DataStore Script for stats in my game and it will not save the progress of the stats.

  2. What is the issue? Include screenshots / videos if possible!
    I’m not quite sure since there are no errors in output. I’ve looked throughout the script multiple times and see no problem with it.

  3. What solutions have you tried so far?
    I’ve tired making new simple DataStore Scripts which still do not working. looked throughout YouTube for what could be wrong and even DevFourm and still no hope.

HERE IS HE CODE

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

local function SaveData(Player)
	
	local SaveTable = {}
	for i = 1, #Player:WaitForChild("StatsData"):GetChildren() do 
		
		if i == 1 then
			SaveTable[1] = Player:WaitForChild("StatsData"):WaitForChild("Focus").Value
		elseif i == 2 then
			SaveTable[2] = Player:WaitForChild("StatsData"):WaitForChild("Wisdom").Value
		elseif i == 3 then
			SaveTable[3] = Player:WaitForChild("StatsData"):WaitForChild("GoodFaith").Value
		elseif i == 4 then
			SaveTable[4] = Player:WaitForChild("StatsData"):WaitForChild("BadFaith").Value
				
end
		
		DataStore:SetAsync(Player.UserId, SaveTable)
end	
end
	

game.Players.PlayerAdded:Connect(function(Player)
	
	local DataFolder = Instance.new("Folder", Player)
	DataFolder.Name = "StatsData"
	
	
	local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
	Focus.Name = "Focus"
	
	
	local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
	Wisdom.Name = "Wisdom"
	
	
	local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
	GoodFaith.Name = "GoodFaith"
	
	local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
	BadFaith.Name = "BadFaith"
	
	
	
	local success, errormessage = pcall(function() -- IF THERE IS AN ERROR THIS WILL KEEP HE SCRIPT FROM STOPPING
	local RetrivedData = DataStore:GetAsync(Player.UserId)
		
		if RetrivedData then				
			
			-- YOUR STATS ARE GIVEN BACK HERE vvv		
				
				for i, value in pairs(RetrivedData) do
					
					
					if i == 1 then
						Focus.Value = value -- PLAYER IS GIVEN BACK THE FOCUS STAT IF PLAYED BEFORE
						
						
					elseif i == 2 then
						Wisdom.Value = value -- PLAYER IS GIVEN BACK THE WISDOM STAT IF PLAYED BEFORE
						
						
					elseif i == 3 then
							GoodFaith.Value = value -- PLAYER IS GIVEN BACK THE GOOD FAITH STAT IF PLAYED BEFORE
						

		            elseif i == 4 then
			             BadFaith.Value = value -- PLAYER IS GIVEN BACK THE BAD FAITH STAT IF PLAYED BEFORE				
end
end
						
					else -- YOU'LL BE GIVEN NOTHING BUT STATS AND A INTRO WHEN YOUR A NEW PLAYER vvv
			
			            Focus.Value = 0
						Wisdom.Value = 0
						GoodFaith.Value = 0
						BadFaith.Value = 0
end
end)
	
	
	
	if success then
		print("SUCCESSFULLY LOADED "..Player.Name.."SAVED DATA")
    else
		print("COULDN'T LOAD "..Player.Name.." DATA: ")
		print(errormessage)
	end	
end)



game:BindToClose(function()
	for i, Player in pairs(game.Players:GetChildren()) do
		SaveData(Player)
		
		wait(2)
	end
end)



game.Players.PlayerRemoving:Connect(function(Player)
		
		SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY

end)

Hi, I’m not sure if this will be a solution for you, but DataStore:SetAsync(Player.UserId, SaveTable) causes studio to hang because it’s currently saving your data, you have to wait for it to finish before you get out, if it infinitely hangs then try this to go ingame instead and test it, and use a datastore plugin manager or run this snippet of code below in a server script to see if your data saved, check the output in studio or in the developer console ingame to see if it worked, Also do what I stated below otherwise you are just running the function multiple times which causes it to hang longer
local RetrivedData = DataStore:GetAsync(502419991) -- This is your userid print(RetrivedData)
I see what you are trying to achieve here

You don’t need this spot below

If you’re only gonna save from a few spots, unless you want it to iterate through the whole thing

local SaveTable = {}
			SaveTable[1] = Player:WaitForChild("StatsData"):WaitForChild("Focus").Value
			SaveTable[2] = Player:WaitForChild("StatsData"):WaitForChild("Wisdom").Value
			SaveTable[3] = Player:WaitForChild("StatsData"):WaitForChild("GoodFaith").Value
			SaveTable[4] = Player:WaitForChild("StatsData"):WaitForChild("BadFaith").Value
DataStore:SetAsync(Player.UserId, SaveTable)
			

It should look like this if you want to save from a few specific values
This and some other pieces of code are still messy, but it should get you started

Thank you, I’ll take your advice and start working on it and come back to you to see if it’s worked or not.

If you are testing it in roblox studio and stop the session then it doesn’t crash, it’s just because of the wait() in the game:BindToClose(function()

Try this:

local DataStore = game:GetService("DataStoreService"):GetDataStore("Focus_Wisdom_GoodFaith_BadFaith_1")
local RunService = game:GetService("RunService")

local function SaveData(Player)
	local Focus = Player:WaitForChild("StatsData"):WaitForChild("Focus").Value
	local Wisdom = Player:WaitForChild("StatsData"):WaitForChild("Wisdom").Value
	local GoodFaith = Player:WaitForChild("StatsData"):WaitForChild("GoodFaith").Value
	local BadFaith = Player:WaitForChild("StatsData"):WaitForChild("BadFaith").Value

	local SaveTable = {
		["Focus"] = Focus,
		["Wisdom"] = Wisdom,
		["GoodFaith"] = GoodFaith,
		["BadFaith"] = BadFaith
	}
	local success, err = pcall(function()
		DataStore:UpdateAsync(Player.UserId, function(oldData)
			return SaveTable
		end)
	end)
	if not success then
		warn(err)
	end
end

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

	local DataFolder = Instance.new("Folder", Player)
	DataFolder.Name = "StatsData"

	local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
	Focus.Name = "Focus"

	local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
	Wisdom.Name = "Wisdom"

	local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
	GoodFaith.Name = "GoodFaith"

	local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
	BadFaith.Name = "BadFaith"

	local success, data = pcall(function()
		return DataStore:GetAsync(Player.UserId)
	end)
	if success and data then
		Focus.Value = data.Focus
		Wisdom.Value = data.Wisdom
		GoodFaith.Value = data.GoodFaith
		BadFaith.Value = data.BadFaith
	elseif not success then
		warn("There was an error loading the data for the player: " .. Player.Name)
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY
end)

game:BindToClose(function()
	if RunService:IsStudio() then
		return
	end
	for i, Player in pairs(game.Players:GetPlayers()) do
		SaveData(Player)
	end
end)

I recommend trying it on the roblox game client.

Thank you for for helping, I tired the remix you’ve done to my script and it has stopped crashing my studio when I end the session, However it doesn’t save the data. I went in game on a Roblox game client just like you said and gave my self a number value to one of the stats that should be saved. I left the game and printed out the stat and it unfortunately didn’t save and went back to the value 0 as shown here:

value 1
Here is me gaining one of the Stat Value and printing out the amount I’ve gained

value 2
Here is me after leaving the server and printing the Stat value that I gained in my last session ( which should be 5) which is 0 meaning the Data hasn’t been saved.

I’ve just done the advice you’ve told me to do and everything is perfect however, the Data does not save when the player leaves the game. I’ve tested this out and gave myself the value in the stat ‘Focus’ and left. I joined shortly after to see that my data had not been save and set back to the value 0.

The issue has to do with PlayerRemoving, you have to make sure the thread stays synchronized or “Instant” so to speak, so nothing can wait essentially, you can’t use waitforchild, or wait otherwise it won’t make it through the entire code, and you’ll lose the Player reference to the void.

This may not work still, so be weary of that, it’ll warn you on the first attempt if it can’t find data, but if you rejoin again, it’ll work fine in an ideal situation because then you’ll have data.

local DataStore = game:GetService("DataStoreService"):GetDataStore("Focus_Wisdom_GoodFaith_BadFaith_1")
local RunService = game:GetService("RunService")

local function SaveData(Player)
	local StatData = Player.StatsData
	local Focus = StatData.Focus.Value
	local Wisdom =	StatData.Wisdom.Value
	local GoodFaith = StatData.GoodFaith.Value
	local BadFaith  = StatData.BadFaith.Value

	local SaveTable = {
		["Focus"] = Focus,
		["Wisdom"] = Wisdom,
		["GoodFaith"] = GoodFaith,
		["BadFaith"] = BadFaith
	}
	local success, err = pcall(function()
		DataStore:UpdateAsync(Player.UserId, function(oldData)
			return SaveTable
		end)
	end)
	if not success then
		warn(err)
	end
	
end

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

	local DataFolder = Instance.new("Folder", Player)
	DataFolder.Name = "StatsData"

	local Focus = Instance.new("IntValue", DataFolder) -- GAINED FROM MEDITATING [ALLOWS TO GET CERTAIN CLASS' AND USE CERTAIN SPELLS AND WEAPONS]
	Focus.Name = "Focus"

	local Wisdom = Instance.new("IntValue", DataFolder) -- GAINED FROM READING [ALLOWS TO GET CERTAIN CLASS' AND UNLOCK CERTAIN SPELLS AND WEAPONS]
	Wisdom.Name = "Wisdom"

	local GoodFaith = Instance.new("IntValue", DataFolder) -- GAINED BY WORKSHIPING THE GOOD
	GoodFaith.Name = "GoodFaith"

	local BadFaith = Instance.new("IntValue", DataFolder) -- GGAINED BY WORKSHIPING THE BAD
	BadFaith.Name = "BadFaith"

	local success, data = pcall(function()
		return DataStore:GetAsync(Player.UserId)
	end)
	if success and data then
		Focus.Value = data.Focus
		Wisdom.Value = data.Wisdom
		GoodFaith.Value = data.GoodFaith
		BadFaith.Value = data.BadFaith
	elseif not success then
		warn("There was an error loading the data for the player: " .. Player.Name)
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	SaveData(Player) -- WHEN THE PLAYER LEAVES THE LOCAL FUNCTION WILL PLAY
end)

game:BindToClose(function()
	if RunService:IsStudio() then
		return
	end
	for i, Player in pairs(game.Players:GetPlayers()) do
		SaveData(Player)
	end
end)
1 Like

Unfortunately, the script didn’t work. but I understand what you say about the script can’t work if you add a ‘WaitForChild’ event to a ‘PlayerRemoving’ function or ‘GameBindToClose’ which makes me believe that where very close to unlocking the mystery to this script and making it work. I’m really do think the script should work but i honestly do not know what it wrong with it. Thank you for the help.

Your script does work. It was me who was in the wrong. I just realised that if I want the data to save I had to make the value change sever sided for it to change. all these time I was making me gain the value client sided. so all I had to do was add a server event and It started to save. sorry for all the problem and thank you.