Skip to content

Prevent softlock when Hookshot cannot spawn on equip - #2571

Merged
fenhl merged 2 commits into
OoTRandomizer:Devfrom
djevangelia:softhook
May 31, 2026
Merged

fenhl merged 2 commits into
OoTRandomizer:Devfrom
djevangelia:softhook

Conversation

@djevangelia

@djevangelia djevangelia commented May 9, 2026 •

Copy link
Copy Markdown

If Hookshot actor cannot spawn, use item none to prevent softlock. Half-fixes #2006.

If the Hookshot item overlay or actor cannot spawn when changing item, player gets softlocked. This can occur due to memory shortage (such as the Hyrule Field glitch) or the object not being loaded (if child; it requires adult Link object). The function that spawns the Hookshot, Player_InitHookshotIA, doesn't check whether the actor was successfully spawned.

This fix makes so that if the actor doesn't spawn, Player_UseItem is called with item none (0xFF) to change to a different item. This fixes both adult Link and child Link softlocking.

Disassembly

NTSC 1.0 matching disassembly for Player_InitHookshotIA here
Decomp C code:

void Player_InitHookshotIA(PlayState* play, Player* this) {
    this->stateFlags1 |= PLAYER_STATE1_HOLDING_RANGED;
    this->unk_860 = -3;
    this->heldActor =
        Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_ARMS_HOOK, this->actor.world.pos.x,
                           this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 0);
 // add NULL check here: if (this->heldActor == NULL) Player_UseItem(play, player, ITEM_NONE);
}

Testing

Tested in Ares recent nightly build and Project64 3.0.1.
Looks like this: https://www.youtube.com/watch?v=kXxg5GH9IZc

It can be tested as child by force-equipping Hookshot to C button, such as pressing D left with this added to debug_utilities:

if (z64_game.common.input[0].pad_pressed.dl) {
    z64_file.button_items[1] = Z64_ITEM_HOOKSHOT;
}

For Hyrule Field, I spawned extra actors to fill memory. I used the object loading function from my Ice Trap PR to spawn Like Likes (take enormous memory due to a 0x2000 unused space in their actor), and extra trees.

if (z64_game.common.input[0].raw.pad.dl && z64_game.common.input[0].raw.pad.a) {
    z64_game_t* play = &z64_game;

    z64_SpawnActor(&play->actor_ctxt, play, 0x77, z64_link.common.pos_world.x+50.0,
                    z64_link.common.pos_world.y, z64_link.common.pos_world.z+50.0, 0, 0, 0, 5);
    //Object_LoadExtra(play, 0xd4);
    //z64_SpawnActor(&play->actor_ctxt, play, 0xdd, z64_link.common.pos_world.x+50.0,
    //                z64_link.common.pos_world.y, z64_link.common.pos_world.z+50.0, 0, 0, 0, 0);
}

djevangelia added 2 commits May 9, 2026 10:31
Hook into Player_InitHookshotIA
Asm check if Hookshot actor is NULL
If so, Player_UseItem item none
@fenhl fenhl added Type: Bug Something isn't working Component: ASM/C Changes some internals of the ASM/C libraries Status: Needs Review Someone should be looking at it labels May 9, 2026
@shirosoluna

Copy link
Copy Markdown

Hopefully trying to prevent softlocks should mitigate the worst consequences. I've had it crash in my decomp build, which is very cluttered and where the entire Hyrule Field is in a permanent state of glitch. Does this ever crash during normal gameplay?
But regardless, there is also the issue of not being able to bomb grottos/bombiwa because the bomb actor can't spawn.
As said, newer versions/PAL try to fix the memory issue by shrinking the space allocated for objects: decomp code here. This is easy to add and should not have consequences, the unused object memory space is fairly big in Hyrule Field.
Another possibility is on actor spawn/overlay load, check how much memory is remaining in the Zelda arena, and cancel depending on how much memory is left, which actor/overlay is loading... however, I believe fragmentation could play a role, too, so I'm not sure how much it would help.

copying this new comment from the issue

since this does not actually resolve the hyrule field glitch from occuring, I dont know if this is worth. You could pull any actor and cause a weird interaction. It reacts in weird ways, from sound to explosives or removing cutscene parts from what I've read. Hookshot being extra special
https://www.youtube.com/watch?v=TqMJYWGPIqk

it would be worth scrolling thru discord to see how many times just loading the boulder coming from the bottom of the map to remote grotto generating a crash would be. It's been awhile since hearing about it (and I've only experienced it maybe 1-2 times myself in rando).

Not really in favor of the force unequipping as a quick and dirty fix for this issue.

some discussion from fig on how the memory overflow and heap with hookshot interaction.
https://discord.com/channels/82938430371139584/102533701761503232/1008848957578940550

also would be nice to determine how this affects the heap fragmentation usage in other locations in gameplay_keep. Which was my other question.
While I don't think it should, it would be helpful to know for sure.

devs can review it and determine if they want this or not, this is just my opinion.

@djevangelia

Copy link
Copy Markdown
Author

since this does not actually resolve the hyrule field glitch from occuring, I dont know if this is worth. You could pull any actor and cause a weird interaction. It reacts in weird ways, from sound to explosives or removing cutscene parts from what I've read. Hookshot being extra special https://www.youtube.com/watch?v=TqMJYWGPIqk

Difference being that Hookshot softlocks the game, making the player unable to continue playing.

Not really in favor of the force unequipping as a quick and dirty fix for this issue.

The issue is not the memory shortage. The issue is that the game doesn't check if the Hookshot actor spawns or not, which results in a softlock that prevents the player from playing the game. This does not depend on why the actor cannot spawn - memory shortage, or the correct object not being loaded, will cause this.

As for memory shortage/Hyrule Field glitch, considering this has been a known problem for over 20 years and considering no fix has been made for it yet, I believe it is better to start off with a short fix that isn't specific to the memory shortage issue (and honestly just is what should have been in the base game - see below regarding MM) that prevents one fatal consequence of it. (This is not in any way intended to undermine the hard work of all contributors here and to other hacks! Merely an observation that a fix to prevent memory shortage problems will not come soon.)

some discussion from fig on how the memory overflow and heap with hookshot interaction. https://discord.com/channels/82938430371139584/102533701761503232/1008848957578940550

Thanks for informational link. It is also revealed in the discussion that Majora's Mask actually already has exactly this change, it's as if copy-pasted.

also would be nice to determine how this affects the heap fragmentation usage in other locations in gameplay_keep. Which was my other question. While I don't think it should, it would be helpful to know for sure.

If the actor doesn't spawn there is no change of the heap.

@fenhl fenhl added Status: Waiting for Release This PR is ready for merge, but we're holding off on it until after the next release and removed Status: Needs Review Someone should be looking at it labels May 10, 2026
@flagrama

Copy link
Copy Markdown

I only want to point out that it can softlock the game if you have no momentum or if your momentum doesn't take you anywhere that eventually results in a scene transition. I don't think anyone has ever done anything useful with the glitched state though, so that probably doesn't matter too much.

@fenhl fenhl removed the Status: Waiting for Release This PR is ready for merge, but we're holding off on it until after the next release label May 31, 2026
@fenhl fenhl added this to the next milestone May 31, 2026
@fenhl
fenhl merged commit 9c31190 into OoTRandomizer:Dev May 31, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: ASM/C Changes some internals of the ASM/C libraries Type: Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants