Datastore overview + advice and/or critisism

I want to make my code cleaner and/or maybe increase the safety of dataloss if it will ever occur.

  • What does the code do and what are you not satisfied with?
    Answer: I want to make the code more clean.

  • What potential improvements have you considered?
    Answer: I added tables for savings.

  • How (specifically) do you want to improve the code?
    Answer: Making it more readable and cleaner to work with when i eventually have around 100+ stats in it.

local dataStoreService = game:GetService("DataStoreService")
local ds = dataStoreService:GetDataStore("key")
local key = "Test1"

local stats = {
	["leaderstats"] = {
		["Cash"] = 0
	}
}

game:GetService("Players").PlayerAdded:Connect(function(plr)
	local data = ds:GetAsync(key.."/"..plr.UserId)
	print(data)
	
	for i, StatTable in pairs(stats) do
		local folder = Instance.new("Folder")
		folder.Name = i
		folder.Parent = plr
		
		for stat, value in pairs(StatTable) do
			local val_new = Instance.new("NumberValue")
			val_new.Name = stat
			val_new.Value = value
			val_new.Parent = folder
			if data then
				val_new.Value = data[folder.Name][stat]
			end
		end
	end
end)


local function SaveData(plr)
	local tableToSave = stats

	for i, folder in pairs(plr:GetChildren()) do
		if folder.ClassName == "Folder" then
			for i, stat in pairs(folder:GetChildren()) do
				tableToSave[folder.Name][stat.Name] = stat.Value
			end
		end
	end

	if tableToSave then
		local tries = 0
		repeat
			tries += 1
			local succ, err = pcall(function()
				local data = ds:UpdateAsync(key..'/'..plr.UserId,function(olddata)
					return tableToSave	
				end)
			end)
			if err then warn(err) task.wait(6) end
		until succ or tries == 3
		print("Data saved for " .. plr.Name)
	end
end

game:GetService("Players").PlayerRemoving:Connect(function(plr)
	SaveData(plr)
end)

game:BindToClose(function()
	for _, plr in ipairs(game:GetService("Players"):GetPlayers()) do
		coroutine.wrap(SaveData)(plr)
	end
end)

I’m pretty sure you could do micro improvements to that type of system. However, if you’re looking for a big upgrade that would support, like you said, hundreds of saved values at reasonable performance cost, you may look forward at using a DataStore library like ProfileService or DataStore2. To replicate player data to the client, you may want to use a custom replication library like ReplicaService. Check out the link below.

There is a good example of Datastore use in Studio if you create a new game and open the “Move It Simulator” example provided. Navigate to ServerScriptService/Data/DataStore. It’s not perfect but it provides a good starting point for managing large amounts of player data.

I would also refrain from NumberValues and use Remotes instead to probe a table with a loaded copy of the Datastore info to Set/Get values (methods of doing this are in the example). The example also has close bindings as well as auto-save capabilities.