Help with remote events

I’m making an AOT game and of course it needs a grapple.
So I made the grapple, but of course. Its client sided.
The script that detects the remote event doesnt work.
Server script:

game.ReplicatedStorage.grapple.OnServerEvent:Connect(function(rope, attachment1, attachment2,vector,m)
	
	vector.Attachment0 = attachment1
	vector.Force = Vector3.new(0,0,-4000)
	rope.Attachment0=attachment1
	local pos = m.Target.Position
	rope.Attachment1=attachment2
	rope.Visible=true
	rope.Color = BrickColor.new("Really black")
	local magnitude = (script.Parent.HumanoidRootPart.Position - pos).magnitude
	rope.Length = magnitude
	while true do
		wait()
		rope.Length = rope.Length -1
		if rope.Length <= 4 then
			rope:Destroy()
			vector:Destroy()
		end
	end

	
end)

Local script in startercharacterscripts

local m = game.Players.LocalPlayer:GetMouse()
local debounce = false
m.KeyDown:connect(function(k)

	if k == "f" then
		if m.Target == nil then warn("target not found.") return end
		local attachment1 = Instance.new("Attachment",script.Parent.HumanoidRootPart)
		local attachment2 = Instance.new("Attachment",m.Target)
		local rope = Instance.new("RopeConstraint",script.Parent.HumanoidRootPart)
		local vector = Instance.new("VectorForce",script.Parent.Torso)
		game.ReplicatedStorage.grapple:FireServer(m, rope,attachment1,attachment2,vector)

	end
end)
1 Like

When making a remote event on the server, the server must reference the Player.

