When a part collides with a CanCollide = false object, there’s a chance the collision, and subsequent touched event, will be fired 1 frame later than when the parts visually intersect.
This issue also occurs with objects that are CanCollide = true.
TouchedBugReportRepro.rbxl (51.3 KB)
The repro I’ve attached demonstrates this issue: There is a ball which falls down repeatedly into a red CanCollide = false part. When the ball’s touched event is fired, the ball is anchored. On every heartbeat, I check to see if the ball is colliding with the red part by using GetTouchingParts. If the ball is colliding with the red part, I set a variable to true. If that variable is true when the touched event is fired, it means the touched event was fired one frame late. Every time the ball touches the red part, I print to the output whether or not the touched event was fired late.
Expected behavior
I expect collisions to resolve properly when the parts are visually intersecting, and for touched events to be fired with no frame delays.
Hi, thanks for reporting and providing the repro file!
The current touch event supports network replication, and we only guarantee eventual consistency. This means there may be delays, early triggers, or triggers without actual contact on your local client. We’ll keep this in mind when we revisit touch events in the future.
Thank you!
I appreciate the response, thank you for linking me to the detailed explanation of how events are replicated!
When I was testing with this repro, both parts are owned by the server. The repro was tested in run mode, not in play mode, so there is no client to replicate to. I apologize for not making this condition clear in my explanation of the repro, as this was my reason for reporting it as a bug.
In this case, where both parts are owned by the server, it seems like there is no point where latency can be introduced, so I don’t think the issue can be explained away by network latency-- unless my understanding here is incomplete.
Thanks for the details! Yes, we’re fully aware that the situation you described is not caused by network delay, and we’ve identified the root cause. The fix for it is non-trivial.
My previous response was more from a public API perspective—our current touch event guarantees eventual consistency. That said, we’ll keep this in mind when we have the opportunity to improve the touch event and address this need.
Also, could you share more details on your use case for the touch event and why avoiding the frame delay is crucial? Thanks!
I don’t know what the use case for OP is, but one im thinking of is detecting collision applied to something that constantly moves. For example, a custom physics interaction may produce incorrect and potentially even entirely bugged results by having the actual touch event register one frame late. It is even possible that such physics interactions may entirely fail in some cases if the touch event delay is long enough for both parts to already no longer be colliding at all.
Can you elaborate on the “custom physcis interaction”? It would be nice to provide as much details as possible so we fully understand what you are trying to achieve.
One example could be two, or multiple, cars colliding. Usually at very high speeds this one frame delay could result in having the cars involved be already in entirely different locations by a lot of times even 10+ studs. One more extreme consequence of this could even be just full on glitching if the game needs to do something more specific with the cars from that collision.
Another much more simpler example could be just adding sounds to physics interactions. This is not that big of a thing but hey, it could generate sounds at the wrong locations and perhaps no sounds at all depending on how a developer would implement this. Though in the best case possible, it would just be the sounds playing from the wrong location.
Another example would be performing union operations triggered by a touched event. Since the delay of one frame, it’s possible for the union operations to be applied somewhere else than intended. This is not as likely to be an issue but its something.
A personal example would be similar to the car’s examples. Personally i need a knockback system which can push and glue players to walls. Of course, touched events work best since they do technically register (or should) the exact moment any player hit anything. Having this one frame delay creates multiple issues. First issue being the fact that any sort of visual impact and effect will be delayed by 1 frame resulting in more subtle jank. It’s true that effects delayed by one frame in such scenario may not be that big of a deal but its also very easy for players to realize that theres something going wrong and just assume its just either the lack of polish or straight up game jank.
Second issue would have to be the player still flying into the wall for one frame even though they were supposed to be stopped. The knockback forces applied to players can range from pretty low/standard levels to forces high enough to fling them hundreds to thousands of studs in seconds. Of course, when flying at high forces that 1 frame delay could potentially glitch up the player a bit and cause them either to shift their position or get flung (that roblox fling glitch).
I’ve managed to resolve the issue by using the GetTouchingParts method on the character collider every frame as a backup to touched events— so it’s non essential that the bug is fixed immediately for my use case.
The use case is obstacle collision in a racing game— I will get specific:
When you hit an obstacle, we briefly freeze the character on impact to help sell the force of the collision. However, the obstacles themselves are non-collidable. When the player is naively frozen in place on touch, they are inside the obstacle, which is counter to the goal of selling the impact. When a touch is detected, a sphere cast is preformed from the players previous position (& some) to the players current position to find the surface of the obstacle— the player is moved to the surface. The player is moving fast enough that with an extra frame ‘passing through’ the obstacle, rubber banding can be felt when the player is moved back to the surface of the obstacle. The camera is also close to the player, so the obstacle will take up much of the screen as the player passes through it before being rubber banded back the next frame, which makes this rubber banding more apparent.
On impact, we use a free physics ragdoll to capture animation poses to apply to the character. The way we do this is that we CFrame the ragdoll to the characters’ animation and position as close as possible on PreSimulation and give the ragdoll the same velocity we know the character will have. Once the character hits an obstacle— we stop ‘overriding’ the ragdoll’s CFrame every frame and let it simulate during the hitstop phase to stabilize before ‘capturing’ its poses every frame to apply to the character. If we detect an impact one frame late and override the ragdoll’s position to be inside the obstacle which it collides with, the simulation would be a lot less stable and wouldn’t look as accurate.