Datastore difficulties

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.

Here it is once again

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)

also, do read incapaxx’s tutorial, it can help

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

1 Like

Ok, this is the function I came up with

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]"

1 Like

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.

You can find that inside Game Settings → Options
image