Pwn Adventure Z is an adventure game where you kill zombies. It was created by Peter LaFosse, Rusty Wagner, and Jordan Wiens of Vector35. You can read more about it here https://github.com/Vector35/PwnAdventureZ/blob/agdq/README.md

Game objectives

  • Emulator used: Bizhawk 1.11.4
  • Takes damage to save time
  • Makes use of a save corruption glitch

The competition:

This game was chosen for the AGDQ 2016 TAS competition which you can read more about here.
The game was originally developed for a capture-the-flag hacking/reverse engineering competition. As such, it contains some intentional glitches (including an ACE glitch). Additionally, the developers found a few glitches (such as the campfire glitch) during testing and chose not to fix them. During the TAS competition, details of some of these glitches were given to the competitors to save them time in glitch-finding.

The routes:

There are various possible routes that could be used to complete the game; some of them were envisaged by the developers, others weren't.

"Intended" route:

The developers didn't expect anyone to actually do this, but it is possible to complete the game without exploiting any glitches. Doing so requires you to beat a number of bosses in order to gather keys to unlock a final area, and is clearly slower than any of the alternatives listed below.

Campfire glitch:

Explanation:

The game has a craftable item, the "campfire", which allows you to change your respawn point upon death (by default you respawn at the last shop you visited, or at the start of the game if you haven't visited a shop). Using the campfire item allows you to set a spawn point at your current location; however, it only records your x and y coordinates and not which map you are on. The game has an overworld map as well as a cave map that use a common coordinate system; the campfire respawn assumes the overworld map and it just so happens that one of the cave rooms is at the same coordinates as the final boss room. As a result you can set a campfire in the cave and deathwarp to the final boss room.

Evaluation:

This glitch was not intentionally added to the game by the developers, but they discovered it before release and decided to leave it in. It was one of the two recommended routes for use in the TAS competition, and the route that was eventually used by both the human competitors and all the fastest TASes; it is considerably easier to optimize than the ACE route, and thus better for a human to run in realtime and easier to figure out in the limited time required for the TAS competition. The main difficulties with the route are that you need to obtain the crafting components for the campfire, and that it places you in an out-of-bounds area of the final boss arena (meaning that you need to obtain a weapon that can fire through walls to be able to damage the final boss).

ACE:

The short version:

The game by design has 28 inventory slots, but 29 unique items. This means that the 29th item/count will stomp on the next two bytes (in this case a jump table for screen loading). This can be used to execute some code that makes the game believe that the boss is dead and get it to trigger the ending.

The long version:

Specifically the two bytes that get stomped on (0x60-0x61) are used for loading the initial cave screen. As a result of this you can configure those bytes (within the restrictions of values easily obtained by inventory items), and simply walk into the first cave screen to make the execution jump to whatever address you've stored there. It was pointed out in the information provided with the competition that a campfire puzzle (a screen with 6 columns of 4 campfires that you can light/extinguish) may be useful. The state of the puzzle is stored in 0x302-0x304 and you can easily go the the room and set those bytes as you please. It would probably take much more setup to take total control, but I was able to find a clever way to complete the game. Address 0x300 is a boss_beaten flag, when it is set to a non-zero value the main loop of the game will trigger a countdown and then jump to the end credits. I was able to achieve this by putting an SMG with an empty clip in the overflow (29th item), this leaves a value of 0x300. I also set up the campfire puzzle to store the values 0x96 0x60 0x60 in addresses 0x302-0x304. It is worth noting that the item overflow can be sped up by an infinite money glitch (if you buy and sell the more expensive SMG first you can get it again from the buyback screen for $0 and resell for profit). Additionally since you are rich you can buy/sell guns to fill up the buyback screen and then buy the whole stack back to boost your item count (for both guns, this greatly reduces the number of unique items you really need to cause an overflow). Once you finally go to the start screen to trigger this setup the execution will first jump to 0x300 (because that is what we stomped into the jump table). There it will execute: BRK BRK STX $60,Y RTS The execution will fall through the breakpoints and store the value of x to the address in location 0x60 + the value of Y. As it happens the value of Y at the time this triggers is 0 and X is non-zero. By genius design we had already put 0x300 in location 0x60 to jump the execution in the first place, but now it is used as the address to store whatever was in X. We just stored a non-zero value to 0x300 so once we return to the main loop the game will think we have beaten the boss. So we do an RTS and return. It was important to be clever here and use a 2 byte instruction to leave us a byte to do a return instruction, had we used a 3 byte instruction the flag would be set but the execution would go off into the weeds and not run the main loop or finish the game.

Evaluation:

It's incredibly convenient for a pointer value to occur just after a buffer overflow; unsurprisingly, this glitch was placed into the game intentionally by the developers. It was one of the two suggested routes for the TAS competition, but as many teams discovered to their cost during the competition, doing it in a naive way is slower than the (much simpler) route involving the campfire. (This is partly because the infinite money glitch was, although known to the developers, unknown to the competition participants.) link_7777 thinks that this route may be faster than the campfire route if fully optimized, but that it's hard to be sure without doing a full TAS of each route: it would be a bit too close to call merely with intuition.

Save corruption:

The short version:

If you reset during a screen transition, the resulting save file is a merge of the save files from before and after the screen transition. If the checksum and reset timing happen to be correct, the effect is that you load at the wrong side of the resulting screen; you move to the next screen, but load at the position within the screen at which you entered the previous screen. For example, if you move one screen to the right, then one screen to the left and reset at the correct point during the transition, you load at the left hand side of the left hand screen.

The long version:

The saving in this game happens during screen transitions or when you say so from the pause menu. The save data includes a 4 byte signature, ram values 0x0-0xFF, 0x300-0x4FF, and a 30-byte header. The data is saved three times, and each of the three copies has its own 16-bit CRC. The game attempts to use the first copy which has a correct CRC (but due to a bug, will delete the save data if the first copy has the wrong CRC).
The save data includes, most notably, the current x/y position of the screen on the map as well as the x/y position at which the character entered the screen (which is used as a position at which to reload the character). As it happens, the map position is copied to the save file before the screen position, and since the saving process takes a number of frames it is possible to reset after the map position change, but before the screen position change. The main issue with this is the CRC, which has to match for the corrupted save data to be used. Fortunately, the CRC is only 16 bits wide, so only 16 bits need to match to manipulate a collision. Even more fortunately, the save data saves the entirety of zero page, which includes some things that change over time (such as a frame counter and the current note of the background music), and even more notably a copy of the controller input. Both of these appear early in the save data and thus can be used to manipulate the CRC of the resulting merged save file to equal the CRC of the original; for this run, link_7777 used brute forcing when doing save corruption to get the CRCs to match.
ais523 was the first to work on the save corruption route, during play-testing for the TAS competition. The very first plan was to use save corruption to get through the 6-key barrier and thus sequence break the plot of the game, but that route is quite slow because you face a mandatory boss ("horde") battle on the way. An obvious improvement was to go to the screen to the right of the final boss room (which is accessible from the overworld map), then go right, left, and reset; this places the character in the final boss room directly. ais523's proof of concept used this route, and it looked obviously faster than the other possibilities.

Evaluation:

The game developers went to a lot of effort to prevent anything like this working (and remarked to ais523 during the playtesting that looking for a route like this was a waste of time). However, having three copies of the save file is pointless if you're simply trusting the checksum on them to see whether they're corrupted, and not comparing them against each other; a simple CRC-16 collision is enough to completely bypass all the save protection. Unfortunately, the game autosaves very aggressively (which is why map transitions are so laggy); typical save approaches like merging an x coordinate from one save file with a y coordinate from a different save file don't work because there's no quick way to change both the x and y coordinates from one save to the next (you could probably use a campfire, but there's a simpler way to win with one of those). The benefits are thus restricted to moving within a screen, and possibly duplicating items (something we didn't look into because it wasn't necessary for the run).
The save corruption route is clearly faster than the intended glitch routes because it doesn't need to go very far out of its way; it can go almost anywhere on the map directly via glitching through walls. The other routes all require detours to pick up items necessary for the route to work, and to map locations to fight bosses, place the campfire or manipulate the torches for ACE.

Out of bounds

Since we can effectively save corrupt through intended barriers, link_7777 began to wonder what was outside the intended map. As it turns out there is quite a bit of interesting stuff (as you can see from this cool video made by Masterjun). As a result the route that this run uses (shown below) starts the game by going right 1 screen and then save corrupting twice to go left 2 screens (1 isn't sufficient since you are stuck in a wall that is too thick). From there we can indirectly make our way down 8 screens to one of several out-of-bounds screens that happens to spawn the boss. I'll note that I pause at a couple of the screen transitions to set up the corruption. I wait 45 frames before going to the right and another 29 before going back to the left in order to set up the in-game time to a value capable of giving us the correct CRC. After the restart I wait an additional 166 frames for the right in-game time to set up the 2nd reset. This means we spend a total of 240 frames setting up these corruptions which was the best I was able to find with my brute forcing scripts. You can visualize the route here (thanks to Masterjun) in red, the dotted yellow shows movements made by save corruption:

Evaluation

Once you can get to the final boss almost directly via glitching through walls, the only real improvement is to find a closer final boss to fight. Sometimes thinking outside the box is a good idea. In this case, we don't even leave the starting cave via the intended route, destroying both the intended "intended" gameplay and the intended glitched gameplay of the game.

Boss fight:

Even though we only have the initial weapon (the axe), BrunoVisnadi brings down the final boss pretty quickly. This is largely due to the splash damage from the exploding zombies that the boss spawns (generally blowing up as a result of his grenade, this requires good but not precise positioning). The boss starts with 1280 health, each axe hit does 10 and each zombie explosion does a base of 120 (240 if another enemy is in the mix, zombie not required).
The boss has 4 different phases he can be in, which are: spawning, walking, throwing bomb and shooting. It is impossible to manipulate how many spiders he will spawn before he spawns the 2 last zombies, so the best thing to do is to make him to spawn the spiders as fast as possible. BrunoVisnadi is hitting with the axe constantly and manipulating the phases and spawns into position. The spawning phase can be skipped by hitting the boss in his left half, which is useful to make him to walk immediately after spawning the second sprite (he spawns 2 sprites in each phase, and normally he takes some time to start walking again). The walking phase can't be skipped, but it's possible to manipulate how far and to which direction he will walk to, depending of the player's position and the position the axe hits the boss. Normally, the best thing to do is to make him to walk as little as possible, so that he spawns more sprites quicker, but sometimes it is useful to make him to walk a bit further to improve the position. The bomb throwing stage can't be skipped, and it wouldn't be useful to skip it as the bombs are essential to kill the spiders (there is a spawn limit in the room, if the spiders don't die, the zombies wouldn't get to spawn); and the shooting phase can also be skipped by hitting the boss in his left half. Additionally taking damage reduces the cooldown time for the axe swing, so damage is taken to pack in the axe hits as quickly as possible. In the end he does 56 axe hits (for 560) and manipulates 3 zombies to do 240 each for the 1280 total. BrunoVisnadi was even able to end the input a number of frames early while waiting for the last zombie to take a grenade hit and finish the boss.

Boss suicide potential:

It is worth noting that there is an alternative strategy for ending input, via getting the final boss to commit suicide. With this route this boss room has a different shape than the intended one and as a result the suicide isn't possible using this strategy, but if you save corrupt into the intended boss room in a position where you don't get hit by the boss laser attack, you can end input and the boss will eventually suicide as he will eventually take enough hits from exploding zombies that he hits with grenades. This takes a number of minutes since the exploding zombies tend to congregate around you instead of wandering near the boss where they could do damage.

Special Thanks To:

  • BrunoVisnadi for the collaboration (and most of the actual input)
  • ais523 for the save corruption idea
  • Masterjun for the ideas, suggestions, and new route video
  • dwangoAC for running and commentating the TAS competition
  • Games Done Quick for hosting the TAS competition at AGDQ 2016
  • The developers at Vector35 for creating the game and letting us use it for the TAS competition

Samsara: Congrats on beating my initial test time by 25 minutes! Judging!
Samsara: Removed the branch name.
This is an impressive run on a technical level, especially in regards to the competition. I knew of two possible routes, the campfire glitch route and the ACE route with the torches, but the emergence of this much shorter route was mind-blowing, and the thread feedback shows that everyone else felt the same way. However, the thread feedback also showed that the audience didn't find the game too entertaining to watch.
Because of the thread feedback, I'm accepting this to Vault, though I do hope the publication votes are good enough to push it up to Moons.
Spikestuff: Right.


TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15628
Location: 127.0.0.1
Samsara
She/They
Senior Judge, Site Admin, Expert player (2241)
Joined: 11/13/2006
Posts: 2822
Location: Northern California
Man, all that effort paid off. Yes vote, great work!
TASvideos Admin and acting Senior Judge 💙 Currently unable to dedicate a lot of time to the site, taking care of family. Now infrequently posting on Bluesky
warmCabin wrote:
You shouldn't need a degree in computer science to get into this hobby.
Amaraticando
It/Its
Editor, Player (162)
Joined: 1/10/2012
Posts: 673
Location: Brazil
Who voted no could at least say the reason... It's a fantastic TAS who shaved off much more frames than I expected and is more entertaining than the AGDQ run. Easy yes vote.
Skilled player (1743)
Joined: 9/17/2009
Posts: 4986
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Does this need a branch name given it's the only one at the moment?
Experienced player (878)
Joined: 11/15/2010
Posts: 267
Technically as the first run it probably doesn't need a category, but I felt it was appropriate since it is very much a glitch category and I think you could easily publish a non-glitched movie along side it.
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
The problem with a game like this, that contains intentional glitches, is that it's hard to know what should count as a non-glitched movie. (On the other hand, I'm happy to see that none of the intentional glitches turned out to be useful in the end.) Hopefully we've managed to save this game from the vault; it looked like it was going there back at the time of the TAS competition, but eliminating basically the entirety of the intended gameplay is something that many players find entertaining (mostly because it stops the game overstaying its welcome).
Alyosha
He/Him
Editor, Emulator Coder, Expert player (3827)
Joined: 11/30/2014
Posts: 2834
Location: US
I originally didn't think this would be that interesting given the intended glitches, but you all managed to find something petty neat, awesome!
Editor, Expert player (2480)
Joined: 4/8/2005
Posts: 1573
Location: Gone for a year, just for varietyyyyyyyyy!!
it contains some intentional glitches
Isn't a glitch unintentional by definition? It might therefore be more accurate to say that the game contains... Uh-oh... I can't think of a word for it.
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
"misfeature" is a word that people use sometimes, although it's more to describe intended features that end up making the program worse, than intended features that make the game more exploitable. Perhaps we're looking for "backdoor"?
Editor, Expert player (2480)
Joined: 4/8/2005
Posts: 1573
Location: Gone for a year, just for varietyyyyyyyyy!!
iGlitch
sack_bot
He/Him
Player (112)
Joined: 11/27/2011
Posts: 394
Location: Massachusetts
Aqfaq wrote:
iGlitch
Please use something else
Message me here for my discord. Current Project: Psycho Waluigi Project on wait list: None?
Joined: 5/23/2014
Posts: 162
Trick? "Benefit" (with the quotes)? In regards to the actual run: I voted no. As interesting as save corruption can be, there's almost no gameplay left, and it's simple moving on an overworld outside the boss fight. Despite the fact I didn't find it entertaining, I do believe it should still be published.
Masterjun
He/Him
Site Developer, Expert player (2047)
Joined: 10/12/2010
Posts: 1185
Location: Germany
Still not entertaining enough for Moons, I think, but at least we got this game out of the way.
Warning: Might glitch to credits I will finish this ACE soon as possible (or will I?)
EgixBacon
He/Him
Player (184)
Joined: 4/15/2013
Posts: 331
Location: In the attic
I'm going to give this a Yes. It's nice to see that this game now has a TAS that does it justice (in terms of optimisation, at least). It may not be the most entertaining movie ever, but reading the sub text made me appreciate it all the more - the game was designed to prevent save corruption, but there was still a will and a way. One question: If this doesn't make it to Moons, would it be possible to do away with the branch name and just publish it to the Vault as an any% run?
FanFiction|Youtube Still on Win7! Take that, Microsoft!
Editor, Expert player (2372)
Joined: 5/15/2007
Posts: 3940
Location: Germany
The game was very lacklustre to be enjoyable to watch, but this run changed that. Good job How did you find the screen transition bug anyway?
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
MUGG wrote:
The game was very lacklustre to be enjoyable to watch, but this run changed that. Good job How did you find the screen transition bug anyway?
I was playtesting the AGDQ competition, under instructions to act as though it were the real competition run live. So although I was playing before everyone else, I was trying to create the fastest possible TAS for the game in four hours, and in particular, to create one that would beat everyone else. I decided that I wasn't good enough at TASing to be able to optimize either of the suggested routes better than the more established TASers who would (hypothetically) be competing against me, so I decided to take a high-risk option: I decided immediately that I'd spend the whole four hours lookjng for a save corruption bug. In terms of the bug itself, after a while spent looking at the save code disassembly, I realised that a checksum collision would cause the first of the three copies to be used, disregarding the other two, even if that copy was corrupted. Then it was a case of working out what the effects of resetting the console during the save would be (the answer is that the resulting save takes some bytes from the old save and some bytes from the new save, which is the most common outcome of doing that). My first thought was to go to the west of the final boss and the south of the final boss and merge the x screen-on-map coordinate of one save with the y screen-on-map coordinate of the other (this probably would have required a subframe-precision reset, but I didn't realise at the time that Bizhawk's input file format can't represent that). Unfortunately, I was stymied upon discovering that the game autosaved at every screen transition. So I tried to work out what exploitable effects you could get via merging two saves on adjacent screens. The most obvious thing to try was to load the character at the wrong side of the screen (via merging one screen's screen-on-map coordinates with the other's pixel-on-screen coordinates), and this turned out to work just fine. Even better, the huge amount of checksumming that the game does turned out to make the save corruption possible even on Bizhawk because it caused enough lag to place the writes of the two sets of coordinates we were merging on different frames from each other. (It's still possible that the run could be improved via a subframe-accuracy reset; you'd be able to manipulate some of the values we don't care about between the ones that we do care about, and that might randomly happen to make the checksum collision require waiting fewer frames.)
Editor, Skilled player (1824)
Joined: 8/25/2013
Posts: 1200
Giving this a No. It's great technical wise, but it's certainly not very entertaining.
effort on the first draft means less effort on any draft thereafter - some loser
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
Almost felt entertained but I’ll give it a meh. I liked the movement.
Invariel
He/Him
Editor, Site Developer, Player (171)
Joined: 8/11/2011
Posts: 539
Location: Toronto, Ontario
Masterjun's video shows that the hard mode map is stapled to the normal mode map -- so could you theoretically save corrupt yourself from normal into hard mode (or the other way), yes?
I am still the wizard that did it. "On my business card, I am a corporate president. In my mind, I am a game developer. But in my heart, I am a gamer." -- Satoru Iwata <scrimpy> at least I now know where every map, energy and save room in this game is
Experienced player (878)
Joined: 11/15/2010
Posts: 267
Invariel wrote:
Masterjun's video shows that the hard mode map is stapled to the normal mode map -- so could you theoretically save corrupt yourself from normal into hard mode (or the other way), yes?
No. You could definitely save corrupt you way onto the hard map, but it wouldn't be hard mode still since you wouldn't be changing the 'difficulty' flag at 0x39F (which the game uses to set enemy HP, etc.). You could change it with ACE, but that probably doesn't make much sense either since you could just use the save file name.
Invariel
He/Him
Editor, Site Developer, Player (171)
Joined: 8/11/2011
Posts: 539
Location: Toronto, Ontario
Alas. Thanks for the explanation.
I am still the wizard that did it. "On my business card, I am a corporate president. In my mind, I am a game developer. But in my heart, I am a gamer." -- Satoru Iwata <scrimpy> at least I now know where every map, energy and save room in this game is
Post subject: Movie published
TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15628
Location: 127.0.0.1
This movie has been published. The posts before this message apply to the submission, and posts after this message apply to the published movie. ---- [3073] NES Pwn Adventure Z "save glitch" by link_7777, BrunoVisnadi & ais523 in 01:30.87
Skilled player (1743)
Joined: 9/17/2009
Posts: 4986
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Finally watched it. That was quite boring. The only saving grace outside the music was the fact you managed to show that leaving a game filled with intentional bugs to appeal to speedrunning would still end up somewhat futile. lol Actually now that I think about it, is there some RTS-friendly way to do something similar?
Experienced player (878)
Joined: 11/15/2010
Posts: 267
jlun2 wrote:
Finally watched it. That was quite boring. The only saving grace outside the music was the fact you managed to show that leaving a game filled with intentional bugs to appeal to speedrunning would still end up somewhat futile. lol Actually now that I think about it, is there some RTS-friendly way to do something similar?
Not that I can think of. You could easily do ACE, but since the in-game timer is involved the save corruption would probably take upwards of 6 frame perfect inputs or bank on a 1/65536 CRC collision. Not RTS-friendly at all.
Joined: 1/13/2007
Posts: 343
Kinda silly for them to do the save in triplicate and not bother with comparison. For reference, the save corruption check for triplicate saves is ridiculously simple. Load save 1. compare each byte with save 2. if no difference is found, start game, if a difference is found, then copy the bytes from save 2 in starting at where the difference was. compare each byte in save 3 with save 2. if they are the same, start game. otherwise load first save and start game. Such a save system is foolproof, assuming that save corruption is a partial save.