Tutorial - anon-noob/mothball GitHub Wiki
So you wanna learn how to use mothball? You've come to the right place! It doesn't take long to start stratfinding linear jumps proficiently (curved jumps are much harder but you'll eventually get there).
Getting Started
To get started, find a discord server which has mothball access. The Minecraft Parkour Central discord server is one that provides access to mothball and is also a server for Minecraft parkour in general.
Running Mothball
As mentioned in the main page, type ;s
or any of the valid commands at the start of your message so the bot knows to begin a mothball simulation. Whatever is typed afterward will be calculated accordingly.
After running a simulation with a message, you can edit that message to re-run mothball calculations so there is no need to spam messages for every calculation. It's also proper etiquette to not clog them with pointless simulations. It only confuses you even further than necessary.
You can continue on a simulation by replying to your message and starting the simulation with ;then
. This will continue the simulation where you left off. If you edited a message which has follow-up simulations, it will also re-run those simulations.
Comments
Anything between two #
or after an unpaired #
will be treated as a comment and Mothball will ignore it. Typing ;s # hello # sprint # world
is equivalent to ;s sprint
Basic Movement
Mothball calculates movement in the following order:
- Add current velocity to position (Move the player)
- Calculate acceleration
- Add acceleration to velocity
Note that this is different from in game ticks, where position is calculated at the end of each tick. However, calculating position first makes it easier to conceptualize simulations.
Before we start simulating in mothball, we recommend taking a look at Mothball Movement Functions which will help with syntax, arguments, and what functions are available to you.
Example Simulation - Walking
To start off, let's simulate walking with mothball. In game, this is simply pressing the w
key (or whatever key you have binded to walking forward). Looking at the Mothball Movement Functions, we see that walk
is the function that can simulate... well... walking in game!
The result should look like this.
FYI for all you nerdy programmers out there,
walk
is the same aswalk()
, which is a simple walk simulation with no arguments passed.
But now you want to simulate walking for more than just one game tick. Looking at the documentation Mothball Movement Functions, we can tell Mothball how long to walk for using the syntax walk(duration)
where duration
is a nonnegative integer. So if we wanted to walk for 5 ticks, then we would type walk(5)
.
The result should look like this.
Now if typing walk
is too hard for you, why not just type w
? Some functions in Mothball have aliases, which means you can do the same stuff using different names. For example, w
is an alias of walk
, and so w(5)
should give us the same results as before.
Looking at the documentation Mothball Movement Functions, we can see that the walk
function has one alias w
. I mean it does literally say
# Other Aliases: w
But why use aliases? Some functions have quite long names and aliases are meant to be faster ways to type, but the choice is yours. Would you rather type sprintstrafejump
or just stfj
?
Example Simulation - Sprint Jumping
Now let's try simulating a jump. Looking at the documentation again, we find the following about the sprintjump
function.
# Other Aliases: sj sprintjump( duration: int = 1, rotation: float = None, *, slip: float = None speed: int = None, slow: int = None )
After jump, the player is airborn. Equivalent to
sj(1)
sa(duration - 1)
.
Here, sa
is an alias of sprintair
, which is when you hold sprint and press w
while airborn.
A normal jump lasts 12 ticks, so let's simulate that in Mothball.
We can also check that sj(12)
is equivalent to sj(1) sa(11)
. In other words, you spend 1 tick jumping, and the remaining ticks midair.
Do remember that unlike the walk
(or w
) function, sj(4)
is NOT equivalent to sj sj sj sj
. That is absurd and is only possible using an in-game glitch. You'll get different results.
With Rotation Argument
Now how would you simulate a normal sprint jump while facing 3 degrees? We see that sprintjump
or sj
has rotation
as an argument, so we can use sj(12,3)
to simulate this. The 3
in this case tells Mothball the angle while the 12
tells the duration.
With Keyword Arguments
But what if I want to simulate a normal sprint jump with speed 2? We see that sprintjump
or sj
has speed
as an argument. Since speed
comes after the asterisk *
, it is strictly a keyword argument, which means you must type speed = 2
instead of just 2
. The simulation would be sj(12, speed=2)
.
Appending Inputs
By default, every movement function assumes you are going forward with the w
key. To change that, we can append inputs after the function name. Inputs can be any combination of the four default in-game movement keys wasd
. The syntax for appending inputs is function.inputs
The function s
sprints one tick going forward, but s.wa
will sprint with w
and a
, going forward and left. Likewise, s.wd(3)
will sprint 3 ticks with w
and d
, going forward and right.
And of course, doing just s
is equivalent to s.w
.
Mothball does not prevent you from doing absurd movement that are impossible in game, such as sj.s(12)
, sprint jumping backward using the s
key. Doing this can be helpful for calculating certain scenarios but it would be better to just use sj(12,180)
, sprint jumping forward facing 180 degrees.
-
Negating Inputs with You can use -
to reverse the inputs of a function. For example, -sn
is equivalent to sn.s
and -wa.wd
is equivalent to wa.sa
. It is recommended that you only use -
if it is equivalent to function.s
for readability reasons.
45 Strafes
A 45 strafe is when you face 45 degrees and counterstrafe in order to move slightly faster, hence gaining additional distance. For example, if you face 45 degrees to the right while moving forward and left, you are 45 strafing. The angle that you're travelling at is still effectively 0, but you gain extra speed!
All the Mothball Movement Functions listed has a corresponding 45 strafe equivalent. Just add 45 after the function name. For example, wa
(alias of walkair
) becomes wa45
(alias of walkair45
).
On the left, with 45; on the right, without.
Sprint Jump 45s Are Weird
The documentation provides a warning.
Be careful!
Unless otherwise stated,function45
is equivalent tofunction.wa(1,45)
. For example,walk45
is equivalent towalk.wa(1,45)
Appending 45 to a function will tell Mothball to maximize as much distance as possible, which may or may not mean facing 45 degrees. For the majority of movement functions, function45
is equivalent to function.wa(1,45)
. Only sprint jumps have this problem.
Sprint jump 45s
sj45(duration)
is equivalent to sj sa45(duration - 1)
. In game this means facing 0 while jumping, and 45 strafing while midair. sj45
is NOT equivalent to sj.wa(1,45)
as this is actually weaker, and you don't even go perfectly straight! In fact, sprint jumping without strafe is stronger than sprint jumping with strafe. Bonus fact, sj45(1) = sj(1)
but sj45(t) != sj(t)
for any $t > 1$.
Sprint strafe jump 45s
sprintstrafejump
or stfj
will jump with strafe and maximize distance by finding the best angle to jump at. The rest of the airborn ticks will either face 0 or 45 depending on whether you use stfj
or stfj45
.
Similar to sj
and sj45
, stfj(duration)
is equivalent to stfj sa45(duration - 1)
. It is also true that stfj45(1) = stfj(1)
and stfj(t) != stfj(t)
for any $t > 1$.
Sneak sprint jump 45s
snsj45(duration)
is equivalent to snsj45 sa45(duration - 1)
However, you might notice that it is not equivalent to snsj sa45(duration - 1)
and that's because snsj45 != snsj
. It turns out that sneak sprint jumping with strafe is stronger than without strafe, hence snsj45
will find the best angle to jump at, with the remaining airborn ticks facing 45.
In this case, facing about $9.11$ degrees is optimal. Keep in mind that this optimal angle is only true for this specific circumstance. Even if the player has speed 1, the optimal angle will be different!
Recommended Practices
While Mothball doesn't prevent you from doing absurd things such as
stop45.wd
(how do you 45 withwd
and not move!?), you should probably follow these practices to avoid confusion and unintended behaviors. If you do try any of these sacrilegious pracitces, consequences will never be the same.Please, DO NOT:
- Append inputs to a
45
ed function, such asw45.wd
, or to thestfj
function- Negate any function that already has inputs explicitly appended, such as
-sj.wd
- Append inputs or
45
-ify any of thestop
function
Using Setter Functions
They way every simulation works is by moving a Player
object. This player object has attributes that affect how it is moved. Below are a list of the relevant attributes.
Player Attributes |
Purpose |
---|---|
z | the player's z position |
x | the player's x position |
vz | the player's z velocity |
vx | the player's x velocity |
rotation | the player's default rotation (or "the angle the player faces") |
slip | the player's default ground slipperiness |
inertia | the player's inertia threshold |
speed | the player's speed potion amplifier |
slow | the player's slow potion amplifier |
air sprint delay | whether the player's sprint activation is delayed while midair |
precision | the precision, or decimal places, the output displays |
Whenever a function is omitted, it will use the default value that was set. For example, all movement functions have the duration
argument default to 1
. However, the rotation
argument does not need to be explicitly stated, which tells mothball to use the player's default rotation.
Mothball has Setter Functions which literally "set" default attributes for the rest of the simulation, unless otherwise overridden.
Dealing with Angles
Recall that almost all movement functions has a rotation
arguemnt. If we wanted to simulate walking with w
for 5 ticks facing -69 degrees, we simply do w(5, -69)
However, doing this does not set our default rotation to -69. In other words, the rest of the simulation will be calculated while facing 0. In mothball syntax, ;s w(5,-69) wa(3,-69)
is NOT equivalent of ;s w(5,-69) wa(3)
because the wa(3)
will not be facing -69.
Face
and Anglequeue
We can change the default rotation using the setter function face
(its alias is f
). Doing ;s f(1.5) sj sa(1,3) sa.wd
is equivalent to ;s sj(1,1.5) sa(1,3) sa.wd(1,1.5)
. Note that the sa(1,3)
overrides the default facing just for that function.
Of course, we can change the default rotation any time we wish.
But now let's say you have multiple angles that you want to turn to each tick. Sure, you can do
sj(1,1) sa(1,2) sa(1,3) sa(1,4) ... sa(1, 12) # you get the point
but that is quite a lot of leg work. Instead, ew use anglequeue
, or its alias aq
. The aq
function takes as many comma-separated numbers and queues up those numbers which will be used as the default facing for subsequent ticks. This means we could rewrite the above simulation as
aq(1,2,3,4,5,6,7,8,9,10,11,12) sj(12)
and as a bonus, it changes the default rotation, so
aq(1,2,3,4,5,6,7,8,9,10,11,12) sj(12) sn(2)
the sn(2)
function is executed while facing 12.
Turn
and Turnqueue
The other way to change the default rotation is by using the turn
function. Whereas face(angle)
sets the default rotation to angle
, turn(angle)
will add to the default rotation and set it as default. And of course, turnqueue
is the anglequeue
version of turn
. Hence,
aq(1,2,3,5,8,13,21) sj(10)
# is equivalent to #
tq(1,1,1,2,3,5,8) sj(10)
Recommendation: For the sake of your sanity, please try to NOT combine
anglequeue
andturnqueue
together. What will happen is that bothanglequeue
andturnqueue
will be applied withanglequeue
taking priority overturnqueue
.
Set Position and Velocity
Probably one of the most common things you'll do in your simulations is setting your position whenever and whereever.
To set your x or z position, use the functions setposx
and setposz
(aliases x
and z
respectively). For example, sj(12) z(0) sj(13)
You can also use the vertical line |
which resets the player's position, that is, |
is equivalent to x(0) z(0)
Likewise, you can set your velocity to any value, anywhere, and anytime you want using vx
and vz
. For example, s(2) vz(0.2) sj(12)
Set Output Precision
Use precision
or pre
to set the number of decimal places that will be displayed, defaults to 6.
Other Setter Functions
Well you don't need much explanation, its essentially the same idea. The setter functions set the default attribute for the rest of the simulation unless otherwise stated. For example,
;s slip(0.98) sj(12) sj(12) slip(0.6) sj(12)
# is equivalent to #
;s slip(0.98) sj(12) sj(12) sj(12, slip=0.6)
Using Output Functions
What's the point in running simulations when you don't utilize output functions? These functions display important information, and you can use as many as you need at any point in the simulation.
blocks
, displacement
, and momentum
Preamble - Converting between Before we introduce the output functions, it is helpful to learn the different ways we measure distance in Minecraft.
The simplest unit is displacement
, which is simply how far the player is from the starting point. When you open the f3 menu and look at your coords, you can calculate your displacement by simple subtraction. For example, if your z coordinate read $3.253$ at the start and your final z coordinate was $5.187$, then your displacement was $1.934$ units.
To describe "block to block" jumps, we typically use the blocks
unit. To convert from displacement $d$ to blocks $b$, we use the formula
$$b = \begin{cases}d + 0.6 &d \geq 0 \ d - 0.6 &d < 0\end{cases}$$
Realistically, this only works when $|d| \geq 0.6$
Okay but what does this $4$ blocks = $3.4$ units of displacement represent in Minecraft?
To describe momentum, we typically use the uniut "blocks of momentum" or "mm" for short. To convert from displacement $d$ to momentum $m$, we use the formula
$$m = \begin{cases}d - 0.6 &d \geq 0 \ d + 0.6 &d < 0\end{cases}$$
Realistically, this only works when $|d| \geq 0.6$
Okay but what does this $1$ block of mm = $1.6$ units of displacement represent in Minecraft?