Is UpdateAsync() better in this case?

I have a datastore script that saves tycoon data on a plot. I am currently using Set and GetAsync() functions to set and read data. In this case, would UpdateAsync() be better. I have heard it’s better than Set and GetAsync().

You can look at the save and load functions here:

local function serialize(plr)
	FindPlot(plr) -- ignore this
	
	local key = "plr#" .. plr.UserId
	
	local data = {}
	
	for i, obj in pairs(ty.PlacedObjects:GetChildren()) do
		if obj then
			table.insert(data, {
				["Name"] = obj.Name,
				["CFS"] = {
					["X"] = ty.Plot.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).X;
					["Y"] =  ty.Plot.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).Y;
					["Z"] =  ty.Plot.CFrame:ToObjectSpace(CFrame.new(obj.PrimaryPart.CFrame.p)).Z;
					["R"] = obj.PrimaryPart.Orientation.Y
				}	
			})
		end
	end
	
	local success, err = pcall(function()
		dataStore:SetAsync(key, data)
	end)
	
	if not success then
		warn("Failed to serialize data: " .. tostring(err))
		
		return
	end
end

local function joinGame(plr)
	getPlot(plr)
	
	local tycoon = workspace.Plots:FindFirstChild(plot)
	
	-- DataStore
	
	local key = "plr#" .. plr.UserId
	local serializedData
	
	local success, err = pcall(function()
		serializedData = dataStore:GetAsync(key)
	end)
	
	if not success then
		warn("Failed to read data: " .. tostring(err))
		
		return
	end
	
	if serializedData then
		for i, data in pairs(serializedData) do
			if data then
				local serializedModel = game.ReplicatedStorage.Models:FindFirstChild(data.Name):Clone()
				
				if serializedModel then
					serializedModel.PrimaryPart.Transparency = 1
					serializedModel.PrimaryPart.CanCollide = false
					
					serializedModel:SetPrimaryPartCFrame(tycoon.Plot.CFrame * CFrame.new(data.CFS.X, data.CFS.Y, data.CFS.Z) * CFrame.Angles(0, math.rad(data.CFS.R), 0))
				end
				
				if serializedModel.PrimaryPart:FindFirstChild("Money") then
					serializedModel.PrimaryPart.Money.Enabled = true
				end
				
				if serializedModel.PrimaryPart:FindFirstChild("Owner") and serializedModel.PrimaryPart:FindFirstChild("AddCash") then
					serializedModel.PrimaryPart.Owner.Value = plr.Name
					serializedModel.PrimaryPart.AddCash.Disabled = false
				end
				
				serializedModel.Parent = tycoon.PlacedObjects
			end
		end
	else
		serialize(plr)
	end
end

The functions are called in the script on player added and player removing.
I have not tried to use UpdateAsync() in this situation, since I have never used it in any situation before.

UpdateAsync is better in cases where the data can be changed more than once at the same time, as it will validate the data you’re updating. UpdateAsync vs SetAsync is purely situational.

In your case, I’m not sure if the player’s cash can be change more than once at the same time, as I don’t know how your game works, but if it can’t, you can stick with SetAsync.

3 Likes

This saves tycoon data not cash.

UpdateAsync() is only useful when you’re updating existing data and it has lower limitations which you can check out here. With that being said, you can check if there is data when using GetAsync() and then you can decide which one to use.

local plrServ = game:GetService("Players")
local DSS = game:GetService ("DataStoreService")
local HTTP = game:GetService("HttpService")

local xData = DSS:GetDataStore("1")

local cache = {}

local function pAdded(p)
   local pId = p.userId
   local data 
   local succ,err = pcall(function() 
        data =  xData:GetAsync(pId)
   end)
   if succ then
     if data then
        cache[p.Name] = true
     end
end
end
local function pRemoving(p)
    local pId = p.userId 
    local data = someValueHere
    if cache[p.Name] then --then we can use GetAsync
        local succ,err = pcall(function()
       xData:UpdateAsync(pId, function(oldData)
            return data
        end)
      end)
       cache[p.Name] = nil
 else -- newPlayer (doesnt have data stored)
       local succ,err = pcall(function()
         xData:SetAsync(pId,data)
        end)
   end

plrServ.PlayerAdded:Connect(pAdded)
plrServ.PlayerRemoving:Connect(pRemoving)

Hope that cleared up stuff (on mobile don’t mind my bad intending)

2 Likes