Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Save/load data stopped working?

Randomly when I was trying to encode boats into my game I realize that whenever I would go in to test the buying system my money would always be set back to whatever it was. There are no errors when saving/loading as It prints the message it should when it is successful

local remote = game:GetService("ReplicatedStorage"):WaitForChild("QuestRemote")

local data = game:GetService("DataStoreService")
local my_data = data:GetDataStore("my_data")

game.Players.PlayerAdded:Connect(function(player)
	--for stats
	local gold
	local level
	local exp
	
	-- for quest stuff
	local QuestTitle
	local QuestTask
	local QuestObjective
	local QuestProgress
	local QuestGold
	local QuestExp
	
	--to tell if the boat is bought or not
	local schooner_ship
	
	
	local sucess, errormessage = pcall(function()
		gold = my_data:GetAsync(player.UserId.."-gold")
		level = my_data:GetAsync(player.UserId.."-level")
		exp = my_data:GetAsync(player.UserId.."-exp")
		
		QuestTitle = my_data:GetAsync(player.UserId.."-QuestTitle")
		QuestTask = my_data:GetAsync(player.UserId.."-QuestTask")
		QuestObjective = my_data:GetAsync(player.UserId.."-QuestObjective")
		QuestProgress = my_data:GetAsync(player.UserId.."-QuestProgress")
		QuestGold = my_data:GetAsync(player.UserId.."-QuestGold")
		QuestExp = my_data:GetAsync(player.UserId.."-QuestExp")
		
		schooner_ship = my_data:GetAsync(player.UserId.."-schooner_ship")
		
	end)
	
	if sucess then
		print("data sucessfully loaded")
		player.stats.Gold.Value = gold
		player.stats.Level.Value = level
		player.stats.Exp.Value = exp
		
		player.QuestInformation.QuestTitle.Value = QuestTitle
		player.QuestInformation.QuestTask.Value = QuestTask
		player.QuestInformation.QuestObjective.Value = QuestObjective
		player.QuestInformation.QuestProgress.Value = QuestProgress
		player.QuestInformation.QuestGold.Value = QuestGold
		player.QuestInformation.QuestExp.Value = QuestExp
		
		player.Boats_bought.schooner_ship.Value = schooner_ship
		
		if QuestTitle == "Default" then
			--does nothing if the title is default
		else
			remote:FireClient(player, "TransferBritish")
		end
	else
		print("there was an error getting your data")
		warn(errormessage)
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	--for all stats
	local sucess, errormessage = pcall(function()
		my_data:SetAsync(player.UserId.."-gold", player.stats.Gold.Value)
		my_data:SetAsync(player.UserId.."-level", player.stats.Level.Value)
		my_data:SetAsync(player.UserId.."-exp", player.stats.Exp.Value)
		-- for quest progression
		my_data:SetAsync(player.UserId.."-QuestTitle", player.QuestInformation.QuestTitle.Value)
		my_data:SetAsync(player.UserId.."-QuestTask", player.QuestInformation.QuestTask.Value)
		my_data:SetAsync(player.UserId.."-QuestObjective", player.QuestInformation.QuestObjective.Value)
		my_data:SetAsync(player.UserId.."-QuestProgress", player.QuestInformation.QuestProgress.Value)
		my_data:SetAsync(player.UserId.."-QuestGold", player.QuestInformation.QuestGold.Value)
		my_data:SetAsync(player.UserId.."-QuestExp", player.QuestInformation.QuestExp.Value)
		
		my_data:SetAsync(player.UserId.."-schooner_ship", player.Boats_bought.schooner_ship.Value)
	end)
	
	if sucess  then
		print("data successfully saved!")
	else
		print("there was an error saving data")
		warn(errormessage)
	end
	
end)

I did go into server-side while coding to give myself money so maybe that could be the issue but I've never had a problem like that previously

1 comment

1

You didn’t make the stats dolder in the player. Make the stats folder in PlayerAdded

1 answer

I noticed that you didn't make the stats folder in the player. In PlayerAdded, always make the stats folder, then you can identify it. Also, when getting ad saving the data, I recommend repeating the pcall until it returns success and putting all data in a table when saving it.

