Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-119811

Boats rubberband on dismount

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • None
    • Minecraft 1.12
    • macOS 10.12.5, Java 8u131
    • Confirmed

      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.

            Unassigned Unassigned
            howtonotwin howtonotwin
            Votes:
            3 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: