How do i save the current tool the player is holding to a table for DataStore?

I’m trying to save the players backpack as a datastore to persist across joins.
My issue is, how do i also grab the tool the player is holding and insert it into this table?
This is the code that is run as the player is leaving at the moment.
Any ideas?

local inventory = {}
	for i,v in pairs(player.Backpack:GetChildren()) do
		if tol:FindFirstChild(v.Name) then

			table.insert(inventory,v.Name)

		end

	end
	local success,errormessage = pcall(function()
		DataStore:UpdateAsync(player.UserId.."-stuff", function(CurrentState) 
			return inventory or CurrentState  
		end)

The equipped tool is always parented to the player’s character. So on top of checking everything in the players backpack, you would also have to check the players character for a tool. You wouldn’t need to loop through the characters children since there will only be 1 tool equipped at a time.

You could try something like this:

local Tool = Player.Character:FindFirstChildWhichIsA("Tool");

if Tool then -- check if the tool exist
-- found a tool and add it to the inventory table
end;

Alternatively, you could also just unequip all tools before the loop

Player.Character.Humanoid:UnequipTools(); -- unequips the tool player is holding

-- continue with your for loop, etc
1 Like

My issue is that this script is executed as the player is leaving so the character has already been destroyed and no longer in workspace resulting in attempt to index nil with 'FindFirstChildWhichIsA' because Player.Character is nil

you should keep a server script that keeps a variable/table of the last equip tool of the player and save from that if character destruction is an issue

1 Like
local Game = game
local Players = Game:GetService("Players")
local ServerStorage = Game:GetService("ServerStorage")
local DataStoreService = Game:GetService("DataStoreService")
local ItemStore = DataStoreService:GetDataStore("ItemStore")

local Cache = {}

local function OnPlayerAdded(Player)
	local function OnCharacterAdded(Character)
		local function OnCharacterChildAdded(Child)
			if not (Child:IsA("BackpackItem")) then return end
			Cache[Player] = Child
		end
	end
	
	Player.CharacterAdded:Connect(OnCharacterAdded)
	
	local Success, Result = pcall(ItemStore.GetAsync, ItemStore, Player.UserId)
	if not Success then warn(Result) return end
	if not Result then return end
	local Item = ServerStorage:FindFirstChild(Result)
	if not Item then return end
	local StarterGear = Player:FindFirstChildOfClass("StarterGear") or Player:WaitForChild("StarterGear")
	Item:Clone().Parent = StarterGear
	Player:LoadCharacter()
end

local function OnPlayerRemoving(Player)
	if not Cache[Player] then return end
	local Success, Result = pcall(ItemStore.SetAsync, ItemStore, Player.UserId, Cache[Player].Name)
	if not Success then warn(Result) end
	Cache[Player] = nil
end

local function OnGameClose()
	for _, Player in ipairs(Players:GetPlayers()) do
		OnPlayerRemoving(Player)
	end
end

Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
Game:BindToClose(OnGameClose)
1 Like