Ah yes, DataStores!
To put it simply? A DataStore is basically something that stores every player’s individual data
You can use DataStores in a lot of different ways, but let’s say you wanna make a simple basic save/load system
Step 1: Setting up our Variables & Events
The first thing when making a script, is that we should go ahead & create our Variables & Events so that we can easily access them! First, we’ll define our variables then we’ll need to use the PlayerAdded
& PlayerRemoving
Events in this Instance:
local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")
local function LoadData()
end
local function SaveData()
end
game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)
LoadData
is just simply whatever we wanna call it when we use the GetDataStore
function (Heck you can even call it a meme string and it’ll still work, just make sure not to name it too long)
The next thing we’ll insert in our script is creating our local Values for each player when they first join:
local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")
local function LoadData(Player)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = Player
local RandomValue = Instance.new("IntValue")
RandomValue.Name = "Value1"
RandomValue.Parent = Player
end
local function SaveData(Player)
end
game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)
Naming our folder leaderstats
& parenting it to the player will create ROBLOX’s leaderstat system!
Step 2: Getting/Saving the Data
Now here’s where things get a bit tricky, saving & loading the Data
Whenever we want to function something relevant to player data, we’d always wanna encase it in a pcall
(Which is in simple terms, a protective call so that we have a much better chance for our data to save/load)
Referring back to our code, once a Player joins the game we’d wanna attempt to load their data if they have any
We also want to include a certain key for every player so that each one has different individual data, so we can go & get the Player’s ID:
local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")
local function LoadData(Player)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = Player
local RandomValue = Instance.new("IntValue")
RandomValue.Name = "Value1"
RandomValue.Parent = Player
local PlayerID = Player.UserId
local Data
local Success, Whoops = pcall(function()
Data = LocalData:GetAsync(PlayerID)
end)
if Success then
print("Loaded data to: "..Player.Name.."!")
RandomValue.Value = Data.RandomValue
else
warn("Something else happened!")
end
end
local function SaveData(Player)
local PlayerID = Player.UserId
local Data = {
RandomValue = Player.leaderstats.RandomValue.Value
}
local Success, Whoops = pcall(function()
LocalData:SetAsync(PlayerID, Data)
end)
if Success then
print("Saved data to: "..Player.Name.."!")
else
warn("An error has occurred saving the data! Please check the Dev Console!")
warn(Whoops)
end
end
game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)
The pcall
will check if we have any sort of Data that’s already been saved for the player, if there is then we can save/load that! We also wanna include our Data
variable inside our SaveData
function in a table, in case if we want to include more data values to save!
Step 3: Last Case Scenario
If for some reason your game suddenly has an update or PlayerRemoving
isn’t working, chances are your Data has not saved properly
Well, how could you fix that? We use a function called: BindToClose()
which fires when the game unexpectedly shuts down
We can connect that with our SaveData
event by getting all the players in this Instance:
local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")
local function LoadData(Player)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = Player
local RandomValue = Instance.new("IntValue")
RandomValue.Name = "Value1"
RandomValue.Parent = Player
local PlayerID = Player.UserId
local Data
local Success, Whoops = pcall(function()
Data = LocalData:GetAsync(PlayerID)
end)
if Success then
print("Loaded data to: "..Player.Name.."!")
RandomValue.Value = Data.RandomValue
else
warn("Something else happened!")
end
end
local function SaveData(Player)
local PlayerID = Player.UserId
local Data = {
RandomValue = Player.leaderstats.RandomValue.Value
}
local Success, Whoops = pcall(function()
LocalData:SetAsync(PlayerID, Data)
end)
if Success then
print("Saved data to: "..Player.Name.."!")
else
warn("An error has occurred saving the data! Please check the Dev Console!")
warn(Whoops)
end
end
game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)
game.BindToClose(function()
for _, Player in pairs(game.Players:GetPlayers()) do
SaveData(Player)
end
end)
We can get all the players using a loop, and saving everyone’s individual data this way!
If you hopefully followed all the steps, you should get something like this!
local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")
local function LoadData(Player)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = Player
local RandomValue = Instance.new("IntValue")
RandomValue.Name = "Value1"
RandomValue.Parent = Player
local PlayerID = Player.UserId
local Data
local Success, Whoops = pcall(function()
Data = LocalData:GetAsync(PlayerID)
end)
if Success and Data ~= nil then
print("Loaded data to: "..Player.Name.."!")
RandomValue.Value = Data.RandomValue
else
warn("Something else happened!")
end
end
local function SaveData(Player)
local PlayerID = Player.UserId
local Data = {
RandomValue = Player.leaderstats.RandomValue.Value
}
local Success, Whoops = pcall(function()
LocalData:SetAsync(PlayerID, Data)
end)
if Success then
print("Saved data to: "..Player.Name.."!")
else
warn("An error has occurred saving the data! Please check the Dev Console!")
warn(Whoops)
end
end
game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)
game.BindToClose(function()
for _, Player in pairs(game.Players:GetPlayers()) do
SaveData(Player)
end
end)