Sandbox: Difference between revisions

From Minecraft Parkour Wiki
Content added Content deleted
No edit summary
mNo edit summary
 
(9 intermediate revisions by one other user not shown)
Line 1:
<languages />
[[File:0t sprintjump graph.png|thumb|600x600px|Movement formulas applied to a 3b jump.]]
<translate><!--T:2--> paragraph 1</translate>
The player's movement can be accurately calculated with [https://en.wikipedia.org/wiki/Sequence sequences].
 
The following formulas come from analyzing the game's [[SourceCode|source code]].
 
 
<translate><!--T:3--> paragraph 2</translate>
 
Note that these formulas are '''not exact''', due to how [https://en.wikipedia.org/wiki/Floating-point_arithmetic 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.
 
<translate><!--T:4--> [[File:Collision box (player and block).png|left|thumb|image 1]]</translate>
 
 
In this article, we only consider standard movement, and ignore mechanics specific to certain blocks.
 
 
 
You will find further documentation of movement physics in these articles:
 
* [[Soulsand]]
* [[Ladders and Vines|Ladders and Vines]]
* [[Slime Block|Slime Blocks]]
* [[Cobweb|Cobwebs]]
 
 
'''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. If need be, we can simply invert the X axis to match Minecraft's coordinate system.
 
<translate><!--T:5--> paragraph 3</translate>
<br />
 
== Vertical Movement ==
 
===Jump Formula===
 
*<math>V\displaystyle _{Y,1} = 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 (the player's height doesn't change for that tick)
 
:In 1.9+, it's compared to 0.003 instead.
 
 
 
'''Notes'''
 
*<math display="inline"> V\displaystyle _{Y,0}</math> isn't assigned a value because it has no importance. By convention, the 0<sup>th</sup> tick corresponds to the player's initial velocity before jumping.
*<math display="inline"> V\displaystyle _{Y,1}</math> corresponds to the initial jump motion. It is increased by 0.1 per level of [[Status Effects|Jump Boost]]
*Terminal velocity is -3.92 m/t
*When the player collides vertically with a block, vertical momentum is cancelled and only the acceleration is left.
 
 
 
===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=1}^{n} V_{Y,t}</math>
 
 
===Jump duration===
 
:The '''duration''' of a jump is the number of ticks between jumping and landing.
 
:It also corresponds to the period of that jump's cycle when performed repeatedly.
 
:This notion is linked to the notion of [[Tiers]].
 
:{| class="wikitable"
!Description
!Duration
|-
|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;
}
 
 
public void onLivingUpdate()
{
if (this.jumpTicks > 0)
--this.jumpTicks;
 
if (Math.abs(this.motionY) < 0.005D)
this.motionY = 0.0D;
 
 
if (this.isJumping)
{
... /* different if in water or lava */
 
if (this.onGround && this.jumpTicks == 0)
{
this.jump();
this.jumpTicks = 10; //activate autojump cooldown (0.5s)
}
}
else
{
this.jumpTicks = 0; //reset autojump cooldown
}
 
...
this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
}
 
</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 three steps:
# Acceleration is added to the player's velocity.
# The player is moved (new position = position + velocity).
# The player's velocity is reduced to simulate drag.
 
We'll start by introducing Multipliers in an effort to make formulas more readable.
 
 
=== Multipliers ===
 
: '''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>
:
 
<br />
=== 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.
:<br />'''Definition''':
:* <math>V_{H,0}</math> is the player's initial speed (default = 0).
:* <math display="inline">V_{H,t}</math> is the player's speed on tick <math display="inline">t</math>.
 
 
 
: '''Ground Speed''':
 
::<math>V_{H,t} = \underset{Momentum}{\underbrace{\underset{ }{V_{H,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_{H,t} = \underset{Momentum}{\underbrace{\underset{ }{V_{H,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_{H,t} = \underset{Momentum}{\underbrace{\underset{ }{V_{H,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 only)
 
 
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 ignore this fact.
 
 
 
 
: '''Definition''':
:* <math display="inline">V_{X,0}</math> and <math display="inline">V_{Z,0}</math> correspond to the player's initial velocity.
:* <math display="inline">V_{X,t}</math> and <math display="inline">V_{Z,t}</math> correspond to the player's velocity on tick <math display="inline">t</math> <br /> '''Ground Velocity''':
 
::<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{Momentum}{\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 Velocity''':
 
::<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{Momentum}{\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 Velocity''':
 
::<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{Momentum}{\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 Threshold''':
 
:: If <math display="inline"> \left | V\displaystyle _{X,t} \times S_{t} \times 0.91 \right | < 0.005 </math> , momentum is cancelled and only the acceleration is left.
:: If <math display="inline"> \left | V\displaystyle _{Z,t} \times S_{t} \times 0.91 \right | < 0.005 </math> , momentum is cancelled and only the acceleration is left.
 
:: In 1.9+, they are compared to 0.003 instead.
 
 
=== Source Code ===
[...]
 
 
<br />

Latest revision as of 04:37, 19 August 2021

Other languages:

paragraph 1


paragraph 2


image 1





paragraph 3