Passing instances through remote function does not work

I need the client to tell the server to make some parts then the client can manipulate them. I want the parts to be on the server so they replicate to other players. I use a remote function. Problem is that when returning, the parts seem to be lost.


Client Script:

		BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld,
			FakeRArm, FakeRWeld = 
			Rep.Armmaker:InvokeServer(
				HRP,Torso,Gun_Ignore,Head,ArmC0,S.ArmC1_UnAimed.Left,S.ArmC1_UnAimed.Right,LArm,RArm,S.PlayerArms,S.FakeArmTransparency,
				Character,S.FakeArmColor,S.FakeArmRealBodyColor,LArm.BrickColor,RArm.BrickColor)
		print(Gun_Ignore:GetDescendants())
		print(BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld,
			FakeRArm, FakeRWeld)

Server Script:

Rep.Armmaker.OnServerInvoke = function(Player,HRP,Torso,Gun_Ignore,Head,ArmC0,SArmC1_UnAimedLeft,SArmC1_UnAimedRight,LArm,RArm,
	SPlayerArms,SFakeArmTransparency,Character,SFakeArmColor,SFakeArmRealBodyColor,LArmBrickColor,RArmBrickColor)
	
	--... Make parts ...

	print(BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld, FakeRArm, FakeRWeld)
	return BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld, FakeRArm, FakeRWeld
end

It is worth noting that the client does receive the parts from the remote function if there are two task.wait() s at the end of the server script

Rep.Armmaker.OnServerInvoke = function(Player,HRP,Torso,Gun_Ignore,Head,ArmC0,SArmC1_UnAimedLeft,SArmC1_UnAimedRight,LArm,RArm,
	SPlayerArms,SFakeArmTransparency,Character,SFakeArmColor,SFakeArmRealBodyColor,LArmBrickColor,RArmBrickColor)
	
	--... Make parts ...

	print(BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld, FakeRArm, FakeRWeld)
	task.wait()
	task.wait()
	return BG, PlayerFolder, AnimBase, AnimWeld, ArmBase, ABWeld, LArmBase, RArmBase, LWeld, RWeld, LWeld2, RWeld2, FakeLArm, FakeLWeld, FakeRArm, FakeRWeld
end

Does anyone know why this happens?
As you can see in the image, the client can see AnimBase, but AnimBase is set to nil by the remote event. I thought it might have something to do with replication time, but that can not be true as, even without the two waits, the client does see the parts.

Am I forced to index the parts on the client rather than through the remote function? I would still have to use a remote function to make the client script yield for the parts being made.

Instances only replicate to client if they are a descendant of a replicated container.

