Best way to add/remove values from server session?

I’m currently wondering what the best way to add or remove values to the data system below would be?

Current solutions that I can think of:

  • 1: Use an event that adds or removes values to the ServerData table when fired, and then update the leaderstats values using a function so the player can see his Fruit values.
  • 2: Use an event that overwrites/updates “ServerData” values with current values from the player’s leaderstats.
  • 3: Your suggestion on how to do this?

Data script:

--// 𝙎𝙀𝙍𝙑𝙀𝙍

--[[ 
	> These lines below tell you how to add data.
	> Add data: ServerData[player].Stats.DATA = ServerData[player].Stats.DATA + AMOUNT
--]]

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")
local ServerData = {}

local function newData()
	return {
		Fruits = {
			Bananas = 0,
			Oranges = 0,
			Apples = 0
		},
		Access = {
			Strawberry = false,
			Blueberry = false
		},
	}
end

local function loadData(player)
	local data
	local Success, Error = pcall(function() data = PlayerData:GetAsync("data:"..player.UserId) end)
	if not Success then
		warn("Could not get data for "..player.Name)
		return
	end
	if not data then
		data = newData()
	end
	ServerData[player] = data
end

local function saveData(player)
	if ServerData[player] then
		local Success, Error = pcall(function() PlayerData:SetAsync("data:"..player.UserId, ServerData[player]) end)
		if not Success then
			warn("Data wasn't saved for "..player.Name..".")
			return
		end
		ServerData[player] = nil
	end
end

local function addLeaderstats(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Bananas = Instance.new("IntValue")
	Bananas.Parent = leaderstats
	Bananas.Name = "Bananas"
	Bananas.Value = ServerData[player].Stats.Bananas or 0
	
	local Oranges = Instance.new("IntValue")
	Oranges.Parent = leaderstats
	Oranges.Name = "Oranges"
	Oranges.Value = ServerData[player].Stats.Oranges or 0
	
	local Apples = Instance.new("IntValue")
	Apples.Parent = leaderstats
	Apples.Name = "Apples"
	Apples.Value = ServerData[player].Stats.Apples or 0
end

game.Players.PlayerAdded:Connect(function(player)
	loadData(player)
	addLeaderstats(player)
end)

game.Players.PlayerRemoving:Connect(function(player)
	--// saveData(player)
	local retries, maxRetries = 0, 5
	repeat
		local Success = pcall(saveData, player) --// pcall(saveData, player) 
		retries = retries + 1
		wait(6)
		until Success or retries == maxRetries
	print("Saved " .. player.Name .. "'s data!")
end)

game:BindToClose(function(player)
	if RunService:IsStudio() then
		print("Not saving data, in studio!")
		return
	end
	
	local retries, maxRetries = 0, 5
	repeat
		local Success = pcall(saveData, player) 
		retries = retries + 1
		wait(6)
	until Success or retries == maxRetries
end)

Personally, I would just create a method called syncLeaderstats(player) that is called every time you update the server data for each player. You could then use the newly updated data from the serverData[player] to update the leaderstats. You could also use a .Changed even on each leaderstats Object to update the serverData table but that would be messier IMO.

2 Likes