You write "id_"..plrid
in the PlayerAdded function but "id"..plr.UserId
in the PlayerRemoving function. So you use two different key because you missed the underscore on the PlayerRemoving function.
After testing your code by creating the leaderstats and the necessary values and changing the key of the PlayerRemoving, I had no problems. I noticed that you added a wait at the start of the function probably because you connected another one to create the leaderstats but I think this is very bad practice. Trying to have only one connection to the PlayerAdded event, it’s a better practice.
local dataStore = game:GetService("DataStoreService"):GetDataStore("SaveData")
game.Players.PlayerAdded:Connect(function(plr)
local plrid = "id_"..plr.UserId
print(plrid)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr
local save1 = Instance.new("IntValue")
save1.Name = "Weight"
save1.Parent = leaderstats
local save2 = Instance.new("IntValue")
save2.Name = "Protein"
save2.Parent = leaderstats
local save3 = Instance.new("IntValue")
save3.Name = "Strength"
save3.Parent = leaderstats
local save4 = Instance.new("IntValue")
save4.Name = "Wins"
save4.Parent = leaderstats
local GetSaved = dataStore:GetAsync(plrid)
print(GetSaved)
if GetSaved then
save1.Value = GetSaved[1]
save2.Value = GetSaved[2]
save3.Value = GetSaved[3]
save4.Value = GetSaved[4]
else
local NumberForSaving = {save1.Value, save2.Value, save3.Value, save4.Value}
dataStore:SetAsync(plrid, NumberForSaving)
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local leaderstats = plr:WaitForChild("leaderstats")
print(leaderstats.Weight.Value, leaderstats.Protein.Value, leaderstats.Strength.Value, leaderstats.Wins.Value)
dataStore:SetAsync("id_"..plr.UserId, {leaderstats.Weight.Value, leaderstats.Protein.Value, leaderstats.Strength.Value, leaderstats.Wins.Value})
end)
This is a completly fixed version of your code:
local DataStoreService = game:GetService("DataStoreService")
local PlayerService = game:GetService("Players")
local dataStore = DataStoreService:GetDataStore("SaveData")
local function RetryFunction(...)
local tries, success, result = 0, false, nil
repeat
tries += 1
success, result = pcall(...)
until ((tries >= 4) or success)
return success, result
end
PlayerService.PlayerAdded:Connect(function(plr)
local plrid = "id_"..plr.UserId
local success, obtainedData = RetryFunction(dataStore.GetAsync, dataStore, plrid)
if success then
-- Create the leaderstats after having found the data to prevent data loss by PlayerRemoving
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr
local save1 = Instance.new("IntValue")
save1.Name = "Weight"
save1.Parent = leaderstats
local save2 = Instance.new("IntValue")
save2.Name = "Protein"
save2.Parent = leaderstats
local save3 = Instance.new("IntValue")
save3.Name = "Strength"
save3.Parent = leaderstats
local save4 = Instance.new("IntValue")
save4.Name = "Wins"
save4.Parent = leaderstats
-- Assign the obtained data or create a new saving
if obtainedData then
save1.Value = obtainedData[1]
save2.Value = obtainedData[2]
save3.Value = obtainedData[3]
save4.Value = obtainedData[4]
else
local NumberForSaving = {save1.Value, save2.Value, save3.Value, save4.Value}
dataStore:SetAsync(plrid, NumberForSaving)
end
else
-- Data loss prevention
warn(obtainedData) -- Print error
plr:Kick("Data loss prevention: Sorry, we are unable to obtain your data, please try to log in again later.")
end
end)
PlayerService.PlayerRemoving:Connect(function(plr)
local leaderstats = plr:FindFirstChild("leaderstats")
if leaderstats then
local value1 = leaderstats:FindFirstChild("Weight")
local value2 = leaderstats:FindFirstChild("Protein")
local value3 = leaderstats:FindFirstChild("Strength")
local value4 = leaderstats:FindFirstChild("Wins")
if value1 and value2 and value3 and value4 then
dataStore:SetAsync("id_"..plr.UserId, {value1.Value, value2.Value, value3.Value, value4.Value})
end
end
end)
I created a function to try to obtain the data with 4 tries maximum. If you are unable to access the API then Roblox has a problem and I advise you to kick the player so as not to rewrite this data.
If you want to know more about pcall you can read the documentation by clicking on the blue text.
In PlayerRemoving I decided to try to find all the values before assigning them to the data store. I think this could cause problems but in any case using values as you do is in my opinion bad practice. Instead, try opting for a table-based structure and using a ModuleScript to create your database system.
If you have any questions, please don’t hesitate to ask me. I don’t know if I was very clear in my explanations but if you copy and paste my code it should work.