Lets Build Ocarina of Time Part 1
Exploring the OoT Decomp Code
Hi, my name is Joshua Walton! I’m a full-stack developer that wants to learn Rust, and I figure, what better way to learn a language than by trying to program your favorite game in it? In this series of articles, we will explore the Ocarina of Time decompilation code and see if we can glean an understanding of it. Then, we will begin to build our own Ocarina of Time in Rust!
For instructions on how to compile, clone, and use the decompilation code, please check the project's github at https://github.com/zeldaret/oot. I'm using the Docker instructions on my MacBook Pro.
To get started, I want to find something in the code that I can conceptualize/understand in the context of the gameplay. I am very familiar with the way that Link–as the player in the game– moves, behaves, and interacts with the environment. Therefore, I want to try and find code in the game that corresponds with my understanding of Link as the player.
So let’s take a look at the code:
As you can see from the directory structure of the project, there is a location just for the code. Let’s look through this folder and see what we can find:
Towards the bottom of the code folder, we can find a few files that relate to the player: z_player_call.c and z_player_lib.c. Let’s open both and see if we can find anything that we can immediately understand/infer is related to our understanding of how we play as Link.
Here is z_player_call.c:
After looking at this file for a minute or so, I don’t see anything that really stands out to me. It’s not immediately obvious what this code does for Link while we are controlling/playing the game. It does seem to initialize some things that are useful for the player, but again, not sure what exactly that means at the present moment. Let’s try the other file.
Here is the top of z_player_lib.c:
Looking at this file already, we see something that is familiar to our experience as the player: sBootData. We know that Link can change what boots that he wears, so maybe this sBootData array describes some characteristics about the boots.
If we check the definition of PLAYER_BOOTS_MAX, we can see that it is equal to 6. This means that there are “6 boots” available to the player, which is not what we would expect considering that Link only has 3 boots to choose from in the game. Also, what are these numbers anyway? We have no idea what they do just by looking at this array, but maybe we can figure it out by looking at where this array is used elsewhere in the code.
If you scroll further down in this file, you will eventually come to the following function:
So there is a lot going on in this function, some of which is still not very obvious what it is doing.
There is, however, something immediately obvious: the code is initializing the variable currentBoots,
which is coming from the Player object. We can infer from this that the Player object is Link’s current state,
and that currentBoots will be whatever Link is currently wearing in-game.
The code then checks to see if the currentBoots is one of four types: PLAYER_BOOTS_KOKIRI, PLAYER_BOOTS_KOKIRI_CHILD,
PLAYER_BOOTS_IRON and PLAYER_BOOTS_IRON_UNDERWATER. These are all enum values that correspond directly to a number.
This means that currentBoots must also be a number. This is useful information, because we can see that we are
indexing sBootData, which we know is an array, with currentBoots. Therefore, we can conclude that there are in
fact 6 different types of boots in the game, but after reading this code, we can now see that the iron boots have
two different configurations as well as the Kokiri boots.
We can use the information we just figured out to go back and label sBootData so we can understand it better.
Let’s go to where PLAYER_BOOTS_KOKIRI is defined to gather the numerical values of these variables:
We can see that PLAYER_BOOTS_KOKIRI has a numerical value of 0. Knowing this, we can go back to the sBootData array and comment it for our own understanding:
Let’s go ahead and do the same for all of the values:
Great! We've managed to figure out values we can modify for each type of boot in the game. In the next article, we will modify these values to try and figure out what each of them actually mean for the player's behavior.
The Ocarina of Time code comes from https://github.com/zeldaret/oot and is thanks to the hard work of many open-source developers. Please consider supporting their awesome work.