It’s most likely due to the server not being able to save the player’s data fast enough, which means you’re trying to get the parent of nil. This is most likely why you saw no errors (since it’s on leave).
You could try implementing a connection in the PlayerAdded, like this:
Players.PlayerAdded:Connect(function(player)
playersavetable[player] = tick()
loadStarterData(player)
loadData(player)
local leaderstats = player:WaitForChild("leaderstats")
Players.PlayerRemoving:Connect(function(vplayer)
if vplayer == player then
saveData(vplayer)
end
end)
end)
This would require some extra work (since you’d have to possibly add in something to check if there is a leaderstats arg), but most likely solves your problem.
No. I said the error is probably due to the server not being able to save the player’s data fast enough. Slowing it down more wouldn’t give enough time. Like I said at the end of my post:
Oh, by the way, you did player:WaitForChild("Inventory") instead of leaderstats:WaitForChild("Inventory").
Which falls back to the server shutting down when they leave. If the data is not saving, it’s through fault of OP’s code, or the server closing too quick. You yourself replied with this.
That’s most likely unimportant to the problem you have, as you were only changing a nil variable to a table. It’s due to how you’re trying to save it. You could try using Datastore2 and seeing if the player doesn’t lose their data.
I can not find anything like what I am doing for datastore2 when looking on the devforum
I am referring to this part of the code
local Data = {
Strength = 0;
Rebirths = 0;
Cash = 1000;
Speed = 20;
Items = 0;
Inventory = nil
}
local playersavetable = {};
local function loadStarterData(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
local Inventory = Instance.new("Folder")
Inventory.Name = "Inventory"
Inventory.Parent = leaderstats
for statname, statvalue in pairs(Data) do
if type(statvalue) == 'number' then
local intvalue = Instance.new("IntValue")
intvalue.Name = statname
intvalue.Value = statvalue
intvalue.Parent = leaderstats
else if type(statvalue) == 'boolean' then
local intvalue = Instance.new("BoolValue")
intvalue.Name = statname
intvalue.Value = statvalue
intvalue.Parent = Inventory
end
end
end
end
local function loadData(player)
local Data
local s, e = pcall(function()
Data = DataStore:GetAsync('UserId'..player.UserId)
end)
if s then
print (player.Name.."Data loaded")
else
print(player.Name.."Data failed to load")
end
if Data then
for statname, statvalue in pairs(Data) do
if type(statvalue) == "number" then
player.leaderstats[statname].Value = statvalue
else if type(statvalue) == "boolean" then
player.leaderstats.Inventory[statname].Value = statvalue
end
end
end
print(player.Name.."Data has been loaded")
else
print(player.Name.."No data found! generating..")
end
end
local function saveData(player)
--if RunService:IsStudio() then return end
local Data = {}
for _, stat in ipairs(player.leaderstats:GetChildren()) do
if not stat:IsA("Folder") then
Data[stat.Name] = stat.Value
end
end
local s, e = pcall(function()
DataStore:SetAsync('UserId'..player.UserId, Data)
end)
if s then
print(player.Name.."Data has been saved")
else
warn (player.Name.."Data failed to save"..e)
end
end
everything I’ve seen on datastore2 makes to process of creating and saving data much more manual and tedious, am I missing something?
Datastore2 prevents data loss more than the Datastore service does. Also, your SaveData function should have two extra args (since you’re connecting the PlayerRemoved event to the PlayerAdded event.)
I am aware of the advantages of datastore2, I am saying that from the examples and threads I have seen that the whole procces seems more manual and tedious. I mean like all the variables are created manually rather then just a few simple lines of code.
local function loadStarterData(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
local Inventory = Instance.new("Folder")
Inventory.Name = "Inventory"
Inventory.Parent = leaderstats
for statname, statvalue in pairs(Data) do
if type(statvalue) == 'number' then
local intvalue = Instance.new("IntValue")
intvalue.Name = statname
intvalue.Value = statvalue
intvalue.Parent = leaderstats
else if type(statvalue) == 'boolean' then
local intvalue = Instance.new("BoolValue")
intvalue.Name = statname
intvalue.Value = statvalue
intvalue.Parent = Inventory
end
end
end
end
same with loading
if Data then
for statname, statvalue in pairs(Data) do
if type(statvalue) == "number" then
player.leaderstats[statname].Value = statvalue
else if type(statvalue) == "boolean" then
player.leaderstats.Inventory[statname].Value = statvalue
end
end
end
I have seen NOTHING like this for datastore2 so I am sorta stuck.
Players.PlayerAdded:Connect(function(player)
playersavetable[player] = tick()
loadStarterData(player)
loadData(player)
local leaderstats = player:WaitForChild("leaderstats")
local Inventory = leaderstats:WaitForChild("Inventory")
Players.PlayerRemoving:Connect(function(vplayer)
if vplayer == player then
saveData(vplayer)
end
end)
end)
The modification was the one line of code as I mentioned earlier.
You forgot to add something. This is what you should’ve done:
Players.PlayerAdded:Connect(function(player)
playersavetable[player] = tick()
loadStarterData(player)
loadData(player)
local leaderstats = player:WaitForChild("leaderstats")
local Inventory = leaderstats:WaitForChild("Inventory")
Players.PlayerRemoving:Connect(function(vplayer)
if vplayer == player then
saveData(vplayer, leaderstats)
end
end)
end)
This would go with a modified save data function.
local function saveData(player, leaderstats)
--if RunService:IsStudio() then return end
local Data = {}
leaderstats = leaderstats or player.leaderstats
for _, stat in ipairs(leaderstats:GetChildren()) do
if not stat:IsA("Folder") then
Data[stat.Name] = stat.Value
end
end
local s, e = pcall(function()
DataStore:SetAsync('UserId'..player.UserId, Data)
end)
if s then
print(player.Name.."Data has been saved")
else
warn (player.Name.."Data failed to save"..e)
end
end