...

: As you've probably guessed by now, this run gains total control of SMW. While this is theoretically nothing new-: so its just another one of those boring ace tases?: I've actually accomplished something this time by using a different setup!: but it still results in the same total control as always right?: Well... yeah, but, I mean look, it even works in Biz-: i dont care what happened before the glitch just tell me what code you wrote and what it does: ...alright.

I wrote flutter A.I a program that procedurally generates every single input accepted by SMW and keeps resetting the Bowser fight until the end is reached. I left out the Start, L and R (shoulder) buttons (and of course the 4 extra buttons, but they aren't being parsed by SMW anyways) because they would just delay getting to the end... (Not that it won't take a long time anymore). The code accounts for deaths and will continue the procedure anyways, and it also checks for completion, where it will then start rolling the credits and end the game in the usual manner.

This triggers a jump to open bus which executes an opcode based on the green shell position. That opcode is a jump which jumps to an offset based on the coin sparkles which happens to be controller registers where I conveniently put a jump to the shell sprite positions. The code there loads a value at the address in the gametimer bytes, which happens to be one controller register and stores it to the stack. This is how total control is gained.

You might've noticed that I have included a lot of information into the encode. Basically the first thing I do is set up the x and y positions of 5 specific shells (the low bytes, to be more precise). In fact, I actually need to set up an additional shell, but setting it up now would only result in it being replaced later on. Then I spawned two Yoshi's and did the invisible tongue glitch to set up the chuck eating glitch. After that I set up one byte of the extended sprites (coin sparkles), the position of the additional shell and then the second byte of the extended sprites (coin sparkles again). I continued with spawning the green shell in the lowest slot and setting up its x position. Doing all this while also delaying one gametimer and finally pausing the game to offset the second gametimer from the first. Finally I spawned the chuck and killed the visible Yoshi so that the chuck is on the tongue of the now visible Yoshi (which is back at the Yoshi block).

What I wanted to show with that dialogue was the fact that, yes, I could have just used on of my other multitap 4 controller 16 button exploits to write the code. This is what I call the lazy method of reaching ACE. In this run however I limited myself to using only a single controller, and it turned out I was able to leave out the 4 extra buttons, too. This meant that this run could be replicated in BizHawk which doesn't support neither multitap nor the 4 extra buttons.

OK at this point even you should probably skip to The Length, as this is getting real technical.

BRK

