Confused on using UpdateAsync

I know that there are already topics on this, but they seem to be tapping into whether to use SetAsync() or the application of UpdateAsync(). I’m just trying to learn the different functionalities of data store at the moment. I want this data store to save the value of Points.


local pointsDataStore = game:GetService("DataStoreService"):GetDataStore("Points")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	local playerKey = "Player_"..plr.UserId
	local success, errormessage = pcall(function()
		pointsDataStore:UpdateAsync(playerKey, function(oldValue)
			local newValue = oldValue or 0
			return newValue
		end)
	end)
end)

So, what is wrong here?

3 Likes

Or would this be an instance where SetAsync() would be better? Even after reading posts about that topic, I am still a bit confused as to when you should do either.

Are you having errors? This seems like a completely valid use case for UpdateAsync and the code itself looks propper.

No errors noted. I added an if not success warn message to the code and nothing popped up.

LGTM. I fully support your use of UpdateAsync here. :+1:

Edit: Ignore my posts. I was under the impression that OP wanted to have the player start with 0 points if they haven’t had anything in the DataStore before.

1 Like

I think maybe this could be because it’s updating the value before it has time to get the value? Not really sure still. If that were the case, how would I go about waiting for the value?

If you have multiple scripts that look for the points whenever the player joins, you can always have a

(value gotten from datastore) or 0

in them. The script you initially posted will at some point update the DataStore to have 0. This way you’re guaranteed to never get nil.

So the issue would still be that it’s not getting the value from the data store and is instead giving the value of 0 though, wouldn’t it be? When I join the game the value is always 0.

I’ve not really done anything with PlayerRemoving, not sure if I needed to do that.

Here’s my leaderstats, maybe something in that caused this not to work:

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	
	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Value = 0
	points.Parent = leaderstats
end)

So I tried removing the or 0 part to see what happened and it still doesn’t work. Any feedback would be appreciated.

Current DataStore script:


local pointsDataStore = game:GetService("DataStoreService"):GetDataStore("Points")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	local playerKey = "Player_"..plr.UserId
	local success, errormessage = pcall(function()
		pointsDataStore:UpdateAsync(playerKey, function(oldValue)
			local newValue = oldValue
			return newValue
		end)
	end)
	if not success then
		warn("Could not save"..errormessage)
	elseif success then
		print("Progress updated")
	end
end)

you’re saving something that is already saved, try:

	local success, errormessage = pcall(function()
		pointsDataStore:UpdateAsync(playerKey, function(oldValue)
			local newValue = oldValue + points.Value
			return newValue
		end)
	end)

or just return points.Value

why are you saving when they join?..
and I don’t see you reference any points variable so what are you even trying to save

The problem with the script is that you are returning oldValue to UpdateAsync. That just sets the new data in the store to the data that is already there. Second issue is that your using UpdateAsync in PlayerAdded. There is no reason to save their data right when they join the game. You probably want to use GetAsync there because it returns the saved data.

To answer the question though, there is a whole article written about it here.

Simplified, it is recommend to use UpdateAsync as it can be used safer, not that it just is safer. Doing UpdateAsync and just returning the new data wouldn’t be much different from SetAsync.

As stated in the article, a good way of utilizing UpdateAsync is by having some kind of DataId that increments by one each time the player saves. The reason this prevents stuff like data loss is because GetAsync may not return the latest data, and if it didn’t, you can check for this inside of UpdateAsync by using the data id - if the data you are about to save is older than the saved data, you can stop saving

I haven’t read the whole thread, but I’m confused.

You’re using UpdateAsync, but you’re just using it to set a default value or keep the existing value? What actual update are you doing here??

Setting a default value is fine and dandy through UpdateAsync, but I don’t know why you’d do that if there’s never going to be anything but a default value.

I’m confused, I just want this to retain the same value that the player has when they leave the game. I.e. If a player leaves the game with 3 points, they should have 3 points when they rejoin.

GlobalDataStore:GetAsync (roblox.com)

Yes, I know how GetAsync works, but I’m trying to figure out how to do this with UpdateAsync.

You shouldnt do it with update async thats the thing

I don’t see why you would use update async > get async for getting the last saved value

UpdateAsync updates data. Your updating data when the player joins a game. Use GetAsync if you want to get the amount of points they have saved. Make sure you also use UpdateAsync when the player leaves or there wont be any data to retrieve with GetAsync.

1 Like

Doesn’t UpdateAsync allow the person to reference the last saved value with its second parameter?