How do I use Data stores?

I did not understand when I read the article on roblox’s page. And I think its necessary for a feature I want to implement in my game.

1 Like

Have you also tried looking up some tutorials online?

2 Likes

How do I even handle DataStores - Help and Feedback / Scripting Support - DevForum | Roblox Try this post.

1 Like

Roblox DataStore Tutorial - Data Stores & Saving Data - Scripting Tutorial - YouTube here

1 Like

Make sure to go to game settings > Security > Turn On Enable Studio Access To API Services. And read my comments

DataStores are a way to save something. Let’s say, we want to save your wins stats:

local dataStore = game:GetService("DataStoreService") -- It's a service, so we get it by using the GetService() Function
local winsData = dataStore:GetDataStore("winsData") -- Now, we are actually getting the datastore. You don't have to call it winsData, I just like to keep the dataStore the same as my variable

game.Players.PlayerAdded:Connect(function(player)  -- Whenever the player joins the game...
    local leaderstats = Instance.new("Folder", player) -- Make A Folder Inside Player
    leaderstats.Name = "leaderstats" -- Now you HAVE to name the folder leaderstats, roblox just made it like that
    
    local wins = Instance.new("IntValue", leaderstats) -- Making an IntValue INSIDE the folder
    wins.Name = "Wins" -- The name of the intValue and the players will see it like that
    -- Time To Start Saving Player Data
 
    local playerID = "Player_" .. player.UserId -- We are getting the player's id so we can save it under their id. We DON'T save their data under their username because if the player changes their name, they will lose ALL their data
    local data = winsData:GetAsync(playerID) -- Here are basically using the function GetAsync to look up the playerID in the dataStore. Like we are checking if the player has some saved data stored in the dataStore
    
    if data then -- If we found some data in our datastore then...
        wins.Value = data -- Here, we're setting their wins to whatever we found in the datastore
    else -- If we couldn't find any data in the datastore then...
        wins.Value = 0 -- We set their wins to 0 because we couldn't find ANY data in the dataStore. Probably means that it's their first time playing your game
    end 
end)




-- Great! But now, we just have to like save their data whenever the player LEAVES the game


game.Players.PlayerRemoving:Connect(function(player)
    local playerID = "Player_" .. player.UserId -- Getting the player's ID so we can save their data BY their id
    
    local success,err = pcall(function() -- Here, we are setting a pcall function. A pcall stands for protected call and we use pcall functions to handle errors. Like if you have an error then do something.
        local registerData = winsData:SetAsync(playerID, player.leaderstats.Wins.Value) -- This function SetAsync will like register or store their information in the our datastore. It takes ✌ arguments. Who to save their data to. And what data do we want to save?
    end)

    -- The Very Ending...

    if success then -- If our pcall function didn't error and ran successfully then...
        print("Successfully saved data! (: ")
   else -- If our pcall function errored and didn't run successfully then...
       warn("Couldn't save your data! ): ")
end)

I really hope you understand now. Now I CAN’T blame you for still not understanding as it took me days to understand.

Useful links:

And if you’re wondering how do I save multiple leaderstats?

Useful Link To Save Multiply leaderstats:

More information about pcall functions:

Pcall functions is a way to handle errors. Now we put infront two variables

local success,err = pcall(function()

Noticed how I said success,err? They are variables. And yes you can name them whatever you like. So we put these variables in front because pcall’s return a bool value. True or false. So at the end or out of the pcall function. We use those variables to do whatever we want.

if success then -- If our pcall function didn't error and ran successfully then...
        print("Successfully saved data! (: ")
   else -- If our pcall function errored and didn't run successfully then...
       warn("Couldn't save your data! ):")
end)

Thanks so much if you reached here! :wave:

2 Likes

This is a good way to start getting into DataStores but for serious projects I highly recommend using a module like DataStore2 or ProfileService, since plain DataStore calls are highly susceptible to outages, corruption, race conditions, rate limiting/budgeting, etc.

The aforementioned modules deal with most if not all of these issues pretty reliably, which is why a lot of games, small and big, make use of them.

1 Like

By the way, a lot of what these modules do are gonna be kind of laughed at because of what is going to happen with DataStores, datastores are getting an entire like, remaking all most, for example:

Well true, but these modules still use normal datastores;

These modules also suffer from corruption. Unless you have backups, on which DataStore2 or the new update can help you on. They both support versioning. Except now it will be INTEGRATED into datastores;

I thought UpdateAsync() calls queued?

I think it’s mostly fair, but they are thinking of having an option of removing per-key write specific limits.

Anyways, these modules are kind of a second-thought, you shoudn’t learn about them right away. You should try understanding datastore calls, make your own solutions, and then use them if you want to.

DataStores allow you to keep data between servers.

It is used usually for player data.

Every datastores has keys, these keys have data in them, so the key can be someone’s userId, and the data is the player’s data.

To get a DataStore you do DataStoreService:GetDataStore("DataStoreName, hello!")

You have some calls, but for people starting out, I recommend looking into :SetAsync() and :GetAsync()

SetAsync will SAVE/SET data to a key.
Example:

DataStore:SetAsync(player.UserId, data)

GetAsync will get data from a datastore. Example:

local data = DataStore:GetAsync(player.UserId)


One thing is that datastore calls can fail. So you should use pcall on these requests.

Sorry, should’ve been more clear with that one, some developers forget to make catch cases for outages which can lead to data being overwritten or lost.

Good to hear Roblox is finally fixing that.

I’ve had some issues with this, it seems that if a player teleports between places, or just rejoins quickly, it’s possible that previous data hasn’t been saved yet before it attempts to load again, causing old data to be loaded instead of the soon-to-be-saved data. Aka, data would get reverted and their last session wiped and overwritten.

This was actually the reason I switched from my own solution to ProfileService, since I’d to delve into caching and such to attempt to fix this.

That’s true, but if you’re new to it and just want to make a game I wouldn’t suggest going with a homemade approach unless you know what you’re doing, since it can negatively impact your game’s (and your own) reputation.

1 Like