position not syncing when falling
Expected behavior
client position and server position should be the same while flying
Observed/Actual behavior
player position is not sync with the server position while flying and syncs when touching the ground
Steps/models to reproduce
- connect with 2 players,
- one of them stands somewhere, the 2nd player flies far away at high speed and then back to the player.
- then compare the position between the two players. (the position should be different)
Note: (the player should still fly, because when he touches the ground, the player position is synchronized).
Plugin and Datapack List
plotsquared, fastasyncworldedit
Paper version
This server is running Paper version git-Paper-54 (MC: 1.20.1) (Implementing API version 1.20.1-R0.1-SNAPSHOT) (Git: 8582999) You are running the latest version Previous version: git-Purpur-2004 (MC: 1.20.1)
Other
https://www.youtube.com/watch?v=RjGqo-xQTLA
Ok, I did verify that this is the case. I tested on 2 vanilla clients with no plugins. I did what was shown in the video, flew straight away, and back. The character was off by a few blocks, and after a few seconds it "jumped" back into the correct spot on the observer client.
EDIT 1: This also affects spigot
The bug occurs after the player is spawned for the viewer if the player is flying somewhere at that moment. In general, when a player is spawned for the viewer, he also receives a relative move packet in EntityTrackerEntry#sendChanges(), which shifts the player for the viewer. If the player's onGround state changes, then a non-relative move packet is sent that synchronizes the position for the viewers, this code can be seen in EntityTrackerEntry#sendChanges().
I tried to send "old" position fields in the ClientboundAddPlayerPacket, but the bug still happens, but much less often.
I think the solution here is not to use relative move packets, which is very dumb, or to try to skip EntityTrackerEntry#sendChanges() for new viewers on the current tick (idk if this will help or not), or to add to EntityTrackerEntry#sendChanges() the sending of non-relative move packets from time to time to synchronize positions at least periodically.