I've been having trouble with this, because in the entire script I getAsync and SetAsync Values the exact same order, yet while troubleshooting ,because I got data loss constantly, it apparently says The 1st value it tries to set for the player is nil, although printing the table shows that it's there, just in a different position than i had set it.
local DataStore = game:GetService("DataStoreService"):GetDataStore("Basic")
local template = {
Money = 0;
Level = 0;
XP = 0
}
local MAXIMUM_RETRY_ATTEMPTS = 5
local RETRY_COOLDOWN = 1
game.Players.PlayerAdded:Connect(function(plr)
local ls = plr:FindFirstChild("leaderstats")
local retryCount = 0
local success = false
local result
while not success and retryCount < MAXIMUM_RETRY_ATTEMPTS do
success, result = pcall(function()
local data = DataStore:GetAsync(tostring(plr.UserId))
if data == nil then
print("nothing?")
else
ls.Money.Value = data.Money
ls.Level.Value = data.Level
ls.XP.Value = data.XP
print("Success import")
print(data)
end
end)
if not success then
retryCount = retryCount + 1
warn(string.format("Failed to Import %s's data with error : %s", plr.Name, tostring(result or "")))
local data = DataStore:GetAsync(tostring(plr.UserId))
print(data)
task.wait(RETRY_COOLDOWN)
end
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local result
local success = false
local ls = plr:FindFirstChild("leaderstats")
while not success do
success, result = pcall(function()
DataStore:SetAsync(tostring(plr.UserId), {
Money = ls.Money.Value;
Level = ls.Level.Value;
XP = ls.XP.Value
})
print("Success export")
end)
if not success then
warn(string.format("Failed to Export %s's data with error : %s", plr.Name, tostring(result or "")))
end
end
end)
As you mentioned in your comment, the error you are seeing is :
Attempt to index nil with
Money
And you've already narrowed it down that it isn't your data
table. That means that your leaderstats ls
is nil. So looking at where you defined it...
local ls = plr:FindFirstChild("leaderstats")
It looks like you've got a race-condition. You are trying to fetch the leaderstats, but if it doesn't exist then it will return nil
. So if another script is creating it, one simple fix might be to change that line to...
local ls = plr:WaitForChild("leaderstats", 10)
But a better fix might be to move the code that constructs your leaderstats folder and all of the NumberValues into the top of this function instead. That way, the code that constructs the leaderstats is the same code that populates it with data.
game.Players.PlayerAdded:Connect(function(plr)
-- create the leaderstats
local ls = Instance.new("Folder")
ls.Name = "leaderstats"
local moneyVal = Instance.new("NumberValue", ls)
moneyVal.Name = "Money"
local levelVal = Instance.new("NumberValue", ls)
levelVal.Name = "Level"
local xpVal = Instance.new("NumberValue", ls)
xpVal.Name = "XP"
ls.Parent = plr
-- fetch data from the data stores
local retryCount = 0
local success = false
local result
while not success and retryCount < MAXIMUM_RETRY_ATTEMPTS do