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

Hardcoded limit of pistons pushing entities

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Works As Intended
    • None
    • Minecraft 1.12.2, Minecraft 1.13, 1.15.2, 20w18a
    • Confirmed
    • (Unassigned)

      The bug

      There is a hardcoded limit imposed by the game to restrict entities being pushed by 0.51 blocks per direction per gametick. It's an arbitrary restriction that is unintuitive when multiple pistons attempt to push an entity in the same tick, especially when it involves mobs "stepping up" (0.5m for most mobs, 1m for player/llama/horse), and becomes glitched inside blocks (example gif.gif).

      Code analysis

      Originally by Myren Eario
      Based on 1.12.2 decompiled using MCP 9.40

      net.minecraft.entity.Entity.move(MoverType, double, double, double) uses the attribute pistonDeltasGameTime to store the offset by which an entity has been moved by pistons in a tick.

      Entity.move(MoverType, double, double, double)
      ...
      
      if (type == MoverType.PISTON)
      {
          long i = this.world.getTotalWorldTime();
      
          if (i != this.pistonDeltasGameTime)
          {
              Arrays.fill(this.pistonDeltas, 0.0D);
              this.pistonDeltasGameTime = i;
          }
      
          if (x != 0.0D)
          {
              int j = EnumFacing.Axis.X.ordinal();
              double d0 = MathHelper.clamp(x + this.pistonDeltas[j], -0.51D, 0.51D);
              x = d0 - this.pistonDeltas[j];
              this.pistonDeltas[j] = d0;
      
              if (Math.abs(x) <= 9.999999747378752E-6D)
              {
                  return;
              }
          }
          else if (y != 0.0D)
          {
              int l4 = EnumFacing.Axis.Y.ordinal();
              double d12 = MathHelper.clamp(y + this.pistonDeltas[l4], -0.51D, 0.51D);
              y = d12 - this.pistonDeltas[l4];
              this.pistonDeltas[l4] = d12;
      
              if (Math.abs(y) <= 9.999999747378752E-6D)
              {
                  return;
              }
          }
          else
          {
              if (z == 0.0D)
              {
                  return;
              }
      
              int i5 = EnumFacing.Axis.Z.ordinal();
              double d13 = MathHelper.clamp(z + this.pistonDeltas[i5], -0.51D, 0.51D);
              z = d13 - this.pistonDeltas[i5];
              this.pistonDeltas[i5] = d13;
      
              if (Math.abs(z) <= 9.999999747378752E-6D)
              {
                  return;
              }
          }
      }
      
      ...
      

            Unassigned Unassigned
            Eta740 Eta740
            Votes:
            39 Vote for this issue
            Watchers:
            16 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: