mojira.dev
MC-247417

Sculk sensor can detect "GameEvent.STEP" before "GameEvent.HIT_GROUND" causing an inconsistent redstone signal output of either 1 or 5 depending on the circumstance

The Bug

Sculk sensor can detect "GameEvent.STEP" before "GameEvent.HIT_GROUND" causing an inconsistent redstone signal output of either 1 or 5 depending on the circumstances.

Relates to MC-247642

Steps to Reproduce

  1. Place a sculk sensor at ground level that outputs it's signal into a command block with the command below (note: "x y z" must be set as the sculk sensor's coordinates):

    tellraw @a {"nbt":"last_vibration_frequency","block":"x y z"}
  2. Build a platform 11 (or more) blocks above the sculk sensor to avoid detection of anything other than the player falling.

  3. Pay attention to the outputs of the sensor in the following two scenarios. Walking off of the platform while not moving in any direction until you hit the ground, and, in the second scenario, walking off the platform, and continuing to move forward until you hit the ground.

An additional command block was placed behind this one to give the player instant health after falling. This last command block is not required for the setup, but recommended for prolonged testing.

Observed Behavior

The redstone signal output of the sculk sensor will be different for the two falling circumstances.

Expected Behavior

The output would remain a consistent number (5 in this case) regardless of how the player fell.

Code analysis

Code analysis by @unknown can be found in this comment.
 

Linked issues

Attachments

Comments 4

The bug is that only for players the STEP event can happen before the hit ground event. If the STEP event happens first, then the HIT_GROUND event will be ignored.

The reason this happens is because ServerPlayerEntity overrides fall() (Where HIT_GROUND event is fired) to make it do nothing. They then have a method called handleFall() which calls the Entity.fall()

Although the cause of the bug is due to the ordering of the methods. Before Entity.move() would run fall() then move() (Where STEP event is fired). Although for the ServerPlayerEntity, that is all handled within ServerPlayNetworkHandler inside of onPlayerMove() and it calls Entity.move() first, then handleFall()


Code Analysis (Yarn Mappings 1.18.1)
Entity.java

 

public void move(MovementType movementType, Vec3d movement) {
    ...
    this.fall(vec3d.y, this.onGround, blockState, blockPos);
    ...
    this.emitGameEvent(GameEvent.STEP);
    ...
} 

protected void fall(double heightDif, boolean onGround, BlockState state, BlockPos pos){
    ...
    this.emitGameEvent(GameEvent.HIT_GROUND);
    ...
}

//Order of GameEvents: HIT_GROUND, STEP

 

ServerPlayerEntity.java

protected void fall(double heightDif, boolean onGround, BlockState state, BlockPos pos) {} 

public void handleFall(double heightDif, boolean onGround) {
   if (!this.isRegionUnloaded()) {
      BlockPos pos = this.getLandingPos();
      super.fall(heightDif, onGround, this.world.getBlockState(pos), pos);
   }
}

 

ServerPlayNetworkHandler.java

public void onPlayerMove(PlayerMoveC2SPacket packet) {
    ...
    this.player.move(MovementType.PLAYER, new Vec3d(m, n, o));
    ...
    this.player.handleFall(this.player.getY() - l, packet.isOnGround());
    ...
} 

//Order of GameEvents: STEP, HIT_GROUND

 

Working Fix

Can confirm this behavior.

The detection of 1 redstone signal output compared to 5 seems to be much more reliable if the player immediately starts walking forward after breaking the block beneath them and continues to walk forward (will give 1) versus falling straight down (which provides 5).

The Bug:

Sculk sensor can detect "GameEvent.STEP" before "GameEvent.HIT_GROUND" causing an inconsistent redstone signal output of either 1 or 5 depending on the circumstance

Steps to Reproduce:

  1. Place a sculk sensor at ground level that outputs it's signal into a command block with the command below (note: "x y z" must be set as the sculk sensor's coordinates):

    tellraw @a {"nbt":"last_vibration_frequency","block":"x y z"}
  2. Build a platform 11 (or more) blocks above the sculk sensor to avoid detection of anything other than the player falling

  3. Detect the both different outputs by 1. Walking off of the platform not moving in either the 'X' or 'Z' axis until you hit the ground, and 2. Walking off the platform, and continuing to move forward until you hit ther ground.

Observed Behavior:

The redstone signal output of the sculk sensor will be different for the two falling circumstances

Expected Behavior:

The output would remain a consistent number (5 in this instance) no matter the player moving forward while falling, or falling straight down

Code analysis

Code analysis by FX - PR0CESS can be found in this comment

user-39c63

(Unassigned)

Community Consensus

Normal

Game Events

1.18.1, 1.18.2

Retrieved