Aim
Beat the game as quickly as possible by exploiting a glitch in World 8-4 that allows controller inputs to be read as arbitrary code.
Background
LuigiSidekick first discovered a bug where they accidentally crashed the game in 8-4 during a casual playthrough of SMB2 and posted about it on Twitter in March. Simplistic6502 then discovered this post in the NESdev Discord server on March 28th and investigated the reasoning behind the crash. The crash occurs due to a logic error in the DuplicateEnemyObj subroutine, which is used by long firebars and Bowser. If all enemy slots are occupied, the object falls out of bounds into memory beyond the object slot flags ($0F to $14 in RAM), storing values at the slot corresponding to the first $00 byte found. The first occurrence results in the object flag being stored at address $15, which is an unused memory location.
However, if this happens a second time, the first slot to contain a green Koopa Troopa (a requirement as they have the ID $00) in the object slot list is overwritten by a glitched object. The enemy ID which has replaced the first green Koopa Troopa will jump to a memory address corresponding to the slot available to the first half of the long firebar or Bowser and execute its contents as instructions.
Method
The game-end glitch method used in this TAS was discovered by Threecreepio and involves loading enemy ID $84 into any object slot other than slot 0. The code that processes enemy ID $84 jumps to $0747 (TimerControl) in RAM, which can be manipulated by taking damage. Initially, it executes a BRK opcode ($00), triggering SMB2’s IRQ handler.
Since this functions as a 2-byte opcode, the program counter moves to $0749 once completed, which is also a BRK opcode. The values at $074A and $074B are determined by the controller inputs of Players 1 and 2, allowing full control over two bytes.
Until damage is taken to manipulate TimerControl, the game must be prevented from crashing by holding B + Select on Controller 2 to create an RTS instruction ($60). Once damage is taken, TimerControl changes to $FE, a 3-byte opcode that moves the program counter to $074A upon execution.
At this point, the payload can be executed. The inputs from Controllers 1 and 2 result in the instruction JMP ($008D), an indirect jump to the address stored in locations $8D and $8E. Addresses $8D and $8E store the X-position of fireballs shot by Mario, which can be freely manipulated. In this case, the stored values are $81 and $AA, forming the address $AA81, which is part of the HandleAxeMetatile subroutine. This subroutine sets OperMode ($0770) to $02, signaling the game to prepare the ending sequence.
Alternate Methods
It is theoretically possible to gain total control using a stop 'n' swap approach. A significant portion of SMB2's stack ($0160-$01E4) is not cleared by the Disk System BIOS, and SMB2 explicitly skips clearing this region when running the InitializeMemory subroutine. This method also relies on an indirect jump but uses only Controller 2 to jump to the address stored in $00 and $01, requiring camera-scroll manipulation. A smaller-scale version of this method, which does not require swapping cartridges, leverages the X-position of the FloateyNumber variables. This was discovered by Simplistic6502 and OnehundredthCoin.
Another alternative method, developed by SBDWolf and threecreepio, involves setting the coin count to 96 ($60) to create an RTS instruction and execute controller inputs as code across multiple frames. This approach requires having a life count other than 3, as this prevents the game from encountering a STP opcode and freezing when executing NumberOfLives. Threecreepio has created a demonstration video showcasing this method.
Are Other SMB1-Engine Games Vulnerable to This Exploit?
Yes. All Night Nippon Super Mario Bros. shares a nearly identical 8-4 level layout with SMB2, allowing this exploit to be used there as well. However, the enemy ID which must be loaded into memory to transfer execution to RAM is enemy ID $83. While SMB1 and Vs. SMB have the same logic error in DuplicateEnemyObj, no level layouts exist that allow a glitched enemy ID to spawn. Additionally, even if a glitched enemy could be spawned in SMB1, the game would likely crash on the cartridge release due to the BRK opcode causing an infinite loop.
feos: Claiming for judging.
feos: Hard to believe but more than 10 years ago I was the one pushing for "game end glitch" movies not obsoleting regular completion! It even happened to one of my movies!
But for all these years a certain aspect was so frequent in "game end glitch" branches (and other major skip glitch ones too) that it started feeling like a natural part of then and one of the reasons they are separate branches - enormous time difference!
actually, I did the math, and I calculated that when Masterjun aims for fastest time, his movie is on average 3395.25% faster than another author's movie
Back in the times of tiers we aimed to have strict and clear rules for Vault, because the goal of that then-new tier was to have clear cuts, and if something doesn't clearly fit then it has to be entertaining enough for Moons. SPOILER: that goal was completely pointless, because no game was made with any kind of clear rules in mind, on the contrary - games aimed to be as varied as possible! That resulted in years of pain when we were trying to make make ends meet (literally) between games and policies. The class system was introduced as a white flag on our part, and we instead decided to start focusing on authors more than on policies.
Then we started allowing more and more goals to be published without any feedback requirements, which constitutes the standard class. "Forgoes major skip glitch" was the first new standard goal after "fastest completion" and "full completion". Then a whole bunch of others.
Now more quotes:
I personally think that whether major skip glitch is caused by memory corruption or breaking in-game physics, exact borderline will always need to be defined as a case-by-case consensus, depending on the game, how severe the skip is, and what the nature of the technique is. There can't be a simple clear-cut rule that resolves every known scenario nicely.
The decision should resolve the community consensus, not limit it
The definition of a major skip varies from game to game, but is generally defined as an unintended skip of otherwise unavoidable gameplay.
And only the old description of the Major skip glitch tag says
Most of the time, more than half of the game is skipped, compared to the fastest movie that avoids this technique.
but that's 1) old, 2) not a rule at all, and 3) even it says "most of the time" and refers to pure statistics.
So after the discussion in this thread happened, we've also had a staff talk, and the agreement was the same: this movie shouldn't obsolete anything. To a lot of staff members, my initial claim that it would obsolete the current record didn't make sense at all, neither before explanation nor after.
In the end, the only reason for obsoletion is if we ignore everything but the time difference. But nobody wanted that, and we depend on the community when resolving edge cases.
And the reason to not obsolete was that major skip glitch is not necessarily major in time, but it can also be major in its nature and not in time.
That's a fair point. Indeed if there are continuous improvements to the "game end glitch" branch, and we now obsolete because the time difference is too small, at which point exactly will we decide that it should stop obsoleting the main movie?
Again if we ignore everything else but time, we'd have to obsolete "for now" and then when the "game end glitch" branch becomes "short enough", we'd unobsolete the regular movie and only keep "game end glitch" ones in their own obsoletion chain. The only problem is when exactly does "for now" end? There's no good answer for that, because it's all subjective anyway. The only real criterion we have is community consensus. And it'd be weird to ignore it until a certain time difference is reached, and then suddenly consider it after. Maybe at that point we wouldn't even have any audience left, because we'd be rendered irrelevant by the community at large.
Bottomline: Everyone wants this, so we just rely on community consensus and accept this movie as a separate goal, because skipping straight to the end is big enough difference on its own regardless of time.
despoa: Processing...