If you connect the Touched event of a Humanoid instance on both the client and the server, the client will experience an incredibly large de-synchronization on any physics related touches on server-controlled objects. Just the existence of a connection on the server is enough for the de-synchronization to exist. The function it is connected to may simply be an empty function and the problem will still appear. Physics ownership does seem to play a role as well, as I am only noticing this when the physics object is controlled by the server.
Below are two videos of a player character jumping over a spinning beam. When the player touches the beam on the client side, an anchored copy is made of both the body part that touched the beam and the beam itself. The location of both copied parts are unchanged. In theory these two copied parts should be colliding with each other, otherwise the Touched event should not have triggered. In practice however the distance between the two instances may be up to 5(!) studs sometimes. The configuration in both videos are almost identical. The only difference is that in the first video the following code is enabled to run on the server:
game.Players.PlayerAdded:Connect( function(Plr) Plr.CharacterAdded:Connect( function(Character) local Humanoid = Character:WaitForChild("Humanoid", 5) if Humanoid ~= nil then Humanoid.Touched:Connect( function(Part: BasePart, Limb: BasePart) end ) end end ) end )
Note that the function linked to the Touched event is completely empty in this case.
Here is a video of the player jumping over the beam when the Humanoid’s Touched event is connected on both the server and the client.
Here is a video of the player jumping over the beam when the code sample above is disabled.
Notice how in the first video two parts are created that are not even close to touching. The character is also shown to be jumping over the spinning beam without touching it at all.
Attached below is the place file which I used to demonstrate this issue. When you run the file, a default character model is created so you do not have to worry about your personal avatar’s collision box messing with anything. A LocalScript instructs the player to jump over the spinning beam whenever the beam reaches certain angles. This means you do not have to touch anything to reproduce this problem. Due to physics not being deterministic however, the body part that touches the beam may not always be the same one. Four scripts are included in the place file:
- ‘StartSpinning’: a Script inside the spinner to set the physics ownership of the spinner to the server. It also waits a few seconds before instructing the beam to start spinning to give you time to load into the game.
- ‘ServerTouch’: a Script inside the ServerScriptService. The contents of this script are the same as the code sample above. All it does is connect the Touched event to the player’s Humanoid.
- ‘AutoJump’: a LocalScript inside the StarterCharacterScripts folder which instructs the player to jump when the spinning beam gets close.
- ‘VisualizeHit’: a LocalScript inside the StarterCharacterScripts folder which listens to
Humanoid.Touchedand visualizes the two parts that “touched” each other.
If you disable the ‘ServerTouch’ script the player will be jumping over the spinning beam without triggering the
Humanoid.Touched event, despite jumping at the same moment as before. If you re-enable the script the player will once again demonstrate the de-synchronization by seemingly “hitting” the beam.
The place file:
physics_touch_bug.rbxl (55.8 KB)
This bug is currently preventing me from adding an important feature to my game, so I am hoping that this problem can be fixed swiftly.
When I register a Touched event on the client I expect the event to only trigger on the client when the two parts have touched each other on the client.