I have a script that saves items in the players backpack into a table that will be accessed when the player rejoins, but the problem is whenever I hold the items and leave they don’t save.
I came to the conclusion that its because the item isn’t in the backpack anymore but in the character model, but no matter what i do to try to access the character after it leaves it does not work.
local inventoryStore = datastores:GetDataStore("InventoryData")
players.PlayerRemoving:Connect(function(player)
local backpack = player:FindFirstChild("Backpack")
if backpack then
local items = {}
for _, item in pairs(backpack:GetChildren()) do
print(item)
table.insert(items, item.Name)
end
if player then
player.CharacterRemoving:Connect(function(character)
for _, item in pairs(character:GetDescendants()) do
if item:IsA('Tool') then
print(item.Name)
table.insert(items, item.Name)
end
end
end)
end
local yay, err = pcall(function()
inventoryStore:SetAsync(player.UserId, items)
end)
if not yay then
warn("Failed to save inventory for", player.Name, err)
end
end
end)
players.PlayerAdded:Connect(function(player)
-- load the items
local yay, items = pcall(function()
return inventoryStore:GetAsync(player.UserId)
end)
if yay and items then
for _, itemName in pairs(items) do
local itemTemplate = workspace.buyableItems:FindFirstChild(itemName)
if itemTemplate then
local clone = itemTemplate:Clone()
clone.Handle.Anchored = false
clone.Parent = player:WaitForChild("Backpack")
end
end
end
end)
This is because you are connecting the CharacterRemoving event with the function after it is fired. In your case, there is no need to get the character through the removing event. Simply get the character via player.Character.
Also, you can simplify your code by getting the held tool with player.Character:FindFirstChildOfClass("Tool"). Since you can only have one held tool, there will only be one Tool in the character, removing the need for loops.
local character: Model? = player.Character
if character then
local tool: Tool? = character:FindFirstChildOfClass("Tool")
if tool then
table.insert(items, tool.Name)
end
end
As far as I know, this is the only way i can get the character because i am doing all of this in a server script. I don’t know how else i can grab the character.
@ardrous 100% knows more than me, but incase you can’t get the character still, a sloppy solution would probably be to have something that keeps track when the player has a tool equipped, so you can just check that variable when saving to make sure you include their equipped tool before they left. (only if you can’t get the character for whatever reason, I’m assuming he already gave the solution, but just incase it isn’t)
Yes, i attempted that and i even added print statements to check if the tool was even being found. The entire character seems to just be gone before it can check for the tool.
local inventoryStore = datastores:GetDataStore("InventoryData")
players.PlayerRemoving:Connect(function(player)
local backpack = player:FindFirstChild("Backpack")
local character = player.Character
if backpack then
local items = {}
for _, item in pairs(backpack:GetChildren()) do
print(item)
table.insert(items, item.Name)
end
if character then
local tool = character:FindFirstChildOfClass('Tool')
if tool then
table.insert(items, tool.Name)
end
end
Ah I see, I misunderstood your followup question. In that case, similar to what @Ender_devTC mentioned, I would store the last equipped tool name. You can use character.ChildAdded and update the last equipped tool name for each player.
It’s important to make sure to also update when there is no tool being held, so you aren’t duping tools that were unequipped and are back in backpack. I also wonder if something like this would still allow for some perfectly timed equipping and unequipping that would have 2 copies of the same tool, so probably might need some basic security system that makes sure it doesn’t save the same tool twice.
Yeah, agreed. I think rather than keeping track of the tool being equipped, it would be much more reliable and efficient to keep track of all tools when they are first added to the backpack. When the player leaves, you will have an updated table of tool names that can be used. This method would make sure quickly equipping or unequipping tools would have no effect on saving.