I currently use leaderstats to save player character choices, which is extremely outdated, how would I go about using datastore?
How would I go about changing my saving feature?
2 answers
The DataStore Service is the one that saves data. Now, to save data you have to make a datastore first using DataStoreService:GetDataStore("any name"). That's where our values would be stored. And you would use two other functions to save the data and then retrive it. :SetAsync() to save the data and :GetAsync() to get that data back.
Now, :SetAsync has 2 paramaters, the first being the "key". The key is gonna be the name of the variable that has our value that we are gonna store. And always remember that this key has to be unique for each player. And that's because when we retrieve the data, we would need the same used key. Ok, wait, what i'm saying is probarly too complicated, lemme give an example.
local DS = game:GetService("DataStoreService") --we got our service
local DataStore = DS:GetDataStore("Example") --made a datastore, you can name it whatever you want.
DataStore:SetAsync("Data-58", "bloxy") --ok you see, "bloxy" is the value that we saved, and we used the key "Data-58". Now when we wanna retrive that data, we would need to use the same key so we get the value corresponding to that key.
DataStore:SetAsync("Data-57", false)
print(DataStore:GetAsync("Data-58")) --you can see that we print it, and we also only need to put the key, now this will print bloxy, because that's the value we saved to that key. See, now it's clear i think.
print(DataStore:GetAsync("Data-57")) --this would print false, cuz that's the value we saved.
print(DataStore:GetAsync("Data-25")) --i think this would print nothing or eithre nil, because nothing and we have no value saved with that following key.
Now, after we understood how you work with this. Let's make this into a system. First we would have to know that, we wanna save the value whenever the player leaves, and retrive whenever he joins. So we would use PlayerAdded and PlayerRemoveing event. You can also make an auto-save system, so you would have it loop for example and each 5 mins it would save the value. But this way is better. You also need to make the leaderstats stuff, but I assume you know how to do that part.
local DS = game:GetService("DataStoreService")
local DataStore = DS:GetDataStore("Example")
game.Players.PlayerAdded:Connect(function(plr)
local p = Instance.new("Folder")
p.Parent = plr
p.Name = "leaderstats"
local v = Instance.new("NumberValue")
v.Parent = p
v.Name = "Coins"
v.Value = DataStore:GetAsync("Data-"..tostring(plr.UserId))
--now here, this is the interesting part, as I said, we need to make the key special for each player, so we can retrieve the same value. We can make a different key, but how will we do that for all player?? Welp, simple, we would use `Player.UserId`. Each player has his own UserId, and this property doesn't change. So we can use it to save and retreive data each time, with out any problem. And that's how to do it!
We would set the NumberValue's value to that data.
end)
game.Players.PlayerRemoving:Connects(function(plr)
--now, when he quit, we would save it, using the same key. Another thing that you may wanna do, is put the :SetAsync() inside a pcall, so if the saving errors, our script should be fine. pcall makes it so if an error happens, we should be fine. It will return true if everything happend succesfully without any errors, and it will return false and the given error if there was a problem. We do it this way.
local success, error = pcall(function()
return DataStore:GetAsync("Data-"..tostring(plr.UserId), plr.leaderstats.Coins.Value)
end)
if success then
print("Succesfully saved data")
else
print("Oh no, something happened. Quick grab the wrench!")
warn(error)
--warn will show a message in orange, it'll show orange having the error message, without stoping anything.
end
And that's really it!
1 comment
I can't put answerrr ;-;
local DataStore = game:GetService("DataStoreService"):GetDataStore("Data") --You can change this.
local Players = game:GetService("Players")
local function PlayerAdded (Player)
local Key = "Player_" .. Player.UserId -- You can change this, but be sure to make it unique for EACH player.
local PlayerData = DataStore:GetAsync(Key) -- This is how you get the player's data.
local Sample1 = 1 -- This is a number
local Sample2 = "Kills" -- This is a string
local Sample3 = true -- This is a boolean
local Data = { --This is a table
Sample1,
Sample2,
Sample3
}
print(Data[1]) --> 1, this is how you get the value inside a table
print(Data[2]) --> Kills
print(Data[3]) --> true
--Now for the fun part.
PlayerData:SetAsync(Key, Sample1) -- This is how you set a player's data.
local PlayerData = DataStore:GetAsync(Key) -- Just updating...
print(PlayerData[1]) --> 1, this is how you get the value in the player's data, you get it just like in the table.
print(PlayerData[2]) --> nil
print(PlayerData[3]) --> nil
PlayerData:SetAsync(Key, Sample1, Sample2, Sample3) -- THIS WON'T WORK. that's why we use a table.
PlayerData:SetAsync(Key, Data)
local PlayerData = DataStore:GetAsync(Key) -- Just updating...
print(PlayerData[1]) --> 1
print(PlayerData[2]) --> Kills
print(PlayerData[3]) --> true
print(PlayerData[4]) --> nil
print(PlayerData[5]) --> nil
PlayerData:RemoveAsync(Key) -- This will remove the data inside the player's data.
local PlayerData = DataStore:GetAsync(Key) -- Just updating...
print(PlayerData[1]) --> nil
print(PlayerData[2]) --> nil
end
Players.PlayerAdded:Connect(PlayerAdded)
This covers everything else but :UpdateSync().
You can use multiple datastore, you can do this by changing the name of the data store here's an example :
local DataStore1 = game:GetService("DataStoreService"):GetDataStore("Data1")
local DataStore2 = game:GetService("DataStoreService"):GetDataStore("Data2")
local Players = game:GetService("Players")
local function PlayerAdded (Player)
local Key = "User_" .. Player.UserId
local PlayerData1 = DataStore1:GetAsync(Key)
local PlayerData2 = DataStore2:GetAsync(Key)
local Data1 = 256
local Data2 = 128
PlayerData1:SetAsync(Key, Data1)
PlayerData2:SetAsync(Key, Data2)
print(PlayerData1) --> nil --Since there's only one value we don't have to do print(PlayerData[1])
print(PlayerData2) --> nil
local PlayerData1 = DataStore1:GetAsync(Key) -- Just updating...
local PlayerData2 = DataStore2:GetAsync(Key)
print(PlayerData1)--> 256
print(PlayerData2) --> 128
end
Players.PlayerAdded:Connect(PlayerAdded)
Please note that this is only my opinion.
This discussion is preserved as it was. New answers, comments, and votes are closed.

5 comments
use leaderstats to save data :thonk:
I do that, thats why im trying to switch from leaderstats to datastore
leaderstats is a folder that you put inside the player taht has value objects that show on the roblox leaderboard thingy, the datastore service is the one that saves the data inside those objects
You mean saving leaderstats money as an example?
I have a system that if you have a leaderstat value, it gives you hats, its my own custom little character creation method, but I think its going to be a very bad version by using something like that.