Recently, I had a discussion in the discord about whether or not to use :UpdateAsync or :SetAsync mainly because I did not need to access the previous values when saving the player's data. I have been mostly encouraged to use :UpdateAsync because it does not return a cached value. However, I don't need to know what the returned value is. Is it worth it to use :UpdateAsync which requires the creation of a function? Another thing that came up during that discussion was that I was creating two functions and using each only once. I am wondering when I should decide not to use functions and when to use functions. You see, I was setting an index in a table to the value returned by the functions and I felt that a function was easier. Here is the script:
local function saveData(player, retryCompatible) local dataStoreService = game:GetService("DataStoreService") local mainDataStore = dataStoreService:GetDataStore("generic") local function createTableOfNames(objectList) local newTable = {} for i,v in pairs(objectList:GetChildren()) do table.insert(newTable, v.Name) end return newTable end local function findEquipedTool(starterGear) local starterGearList = starterGear:GetChildren() if #starterGearList > 1 then return false else for i,v in pairs(starterGear:GetChildren()) do return v.Name end end end local replicatedStorage = game:GetSErvice("ReplicatedStorage") local stats = replicatedStorage.Stats local playerData = stats:FindFirstChild(player.Name) local purchasedItems = playerData.PurchasedItems local spaceCoins = playerData.SpaceCoins local snow = playerData.Snow local starterStuff = player.StarterGear local equippedTool = findEquipedTool(starterStuff) local listToSave = {} local specialKey = "User-"..player.UserId listToSave["Equipped"] = equippedTool listToSave[purchasedItems.Name] = createTableOfNames(purchasedItems:GetChildren()) listToSave[spaceCoins.Name] = spaceCoins.Value listToSave[snow.Name] = snow.Value local success, message = pcall( mainDataStore.SetAsync, specialKey, listToSave ) if not success and retryCompatible then local maxRetryAttempts = 3 local retryAttempts = 0 repeat wait(5) local success, message = pcall( mainDataStore.SetAsync, mainDataStore, specialKey, listToSave ) retryAttempts = retryAttempts + 1 until retryAttempts == maxRetryAttempts or success end end return saveData
I am wondering if I should use :UpdateAsync in the areas where :SetAsync is being used. Also, you can see the two functions I create that I only use once each. I would appreciate any insight you guys may have. Thanks!
They have different purposes, if you just need to set a value then use Set if you need a function to update a value then use Update. If there are several servers writing to the same key you most likely don't want values to overwrite each other, hence update. If it's updating the cash value of a player for example, it doesn't matter what was there before, then set.
Update: Lets look at two scenarios
Scenario #1 We have a player in our server that has cash and purchased something during the game, we got his cash when he joined, no other server is editing his cash value and the current server knows exactly what it should be, when he leaves it doesn't matter what the old value in the datastore is, because we got it before and nothing else would affect it. When they leave we use Set.
Scenario #2 I have a list of unique names that records in what order the first time a player joined our game is. At the moment it looks like this [noob, gullet]. Then someone joins Server#1 and this is his first time playing. So to update the list we need to know what the list looks like so far, so we get the list. Then a split second later someone joins Server#2 also for their first time. So Server#2 gets the list so it can update it. Server#1 adds builderman to the list, in Server#1 it now looks like [noob, gullet, builderman] and it Sets the list to the datastore. Then Server#2 adds guest to the list he got and it now looks like [noob, gullet, guest]. He then Sets the list to the datastore.
The datastore now has a value of [noob, gullet, guest] because that's what was last set, and builderman was lost because Server#1 didn't set the list fast enough before Server#2 needed to get it.
To fix this we instead use Update which can queue functions to be performed on the saved value, if we have a function that appends a name to the list, we don't need to get it to do the calculation on either server they can both send their function to add a certain name and the one that reaches it first will add it first but they will never cancel each other out.
I don't know, but you can make a table save itself by using any of them even if you mix them in your script.