Saving Data
Posted on May 7, 2015 by NoahWillCode
If you are playing a game, such as Twisted Murderer or Mad Paintball, and you buy in-game currency or a character, or level up, you expect that to save. You expect that, next time you play this game, your progress, your purchases, will not be gone.
So now, you're making your own game. And you want to make sure your game saves some important data for the player, too. How do you do that?
You use the DataStoreService
.
The DataStoreService
is an awesome API specifically meant for saving and loading data for your game. Literally in its name - it stores data! (No it doesn't mean it is a store to buy data from.)
How do you use the DataStoreService
? I'll teach you.
The first step is to get the DataStoreService into your script. You do this by loading it in, just like any other ROBLOX Service.
local DSS = game:GetService("DataStoreService")
After this, you get your specific DataStore
. See, the DataStoreService
is not actually where you save your data, it is simply an API to get your DataStores
. The DataStore
is actually where all your data is saved and loaded from. And here is how to get a DataStore
:
local datastore = DSS:GetDataStore("GeneralSaveData", "Players")
The DataStoreService:GetDataStore()
function has two parameters, name
and scope
. The name
parameter is required, and it just means the actual name of your DataStore
. You can name your DataStore
anything, even if it is "BillyBobJoeManLikesUnicorns". However, it helps to name your DataStore
according to its purpose. The reason I have mine named "GeneralSaveData" is that it is where I am saving the general data for each player, so the name makes perfect sense.
The second parameter, scope
, is a bit more tricky. Thankfully, this parameter is not required, so you can just leave it empty and only provide a name
argument. But, if you're feeling adventurous, you can use the scope
argument to have different, sort of, groups of DataStores
. Let's say you saved general data for every player, but that you also saved general data for your game itself. You could then have two DataStores named "GeneralSaveData", but each in a different scope (e.g. "Players" and "Game"). You can sort of see it as a folder structure on your computer. You can have two different folders, each with files that have the same name. But because the files are in different folders, there isn't a problem!
So, great, now you know how to make and have a DataStore
! How do you use it?
Let's start with how to save data. There are couple things you're going to need in order to save your data. The first thing is, you're going to need a key
. I don't mean a key to unlock a door or even a fancy wireless key for one of those push-to-start cars. No, in this case, the key
is a string
, and it is sort of a name for the data itself. Since we're working with data for players, we're going to want to make this key
specific to the player. The best way to do this is to create the key
based off of the player's userId
, because this is the only thing we can be sure won't change for each player's account. What I like to do is create a function inside of my data script that generates a key
by just giving it a player as an argument. Here's what I normally do:
function generateDataKey(player) local ret = "uid_" .. player.userId return ret end
For my account, my key
from this function would be "uid_3276148".
The next thing you need is the data itself. The data has to be in the form of primitives
(e.g. numbers, strings, and booleans), but these primitives
CAN be stored in a table
. Typically, this is how I store data, because it is easy to access. So let's create a mock table
, assuming the player has two leaderstats - Points and Wins.
function generateDataTable(player) local dataTable = { Points = player.leaderstats.Points.Value, Wins = player.leaderstats.Wins.Value } return dataTable end
The last part of saving data is to actually tell your DataStore
to save it! This is done using your key
and your data
, in that order. And then all you have to do is call the SetAsync
method on your DataStore
. I like to put this in its own function that takes a player as an argument, and then it calls the generateDataKey
and generateDataTable
functions right there. Here's what I normally do:
function saveDataForPlayer(player) local key = generateDataKey(player) local data = generateDataTable(player) datastore:SetAsync(key, data) end
What this function does, is it saves whatever data you give it with the assigned key
. Now it safely stored away in ROBLOX's systems, ready to be loaded back in at any time! We'll discuss loading data in my next blog post, since this one is so long already. So make sure to check back on Thursday, May 21 for my next post! For now, here is the script we've made, in total:
local DSS = game:GetService("DataStoreService") local datastore = DSS:GetDataStore("GeneralSaveData", "Players") function generateDataKey(player) local ret = "uid_" .. player.userId return ret end function generateDataTable(player) local dataTable = { Points = player.leaderstats.Points.Value, Wins = player.leaderstats.Wins.Value } return dataTable end function saveDataForPlayer(player) local key = generateDataKey(player) local data = generateDataTable(player) datastore:SetAsync(key, data) end
Commentary
Leave a Comment