Skip to content

YarnSpinner DLLS >= 3.10 Timing issue with VirtualMachine.Continue can cause permanent hang #116

@dogboydog

Description

@dogboydog

What is the current behavior?

Please provide the steps to reproduce, and if possible a minimal demo of the problem:

https://github.com/YarnSpinnerTool/YarnSpinner-Godot/pull/118/changes#diff-ace6b3352f8636943d9eaa62c1d1ceae5907f7e1d71141e1661cee55ee0d1558

The same DialogueRunner code does not work in YarnSpinner-Godot when upgrading to 3.1 or 3.2 of the base libraries. When any command is issued, the dialogue hangs forever. I currently have a workaround in the above PR of waiting a frame after commands complete, which prevents the issue.
Workaround in OnCommandReceivedAsync:

        await YarnTask.NextFrame();
        if (!IsInstanceValid(this))
        {
            return;
        }
        Dialogue.Continue();
    }

Here is the sequence of events as I see in my debugger. Seems like there is an unintentional breakage here to me since without any code changes to the dialogue runner and just upgrading the DLLs, it breaks like this (Unless it's intended that DialogueRunner changes are required for compatibility, but last time we talked about this it didn't sound like that was the case)

Any sample with commands will demonstrate it, but VisualNovel starts with a command so it shows the issue right away

StartDialogue() calls Dialogue.Continue() which calls VirtualMachine.Continue()
this sets isContinuing to true() and falls into this block

        while (this.currentNode != null && this.CurrentExecutionState == VirtualMachine.ExecutionState.Running)
        {
          this.RunInstruction(this.currentNode.Instructions[this.state.programCounter]);

The command completes : OnCommandReceivedAsync is called , which calls Dialogue.Continue() , but isContinuing is true, so VirtualMachine.Continue() immediately returns

Image

Then the finally block in VirtualMachine runs, unsetting this.isContinuing , but the command finishing has already been ignored, so dialogue hangs forever

Image

More detail where the command finishing triggers continue() (which returns early due to this.isContinuing still being true) currentExecutionState is DeliveringContent, then , I see the original call to Continue move from

this.RunInstruction(this.currentNode.Instructions[this.state.programCounter]);
          ++this.state.programCounter;

to

More detail where the command finishing triggers continue() (which returns early due to this.isContinuing still being true) currentExecutionState is DeliveringContent, then , I see the original call to Continue move from
this.RunInstruction(this.currentNode.Instructions[this.state.programCounter]);
          ++this.state.programCounter;

... however now the currentExecutionState is Waiting for continue, which means the while loop exits, and VirtualMachine.Continue() is never called again

Image

What is the expected behavior?

The same DialogueRunner code would work without needing to wait a frame after commands complete.
Please tell us about your environment

  • Operating System: Observed on Linux, Windows, Mac
  • Yarn Spinner Version: 3.10 >
  • Extension Version: n/a
  • Unity Version: n/a

Other information

Add tags

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething not working as intended

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions