Remote event bug

So i have 2 remote events in replicated storage: Event2 and RemoteEvent
I also have a simple client script:

local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.X then
		game.ReplicatedStorage.RemoteEvent:FireServer()
	elseif input.KeyCode == Enum.KeyCode.Z then
		game.ReplicatedStorage.Event2:FireServer()
	end
end)

And a server script:

game.ReplicatedStorage.Event2.OnServerEvent:Connect(function()
	game.ReplicatedStorage.RemoteEvent.OnServerEvent:Once(function()
		print(1)
	end)
	print(2)
end)

After pressing X and then Z i expect nothing to happen because for the RemoteEvent to fire Event2 has to be fired before it, not after. For some reason RemoteEvent is being fired and 1 is getting printed AND 2 is getting printed after it. So for some reason the RemoteEvent fires as soon as it is summoned. Why?
image
(2 and 1 are printed the same exact moment)

1 Like
local UIS = game:GetService("UserInputService")

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.X then
		game.ReplicatedStorage.RemoteEvent:FireServer()
	elseif input.KeyCode == Enum.KeyCode.Z then
		game.ReplicatedStorage.Event2:FireServer()
	end
end)

server

game.ReplicatedStorage.Event2.OnServerEvent:Connect(function()
	local remoteEvent = game.ReplicatedStorage.RemoteEvent
	local connection
	connection = remoteEvent.OnServerEvent:Connect(function()
		print(1)
		connection:Disconnect() -- Disconnect the event after it's fired once
	end)
	print(2)
end)

U can try disconnecting

1 Like

And put print 2 before print 1

1 Like

you can just do this instead

remoteEvent.OnServerEvent:Once(function() -- Runs only once after called.
		print(1)
end)
1 Like

Nvm i think i messed up somewhere because now I see what the problem was

1 Like

oof i dont know how to fix this Sorry

1 Like

Great question!

This behavior is occurring as a result of the ā€˜invocation queueā€™. When a RemoteEvent is fired, it creates a queue of inbound events. I donā€™t recall the exact behavior off the top of my head, but essentially what is happening here:

You press X. An event is added to the ā€œRemoteEventā€ invocation queue. Then, you press Z. ā€œRemoteEventā€ is connected, and it can now process its queue. Since it is synchronous and is connected before print(2), it will run print(1) before proceeding.

You can further see this behavior by pressing X several times. Upon pressing Z, youā€™ll notice print(1) will execute the same number of times you pressed X.

The easiest way to fix this behavior is to avoid putting event connections inside of other event connections. Keep them top-level, and then handle the logic inside the connection itself.

2 Likes

I think i understand and i think i found 2 solutions for that (it would be difficult to have the events on the top level):

  1. Putting a timer so for example the event cannot be fired the first 2 miliseconds and would automaticaly stop after 50 miliseconds passed so it wouldnt have a bad effect on the server.
game.ReplicatedStorage.Event2.OnServerEvent:Connect(function()
	local TimerStopped = false
	local TimerAmount = 0
	task.spawn(function()
		while not TimerStopped do
			TimerAmount += 1
			task.wait()
		end
	end)
	
	game.ReplicatedStorage.RemoteEvent.OnServerEvent:Once(function()
		print(TimerAmount)
		if TimerAmount - 2 > 0 then
			TimerStopped = true
			print("Second event fired")
		end
	end)
	print("First event fired")
	
end)
  1. Creating another empty event before the main event is fired so it unloads the que. It seems more efficient in terms of performace and overall cleaner but could im not sure if it could affect other players experience.
game.ReplicatedStorage.Event2.OnServerEvent:Connect(function()

	game.ReplicatedStorage.RemoteEvent.OnServerEvent:Once(function()
	end)

	game.ReplicatedStorage.RemoteEvent.OnServerEvent:Once(function()
		print("Second event fired")
	end)
	print("First event fired")

end)

You seem pretty experienced in this field so could please suggest which one to choose?

2 Likes

Both of these solutions seem a bit hacky. Iā€™d be especially hesitant to use the first one because timing can be inconsistent. The second solution is somewhat unpredictable, potentially firing the second event multiple times with only one corresponding Z press.

I donā€™t know your exact use-case, but hereā€™s my general recommendation, keeping the connections top-level. This also ensures that there can be, at most, 1 ā€œresponseā€ (X key processing) for any given Z press:

local awaitingResponse = false
Event2.OnServerEvent:Connect(function()
	awaitingResponse = true
	print(2)
end)

RemoteEvent.OnServerEvent:Connect(function()
	if awaitingResponse then
		awaitingResponse = false
		print(1)
	end
end)
2 Likes

Ye, this seems like the neatest and most consistent way of doing it, thx :grin:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.