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
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
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)