How to save tools when backpack changes or player dies

I’m making a retro survival game with tools and items but I’m having a problem. I found this script and modified it a bit. The problem is that it only saves when player leaves the game. The items can be dropped so it’s possible to duplicate items and the same thing happens when a player dies. Is it possible to save when backpack is modified or before a player dies? I’m not that good at scripting datastores.

local dss = game:GetService("DataStoreService")
local toolsDS = dss:GetDataStore("ToolsData")

local toolsFolder = game.ReplicatedStorage.Items

game.Players.PlayerAdded:Connect(function(plr)

	local toolsSaved = toolsDS:GetAsync(plr.UserId .. "-tools") or {}

	for i, toolSaved in pairs(toolsSaved) do

		if toolsFolder:FindFirstChild(toolSaved) then 

			toolsFolder[toolSaved]:Clone().Parent = plr.Backpack
			toolsFolder[toolSaved]:Clone().Parent = plr.StarterGear 
		end
	end

	plr.CharacterRemoving:Connect(function(char)
		if char:FindFirstChildOfClass("Tool") then
			char:FindFirstChildOfClass("Tool").Parent = plr.Backpack
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(plr)
	
	local toolsOwned = {}

	for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do

		table.insert(toolsOwned, toolInBackpack.Name)
	end

	local success, errormsg = pcall(function()

		toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)
	end)
	if errormsg then warn(errormsg) end
end)

I tried to to this but it didn’t work:

local dss = game:GetService("DataStoreService")
local toolsDS = dss:GetDataStore("ToolsData")

local toolsFolder = game.ReplicatedStorage.Items

game.Players.PlayerAdded:Connect(function(plr)

	local toolsSaved = toolsDS:GetAsync(plr.UserId .. "-tools") or {}

	for i, toolSaved in pairs(toolsSaved) do

		if toolsFolder:FindFirstChild(toolSaved) then 

			toolsFolder[toolSaved]:Clone().Parent = plr.Backpack
			toolsFolder[toolSaved]:Clone().Parent = plr.StarterGear 
		end
	end

	plr.CharacterRemoving:Connect(function(char)
		if char:FindFirstChildOfClass("Tool") then
			char:FindFirstChildOfClass("Tool").Parent = plr.Backpack
		end
	end)
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.Backpack.ChildAdded:Connect(function()
		local toolsOwned = {}

		for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do

			table.insert(toolsOwned, toolInBackpack.Name)
		end

		local success, errormsg = pcall(function()

			toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)
		end)
		if errormsg then warn(errormsg) end
	end)
	
	plr.Backpack.ChildRemoved:Connect(function()
		local toolsOwned = {}

		for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do

			table.insert(toolsOwned, toolInBackpack.Name)
		end

		local success, errormsg = pcall(function()

			toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)
		end)
		if errormsg then warn(errormsg) end
	end)
end)

Thanks for helping.

you might want to ensure that tools are not duplicated when a player dies, is to clear the player’s StarterGear and Backpack before re adding the tools:

plr.CharacterRemoving:Connect(function(char)
    plr.StarterGear:ClearAllChildren()
    plr.Backpack:ClearAllChildren()
    if char:FindFirstChildOfClass("Tool") then
        char:FindFirstChildOfClass("Tool").Parent = plr.Backpack
    end
    saveTools(plr)
end)
1 Like