I’ve been quite surprised to see the low rate of adoption of the new DataStoreService. Talking a look at things I’m guessing that a big part of the reason is that it’s not so obvious how to easily attach data in the new DataStores to a individual players, and there’s the fact that you really need some caching+intermittent saves inbetween your actual writes to a player’s data, and that data being loaded/saved.
To take down those barriers I’ve written a module that handles both of those things for you. The design of the module is such that you can use it as a sort of “drop in” adapter between code wanting the old style DataPersistence and the new DataStoreService API.
What the module does is automagically cache the DataStoreService data for each player (including offline players if you want that) and batch reads and writes to that player data so that you can have immediate reading and writing of it while letting a intermittent task in the module save the data in batches.
The module also does really nice things such as:
[ul]
[li]Ensure that nothing goes wrong if there is cached data for a player who is not online in the instance, and then that player actually joins the instance. The module will make sure that the cached data is always associated with the player whether online in the place or not.[/li]
[li]Let you plug in custom Serialization / Deseralization for specified keys of the stored data.[/li]
[li]Just like with the old DataPersistence API, data for players who are currently in the server is automacically loaded in and cached unless it was already loaded in manually by some script like a leaderboard while the player was not online.[/li]
[li]Unloads cached data after a certain delay, but only if the user it’s associated with has left the server, and only if no other code in your project is still holding onto references to that SaveData object storing the cached data. Basically, if the data should still be kept in the cache then it is being kept, and you won’t ever be doing more DataStore requests than you need to be by having to re-get it.[/li]
[li]It doesn’t randomly delete your stored data for no reason ← most important reason right there[/li]
[/ul]
The ModuleScript in question is attached. Here’s an example of it at it’s simplest, used exactly like the old DataPersistence API on the Player:
local PlayerDataStore = require(game.ServerScriptService.PlayerDataStore)
--... then in the game logic somewhere:
local saveData = PlayerDataStore:GetSaveData(player)
saveData:Set('Score', (saveData:Get('Score') or 0) + 1)
local PlayerDataStore = require(game.ServerScriptService.PlayerDataStore)
game.Players.ChildAdded:connect(function(player)
local saveData = PlayerDataStore:GetSaveData(player)
saveData:Set('VisitCount', (saveData:Get('VisitCount') or 0) + 1)
end)
…And that’s it! No need to call some sort of “save” explicitly somewhere or something like that, it will just work.
Note on stability: This isn’t totally bulletproof yet, there’s probably still a couple bugs in it somewhere. But, I did spend 3 hours today testing it and I think I have all of the obvious bugs found and fixed, so it is pretty stable: If you’re starting a on a new place and it fits it well I would give it a try.
PS: No association with the unfortunate DataPersistence events of today, just happens to be an interesting cooincidence.