Note: If you're using gz on the Wii VC, you should read the VC issues section to find out about the differences in the VC version.

The main interface for accessing the provided tools is the utility menu. By default, this menu is brought up by pressing R + L, but this button combination can be changed (see Settings). Use the D-Pad to navigate the menu, and L to make a selection. For a description of each of the submenus, see their respective section below.

Beyond the tools provided by the utility menu there is also;

  • An input display. The two numbers represent the x and y coordinate of the control stick. The button icons that appear represent the buttons that are pressed on the controller. Enabled by default.
  • A lag counter. Displays lag by subtracting the number of game frames passed from the game's vertical interrupt counter. Displayed in units of frames (60Hz, default), or seconds. Disabled by default.
  • A timer. Measures real-time using the CPU counter. Disabled by default.
  • Various button-activated commands.

These features can be configured from the settings menu (see Settings).

Installing The Practice ROM

Note, Gamecube listings DO NOT use the .ISO, they an N64 ROM File for patching and usage on a N64 Console with a Flash Cart, The Wii Virtual Console or on an N64 Emulator such as Project 64

Supported Games

The following iterations of The Legend of Zelda: Ocarina of Time are supported for use with The Practice ROM.

N64 ROMs of The Legend of Zelda: Ocarina of Time

  • The Legend of Zelda: Ocarina of Time (USA) (1.0)
  • The Legend of Zelda: Ocarina of Time (USA) (1.1)
  • The Legend of Zelda: Ocarina of Time (USA) (1.2)
  • The Legend of Zelda: Ocarina of Time - Master Quest (USA) (GC)
  • The Legend of Zelda: Ocarina of Time (USA) (GC) (Master Quest Disc / Collector's Edition)
  • Zeruda no Densetsu: Toki no Okarina (JPN) (1.0)
  • Zeruda no Densetsu: Toki no Okarina (JPN) (1.1)
  • Zeruda no Densetsu: Toki no Okarina (JPN) (1.2)
  • Zeruda no Densetsu: Toki no Okarina - GC Ura (JPN) (GC)
  • Zeruda no Densetsu: Toki no Okarina (JPN) (GC) (GC Ura Disc)
  • Zeruda no Densetsu: Toki no Okarina (JPN) (GC) (Zeruda Korekushon)

Wii Virtual Console WADs of The Legend of Zelda: Ocarina of Time

  • The Legend of Zelda: Ocarina of Time (USA) (1.2) (Wii VC)
  • Zelda no Densetsu: Toki no Okarina (JPN) (1.2) (Wii VC)

Line microcode donator ROMS:

  • Hey You, Pikachu! (USA)
  • Hey You, Pikachu! (JPN)

Using the patcher GUI

Start the gz-gui program. Click the tab that corresponds to the type of file you want to create and fill out the options according to the instructions below. Press Go! to run the patcher. The output log window will show information about the patching process. When the patcher is done, you'll be asked where you want to save the new file. Enter a filename and press Save. When the output window closes, the new file has been saved and you can close the program.

Patching a ROM

In the ROM group box, press Select and open the ROM that you wish to patch. If you want to enable line features, check Inject line microcode in the Line microcode group box, then press Select and open one of the supported microcode donor ROMs.

Patching a WAD

Press the Select button in the WAD group box and open an Ocarina of Time WAD. The ROM contained in the WAD will be used by default (USA 1.2 or JPN 1.2 depending on the WAD used). To use a different version, check Use external ROM in the ROM group box, press Select and open the ROM that you wish to patch and inject. The default options should be fine for most users.

Using the command-line

Patching a ROM

Windows: patch-rom.bat [options...] <input-rom>

GNU/Linux: ./patch-rom [options...] <input-rom>

macOS: From ./patch-rom [options...] <input-rom>


  • -s: Invoke as a sub-program to the gui patcher. Log messages are redirected to stderr, and the default filename is printed to stdout.
  • -o <output-rom>: Save as <output-rom> instead of the default filename.

Patching a WAD

Windows: patch-wad.bat [options...] <wad-file>

GNU/Linux: ./patch-wad [options...] <wad-file>

macOS: From ./patch-wad [options...] <rom-file>


  • -s: Invoke as a sub-program to the gui patcher. Log messages are redirected to stderr, and the default filename is printed to stdout.
  • -o <output-wad>: Save as <output-wad> instead of the default filename.
  • -m <input-rom>: Patch and inject <input-rom> instead of using the ROM contained in the content file.
  • -i|--channelid <id>: Set the channel ID to <id> instead of the default.
  • -t|--channeltitle <title>: Set the channel title to <title> instead of the default.
  • -k|--key <key-file>: Use <key-file> as the common key instead of common-key.bin.
  • -r|--region <region>: Set the channel region to <region>. <region> should be one of the following:
    • 0: Japan
    • 1: USA
    • 2: Europe
    • 3: Region free (default)
  • -d|--directory <content-directory>: Use <content-directory> as working directory for the main content file. The default is wadextract.
  • --raphnet: Use Raphnet Adapter controller remapping. L is bound to the Z Trigger on the controller instead of Down on the C-stick.
  • --disable-controller-remappings: Disable all controller remappings.
  • --no-homeboy: Do not inject the homeboy binary and hooks. Homeboy features will be unavailable.

Injecting the line microcode

Windows: inject_ucode.bat <dst-file> <src-file>

GNU/Linux: ./inject_ucode <dst-file> <src-file>

macOS: <dst-file> <src-file>


There are numerous menus within The Practice ROM and to the unexperienced user can be initially overwhelming. Within this menu we've broken down each of the menus into detailed explanations for users to quick look through, or, using the search feature withiin the manual, find what they're looking for.


The places menu provides a list of all scenes and their respective entrances, grouped into eight categories. Selecting a scene with multiple entrances will show a list of all entrances for that scene. Selecting an entrance will instantly warp you to that entrance. Scenes with only one entrance will warp you to that entrance when selected, without showing an entrance list. If you want to warp to a specific entrance index, you can enter that index in the warps menu and select warp. The age and cutscene options specify which age Link will be at when performing a warp, and which cutscene should be played for that scene. These options apply to both the places menu and warping using an entrance index.

clear cs pointer will point the cutscene pointer to an empty cutscene, which is useful for preventing certain wrong warps from crashing. The bottom of the warps menu shows information about the game's current warp parameters.

Warning: Attempting to load a beta scene will cause a crash on all but the debug version of Ocarina of Time, which is currently unsupported.

Warning: Starting a game (with a warp or scene loading command) when no file data is loaded (i.e. from the N64 logo and, to a lesser extent, the file select menu) will cause undefined behavior.


Selecting explorer will bring up the scene explorer, which shows an overlay of the current scene. Use the D-Pad up and down to navigate forwards and backwards through the scene, and D-Pad left and right to rotate the view. While holding Z, the D-Pad up and down will navigate vertically through the scene, and D-Pad left and right will move sideways. Use the explore prev room and explore next room commands to cycle through the rooms of the scene (bound to R + D-Down and R + D-Up by default). Pressing L will teleport Link to the location and orientation of the crosshair and close the scene explorer.

set entrance point sets Link's current position and orientation as the point where he will respawn after voiding out. clear flags and set flags modifies the temporary and permanent flags for the current scene, which keep track of things such as which chests have been opened, which items have been collected, which enemies have been defeated, etc. The load room option loads the room with the specified index, if a room which such an index exists within the current scene. If that room is already the currently loaded room, it will be unloaded. teleport slot selects which position to save and load when using the teleportation commands (this can also be bound to a button combination, but is unbound by default). The bottom of the scene menu shows information about the current scene.


Show collision, when enabled, shows the static and dynamic scene collision in the current scene. The collision polygons are color-coded to show special properties;

  • Blue: Hookshotable surface.
  • Purple: Surface with special interaction (ladder, vine, crawlspace, not climbable, grabbable).
  • Red: Void trigger.
  • Green: Load trigger.
  • Light green: Surface with special behavior (sand, quicksand, ice, lava, jabu wall, damaging wall, no recoil wall, void).
  • Light yellow: Slippery slope.
  • White: Normal surface.

Note that collision polygons are affected by scene lighting and fog, which can cause their appearance to be misleading. These effects can be disabled by turning off the shaded option. The collision view mode decides how collision polygons are drawn. The decal setting will draw polygons overlaid on scene textures, but will not produce any new surfaces (note however that most emulators do not correctly emulate this behavior). The surface setting draws collision polygons as their own surfaces, but can produce depth flickering on existing scene textures. Collision polygons can be configured to be completely opaque, or see-through with the translucent option. Enabling wifreframe will display lines around the edges of each polygon. The reduced option will reduce potential lag by only rendering collision polygons with some special property (i.e. colored polygons). When auto update is on, the collision view will update automatically when a collision view setting is changed, or when the collision changes. If turned off, the collision view must be manually disabled and re-enabled in order to update.

The show hitboxes option shows simple collision bodies and damage sources and sinks. The translucent and shaded options are identical to the collision view options with the same names. Hitboxes are also color-coded by their type;

  • Red: Hitboxes; deal damage.
  • Blue: Hurtboxes; take damage.
  • White: Bumpboxes; pushes and/or get pushed.

Free Camera

The free camera function provides full control of the game's camera. When enabled, the camera can be controlled with the joystick, C buttons, and Z trigger. These controls are disabled in the game when controlling the free camera. Press lock to disable the manual camera controls and restore the normal game controls.

The free camera has two mode settings; when set to camera, the game's camera is physically moved, which affects the behavior of in-game objects that react to the camera's position. When set to view, only the graphical viewpoint is changed. The game's camera then behaves as usual and is disjoint from the user's view of the scene.

The behavior setting decides how the camera moves and how the controls work;

  • manual: The camera does not move by itself. Use the joystick to look around, and the C buttons to move. Hold Z to move with the joystick, look with C-left and right, and move vertically with C-up and down. The distance min and distance max settings do nothing.
  • birdseye follow: The camera automatically looks at Link, and moves forward and backward to stay within the specified distance. Controls are the same as for manual.
  • radial follow: The camera follows Link from a fixed viewing angle. It will move up, down, and sideways to keep Link in focus, and forward and backward to stay within the specified distance. Use the joystick, C-left, and C-right to rotate the viewing angle, and C-up and down to move towards and away from the focus point. Hold Z to swap the function of C-up and down with the vertical joystick axis.


This menu allows toggling the builtin cheats on and off. The following cheats are available:

  • energy: Gives full health.
  • magic: Gives full magic.
  • various items: Sets item amounts to the current capacity of that item, or to one if the capacity is zero or unlimited.
  • small keys: Sets the number of small keys to one within the current dungeon, if any.
  • rupees: Sets the rupee amount to the capacity of the current wallet.
  • nayru's love: Prevents nayru's love from expiring, if active. If nayru's love is not currently active, entering a scene while this cheat is enabled will activate it.
  • freeze time: Prevents the current time of day from advancing. Does not affect sun's song or the time of day modifiers in the file menu.
  • no music: Stops background music from playing.
  • items usable: Clears all item restriction flags, allowing all items to be used regardless of location.
  • no minimap: Keeps the minimap hidden at all times.
  • isg: Permanently activates the infinite sword glitch.
  • quick text: Activates fast scrolling for all textboxes.

To undo the effects of the no music, items usable, and no minimap cheats, turn the cheat off and enter a new scene, or reload the current scene.


The equipment and items menu lets you modify your equipment, C-button items, and passive equipment items. There is also an option to set whether or not the Giant's Knife has been broken, and whether or not the Biggoron's Sword has been obtained. Pressing a bottle, trade item, or equipment item will bring up an item wheel where you can select from the possible items for that slot. Use the D-Pad left and right to cycle through the items, and the D-Pad up and down to cycle three items at a time. Capacity equipment items (e.g. quiver, bomb bag etc.) that are not normally obtainable without using cheats or glitches are denoted with an asterisk.

The quest items menu lets you modify all items on the Quest Status screen, as well as your energy and magic. There are also options to modify the dungeon items and small key amount of a specified dungeon. energy cap., defense, magic cap., and heart pieces are specified in hexadecimal for simplicity (from here on denoted with an h). For energy capacity, 10h corresponds to one heart container. The defense checkbox enables or disables double defense damage reduction, and the field next to it modifies the number of defense heart containers. For magic capacity, 0h is the normal capacity, 1h is double magic, 2h is what would be triple magic etc. For heart pieces, 10h corresponds to one heart piece.

The amounts menu lets you modify the ammo of your C-button items, your magic and energy amount, number of hits left on Giant's Knife, and rupee amount. The number of Giant's Knife hits left is what decides whether or not the Giant's Knife / Biggoron's Sword appears to be broken when Link wields it. Magic, energy, and Giant's Knife hits are specified in hexadecimal. 30h magic is the max for normal magic capacity, and 60h is the max for double magic capacity. For energy, 10h corresponds to one heart container. Though the highest amount of rupees that can be specified is 99999, entering a value greater than or equal to 65536 will wrap the amount around to zero and on.


This menu lets you modify your current equips, and the items equipped to your B and C-buttons. Pressing a piece of equipment that is already equipped will unequip it. Unequpping a sword or equipping nothing to the B button will automatically set the current file's swordless flag. Warning: Unequipping boots will have strange effects, and usually cause an immediate crash. Note: Changing a C-button equip will not modify the equipped item slot for that button.


The restore skulltulas option clears all the gold skulltula flags in the current file, thus restoring all destroyed gold skulltulas. The gold skulltulas in the current scene are not affected until the scene is reloaded. call navi sets Navi's advice timer to a value which will make her want to talk to you. This will not have any effect until you enter an area where Navi normally appears. The memory file selects the memory file to save to and load from when using the memory file commands (see Settings). The current time of day can be manually adjusted, or automatically fast-forwarded to day or night with the corresponding buttons. epona freed, carpenters freed, intro cutscenes, and rewards obtained let's you set and clear various useful flags in the current file. Pressing the checkmark will set the pertinent flags such that they have been "completed", and the cross will clear them (setting them to the state that they were in when the file was created).

The timer 1 and timer 2 options display and modify the state of the two types of timers in the game. The first timer is used for hot rooms and races, and the second timer is used for trade items and the Castle Collapse sequence. The numbers represent the number of seconds left on the timers, and the options show the current state of the timers. Both of these can be modified manually. Note: When the first timer is set to a heat state, the game will instantly deactivate it if the current room is not "hot". Warning: Modifying the state of the timers can yield strange behavior. In general, it is safest to use the the starting and stopped states when doing this.

The file index option decides which file the game will be saved to when saving from the start menu or the Game Over screen. When the file index is set to FFh, as it is by default on the title screen, saving will have no effect. There's also a language and z targeting option, which apply to the current file.

Save files can be saved to and and loaded from an SD card with the save to disk and load from disk options. Pressing load from disk will bring up the file browser. Pressing the name of a save file will load it and return to the file menu. The load file to and after loading options decide where in memory the file will be loaded to (the current zelda file, the currently selected memfile slot, or both), and what should happen when the loading is completed (reload scene, void out, or nothing). The after loading option will have no effect when loading only to the current memfile. The file extension used for save files on disk is .ootsave, and the default filename is file. The filename can be changed by pressing the name field. Pressing clear will set the name field to be empty. When the name field is empty, the default filename is untitled. When saving, pressing the name of a save file in the file browser will copy that name to the name field. Pressing accept will save the file to the current folder in the file browser with the specified file name. If the file exists, you will be prompted to overwrite it.


This menu provies tools for producing tool-assisted gameplay recordings. Press pause to freeze/unfreeze the game, and frame advance to advance the game one frame at a time, allowing for precise input control. Start recording your inputs by pressing record macro, and play back your recorded inputs by pressing play macro. The macro frame control shows the number of the current frame which your inputs are being recorded to / played back from. You can edit this value to seek to a specific frame of input, or press rewind macro to seek to frame 0. The total number of input frames recorded in the current macro is displayed on the right. Press trim macro to delete all recorded inputs after the current macro frame, should you feel that you've recorded too far.

Use the arrows to select a savestate slot, and save the current state of the game to that slot by pressing save state. You can then return to that state by pressing load state. If you are in macro recording/playback when saving a state, the frame number will be saved within the state, and the macro will seek to that frame when loading the state. This allows you to record over previously recorded inputs, to correct mistakes for example. If there's no macro frame stored in the state, your macro will not be affected. clear state deletes the state in the current state slot. Some information about the state saved in the current slot is displayed; the scene in which it was saved, the size of the state, and the macro frame (if any) on which it was saved.

Quick record movie is a convenience option to start recording a macro, save a state to slot 0 for playing back the macro from the start, and then switch to slot 1 to use for rerecording. quick play movie will start macro playback from the start and load the state in slot 0.

Macros and savestates can be saved to and loaded from an SD card using export macro / import macro and export state / import state.

Note: Macros override all controller input by default, but this can be changed with the macro input setting in the settings menu.

Note: States can not be used in the file select menu or on the n64 logo.

See also: Issues with Savestates.


This menu provides advanced settings for macro recording. The Practice ROM implements certain hacks to keep macros in sync (See About Frame Advancing and Recording). All hacks are enabled by default. Disabling the hacks can cause issues and desyncs, and should only be done if required. For example, when recording a setup that is sensitive to room loading lag. For such use cases, the hacks should not be kept disabled longer than necessary (i.e. disable only when recording that particular section).

The wii vc camera setting enables a camera quirk that is present on the Wii VC versions of the game. This setting can be used to sync macros that were made on Wii VC when played back on N64, or vice versa. It is enabled by default on Wii VC versions of The Practice ROM.

Virtual Controller

Press the checkbox next to the controller number to override the game's input for that controller with a virtual controller. When the virtual controller is enabled, the plugged in option decides if the controller should appear to be connected to the system. The joystick controls set the x and y coordinates of the joystick on the virtual controller, and the buttons controls decide what buttons are held down on the virtual controller.


This menu lets you add custom RAM watches to observe arbitrary parts of game's memory in real-time. Pressing the plus icon will add a new watch, and pressing the cross next to a watch will remove that watch. After adding a watch, enter a memory address and value type to display the value at that address. These watch types are available:

  • u8: one-byte value, unsigned.
  • s8: one-byte value, signed.
  • x8: one-byte value, hexadecimal.
  • u16: two-byte value, unsigned.
  • s16: two-byte value, signed.
  • x16: two-byte value, hexadecimal.
  • u32: four-byte value, unsigned.
  • s32: four-byte value, signed.
  • x32: four-byte value, hexadecimal.
  • f32: four-byte value, IEEE 754 single-precision floating-point.

Pressing the anchor button next to a watch will release the watch from the watches menu so that it's always visible, even when the menu is closed. When a watch is released, a positioning button will appear which lets you change the position of the watch on the screen. Holding Z when positioning the watch will move it faster. The visible option can be unchecked to hide all watches globally.

Watches can be imported from text files on an SD card by pressing the folder icon. Press a watch file to bring up a list of all watches contained in that file. Press a watch to import it to your watch list. When you've imported all the watches you need, press return to go back to the watches menu. The format of watch files is described here.

Premade Import Files

For a maintained list of watches by the community, (always updated, based on a spreadsheet that's always kept up to date) ready for download and use, please follow one of the following links to the appropriate watch list and place the file on your SD Card:

Watch Import Syntax

A watch file is a normal text (*.txt) file containing names, types, and addresses of watches. Like this document, which happens to be a valid watch file. Each line in the file can have one watch entry. The # character starts a line comment (like this one). Comments are just plain text that gets ignored when importing watches from a watch file.

Watches look like this:

"this is a watch" u16 0x80001234

The name of the watch goes first, contained in double quotes. After it comes the data type. valid data types are:

u8,  s8,  x8  : one-byte value (signed format, unsigned format, hex format)
u16, s16, x16 : two-byte value (ditto)
u32, s32, x32 : four-byte value (ditto)
f32           : four-byte value, 32-bit ieee 754 single-precision floating-point format

Finally comes the address. In the example above, the address is just a simple hexadecimal number. Numbers can start with '0x' for hexadeciaml, '0b' for binary, '0' for octal, or any digit other than zero for decimal, but, the address can also be a more complex expression, with arithmetic and indirection.

The available arithmetic operators are:

*, /, % : multiplication, division, and remainder
+, - : addition and subtraction

Here's an example address with arithmetic operations:

"complex address with arithmetic" f32 5 * (3 + 4)

The address in this example becomes the result of the arithmetic expression, which is equal to:

5 * (3 + 4) = 5 * (7) = 35

Obviously this isn't very useful, since you could have just written '35' as the address (and also 35 isn't even a valid address). That's where indirection comes in.

Indirection is the act of replacing part of an expression with the value at the address given by that expression. This is done by enclosing the sub-expression in [square brackets]. If we do this with the address in the first example we get:

"this is also a watch" u16 [0x80001234]

This expression no longer means "the address I want is 0x80001234", but instead means "the address I want is the value located at 0x80001234 in memory". So whatever 32-bit value happens to be at 0x80001234 when this watch is imported, that's going to be the address of the new watch. This is useful for computing the address of dynamically loaded things, such as most actors. The value given by the indirection doesn't need to be an actual address though. It can be a smaller part that is needed to compute the address of a bigger expression. The result of an indirection can be used in arithmetic just like any number. There can also be nested indirection:

[[0x80001234 + 0x20] + [0x80003210] * 0x31]

The expression above means: "add 0x20 to 0x80001234, then get the value at the resulting address. Multiply the value at 0x80003210 by 0x31. Take these two values and add them together. Then, since the whole thing is enclosed in square brackets, get the value at the address resulting from the last summation and use that as the new watch address."

In all of the above uses of indirection, the type of the value to get is implicitly a 32-bit integer. But, other types can be used as well by explicitly preceding the square brackets with a mode indicator.

The following modes are available:

b.[0x80001234]  : one-byte value, sign-extended to 32 bits.
bz.[0x80001234] : ditto, zero-extended to 32 bits.
h.[0x80001234]  : two-byte (16-bit halfword) value, sign-extended to 32 bits.
hz.[0x80001234] : ditto, zero-extended to 32 bits.
w.[0x80001234]  : four-byte value (32-bit word, the default mode when no mode is explicitly specified)

Finally, there are a few builtin symbols that can be used in address expressions. Whenever one of these are encountered, they are replaced by the address represented by that symbol.

"Link x" f32 link + 0x24

The above expression results in whatever address the Link actor is loaded at, plus 0x24. This happens to be the address of Link's x-coordinate.

These symbols exist:

link  : gets replaced by the starting address of the Link actor
ctxt  : gets replaced by the address of the global context
file  : gets replaced by the address of the current zelda file data


Note: These features are for advanced users. Be careful.

This menu contains various debug features to use for testing;

  • heap: Displays information about the game's dynamic memory arena.
  • display lists: Displays information about display list usage.
  • objects: Shows a list of currently loaded objects, which contain graphical assets. The push option loads the object file of the given id at the end of the list, and the pop option unloads the last object in the list.
  • actors: Browse the currently loaded actors, and spawn new actors. Select an actor type and use the arrows to scroll between all the loaded actors of that type. The address and id of the selected actor is displayed below, as well as the actor variable in that actor instance. The delete option deletes the currently selected actor, and the go to option teleports Link to the location of that actor. To spawn a new actor, enter an actor id, variable, the x, y, and z components of the position and rotation to spawn the actor at, and press spawn. The fetch from link option loads Link's current position and rotation into the position and rotation fields.
  • flags: Display and edit saved game flags. The flags are grouped by the records they are kept in. Use the arrows to cycle between flag records. Press a flag to toggle its state. A red flag is "off", and a green flag is "on". The log menu displays a list of recent flag events. When a flag changes, its record, id, and new value is inserted at the top off the list. The undo option reverts the effect of the most recent flag event and removes it from the log. The clear option removes all flag events from the log, but does not affect the state of the given flags. Note: The flag log only records changes when the log menu is open. If a flag changes and then changes back while the log is closed, these changes will not be recorded. Note: Scene-related flags only affect the currently loaded scene. If a scene flag event that occurred in one scene is undone in a different scene, it will not have the desired effect.
  • memory: Memory editor. Use the horizontal arrows to cycle between memory domains, and the vertical arrows to scroll up and down between addresses. Holding Z while scrolling will scroll faster. You can also enter an address manually in the address field. To edit memory, select the desired data type and press a memory cell to modify it.
  • rdb: Remote debugging interface through ED64v3 USB FIFO. Press start rdb to attach the debugger and halt the program, and stop rdb to detach the debugger. Press break to hit a breakpoint on the graph thread.


This is where most of the functionality of The Practice ROM is configured.

The profile option selects which profile to save and load settings to and from. When the game starts, the settings saved to profile zero are automatically loaded, if any.

The appearance of the menu can be configured with the font and drop shadow options. Disabling drop shadow can reduce the graphical computation impact of the menu, but may also reduce readability. The visibility of the on-screen display elements can be configured with the input display, log, lag counter, timer, and pause display options. The screen position of the utility menu, input display, log, lag counter, and timer can be configured by their respective positioning buttons. Holding Z when positioning an element will move it faster.The display unit of the lag counter can be set to frames or seconds. macro input enables or disables controller input when macro playback is active. The break type option decides how the break free command will function. When the break type is normal, the command will end textboxes, certain events and traditional cutscenes. The aggressive break type will cause the command to also try to reset the camera and some of Link's state flags. save settings and load settings will save and load the current settings to the currently selected profile. restore defaults will restore all saved settings to their default values (Does not affect saved profiles). If the saved settings were to become corrupted in such a way that they prevent the game from starting, holding the Start button when the game is starting will load the default settings instead of loading profile zero. The following settings are saved:

  • Menu and on-screen displays appearances and settings.
  • Saved positions and the currently selected position slot number.
  • Watches.
  • Command button binds.
  • Activated cheats.
  • Warp menu age, cutscene index, and entrance index.
  • Disk file loading settings.

The commands menu lets you bind commands to custom button combinations and/or activate them manually. Pressing the name of a command will activate that command, and pressing the button combo in the right column will bind a button combo to the corresponding command. If you want to unbind a command, press and keep holding L when starting the binding. A button combo for any given command can contain at most four buttons. When activating a command with a button combo, the button combo must explicitly be input the way it appears in the commands menu. For example, a command with the button combo R + A will only be activated if you press R first and then A, or R and A at the same time. A + R, or R + B + A will not activate the corresponding command. If the set of buttons in one button combo is a subset of those in another button combo, the former will be overridden by the latter when both are active simultaneously.

The following commands are available:

  • show/hide menu: Opens the utility menu if it's closed, closes it if it's opened. Default: R + L
  • return from menu: Returns to the previous menu, as if the return button was pressed. Default: R + D-Left
  • break free: Attempts to break any effect that removes control of Link. Default: C-Up + L VC Default: Start + L
  • levitate: The classic L to levitate command. Default: L
  • fall: Makes Link fall through the floor, as if there was no floor. Default: Z + L
  • turbo: Sets Link's linear velocity to 27. Default: unbound
  • file select: Returns (or proceeds) to the game's file select menu. Default: B + L
  • reload scene: Reloads the current scene, starting from the last scene entrance. Default: A + L
  • void out: Reloads the current scene, starting from the last room entrance as if Link voided out. Default: A + B + L
  • toggle age: Toggles between Adult and Child Link. Takes effect when entering a new area. Default: unbound
  • save state: Save the state of the game to the currently selected state slot. Default: D-Left
  • load state: Load the state saved in the currently selected state slot. Default: D-Right
  • save memfile: Saves the current state of the game to the memory file in the current memory file slot. Everything that would be saved when saving the game normally is saved to the memory file. Default: unbound
  • load memfile: Loads the state of the current memory file. Default: unbound
  • save position: Saves Link's current position and orientation to the current position slot. Default: unbound
  • load position: Teleports Link to the position in the current position slot. Default: unbound
  • previous state: Selects the previous savestate slot. Default: unbound
  • next state: Selects the next savestate slot. Default: unbound
  • previous memfile: Selects the previous memory file slot. Default: unbound
  • next memfile: Selects the next memory file slot. Default: unbound
  • previous position: Selects the previous position slot to be used for teleportation. Default: unbound
  • next position: Selects the next position slot to be used for teleportation. Default: unbound
  • pause/unpause: Pauses the gameplay, effectively freezing the state of the game. If the game is already frozen, resumes gameplay as normal. While the game is frozen, a pause icon will appear on the top-left of the screen (enabled by default, can be turned off). Default: D-Down
  • frame advance: If the game is frozen by the pause command, advances one frame of gameplay. Otherwise, freezes the game as if the pause command was activated. Default: D-Up
  • record macro: Start/stop input macro recording. Default: unbound
  • play macro: Start/stop input macro playback. This command can be held down to loop the macro. Default: unbound
  • collision view: Toggle the collision view on or off. Default: unbound
  • hitbox view: Toggle the hitbox view on or off. Default: unbound
  • explore prev room: Loads the previous room while using the scene explorer. Default: R + D-Down
  • explore next room: Loads the next room while using the scene explorer. Default: R + D-Up
  • reset lag counter: Resets the number of lag frames recorded to zero. Default: R + B + D-Right
  • toggle watches: Shows or hides watches globally. Default: R + D-Right
  • start/stop timer: Starts the on-screen timer if it is stopped, stops it if it's running. Default: R + A + D-Left
  • reset timer: Sets the time of the on-screen timer to zero. Default: R + B + D-Left
  • start timer: Starts the on-screen timer if it is stopped. Default: unbound
  • stop timer: Stops the on-screen timer if it is running. Default: unbound
  • reset: Reset the game, as if the reset button had been pressed. Default: unbound

Warning: Unbinding the show/hide menu or return from menu commands, or binding them to a button combination that will interfere with menu navigation can make it impossible to use the utility menu. If this happens, you can restore the default settings by entering the following button sequence: D-Up D-Up D-Down D-Down D-Left D-Right D-Left D-Right B A.

Note: Button combos that interfere with menu navigation for commands that aren't related to menuing are disabled while the utility menu is active.

VC Issues

There are some known issues with the Wii VC version of The Practice ROM:

  • The D-Pad on the Classic/Gamecube Controller is mapped to the L button on the Virtual Console. The WAD patcher remaps the D-Pad to be functional again, and maps C-Stick Down to L on the Virtual Console to provide access to the utility menu.
  • The scene explorer has graphical glitches due to poor emulation.

Using an N64 Controller on Wii Vritual Console

If you wish to use the Nintendo 64 controller, using an adapter, on Wii Virtual Console you will notice some issues when it comes to the mapping of the controller and using the menu system in The Practice ROM.

To get around these issues, you will need a Wii Remote synced with your Nintendo Wii and will also have to boot the game using an application such as GeckoOS to run a cheat file from your SD Card to enable the reconfigured mapping.

The following contents can be placed on your SD card at the following location /codes/NGZJ.gct from the root of your SD Card.

You can also download a copy of the file here if you'd prefer to not make your own copy.

82110001 001C7E52
86300001 0000000C
86100001 00000100
82110002 001C7E52
86300002 00000001
86100002 00000200
82110003 001C7E52
86300003 00000002
86100003 00000080
82110004 001C7E52
86300004 00000C00
80000005 00000006
88600005 00000004
88200001 00000002
88200001 00000003
88200001 00000005
84110001 00E7445E

Issues With Savestates

There are a number of known issues with Save States at this time.

These are as follows:

Dangling Pointers

This mainly concerns what's known as the cutscene pointer. When executing a wrong warp, the cutscene pointer will often be a dangling pointer, meaning that it points to memory which is no longer in use, or is now used by something else. This affects the behavior of wrong warps, because the cutscene data will now have been replaced by garbage.

The Practice ROM does not save unused memory in states, and this can have some unexpected side effects when loading a state that had a dangling pointer. The pointer itself will have the same value, and be exactly the same. However, the memory that the pointer points to may not necessarily be exactly the same. Specifically, if the cutscene pointer pointed to garbage, the only guarantee is that it will still point to garbage, not the exact same garbage. Because of this, the behavior of wrong warps is not guaranteed.


Some assumptions are made about the state of the game when it is saved. For example, the scene file is assumed to be largely the same as it appears on the rom. As such, only a few details actually need to be saved. There are situations where these assumptions break down; if the scene file had become corrupted for some reason (e.g. double loading), those corruptions would not be restored when the scene is loaded again.


Graphical dependencies (i.e. object files) take up a lot of space, and saving them in states would not be practical. Fortunately, they mostly contain static data that never changes, and can plainly be loaded from the rom when needed. But there are some graphical effects that modify these files, and The Practice ROM does not account for this. Specifically, some dissolving effects are known to modify textures, which can cause them to look odd after a state load. These issues are purely aesthetic.


The state of the audio is well separated from the state of the game, so restoring the audio state is not necessary for the game to behave correctly after a state load. The audio state is also quite complex and take up much space. For these reasons, savestates only save minimal information about the state of the audio. This has been known to sometimes cause audio bugs, such as music failing to start playing, or sound effects not playing as they should.

About Frame Advancing And Recording

The Practice ROM has the ability to advance frames and also record user input and play it back on command. There are a number of things to note about these features.

These are as follows:

Room Loading

Room loading normally happens asynchronously. That means the game continues playing while the room loads, and the room appears whenever it's finished loading. This usually takes 1 frame, but can take longer, depending on the cpu and cartridge load. Emulators typically don't emulate cartridge bandwidth limitations, so the delay is usually 0 frames.

When recording or playing back a macro, room loading behavior is changed to always load synchronously. Thus the game stops until the room has finished loading, such that load delay variations can not cause macros to desync.

Ocarina Notes

When an ocarina song plays on a staff, the notes appearing on the staff are synced to the audio. The purpose of this is to compensate for potential differences in lag or framerate, so that the note always appears when you hear the sound. This poses a problem when frame advancing, because as far as the game is concerned, frame advancing is essentially lag. The note sync mechanic is not robust against severe lag, and such lag can cause the staff to simply stop playing notes, or break in other strange ways.

The Practice ROM circumvents these issues by disabling the audio sync when frame advancing or recording/playing a macro. Instead, the game is assumed to run at a constant framerate with no lag, so that no timing adjustment needs to be done.

Ocarina Input

The game's input manager polls the controller at a rate of ~60Hz. Ocarina input is handled separately from the common game input, and circumstances can cause it to be delayed into a different controller input window. When this happens, the input seen by the ocarina on a given frame may be different from that seen by the rest of the game.

This is a source of potential desyncs in macros, so when playing or recording a macro, The Practice ROM ensures that the ocarina input is the same as the common game input for any given frame.

RNG Seeds

The game's Random Number Generator (RNG) is used to decide the outcomes of random events. The RNG is deterministic, which means that given the same initial conditions, it will produce the same results. For example, by starting from a savestate in the graveyard and playing a macro to have Dampé dig a grave, your reward should be the same every time, as long as the same savestate and macro is used.

The value of the RNG is predictable given a known starting state. However, the starting state of the RNG itself (the seed), is generally not predictable (read pretty damn random). The RNG is reseeded on every scene load, and from that point, the future state of the RNG is equally unpredictable.

In order for macros to stay synchronized across scenes, all RNG reseeds are recorded in the macro file. When an RNG reseed is detected during macro playback, the stored seed will be used instead of a random value if the following conditions hold;

  • The state of the RNG is the same as when the seed was recorded (i.e. the RNG is synced up until this point).
  • The reseed happens on the same macro frame that it was recorded.

If either of these would fail, the RNG is reseeded as normal with an unpredictable value.



To build this software, you need to have the n64 tools installed. See the readme in the n64 repository for instructions. To make a VC inject with a Wii WAD, you need gzinject, and optionally a C compiler that targets PowerPC (see Patching).


To build all The Practice ROM binaries, navigate to the root directory of the repository and run make. To build binaries that will work correctly on the Wii VC, you must have configured the n64 tools with --enable-vc when building the MIPS toolchain.


To create a UPS patch or a pre-patched rom, run ./make-patch <rom-file> or ./make-rom <rom-file>. <rom-file> should be an unmodified rom to be used for creating the patch. Use ./make-patch-vc <rom-file> to create a rom patch that targets the Wii VC. To create a patched Wii WAD with a rom inject, run ./make-wad <wad-file>. You will need powerpc-eabi-gcc (provided by devkitPPC or wii-toolchain) to build the homeboy submodule, which is required to enable certain features for Wii VC, such as SD card access. To make a wad without such features, use ./make-wad --no-homeboy.


Here's some things you could do if you want to help the project.

Thank you for contributing!

GitHub Repositories:

Bug reports

When submitting a bug report, you should include all the necessary steps for reproducing the bug. Describe in detail the expected behavior and the observed behavior. Do not submit bug reports about odd behavior caused by using the provided utilities to break the game.


If you want to submit feedback about possible improvements or feature requests, include a detailed description of your proposed changes, how they should be designed, how they will fit in with the current design, and possibly how they should be implemented. Do not submit suggestions that are too subjective to be considered improvements.


If you want to fix a bug or implement a feature yourself, feel free to make a development fork. Before you start working on a feature, you may first want to submit an issue where you describe the feature you want to add, to be sure that such a feature would be accepted. There's no canonical style guide for this project, but you should adhere to the style used in the rest of the code. Code that doesn't meet the current quality standard will be rejected. When your code is ready, send a pull request. Your code will be reviewed, and possibly merged with the master branch.


This work is built upon research and documentation made by a whole community of people. Thanks to everyone who has directly or indirectly contributed!