What is best way to save this data?

Hello, I am developing my tower game, however I run into serious issues like dataloss. Which occurs in most of my players that have poor/slow internet. I am saving this data:

image

My current method of saving this is:

local ToStoreName = script.Parent.Parent.Name.. script.Parent.Name.. script.Name
local DataStore = game:GetService("DataStoreService"):GetDataStore("DataStore")

game.Players.PlayerAdded:Connect(function(player)
	local folder = game.Players[player.Name]:WaitForChild("Inventory")
	folder = folder:WaitForChild(script.Parent.Parent.Name)
	folder = folder:WaitForChild(script.Parent.Name)
	wait()
	if folder then
		local ToStore = Instance.new("BoolValue")
		ToStore.Name = ToStoreName
		ToStore.Parent = folder
	
		local ID = ToStoreName.."-"..player.userId
		local savedData = nil
	
		local success, err = pcall(function()
			savedData = DataStore:GetAsync(ID)
		end)
		
		if success ~= true then
			warn(err)
		end
		
		if savedData ~= nil then
			ToStore.Value = savedData
		else
			ToStore.Value = false
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local ID = ToStoreName.."-"..player.userId
	local success, err = pcall(function()
		DataStore:UpdateAsync(ID, function(oldValue)
			local newValue = oldValue or 0
			newValue = player.Inventory[script.Parent.Parent.Name][script.Parent.Name][ToStoreName].Value
			return newValue
		end)
	end)
	if success ~= true then
		warn(err)
	end
	--DataStore:SetAsync(ID, player.Inventory[script.Parent.Parent.Name][script.Parent.Name][ToStoreName].Value)
end)

I am trying to do it using tables:

local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")

local DataTemplate = {
	Towers = {
		Commander = {Purchased = false, Equipped = false},
		FireworkMurder = {Purchased = false, Equipped = false},
		Freezer = {Purchased = false, Equipped = false},
		JeepBase = {Purchased = false, Equipped = false},
		John = {Purchased = false, Equipped = false},
		NoobMiniGunner = {Purchased = false, Equipped = false},
		NoobyMachine = {Purchased = false, Equipped = false},
		NoobyNew = {Purchased = false, Equipped = false},
		NoobyShooter = {Purchased = false, Equipped = false},
		NuclearStation = {Purchased = false, Equipped = false},
		PlantBase = {Purchased = false, Equipped = false},
		PlazmaExpert = {Purchased = false, Equipped = false},
		PoliceNoob = {Purchased = false, Equipped = false},
		Rocketer = {Purchased = false, Equipped = false},
		Sniper = {Purchased = false, Equipped = false},
		TankBase = {Purchased = false, Equipped = false},
		ZeroTwo = {Purchased = false, Equipped = false}
	},
	Stats = {
		Coins = 0,
		Cxp = 0,
		Nxp = 100,
		Level = 0
	},
	Achievements = {
		Welcome = {Unlocked = false},
		FirstGame = {Unlocked = false},
		TenGames = {Unlocked = false},
		OneHundredGames = {Unlocked = false}
	}
}

local module = {}
	function module.getDataFromPlayer(Player)
		local UserKey = "Player_" .. Player.UserId
		local Data = PlayerData:GetAsync(UserKey)
		wait()
		if Data and Data ~= nil then
			return Data
		else
			Data = DataTemplate
			wait()
			return Data
		end
	end
	function module.saveDataToPlayer(Player, Data)
		local UserKey = "Player_" .. Player.UserId
		if Data and Data ~= nil then
			PlayerData:SetAsync(UserKey, Data)
		end
	end
return module

But I am not sure what would be best way, I tried first method I am currently using, and I keep getting dataloss, I didn’t use the method with tables, because I am not sure how to do it. I saw datastore2 but I dont get how to use it still. I am terrible at datastores

Any suggestions to fix one of those scripts, or an method how I could save it (please include example script and explanation if possible, thanks!).

1 Like

You could use Datastore2 which is a much more efficient way to save data, and is meant to save bigger things rather than a regular datastore.

How to use DataStore2 - Data Store caching and data loss prevention is an open sourced module with a re-written datastore infrastructure that relies on the internal cache I believe to prevent data loss.
Very simple to use so it wont be difficult to migrate.
Says in thread not yet one single case of data loss.

Hope this helps!