Monday, March 24, 2014

Predicting Mario's X Position

This information is a very basic version of predicting speeds.
For this section, I will be assuming that mario's speed is going to be constant.  Something more advanced (predicting what it would be like with a direction held) would require a more complex formula.

Since mario's speed is in subpixels per frame, all we must do to predict his x position in a given future frame is to convert his position and subpixel to a position in subpixels and a "true" subpixel, add the speed mutiplied by a given amount of frames, and then convert that back to pixels and hex subpixels.

For example, say the player is at an x position of 572.d0 with an x velocity of 23, and we want to find his new position after 13 frames.

572 * 16 + 0xd0 / 16 = 9165
9165 + 23 * 13 = 9464
9464 subpixels --> 591.80 in game positions.

So our predicted position will be 591.80

Corner Clipping

Corner Clipping is a precise trick in which Mario's speed allows him to skip over the first three pixels of a block, and then, with an extra boost, he is able to clip into the entire thing, and pass through the block completely.
This is generally the aimed jump when wanting to do a corner clip, where mario presumably jumps into the corner of the block.  Mario can corner clip on either side of the block, except when he is small, in which he can only clip from the right side.

This bit will have assumed that you have read the logic of the below tutorials, in which subpixels are the magic behind most of these tricks.
A walljump is where mario must have the speed that allows him to go more two pixels into the block (32 subpixels) within one frame, which means he must have 33 speed.  Well, a corner clip actually requires him to enter the block by more than 3 pixels, which is 48 subpixels, meaning he must have a speed of 49.  Coincidentally, 49 is the maximum amount of speed that you can achieve with a run as any form of mario.


The only difficult part is getting your subpixel and position to line up to where you can reach the exact position of the block, allowing you to fully enter the block by 3 pixels on the following frame.
This is why it is recommended to create or use a lua script, as a lua script such as mine or masterjun's will automatically check every frame for the subpixel line ups to a block you are predicting to, and does not require you to manually check every time (which would otherwise make this trick take a very long time).

The reason why it is needed for you to enter the block by its corner is because just entering the side isn't enough.  At the point in which you touch the side of the block, block pressure immediately comes in, and in this situation mario could completely stop before the block.  By entering the block's corner, you can avoid block pressure for the frames needed before dropping into the block by 3 pixels.  The action in turn will push you to the left, since the inner part of the block is automatically set to push the player left if he is in it, and from the right this means that saving frames.  You can also save frames and be pushed right from the left side if you are on yoshi.
When done correctly, you should achieve the x position scrolling to allow you to get 3 pixels into the block...
The red region indicates that the subpixels will line up correctly for a corner clip on that list of blocks to occur.
Normally, on the frame after this, I would be stopped immediately because of block pressure.  However, since I have entered the block through its corner, I will not be stopped.  And, by the time I do get 3 pixels in the block, the game stops collision detection for the right side of the block, and instead registers me in the middle, where I will immediately be pushed out.
The frame that I actually enter the block, although the graphics are one frame behind so it is not completely obvious that I have yet.
The second frame I have entered the block.  At this point I have hit the block below the block I am clipping, so I should start losing x speed on the next frame...
And one last screen shot just because it looks cool :D

Good luck clipping!  And again, if you have any questions about anything above, PM me preferably on SMWC.

Sunday, March 23, 2014

Walljumping

Walljumping occurs when the player enters a block by just over 2 pixels.  I am going to explain it fully in this description.
First I'm going to begin about talking about how the player moves.  Have you ever wandered what speeds actually meant?  Basically, the game's smallest unit of measurement in speeds is not in pixels, but subpixels.  There are 16 subpixels in one pixel, meaning that there are 256 in each tile of the game.  The player doesn't move relative to pixels, but in fact subpixels.  When you have a speed of 19, this means that you are moving 19 subpixels per frame.

To make this more comprehensible, you can convert everything into subpixels when it comes to the player.  The player's subpixel is not exactly accurate, as it takes up an entire byte.  To make it take up only 16 values (0-15) we must divide it by 16.  To convert from pixels to subpixels, all that we must do is multiply by 16.  This new position is the "combined position" and allows you to check things in units of subpixels rather than random check values.
Hypothetically, let's say that Mario is at position 255.c0 (according to the game)
255 * 16 + c0 (192) / 16 = 4092

Since mario's speed is measuring in subpixels per frame, all that we must do to find his position on the next frame of the game is to add the speed in which we are at presently.  Now, let's just think for a second, and realize that eventually, the game is going to have the player move so many subpixels per frame that he is going to have the capability to skip over a slight section of the block you are hitting.  If you were to get into a position in which you could move over 2 pixels into the block, you could clip the bottom of the block that you are hitting.  What is intended is for you to hit the block, and then immediately be shoved out.

Remember that we are working with subpixels, so 2 pixels is going to be represented as 32 subpixels.
Since we want to go into the block by more than 2 pixels, we will need to be moving 33 subpixels per frame at least, or, in other words, have an x speed of 33 or more.

