Extremely huge wait on .Touched()

Very first thing I did was print statements, the issue isn’t with what happens on .Touched(), all that really happens is the block is checked for if it’s a player, the anchoring of the boat is purely for debugging purposes

You missed clarifying my assumption; where is the part that has the Touched trigger?

And additionally; are there more invisible parts with triggers in that video?

Perhaps the invisible parts are so thin, that - due to how collision detection works in games - when the player looks like he passes through the “trigger”, the player model is actually never at-a-point-within-the-trigger-area, due to going so fast.

it’s the black bricks, the detection happens just with a massive delay. There are more parts but none of them have a function with .Touched for this test

I see that there are many parts that boat consist of.

How efficient is your code in the Touched event, to discard/ignore anything that is ‘not a player’?

Have you tried adding a counter-variable to the Touched event’s function, that gets increased at every “touch” (and possibly printed), to determine if it is simply a “massively overload of parts” that causes the “huge delay”?

Stay with .Touched event but change to a normal sized “gate” part and place it in front of the real gate position to meet the boat earlier.

Use it to turn on a boat position change listener (as suggested on the forum) that runs until the boat reach the desired point.

I agree with what the others above have been saying more recently.

It looks like you’ve got the thread suspending somewhere between the .Touched firing and the boat being anchored.

That long of a delay is unnatural.

I noticed another topic, which could be an alternative method to detect when player passes some area:

Though constantly checking Region3 area / zones, have the same problem as with normal collision-detection; if the player is moving so fast, that the player model never actually is inside the zone, the code won’t be able to detect it.

Maybe instead of “slim check-point gates”, you create “pathway areas/zones” where server-side code checks when a player, that has last been seen moving around in “zone A”, now suddenly is moving around in “zone B”, it could be considered as an “having passed the checkpoint from A into B”-event.

Although there is more than one reason not to use this method, the most obvious one is that GetPropertyChangedSignal (and I believe .Changed too) makes an exception for changes in position and velocity if they are physics based changes. This isn’t a very well-documented exception, but I thought I would make a post to cover its existence sometime. So here we are:

Consider the following code, in a script inside a brick in workspace:

script.Parent:GetPropertyChangedSignal("BrickColor"):Connect(function()
	print("BrickColor Changed")
end)

script.Parent:GetPropertyChangedSignal("Position"):Connect(function()
	print("Position Changed")
end)

Now pay attention the output in the following gif. The small brick in the foreground is the one that has the script inside. Watch as I modify the BrickColor, and then induce a physics update by deleting the brick below it:
https://gyazo.com/76c8df8aa272d70fe7138823ec3861d4
As you can see, only the BrickColor change listener prints changes to the output.

Now consider the same listener script, but alongside another script that manually edits the brick’s position. In this case the brick will be anchored so these updates don’t confuse us by happening parallel to actual physics updates.

Another script:

local x = 10

while wait(1) do
	script.Parent.Position = script.Parent.Position + Vector3.new(0, x, 0)
	script.Parent.BrickColor = BrickColor.Random()
	x = -x
end

Output: https://gyazo.com/b018da7c94fbed294ea5eeceb03dacd7
The reason the BrickColor did not change on the second loop is because the random color selector happened to select the same color, so the change listener did not fire.
As you can see, both of the listeners function as desired here, printing both of the changes to the output.

It should also be noted that listening for changes in CFrame works exactly the same way.

3 Likes

If this is correct, then this excludes the possibility of the .Touched event just taking a long time to fire, because of performance issues or otherwise. I’m wondering now why might there be a delay on the server’s .Touched event? Because as far as I understand (purely through testing), .Touched behaves like this:

  • The listener behaves normally when the listener part and the hit part both have network ownership on the server.
  • When one of these parts is network-owned by a client, but the .Touched listener remains in a server-side script, the listener then functionally acts as a RemoteEvent, firing when that client detects a touch. This is why sword reaching works in games like Fencing.

If that was the case, then why would there be a massive delay beyond the regular one-way ping time? Maybe there is some more undocumented behavior here.

1 Like

Here’s what’s going on: You’re seeing the results of the fact that physics is simulated on the client.

  1. Physics is being simulated on the client.
  2. You touch the part on the client in that simulation
  3. The client sends a touched event to the server. While this is happening, you keep moving
  4. The server gets the event and decides to change where you are
  5. The server sends the changes back to your client, while this is happening, you still keep moving
  6. Finally, the changes get to the client, and you see the updated position, after having moved two entire network round-trips worth of movement in the meantime.

If you listen for the touch on both the client and the server and apply the move on both, you can solve this problem. That way you’ll immediately move, but also still have security because the server will still eventually verify your actions.

Another factor to apply is that the server heartbeat may be very throttled. That is, the server may be running at like, 5 FPS, not the 60 FPS that your client is. That adds yet more latency because the server may have to wait a bit to process that Touched event even after it arives.

5 Likes

The delay is exactly as significant when the build doesn’t get anchored (when I tested with prints), so I think it’s mainly related to the server FPS, is there a way I can view this? or should I make my own server sided fps counter

So looking at 4slug’s boat design, there are many(!) parts, which passes through that Touched trigger. - So does this mean that each-and-every-part (their internal identification) is then sent from client to server?

If that is true, are there any options/methods in Roblox’s framework, to instruct the (network-owner
client-side) “Touched-handler” to ignore certain parts/objects, so they are not sent to the server, as they will be ignored/discarded anyway by the server-side user coded Touched-handler?

1 Like

are there any options/methods in Roblox’s framework, to instruct the (network-owner

It’s transmitting every single touch for client simulated parts which you listened for touches on. You don’t need to worry about this though. Those Touch transmits barely amount to anything network traffic wise compared to other stuff that’s getting replicated all the time.

If you really care in spite of the fact that you shouldn’t, you could always use collision groups to prevent there from being physics touches in the first place.

1 Like

You could try making the .Touched event run locally on the client and use :FireServer() to activate the changes, it would probably help with the delay.

that’s what I ended up doing, works nearly instantly

1 Like

.Touched Events are just about always slow.

I recommend using Region3 or RayCasting to check rather than depending on .Touched.

A useful guide on how you might use RayCasting can be found in the following article:

I hope this helped.

It may work to use .Touched locally and then :FireServer() once it happens, this works if it does not matter whether someone exploits or not, but if it does matter, then I’d consider using RayCasting.

neither region3 or raycasting would be better than touched in this situation as none of those have any method to connect, its not about detecting where the person is, its about figuring out when they reach a certain place

What I’m saying is, you could possibly manipulate it to trigger functions when the boat reaches a certain point.

Otherwise, if it is not critical, then firing an event or function to the server would do the trick.

What trigger functions are you thinking? Because as far as I know neither of those have triggers