How can I prevent Data Loss?

So my game is having Data Loss, which it obviously is not a good thing to happen in your game. But my game is experiencing that and I don’t know how to fix that. Yes, my API Service is on and I’m using Pcalls. Here is my leaderstats script and table.insert (inventory) script:

Leaderstats:

-- leaderstats

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MainPlayerData")
local Players = game:GetService("Players")

local function saveData(player)
	local tableToSave = {
		player.leaderstats.Points.Value,
		player.leaderstats.Rubys.Value,
		player.leaderstats.playTime.Value,
		player.leaderstats.Deaths.Value,
		player.leaderstats.Kills.Value
	}
	
	local success, errorMessage = pcall(function()
		DataStore:SetAsync(player.UserId, tableToSave)
	end)
	
	if success then
		print("Data Saved For Player's Leaderstats")
	else
		print("Data Did Not Save For Player's Leaderstats")
		warn(errorMessage)
	end
end

game.Players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	local Points = Instance.new("IntValue")
	Points.Name = "Points"
	Points.Parent = leaderstats

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

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

	local Kills = Instance.new("IntValue")
	Kills.Name = "Kills"
	Kills.Parent = leaderstats
	
	leaderstats.Parent = player
	
	player.CharacterAdded:Connect(function(char)
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			Deaths.Value = Deaths.Value + 1
		end)
	end)
	
	
	local data
	local success, errorMessage = pcall(function()
		data = DataStore:GetAsync(player.UserId)
	end)
	
	if success and data then
		Points.Value = data[1]
		Rubys.Value = data[2]
		playTime.Value = data[3]
		Deaths.Value = data[4]
		Kills.Value = data[5]
	else
		print("Player has no Data")
	end
	
	while true do
		wait(60)
		playTime.Value = playTime.Value + 1
	end
	
	task.spawn(function()
		while true do
			task.wait(60)
			playTime.Value = playTime.Value + 1
		end
	end)
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errorMessage = pcall(function()
		saveData(player)
	end)
	
	if success then
		print("Players Leaderstats Saved Successfully")
	else
		warn(errorMessage)
	end
end)

game:BindToClose(function()
	for _, player in pairs(Players:GetPlayers()) do
		local success, errorMessage = pcall(function()
			saveData(player)
		end)
		
		if success then
			print("Data has been saved")
		else
			print("Data has not been saved!")
		end
		
	end
end)

Inventory Script (table.insert):

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

local Players = game:GetService("Players")

local function addFolderGuns(player)
	local folder = Instance.new("Folder")
	folder.Name = "myInventory"
	folder.Parent = player

	local data

	local success, errorMsg = pcall(function()
		data = DataStore:GetAsync(player.UserId)
	end)

	if data ~= nil then
		if data.Inventory then
			for index,inventory  in pairs(data.Inventory) do
				local bool = Instance.new("BoolValue",folder); bool.Name = inventory
			end
		end
	else
		-- New player
		print("A new player has joined")
	end
end

game.Players.PlayerAdded:Connect(addFolderGuns)

for _, player in pairs(Players:GetPlayers()) do
	spawn(function()
		addFolderGuns()
	end)
end

game.Players.PlayerRemoving:Connect(function(plr)
	local data = {}

	data.Inventory = {}

	for i,v in pairs(plr.myInventory:GetChildren()) do
		table.insert(data.Inventory,v.Name)
	end

	local success, errorMsg = pcall(function()
		DataStore:SetAsync(plr.UserId,data)
	end)

	-- if its succeed then the data is saved else we got an error

	if success then 
		print("Succesfully saved") 
	else 
		print(errorMsg) 
	end

end)

local function gameBindSave(plr)
	local data = {}

	data.Inventory = {}

	for i,v in pairs(plr.myInventory:GetChildren()) do
		table.insert(data.Inventory,v.Name)
	end

	local success, errorMsg = pcall(function()
		DataStore:SetAsync(plr.UserId,data)
	end)

	-- if its succeed then the data is saved else we got an error

	if success then 
		print("Succesfully saved") 
	else 
		print(errorMsg) 
	end
end

game:BindToClose(function()
	for _, v in pairs(Players:GetPlayers()) do
		gameBindSave(v)
	end
end)

If you can help, thank you very much!

papahetfan

I’d recommend switching to ProfileService, an amazing thing tbh. Haven’t had any problems with that.

1 Like

use UpdateAsync instead of SetAsync, like this:

DataStore:UpdateAsync(player.UserId, function(OldData)
    return tableToSave or OldData
end)

i assume leaderstats is a script, and inventory script is a localscript. (correct me if i’m wrong please)

I think if you use the print command somewhere in your code like in inventory script to see if lua data.Inventory has the correct currect data before the player leaves.

message above me is a good suggestion

Profile Service is amazing module and I have never got a time a Data Loss happen

Not only that it has alot more features that regular datastore don’t have

+1, I’ve never had issues with data since switching to ProfileService

1 Like

So what should I do with ProfileService?