Separate DataStores & Multiple Values - Improvement Needed

Greetings! I hope you’re having a great day so far.

Anywho, I’m looking to improve the organization of my data stores so that they’re more efficient (with respect to the limits of the DataStoreService). I’m not satisfied with the way my script is organized, as well as the inconsistency of data being saved/loaded.

For context, the code creates two values. The first is stored in a common leaderstats folder and is basically the currency for the game. The second value is stored directly inside of the player and represents the amount of Robux that the player has donated. My code is inside a server script, which is located in ServerScriptService.

Although my system works fine, there have been some rare occurrences where only the currency value is saved, and the donation amount is queued and dropped (resulting in the donation amount not being saved) when the player leaves the game. This is what I’m primarily worried about, and this also makes it clear that there’s definitely some room for improvement.

Code
local DataStoreService = game:GetService("DataStoreService")

local CashData = DataStoreService:GetDataStore("CashData")
local DonationData = DataStoreService:GetDataStore("DonationData")

game.Players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local cash = Instance.new("IntValue")
	cash.Name = "Cash"
	cash.Parent = leaderstats
	
	local donationamount = Instance.new("IntValue")
	donationamount.Name = "DonationAmount"
	donationamount.Parent = player
	
	local dataCASH
	local dataDONATION
	
	local success, errormessage = pcall(function()
		dataCASH = CashData:GetAsync(player.UserId .. "Cash")
		dataDONATION = DonationData:GetAsync(player.UserId .. "DonationAmount")
	end)
	
	if success then
		cash.Value = dataCASH
		donationamount.Value = dataDONATION
		print(player.Name .. " has joined the game. Their cash and donation stats have been successfully loaded.")
	else
		warn(player.Name .. " has joined the game. Their cash and donation stats COULD NOT be loaded due to an error. (" .. errormessage .. ")")
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local success, errormessage = pcall(function()
		CashData:SetAsync(player.UserId .. "Cash", player.leaderstats.Cash.Value)
		DonationData:SetAsync(player.UserId .. "DonationAmount", player.DonationAmount.Value)
	end)
	
end)

game:BindToClose(function(player)
	
	local success, errormessage = pcall(function()
		CashData:SetAsync(player.UserId .. "Cash", player.leaderstats.Cash.Value)
		DonationData:SetAsync(player.UserId .. "DonationAmount", player.DonationAmount.Value)
	end)
	
	if success then
		print(player.Name .. " has left the game. Their cash and donation stats have been successfully saved.")
	else
		warn(player.Name .. " has left the game. Their cash and donation stats COULD NOT be saved due to an error. (" .. errormessage .. ")")
	end
	
end)

All suggestions will be greatly appreciated, as I wish to have the most efficient data store system for the game I’m working on. Thank you in advance!

Consider saving these values in a table as soon as possible. Saving separate keys for values that are that related becomes a pain later on. Also look into using :UpdateAsync() and using the DataId ‘tecnic’ shown here.

(Also your bind to close doesn’t make sense)

1 Like