Movement Formulas

From Minecraft Parkour Wiki
Revision as of 11:25, 20 May 2020 by MCPK (talk | contribs) (precision warning complete)
Movement formulas applied to a 3b jump.

The Player's movement can be accurately calculated with sequences.

The following formulas come from analyzing the game's source code.


Please note that these formulas are not exact, due to how floats are computed. When used in a spreadsheet, only the first 4-6 decimals should be considered accurate. For a completely accurate simulation, you would need to replicate the source code.



In this article, we're only considering standard movement, and ignoring mechanics specific to certain blocks.


You will find further documentation of movement physics in these articles:



Vertical Movement

Jump Formula:


If , is set to 0 instead.
In 1.9+, it's compared to 0.003 instead.


Notes:

  • corresponds to the initial jump motion.
  • is increased by 0.1 per level of Jump Boost
  • Terminal velocity is -3.92 b/t
  • When the Player collides vertically with a block, is set to 0.


Vertical Position:

To get the position on a given tick, you simply need to sum


Airtime:

The airtime of a jump is the number of ticks between jumping and landing.
It also corresponds to the period (in ticks) of that jump's cycle when performed repeatedly.
Airtime is linked to the notion of Tiers.
Description Airtime
Flat Jump 12 t
3bc Jump 11 t
+0.5 Jump 10 t
+1 Jump 9 t
2.5bc Jump 6 t
2bc Jump 3 t
1.8125bc Jump 2 t


Source code (from EntityLivingBase)

/* Code unrelated to vertical movement is cut out */

protected float getJumpUpwardsMotion(){
    return 0.42F;
}


protected void jump()
{
    this.motionY = this.getJumpUpwardsMotion();
    if (this.isPotionActive(Potion.jump))
    {
        this.motionY += (this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F;
    }
    this.isAirBorne = true;
}


public void moveEntityWithHeading(float strafe, float forward)
    ... /* also moves the player horizontally */

    this.motionY -= 0.08;
    this.motionY *= 0.98;
}


Horizontal Movement

Horizontal Movement is a bit more complex than Vertical Movement, as it relies on many more factors: Player Actions, Direction, and Ground Slipperiness.

On every tick, the game does these steps:

  1. Acceleration is added to the Player's speed.
  2. The Player is moved (new position = position + velocity).
  3. The Player's velocity is reduced to simulate air resistance.

We'll start by introducing Multipliers in an effort to make formulas more readable.


Multipliers


Movement Multiplier (See 45° Strafe)


Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle M(t) = \begin{Bmatrix}1.3 & \textrm{Sprinting} \\ 1.0 & \textrm{Walking}\\ 0.3 & \textrm{Sneaking}\\ 0.0 & \textrm{Stopping} \end{Bmatrix} \times \begin{Bmatrix}0.98 & \textrm{Default}\\ 1.0 & \textrm{45° Strafe} \\ 0.98 \sqrt{2} & \textrm{45° Sneak} \end{Bmatrix}}


Effects Multiplier (See Status Effects)


Failed to parse (syntax error): {\displaystyle E(t) = (\underset{Decreases \; by \; 15\% \; per \; level \; of \; Slowness}{\underset{Increases \; by \; 20\% \; per \; level \; of \; Speed}{\underbrace{\left ( 1 + 0.2\times Speed \right ) \: \times\: \left ( 1 - 0.15\times Slowness \right )}}} \geq 0}


Slipperiness Multiplier (See Slipperiness)


Linear Formulas

These simplified formulas only apply to linear movement (no change in direction).
While this condition might seem very restrictive, these formulas are very useful to analyze conventional jumps and momentum.
We'll later expand on these formulas by including angles.


Ground Speed:
Failed to parse (syntax error): {\displaystyle V(t) = \underset{Inertia}{\underbrace{\underset{ }{V(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3}}} }


Jump Speed:
Failed to parse (syntax error): {\displaystyle V(t) = \underset{Inertia}{\underbrace{\underset{ }{V(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3}}} + \underset{Sprintjump \; Boost}{\underbrace{\begin{Bmatrix}0.2 & \textrm{Sprinting}\\ 0.0 & \textrm{Else}\end{Bmatrix} }}}


Air Speed:
Failed to parse (syntax error): {\displaystyle V(t) = \underset{Inertia}{\underbrace{\underset{ }{V(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{\underset{ }{0.02 \times M(t)}}} }


Complete Formulas

Let's introduce two more variables:
  • , The player's Direction in degrees (defined by their inputs and rotation)
  • , The player's Facing in degrees (defined by their rotation)


In reality, angles aren't as simple as that, as there are a limited number of significant angles (see Facing and Angles).

For the purpose of simplicity, we'll assume and are not affected by yaw-to-angle conversion.


Ground Speed:
Failed to parse (syntax error): {\displaystyle V\displaystyle _{X}(t) = \underset{ }{V\displaystyle _{X}(t-1) \times S(t-1) \times 0.91 } \: + \: 0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3} \times \sin (D(t)) }
Failed to parse (syntax error): {\displaystyle V\displaystyle _{Z}(t) = \underset{Inertia}{\underbrace{\underset{ }{V\displaystyle _{Z}(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3}}} \times \cos (D(t)) }
Jump Speed:
Failed to parse (syntax error): {\displaystyle V\displaystyle _{X}(t) = \underset{ }{V\displaystyle _{X}(t-1) \times S(t-1) \times 0.91 } \: + \: 0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3} \times \sin (D(t)) + \begin{Bmatrix} 0.2 & \textrm{Sprinting}\\ 0.0 & \textrm{Else}\end{Bmatrix} \times \sin (F(t)) }
Failed to parse (syntax error): {\displaystyle V\displaystyle _{Z}(t) = \underset{Inertia}{\underbrace{\underset{ }{V\displaystyle _{Z}(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{0.1 \times M(t) \times E(t) \times \left (\frac{0.6}{S(t)} \right )^{3}}} \times \cos (D(t)) + \underset{Sprintjump \; Boost }{\underbrace{\begin{Bmatrix} 0.2 & \textrm{Sprinting}\\ 0.0 & \textrm{Else}\end{Bmatrix} \times \cos (F(t))}} }


Air Speed:
Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle V\displaystyle _{X}(t) = \underset{ }{V\displaystyle _{X}(t-1) \times S(t-1) \times 0.91 } \: + \: 0.02 \times M(t) \times \sin (D(t)) }
Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle V\displaystyle _{Z}(t) = \underset{Inertia}{\underbrace{\underset{ }{V\displaystyle _{Z}(t-1) \times S(t-1) \times 0.91 }}} \: + \: \underset{Acceleration}{\underbrace{\underset{}{0.02 \times M(t)}}} \times \cos (D(t)) }

Stopping Conditions

Horizontal speed is set to 0 if the Player hits a wall, or if the speed is considered to be negligible.


Wall Collision:
If the player hits a X-facing wall, then is set to 0 and the Player is placed against the wall.
If the player hits a Z-facing wall, then is set to 0 and the Player is placed against the wall.


Negligible Speed:
If after applying inertia, is set to 0.
If after applying inertia, is set to 0.
In 1.9+, they are compared to 0.003 instead.