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 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.
There are three main levels of SRM.
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.
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:
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%.
When Link Picks Up the Actor | ||
Offset | Offset Description (type) | Notes |
0x88 | bgCheckFlags (u16) | writes 0x0000 |
While Link is Carrying the Actor | ||
Offset | Offset Description (type) | Notes |
0x24 | X-coordinate (float) | writes the X-coordinate of Link's Hands |
0x28 | Y-coordinate (float) | writes the Y-coordinate of Link's Hands |
0x2C | Z-coordinate (float) | writes the Z-coordinate of Link's Hands |
0x30 | X Rotation 1 (s16) † | writes Link's X Rotation |
0xB4 | X Rotation 2 (s16) † | writes Link's X Rotation |
0x32 | Y Rotation 1 (s16) †† | writes Link's Y Rotation (angle) |
0xB6 | Y 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 | ||
Offset | Offset Description (type) | Notes |
0x60 | Y Velocity (float) | writes 0x41400000 |
0x68 | XZ speed (float) | writes 0x41000000 |
0x118 | Attached Actor Pointer (u32) | writes 0x00000000 |
When Link Drops the Actor with A | ||
Offset | Offset Description (type) | Notes |
0x60 | Y Velocity (float) | writes 0x00000000 |
0x68 | XZ speed (float) | writes 0x00000000 |
0x118 | Attached Actor Pointer (u32) | writes 0x00000000 |
When Link Shield Drops the Actor | ||
Offset | Offset Description (type) | Notes |
0x118 | Attached Actor Pointer (u32) | writes 0x00000000 |
While the Boomerang is Carrying the Actor | ||
Offset | Offset Description (type) | Notes |
0x24 | X-coordinate (float) | writes Boomerang's X-coordinate |
0x28 | Y-coordinate (float) | writes Boomerang's Y-coordinate |
0x2C | Z-coordinate (float) | writes Boomerang's Z-coordinate |
When Link Catches the Boomerang | ||
Offset | Offset Description (type) | Notes |
0x4 | Flags (u32) † | unsets 0x02000000 bit |
0x24 | X-coordinate (float) †† | writes Link's X-coordinate |
0x28 | Y-coordinate (float) †† | writes Link's Y-coordinate |
0x2C | Z-coordinate (float) †† | writes Link's Z-coordinate |
0x6C | Gravity (float) ††† | writes 0xBF666666 |
0x88 | bgCheckFlags (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.)