First I tested the mole glitch (stunning a mole to spawn an invalid sprite to make the game crash (execute opcode 00 () that I used in the AGDQ run of SMAS+SMW (you might remember that Super Mario Maker on SNES), but it turned out that it doesn't work because of one ROM vector which is different for the SMAS+SMW cartridge. So I was back to the chuck eating glitch which requires a more difficult setup.

Eating a chuck with Yoshi can be done in different ways. The game end glitch run uses a coin which is collected while simultaneously licked by Yoshi creating a replacable sprite on Yoshi's tongue which results in the chuck spawning on said tongue. However, this creates coin sparkles which overwrite important data to manipulate where the glitch is going. Another way of eating a chuck is by using a mushroom instead of a coin, but that takes too long to set up (eating a bunch of berries and collecting the midway point). I decided on using two Yoshi's to perform the glitch. This works because when you lick a sprite with Yoshi and then overwrite that Yoshi with another Yoshi, the fact that the now invisible Yoshi has a specific sprite slot on his tongue remains. This means despawning the visible Yoshi (for example by killing) reactivates the old Yoshi and the tongue.

JSR

The code jump to open bus when you eat a chuck and it will execute shenanigans , but most importantly it needs to execute the opcode 0xFC (). Executing 0xFC requires the value at the address at address $01+chuckslot to be 0xFC. I found out that if the chuck is in slot #8, I need the sprite with the lowest slot to have the xposition low byte to be 0x81, which will turn into 0x8F (because it adds an offset of 14 apparently) which then turns into $8F01 (0x01 because of $09) and that turns into $018F01 (because DB is 0x01) and luckily that holds 0xFC.

JSR $00E4

So far so good, the code now jumps to whatever address $1804 points to. $1804 are the ypositions of minor extended sprites which are being used for coin sparkles for example. The only problem with coin sparkles is the fact that they spawn in bundles of 4, the 3rd takes up $1805 and the fourth uses $1804. You can avoid spawning the fourth by collecting the coin close to the edge of the screen, meaning you can manipulate the low and the high byte seperately. Now where do we jump to? Of course we simply jump to the start of yposition data of normal sprites which is followed by xposition data meaning we have a bunch of values we can manipulate right!? No, we have two problems here. The first problem is the fact that it would be address $00D8 which is impossible to get with coin sparkles at the start of the level. So we instead jump to some other location that can be manipulated more easily to jump to $00D8. Which location you ask? Controller registers of course. By holding B, Y, select, down and L the values at $4218 read 20 E4 00 (the 00 because we don't have a second controller... or at least it isn't pressing anything) which translates to... but wait a minute, that isn't $00D8 at all! Well yeah, you can also change it to $00D8 if you want but we still have problem number 2 to discuss.

The second problem is the fact that the most important part of the whole glitch, the part that starts even before the TAS, the payload itself, is pretty limited in size and shape. SMW uses 12 sprites slots (#0 to #B) but in YI2 the slots #A and #B are reserved for special sprites. We also need the chuck in slot #8, two Yoshi's (preferably in slots #9 and #7 then) and the lowest slot xposition sprite (in slot #6 then). So we only have 6 ypositions and 6 xpositions to work with. The important part is that the two blocks are not back to back so each block has to jump to the other (this is also why I could simply jump to $00E4, the xpositions, instead of $00D8, the ypositions, and it turned out that switching the blocks made it faster to manipulate the values) and one of the blocks also needs to jump out.

$00D8: B2 13 D0 09 F0 60 $00E4: CB 48 CB CB D0 EE

$00D8: LDA ($13) : BNE $00E5 : BEQ $013E $00E4: WAI : PHA : WAI : WAI : BNE $00D8

LDA ($13)

BNE $00E5

WAI

WAI

BNE

BEQ $013E

BNE

WAI

WAI

PHA

WAI : WAI

BNE $00D8

BNE

So the full code I wrote was:or simply:: Let's explain from the start. $13 is the framecounter of SMW and $14 is the game-framecounter. You can offset them from each other by pausing the game because $14 also stops when pausing whereas $13 continues (they are the reasons why I jumped around strangely after placing the green shell and also why I pause the game just before the glitch). The timers also stop when this glitch happens. I made them read $4219 so I could use B, Y, select, Start, up, down, left and right to manipulate what's loaded into the accumulator there.: Hold on a second that doesn't even line up with the second block, are you stupid? No, the reason I did that is because I need two's to advance one frame, but unfortunately I start at the wrong offset meaning that I have to advance a singlebefore starting the loop. But I only have to execute it once so I jump to $00E4 to start off the code and to $00E5 when in the loop. Also you might notice theopcode (branch if not equal to zero), which only branches if the previous result wasn't 0, meaning I can stop the loop if I just input 00 for one frame (this also means my written code can't include a single 00).: Since this is the exact opposite ofthis will always jump. $013E lies within the stack. (Why the stack? Continue reading.): This instructions waits for an interrupt (like NMI or IRQ). This firstwas for the offset so I don't read the controller registers while they're being updated (because it puts me after IRQ instead of after NMI).: Remember that the accumulator still holds controller data, meaning that byte is pushed into the stack with this instruction. This is the reason why I can simply jump into the stack once I'm done writing code (because it's exactly where I write my code in the first place).: This effectively waits a frame.: Complete the loop. (Oh, and yes, this always jumps even if it is a.)

Since the amount of bytes I can write is pretty limited and I'm not able to write 00's, I simply wrote code to write code somewhere else. That somewhere else is where I put my code which simulates the main game loop with some additional hooks like overwriting parsed input or resetting the bowser fight when the end of the current input is reached or simply when you die.