Sneaking

    From Minecraft Parkour Wiki
    Other languages:

    Sneaking is a mechanic that slows the player's movement and allows them to avoid falling off a block


    Activation

    Sneaking is activated immediately upon pressing the Sneak key, and remains active while pressed.

    Sneaking is incompatible with Sprinting. (except in 1.14+).


    Effects

    When the player is on ground, sneaking prevents them from falling more than 1 block.

    • Speed is conserved when sneaking against the edge of a block, which is useful for specific jumps such as no-mm 3+1.
    • In 1.11+, the lower limit is changed to 0.6b
    • A "shift glitch" happens when the player lands on the edge of a block while sneaking, in which case they may fall off (fixed in 1.16.2).
    • In some cases, the player may fall off unexpectedly while sneaking on ground (examples) - partly fixed in 1.16.2.

    When sneaking, the player can hang on the side of ladders and vines.

    • They can still climb up as usual, but they can't fall down as long they stay within the block.
    • In general, sneaking makes ladder jumps much easier.

    In 1.9+, sneaking lower the player's height down to 1.65m. In 1.14+, sneaking lowers it even more, down to 1.5m.


    Speed

    Sneaking is 70% slower than walking, granting a base acceleration of 0.03, but it doesn't get applied the same way as walking and sprinting:

    • When sneaking forward, the ground acceleration is 0.03×0.98 = 0.0294, as expected.
    • When sneaking diagonally, the ground acceleration is 0.0294×2 ≈ 0.0416


    Code

    It is worth showcasing how sneaking is implemented, and why it's flawed.
    /* In Entity.java, stripped of irrelevant code */
    public void moveEntity(double dX, double dY, double dZ)
    {
        double dX_intended = dX;
        double dY_intended = dY;
        double dZ_intended = dZ;
        boolean sneakingOnGround = this.onGround && this.isSneaking();
        
        if (sneakingOnGround)
        {
            double increment = 0.05;
    
            //check for furthest ground under player in the X axis (from initial position)
            while(dX != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,0)).isEmpty())
            {
                if (dX < increment && dX >= -increment)
                    dX = 0.0D;
                else if (dX > 0.0D)
                    dX -= increment;
                else
                    dX += increment;
    
                dX_intended = dX;
            }
                    
            //check for furthest ground under player in the Z axis (from initial position)
            while(dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(0,-1,dZ)).isEmpty())
            {
                if (dZ < increment && dZ >= -increment)
                    dZ = 0.0D;
                else if (dZ > 0.0D)
                    dZ -= increment;
                else
                    dZ += increment;
    
                dZ_intended = dZ;
            }
                    
                    
            //calculate definitive dX and dZ based on the previous limits.
            while(dX != 0.0D && dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,dZ)).isEmpty())
            {
                if (dX < increment && dX >= -increment)
                    dX = 0.0D;
                else if (dX > 0.0D)
                    dX -= increment;
                else
                    dX += increment;
                dX_intended = dX;
    
                        
                if (dZ < increment && dZ >= -increment)
                    dZ = 0.0D;
                else if (dZ > 0.0D)
                    dZ -= increment;
                else
                    dZ += increment;
                dZ_intended = dZ;
            }
        }
    
        ... //move the player with the new values of dX and dZ (order of collisions: Y-X-Z)
    }
    
    Illustration of the code presented above. The red blocks are necessary for the player to sneak on top of the green block.