As explained in print(Gun_Ignore:GetDescendants()) The client does see the parts, they just are not passed by the remote function. Only BG and PlayerFolder are. They are made in the workspace btw.
I guess I will give you the creation code, I dident want to include it as it is very long and repetative.

	local BG = Instance.new("BodyGyro", HRP)
	BG.maxTorque = VEC3(10000,10000,10000)
	BG.Name = "BG"
	BG.P = 1e5
	BG.D = 250
	BG.cframe = CF(Torso.CFrame.p, Torso.CFrame.p + Torso.CFrame.lookVector)

	local PlayerFolder = Instance.new("Model")
	PlayerFolder.Name = "PlayerFolder"
	PlayerFolder.Parent = Gun_Ignore

	local AnimBase = Instance.new("Part")
	AnimBase.Transparency = 1
	AnimBase.Name = "AnimBase"
	AnimBase.CanCollide = false
	AnimBase.FormFactor = Enum.FormFactor.Custom
	AnimBase.Size = VEC3(0.2, 0.2, 0.2)
	AnimBase.BottomSurface = Enum.SurfaceType.Smooth
	AnimBase.TopSurface = Enum.SurfaceType.Smooth
	AnimBase.Parent = PlayerFolder

	local AnimWeld = Instance.new("Weld")
	AnimWeld.Part0 = AnimBase
	AnimWeld.Part1 = Head
	AnimWeld.C0 = CF(0, 1, 0)
	AnimWeld.Parent = AnimBase

	local ArmBase = Instance.new("Part")
	ArmBase.Transparency = 1
	ArmBase.Name = "ArmBase"
	ArmBase.CanCollide = false
	ArmBase.FormFactor = Enum.FormFactor.Custom
	ArmBase.Size = VEC3(0.2, 0.2, 0.2)
	ArmBase.BottomSurface = Enum.SurfaceType.Smooth
	ArmBase.TopSurface = Enum.SurfaceType.Smooth
	ArmBase.Parent = PlayerFolder

	local ABWeld = Instance.new("Weld")
	ABWeld.Part0 = ArmBase
	ABWeld.Part1 = AnimBase
	ABWeld.Parent = ArmBase

	local LArmBase = Instance.new("Part")
	LArmBase.Transparency = 1
	LArmBase.Name = "LArmBase"
	LArmBase.CanCollide = false
	LArmBase.FormFactor = Enum.FormFactor.Custom
	LArmBase.Size = VEC3(0.2, 0.2, 0.2)
	LArmBase.BottomSurface = Enum.SurfaceType.Smooth
	LArmBase.TopSurface = Enum.SurfaceType.Smooth
	LArmBase.Parent = PlayerFolder

	local RArmBase = Instance.new("Part")
	RArmBase.Transparency = 1
	RArmBase.Name = "RArmBase"
	RArmBase.CanCollide = false
	RArmBase.FormFactor = Enum.FormFactor.Custom
	RArmBase.Size = VEC3(0.2, 0.2, 0.2)
	RArmBase.BottomSurface = Enum.SurfaceType.Smooth
	RArmBase.TopSurface = Enum.SurfaceType.Smooth
	RArmBase.Parent = PlayerFolder

	local LWeld = Instance.new("Weld")
	LWeld.Name = "LWeld"
	LWeld.Part0 = ArmBase
	LWeld.Part1 = LArmBase
	LWeld.C0 = ArmC0[1]
	LWeld.C1 = SArmC1_UnAimedLeft
	LWeld.Parent = ArmBase

	local RWeld = Instance.new("Weld")
	RWeld.Name = "RWeld"
	RWeld.Part0 = ArmBase
	RWeld.Part1 = RArmBase
	RWeld.C0 = ArmC0[2]
	RWeld.C1 = SArmC1_UnAimedRight
	RWeld.Parent = ArmBase

	local LWeld2 = Instance.new("Weld")
	LWeld2.Name = "LWeld"
	LWeld2.Part0 = LArmBase
	LWeld2.Part1 = LArm
	LWeld2.Parent = LArmBase

	local RWeld2 = Instance.new("Weld")
	RWeld2.Name = "RWeld"
	RWeld2.Part0 = RArmBase
	RWeld2.Part1 = RArm
	RWeld2.Parent = RArmBase
	
	local FakeLArm
	local FakeLWeld
	local FakeRArm
	local FakeRWeld
	if SPlayerArms then
		FakeLArm = LArm:Clone()
		FakeLArm.Parent = PlayerFolder
		FakeLArm.Transparency = SFakeArmTransparency
		FakeLArm:BreakJoints()
		FakeLArm.CanCollide = false
		LArm.Transparency = 1

		FakeLWeld = Instance.new("Weld")
		FakeLWeld.Part0 = FakeLArm
		FakeLWeld.Part1 = LArm
		FakeLWeld.Parent = FakeLArm

		FakeRArm = RArm:Clone()
		FakeRArm.Parent = PlayerFolder
		FakeRArm.Transparency = SFakeArmTransparency
		FakeRArm:BreakJoints()
		FakeRArm.CanCollide = false
		RArm.Transparency = 1

		RArm.Transparency = 1

		FakeRWeld = Instance.new("Weld")
		FakeRWeld.Part0 = FakeRArm
		FakeRWeld.Part1 = RArm
		FakeRWeld.Parent = FakeRArm

		Instance.new("Humanoid", PlayerFolder)

		for _,Obj in pairs(Character:GetChildren()) do
			if Obj:IsA("CharacterMesh") or Obj:IsA("Shirt") then
				Obj:Clone().Parent = PlayerFolder
			end
		end
	else
		local ArmTable = CreateArms(SFakeArmRealBodyColor,LArmBrickColor,RArmBrickColor,SFakeArmColor,SFakeArmTransparency)
		ArmTable[1].Model.Parent = PlayerFolder
		ArmTable[2].Model.Parent = PlayerFolder

		FakeLArm = ArmTable[1].ArmPart

		LArm.Transparency = 1

		FakeLWeld = Instance.new("Weld")
		FakeLWeld.Part0 = FakeLArm
		FakeLWeld.Part1 = LArm
		FakeLWeld.Parent = FakeLArm

		FakeRArm = ArmTable[2].ArmPart

		RArm.Transparency = 1

		FakeRWeld = Instance.new("Weld")
		FakeRWeld.Part0 = FakeRArm
		FakeRWeld.Part1 = RArm
		FakeRWeld.Parent = FakeRArm
	end

I’m sorry, I didn’t read the whole thing because it is too long for me. I just offered an answer to a common problem in case you had that problem. Good luck figuring it out!

I wanna quickly note that any instances created on the client will not show up on the server. Meaning that if you sent over for example a Weld that you created on the client to the server, the server will just think that what you sent is nothing (nil).

Yes I know, but these parts are made on the server. And they are replicated in time, they are just not passed by the remote function unless it has two task.wait()s, which is weird and confusing.

This is so weird, I simplified the problem and it seems like an intrinsic fault in the remote function, I have no explanation for this.
Client

print("a")
wait(2)
print("b")
local array,a,b,c,d,e,f,g = game.ReplicatedStorage.RemoteFunction:InvokeServer()
print(game.Workspace:GetChildren())
print(array,a,b,c,d,e,f,g)

Server

game.ReplicatedStorage.RemoteFunction.OnServerInvoke = function()
	local parts = {}
	
	for i = 1, 7 do
		local part = Instance.new("Part",game.Workspace)
		table.insert(parts, part)
	end
	
	print(table.unpack(parts))
	wait(2)
	return parts,table.unpack(parts)
end

Produces


Then, If I comment out the wait, the parts are not passed anymore.