Learn how to install the Zelda Ocarina of Time Decompilation Project step by step.
This guide walks you through setting up WSL and Ubuntu, cloning the repo, installing required packages, and building the project from source. Whether you’re looking to dive deep into game code or create advanced Zelda mods, this tutorial is your first step into the powerful world of decomp-based modding.
What is the Zelda Decomp Project?
Install WSL & Ubuntu
Install Zelda OoT Decomp Project
Get The Master Quest Debug Rom
Extract Rom
Test Rom
Understanding The File Structure
Important Files
Useful Files To Explore
Ubuntu Make Commands
Setup The Decomp For Modding
1st Mod: Changing a Hyrule Sign
Change How The Game Starts
Create a Map With Fast64
What is the
Zelda Decompilation Project
The Zelda Ocarina of Time Decompilation Project is a fan-led effort to reverse-engineer the game’s original source code into readable C code. This opens up powerful new possibilities for modding.
2 main ways to create Zelda Oot Mods:
#1 SharpOcarina (BEGINNER)
#2 Using the Zelda OoT Decomp Project.
(MORE ADVANCED)
While Sharp Ocarina is more beginner-friendly, the decomp method offers far greater control and flexibility—allowing advanced users to modify game logic, add new mechanics, and even port the game to different platforms.
Install WSL & Ubuntu
First, we will need to install WSL (Windows Subsystem for Linux) and Ubuntu on your computer.
WSL is a compatibility layer that allows you to run a Linux environment directly within Windows without the need for a virtual machine or dual boot setup.
Ubuntu is a popular Linux distribution that will provide the tools and environment necessary to compile and build the Zelda Ocarina of Time decompilation project.
This setup ensures compatibility with the development tools used in the decomp community and makes the compilation process much smoother on Windows systems.
2. Type: wsl --install
This will download and install both WSL and Ubuntu.
You made need to restart, I had to install it twice to get it to work. If it worked you should be able to see it inside the start menu when searching for it.
3. Open Ubuntu: Just be a new terminal with some green text.
At this point you will need to create a username and password. Make sure you remember it.
How to Install
Zelda Oot Decompilation Project
4. Type Into Ubuntu Terminal:
git clone https://github.com/zeldaret/oot.git
The repository is installed in your computer. There will be a new Linux section in windows explorer with a little penquin icon next to the word Linux. Click that.
You will find you zelda decomp folder installed here:
\\wsl.localhost\Ubuntu\home\your-name\oot
5. Install needed packages
The decomp is not fully installed we need to install a bunch of other packages.
In Ubuntu Change the directory to our decomp folder.
Type: cd oot
Each time you open Ubuntu you will need to change the directory to your oot folder.
Type: sudo apt-get update
You might need to enter the password you set up at this point.
Type: sudo apt-get install git build-essential binutils-mips-linux-gnu python3 python3-pip python3-venv libpng-dev
Type: sudo apt-get update
Type: sudo apt-get install gcc-mips-linux-gnu
Type: sudo apt-get install libxml2-dev.
Get The Master Quest Debug Rom
This video includes a link to all Zelda OotMQ Debug Roms in bps form in the YouTube description. Also includes tools to patch them to the regular rom that you can find on the internet pretty easily.
By Bruce Shankle
Download the BPS patches from the video.
Apply BPS patches to an OoT 1.0 (U) rom using the flips.exe file included in the download. Make sure to use the ZELOOTMA file.
After applying the patch add a copy of the Master Quest (Debug) ROM inside the baseroms/gc-eu-mq-dbg/ folder. The ROM needs to be renamed baserom.z64
6. Extract everything from the rom by typing:
make setup -j
Once it’s done, we’ll do the final step run:make -j
There will be a crazy amount of text flying around on the terminal for a bit.
If you get a build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.z64: OK The decomp was installed correctly on your computer.
There should also be a new rom created in this folder\\wsl.localhost\Ubuntu\home\your-name\oot\build\gc-eu-mq-dbg\oot-gc-eu-mq-dbg.z64
7. Test New Rom
Try to open the newly generated ROM called zelda_ocarina_mq_dbg.z64 with the project64 emulator.
Make sure to set the memory size to 8MB in your emulator’s settings. Options >> Configuration
If the Zelda Master Quest intro plays with the moon falling and Link galloping on Epona, then everything’s set up correctly!
Understanding Zelda Oot Decomp File Structure
In this project, we’ll primarily work with the src, assets, extracted, and include folders, as they contain the main code and editable content. The other folders are used less frequently and are typically only needed for advanced modifications or setup tasks.
.Git
.git directory is the core of any Git repository—it stores all the essential data for tracking your project’s history. From managing branches and tags to handling configurations and staging changes, this hidden folder contains everything Git needs to monitor and control your code versions. In essence, it powers the entire version control system.Assets
assets folder contains the visual and audio elements of the game—like text, models, and maps—which define how the game looks and sounds but aren’t part of the code. These can be modified to create custom content such as new characters or maps. In the decomp project, assets begin as XML files, which are converted during compilation into usable formats stored in the extracted subfolder.Baserom
The baserom is a directory that contains an original, unmodified ROM file, typically used as the foundation for game modding. In retro gaming and ROM hacking, this untouched file serves as the reference point for all changes. It allows patches or modifications to be applied cleanly, ensuring stability and compatibility throughout the development process.
Build
build folder in a decomp project stores all files generated during compilation, including compiled binaries, libraries, and other outputs. It plays a key role in keeping the main directory clean by separating source code from build artifacts. Essentially, this folder contains the files required for the game to run. Source files like .c and .h can be edited, and during compilation, they are transformed into .o (object) files. These .o files are crucial for the game’s functionality but cannot be modified directly.Docs
This subfolder includes highly technical documentation intended for advanced users and developers. It contains files like BUILDING_DOCKER.md, BUILDING_MACOS.md, compilers.md, decompiling_tutorial.md, Documenting.md, retail_versions.md, and vscode.md, each covering specific topics related to building, documenting, or working with the decomp project on various platforms and environments.
Src
The src folder is the heart of the repository, containing all the game’s source code. Here, you can create or modify characters, objects, shops, and other gameplay elements. There are two main types of code:
- Actors – Interactive characters or objects within the game (we’ll cover these in detail later).
- Game functions – Systems like weather, HUD, minimaps, and other core features.
Extracted
extracted folder holds game assets that have been processed and extracted for use. These files can be modified or replaced, making this folder especially important when developing a ROM hack.Include
include folder typically contains header files, which hold essential declarations such as functions, constants, and data structures used throughout the code. It plays a key role when adding new functionality to the project, as this is where new functions are declared. We’ll go into more detail on this later.Tools
tools folder in a decomp project contains utilities and scripts that support decompilation, modification, and project management. It includes programs for tasks like asset processing, code generation, and custom workflows. This folder is rarely used unless you’re adding new systems—like a custom audio engine or build step.Important Files
Makefile
Makefile is a script used to build the project with commands like make, make clean, and make distclean. It handles file dependencies and ensures only updated parts of the code are recompiled, saving time during development. For instance, you can modify the Makefile to add a custom command—like one that builds the game specifically for the Wii Virtual Console.Spec
spec file defines which source files should be compiled to build the final game. It becomes especially important when adding new files to the project—for example, when creating new actors. By listing these files in the spec file, you ensure they’re included in the build process.Useful Files To Explore In Zelda Decomp Project
Actor Files
Contains the C source files for all in-game actors, dynamic objects, characters, enemies, items, and environmental features. Each subfolder represents a specific actor (e.g., En_Goron, Bg_Tree), and includes the actor’s initialization code, update logic, and rendering functions.
File Location:oot/src/overlays/actors
List Zelda OoT Actor Files – Includes photos and explanations of what each file does.
Object Assets
File Location:
oot/assets/objects/
Scene Data
Scene headers, metadata, and initial setups for maps/dungeons.
File Location:oot/assets/scenes/
Room layouts, collision data, and environment settings.
File Location:oot/assets/maps/
scene_table.h
Contains the scene table, which defines all the game’s locations (like Kokiri Forest, Hyrule Field, dungeons) using entries with metadata such as file names, entrance indices, and map settings. This table is essential for linking scene IDs to their corresponding map data and loading logic.
File Location:oot/include/tables/scene_table.h
entrance_table.h
Maps entrance indices to specific scenes, spawn points, and player starting positions. Each entry defines where the player appears when entering a scene, including the exact coordinates, orientation, and transition type.
File Location:oot\include\tables\entrance_table.h
z_select.c
Implements the debug Map Select screen. Menu, which lets you jump directly to any scene and entrance in the game for debugging. It includes a scrollable list of all available scenes, handles input for selecting entries, and starts the game at the chosen location with optional parameters like cutscene or age.
File Location:oot\src\overlays\gamestates\ovl_select\z_select.c
message_data.h
Each message is identified by a unique ID (like 0x033A) and contains control codes for formatting, colors, and player input prompts.
File Location:
oot/extracted/gc-eu-mq-dbg/text
Compiled message & font assets:
assets/text/
Player
Helper functions used by the player actor (Player) for movement, animation, item handling, and interaction with the environment. It acts as a utility library supporting z_player.c, abstracting common logic like camera targeting, swimming, climbing, and equipment checks.
File Location:oot/src/code/z_player_lib.c
Main source file for the Player actor (Link). Handles controls, animations, interactions, etc.
File Location:oot/src/overlays/actors/player/z_player.c
z64item
File Location:
oot/include/z64item.h
z_sram.c
File Location:
oot\src\code\z_sram.c
Ubuntu Make Commands
In this section, we’ll go over the essential commands used in Ubuntu.
This is a key part of the guide, as these commands are used frequently throughout the project.
Make Setup
The make setup command extracts XML files from the game and converts them into usable assets for ROM hacking. It’s one of the first commands you should run at the start of the project, and it should also be used after running make clean.
Make
The make command compiles the project files and builds the game. You should run this command after using make setup or whenever you modify source or asset files.
Make Clean
The make clean command deletes the generated .o (object) files created during compilation. It’s commonly used when encountering build or programming issues, as it can help resolve problems by forcing a fresh rebuild.
Make Distclean
The make distclean command resets all extracted assets back to their original state. It’s rarely used and typically only needed when you encounter asset-related issues that can’t be fixed by other commands.
Warning: Using this command will permanently delete any custom or modified assets created by modders. If you need to run make distclean, it’s strongly recommended to back up your modified files beforehand to avoid losing your work. If you completely mess something up its a good way to start from scratch with a clean decomp install.
Most of the time, you’ll be using the commands make, make setup, and make clean. Among these, make is used to start the build process—but since there are a large number of files to compile, it can be time-consuming. In many cases, running make alone can take 10 minutes or more. Fortunately, there’s a way to speed things up. The faster and more powerful your computer, the more you can take advantage of parallel processing to reduce build time.
nproc
To speed up the build process, you’ll need to find out how many threads your CPU can handle. This determines how many tasks can be compiled in parallel. To check this in Ubuntu, simply enter the following command:
make -jN
You can use the command make -jN to speed up the build, where N is the number of threads your CPU can handle (as determined by the nproc command).
make -j18
It’s generally recommended not to use all available threads, but rather a large portion of them to avoid overloading your system. For example, if your CPU supports 20 threads, you might use 18 by running:
make setup -j18
make -j18
Note that for make clean and make distclean, you don’t need to specify the number of threads, as these commands simply remove files and execute quickly:
make clean
make distclean
Enough about commands—let’s move on to the next section, where we’ll begin working with the actual decompilation!
How to Setup The Decomp For Modding
As we begin setting up the decompilation, there are a few important configurations to ensure everything runs smoothly. The first step is to edit the Makefile. Open Visual Studio Code, navigate to your project folder, and open the Makefile to begin making the necessary changes.
oot/Makefile
On line 17 of the Makefile, you’ll see the following line:
COMPARE ?= 1
You need to change it to:
COMPARE ?= 0
This disables comparison with the original ROM, which can help avoid errors during the early stages of setting up your project.
On line 19 of this file, you’ll find:
NON_MATCHING ?= 0
You need to change it to:
NON_MATCHING ?= 1
This will allow the make command to account for modified files.
To build the project efficiently, we need a reliable compiler. By default, the Makefile uses ido, as shown on line 23:
COMPILER ?= ido
We’ll replace this with gcc, a more modern and performant compiler. Change the line to:
COMPILER ?= gcc
Using gcc offers several advantages—it provides more detailed warnings about your code changes, helping you catch and fix issues early. It also supports newer C language features that ido does not.
Now that we’ve made the necessary changes, it’s time to compile the project so those changes take effect. In Ubuntu, run the following commands:
make clean
make -jN # Replace N with the number of threads you want to use
Note: We run make clean here because we edited files like the Makefile. You don’t need to use make clean every time—just when modifying non-source files that affect the build process.
If these edits hadn’t been made, you would have encountered an error like this during compilation:
WARNING: 1 computed checksum did NOT match
Now that everything is set up correctly, you’re ready to start making basic changes to the game and exploring how the project works—before diving into more advanced modding tasks!
Your 1st Zelda Modification: Changing a Hyrule Sign
Now that everything is set up, let’s make a quick edit to test your decomp build. Navigate to the file located at:oot/extracted/gc-eu-mq-dbg/text/message_data.h
Search for text ID 0x033A — this is the message displayed on one of the Hyrule Field signposts. Try replacing the text that mentions Hyrule Castle and Lon Lon Ranch with custom names of your choice.
Once edited, open Ubuntu and type make to recompile the project. After the build completes, launch the game and check the signpost in-game.
On the File Select Menu, load the first file and choose the scene Spot00 — this is Hyrule Field where the signpost is located.
Congratulations you have successful modded Zelda!
HOW DEFINE MESSAGE WORKS
DEFINE_MESSAGE(message_id,
textbox_type,
textbox_position,
MSG(english_text),
MSG(german_text),
MSG(french_text)
)
Message ID: 0x033A
The message ID is a unique hexadecimal number that tells the game which text message should be displayed when this dialog, sign, cutscene, or actor is triggered. NPCs or signs often have this->messageId = 0x0339;
Text Box Types
TEXTBOX_TYPE_BLACK
TEXTBOX_TYPE_WOODEN
TEXTBOX_TYPE_BLUE
TEXTBOX_TYPE_OCARINA
TEXTBOX_TYPE_NONE_BOTTOM
TEXTBOX_TYPE_NONE_NO_SHADOW
Find a list of all the text box types:
oot/include/message_data_static.h
Text Box Position
Defines the position of the textbox.
TEXTBOX_POS_TOP
TEXTBOX_POS_MIDDLE
TEXTBOX_POS_BOTTOM
TEXTBOX_POS_VARIABLE
The textbox position depends on the player’s position. For example, if Link is seen at the bottom of the screen, the textbox will move to the top of the screen so that Link can be seen.
COLOR()
Defines the color of the text.
DEFAULT
RED
ADJUSTABLE
BLUE
LIGHTBLUE
PURPLE
YELLOW
BLACK
Understanding Message Tags
QUICKTEXT_ENABLE
QUICKTEXT_DISABLE
This displays the text immediately
SHIFT(22) Shifts the text position from left to right.
BOX_BREAK Allows you to move from one textbox to the next. This is useful if there is a lot of text to display.
BOX_BREAK_DELAYED Same command as BOX_BREAK, except there’s a delay before moving on to the next textbox.
PERSISTENT This command is specially designed for textboxes in shops. It simply removes the blue icon at the bottom of the text.
EVENT This command enables an actor to perform an action. For example, at the end of the textbox, the Gerudo claps her hands to open the door to the Gerudo Training Ground.
FADE Makes the textbox disappear after a specific delay.
NAME Display the name of the player.
OCARINA Used to validate or invalidate the learned song.
SFX Play a sound effect in the textbox.
ITEM_ICON Displays an item icon. This is used when Link receives an item.
TEXT_SPEED Reduces text scrolling speed. The default speed is x00: TEXT_SPEED(“\x00”)
TOKENS Display the number of Gold Skulltula
UNSKIPPABLE Prevents textbox from being skipped
TWO_CHOICE Displays two choices for the player. These are usually Yes/No
THREE_CHOICE Displays three choices for the player.
TIME Display the time in the game
Change How The Game Starts
Next, we’ll walk through how to modify z_sram.c to change how the game begins. For example, you might want Link to start as an adult in a different map location. To do this, open the file at oot/src/code/z_sram.c and find the function void Sram_InitSave. This is where you can customize the game’s starting state. Find this line of code in the file. just search for gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
// Links House
gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
// Start off as child
gSaveContext.save.linkAge = LINK_AGE_CHILD;
// Start at 10:00 AM
gSaveContext.save.dayTime = CLOCK_TIME(10, 0);
// Add cut scene
gSaveContext.save.cutsceneIndex = 0xFFF1;
Updated Code
Pick a map from oot\include\tables\entrance_table.h. This is where you can add new maps but for simplicity lets pick an existing one. ENTR_LAKESIDE_LABORATORY_0 In the future we can cover how to create our own maps with Fast64 and blender.
// ✅ LAKE SIDE LAB
gSaveContext.save.entranceIndex = ENTR_LAKESIDE_LABORATORY_0;
// ✅ Start off as adult
gSaveContext.save.linkAge = LINK_AGE_ADULT;
// Start at 10:00 AM
gSaveContext.save.dayTime = CLOCK_TIME(10, 0);
// ✅ No cutscene trigger
gSaveContext.save.cutsceneIndex = 0;
// YOU CAN LOAD YOUR OWN CUSTOM MAPS BUT THERES MORE TO THAT WE WILL COVER THAT LATER
// ✅ LOAD CUSTOM MAP
// gSaveContext.save.entranceIndex = ENTR_FOREST_TOWN_0;
FIND THIS LINE IN Sram_OpenSave
default:
if (gSaveContext.save.info.playerData.savedSceneId != SCENE_LINKS_HOUSE) {
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
} else {
gSaveContext.save.entranceIndex = ENTR_TEMPLE_OF_TIME_7;
}
} else {
gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
}
break;
Updated Code
This is where link goes when he resumes a save. Have to update this or he will still always go to his house. Replace all these maps with the new map. First if block is where link goes as a child (default was his house), second is as an adult (default was the temple of time). I think its a good idea to update all 3 but you can play around with it.
default:
//✅ CHANGED - START OFF LINK AT NEW MAP LOCATION
if (gSaveContext.save.info.playerData.savedSceneId != SCENE_LINKS_HOUSE) {
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
// gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
// gSaveContext.save.info.playerData.savedSceneId = SCENE_FOREST_TOWN;
gSaveContext.save.info.playerData.savedSceneId = ENTR_LAKESIDE_LABORATORY_0;
} else {
// gSaveContext.save.entranceIndex = ENTR_TEMPLE_OF_TIME_7;
// gSaveContext.save.info.playerData.savedSceneId = SCENE_FOREST_TOWN;
gSaveContext.save.info.playerData.savedSceneId = ENTR_LAKESIDE_LABORATORY_0;
}
} else {
// gSaveContext.save.entranceIndex = ENTR_LINKS_HOUSE_0;
// gSaveContext.save.info.playerData.savedSceneId = SCENE_FOREST_TOWN;
gSaveContext.save.info.playerData.savedSceneId = ENTR_LAKESIDE_LABORATORY_0;
}
break;
Remove code that automatically starts link off with the master sword equipped as an adult.
Find this line of code in Sram_OpenSave and comment it out. This will remove it from the inventory, and equipped status not the model. I think that’s baked into the model as there was no time in the game where Adult link didn’t have a sword.
//🚫 This block forcefully gives Link the Master Sword on game load if he's an adult and doesn't already have it:
/*
if (LINK_AGE_IN_YEARS == YEARS_ADULT && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) {
gSaveContext.save.info.inventory.equipment |= OWNED_EQUIP_FLAG(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
#if OOT_VERSION >= NTSC_1_1
gSaveContext.save.info.equips.buttonItems[0] = ITEM_SWORD_MASTER;
gSaveContext.save.info.equips.equipment &= ~(0xF << (EQUIP_TYPE_SWORD * 4));
gSaveContext.save.info.equips.equipment |= EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4);
#endif
}
*/
RESULT
Open: ubuntu
Run: cd oot
Run: make – j and launch game
Select file spot 2: Launch the game NOT IN DEBUG MODE
Zelda Oot Decomp Tutorials
DECOMP COURSE
From the creator of
'The Ultimate Trial'
FAST 64 DECOMP COURSE
From the creator of
'The Ultimate Trial'










