Here is the code, it's a regular script!
--// Variables \\-- local DataStoreService = game:GetService("DataStoreService") local ds1 = DataStoreService:GetDataStore("CashDATA") local ds2 = DataStoreService:GetDataStore("SoulsDATA") local ds3 = DataStoreService:GetDataStore("isNewDATA") local ds4 = DataStoreService:GetDataStore("swordDATA") local ds5 = DataStoreService:GetDataStore("shurikenDATA") --// Functions \\-- function giveStats(player) local Stats = Instance.new("Folder", player) Stats.Name = "Stats" local isNew = Instance.new("BoolValue", Stats) isNew.Name = "isNew" isNew.Value = ds3:GetAsync(player.UserId) or true local Coins = Instance.new("IntValue", Stats) Coins.Name = "Coins" Coins.Value = ds1:GetAsync(player.UserId) or 0 local Souls = Instance.new("IntValue", Stats) Souls.Name = "Souls" Souls.Value = ds2:GetAsync(player.UserId) or 0 local streak = Instance.new("IntValue", Stats) streak.Name = "currentStreak" streak.Value = 0 local currentSword = Instance.new("StringValue", Stats) currentSword.Name = "currentSword" currentSword.Value = ds4:GetAsync(player.UserId) or "StarterSword" local currentShuriken = Instance.new("StringValue", Stats) currentShuriken.Name = "currentShuriken" currentShuriken.Value = ds5:GetAsync(player.UserId) or "StarterShuriken" if isNew.Value == true then currentShuriken.Value = "StarterShuriken" currentSword = "StarterKatana" isNew.Value = false end while true do wait(30) local stats = player:WaitForChild("Stats") ds1:SetAsync(player.UserId, stats.Coins.Value) ds2:SetAsync(player.UserId, stats.Souls.Value) ds3:SetAsync(player.UserId, stats.isNew.Value) ds4:SetAsync(player.UserId, stats.currentSword.Value) ds5:SetAsync(player.UserId, stats.currentShuriken.Value) end end game.Players.PlayerAdded:Connect(giveStats) game.Players.PlayerRemoving:Connect(function(player) local stats = player:WaitForChild("Stats") ds1:SetAsync(player.UserId, stats.Coins.Value) ds2:SetAsync(player.UserId, stats.Souls.Value) ds3:SetAsync(player.UserId, stats.isNew.Value) ds4:SetAsync(player.UserId, stats.currentSword.Value) ds5:SetAsync(player.UserId, stats.currentShuriken.Value) end)
I'm new with datastores just letting you know! :)
Datastores
Datastores are a way of accessing data and saving it, so players can continue their progress on a game. Datastores are(in my opinion) the most important thing in a game. Faulty datastores are something that can cause major problems in a game. Avoiding that is very important.
Let me explain some basic things.
• Roblox Datastores can fail at any time. There is nothing we can do about it. But we can try to prevent these to the furthest possibility.
• PCalls(Protected Calls) is a way of handling errors from code. It is recommended to only use these when accessing outside of Roblox.
• Try to save everything in one Datastore. It is a wise decision. There may be certain occasions that you MAY have to use more than one. But that is pretty uncommon.
• Datastores can be accessed anywhere inside of the game including all the places in the game.
I assume that you read those, so we can move on.
Using Tables
Tables are an important and very useful way to organize and store data. Let's start by creating our table to organize data.
local dataTable = { Gold = 0; Gems = 0; }
As you can see, I made two different currency. One gold and one gems. I set both of those to "0". Just keep this in your script and we will use it later.
Creating Datastores
To get a Datastore, we need to first get the DataStoreService by using ":GetService()".
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") -- Gets the DataStoreService.
Next, let's get a Datastore by using ":GetDataStore()").
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") local myDatastore = DataService:GetDataStore("ThisIsMyData123") -- Gets the Datastore.
As you can see inside of the "()" for ":GetDataStore()", that is the name of your Datastore. You can name it to anything you want.
Now, let's create a simple leaderstats script. I assume you know how to create one.
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") local myDatastore = DataService:GetDataStore("ThisIsMyData123") -- Gets the Datastore. game.Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder") -- Creates a new folder which will be our stats. stats.Name = "leaderstats" stats.Parent = player local gold = Instance.new("IntValue") -- Creates our currency "Gold". gold.Name = "Gold" gold.Value = 0 gold.Parent = stats local gems = Instance.new("IntValue") -- Creates our currency "Gems". gems.Name = "Gems" gems.Value = 0 gems.Parent = stats end)
There we go. We made a simple leaderstats.
Next, we are going to check if the player joined has data. If the player does not, we will make new data for him using the dataTable. We will also use a method called ":GetAsync()". This will check if we have data. It also needs the key to access which is basically a unique code to access a player's data.
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") local myDatastore = DataService:GetDataStore("ThisIsMyData123") -- Gets the Datastore. game.Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder") -- Creates a new folder which will be our stats. stats.Name = "leaderstats" stats.Parent = player local gold = Instance.new("IntValue") -- Creates our currency "Gold". gold.Name = "Gold" gold.Value = 0 gold.Parent = stats local gems = Instance.new("IntValue") -- Creates our currency "Gems". gems.Name = "Gems" gems.Value = 0 gems.Parent = stats local checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same. if checkData then -- Simple if statement to check if there is data. -- We are going to be setting the values for each currency if there is data. This will make sense later on. gems.Value = checkData.Gems gold.Value = checkData.Gold else checkData = dataTable -- setting checkData to our datatable since checkData is nil. myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table. end end)
Now, we have a basic data retriever. Let's work on the saving side now. We will be using the method ":SetASync()". The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving.
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") local myDatastore = DataService:GetDataStore("ThisIsMyData123") -- Gets the Datastore. game.Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder") -- Creates a new folder which will be our stats. stats.Name = "leaderstats" stats.Parent = player local gold = Instance.new("IntValue") -- Creates our currency "Gold". gold.Name = "Gold" gold.Value = 0 gold.Parent = stats local gems = Instance.new("IntValue") -- Creates our currency "Gems". gems.Name = "Gems" gems.Value = 0 gems.Parent = stats local checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same. if checkData then -- Simple if statement to check if there is data. -- We are going to be setting the values for each currency if there is data. This will make sense later on. gems.Value = checkData.Gems gold.Value = checkData.Gold else checkData = dataTable -- setting checkData to our datatable since checkData is nil. myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table. end end) game.Players.PlayerRemoving:Connect(function(player) dataTable.Gold = player.leaderstats.Gold.Value -- We will be setting the "Gold" in the dataTable to the "Gold" IntValue inside our leaderstats. dataTable.Gems = player.leaderstats.Gems.Value -- same thing, but with gold myDatastore:SetAsync(player.UserId, dataTable) -- We are saving the dataTable after we have set the values. end)
Now, we have a basic working datastore. It saves and retrieves. But this isn't a good datastore. We need to use "PCalls" or Protected Calls like I said at the beginning because Roblox Datastores can fail. If they do, we do not want them to break our script. In the way we are using PCalls, It has two returns. Success and ErrorMessage. If the data was saved succesfully, it returns success. If not, it returns the Error Message.
local dataTable = { Gold = 0; Gems = 0; } local DataService = game:GetService("DataStoreService") local myDatastore = DataService:GetDataStore("ThisIsMyData123") -- Gets the Datastore. game.Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder") -- Creates a new folder which will be our stats. stats.Name = "leaderstats" stats.Parent = player local gold = Instance.new("IntValue") -- Creates our currency "Gold". gold.Name = "Gold" gold.Value = 0 gold.Parent = stats local gems = Instance.new("IntValue") -- Creates our currency "Gems". gems.Name = "Gems" gems.Value = 0 gems.Parent = stats local checkData local success, errorMessage = pcall(function() checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same. end) if checkData and success then -- Simple if statement to check if there is data. -- We are going to be setting the values for each currency if there is data. This will make sense later on. gems.Value = checkData.Gems gold.Value = checkData.Gold else checkData = dataTable -- setting checkData to our datatable since checkData is nil. local success, errorMessage = pcall(function() myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table. end) if success then print("Data saved successfully") else print("Error occurred while saving Data.") warn(errorMessage) end elseif not success then print("Data error while loading") end end) game.Players.PlayerRemoving:Connect(function(player) dataTable.Gold = player.leaderstats.Gold.Value -- We will be setting the "Gold" in the dataTable to the "Gold" IntValue inside our leaderstats. dataTable.Gems = player.leaderstats.Gems.Value -- same thing, but with gold local success, errorMessage = pcall(function() myDatastore:SetAsync(player.UserId, dataTable) -- We are saving the dataTable after we have set the values. end) if success then print("Data saved successfully") else print("Error occurred while saving Data.") warn(errorMessage) end end)
Now we have a really good and efficient Datastore. I hope this help anyone that is reading. I am not the best at explaining and writing things, but just try to understand haha. Thanks!
For some reason it did not work, please point out my mistakes!
local dataTable = { isNew = true; Coins = 0; Souls = 0; currentSword = "StarterSword"; currentShuriken = "StarterShuriken"; } local DataService = game:GetService("DataStoreService") local DS = DataService:GetDataStore("MainDS") game.Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder", player) stats.Name = "Stats" local isNew = Instance.new("BoolValue", stats) isNew.Name = "isNew" local Coins = Instance.new("IntValue", stats) Coins.Name = "Coins" Coins.Value = 0 local Souls = Instance.new("IntValue", stats) Souls.Name = "Souls" Souls.Value = 0 local currentSword = Instance.new("StringValue", stats) currentSword.Name = "currentSword" currentSword.Value = "StarterSword" local currentShuriken = Instance.new("StringValue", stats) currentShuriken.Name = "currentShuriken" currentShuriken.Value = "StarterShuriken" local streak = Instance.new("IntValue", stats) streak.Name = "streak" streak.Value = 0 if isNew.Value == true then currentSword.Value = "StarterSword" currentShuriken.Value = "StarterShuriken" isNew.Value = false end local checkData local success, errorMessage = pcall(function() checkData = DS:GetAsync(player.UserId) end) if checkData and success then isNew.Value = checkData.isNew Coins.Value = checkData.Coins Souls.Value = checkData.Souls currentSword.Value = checkData.currentSword currentShuriken.Value = checkData.currentShuriken checkData = dataTable local success, errorMessage = pcall(function() DS:SetAsync(player.UserId, checkData) end) if success then print("Data saved successfully") else print("Error occurred while saving Data.") warn(errorMessage) end elseif not success then print("Data error while loading") end end) game.Players.PlayerRemoving:Connect(function(player) dataTable.isNew = player.Stats.isNew.Value dataTable.Coins = player.Stats.Coins.Value dataTable.Souls = player.Stats.Souls.Value dataTable.currentSword = player.Stats.currentSword.Value dataTable.currentShuriken = player.Stats.currentShuriken.Value local success, errorMessage = pcall(function() DS:SetAsync(player.UserId, dataTable) -- We are saving the dataTable after we have set the values. end) if success then print("Data saved successfully") else print("Error occurred while saving Data.") warn(errorMessage) end end)