I’m currently in the process of setting up my latest datastore. I was just wondering, what would you recommend to save player data: SetAsync or UpdateAsync? In the past, I’ve always used SetAsync, however the wiki recommends the latter:
UpdateAsync is the one to use. It will compare to make sure that the data hasn’t been changed while you were in the process of setting it, and in that event, it will retry given the latest value that is currently saved.
SetAsync is for data that you want to force to be clobbered.
An example of UpdateAsync doing it’s magic:
Datastore: x = 0
GameserverA and GameserverB simultaneously: use UpdateAsync() to add 10 to x
Datastore: x = 20
An example of SetAsync doing it’s set overwrite:
Datastore: x = 0
Game Server A and Game Server B simultaneously: newX = x+10 (result newX = 10)
Game Server A and Game Server B simultaneously: use SetAsync() to set x to newX
Datastore: x = 10
You need to look out with saving data from other servers if you save a local copy of the data when the player first joins. You may override data even when you use UpdateAsync.
I learned data stores with :SetAsync(), been using it for over a year now and have had many issues with it (data loss / overwrites). I highly recommend using UpdateAsync. My friend, mightybaseplate, uses it for counter blox’s skin saving and we haven’t had any issues with data loss.
Use UpdateAsync. Every time you save, ensure that the data you are saving is not overwriting old data. A good way to ensure you aren’t overwriting old data is putting a counter in user data that is incremented every time you save. If the data you are about to save has a lower counter than existing data, you have a problem and saving would erase the player’s existing data.
Only really feasible if you can fit all of your player associated data into a single data store key per player.
Trying to use that approach with multiple data store keys would get hairy really fast because it would be easy to get into an inconsistent state. Even with just a single key it took me a couple hundred lines to write a really bulletproof implementation of it. You also inherently use double the datastore requests because you have to update the data table and timestamp table on each save, so if you’re already riding on the limit it might not be an option.