Hello! I’m making a system that looks inside a players inventory folder, which holds Configurations with ObjectValues, and gets the tool from said ObjectValue, clones it, and places it in the players backpack. I have a remote function in ReplicatedStorage called CloneModel to help this. However, my problem is that it seems to not be parented inside the players backpack. I’ve tried debugging by putting it inside the workspace instead, but it goes into the workspace fine-it only seems to be a problem when i place it in the backpack. Whenver I use print to constantly print the parent of the model, it only prints backpack once and then it keeps printing nil. Any help is appreciated!
Player Code (in localScript):
--this current script just looks throughout the players inventory folder, looks for any configs which
--ObjectValue called "Model" is a tool ,and places them in the players backpack. This needs to be updated when
--you finally get better inventory logic, but for now its-a-good (mario reference)
local plr = game.Players.LocalPlayer
local inventory = script.Parent.PlayerInventory --update whenver inventory may change
local backpack = plr.Backpack
function updateInventory()
--[[for i,v in pairs(backpack:GetChildren()) do
v:Destroy()
end]]--
for i,v in pairs(inventory:GetChildren()) do
print("Loooking at Inventory item")
print(v)
if v:IsA("Configuration") then
if v.Model then
if v.Model.Value ~= nil then
print("Found adequate model")
if v.Model.Value:IsA("Tool") then
print("Model is a tool. Going into backpack...")
if backpack:FindFirstChild(v.Name) == nil then
local tool = v.Model.Value
local backpack = plr:WaitForChild("Backpack")
game.ReplicatedStorage.CloneModel:FireServer(tool,backpack)
end
end
end
end
end
end
end
--just to make sure everything is loaded in the folder
inventory:WaitForChild("Sword")
updateInventory()
Server side code (in serverscriptservice):
game.ReplicatedStorage.CloneModel.OnServerEvent:Connect(function(plr,model,par)
local clone = model:Clone()
clone.Parent = par
print(model,par)
print(clone.Parent.Parent)
end)
Imo your best decision is to rewrite this whole thing except completely serversided. Store the inventory in the server, whether that’s through a folder object with the items as its children, or simply a table, you should 100% migrate it to the server. Your “CloneModel” remote event opens up some pretty big security vulnerabilities as exploiters can fire remote events/functions whenever they want, so as long as they found where the tools are located they could give themself every single one.
You can see an example of a simple inventory back end I made a while ago here.
Security isn’t a problem for me though-my game is singleplayer (it even has loadString enabled). If I was making a multiplayer game, I wouldn’t do that, but this is like a singleplayer rpg. Should I still rewrite it completely serverside?
I guess if you don’t mind, then no, you shouldn’t need to rewrite it. Back to your original problem; I’m not sure, do you think you could paste exactly what the output says for both of the print statements?
--upated code with logs:
local pastModel
game.ReplicatedStorage.CloneModel.OnServerEvent:Connect(function(plr,model,par)
local clone = model:Clone()
clone.Parent = par
print(model,par)
print(clone.Parent.Parent)
pastModel = model
end)
while task.wait(1) do
print(pastModel)
print(pastModel.Parent)
end
17:03:18.898 Loooking at Inventory item - Client - InventoryLocalizer:14
17:03:18.898 Sword - Client - InventoryLocalizer:15
17:03:18.901 Found adequate model - Client - InventoryLocalizer:19
17:03:18.901 Model is a tool. Going into backpack… - Client - InventoryLocalizer:21
17:03:19.790 Weld Constraint Plugin by RyCitrus Loaded - Server
17:03:19.832 Sword Backpack - Server - CloneManager:5
17:03:19.841 domo30174 - Server - CloneManager:6
17:03:19.845 Sword - Server - CloneManager:11
17:03:19.848 ItemModels - Server - CloneManager:12
17:03:20.148 Weld Constraint Plugin by RyCitrus Loaded - Client
17:03:20.868 Sword - Server - CloneManager:11
17:03:20.871 ItemModels - Server - CloneManager:12
17:03:21.878 Sword - Server - CloneManager:11
17:03:21.882 ItemModels - Server - CloneManager:12
17:03:22.903 Sword - Server - CloneManager:11
17:03:22.906 ItemModels - Server - CloneManager:12
17:03:23.918 Sword - Server - CloneManager:11
17:03:23.923 ItemModels - Server - CloneManager:12
17:03:25.064 Disconnect from ::ffff:127.0.0.1|57603 - Studio
17:03:25.065 Sword - Server - CloneManager:11
17:03:25.067 ItemModels - Server - CloneManager:12
It’s possible the backpack is not shared over the client-server boundary reference-wise due to unique behavior. How this would be caused is Backpack is actually instantiated separately on the client and server with different reference ID’s. So, when the client provides par (which gets serialized into a reference ID) it cannot be solved to the Backpack on the server.
To test this, try setting the parent to Player.Backpack rather than the given parent. If it works, this is the case.
I made this script which when parented to a part adds an item to the players backpack whenever a player touches it. You could try it out and see if it helps you find your issue.
local Players = game:GetService("Players")
local part = script.Parent
local function action(hit)
local character = hit.Parent
local humanoid = character:FindFirstChild("Humanoid")
local player = Players:GetPlayerFromCharacter(character)
if player and humanoid then
local backpack = player:FindFirstChild("Backpack")
if backpack then
local tool = Instance.new("Tool")
tool.Parent = backpack
end
end
end
part.Touched:Connect(action)
just found the problem-it was the character hadn’t fully loaded in along with the backpack. I assume LoadCharacter reloads the character BUT destroys the inventory. I added a simple wait(5) before the first updateInventory call and it works just dandy