Skip to content

talkActor not unset in noclip update, stale reference/softlock risk #98

@djevangelia

Description

@djevangelia

During practice player enters a softlocked state twice after exiting noclip in Lost Woods: https://www.youtube.com/live/Hzq_j0N8O6g?t=8153s
I was able to replicate this in modified decomp build with vanilla noclip function: https://www.youtube.com/watch?v=DJisIo4FMBU

player->talkActor is set by NPC when player gets in range by Actor_OfferTalkExchange. This is normally unset by this code in Player_Update:

    if (ACTOR_FLAGS_CHECK_ALL(&this->actor, ACTOR_FLAG_TALK)) {
        this->talkActorDistance = 0.0f;
    } else {
        this->talkActor = NULL;
        this->talkActorDistance = MAXFLOAT;
        this->exchangeItemId = EXCH_ITEM_NONE;
    }

As both gz and vanilla noclip replace the normal update function, the current talkActor pointer is never unset unless player gets close to another talk NPC. If the talkActor is unloaded any new data there will be used. There are textbox IDs that softlock, and an actor flag that forces player to talk. If these are "set" in the data, and player exits noclip on the ground, player will forced into talk and be unable to move (can void with noclip).

Very niche situation that can be avoided by exiting noclip in the air. However I do believe setting player->talkActor to NULL in the noclip update function (maybe even all 3 above) would prevent this without any gameplay consequences. The frame you exit noclip any nearby NPC will set talkActor again. Also, the pause menu (z_kaleido_scope.c) for case PAUSE_STATE_RESUME_GAMEPLAY also sets talkActor to NULL, which is a similar case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions