Walking into a Bumper with a Pot

One of my favorite weird glitches is that when you walk into a bumper with a pot (an action alluded to in the title), the pot flies off somewhere else. This is a very funny teleport. We can make it even funnier by calling it a "telepot". Telepotting.

Are you high?

This behavior might have you eager to draw some connection to what happens when you carry a bomb with superspeed. But, in this situation, the error occurs not because of Link's animation, but because of Link's height—his Z coordinate. And it's not his height being used to index a table; it's just taken literally.

Link's Z-coordinate is interesting, because it's a 16-bit value, but it's almost never used as such. Most routines, including Link's draw code, only use the lower 8 bits of this value. A height of $0108 is the same as a height of $0008, because only that $08 matters. For most things. As you may have surmised by now, throwing pots is a thing where that is not the case.

But why does that matter?

To answer that, we need to know one more quirk of how Link's Z-coordinate is used: $00 and values from $F0 to $FF are treated the same when drawing Link. In fact, Link's default height is $FFFF.

High pot enuse

Pots use Link's X-, Y-, and Z-coordinates to determine their physical position. Link's animation step does come into play here, but the code is meticulous enough to validate what it reads. Even though sprites have a Z-coordinate of their own, carried sprites use Link's Z-coordinate to help calculate their Y-coordinate. And, as mentioned, they use the full 16-bit value.

In most cases, this happens to work out, because the code that handles Link's Z tries to keep the full 16-bit value sensical. Normally, getting hit gives Link some Z-velocity as he recoils, and that velocity effects a value that's pretty low. Things go awry when Link recoils with no velocity in his Z. The low byte of his coordinate will stay at $FF, but the high byte will be zeroed out by the recoil handler every frame, because it just assumes it will always be working with a small positive value.

As far as the pot is concerned, Link's Z-coordinate is $00FF, and it needs to adjust for that. Which it does, by subtracting that value from its Y-coordinate. But the 8-bit interpretation of the value is out of sync with the 16-bit interpretation. Instead of seeing a Z-coordinate of -1, the pot sees 255.

Why don't bombs work?

Bombs don't work simply because of order of operations. Link's Z-coordinate is, in fact, used by lifted ancillae as a 16-bit value in much the same way that sprites use it, but by the next time the bomb has run its code after a bumper recoils Link, it is no longer attached to him. The value simply doesn't matter.

It doesn't matter for all sprites either. Only sprites in a slot higher than the culprit bumper will be telepotted upwards. But pots always spawn in the highest available slot. And, in the vanilla game, bumpers are always in low slots. In fact, they're always the first sprites, except in:

The way blob intended

It takes some set up, but we can walk into a bumper while carrying a sprite in a lower slot.

Before proceeding, we will require:

Perform as follows:

  1. Go to the big chest room in Skull Woods however you'd like.
  2. Kill the red bari and red hardhat beetle. They're annoying.
  3. Get to the big chest platform however you'd like.
  4. Powder one of the minimoldorms to turn it into a blob.
  5. Freeze the blob.
  6. Throw the blob across the pit.
  7. Get 1 tile (8 pixels) below the door and throw the blob left into the rail. This will put it in a position to perform the next step.
  8. Use the blob to juke the door.
  9. Walk into the bumper carrying the blob.

Hooray! It took a lot of effort and some major glitches, but we managed to experience intended behavior in the vanilla game!

Summary

A mismatch between how most entities use Link's Z-coordinate and how carried objects use it leads to a disagreement when Link is recoiled with no velocity on the Z-axis. This disagreement results in normal behavior for most, but an apparent height of 255 for carried objects. For ancillae, this error just happens to be avoided. Carried sprites in a slot higher than the bouncing bumper will be teleported, because they are still attached to Link (and incorrectly) as they are knocked out of his hands.

Pots think you are high, but you're not.