mojira.dev
MC-119811

Boats rubberband on dismount

The bug

Under specific conditions, exiting a boat will cause the boat to move back to the point where the player first entered it, and then the boat will move back into the correct position. The boat does not actually move on the server; it only moves on the client.

Steps to reproduce

  1. Place a boat on land.

  2. Without entering the boat, move the boat by pushing it around.

  3. While moving it, enter the boat. This must be done within 10 ticks/.5 seconds of moving the boat, and even then it can take about half a dozen tries.

  4. While inside the boat, row it a few blocks in any direction. (The bug is easiest to observe when the boat is moved away from the original position.)

  5. Dismount

What should happen

The boat stays in place on dismount.

What happens

The boat snaps back to the original position, and then moves back to the dismount point in about a second.

Note: The redstone contraption in the video is there to show that the issue is client-side only, because the boat does not activate the tripwire on either jump.

Code analysis

(Based on Minecraft 1.12, decompiled with MCP 9.37)

When the player moves the boat without entering it, it causes the server to send SPacketEntity to the client with the updated position, which is handled in NetHandlerPlayClient::handleEntityMovement. This calls EntityBoat::setPositionAndRotationDirect, which sets up linear interpolation of the movement by setting lerpSteps to 10 and storing the target position. Normally, EntityBoat::tickLerp is called every tick by EntityBoat::onUpdate to handle this, and the lerp will be complete in 10 ticks.

However, if the player enters the boat while lerpSteps != 0, EntityBoat::tickLerp stops decrementing lerpSteps, essentially "freezing" the remaining duration and target of the lerp. As the player moves the boat, even though SPacketEntity is still being sent to the client, NetHandlerPlayClient::handleEntityMovement does not call EntityBoat::setPositionAndRotationDirect because the boat's passenger (the player) can steer. This preserves the state of the lerp as long as the player is in the boat.

When the player exits the boat, the lerp is "unfrozen", and the boat completes the lerp'd movement by flying back to the starting position. When the server sends the next SPacketEntity, the boat starts a new lerp'd movement and flies back to where it should be.

Linked issues

Attachments

Comments

[Mod]Les3awe

This issue duplicates MC-103672.
May be able to merge.

migrated

(Unassigned)

Confirmed

boat

Minecraft 1.12

Retrieved