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
Why are you nesting the PlayerRemoving listener inside PlayerAdded’s? These connections are gonna build up and cause a memory leak. I linked my tutorial, which might help with player’s data not saving.
local function loadData(player, leaderstats)
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
should I add the “,leaderstats)” to the loadData as well?
The data you are trying to save will be loaded normally. You don’t need to add that if you’re trying to fix the data saving.
Oh, and I forgot to mention, you need to disconnect your PlayerRemoving event.
Players.PlayerAdded:Connect(function(player)
playersavetable[player] = tick()
loadStarterData(player)
loadData(player)
local leaderstats = player:WaitForChild("leaderstats")
local Inventory = leaderstats:WaitForChild("Inventory")
local RemoveEvent
RemoveEvent = Players.PlayerRemoving:Connect(function(vplayer)
if vplayer == player then
saveData(vplayer, leaderstats)
RemoveEvent:Disconnect()
end
end)
end)
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("ss")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Data = {
Strength = 0;
Rebirths = 0;
Cash = 1000;
Speed = 20;
Items = 0;
Inventory = {}
}
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, 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
ReplicatedStorage.SaveEvent.OnServerEvent:Connect(function(player)
saveData(player)
end)
Players.PlayerAdded:Connect(function(player)
playersavetable[player] = tick()
loadStarterData(player)
loadData(player)
local leaderstats = player:WaitForChild("leaderstats")
local Inventory = leaderstats:WaitForChild("Inventory")
local RemoveEvent
RemoveEvent = Players.PlayerRemoving:Connect(function(vplayer)
if vplayer == player then
saveData(vplayer, leaderstats)
RemoveEvent:Disconnect()
end
end)
end)
This is the updated script, having the same results as before as far as I can see. I will check incapaxx’s tutorial
game:BindToClose(function()
for _, client in ipairs(Players:GetPlayers()) do
spawn(function()
saveData(client)
end)
end
end)
I have added this function to my script at the end of it.
EDIT: I posted to soon lol, the inventory still isn’t saving sigh
EDIT 2: One error that may be unrelated in the output is " [ InsertService cannot be used to load assets from the client]"
Your original code is working fine? lol… ( Just tested it ) and also I would never let the client tell the server when to save data if I were you. ( I’m talking about the remoteevent )
Instead have a loop that saves data every 60 seconds or so, save data when player leaves and on BindToClose.
I also quickly cleaned up the code if you want I could give you that ( though I am still doing exactly what you’re doing like using SetAsync which is kind of bad… and I am still using your variable naming kindish )
I think your problem is that you’re not updating the values from the server but from the client, maybe you should consider looking at your value changing code and use RemoteEvents and such if you’re not already doing that, or you’re just testing on studio without the game being published/ not having the “Enable Studio Access to API Services” on.