SRM Overview

Stale Reference Manipulation (SRM) is a glitch which overwrites certain parts of the game's actor data and code to arbitrary values, by unloading actors and loading something else in their place.

The Heap, Actor References, and SRM

The heap is a doubly linked list of actor instances (the variables for an actor, such as its position), actor overlays (code used by actors), and more.

Some actors have references to other actors on the heap. For example, Link stores a reference to the actor he is holding above his head, such as a bush, rock, bomb, or bombchu. The Boomerang stores a reference to the actor it is carrying, such as a Rupee, Recovery Heart, or Gold Skulltula Token. When Link or the Boomerang move, they change the position of the actors they are carrying, as well as some other data.

Under specific circumstances, it is possible to unload the actor being carried, then load a new actor instance or overlay in its place. The actor carrying that actor will continue to write values such as position data to that location, which could now be an entirely different actor or even actor code. The act of writing that data to the referenced location, despite the reference no longer pointing to the original actor, is known as Stale Reference Manipulation.

Typically, several actors and rooms are carefully loaded in a particular order, causing a specific part of an actor instance or overlay to align with the reference to the region in memory which previously contained the carried actor. Manipulating memory in this way is known as heap manipulation.

Levels of SRM

There are three main levels of SRM.

1. Editing Actor Variables

Every actor instance has data that determines it's position, angle, animation timers, and more. It is possible to edit this data in order to change the attributes of the corresponding actor. The most basic example of this is editing position and rotation data to make Link or the boomerang carry actors, such as doors or enemies. A more advanced example is editing the contents of a treasure chest.

2. Function Pointer Manipulation (FPM)

Function Pointer Manipulation is overwriting a pointer to code. Rather than directly modifying code, FPM changes which existing code the game will run, by modifying a code reference to point elsewhere. This level only allows calling code which is in the game normally, not created by the player.

Actor instances have multiple pointers to code. The most commonly used one is the Draw Function Pointer, which points to the function used to draw the actor onscreen. This lines up nicely with the methods of SRM that use actors held by Link, allowing the player to modify the lower half of the pointer to run any code nearby the draw function in memory.

Partial Function Calls are a subset of this type of SRM, and instead of pointing the code to the start of a function, point the code to specific instructions within a function. Running code in the middle of a function in this way is extremely powerful, as it allows reading or writing data to a manipulable place in the Save Context. The most common uses of Partial Function Calls include:

  • Calling any function in the game, rather than just ones nearby in memory to the actor which is being used for SRM. This is generally used to call the Title File Function, which gives nearly every item instantly and can be quickly performed at the start of the game, without leaving Kokiri Forest.
  • Writing a variety of values to a large portion of Save Context. This is commonly used for FW SRM Warping, Age Change SRM, Inventory/Quest Status SRM, and F Boots.

3. Arbitrary Code Execution (ACE)

Arbitrary Code Execution is directly modifying the game's code or creating custom code for the game to run. This can be used to do just about anything, such as creating new actors, scenes, items, or otherwise changing the game's code or data. Due the the limitless possibilities, this is banned in most speedrun categories, but still used for a Credits Warp in Any%.

Methods of SRM

Loading a new room while Link is carrying a culled actor:

  1. Hold an actor over Link's head, such as a rock or grass
  2. Load a new room while the held actor is culled. This can be accomplished in a few ways:
    • Perform a superslide, with the grabbable actor and an inverted camera angle, through a loading plane
    • Use Walking While Talking to lock the camera and enter a loading plane. The held actor must be culled when link successfully grabs it, or it will stay loaded when changing rooms, even if culled at that point.
    • Use Get Item Delay to load a new room while an actor frozen in place. This appears to only be possible with regenerating grass, such as in the Deku Tree.
  3. New actors can be loaded at the memory location which was used by the unloaded actor. Link will continue writing position and angle data to that location while carrying nothing around.

Loading a new room while the Boomerang is carrying a culled actor

  1. Throw the boomerang at an actor it can carry, such as a Gold Skulltula token or Heart Piece.
  2. Turn the camera away from the carried actor far enough to cull it.
  3. Load a new room by entering a loading plane or going through a door. This will unload the actor carried by the boomerang. If using a door, the camera can turn different directions based on Link's angle when opening the door, which could affect the cull status of the carried actor.
  4. As the boomerang returns to you, it will continue writing position data to the location in memory formerly used by the actor.

Bomb or Bombchu exploding in Link's hands while he is frozen, then loading a new actor

  1. Hold a bomb or bombchu in your hand
  2. Freeze Link by either collecting a Gold Skulltula Token or being seen by a Redead/Gibdo.
  3. Allow the explosive in your hand to explode while frozen
  4. Load a new actor into the place in memory the bombchu previously used. This can be accomplished by turning the camera towards actors which unload if far off screen, such as groups of grass or rocks. Other methods work without turning the camera, such as blowing up a sign or having a deku scrub to shoot a nut.
  5. Link will continue writing position and angle data to that place in memory, even if it is overwritten with something entirely different.

Values Written by Link Held Actor SRM

When Link Picks Up the Actor
OffsetOffset Description (type)Notes
0x88bgCheckFlags (u16)writes 0x0000
While Link is Carrying the Actor
OffsetOffset Description (type)Notes
0x24X-coordinate (float)writes the X-coordinate of Link's Hands
0x28Y-coordinate (float)writes the Y-coordinate of Link's Hands
0x2CZ-coordinate (float)writes the Z-coordinate of Link's Hands
0x30X Rotation 1 (s16) †writes Link's X Rotation
0xB4X Rotation 2 (s16) †writes Link's X Rotation
0x32Y Rotation 1 (s16) ††writes Link's Y Rotation (angle)
0xB6Y Rotation 2 (s16) ††writes Link's Y Rotation (angle)

† - Only written if offset 0x4 has the 18th bit (0x00020000) set

†† - Only written if offset 0x4 has the 18th bit (0x00020000) unset

When Link Throws the Actor
OffsetOffset Description (type)Notes
0x60Y Velocity (float)writes 0x41400000
0x68XZ speed (float)writes 0x41000000
0x118Attached Actor Pointer (u32)writes 0x00000000
When Link Drops the Actor with A
OffsetOffset Description (type)Notes
0x60Y Velocity (float)writes 0x00000000
0x68XZ speed (float)writes 0x00000000
0x118Attached Actor Pointer (u32)writes 0x00000000
When Link Shield Drops the Actor
OffsetOffset Description (type)Notes
0x118Attached Actor Pointer (u32)writes 0x00000000

Values Written by Boomerang SRM

While the Boomerang is Carrying the Actor
OffsetOffset Description (type)Notes
0x24X-coordinate (float)writes Boomerang's X-coordinate
0x28Y-coordinate (float)writes Boomerang's Y-coordinate
0x2CZ-coordinate (float)writes Boomerang's Z-coordinate
When Link Catches the Boomerang
OffsetOffset Description (type)Notes
0x4Flags (u32) †unsets 0x02000000 bit
0x24X-coordinate (float) ††writes Link's X-coordinate
0x28Y-coordinate (float) ††writes Link's Y-coordinate
0x2CZ-coordinate (float) ††writes Link's Z-coordinate
0x6CGravity (float) †††writes 0xBF666666
0x88bgCheckFlags (u16) †††unsets 0x03 bits

† - Only written if the Boomerang is not carrying an Item00 actor

†† - ?

††† - Only written if Boomerang is carrying an Item00 actor (such as a Heart Piece, Small Key, Rupee, etc.)

Last updated 12/02/2020 – Exodus