And when the server is getting shut down, it kicks the player before it fires the PlayerRemoving event. To avoid that, we'll use the game:BindToClose() function.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")

local remote =ReplicatedStorage:WaitForChild("QuestRemote")
local my_data = DataStoreService:GetDataStore("my_data")

function GetData(player)
	-- getting the data
	local key = player.UserId .. "-player_dataTable"
	local success, dataTable
	
	repeat
		success, dataTable = pcall(my_data.GetAsync, my_data, key)
	until (success and dataTable) or not Players:FIndFirstChild(player.Name)
	
	if success then
		-- for stats
		player.stats.Gold.Value = dataTable.stats.Gold or 0
		player.stats.Level.Value = dataTable.stats.Level or 0
		player.stats.Exp.Value = dataTable.stats.Exp or 0
		
		-for quest stuff
		player.QuestInformation.QuestTitle.Value = dataTable.questInfo.QuestTitle or ""
		player.QuestInformation.QuestTask.Value = dataTable.questInfo.QuestTask or ""
		player.QuestInformation.QuestObjective.Value = dataTable.questInfo.QuestObjective or ""
		player.QuestInformation.QuestProgress.Value = dataTable.questInfo.QuestProgress or 0
		player.QuestInformation.QuestGold.Value = dataTable.questInfo.QuestGold or 0
		player.QuestInformation.QuestExp.Value = dataTable.questInfo.QuestExp or 0
		
		-- others
		player.Boats_bought.schooner_ship.Value = dataTable.boatsBought.schooner_ship or false
		
		print("Data has been loaded successfully!")
	end
end

function SaveData(player)
	local stats = player:WaitForChild("stats")
	local questInfo = player:WaitForChild("QuestInformation")
	local boatsBought = player:WaitForChild("Boats_bought")
	 
	-- saving the data
	local key = player.UserId .. "-player_dataTable"
	local dataTable = {
		["stats"] = {
			Gold = stats:WaitForChild("Gold").Value,
			Level = stats:WaitForChild("Level").Value,
			Exp = stats:WaitForChild("Exp").Value
		},
		
		["questInfo"] = {
			QuestTitle = questInfo:WaitForChild("QuestTitle").Value,
			QuestTask = questInfo:WaitForChild("QuestTask").Value,
			QuestObjective = questInfo:WaitForChild("QuestObjective").Value,
			QuestProgress = questInfo:WaitForChild("QuestProgress").Value,
			QuestGold = questInfo:WaitForChild("QuestGold").Value,
			QuestExp = questInfo:WaitForChild("QuestExp").Value
		},
		
		["boatsBought"] = {
			schooner_ship = boatsBought:WaitForChild("schooner_ship").Value
		}
	}
	
	local success, result
	
	repeat
		success, result = pcall(my_data.UpdateAsync, my_data, key, function(oldData)
			return dataTable
		end)
	until success
	
	if success then
		print("Data has been saved successfully!")
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	coroutine.wrap(GetData)(player)
end

Players.PlayerAdded:Connect(GetData)
Players.PlayerRemoving:Connect(SaveData)

game:BindToClose(function()
	if RunService:IsStudio() then
		task.wait(2)
	else
		local finished = Instance.new("BindableEvent")
		local allPlayers = Players:GetPlayers()
		local leftPlayers = #allPlayers

		for _, player in ipairs(allPlayers) do
			coroutine.wrap(function()
				SaveData(player)
				leftPlayers -= 1
				if leftPlayers == 0 then
					finished:Fire()
				end
			end)()
		end

		finished.Event:Wait()
	end
end)

4 comments

0

Thanks for the reply!. The player stats folder and values are already created and assigned to the player it's just in a separate script not related to this one. Also correct me if i'm wrong but bindtoclose is a function for when the server shuts down?. The script above is just for saving a players data when they decide to leave the game

0

Also the script above has worked just fine for the longest time and I haven't touched it up until recently when I did a boat buying system and noticed then that the new data was not saving. It only saves the old data even though in the player folder the value is updated?

0

If that's the case, use SetAsync instead. When the server shuts down, it's not always that the PlayerRemoving event will run.I fixed the script.

0

Oh wait nvm you still have to use UpdateAsync

This discussion is preserved as it was. New answers, comments, and votes are closed.