Issues with Inventory/Tool Saving

What I am trying to do: I have many shops in my game selling different tools. I want the tools that have been bought to save for each player.

What I have done to try and achieve that: I have made a folder in Replicated Storage named Tools with all the tools in my game. I have tried many scripts and used many scripts written by other people to try and save players’ tools with DataStores. However, none of the scripts that I’ve scripted have worked. Here’s an examle of one:

local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("BackpackSave")

game.Players.PlayerAdded:Connect(function(player)
	pcall(function()
		local tool = dataStore:GetAsync("User-"..player.UserId)
		if tool then
			for i,v in pairs(tool) do
				local toolFound = game.ReplicatedStorage.Tools:FindFirstChild(v)
				if toolFound  then
					toolFound:Clone().Parent = player.Backpack
					toolFound:Clone().Parent = player.StarterGear
				end
			end
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	pcall(function() 
	local toolsSave = {}
	for i, tool in pairs (player.Backpack:GetChildren()) do
    if tool then
		table.insert(toolsSave,tool.Name)
	end
end
		dataStore:SetAsync("User-"..player.UserId,toolsSave)
	end)
end)

Can anybody help me? I’ve read through my script many times, but I am not able to find anything wrong with it. Yet, my tools do not save. What am I doing wrong?

1 Like

What would you need

 if tool then

for? If there was nothing in the backpack, it would not run anyways.

My tools still do not save for some reason even after removing extra lines of codes like that, but thanks for pointing that out.

Maybe change this

	pcall(function()

to this

local s,c = pcall(function()

Unfortunately, my tools still did not save. Thank you for your time and help though. :slightly_smiling_face:

Maybe because some tools are equipped already:

for i, tool in pairs (player.Backpack:GetChildren()) do

Loop through the character also:

for i, tool in pairs (player.Character:GetChildren()) do

Pcall isn’t needed at the start of the function, this is what the code would look like:

game.Players.PlayerRemoving:Connect(function(player)
	local toolsSave = {}
	for i, tool in pairs (player.Backpack:GetChildren()) do
        if tool:IsA("Tool") then
		    table.insert(toolsSave, tool.Name)
        end
    end
    for i, tool in pairs (player.Character:GetChildren()) do
        if tool:IsA("Tool") then
		    table.insert(toolsSave, tool.Name)
        end
    end
    local Success, Errormessage = pcall(function()
	    dataStore:SetAsync("User-"..player.UserId, toolsSave)
    end)
end)

Still did not work, but I appreciate your help. :sob: :sob: :sob:

Are there any errors? Did you try to debug your code by adding print statements?

Nothing shows up in output when I run the game. I haven’t tried using print statements to try and debug my script yet, but I am considering doing it at this point.

You should always do that as it shows which line isn’t reached. Please do that and attach your script with the prints. Then, tell us which print statements were reached.

1 Like

Okay, I will do that right now.

1 Like

Ah, this time an error occured. Here is my updated script:

local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("InventorySave")

game.Players.PlayerAdded:Connect(function(player)
	local s,c = pcall(function()
		local tool = dataStore:GetAsync("User-"..player.UserId)
		print("tools found")
		for i,v in pairs(tool) do
			local toolFound = game.ReplicatedStorage.Tools:FindFirstChild(v)
			if toolFound  then
				toolFound:Clone().Parent = player.Backpack
				toolFound:Clone().Parent = player.StarterGear
				print("tools cloned")
			end
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local toolsSave = {}
	for i, tool in pairs (player.Backpack:GetChildren()) do
        if tool:IsA("Tool") then
		    table.insert(toolsSave, tool.Name)
			print("tools inserted from backpack")
        end
    end
    for i, tool in pairs (player.Character:GetChildren()) do
        if tool:IsA("Tool") then
		    table.insert(toolsSave, tool.Name)
			print("tools inserted from character")
        end
    end
    local Success, Errormessage = pcall(function()
	    dataStore:SetAsync("User-"..player.UserId, toolsSave)
		print("tools saved")
    end)
end)

The error occured on line 27 of my script, where it says “for i, tool in pairs (player.Character:GetChildren()) do”. Here is the message that showed up in the output:

[13:27:50.303 - ServerScriptService.ToolsDataStore2:27: attempt to index nil with ‘GetChildren’]

13:27:50.304 - Stack Begin

[13:27:50.304 - Script ‘ServerScriptService.ToolsDataStore2’, Line 27]

13:27:50.305 - Stack End

Only “tools found” and “tools inserted from backpack” was printed. I am not sure why my tools weren’t cloned or saved from character :/. I am very confused now, and I do not want to do. Do you have any idea on how to debug/fix this?

What is line 27? We can’t tell.

Oh sorry about that. Here is line 27:

for i, tool in pairs (player.Character:GetChildren()) do

Here is line 27 and all of the lines after line 27 that are in the same paragraph in case you need it:

for i, tool in pairs (player.Character:GetChildren()) do
    if tool:IsA("Tool") then
		 table.insert(toolsSave, tool.Name)
		 print("tools inserted from character")
    end
end

Are you calling the correct lines? Are there any folders inserted into the player?

I don’t understand what you mean by calling lines, and no, I am not inserting any folders into the player. All I am doing is saving the tool names of all the tools owned by the player (tools in their backpack) into a table along with their user ID into a table, and then taking the info from the table when a player joins the game and cloning tools from a folder inside of Replicated Storage using the tool names that were saved with their user ID. My main issue is I do not understand why the tools are not saving into the table.

Pretty sure the Character is destroyed by the time PlayerRemoving fires. You should never use literal instances in the backpack or the character as a dependency for data saving. As well, by wrapping your entire PlayerAdded content in a pcall instead of just the DataStore call, you’re effectively silencing any errors that may be occurring there.

1 Like

Okay, I will remove the section that pulls tools from players’ characters. :confounded:

You could store the data when before the Character is removed with player.CharacterRemoving then save the data on PlayerRemoving or after you store the data in CharacterRemoving.

Ohhhh that’s smart! Thanks, I will try that out lol.