DataStore not saving player's items

Hi, I’m trying to make a script that saves items in a player’s inventory by getting the name of the item, matching it with items in a folder in ReplicatedStorage, and giving it back to them when they rejoin. For some reason, I can’t get it to work properly. The tables end up being blank when the player leaves. If someone could help me, I would greatly appreciate it! Thank you!

local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("EquippedUserItems")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

game.Players.PlayerAdded:Connect(function(player)
	local data
	
	local success, errorMsg = pcall(function()
		data = DataStore:GetAsync("EquippedUserItems-"..player.UserId)
	end)
	
	if success and data then
		for _, itemName in pairs(data) do
			game:GetService("ReplicatedStorage"):WaitForChild("ShopItems").Items[itemName]:Clone().Parent = player.Backpack
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local itemTable = {}
	for _, item in pairs(player.Backpack:GetChildren()) do
		table.insert(itemTable,item.Name)
		print(item.Name.. " saved to UserId "..player.UserId)
	end
	local success, errorMsg = pcall(function()
		DataStore:SetAsync("EquippedUserItems-"..player.UserId,itemTable)
	end)
	
	if success then
		print("Saved!")
	else
		print(errorMsg)
	end
end)

game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		local itemTable = {}
		for _, item in pairs(player.Backpack:GetChildren()) do
			table.insert(itemTable,item.Name)
			print(item.Name.. " saved to UserId "..player.UserId)
		end
		local success, errorMsg = pcall(function()
			DataStore:SetAsync("EquippedUserItems-"..player.UserId,itemTable)
		end)

		if success then
			print("Saved!")
		else
			print(errorMsg)
		end
	end
end)

is it maybe when the player is being removed so the backpack becomes unavaliable leaving it empty because the backpack couldnt be found? sounds dumb but that was the first thing that came to my head since you said the tables were blank

That’s what I was thinking, but this tutorial disproves that

I didnt see bind to close in the tutorial, have you tried removing that part and testing it from there?

or

try defining the backpack first? example:

local plrbackpack = player:FindFirstChild("Backpack")

I used BindToClose because sometimes if the last player in the server leaves, it doesn’t work properly. That’s just a backup measure. I also noticed that in another script (I have two, one to get the currently equipped items and one for all items the player has purchased) it is also not saving, which is really weird, because in another script I made for easter eggs (the total items script is literally a copy-paste of the easter egg script), it’s working properly.

I actually hired someone to do this for me the last time I did this… if you ever get the time try hiring @CannedSlices

go to your game settings i think one of them need to be checked in to have data saving to work.

Here’s my Easter Egg script that works just fine

local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("GBNEasterEggs")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

game.Players.PlayerAdded:Connect(function(player)
	local eggsFolder = Instance.new("Folder")
	eggsFolder.Name = "Eggs"
	eggsFolder.Parent = player
	
	local data
	
	local success, errorMsg = pcall(function()
		data = DataStore:GetAsync("EggData-"..player.UserId)
	end)
	
	if success and data then
		for _, eggName in pairs(data) do
			local eggValue = Instance.new("BoolValue")
			eggValue.Name = eggName
			eggValue.Parent = eggsFolder
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local eggsTable = {}
	for _, egg in pairs(player.Eggs:GetChildren()) do
		table.insert(eggsTable,egg.Name)
		print(egg.Name.. " saved to UserId "..player.UserId)
	end
	
	local success, errorMsg = pcall(function()
		DataStore:SetAsync("EggData-"..player.UserId,eggsTable)
	end)
	
	if success then
		print("Saved!")
	else
		print(errorMsg)
	end
end)

game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		local eggsTable = {}
		for _, egg in pairs(player.Eggs:GetChildren()) do
			table.insert(eggsTable,egg.Name)
			print(egg.Name.. " saved to UserId "..player.UserId)
		end

		local success, errorMsg = pcall(function()
			DataStore:SetAsync("EggData-"..player.UserId,eggsTable)
		end)
		if success then
			print("Saved!")
		else
			print(errorMsg)
		end
	end
end)

And here’s my purchased items script that does not work

local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("UserItems")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

game.Players.PlayerAdded:Connect(function(player)
	local itemsFolder = Instance.new("Folder")
	itemsFolder.Name = "UserItems"
	itemsFolder.Parent = player
	
	local data
	
	local success, errorMsg = pcall(function()
		data = DataStore:GetAsync("UserItems-"..player.UserId)
	end)
	
	if success and data then
		for _, itemName in pairs(data) do
			local itemValue = Instance.new("BoolValue")
			itemValue.Name = itemName
			itemValue.Parent = itemsFolder
		end
	end
	player.CharacterRemoving:Connect(function(char)
		char.Humanoid:UnequipTools()
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local itemTable = {}
	for _, item in pairs(player.UserItems:GetChildren()) do
		table.insert(itemTable,item.Name)
		print(item.Name.. " saved to UserId "..player.UserId)
	end
	
	local success, errorMsg = pcall(function()
		DataStore:SetAsync("UserItems-"..player.UserId,itemTable)
	end)
	
	if success then
		print("Saved!")
	else
		print(errorMsg)
	end
end)

game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		local itemTable = {}
		for _, item in pairs(player.UserItems:GetChildren()) do
			table.insert(itemTable,item.Name)
			print(item.Name.. " saved to UserId "..player.UserId)
		end

		local success, errorMsg = pcall(function()
			DataStore:SetAsync("UserItems-"..player.UserId,itemTable)
		end)
		if success then
			print("Saved!")
		else
			print(errorMsg)
		end
	end
end)

does it work if you add

game:BindToClose(function()
   task.wait(2)
end)

at the end

i believe there is a cooldown between setasyncs by like 6 seconds, maybe they try to both save but one goes first before the other? disable the egg script and test it.

Is this a folder in the player you have created? is there any errors in output?

I have added task.wait(2) and it is still not working.
player.UserItems is a folder that gets created in the “purchased items” script I posted in post 8. There are no errors when the game starts or stops regarding the scripts.

defined here

[ignore this looooll]

was the task.wait in the bind to close funtion

Yes, I put it at the beginning. Should it be at the end?

game:BindToClose(function()
	task.wait(2)
	for _, player in pairs(game.Players:GetPlayers()) do
		local itemTable = {}
		for _, item in pairs(player.UserItems:GetChildren()) do
			table.insert(itemTable,item.Name)
			print(item.Name.. " saved to UserId "..player.UserId)
		end

		local success, errorMsg = pcall(function()
			DataStore:SetAsync("UserItems-"..player.UserId,itemTable)
		end)
		if success then
			print("Saved!")
		else
			print(errorMsg)
		end
	end
end)

I don’t believe you need this function.
End or front, doesn’t matter

quoted wrong one, I mean for the first script

you didnt define player up there but did down there

nvmmmmmmmmm, its bind to close its not a player thing, im dumb [ignore this]

I’m gonna put the task.wait(2) in both scripts to be sure.
Would it be because there’s so many data stores in my game? I just realized I have quite a bit lol
There are four current data stores that are saving when the player leaves. Settings, Easter Eggs, Purchased Items and Equipped Items

I don’t think it’s because of that

i had a similar issue, maybe the response i got could help you?

the link