I’ve created a tutorial for new people regarding the datastore and how to save multiple/singular data.
In this tutorial I’m gonna try my best to explain every single line assuming that you’re really new to coding, but if you already know some basic stuff, it will be easier to read.
For any improvements for this topic/thread please comment down below so I can improve it and make it better for future readers
Copy code for lazy people
Btw, the tutorial is under this code, this just shows what you’re gonna learn today
-- This for lazy people who just came to copy & paste, not to learn the code...
-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore") -- This can be changed to whatever you want
local function saveData(player) -- The functions that saves data
local tableToSave = {
player.leaderstats.Money.Value; -- First value from the table
player.leaderstats.Coins.Value -- Second value from the table
}
local success, err = pcall(function()
dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
end)
if success then -- If the data has been saved
print("Data has been saved!")
else -- Else if the save failed
print("Data hasn't been saved!")
warn(err)
end
end
game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game
-- // Assigning player stats //
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Money = Instance.new("IntValue")
Money.Name = "Money"
Money.Parent = leaderstats
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Parent = leaderstats
local data -- We will define the data here so we can use it later, this data is the table we saved
local success, err = pcall(function()
data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore
end)
if success and data then -- If there were no errors and player loaded the data
Money.Value = data[1] -- Set the money to the first value of the table (data)
Coins.Value = data[2] -- Set the coins to the second value of the table (data)
else -- The player didn't load in the data, and probably is a new player
print("The player has no data!") -- The default will be set to 0
end
end)
game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
local success, err = pcall(function()
saveData(player) -- Save the data
end)
if success then
print("Data has been saved")
else
print("Data has not been saved!")
end
end)
game:BindToClose(function() -- When the server shuts down
for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
local success, err = pcall(function()
saveData(player) -- Save the data
end)
if success then
print("Data has been saved")
else
print("Data has not been saved!")
end
end
end)
I know it might look confusing at first, but I will explain each part
Introduction
Introduction:
First of all you need to have API Services Enabled in your game settings.
To Get there, press Home > Game Settings > Security > Check the Enable studio access to api services
Now make a server script (not a local script) and put it into Server Script Service
First we need to define variables, and to do so we will get the DataStoreService and then we will make our own Data Store (trust me it’s not confusing):
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore") -- You can change the name of the datastore to whatever you want
BE AWARE THAT WHENEVER YOU CHANGE THE DATASTORE IN THE FUTURE NAME IT WILL CREATE A NEW ONE WITHOUT ANY DATA!
After you’re done with this, make sure you save the game and publish it.
Part1 - Assigning the function
local function saveData(player) -- The functions that saves data local tableToSave = { player.leaderstats.Money.Value, -- First value from the table player.leaderstats.Coins.Value -- Second value from the table } local success, err = pcall(function() dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save end) if success then print("Data has been saved!") else print("Data hasn't been saved!") warn(err) end end
In here, we are determining the table that we want to save (tableToSave) and inside we are putting the data that you want to save,
So basically – player.leaderstats.Money.Value is gonna insert the players Money.Value into the table, same with Coins, and you can add as much stuff here as you want.
If you don’t know how we got the player, i will tell you later
Now we will use our dataStore (which i assigned at the beginning of the entire script) to save the table, so we do dataStore:SetAsync, Now SetAsync is a built in function that allows us to call the dataStore and tell it that we want to save something, in our case the “tableToSave”, So i say
dataStore:SetAsync(player.UserId, tableToSave)
The “player.UserId” is the key, aka. We want to save the table with the players Id as the unique key, following it with the table we want to save…
For example, when we want to load the players data we will use the key to access their data, like a chest, and it will be player.UserId in our case, a lot of people also do
local key = player.UserId.."-uniqueKey" -- but this is completely optional
Now you might have realized this is all a function with a passing variable saveData(player) – “player” and we never called the function which i will tell you in part 2 and 3
But before that we first need to use a pcall function to make sure the script doesn’t find an error.
Pcall is basically a built in function you can tell it anything and if it catches an error it will not stop the entire script outside the pcall.
So to use a pcall we would do
local success, err = pcall(function()
-- Do stuff
end)
If the “Do stuff” didn’t get any errors the success is going to be true, meanwhile the error being nil, and if finds an error success will be nil and error will be true
so we can do:
local success, err = pcall(function()
dataStore:SetAsync(player.UserId, tableToSave)
end)
And if the data got saved we can check if success then:
if success then -- If the data got saved
print("Data has been saved")
else -- Else if the data didn't get saved
print("Data has not been saved!")
end
So at the end it all looks like:
local function saveData(player) -- The functions that saves data
local tableToSave = {
player.leaderstats.Money.Value, -- First value from the table
player.leaderstats.Coins.Value -- Second value from the table
}
local success, err = pcall(function()
dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
end)
if success then
print("Data has been saved!")
else
print("Data hasn't been saved!")
warn(err)
end
end
Part2 - Saving the Data
game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves the game saveData(player) -- Save the data end) game:BindToClose(function() -- When the server shuts down for _, player in pairs(game.Players:GetPlayers()) do saveData(player) -- Save the data end) end)
Now that we have the function, we need to call it. So when the player leaves the server, we call the function.
And when we connect the function to player Removing we have to add a variable called player here
game.Players.PlayerRemoving:Connect(function(player) -- this one, it gets the player that left
end)
and then in the playerRemoving we call the function saveData() and inside the brackets we give it the variable player we got from the line above so it looks like this saveData(player)…
game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
saveData(player) -- Save the data
end)
Bind To Close Explanation →
Whenever a player leaves a server (the last player) the data will save then a few seconds later the server shutdowns.
However in roblox studio the server shuts down as soon as the player presses the stop button giving it no time to save the data. (BindToClose is also useful for unexpected shutdowns by roblox)
So what we do to save data in roblox studio is use game:BindToClose()
in our case, when the game is closing we wanna loop through all players and save their data like this
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
-- Do stuff
end
end)
local table = {a, b, c}
for index, value in pairs(table) do -- you can call index, value whatever you want
print(index)
print(value)
end
--[[ Output should be
1, a
2, b
3, c
--]]
The game.Players:GetPlayers() will return a table of all players in the game, and for _, player in pairs(playerTable) thats really what it is in short
Most people use i, v. But to look clean I use _, player
So then we wanna do the same thing as for when the player leaves, we save their data by calling the function and giving it the parameter (player).
game:BindToClose(function() -- When the server shuts down
for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
saveData(player) -- Save the data
end
end)
Part3 - Getting the Data
game.Players.PlayerAdded:Connect(function(player) local leaderstats = Instance.new("Folder") leaderstats.Name = "leaderstats" leaderstats.Parent = player local Money = Instance.new("IntValue") Money.Name = "Money" Money.Parent = leaderstats local Coins = Instance.new("IntValue") Coins.Name = "Coins" Coins.Parent = leaderstats local data local success, err = pcall(function() data = dataStore:GetAsync(player.UserId) end) if success and data then Money.Value = data[1] Coins.Value = data[2] else print("The player has no data!") -- The default will be set to 0 end end)
This is the playerAdded part of the script, this is the place where we manage the leaderstats, aswell as the data, so the first few lines are just making the Coins and Money values and inserting them into the player, before loading the data…
However the 2nd part of the script is receiving the data from the table.
So to receive data from the player we can just use
local data
data = dataStore:GetAsync(player.UserId)
But there’s 1 issue, if the player is new it never had any data saved it will error since theres no information about that player in our datastore, so we will use the pcall()
local data -- We are assigning this here so we can use it later on
local success, err = pcall(function()
data = dataStore:GetAsync(player.UserId)
end)
The GetAsync is a built in function just as SetAsync, and we are calling the dataStore and telling it to give us the data with the player.UserId being the unique key.
So when we combine all of this it should look like this:
local success, err = pcall(function()
data = dataStore:GetAsync(player.UserId)
end)
if success then
Money.Value = data[1]
Coins.Value = data[2]
else
print("The player has no data!") -- The default will be set to 0
end
Ok, if you’re probably confused by the
Money.Value = data[1]
Whenever we have a table and value inside of it, we can access each and every single value by doing:
local table = {
"a", -- This is the first value (1)
"b", -- This is the second value (2)
"c" -- This is the third value (3)
}
local firstValue = table[1]
print(firstValue)
-- OUTPUT:
-- a
So that line of code is getting the first value from the table because “a” is represented as the first one, the “b” in out example would be 2 and for “c”, the number would be 3.
So at the end the Money.Value is going to be the data[1] and Coins.Value is going to be data[2] as Money is the 1st value in the tableToSave and Coins it’s the 2nd value in the table.
After all of this we will type else (because if the pcall catches an error we wouldn’t get any data and the success will be nil) and then we print that the player has no data and if you want to set a custom data for new players you can do
if success then
Money.Value = data[1]
Coins.Value = data[2]
else
print("The player has no data!") -- The default will be set to 0
-- Custom Change (optional)
Money.Value = 50
Coins.Value = 30
end
Manually changing the data in the datastore
After you’ve done everything, you might come to a scenario where you wanna change players saves (for example you can use data stores to ban people and sometimes you wanna unban them by changing their data)
To do this simply, you should get this plugin, It’s safe and it really helps out, I personally use it whenever I wanna change something manually.
When you get the plugin and run it you will be shown a gui with alot of text boxes
It will ask for a Name, Place id should be set automatically and for the Name set it to whatever you’ve called the datastore you wanna manually change data on
After you’ve done that, press Connect.
Then you will be asked to write a key, Now remember the unique key I was talking about, and how you set the unique key to be the players userId, Just write in the players userId you wanna change data on,
For example if I wanna change data for myself I would type my UserId and then press Enter.
After that it will show everything you’ve saved with that User Id on that datastore and you can manually change it.
Here’s a little challenge now. If you read through all 4 parts, I want you to look at the entire script at the top of the topic and see how easy everything is! Good Luck! (Oh also don’t forget to save and publish your work!)
This topic took me a while to write so please if it helped you, I would appreciate it if you dropped a like…
I hope I helped you guys understand this way better, for any questions just ask me!
Note:
You might see comments about some stuff, that I probably deleted/corrected, so no need to worry about that
PS. If you have any way of making this topic better for new readers just leave it in the comments!