Backpack Tool Saving

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Save players BackPack

  2. What is the issue? When a player leaves the game with an item equipped, they do not get that item back upon joining the game.

local toolsFolder = game:GetService("ServerStorage"):FindFirstChild("Tools")
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("Backpacks")

game.Players.PlayerAdded:Connect(function(plr)
	local backpackData = dataStore:GetAsync(plr.UserId)
	
	local backpack = plr:WaitForChild("Backpack")
	local startergear = plr:WaitForChild("StarterGear")
	
	if backpackData ~= nil then
		for i, v in pairs(backpackData) do
			if toolsFolder:FindFirstChild(v) and backpack:FindFirstChild(v) == nil and startergear:FindFirstChild(v) == nil then
				toolsFolder[v]:Clone().Parent = backpack
				toolsFolder[v]:Clone().Parent = startergear
			end
		end
	end
	
	plr.CharacterRemoving:Connect(function(char)
		char:WaitForChild("Humanoid"):UnequipTools()
	end)
end)

game.Players.PlayerRemoving:Connect(function(plr)
	
	plr.Character:WaitForChild("Humanoid"):UnequipTools()
	
	local backpackTable = {}
	
	for i, v in pairs(plr.Backpack:GetChildren()) do
		table.insert(backpackTable, v.Name)
	end
	
	if backpackTable ~= nil then
		dataStore:SetAsync(plr.UserId, backpackTable)
	end
end)

I added
plr.Character:WaitForChild(“Humanoid”):UnequipTools() to line 27 to try to unequip the tool when the player leaves but by the time it gets to that, the player is already gone. Im not really sure what else to do.

2 Likes

Try this:

-- Initialize empty inventory table
local Inventory = {}

-- Function to handle player spawning
local function Spawned(Char)
    local Plr = game.Players:GetPlayerFromCharacter(Char)
    
    for i, v in pairs(Inventory[Plr] or {}) do     -- Check and move items from inventory to backpack
        if Plr.Backpack:FindFirstChild(v.Name) then
            Plr.Backpack[v.Name]:Destroy()
        end
        v.Parent = Plr.Backpack
    end
    
    Inventory[Plr] = {}     -- Clear inventory for the player
    
    Char:WaitForChild('Humanoid').Died:Connect(function() -- Listen for player death to store items back to inventory
        for i, v in pairs({ Plr.Backpack, Char }) do
            for ii, vv in pairs(v:GetChildren()) do
                if vv:IsA('Tool') then
                    -- Check if the tool is not a starter tool before storing
                    if not game:GetService("StarterPack"):FindFirstChild(vv.Name) then
                        table.insert(Inventory[Plr], vv:Clone())
                    end
                    vv:Destroy()
                end
            end
        end
    end)
end

game.Players.PlayerAdded:Connect(function(Plr)
    -- Initialize player's inventory
    Inventory[Plr] = {}
    
    local Char = Plr.Character or Plr.CharacterAdded:Wait()     -- Get the character or wait for it to respawn
    
    Spawned(Char) -- Call the Spawned function for the player
    
    Plr.CharacterAdded:Connect(Spawned)    -- Listen for character respawn to call Spawned again
end)


This script manages player inventory by storing their tools in a table, moving them to the backpack when respawning, and restoring them upon death, ensuring persistent inventory across player sessions.

Edit: added coments so you can understand how the code works

This doesnt have any DataStoring though? I need the tools to save if they leave.

Data storage refers to the process of saving and retrieving data in a game to maintain player progress, settings, or inventory across sessions. In the provided script, there’s no mechanism for saving the player’s inventory across sessions, so if they leave the game, their inventory will be lost. To implement data storage, you’d need to use methods like DataStoreService to save and load player inventory data.

I suggest you to take a look to this documentation

It has so many content related which will be usefull for you

Are you using an AI for these messages lol? That script would not ensure persistent inventory across player sessions. Obviously I know what DataStores are if the original script has them. I just want to know how I could save the tools that arent in the backpack.

Why dont you just save the inventory Table under the player using DataStorage?

I think when a player equips a tool it goes into their workspace model? Try adding a check if there is a tool in the player and if there is, save it to the backpackTable

1 Like

Thank you! I wasnt sure where the tool went. Incase anyone else has this issue, I just added the following to the player removing function.

	for i,v in pairs(plr.Character:GetChildren()) do
		if v:IsA("Tool") then
			table.insert(backpackTable, v.Name)
		end
	end

This was working before, but it stopped working. No idea why, but Im getting the error "attempt to index nil with ‘GetChildren’. Im assuming the players character is being removed before the code can be ran, But im not sure how I would check their tools if thats happening. Any Ideas?

You can use .CharacterRemoving, it fires before the player’s character gets removed

game.Players.PlayerRemoving:Connect(function(player)
	player.CharacterRemoving:Connect(function(char)

	end)
end)

I tried that, but in its own function, and what you suggested, but neither run in time. The characters already gone at that point.

I don’t really know any other suggestions to fully fix this problem (maybe a failsafe with collectionservice to check if the player leaves? In my experience PlayerRemoving is kinda unreliable) but that’s about it, or maybe try checking if you added any deferring in PlayerRemoving? eg.

game.Players.PlayerRemoving:Connect(function(plr) 
      task.wait(1) -- this wont work
      print("Hello")
end)

It’s also possible that running this line (if you still have it) plr.Character:WaitForChild("Humanoid"):UnequipTools()
can defer the PlayeRemoving code because it uses :WaitForChild()