Safe way to save player data?

Ok so. Im making a DataStore that will save a players: Coins, Wins. And deaths.

The “getData” function basically does what it says. It gets the players saved data. And the “saveData” function saves a players data when they leave. Or when the game shutsdown.

But i want to ask. Is this a good and safe way to save… Is there anything i could improve?

GET DATA FUNCTION

function getData(Key)
	local Sucess, Err = nil
	local Tries = 0
	local Table = nil
	
	
	repeat
		Sucess, Err = pcall(function()
			Table = Store:GetAsync(Key)
		end)
		Tries = Tries + 1
		wait(0.5)
	until Sucess == true or Tries >= 10
	if Sucess == true then
		if Table ~= nil then
			return Table
		else
			return nil
		end
	else
		error(Err..", Sent this to the developer!")
	end
end

SAVE FUNCTION:

function saveData(Key, Table)
	
	
	Store:UpdateAsync(Key, function(Old)
		local returnedTable = Old
		if Table["COINS"] ~= Old["COINS"] then
			returnedTable["COINS"] = Table["COINS"]
			warn("CAN UPDATE COINS")
		end

		if Table["WINS"] ~= Old["WINS"] then
			returnedTable["WINS"] = Table["WINS"]
			warn("CAN UPDATE WINS")
		end

		if Table["DEATHS"] ~= Old["DEATHS"] then
			returnedTable["DEATHS"] = Table["DEATHS"]
			warn("CAN UPDATE DEATHS")
		end


		return returnedTable
	end)
end

PLAYER JOINING:

game.Players.PlayerAdded:Connect(function(Player)
	local Folder = Instance.new("Folder")
	Folder.Name = "leaderstats"
	Folder.Parent = Player
	
	local Coins = Instance.new("IntValue")
	Coins.Name = "COINS"
	Coins.Parent = Folder

	local Wins = Instance.new("IntValue")
	Wins.Name = "WINS"
	Wins.Parent = Folder

	local Deaths = Instance.new("IntValue")
	Deaths.Name = "DEATHS"
	Deaths.Parent = Folder
	
	
	local Data = getData(Player.UserId)
	if Data == nil then
		warn("NEW PLAYER")
		Store:SetAsync(Player.UserId, {
			["COINS"] = 0;
			["WINS"] = 0;
			["DEATHS"] = 0;
		})
	else
		Coins.Value = Data["COINS"]
		Wins.Value = Data["WINS"]
		Deaths.Value = Data["DEATHS"]
	end
end)

PLAYER LREAVING:

game.Players.PlayerRemoving:Connect(function(Player)
	local statsToSave = {
		["COINS"] = 0;
		["WINS"] = 0;
		["DEATHS"] = 0;
	}
	
	
	for _, v in pairs(Player.leaderstats:GetChildren()) do
		if v.Value ~= 0 then
			statsToSave[v.Name:upper()] = v.Value
		end
	end
	
	
	saveData(Player.UserId, statsToSave)
end)
2 Likes

I’m not sure, but this helps to properly save player data in game shutdown

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Save = function(Player)
	--save thing..
end
game:BindToClose(function()
	for i,Player in pairs(Players:GetPlayers())do
		coroutine.wrap(Save)(Player)
	end
end)
7 Likes

A form of auto saving can also help if you implement it correctly :slight_smile:

Auto saving is good because maybe the server might crash and it wouldn’t save :(

So that’s another tip.

1 Like

So my saving script is good as it is. Or ss there anything that could be improved or??

Also thanks for all the tips.