mojira.dev
MC-310642

Landing on farmland deals no fall damage when the block is prevented from being trampled

Farmland's fall handler decides whether the block gets trampled into dirt. In 26.3 that decision
also, accidentally, decides whether the falling entity takes damage at all. When trampling is
suppressed, the entity lands on farmland and takes zero fall damage.

Two ways trampling is suppressed, both of them ordinary:

  • mobGriefing is false: no mob takes fall damage on farmland.

  • The player is inside spawn protection and is not an operator: that player takes no fall damage
    on farmland. A vanilla dedicated server has spawn-protection=16 by default.

Steps to Reproduce (mobs, single player, no server needed)

  1. Create a world and run /gamerule mobGriefing false.

  2. Place a farmland block.

  3. /summon minecraft:zombie ~ ~24 ~ directly above it.

  4. The zombie lands on the farmland.

Observed: the zombie is at full health. Expected (and 26.2 behaviour): about 20 hearts of fall
damage. Control: repeat with mobGriefing true, or with the zombie landing on dirt instead — the
damage is dealt normally.

Steps to Reproduce (players, default dedicated server)

  1. Start a vanilla dedicated server with default server.properties (spawn-protection=16) and at
    least one operator listed in ops.json, so spawn protection is actually enforced.

  2. Join as a non-operator player. Place farmland within 16 blocks of world spawn.

  3. Pillar up 30 blocks and jump onto the farmland.

Observed: no damage. Expected: normal fall damage. Control: jump onto dirt next to it — normal
damage.

Cause

26.2 used a single boolean chain, so super.fallOn was reached on every path
(src-26.2 world/level/block/FarmlandBlock.java:108-119):

if (level instanceof ServerLevel serverLevel
&& level.getRandom().nextFloat() < fallDistance - 0.5
&& entity instanceof LivingEntity
&& (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING))
&& entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) {
turnToDirt(entity, state, level, pos);
}

super.fallOn(level, state, pos, entity, fallDistance);

26.3 restructured this into nested ifs while turnToDirt became the instance method
turnToBaseBlock (part of the DirtPathBlock -> PathBlock / baseBlock refactor). Two bare returns
now skip the super call (world/level/block/FarmlandBlock.java:103-120):

if (entity instanceof Player player) {
if (level.getServer().isUnderSpawnProtection(serverLevel, pos, player)) {
return; // line 108
}
} else if (!serverLevel.getGameRules().get(GameRules.MOB_GRIEFING)) {
return; // line 111
}

Block#fallOn is the only path that applies landing damage: Entity#checkFallDamage is its single
non-super caller. Farmland declares no fall-distance reduction, so in 26.2 landing on farmland
always dealt normal damage whether or not the block was trampled. Entity then calls
resetFallDistance() unconditionally, so the damage is destroyed rather than deferred.

The immunity is deterministic, not random: the outer gate nextFloat() < fallDistance - 0.5 is
always satisfied once fallDistance >= 1.5, which is any fall that could hurt. The size check
sits after the returns, so small mobs get the immunity too.

Why this is a bug and not a design choice

  • Sibling asymmetry, same package: TurtleEggBlock#fallOn
    (world/level/block/TurtleEggBlock.java:58-64) implements the identical operator/mobGriefing gate
    through canDestroyEgg and still ends with an unconditional super.fallOn(...). Farmland is the
    only block whose trampling gate also gates damage.

  • The three blocks that legitimately cancel fall damage — slime, honey, powder snow — do it by
    overriding fall behaviour explicitly, not by returning early out of a trampling check.

  • Nothing in any 26.3 changelog announces farmland as a fall-damage-negating block.

Comments 0

No comments.

yuluo

etanaratsastaja

Confirmed

Platform HC

Important

Player

26.3 Snapshot 6

26.3 Snapshot 8

Retrieved