When hitting a shulker bullet while sprinting, the client instantly applies some knockback velocity causing it to start moving. On a normally functioning server this movement is usually barely noticable, as the shulker gets destroyed shortly after. This doesn’t occur if the players' attack_damage attribute is set to 0. In this case we can observe the following:
If we hit a moving shulker bullet while sprinting, then its movement is slightly jittery for a short amount of time.
If we hit a still shulker bullet (obtained by spawning one with no gravity) while sprinting, the shulker bullet starts moving at a constant velocity and only gets reset back to its true position every 2 seconds.
How to reproduce:
Set your attack_damage attribute to 0 by entering the command: /attribute @s minecraft:attack_damage base set 0
Summon a shulker bullet with no gravity with: /summon minecraft:shulker_bullet ~ ~ ~ {NoGravity:1b}
Then hit the shulker bullet while sprinting.
Notes:
The shulker bullet is the only entity that is being moved directly by the client with hurtClient() returning true. The fact that hurtClient() returns true causes Player::attack to call Player::causeExtraKnockback. The main responsibility of this method on the client is to slow the player down when hitting certain entities (like other players), but it also applies some velocity to the entity on the client. This velocity usually doesn’t matter, as most entities aren’t moved on the client except by interpolation as dictated by the server, and entities which can be controlled by the client by riding cannot be hit while doing so. This is the relevant code snippet from Player::causeExtraKnockback:
if (knockbackAmount > 0.0F) {
if (entity instanceof LivingEntity livingTarget) {
livingTarget.knockback(
knockbackAmount,
Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)),
-Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)),
damageSource,
damage,
comesFromEffect
);
} else {
entity.push(
-Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)) * knockbackAmount,
0.1,
Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)) * knockbackAmount
);
}
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6, 1.0, 0.6));
this.setSprinting(false);
}This could be fixed by either making shulker bullets not return true in hurtClient(), or by making the entire top part of the above code snippet before this.setDeltaMovement(…) exclusive to the server. The first fix would have the additional consequence that hitting shulker bullets wouldn’t slow players down anymore, similar to all mobs.
Thank you for helping us improve Minecraft! We saved your files: