This is a completely new type of a Super Mario World run. It beats the game by getting the THE END [dead link removed] screen in the 2nd level (Yoshi's Island 3).
After the discovery of a new glitch by あんた (anta), our Skype TASing community was trying to understand what happened in the .smv. Since he only uploaded the .smv and a japanese documentation, we had to find it out by ourselves.
"spit sprite position = yoshi X position + offset to spit object(index by Y which is the direction)
normally, this would store to the sprites X position, however, because the sprite index is #$FF
It writes to #$E4 + #$FF which is #$01E3. This is the stack address that is corrupted. If yoshi
is facing left he must be at the position #$86, and if he is facing right it should be #$66."
p4plus2's documentation of the "credits glitch" [dead link removed]
X position of sprite #04 (it's Yoshi in this case) (freezes when the sprite disappears, though you shouldn't have him disappear)
OAM Address
needed Value
Description
$01:02D4
#$26
X position of some score numbers onscreen (freezes when it disappears)
$01:02FC
#$A3
X position of the "smoke" effect (like when a fireball goes into a wall) (freezes when it disappears)
$01:02FD
#$F0
Y position of the "smoke" effect (same as above) (sets to #$F0 when it disappears)
$01:0304
#$81
X position of a Mario tile that appears when Mario is on Yoshi and he is in the turning animation (freezes when it disappears)
$01:0305
#$39
Y position of the same Mario tile as above (freezes when it disappears)
$01:0308
#$B0
X position of a cape tile (freezes when it disappears)
$01:0309
#$F0
Y position of a cape tile (sets to #$F0 when it disappears)
$01:030C
#$60
X position of a cape tile that appears when mario is flying (freezes when it disappears)
Those addresses starting with "01" are just OAM Addresses. OAM is a chunk of memory that stores the data about the sprite tiles to draw onto screen.
RNG:
The Random Number Generators (RNGs) change with certain events. We have to change the RNG 1197 times for it to work in our favor. When a koopa spawns, it's called once (when the RNG is "called", it changes). Before going into the pipe in YI3, three koopas appear; this leaves the RNG to be called a remaining 1194 times. This is where the fish come in. When a flopping fish bounces on the floor, it calls the RNG three times. So, that means the fish need to bounce 396 times (to call the RNG 1188 more times). After the fish manipulation, there are exactly six koopas that spawn. After they spawn, the RNGs are set perfectly in order for me to activate the credits.
There are also some OAM addresses that have more than one possible values, they have to have the same bytes of opcode and they also have to not affect the A register.
OAM Address
Bytes of Opcode
Description
$01:02FA
2
Will be the right value when you shoot a fireball with X
$01:02FE
2
Will be the right value when you shoot a fireball with Y
$01:0300
4
X position of a koopa shell tile
$01:0302
3
Will be the right value when you pick up a shell
$01:0306
2
Nearly always right
$01:030A
2
Nearly always right
(actually you can change the bytes of the opcode, only the number of bytes between two required values is important)
Stage by stage comments
Yoshi's Island 2
We can't manipulate the addresses here since they would reset in the overworld.
Yoshi's Island 3
If you jump on a p-switch and then get the "pressed" p-switch in Yoshi's mouth on the right time, you will spawn a fish if you spit out the p-switch fast enough. Also, there can only be eight fishes in the room. After this room, I went back to the Yoshi block. I spawned two Yoshi's by hitting the block with Mario and the p-switch at the same time. I jumped on one Yoshi, got the p-switch in his mouth and let him die, so the second - invisible - Yoshi becomes visible and have a null sprite in his mouth. Then I go right to perform a PI (Powerup Incrementation) so i get a cape, to manipulate some values.
Other comments
Potential Improvements
Maybe the part with the fishes can be improved, since its heavy luck manipulation.
Also, maybe there is a faster strategy to get all the right values.
Suggested Screenshots
[dead links removed]
Thanks to
Our Skype TASing community, for being able to help each other.
あんた (anta), for the discovery of this awesome glitch.
p4plus2 and smallhacker, for their awesome work exploring the glitch.
DarkMoon and Kaizoman666, for helping me writing this submission text.
I'm fairly sure it actually did execute the ending. The ending screen normally doesn't play music, it just lets the end music continue from the previous screens. This is doing the same thing but the last music played isn't the ending music, but the level music.
As far as I know, the "credits" version starts from the Yoshis' "Thank You" and plays through that half of the credits with no sound or music at all.
It's not just a splash screen; p4plus2 said that the game state is actually changed to that of the end of the game, so the game thinks you have already beaten Bowser and the rest of the credits have already rolled. Just like when you've finished the game the normal way, you cannot press anything at the "The End" screen; all you can do is reset/turn off the SNES.
That's exactly what I meant - I was including the program counter as part of the hardware state. So here, the "display ending screen" routine is executing, therefore you win. Having the wrong background music is irrelevant - even under normal conditions, the ending screen is just the continuation of the music of the previous screen.
I don't see the difference between doing that and using the reverse bottle adventure glitch in Ocarina of Time to pick up sage medallions out of thin air.
That said, I think most people would require some kind of visual feedback as evidence, and checking the value of a bit in RAM is not the proper method to do so in general as you just pointed out, unless changing that bit has some obvious consequences. Therefore, checking the program counter value and the stack state is a much better test to determine a win.
WARNING: Huge technical post ahead.
No you can not move Mario. The game no longer is in a level, it it has changed its mode of processing entirely. In this glitch the game mode is changed to #$26 (as I explained like three times now). But let me bring the actual code into this now:
First lets talk about how SMW actually processes its game loop. There is a small infinite loop that basically checks if NMI has run, and once it has it will run a routine called "RunGameMode". So lets take a look at the game loop:
GameLoop:
LDA $10 ;$00806B |\ Main wait loop
BEQ GameLoop ;$00806D | | $10 is set in NMI to $00
CLI ;$00806F | | Enable interrupts
INC $13 ;$008070 | | Increment frame counter
JSR RunGameMode ;$008072 | | Run the game
STZ $10 ;$008075 | | Clear $10
BRA GameLoop ;$008077 |/ Back to the wait loop
As you can see, the game simply runs in an infinite loop. So the real important thing to us is what happens in the different game modes. So lets take a look at the routine next.
RunGameMode:
LDA.w $0100 ;$009322 | Load the current game mode
JSL ExecutePtr ;$009325 | Call the execute pointer routine
Simple enough, So what does this mean? It means there are a series of pointers that control game execution.
So here are the important game mode pointers to us, I have snipped non-important ones.
*snip*
dw InLevelGameMode ; 14 - In level
*snip*
dw CODE_009F6F ; 26 - Fade to the end
dw CODE_00963D ; 27 - load the end
dw CODE_009F7C ; 28 - Fade in to the end
dw Return00968D ; 29 - END (last game mode in SMW)
In game mode 14 is when you are controlling Mario and the level is executing as normal. The code for game mode 14 is huge, I won't torture you with that unless you want to see the code for it.
Game mode 26 is the code there the game will fade out to enter F-Blank (brightness of 00 with the negative bit set) in preparation for game mode #$27 to upload graphics.
CODE_009F4C:
LDA.w $0DAE ;$009F4C |\ Calculate the current brightness step
CLC ;$009F4F | |
ADC.w DATA_009F2F,Y ;$009F50 | |
STA.w $0DAE ;$009F53 |/ Store the current brightness ($2100 mirror)
CMP.w DATA_009F33,Y ;$009F56 |\ If the brightness has not reached the desired brightness
BNE CODE_009F66 ;$009F59 |/
INC.w $0100 ;$009F5B | Increment the game mode (putting you at game mode #$27)
LDA.w $0DAF ;$009F5E |\ Flip the Mosaic/Fade direction
EOR.b #$01 ;$009F61 | |
STA.w $0DAF ;$009F63 |/
CODE_009F66:
LDA.b #$03 ;$009F66 |\ Copy the mosaic mirror to the mosaic register
ORA.w $0DB0 ;$009F68 | |
STA.w $2106 ;$009F6B |/
Return009F6E:
RTS ;$009F6E | Done with game mode 26
CODE_009F6F:
DEC.w $0DB1 ;$009F6F |\ Keep the current game mode active
BPL Return009F6E ;$009F72 | |
JSR KeepModeActive ;$009F74 |/
CODE_009F77:
LDY.w $0DAF ;$009F77 |\ Load the current Mosaic/Fade direction
BRA CODE_009F4C ;$009F7A |/ Branch to an earlier portion of code
Game mode #$27 is where the actual graphics are uploaded. This game mode simply prepares the screen in F-Blank.
CODE_00963D:
JSR CODE_0085FA ;$00963D | Turns off IO and does some DMA
JSR Clear_1A_13D3 ;$009640 | Clean RAM $131A to $13D3
JSR SetUpScreen ;$009643 | Do some screen setup
JSR CODE_00955E ;$009646 | Upload the layer graphics to VRAM
LDA.b #$19 ;$009649 |\ Set some screen properties(such as palette settings)
STA.w $192B ;$00964B | |
LDA.b #$03 ;$00964E | |
STA.w $192F ;$009650 | |
LDA.b #$03 ;$009653 | |
STA.w $1930 ;$009655 |/
JSR UploadSpriteGFX ;$009658 |\ Upload the palette and graphics
JSR LoadPalette ;$00965B |/
LDX.b #$0B ;$00965E | Load the loop index
CODE_009660:
LDA.w TheEndPalettes,X ;$009660 |\ Do some palette corrections
STA.w $08A7,X ;$009663 | |
LDA.w DATA_00B71A,X ;$009666 | |
STA.w $08C7,X ;$009669 | |
LDA.w DATA_00B726,X ;$00966C | |
STA.w $08E7,X ;$00966F | |
DEX ;$009672 | |
BPL CODE_009660 ;$009673 |/
JSR CODE_00922F ;$009675 | DMA the palettes to CGRAM (they were in mirrors before)
LDA.b #$D5 ;$009678 |\ Set and load a layer three image (THE END text)
STA $12 ;$00967A | |
JSR LoadScrnImage ;$00967C |/
JSL CODE_0CAADF ;$00967F | Copy some sprites to OAM (the characters)
JSR CODE_008494 ;$009683 | Run the OAM size table routine
LDX.b #$14 ;$009686 |\ Useless loads, probably old leftover code
LDY.b #$00 ;$009688 |/
JMP CODE_009622 ;$00968A | Jump ahead
CODE_009622:
JSR KeepModeActive ;$009622 | Keep the game mode active(unused since there is no $0DB1 check)
LDA.b #$09 ;$009625 |\ Set the background mode
STA $3E ;$009627 |/
JMP CODE_0093EA ;$009629 | Jump ahead
CODE_0093EA:
LDA.b #$01 ;$0093EA |\ Set to the cutscene mode
STA.w $0D9B ;$0093EC |/
LDA.b #$20 ;$0093EF |\ Update some screen settings
JSR ScreenSettings ;$0093F1 |/
INC.w $0100 ;$0093F4 | Increment the game mode
LDA.b #$81 ;$0093F7 |\ Renable NMI
STA.w $4200 ;$0093F9 |/
RTS ;$0093FC | Done with game mdoe #$27
Game mode #$28 is a small game mode that shares most of the code with #$26. This game mode is responsible for doing the fade-in effect.
CODE_009F7C:
DEC.w $0DB1 ;$009F7C |\ Check if the game mode should be kept active
BPL Return009F6E ;$009F7F |/
LDA.b #$08 ;$009F81 |\ Set the number of frames to delay the fade-in steps
JSR CODE_009F2B ;$009F83 |/
BRA CODE_009F77 ;$009F86 | Run the fade code from game mode #$26 (opposite direction)
And lastly, game mode #$29. The simplest one of them all.
Return00968D:
RTS
Thats it. The game just simply returns. It has nothing more to do. For all intents and purposes, the game is done with execution.
Hopefully this helps clarify what a "winning" state in SMW is.
Wow, very nice and precise explanation p4plus2! Impressive, I like that!
So basically, beating SMW normally eventually causes the game to reach game mode 29 and stay on it until reset. If somehow we would have jumped directly to game mode 29 from game mode 14 however, it would have looked as if the game simply hanged while playing instead of a win, but by passing through game mode 27 beforehand, then we get the ending screen, which is the latest output feedback of the ending sequence.
Also, if I understand the code you posted correctly (correct me if I'm wrong), passing through game mode 26 simply allows a smoother transition, since the game would otherwise need to overflow the brightness value during game mode 28 to reach game mode 29.
Considering this, even though reaching game mode 29 is the final win state of SMW, since there is no win output feedback that far in the code, the best test in my opinion to determine a win is to check if the program counter equals $00963D, or in other words if the game is about to execute the code associated with game mode 27.
As for those that feel that the correct win test should be at the earliest point of the ending sequence rather than the latest, well that point would be the exact moment when Bowser is defeated, not the Thank You screen. Therefore, both versions of this run would need to be rejected, since adding the 3 frames would merely be a compromise that satisfies nobody except on a purely subjective level.
Wow, very nice and precise explanation p4plus2! Impressive, I like that!
So basically, beating SMW normally eventually causes the game to reach game mode 29 and stay on it until reset. If somehow we would have jumped directly to game mode 29 from game mode 14 however, it would have looked as if the game simply hanged while playing instead of a win, but by passing through game mode 27 beforehand, then we get the ending screen, which is the latest output feedback of the ending sequence.
Also, if I understand the code you posted correctly (correct me if I'm wrong), passing through game mode 26 simply allows a smoother transition, since the game would otherwise need to overflow the brightness value during game mode 28 to reach game mode 29.
Considering this, even though reaching game mode 29 is the final win state of SMW, since there is no win output feedback that far in the code, the best test in my opinion to determine a win is to check if the program counter equals $00963D, or in other words if the game is about to execute the code associated with game mode 27.
As for those that feel that the correct win test should be at the earliest point of the ending sequence rather than the latest, well that point would be the exact moment when Bowser is defeated, not the Thank You screen. Therefore, both versions of this run would need to be rejected, since adding the 3 frames would merely be a compromise that satisfies nobody except on a purely subjective level.
Pretty much spot on. The only additions I hate to make to that is that the "smoother transition" enables F-Blank which is required to not have glitched graphics from writing to VRAM outside of a blank. But those will be temporary effects, so game mode #$27 is still a fair judgment on whether or not to call it a victory.
Caution: I was bored and decided to type up a bunch of semantics.
I am of the opinion that 2 things are necessary for game completion
1: Convince the viewer that the game was ended.
- (Perhaps graphically for you most part? Audio itself is probably not sufficient),
2: Convince us here that the game is in its end state.
- (The code presented is more than sufficient enough to explain this in this case.)
I'll just explain some possible cases as I would judge them
1: The End graphic is displayed on screen
- If the game has just loaded a graphic due to corruption, this is not sufficient to me to say the game has ended
-No, IMO
2: Game is placed in state 29, frozen game screen
- The game is in the end state, frozen, but you'll never be able to convince a viewer the game was finished.
- No, IMO
3: Game is placed in state 26, shows an ending graphic on screen, and runs through to state 29
- Visual confirmation, and correct end state in code is good enough for me.
- Yes
4: The gameplay halts, the credits roll in their entirety, the game resumes mid-gameplay (or even if it just crashes right at the end of the credits.)
- The game is not in the correct end state in my opinion
- I would say no.
Is it worth sacrificing 3 frames "for speed entertainment tradeoffs" to show an earlier state of the credits and do a little better convincing of the viewer? Since people are so divided, I would probably leave this choice to the author.
Given the state of the current "any%" that recently hit the workbench, I think this opens up room for 3 categories.
1: Credits glitch
2: any%
3: any% low glitch
This is all my opinion of course.
It's amazing really, but the way to finish. I find that the game makes no sense, in which Mario suddenly mad and take actions to suddenly appear on the screen "THE END". For this reason, I vote NO!
Joined: 1/27/2011
Posts: 78
Location: Minnesota, USA
Felipe wrote:
It's amazing really, but the way to finish. I find that the game makes no sense, in which Mario suddenly mad and take actions to suddenly appear on the screen "THE END". For this reason, I vote NO!
You're insane. This is quite literally the most insane glitched TAS I've ever seen. It's
literally breathtaking. I can't even think of a better TAS in any category ever. This is the most impressive thing I've ever seen.
A strong, strong Yes vote from me. Holy motherfuck.
Taking a point of view, about that happens at the end. It not seems so strange that when you see the end, continue listening the background music of level. When you finish the game by defeating Bowser, the credits music is just finishing when the message "THE END" appear, then it is normal that continue the music.
However, I do not understand because it appears in the middle of the final level. You say that we have certain values in the RAM and OAM to display the end, if I remember correctly. So, the game were programed so that the message appears under the conditions of certain values in memory?
You're insane. This is quite literally the most insane glitched TAS I've ever seen. It's
literally breathtaking. I can't even think of a better TAS in any category ever. This is the most impressive thing I've ever seen.
A strong, strong Yes vote from me. Holy motherfuck.
I support that's crazy, I realize that. But I had voted NO to see things from a different point of view. Besides, I'm not the only one to vote NO.
Is it worth sacrificing 3 frames "for speed entertainment tradeoffs" to show an earlier state of the credits and do a little better convincing of the viewer? Since people are so divided, I would probably leave this choice to the author.
It's a tricky line to draw... and not one that would be made by this run alone.
Primarily, the Earthbound run currently on the workbench has an identical conundrum; go for the absolute fastest (both in video time and in frames) condition that triggers a "The End" screen, or a slower condition that triggers credits instead. Only real difference, though, is that this video serves to lose a mere 3 frames* from switching to a version with partial credits, while Earthbound would lose eleven minutes due to being required to sit through the credits.
That said, while many people are in favor of maintaining credits, my opinion has gradually shifted to being more in favor of abrupt The-End-iness, as the glitched credits we'd get from waiting leave much to be desired. We'll always have non-game-breaking-glitched runs available to view credits from, and it is decidedly not the highlight point of the run.
* While there are those who would say three frames matter, please keep in mind that not only is this video nearly unobsoletable, this frame loss would also be required by any contenders to the video if it were determined that getting the "credits" are required.
As an unrelated note, I am extremely in favor of frame 6666 as the screenshot, as suggested by the author and Noob Irdoh. It's just too bizarre to pass up.
First a movie gets submitted, and ends up accepted despite breaking rules other runs have been rejected for. And when I vote less than spectacularly on this movie, I become the victim of harassment and threats.
Yay, favoritism.
I don't see the difference between doing that and using the reverse bottle adventure glitch in Ocarina of Time to pick up sage medallions out of thin air.
The difference is fairly obvious. In oot, you don't beat the game until you do the exact same thing you would normally do: beat the final boss. Most of the game before that is skipped, but in the end, you still need to beat the boss.
..except he doesn't even TAS. :P
Also, I don't get why some people are still skeptical about the glitch in the run. There's dozens of other games that abuse glitches like this and AFAIK they get accepted too. Is the main argument the credits not being viewable? If so, they aren't in the Tetris TAS either. The whole point of a TAS is get to the final part of the game in the shortest time possible and that is what this TAS does.
Given the state of the current "any%" that recently hit the workbench, I think this opens up room for 3 categories.
1: Credits glitch
2: any%
3: any% low glitch
In my opinion, I don't see the point of having different categories for every type of glitch ever found. I won't go into much detail since I already discussed this matter in the other SMW submission, but basically I only see the relevance of the following categories:
- Any%
- 100%
- Glitchless 100%
rog wrote:
The difference is fairly obvious. In oot, you don't beat the game until you do the exact same thing you would normally do: beat the final boss. Most of the game before that is skipped, but in the end, you still need to beat the boss.
You are correct: the credits glitch directly beats the game while the reverse bottle adventure glitch does not. What I meant was that both glitches are memory manipulation bugs and thus must be considered equally powerful. If the RBA glitch is allowed, then the credits glitch must also be allowed.
As for the rest, I already discussed it in my previous posts, but I would find it a real shame if this run would be rejected simply because the game is not beaten the expected way.
Question: Is this video of getting 120 stars in Mario 64 (European version?) real? http://www.youtube.com/watch?v=Ro53MEsvzwo
If it is, using the logic discussed to accept this Super Mario World run, why would this method not be usable to create a 2 minute, 0 star TAS?
If the process were real (i.e. glitch the menus to get a file with 120 stars), it could be used to beat the current 0 star TAS. Assuming all keys were also opened (a reasonable assumption given that this is a hypothetical situation anyway), the player could simply run up to the final Bowser fight and beat him to see the credits.