Movement Formulas: Difference between revisions

From Minecraft Parkour Wiki
Content added Content deleted
(Marked this version for translation)
 
(38 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<languages/>
__NOTOC__
<translate>
[[File:0t sprintjump graph.png|thumb|600x600px|Movement formulas applied to a 3b jump.]]
<!--T:1-->
The Player's movement can be accurately calculated with [https://en.wikipedia.org/wiki/Sequence sequences].
[[File:0t sprintjump graph.png|thumb|500x500px|Movement formulas applied to a 3b jump.]]
The player's movement can be accurately calculated with [https://en.wikipedia.org/wiki/Sequence sequences].


<!--T:2-->
The following formulas come from analyzing the game's [[SourceCode|source code]].
The following formulas come from analyzing the game's source code.






Because this field is so extensive, we're only considering standard movement, and ignoring mechanics specific to certain blocks.


<!--T:3-->
Note that these formulas are '''not exact''', due to how [https://en.wikipedia.org/wiki/Floating-point_arithmetic floats] are computed. <br>
When used for calculations, only the first 4-6 decimals should be considered accurate. <br>
For a completely accurate simulation, you would need to replicate the source code.


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


<!--T:4-->
* [[Soulsand]]
* [[Special:MyLanguage/Vertical Movement Formulas|'''Vertical Movement''' (recursive formulas)]]
* [[Ladders and Vines|Ladders and Vines]]
* [[Special:MyLanguage/Horizontal Movement Formulas|'''Horizontal Movement''' (recursive formulas)]]
* [[Slime Block|Slime Blocks]]
* [[Special:MyLanguage/Nonrecursive Movement Formulas|'''Non-recursive formulas''']]
* [[Cobweb|Cobwebs]]




<br />


<!--T:5-->
== Vertical Movement ==
'''Note:''' <br>

Minecraft's coordinate system is oriented differently: 0° points towards "positive Z", and 90° points towards "negative X". <br>
==='''Jump Formula:'''===
We choose to work in the standard coordinate system to make calculations more intuitive.

</translate>
* <math>V\displaystyle _{Y}(0) = 0.42</math>
* <math>V\displaystyle _{Y}(t) = \left (V_{Y}(t-1) - \underset{gravity}{0.08} \right ) \times \underset{drag}{0.98}</math>


:If <math display="inline"> \left | V\displaystyle _{Y}(t) \right | < 0.005 </math>, <math display="inline">V\displaystyle _{Y}(t)</math> is set to 0 instead.

:In 1.9+, it's compared to 0.003 instead.


==='''Notes:'''===

*<math display="inline"> V\displaystyle _{Y}(0)</math> corresponds to the initial jump motion.
*<math display="inline"> V\displaystyle _{Y}(0)</math> is increased by 0.1 per level of [[Status Effects|Jump Boost]]
*Terminal velocity is -3.92 b/t
*When the Player collides vertically with a block, <math display="inline">V\displaystyle _{Y}(t)</math> is set to 0.


==='''Vertical Position:'''===

: To get the position on a given tick, you simply need to sum <math display="inline">V\displaystyle _{Y}</math>

: <math display="inline">Y(n) = \sum_{t=0}^{n} V_{Y}(t)</math>


==='''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]].

:{| class="wikitable"
!Description
!Airtime
|-
|Flat Jump
|12 t
|-
|3bc Jump
|11 t
|-
|<nowiki>+0.5 Jump</nowiki>
|10 t
|-
| +1 Jump
|9 t
|-
|2.5bc Jump
|6 t
|-
|2bc Jump
|3 t
|-
|1.8125bc Jump
|2 t
|}


==='''Source code (from [[SourceCode:EntityLivingBase|EntityLivingBase]])'''===
: <syntaxhighlight lang="java">
/* 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;
}
</syntaxhighlight>



== 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:
# Acceleration is added to the Player's speed.
# The Player is moved (new position = position + velocity).
# 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 ===
<br>
: '''Movement Multiplier''' (See [[45 Strafe|45° Strafe]])


:: <math>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}</math>


: '''Effects Multiplier''' (See [[Status Effects]])


:: <math>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</math>


: '''Slipperiness Multiplier''' (See [[Slipperiness]])


:: <math>S(t) = \begin{Bmatrix}0.6 & \textrm{Default}\\ 0.8 & \textrm{Slime}\\ 0.98& \textrm{Ice} \\ 1.0 & \textrm{Airborne} \end{Bmatrix}</math>

=== 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''':

:: <math>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}}} </math>


: '''Jump Speed''':

:: <math>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} }}</math>


: '''Air Speed''':

:: <math>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)}}} </math>


=== Complete Formulas ===

: Let's introduce two more variables:
:* <math display="inline"> D(t) </math> , The player's Direction in degrees (defined by their inputs and rotation)
:* <math display="inline"> F(t) </math> , 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 <math display="inline"> D(t) </math> and <math display="inline"> F(t) </math> are not affected by yaw-to-angle conversion.


: '''Ground Speed''':

:: <math>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)) </math>
:: <math>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)) </math>

: '''Jump Speed''':

:: <math>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)) </math>
:: <math>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))}} </math>


: '''Air Speed''':

:: <math>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)) </math>
:: <math>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)) </math>

=== 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 <math display="inline">V\displaystyle _{X}(t)</math> is set to 0 and the Player is placed against the wall.
:: If the player hits a Z-facing wall, then <math display="inline">V\displaystyle _{Z}(t)</math> is set to 0 and the Player is placed against the wall.


: '''Negligible Speed''':

:: If <math display="inline"> \left | V\displaystyle _{X}(t) \right | < 0.005 </math> after applying inertia, <math display="inline"> V\displaystyle_{X}(t)</math> is set to 0.
:: If <math display="inline"> \left | V\displaystyle _{Z}(t) \right | < 0.005 </math> after applying inertia, <math display="inline"> V\displaystyle_{Z}(t)</math> is set to 0.

:: In 1.9+, they are compared to 0.003 instead.

Latest revision as of 04:30, 22 August 2021

Other languages:
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.



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



Note:
Minecraft's coordinate system is oriented differently: 0° points towards "positive Z", and 90° points towards "negative X".
We choose to work in the standard coordinate system to make calculations more intuitive.