RAM-addresses
| Addr | What |
|---|
| 057C/057B/0575 | Bart's x-position (level) |
| 057E/057D/0533 | Bart's y-position (level) |
| 0055/0054 | Bart's x/y on screen |
| 0057/0056 | x/y screen |
| 0574/0573 | Bart's x-speed |
| 052D/0527 | Bart's y-speed (not used for the skateboard stage) |
| 051C | Invincibility timer |
| 04E6 | Bartman timer |
| 06BF | Remaining ammo |
| 04E7 | Collectibles (Krusty heads and unique Krusty treasures) |
| 0028 | RNG |
| 001E/001D | Global timer |
| 0097/00EC | Boss damage/health (some bosses use one address, some the other) |
| 061D/0068+X | x object X |
| 063B/006E+X | y object X |
| 0074/007A+X | x/y sub-speed object X |
Movement
Acceleration
Let's assume Bart moves to the right, so a right input (R) is an acceleration and a left input (L) is braking:
| Input | Ground | Air |
|---|
| R+A(+B) | 0x10 | 0x10 |
| R+B | 0x10, max speed 0x130 | 0x10 |
| R | 0x10, max speed 0x130 | 0x10, max speed 0x130 |
| L+A and/or B | -0x26 | -0x30 |
| L | -0x26 | -0x20, max 0x100 |
| Neutral | -0x90 | 0 |
Movement speed
Bart stops accelerating when his speed is 0x260 or higher (special cases described in the acceleration table). The fastest movement speed is 0x26E and it can be achieved in the following way:
| Frame | State | Input | Acceleration | Speed | Comment |
|---|
| 1 | Ground/Air | R+A+B | 0 | 0x260 |
| 2 | Ground | R+A+B | 0 | 0x260 | No acceleration possible on landing frames |
| 3 | Ground | L+A(+B) | -0x26 | 0x260 |
| 4 | Ground | R+A(+B) | 0x10 | 0x23A |
| 5 | Ground | R+A(+B) | 0x10 | 0x24A |
| 6 | Ground | R+A(+B) | 0x10 | 0x25A |
| 7 | Ground | L+A(+B) | -0x26 | 0x26A |
| 8 | Ground | R+A(+B) | 0x10 | 0x244 |
| 9 | Ground | R+A(+B) | 0x10 | 0x254 |
| 10 | Ground | L(+B) | -0x26 | 0x264 |
| 11 | Air | R+A(+B) | 0 | 0x23E | No acceleration on the first jump frame |
| 12 | Air | R(+A)+B | 0x10 | 0x23E |
| 13 | Air | R(+A)+B | 0x10 | 0x24E |
| 14 | Air | R(+A)+B | 0x10 | 0x25E |
| 15 | Air | (A) | 0 | 0x26E |
| 16 | Air | (A) | 0 | 0x26E |
If forward input is given when the speed is above 0x260, the speed will revert back to 0x260. However, as long as no directional input is given and Bart is in the air/bunny-hopping, he will keep his current speed. Other than potentially resulting in more lag when going at the maximum speed of 0x26E, there is one distinct disadvantage with this setup. Bart will jump backwards, meaning he won't be able to shoot or activate items in the direction of movement. The following movement variation also results in Bart moving at 0x26E, but facing forward instead. However, it's slower to set up this movement, so it's only worth it for longer stretches that would otherwise require {brake to face forward}-{accelerate back to 0x26E}-{brake to face forward}-{accelerate back to 0x26E}- etc:
| Frame | State | Input | Acceleration | Speed |
|---|
| 10 | Ground | L+A(+B) | -0x26 | 0x264 |
| 11 | Ground | (R+)A(+B) | 0x10 | 0x23E |
| 12 | Ground | R(+A)+B | 0x10 | 0x24E |
| 13 | Ground | R(+A)+B | 0x10 | 0x25E |
| 14 | Ground | | -0x90 | 0x26E |
| 15 | Ground | (R+)A(+B) | 0 | 0x1DE |
| 16 | Air | R(+A)+B | 0x10 | 0x1DE |
| 17 | Air | R(+A)+B | 0x10 | 0x1EE |
| 18 | Air | R(+A)+B | 0x10 | 0x1FE |
| 20 | Air | R(+A)+B | 0x10 | 0x20E |
| 21 | Air | R(+A)+B | 0x10 | 0x21E |
| 22 | Air | R(+A)+B | 0x10 | 0x22E |
| 23 | Air | R(+A)+B | 0x10 | 0x23E |
| 24 | Air | R(+A)+B | 0x10 | 0x24E |
| 25 | Air | R(+A)+B | 0x10 | 0x25E |
| 26 | Air | (A) | 0 | 0x26E |
| 27 | Air | (A) | 0 | 0x26E |
Sub-pixel anomaly
In most games, a pixel is added to the right when the sub-pixels roll over. E.g. if the position is 0x05F0 and a sub-pixel movement speed of 0x10 to the right, one would expect the next position to be 0x0600, while a sub-pixel movement speed of 0x10 to the left would result in a position of 0x05E0. However, the calculation in this game is different. By using the same starting position as previously and a movement speed to the left of 0x10, the next position will be 0x0400! If the movement speed is 0x10 to right, the new position will be 0x0600 though.
Fall cancellation trick
Pressing the opposite direction of movement prevents the fall animation from initiating. While this produces a kind of hovering effect, it also creates a significant brake effect and therefore only lasts at most a few frames before all speed is gone and Bart will start falling. In general, this trick isn't a time save, but can be useful in some edge cases, as well as creating an entertainment effect of Bart hovering mid-air.
Randomness
The principal contributor to "random" behavior in the game is the RNG function. It's calculated without external input and is updated every non-lag frame. The algorithm for calculating the RNG is slightly imperfect and cycles after 217 calculations (and not the "expected" 256):
A:00 $D46C: A5 28 LDA $28 = #$F7
A:F7 $D46E: 0A ASL
A:EE $D46F: 0A ASL
A:DC $D470: 0A ASL
A:B8 $D471: 45 28 EOR $28 = #$F7
A:4F $D473: 0A ASL
A:9E ROL $28 = #$F7
A:9E LDA $28 = #$EE
A:EE $D478: 60 RTS (from $D46C)
Other than the updates every frame, additional calls can be made under certain circumstances. This is a (probably incomplete) list of additional calls of the RNG function:
- Triggering an additional ammo bag to drop at a boss
- In world 4 (Hollywood), another call to the RNG function is made when any (or more) button on the D-pad is pressed. It hasn't been investigated why this additional call isn't present in all worlds.
The way to manipulate the RNG is therefore by forced delays (world 1-3) or D-pad presses (world 4). Forcing additional ammo bag drops is generally not practical without time loss.
There is also an unknown contributor to randomness in the game that hasn't yet been described. Some objects that should not depend on RNG don't always appear/behave the same way from the same inputs (and even when the RNG is the same).
Note: A second update of the RNG function during the same frame was observed (by 'ktwo') in the frozen river level. Since Bizhawk was used, it was not attempted to find an explanation in the code for the addtional RNG call.
First boss (China)
The following aspects are be determined by RNG
- Time until folding the fan
- x-position of the ammo bag drop(s)
- Timing of fireballs thrown towards Bart (should not matter for a TAS)
The only possible way to manipulate the boss and ammo bag seems to be by forced delays to the start of the fight.
$613 determines how long before the boss starts folding the fan. This is directly calculated from the RNG-function and results in a delay of up to 64 frames. Note however that there is an edge case, where instead of a 1 frame delay, the counter loops before triggering the folding the sequence and the delay instead becomes 256 frames. The folding/unfolding then follows a set pattern of always the same duration.
Second boss (North pole)
At least the first icicle pattern/timing appears to be set when the fight starts and in general only possible to manipulate by forced delays to the start of the fight. The icicles are, however, subject to some random behavior outside the RNG function that hasn't yet been described, so a major re-routing in the earlier levels might result in a slightly (?) different pattern.
The boss' first appearance seems to always be in the right-most hole. The hole it appears in ($ED) during sub-sequent cycles depends on RNG (but also depends on number of hits - not investigated in more detail). 50% chance in the middle hole and 25% chance in the left and right holes, respectively.
The boss retreats when the global timer loops or when it's hit (but two hits are possible in after cycle 1). It comes back up when the timer in $E8 has finished counting down (always the same delay).
The fastest fight is when the boss almost immediately retreats in the first cycle and there is just enough time to deal one damage before it's disappeared. Another fast, but slightly slower, fight happens when the third icicle is thrown early enough so Bart can jump beneath it and deal a quick damage, which will also make the boss disappear quickly.
Third boss (Egypt)
The y-trajectory follows a set sinusoidal pattern with the amplitude increasing the more times Bart has pulled the rope.
The x-direction is re-calculated when the counter in $758 has counted down. For the first movement, the counter is set to 0xC0 when the fight starts. After that, the counter directly takes the RNG-value in $28, but with a minimum of 0x40. If the boss hits the edge of the screen, it starts moving in the opposite direction, but without impacting the movement counter.
The trick to pulling the carpet rope as early as possible seems to be to make sure Bart spends a frame on the ground before jumping again. It seems to always be possible to get a "perfect" fight in a TAS.
Fourth boss (Hollywood)
Like the first and third bosses, the initial movement pattern is always the same, but then becomes random. The boss movements and timing of megaphone throws seem to be set at the start of the fight without dependence on Bart's actions. A perfect fight goes by so quickly that only RNG variable seems to be the ammo bag drops and the megaphones thrown by the best. They can be manipulated by using the D-pad to change the RNG in soundstage 2. The megaphone throws can to some extent also be manipulated by changing Bart's position before the throw.
Ice flows on the frozen river
The calculation of the ice flow movements isn't trivial. The ice flow's sub-position is calculated 0-2 times per frame. The number of calculations is stored in $052E. Differences in ice flow movements (with the same inputs) occur for reasons unrelated to RNG. This "randomness" is currently unexplained.
Stalactites in the ice cavern
The initial pattern of the stalactites seems to only be possible to manipulate by delaying. During the stage, it's possible to some extent to manipulate the stalactites by introducing short delays around when they spawn. The game mechanics behind are currently undescribed.
Sea gulls
By releasing up on the D-pad on the same frame a sea gull spawns in the pirate ship level (soundstage 1), it will spawn below instead of above Bart.
The sea gulls in the frozen river level are also "random" and can prevent Bart from jumping between ice flows as early as possible if they spawn in a bad position. Ways to manipulate them haven't been studied in depth, but once Bart has fireball crackers, defeating one sea gull will change the pattern later on.
Enemy despawning
Some enemies can be despawned. At least tornados in the pyramid stage and bats in the graveyard stage have been despawned. It's done by quickly braking before they're loaded in memory. The details are undescribed, but it does at least not seem to work on all enemies.