Hello.
I did this, and it works but seems a bit hardcoded as I must save as like 14 different items.
I tried to use for-loops to do this but it isn’t working.
Code:
-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("PlaneSkinOwnedSave") -- This can be changed to whatever you want
local function saveData(player) -- The functions that saves data
local skins = player.OwnedSkins
tableToSave = {
}
for i,v in pairs(skins:GetDescendants()) do
if v.Name == "Owned" then
table.insert(tableToSave, v.Value)
print(v.Value)
end
end
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
wait(1)
-- // Assigning player stats //
local skins = player.OwnedSkins
local toGive = {}
for i,v in pairs(skins:GetDescendants()) do
if v.Name == "Owned" then
table.insert(toGive, v.Value)
end
end
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
for count = 1,14 do
print(data[count])
toGive[count] = data[count]
end
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)
Hi i tried using your datastore tutorial but whenever i leave the game it doesnt save the data. i didnt changed anything in the code. just added the values and another folder.
I also really appreciate the helpful comments and explanation for what each code segment does and why! Very helpful for newer scripters who may have no idea what each segment does.
As an extra side note by the way, in Part 2 for the final code at the top, the second to last ‘end’ still has a parenthesis even though it doesn’t need it.
game:BindToClose(function() – When the server shuts down
for _, player in pairs(game.Players:GetPlayers()) do
saveData(player) – Save the data
end)
end)
well you can do both, you can save everything into 1 string and then get the names by using string.split, or if you want to save it into 1 array then you can loop through each value for the savedWeapons
What a misinformed article lol. While it is obviously bad practice to use while wait() do in cases when a conditional could easily be substituted into the while statement (like the example provided in the doc), there are many cases like the example provided by @Urxpaly45 where it really doesn’t matter and— in fact— increases readability.
Acting as if someone is “a bad programmer” (as the article states) simply for following a certain convention— irrespective of the circumstances surrounding the use case— proves the only bad programmer is the one peddling this misinformation. And exposes their lack of critical thinking skills.
while wait() do is a tool in your coding arsenal. Good programmers know when to use it and when not to. Bad programmers read opinion and accept it as doctrine.
There’s not even a need to do any while wait statements. Just use RunService
RunService.Heartbeat:Connect(function()
-- fires once every frame
task.wait(1) -- add this to make it wait one second every frame before firing code
end)
Would this be good to handle if data wasn’t loaded in? (Ex. There was an error loading data).
I changed the if & elseif statements to check for:
Success and data > load in the data.
Success but no data returned > set the players data to 0 (assuming they are a new player)
Otherwise if no success > Kick the player
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
Rank.Value = data[1] -- Set the money to the first value of the table (data)
Tokens.Value = data[2] -- Set the coins to the second value of the table (data)
elseif success then -- 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
else
warn(err)
player:Kick("Data loading error - check your connection & Roblox status")
end
end)
If you want to save data safer and easier with less risk of data loss you should also look into learning a known datastore module like ProfileService or Suphis, even if you’re a beginner, when you learn it, you’re pretty much done.
It’s also less of a hassle than regular datastores and they have templates for player data!
If you think ProfileService is complicated you probably won’t like Suphi’s either, but they are all pretty equal to learn as the normal datastores, just with different formats. I find it easier to stay away from the default datastore system because (i suck at it haha)
If you want, here’s my reccomended tutorials on ProfileService and SDM, SDM is more up-to-date so if you can and have the time, I’d suggest learning it, otherwise you can just stick with the default roblox datastore. One problem I have with the normal roblox datastore though is the lack of session locking.
Session locking is pretty complicated, but here’s the gist of it. Just read the “Why is session locking useful?” section. Basically prevents Item Duplication and Loading Old Data.
Also I’d (PERSONALLY) reccommend Suphi’s over ProfileService as they are pretty similar but Suphi’s is more modern.