Keep in mind that you must be in the position in which you can move passed the position of the block by more than 2 pixels, meaning that just getting 33 speed will not do anything.  You must get to the point in which the subpixels will align just perfectly for you to be able to get passed the block by 33 subpixels within one frame, and be able to hit the block before being shoved out.
In this case, I have found a frame where I can in fact pull this off:
This is the point in time where I will be moving and my positions will fall just right so that I can go into the position of the block by 2 pixels.
Mathematical proof:
Position of block: 2285.00
Position of player: 2293.d0 moving with -35 velocity
Block Position in subpixels: 36560
Player Position in subpixels: 36701

Player prediction of position (moving -35 subpixels every frame):
36701, 36666, 36630, 36595, 36560, 36525 <-- Position before I am shoved out of the block
However, if you notice, I come across the exact position of the block on a frame, but I still haven't gone into the block yet, which is when it actually pushes you out.  So, 36525 < 36560 - 32 which means that this is a successful walljump, as my lua script shows.
This means that my position before the block shoves me out should be:
floor(36525 / 16).(36525 % 16 * 16)
which is 2282.d0 (2282.208 without hex conversion)
However, sadly, block pressure is going to slightly push you out as soon as you touch the side of the block, landing your actual position at 2283.e0 (increase of 1.10 pixels).  But, this is still a correct walljump value.

So, that is how a walljump works on a subpixel level, and also how you can predict it.

Predicting Jump Speed and Position At A Certain Point In Time

Predicting jumps can be a bit tricky, as the initial jump speed is dependent upon the x speed of the player on the frame that the jump takes place.


If you match up a table of a jump and a spin jump, you will achieve the following:
Normal Jump
[0, -77]
[8, -79]
[16, -82]
[24, -84]
This pattern of x speeds to jumps is actually constant, even though the oscillation scrolls between 2 and 3 because everything is represented as integers.  This change is 2.5 every 8 speed changes.  Knowing this, we can come up with the formula:
ceil(-2.5 * floor(abs(x speed) / 8) - 77)
Which is a variant on arithmetic sequences conforming to the situation, and makes it so that you will always have an integer result.

A similar table can be achieved with spin jumps
Spin jumps have a much more simple pattern though, and this one is an actual arithmetic sequence.
[0, -71]
[8, -73]
[16, -75]
[24, -77]
From here, all you must do is account for negative speeds (like I did in the first example) and account for the fact that the increase between each speed is 8.
2 * -floor(abs(xspeed) / 8) - 71

Now, you have the ability to predict what the player's y speed will be based solely upon x speed.

From here is the more challenging, theoretical standpoint - predicting the position in which the player will be at for a given point in time.  We need a method for passing time - and we'll call this time t.  At 0, t represents the present point in time.  However, we're more interested in what will happen at a future point in time.
First, we'll need a single unit of position to track where the player is going to be at in the future.  For this example (and for most examples) I will be using subpixels.  The subpixel that the player is at is not a "true" subpixel per say, so we'll have to convert that to a "real" subpixel (not in hex).  Also, the player's main position is in pixels, so we'll have to convert that to subpixels as well.
For this specific example, let's say that the player has an x speed of 29, and is at x position 297.f0
Using our previous math formulas, we can calculate the y speed of the player when he jumps.  Let's say that he is doing a regular jump.  You will end up with -84.

Now comes the more confusing part.
From here, we'll need to convert our position into subpixels
297 * 16 + f0 (240) / 16 = 4752 + 15 = 4767
Predicting the position is simple without the delta included because of gravity.  It is simply done by adding the y speed of the player, since the y speed is in its definition subpixels moved per frame.  Every frame from here, we will be adding a new result.  So, a summation is actually needed to do things.
The summation we will be doing will be in reference to the passed frames f from the present frame to the predicted frame.  Let's say that we want to see mario's y position at 15 frames into the future.  Well, we will need a summation from 0 to 15.
To predict the delta, some more observations will have to be done, but you will soon find that holding down B/A increases the y speed by 3, and not increases it by 6.

Mathematical representation:
Predicted position = 4767 + summation {from 0 to 15 represented by f} (-84 + 3 * f)
Remember that 4767 is the position of the player in subpixels, -84 is his initial y speed predicted and 3 is the delta increase every frame.

With this, we will end up with
4767 - 984 = 3783
3783 will be our new position in subpixels.
Happy predicting!

General

Inner SMW is a blog that I started to help people understand an actual mathematical representation of a lot of tricks found in the game, or how things work in general that not everyone would understand without something like this.

My goal for this is to help you learn something new about the game or how to do something you never knew how to do before.  A lot of what I will be doing will be demonstrated in Lua Scripts, and if you don't know the Lua language and how it applies to reading RAM, I would advise you that it will help you a lot (basically, it obsoletes RAM watch, and does much more as a scripting language)