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:
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.
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.
Here’s what’s going on: You’re seeing the results of the fact that physics is simulated on the client.
Physics is being simulated on the client.
You touch the part on the client in that simulation
The client sends a touched event to the server. While this is happening, you keep moving
The server gets the event and decides to change where you are
The server sends the changes back to your client, while this is happening, you still keep moving
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.
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?
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.
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.
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