game.ReplicatedStorage.grapple.OnServerEvent:Connect(function(rope, attachment1, attachment2,vector,m)

The first parameter here should reference the “Player”, as the server needs to know who requested this event. Your first parameter is rope, so the server is assuming “rope” is the player.

I also noticed that your parameters don’t seem to be lined up:
game.ReplicatedStorage.grapple:FireServer(m, rope,attachment1,attachment2,vector)

game.ReplicatedStorage.grapple.OnServerEvent:Connect(function(rope, attachment1, attachment2,vector,m)

You have to line up the parameters correctly. On the client it would be (rope, attachment1, attachment2, vector, m) and on the server it would be (Player, rope, attachment1, attachment2, vector, m). Otherwise the script will mix the parameters up.

1 Like

It still does not work, and doesnt recognize any of the locals sent to the remote event.

game.ReplicatedStorage.grapple.OnServerEvent:Connect(function(player,m,rope,attachment1,attachment2,vector)
	
	vector.Attachment0 = attachment1
	vector.Force = Vector3.new(0,0,-4000)
	rope.Attachment0=attachment1
	local pos = m.Target.Position
	rope.Attachment1=attachment2
	rope.Visible=true
	rope.Color = BrickColor.new("Really black")
	local magnitude = (script.Parent.HumanoidRootPart.Position - pos).magnitude
	rope.Length = magnitude
	while true do
		wait()
		rope.Length = rope.Length -1
		if rope.Length <= 4 then
			rope:Destroy()
			vector:Destroy()
		end
	end

	
end)

It prints an error saying “attempt to index nil with attachment0”

local m = game.Players.LocalPlayer:GetMouse()
local debounce = false
m.KeyDown:connect(function(k)

	if k == "f" then
		local player = game.Players.LocalPlayer
		if m.Target == nil then warn("target not found.") return end
		local attachment1 = Instance.new("Attachment",script.Parent.HumanoidRootPart)
		local attachment2 = Instance.new("Attachment",m.Target)
		local rope = Instance.new("RopeConstraint",script.Parent.HumanoidRootPart)
		local vector = Instance.new("VectorForce",script.Parent.Torso)
		game.ReplicatedStorage.grapple:FireServer(player,m,rope,attachment1,attachment2,vector)

	end
end)
1 Like

game.ReplicatedStorage.grapple:FireServer(player,m,rope,attachment1,attachment2,vector)

The player parameter here is messing up the server’s parameters. Only the server should have the player parameter, not the localscript.

The server’s referencing the player because it’s taking a local client’s request and it needs to refer to what client was firing. The localscript doesn’t need to include this when firing to the server.

1 Like

Ah, okay. So do I get rid of the player on the local script?

Yeah, only the player parameter should be on the server.

Also I noticed that your script has a while loop that fires here:

while true do
		wait()
		rope.Length = rope.Length -1
		if rope.Length <= 4 then
			rope:Destroy()
			vector:Destroy()
		end
	end

I would suggest replacing that with this:

while true do
		wait()
		rope.Length = rope.Length -1
		if rope.Length <= 4 then
			rope:Destroy()
			vector:Destroy()
            break
		end
	end

Break forces the while loop to end once the condition is met. This fixes a potential memory leak and any errors that may crop up.

Still, does not recognize the locals.

1 Like

It appears you switched the order around on your variables. It’s easier than that.

On client:

Eventname:FireServer(arg1, arg2…)

On server:

Eventname.OnServerEvent:Connect(function (player, arg1, arg2…))

The client already knows what the player is. It tells the server as the first variable. Everything else has to stay the same in the same order.

Could try showing your code? Or did a new error crop up?

1 Like

Local code

local m = game.Players.LocalPlayer:GetMouse()
local debounce = false
m.KeyDown:connect(function(k)

	if k == "f" then
		local player = game.Players.LocalPlayer
		if m.Target == nil then warn("target not found.") return end
		local attachment1 = Instance.new("Attachment",script.Parent.HumanoidRootPart)
		local attachment2 = Instance.new("Attachment",m.Target)
		local rope = Instance.new("RopeConstraint",script.Parent.HumanoidRootPart)
		local vector = Instance.new("VectorForce",script.Parent.Torso)
		game.ReplicatedStorage.grapple:FireServer(m,rope,attachment1,attachment2,vector)

	end
end)

Server code

game.ReplicatedStorage.grapple.OnServerEvent:Connect(function(player,m,rope,attachment1,attachment2,vector)
	
	vector.Attachment0 = attachment1
	vector.Force = Vector3.new(0,0,-4000)
	rope.Attachment0=attachment1
	local pos = m.Target.Position
	rope.Attachment1=attachment2
	rope.Visible=true
	rope.Color = BrickColor.new("Really black")
	local magnitude = (script.Parent.HumanoidRootPart.Position - pos).magnitude
	rope.Length = magnitude
	while true do
		wait()
		rope.Length = rope.Length -1
		if rope.Length <= 4 then
			rope:Destroy()
			vector:Destroy()
			break
		end
	end

	
end)

Can we see how you have grapple set up? Remote/bindable/event/function still trips me up.

Also, what errors are you getting?

1 Like

This is the old script that only fired on the client.

local m = game.Players.LocalPlayer:GetMouse()
local debounce = false
m.KeyDown:connect(function(k)

	if k == "f" then
		if m.Target == nil then warn("target not found.") return end
		local attachment1 = Instance.new("Attachment",script.Parent.HumanoidRootPart)
		local attachment2 = Instance.new("Attachment",m.Target)
		local rope = Instance.new("RopeConstraint",script.Parent.HumanoidRootPart)
		local vector = Instance.new("VectorForce",script.Parent.Torso)
		vector.Attachment0 = attachment1
		vector.Force = Vector3.new(0,0,-4000)
		rope.Attachment0=attachment1
		local pos = m.Target.Position
		rope.Attachment1=attachment2
		rope.Visible=true
		rope.Color = BrickColor.new("Really black")
		local magnitude = (script.Parent.HumanoidRootPart.Position - pos).magnitude
		rope.Length = magnitude
		while true do
			wait()
			rope.Length = rope.Length -1
			if rope.Length <= 4 then
				rope:Destroy()
				vector:Destroy()
			end
		end

	end
end)

PS: Im getting “attempt to index nil with attachment0”

OK, attachment0 is not in the event parameters. Either “vector” or “rope” are nil.

1 Like

It appears everything is nil actually.

Okay, I see the issue.

You’re making instances on the client. You cannot translate this to the server, it doesn’t read anything made on the client.

        local attachment1 = Instance.new("Attachment",script.Parent.HumanoidRootPart)
		local attachment2 = Instance.new("Attachment",m.Target)
		local rope = Instance.new("RopeConstraint",script.Parent.HumanoidRootPart)
		local vector = Instance.new("VectorForce",script.Parent.Torso)

This is on the client, which is why the server sees it as nil. Whenever you make something on the client, the server cannot read it. That’s why the error pops up.

I think what solves this issue is by moving these instances to the server event and have it deal with the instances there.

Although I’m not sure if this is entirely the case since the error is popping up in a weird spot, try doing this anyway.

1 Like

Found it! Calling the parent in Instance.new() is not recommended. Use multiple lines. (/crossesfingers)

2 Likes

I actually never knew this. Thanks for showing it!

I always just parented it once I created the instance in a separate line but I’ll keep on that habit for sure now.

Do I move the new instances over to the serverscript?

1 Like

I agree client/server will be a problem later, but a new instance shouldn’t be nil in the very next line of code. :smiley:

Yes. And because you’re doing all of it on the server you can remove the parameters too (not the player one tho)