The bug
When a boat is falling while over a slime block, once it gets to about 5 blocks on top of the slime block, the boat will start rising and falling very slowly. As of 22w12a, this also occurs with boats with chests. As of 1.21.2 Pre-Release 2, the effect is not as large and does not occur with every bounce, but still happens.
How to reproduce
Video demonstrating the issue: https://gfycat.com/PrestigiousDistantGardensnake
Code analysis
Code analysis by @unknown can be found in this comment.
Linked issues
is duplicated by 8
Attachments
Comments 21
Video documenting the bug: https://www.youtube.com/watch?v=KJsT9R3tckE
A possible cause could be an interference with how the game extrapolates positions of a moving object and with collision detection. A similar behavior is seen in MC-110648 (possibly the same cause, different issue though). This issue is also in 18w08b.
Code Analysis (Yarn - 1.18.1)
The issue here is that the client does not run the same calculations as the server.
BoatEntity.java
public void tick() {
//...
if (this.isLogicalSideForUpdatingMovement()) {
if (!(this.getFirstPassenger() instanceof PlayerEntity)) {
this.setPaddleMovings(false, false);
}
this.updateVelocity();
if (this.world.isClient) {
this.updatePaddles();
this.world.sendPacket(new BoatPaddleStateC2SPacket());
}
this.move(MovementType.SELF, this.getVelocity());
} else {
this.setVelocity(Vec3d.ZERO);
}
//...
}
isLogicalSideForUpdatingMovement()
returns true
if the client is running the code and the client player is controlling the boat, or if the server is running the code.
Basically, when you are not controlling the boat, the client will run this.setVelocity(Vec3d.ZERO);
instead of running the actual physics.
Resulting in de-sync of the client & server.
Proposed Fix:
public void tick() {
//...
if (!(this.getFirstPassenger() instanceof PlayerEntity)) {
this.setPaddleMovings(false, false);
}
this.updateVelocity();
if (this.world.isClient && this.isLogicalSideForUpdatingMovement()) {
this.updatePaddles();
this.world.sendPacket(new BoatPaddleStateC2SPacket());
}
this.move(MovementType.SELF, this.getVelocity());
//...
}
This has been tested and works perfectly. It will simply allow the client to run the physics while still limiting the updating & packets for when it's being controlled.
Confirmed for 1.12
Actually the boat movements seems to get softened, and that makes it visually bounce on the air when it hits the slime block server-side and it goes up again before it hits the ground client-side.
MC-111271 describes it better, and the gif in this issue is still relevant for 1.12.
EDIT: on a side note, slime blocks pushed by pistons sometimes fail to launch a boat in the air and only push it a few blocks. Is that a different issue?