- Emulator: BizHawk
- Emulator version: 2.4.1
- Profile: N64 Tool-assisted Speedruns
- Core type: Pure interpreter
- Video plugin: GLideN64 (default settings)
- Video resolution: 320x240
- Controllers: 1 and 3
Game version: JPN 1.0
Run goal
The goal of this TAS is to beat The Legend of Zelda: Ocarina of Time as fast as possible, without any restriction. This category is widely known as any%, and takes advantage of the Stale Reference Manipulation glitch to achieve Arbitrary Code Execution and reach the credits.
The Japanese version of the game was used because of faster text. The version 1.0 was chosen because the setup to manipulate the memory requires this version of the game.
Introduction
We all thought Ganondoor would remain the fastest way to beat the game... but we were wrong !
Since the
last official submission on this website, the
Get Item Manipulation glitch was found in 2015, which saved a little more than a minute according to this
unofficial TAS, but was not possible to do on Nintendo 64 under normal circumstances and required the usage of Rice video plugin to work on emulator. This route remained the same for years until a new major glitch has been found: the Stale Reference Manipulation glitch, or SRM for short. This glitch enables us to achieve Arbitrary Code Execution, or ACE for short, to warp straight to the credits. After this glitch was applied to any% mainly thanks to
MrCheeze's work, I made a TAS of it which ended up with a time of
6:54.27. However, there was one big problem with it: the route I used was intended to be used by speedrunners. Therefore, the advantages that TAS has over real-time speedrunning could not be exploited to save even more time. Moreover, I used the Mupen64 emulator which is banned from this website, because I was expecting this category to evolve since ACE was fairly new. Immediately after I published my TAS, Tharo contacted me and was motivated to work on a route that would take advantage of TAS powers to reach credits faster by using controller 1 and 3 inputs. After some failed attempts, we successfully found a setup that worked and avoided the game over, which itself saves about 12 seconds ! This time, I tried the Bizhawk emulator for the run to be publishable on this site since it is a big improvement. The final time for this run is 6:37.33, which is 16.94 seconds faster than my previous TAS, and 13 minutes and 32 seconds faster than the previous official submission on this website. Although the bk2 file indicates 9,432 re-records, it is actually much more than that because I reproduced some inputs from my previous TAS, which has 20,793 re-records. I think this new TAS also has around 20,000 re-records in reality.
The SRM glitch
In October 2019, Glitches0and0stuff noticed a weird behaviour of boomerang when changing rooms
while it is grabbing an object. We can observe that the object the boomerang is holding changed and was replaced by a door. Similar instances were also observed with bomchus in the past, notably one
back in 2007, over 12 years earlier. However, what changed over 12 years in the Ocarina of Time community is our tools to analyse the game that became way more sophisticated and enabled much deeper look into the memory of the game to understand this glitch. Interestingly, it was noticed that this glitch enables to write some data in some memory locations based on how it set up. By manipulating the structure of the memory, we can take advantage of this glitch to write specific data into a specific location to give special effects to objects. Only two weeks after Glitches0and0stuff's video, he found an interesting application that consists in
editing the chest contents. Two more weeks later, the
first instance of ACE was achieved, and another month later,
Total Control ACE was achieved which truly broke all limits of the game.
Route description
This part has been written by Tharo and is going to explain in detail how this route exploits the SRM glitch to reach the credits:
- Actor
- A dynamic, interactive game entity whose state may evolve during gameplay. For example: Link, Kokiri Children, Rocks and Signs
- Actor Heap
- The dynamic memory arena in which Actor Instances and Overlays, and possibly other data can be found
- Actor Instance
- Data pertaining to a particular instance of an actor, one of these is loaded for each actor and contains data common to all actors (position, rotation, flags, etc.) and specific data (i.e. in Link, information for his shield hitbox)
- Actor Overlay
- The file in which an actor's code and data that is the same for all actors of that type is stored. Only one of these is allocated for all actors of the same type.
- MIPS
- The CPU Architecture of the Nintendo 64. It defines the assembly instruction set used by the CPU.
- Culling
- Actors that are sufficiently far off camera will not update or draw.
- Wonder Item
- An actor present in Kokiri Forest responsible for handling giving you blue rupees for jumping the platforms in time.
- Cutscene Pointer
- A reference to tell the game where the data for the cutscene currently being played is located.
- Stale Reference Manipulation (SRM)
- A use-after-free bug which allows us to continue writing data to actors that are no longer loaded. There are several ways in which this can be achieved but in this run we only use held actor SRM. If an actor is grabbed by link but is culled and subsequently unloaded, the reference to this actor is not invalidated and data such as position and rotation values are still written to where this actor used to be located in memory. If something new loads into the space the grabbed actor's instance used to occupy, those values still being written will corrupt the newly loaded entity in possibly useful ways.
Throughout the run, actions are performed to set up the game's dynamic memory arena in an effort to line up a MIPS branch instruction with the rotation value written with SRM in order to redirect it to a location in memory where we can write our own code. By shuffling different actors around in memory with the methods described below, we can align where we write with SRM with actor overlay code and modify that code to our benefit.
By collecting permanent rupees in Kokiri Forest, more free space will be available leading to different permutations of heap entities.
There is a loading transition between the Deku Tree clearing and the Kokiri village which unloads actors in one area and loads new actors for the other. This can be exploited to shuffle actors around in memory even further. By traversing this loading transition several times with a combination of charging a spin attack (which loads its own actor)/not charging a spin attack and looking towards Mido/looking away from Mido (as some allocations are sensitive to camera angle) we can move everything into the correct positions in memory for later.
Getting Walking While Talking off the crawlspace and sign, we load the circle of rocks near Mido's House. We cancel Return A by slashing our sword and recoiling off a rock, making the camera begin to zoom out towards the crawlspace. Before it gets too far away, we pick up the rock which culls soon after due to the camera getting too far away. The rock we pick up is the one that results in the grabbed actor reference eventually lining up the way we want.
With the culled rock held we make our way blind through the loading transition, which unloads the rock and allows new entities to allocate into this space, achieving SRM.
We traverse the loading plane once more to return to the village area and shield-drop the rock in the angle range 0x821A to 0x8245 to corrupt a branch instruction in the Wonder Item actor overlay to point into Link's actor instance.
We point the branch instruction to direct execution onto two adjacent 16-bit values, both of which we manipulate into a single valid MIPS instruction beforehand. These values are the "movement angle", the angle Link last moved towards, and the "target angle", the angle link last targeted or used a spin attack towards.
We manipulate these angles such that they form 080475E4, which is `J 0x8011D790`, or "Jump to 0x8011D790"
Located at address 0x8011D790 is the most recently polled inputs from each controller, with some additional status information. Only controllers 1 and 3 are polled by the retail releases of the game, controller 3 being available to delete save data in the event of a corruption by an input code. Each controller is 6 bytes long, 4 of which are the inputs themselves. Since MIPS instructions are all 4 bytes long and must start at an address that is a multiple of 4, we can only trivially form two instructions from both Controller 1 and Controller 3's input as they are the only ones that align properly, so not being able to use Controller 2 and 4 is not especially impactful.
With controller 1, we perform arithmetic on the N64's GP Register (Global Pointer) which goes unused by the game due to the settings it was compiled with. This gives us a useful temporary space in which to load values to and then store them where we want on the next
frame. However, we can only hold one temporary value at a time and not all load/store instructions are available with the possible inputs we can form with controller button presses.
With controller 3, we run another jump instruction to safely resume game execution to prevent crashing on invalid instructions following our carefully crafted controller input values.
The controller inputs we perform at this stage are as follows:
Controllers (FORMAT: Number: Buttons, (StickX, StickY) ; Hex Value ; MIPS Instruction)
Frame 1: (Loads the first value to store to the Cutscene Pointer)
1: Z, D-Down, R, C-Up, C-Down, (-16, -16) ; 0x241CF0F0 ; ADDIU gp r0 0xF0F0 ; Adds the value 0xF0F0 to zero and stores the result in GP
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
Frame 2: (Stores lower half to cutscene pointer)
1: A, Z, D-Down, D-Left, L, R, C-Up, C-Down (29, 106) ; 0xA63C1D6A ; SH gp 0x1D6A(s1) ; Stores the value in GP to s1 + 0x1D6A
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
Frame 3: (Loads the second value to store to the Cutscene Pointer)
1: Z, D-Down, R, C-Up, C-Down, (-128, 55) ; 0x241C8037 ; ADDIU gp r0 0x8037 ; Adds the value 0x8037 to zero and stores the result in GP
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
Frame 4: (Store upper half to cutscene pointer)
1: A, Z, D-Down, D-Left, L, R, C-Up, C-Down (29, 104) ; 0xA63C1D68 ; SH gp 0x1D68(s1) ; Stores the value in GP to s1 + 0x1D68
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
Frame 5: (loads the cutscene value to store to current cutscene)
1: Z, D-Down, R, C-Up, C-Down, (-1, -3) ; 0x241CFFFD ; ADDIU gp r0 0xFFFD ; Adds the value 0xFFFD to zero and stores the result in GP
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
Frame 6: (stores cutscene value to current cutscene)
1: A, Z, D-Down, L, R, C-Up, C-Down (-91, -38) ; 0xA43CA5DA ; SH gp 0xA5DA(at) ; Stores the value in GP to at + 0xA5DA
3: D-Up, C-Left, C-Right, (94, -69) ; 0x08035EBB ; J 0x800D7AEC ; Jump to 0x800D7AEC
The registers at and s1, at the time of jumping to controller inputs, have the values:
- at = FFFFFFFF 80120000 | Intermediate value for accessing game save data beginning at 8011A5D0
- s1 = FFFFFFFF 801C84A0 | Pointer to the "Global Context", containing information about the current state of the game.
At address 0x800D7AEC is code to restore the stack pointer by the required amount and a jump to the return address register to resume normal execution.
The code we execute here is to load two halves of the address at which one of the two Kokiri Forest credits cutscenes is at and store them to the Cutscene Pointer. Once this is done, we store 0xFFFD to the "current cutscene" value, causing the credits to immediately play, ending the run.
Rupee route
In order to perform SRM, the sword, the shield and Deku nuts are needed. The shield and Deku nuts must be bought for 55 rupees. To collect this amount, a route has to be chosen with some constraints. First of all, as Tharo explained in the previous section, this route requires to collect all permanent rupees in the Kokiri area in order to set up the memory. These rupees themselves make 22 rupees. Another constraint is that we also have some rupees that are directly on the way and that require extremely little to no time to get. These rupees make another 15 rupees. Therefore, we already have 37 rupees collected normally. The remaining 18 rupees have to be collected among rupees that can be reached without loosing a significant amount of time. The map below (taken from
https://www.vgmaps.com/Atlas/N64/ and edited by me) sums up the situation.
We see an interesting option here. We can manipulate bushes so that they always give 3 rupees (1/16 chance). Fortunately, 18 is a multiple of 3 so 6 perfect bushes just fulfils the rupee requirement. Moreover, they are also on the way to the hidden permanent blue rupee located in the sign.
When Tharo was adapting MrCheeze's route for this TAS, I suggested him to research for a way to skip the permanent blue rupee on the bridge, as well as the permanent blue rupee behind Mido's house. The reason is because both of these rupees take too much time to collect. Notably, it is possible to compensate these 10 rupees by taking the blue rupee near the bush in the sword area and the blue rupee in the shop. Unfortunately, no setup was found after researching with simulation tools. I even suggested to check the versions 1.1 and 1.2 of the game to see if they are different enough to permit a setup, but it turns out they are not different enough to have different setups.
Section by section
Filename:
From my previous TAS, we notice that I no longer put a special filename. This is because Tharo's adaptation of the route bypassed this requirement.
Link's house -> Crawlspace:
This section is very straight-forward since it has been optimised since years. I only had to redo inputs from my previous TAS for this part.
Crawlspace -> Sword:
We notice here that I did different movements than traditional TASes to reach the blue rupee. These differences did not end up saving time since going any faster would result in link hitting the rolling rock. However, I managed to save 6 frames over MrGrunz and Bloobiebla's TAS from the blue rupee until the sword chest. This improvement comes from the fact that I somehow got a good positioning before the last turn that enabled me to not have to walk for 6 frames before the last sidehop to reach the chest.
Sword -> Crawlspace:
After the sword the movement remains the same in my previous TAS until the crawlspace, which ties traditional TASes as well.
Rupee collection:
This section is one of the hardest of the run. Although I explained earlier which rupees should be collected, it was also needed to find the order in which they should be collected. The beginning is straight-forward since Link is just in front of the bushes and the hidden permanent rupee. RNG was manipulated such that 3 rupees always spawn. We notice that, like in my previous TAS, I was able to cut 3 bushes with a single slash and 2 of them spawned 3 rupees. Unfortunately, I was not able to find a good reachable RNG for which I wouldn't have to cut that extra bush (because cutting a bush creates a lag of 3 frames). I was neither able to reproduce such luck elsewhere that would cut 2 bushes. Overall, I manipulated the RNG better than in my previous TAS, which lead to faster movements and saved about 19 frames.
After the bushes are cut and the hidden blue rupee taken, I tried a new route I did not try on my previous TAS: instead of going for the blue rupee behind Mido's house first and then the blue rupee on the bridge, I was thinking of doing the opposite. My motive was that I thought that it could be possible to
WESS after collecting the bridge rupee to clip inside the house and get the last permanent blue rupee from out of bounds. This house clip has been known for quite some years, but was only used to get to Lost Woods faster. The advantage of this new route is that we can get to this rupee faster and we also avoid a ledge grab.
To take the blue rupee on the bridge, there is a clip found many years ago that speedrunners have always been using, but never used in TAS because of the time it takes to take it. By jumpslashing at a specific frame, Link is popped on top of the bridge because he is close enough of the floor. After that, something interesting is done to grab the blue rupee optimally: there is a girl next to the blue rupee, consequently, if you press A to sidehop to the stone to WESS just after collecting the rupee, Link will instead talk to the girl because the rupee hitbox is located within the range where Link can talk. To counter this problem, I take advantage of how forward slashing works (holding the joystick to the front of Link and pressing Z and B). This type of slash makes Link go backward for 1 frame, and suddenly forward with high speed for a brief amount of time. The frame where Link goes backward is enough to grab the rupee, and the forward boost makes link go forward enough to be outside the range of the girl. This method is much faster than walking to the blue rupee, turning and walking to exit the range. That trick was also done in my previous TAS. After that, I keep the same angle and do a twisted sidehop in order to sidehop diagonally and jumpslash at the perfect frame to barely hit the stone and barely enter in the water to perform the WESS.
Clipping inside the house with WESS speed is more precise than with SuperSlide or HESS speed since it is a much lower speed. It requires not only a good angle, but also a good positioning that is gotten by changing angle at the correct moment and is more precise than it looks. Once we clip inside the house, getting to the rupee is tricky. The wall where we normally ledge grab extends inside the house as well and normally requires grabbing it. However, the house collision also extends behind this wall on the left side of the house (see the screenshots below).
This house collision is very helpful because it causes an unwanted effect which is, if you have sufficient speed, it is possible that the house collision pushes link out of bounds and completely ignores the wall collision. Sidehopping gives sufficient speed for this. Similarly to the bridge clip, since Link is close enough of the floor above him, he is popped up and we then collect the rupee without grabbing any ledge.
The last rupees are then collected and something interesting happened when I was doing the last sidehop to go the shop. Thanks to the very good positioning I had on the stones, I was able to land extremely close to the shop loading zone. So close that doing a vertical slash forward was the fastest way to enter in it and was 3 frames faster than anything else. Until this point (since the hidden blue rupee in the sign), about 131 frames have been saved compared to my previous TAS: 74 frames come from the new rupee collection order and about 57 come from avoiding to call Navi, because this new any% route does not need to go to first person during ACE anymore.
Shop -> Deku tree area:
After buying Deku nuts and the shield and exiting the shop, I do another WESS to get to Mido that I took from my previous TAS since it was already optimal. This WESS does not save a big amount of time, but it is still faster and very cool too. Unfortunately, we cannot skip Mido like in MrGrunz and Bloobiebla's TAS because later in the run, during the Walking While Talking glitch that will be performed later, Mido's collision will remain and there is no way to skip Mido while holding a rock.
Once we get past this guy, we start the heap manipulation to setup the memory. For that, we need to cross several times the transition between the forest area and the Deku tree area. A map of transitions and area can be found below:
However, we need to cross them in a special way: during some transitions, it is necessary to have Mido unloaded or loaded. When he needs to be loaded, the camera should be directed towards the forest, and directed towards the Deku tree otherwise. Moreover, during some transitions, it is also necessary to cross the transition while charging a spin attack, in order to cross the transition with this actor loaded. However, while making my previous TAS, I noticed that if Link does a forward slash, the actor spawns and link can walk for just one frame before starting to charge the sword. So when a transition should be crossed using a spin attack, I get Link close enough of the transition, do the forward slash, and during that frame of walking, cross the transition and immediately release B. By doing this, Link will still crouch and the memory set correctly, but Link will not spin attack, which saves time.
Once I reach the last transition from the forest area to the Deku tree area, I perform a glitch called Return A which will be useful later. It is done by pressing Z, R and C-up at the same frame and having a damage source hit the shield at the first possible frame. We can also note that from the shop until the last transition, 3 frames have been lost compared to my previous TAS although I kept the exact same inputs. This is likely due to emulation differences during the transition from Deku area to the Forest area that is longer on Bizhawk.
Deku babas -> Crawlspace:
The goal is now to get to the crawlspace for the next glitch that will come. In order to get there, the first idea is to go there normally by sidehopping. However, in TAS, we can take advantage of the damage source from the Deku baba to perform an
A-Slide which gives link a speed of -18 to get to the platform near Mido faster (for reference, walking speed is 5.5 as child and sidehop speed is 8.5). The disadvantage of A-Slide is that the angle can be changed in a limited way without loosing speed, and requires loosing speed to change even further than a certain limit, +2 of speed every walking frame to be exact. Normally, we can also perform an
HESS out of a Deku baba as well because of its special way to deal damage. The advantage of HESS is that we can change angle and thus reach the crawlspace extremely fast. However, the Return A glitch gets cancelled if Link takes damage at low speed (has the knockback animation), which is a necessary step to perform an HESS, and can therefore not be done.
Because of the limited angle change A-Slide offers, I can keep the maximum speed until the corner, and then I change my angle in a first time without loosing speed, and walk for one frame to trade 2 of speed for a better angle (so we now have a speed of -16) and we keep the speed thanks to Z-Sliding until the very edge of the platform. Once we reach the end of the platform, we have no choice to sidehop until our goal. It should be noted that we also cannot enter in the water as it also cancels the Return A glitch, so we cannot do a WESS neither to reach the crawlspace faster. We might notice that I used a slightly different path in this version of the TAS than in my previous one because I did not try this path before, but it ended up being tied.
Crawlspace -> Rocks:
After Link exits the crawlspace, we have little time to sidehop to the sign and read it while throwing a Deku nut. This glitch is known as
Walking While Talking. Under normal circumstances, doing this glitch would stick the camera to the sign as seen in
this video. Because of the camera position, the rocks next to Mido's house cannot load and so, cannot be picked up. Thankfully, the Return A glitch we did earlier enable the camera to continue following Link. Now, we target the sign in order to change Link's angle to backflip through the fence. You may notice that I paused before the backflip. That is because if I press A without having paused beforehand, Link will try to read the sign no matter the distance and will softlock the game. Once we get past the fence, the goal is to get to these rocks, however, for memory to be set up correctly, it necessary that the sign regenerate before these rocks load. A sign regenerates either by playing Zelda's lullaby, which we cannot do here, or either by getting far enough of it. Normally, going directly to the rocks would load them before the sign regenerates, which will result in ACE failing. However, when making my previous TAS, with some camera manipulation, I managed to somehow regenerate the sign before rocks load while still going straight into them, which saves a good amount of time. When we reach the rocks, I have to slash and pick up one rock in particular that is located exactly where we want in memory. Slashing a rock or falling from a ledge has the effect of cancelling the Return A glitch while keeping the Walking While Talking glitch, so the camera will behave like normal and try to stick to the sign. Because of this, the camera gets too far away of the rocks to remain loaded, however, I pressed A to pick up the rock just before they unload, so we are now carrying an unloaded rock. On this section, I saved 9 frames compared to my previous TAS because I somehow got a better sidehop angle which got Link closer of the rock, so it could be slashed earlier.
Rocks -> Deku tree area:
The next step to achieve ACE is to bring Link to the Deku tree area while holding the unloaded rock. For that we might think of several paths. It should be noted that Link can also jump, but not very high. In my previous TAS, I used a path that seemed to be the most optimal, however, I somehow forgot to consider the possibility of jumping to land on the wonder item platform near Mido which seems to be a faster path to the Deku tree area. Finally, I tried this possibility and it ended up being 56 frames quicker.
To navigate blindly through the forest, I used Link's position at some checkpoints and found the angle that had to be held to go straight to the checkpoint. The map below shows the path of both TAS including jumping parts and checkpoints I used.
Reaching credits:
Once Link reaches the Deku tree area transition, the camera snaps back towards Link. However, this does not completely cancel the Walking While Talking glitch because the effect of the Z button (i.e. targeting) is disabled. The next step consists of going back to the Forest area and dropping the rock at a certain angle range (explained earlier by Tharo). The range is pretty big and was obtained easily. In addition, 11 frames have been saved from the previous TAS on this small section because of better movement that turned the camera faster towards the wonder item actor. After that, a value that stores the last target angle has to be set to a single possible value which is 75E4 (or 30180 in decimal). For reference, there are 2^16, or 65536 angle values that Link can have. Since Z targeting no longer works, the only way to set the value is to charge a spin attack (without necessarily attacking). With precise movement prior to slashing the sword, I was able to manipulate the camera in a way that made this value reachable. The last step is now to look at the wonder item actor with an angle of 0804 (or 2052 in decimal). Looking at the wonder item with any other angle will result in a crash. After the spin, the wonder item is not yet looked at which lets time to set up the angle. The map below shows where it is located.
Unfortunately, there was no possible joystick angle that resulted in the desired Link angle directly. But fortunately, once the camera starts to turn towards the wonder item, there was still 3 visual frames (9 frames) before the wonder item runs the code. On the first frame the camera turned, I was able to find a joystick angle that worked just fine and thus, did not loose time. Once the wonder item is looked at, I use the controller 1 and 3 and followed what Tharo wrote for joystick values and buttons to press which lead to credits.
On a funny note, I threw a Deku nut just one frame before the wonder item code started to give the allusion of using Deku nuts to wrong warp to credits, similarly to how Sheik uses Deku nuts to disappear.
And that's how you save Hyrule in just 3 minutes !
Special thanks
First of all, big thanks to the analysers of this game for understanding the power of SRM that made this route possible and for finding an application of SRM for any%. These are, but not only limited to,
Glitches0and0stuff,
Fig,
Tharo,
MrCheeze,
blini,
natalyahasdied and probably even more.
Special thanks to MrCheeze for finding the initial setup for ACE used in my previous TAS.
Special thanks to Tharo for adapting MrCheeze's route for TAS to reach the credits faster.
Suggested screenshots
Frame 15759:
Frame 16698:
Frame 20301:
Feel free to propose more and vote for the best one !
Note: Screenshots were taken with the lowest resolution: 320x240 because it is the only one that syncs. Higher resolution should be provided if published.
Memory: There are no signs of any mistakes.
The movie was entertaining, featuring some interesting movement but the main draw is obviously the game end glitch.
There were questions as to whether or not this should obsolete the current run. This run visits a fair amount of fewer areas than the current run and there’s some different glitches exploited.
Accepting to Moons as a new branch.
Memory: Adding geg branch label.