Improving regular DataStore

Title pretty much says it all.

I haven seen some posts about this but none of them really helped me. More specific stuff for this would be:

  • How would I prevent data loss from servers that crash/shutdown?
  • Should I use :SetAsync() or :UpdateAsync(), why? I’ve heard it’s better to use :UpdateAsync() but don’t really know why.
  • Is there a more efficent way of how I wrote the code?

I wrote some sample code of how a regular DataStore would be:

Code
--Varibles

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("Data")

local function PlayerAdded(Player)
	
	--Create the values
	
	local leaderstats = Instance.new("Folder", Player)
	leaderstats.Name = "leaderstats"
	
	local Value1 = Instance.new("IntValue",leaderstats)
	Value1.Name = "Value1"
	
	local Value2 = Instance.new("IntValue",leaderstats)
	Value2.Name = "Value2"
	
	local Template = {
		["Value1"] = 100,
		["Value2"] = 0,
	}
	
	--Load data
	
	local PlayerData
	local success,errormessage = pcall(function()
		PlayerData = DataStore:GetAsync("player_"..Player.UserId)
	end)
	
	if PlayerData == nil then
		PlayerData = Template
	end
	
	if success then
		Value1.Value = PlayerData["Value1"]
		Value2.Value = PlayerData["Value2"]
	else
		print(errormessage)
	end
end

local function PlayerLeft(Player)
	
	local PlayerData = {
		["Value1"] = nil,
		["Value2"] = nil,
	}
	
	PlayerData["Value1"] = Player.leaderstats.Value1.Value
	PlayerData["Value2"] = Player.leaderstats.Value2.Value
	
	local success,errormessage = pcall(function()
		DataStore:SetAsync("player_"..Player.UserId,PlayerData) --Or :UpdateAsync()
	end)
	
	if success then
		print("Saved")
	else
		print(errormessage)
	end
	
end

--Call the functions

Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerLeft)

Note: This code wasn’t tested so it will not be perfect. It is just an example for those 3 questions.

For the first question: How would I prevent data loss from servers that crash/shutdown? I would recommend using the game:BindToClose() function. This function basically gives 30 seconds of time to run whatever code is inside the function, when the game is shutdown. I’d recommend using a loop to get every single player and then Kick() then to fire a PlayerRemoving event which will save the data.

For the second question: Should I use :SetAsync() or :UpdateAsync()? I’d recommend using UpdateAsync, unless the user doesn’t have any data stored. UpdateAsync just helps prevent data loss, as it keeps the old data in mind.

And third question: Is there a more efficient way of how I wrote the code? I’d definitely recommend implementing an auto save system to help prevent data loss, and I’d recommend using the game:BindToClose() function, like said previously. I’d also obviously use :UpdateAsync() instead of :SetAsync() to help prevent data loss.

A very good and informative guide is here

2 Likes

Also maybe try to save data again and again until it works. Only do this is the first time you tried to save the data it failed.

1 Like