Help with datastores

I can never understand datastores. i watched over 10 videos and still confused and i tried searching on dev forum but most of them dont even work

Youtube tutorials are honestly bad for data stores, most are at the best mid and don’t teach properly.

I never fully grasped the concept of data stores until I became more experienced and was able to use the docs, I used the docs tutorial to learn about them. I haven’t used youtube tutorials ever since I was 1-3 months into scripting.

This tutorial is honestly much easier than youtube ones and the documentation knows more than youtube tutorials ever could.

1 Like

Youtube tutorials aren’t a really good source to start off with learning scripting. That is if you want to learn, not copy paste scripts. Anyways, to answer your question, Roblox has its own documentation regarding scripting so I suggest you should check that out as mentioned by Amiritss.

It’s my first time making a reply, so correct me if I do anything wrong!

Side note: If you want to learn here, then here you go. Source is from the documentation above.
Datastores (DataStoreService) lets you store data that you would have to use in between sessions, such as leaderboard stats or items in any players inventory. Datastores are consistent per experience, so any place within an experience could access and change the same data, including places on different servers.

Experiences that are tested in Studio can’t access Datastores, so you have to enable them to use them, but accessing Datastores in Studio can be risky for live experiences due to the fact that Studio will access the same datastores as the client application. If you want to avoid overwriting production data on them, you shouldn’t enable this setting for live experiences. Instead, enable it for a separate test version of the experience.

1 Like

I will try to explain it to you in the simplest detail I can:
To store data in a Data Store, we need to define two things:

  • A Key, which is a string and it can be used to identify player’s data (such as “Player_UserId” or “UserId” and etc…)
  • A value directly attached to the key. This can be a boolean, string, table and number, roblox will not accept any other data types (Vector3, CFrame, Instance…)

To visualize it easier, let’s say you have a simulator game and you want to save someone’s coins.
We need to first create a key name, this can be something like "Player_"..player.UserId and such, it doesn’t really matter what the prefix or suffix is, what matters is that you have the player’s id that you can retrieve again when loading their data the next time, and the value that we’re storing would be the player’s coins, which would be a number. We will then use the :SetAsync(key,value) to store the value.
Here’s what saving data should be like:

local DS = game:GetService("DataStoreService"):GetDataStore("DS")
game.Players.PlayerAdded:Connect(function(plr) --Loading Data Function
           local leaderstats = Instance.new("Folder")
           leaderstats.Name = "leaderstats"
           leaderstats.Parent = plr
         
           local Coins = Instance.new("NumberValue")
           Coins.Name = "Coins"
           Coins.Parent = leaderstats
           
           local data --Make sure to define this variable so the script knows it's there
           local key = "Player_"..plr.UserId
           local success,err = pcall(function()
                     data = DS:GetAsync(key)
           end)
           if success then
                    Coins.Value = data --data variable would be a number, the amount of coins the user had, or nil if the player has never played the game in the past, which wouldn't error.
           else
                  warn("Data Store Load error: "..err)
           end
end)
local function saveData(plr) --Saving Data Function
         local key = "Player_"..plr.UserId
         local success,err = pcall(function()
                      return DS:SetAsync(key,plr.leaderstats.Coins.Value)
         end)
         if success then
                  print("Data Successfully Saved!")
         else
                  warn("Data Store Saving error: "..err)
         end
end
game.Players.PlayerRemoving:Connect(saveData) --Data gets saved when the player leaves.
game:BindToClose(function() --Data gets saved when the server shuts down (i.e leaving the game in roblox studio or shutting down servers for update)
        for i,v in ipairs(game.Players:GetPlayers()) do
               task.spawn(saveData,v)
        end
end)

Here is a fully working data store script for this example. You might be asking: How do you load data? It’s quite simple really, similar to :SetAsync(key,value) it’s basically :GetAsync(key), which returns the data that was stored in that key, if it exists.

game:BindToClose() is also a useful function that is present in lots of data store systems, I have explained how it works in the script.

I hope you understood my explanation. If you have anymore questions, ask right away!

1 Like

Data Stores are difficult to explain in just one post, but I’ll give you an overview here:
Data Stores are ways to be able to save player data across multiple sessions, and there are a few methods to do this. Firstly you do need to publish your game and enable API services for it to work. Then put in this script:

local DataStoreService = game:GetService('DataStoreService') -- Get the service
local MyDataStore = DataStoreService:GetDataStore("MyDataStore") -- Get an existing data store or create one if it doesn't exist

game.Players.PlayerAdded:Connect(function(plr) -- Get data when player joins
   local leaderstats = Instance.new("Folder",plr)
   leaderstats.Name = 'leaderstats'
   local data -- Variable for data
   local Money = Instance.new('IntValue',leaderstats)
   Money.Name = 'Money'
   local success, errormessage = pcall(function() -- pcall is short for protected call and it prevents the script from crashing in case of an error. Always save and get data in a pcall
      data = MyDataStore:GetAsync("Player_"..plr.UserId -- [[This is the key used to retrieve the player's
 data. It can be anything with the players userid in it--]]) -- Get the player's data when they join
   end
   if success then
      if data then Money.Value = data --[[ Set money value to the data we retrieved ]] else Money.Value = 100 --[[Default Value]] end
   else
      warn(errormessage) -- If there was a failure in getting data then warn the error
end)

game.Players.PlayerRemoving:Connect(function(plr) -- Save data when player leaves
   local data = plr.leaderstats.Money.Value -- We set the data we want to save here
   local success, errormessage = pcall(function()
      return MyDataStore:SetAsync("Player_"..plr.UserId, data) -- [[VERY IMPORTANT, SetAsync() has a
      second parameter for data you want to save and make sure the key
      you are saving it to is the key you get the data with--]]
   end
   if success then print('Success saving data!') else print('There was a problem saving data!', warn(errormessage)) end -- Make sure data is saved
end)

This is a generic data store beginner script and if you want to clarify anything with me, feel free!
Edit: If you want to save multiple values to :SetAsync, then data should be a table, smth like this:

local data = {
   ['Money'] = plr.leaderstats.Money.Value
   ['Wins'] = plr.leaderstats.Wins.Value
   ['Rebirths'] = plr.leaderstats.Rebirths.Value
} -- You can save data the same way as if data was one value only
-- Getting player data with this table (assume you called get async already)
for stat, value in pairs(data) do
   plr.leaderstats[i].Value = value
end
1 Like

does BindToClose() have a player argument? I didn’t see that in the docs when I was reading before

“value of type nil cannot be converted to a number”

You need to assign data to DS:GetAsync(key) like this:

data = DS:GetAsync(key)

If you want by the way I made my own community tutorial on datastores, wanna check it out?

Fixed it