ink icon indicating copy to clipboard operation
ink copied to clipboard

How to manipulate condition evaluations

Open fawcilize opened this issue 3 years ago • 0 comments

I wanted to write a script to traverse through the whole story and run a check on each knot. Here is what I have so far:

const visitCounts: { [key: string]: number } = {};

function recurseStory(story: Story) {
  while (story.canContinue) {
    story.Continue();
  }

  for (let i = 0; i < story.currentChoices.length; i += 1) {
    const targetPath = story.currentChoices[i].targetPath!.toString();
    visitCounts[targetPath] = (visitCounts[targetPath] || 0) + 1;

    // Only want to hit each knot once, and the story has infinite looping in some places
    if (visitCounts[targetPath] < 2) {
      // Save and load state to handle each new path in an isolated environment
      const saveState = story.state.ToJson();
      story.ChooseChoiceIndex(i);
      recurseStory(story);
      story.state.LoadJson(saveState);
    }
  }
}

recurseStory(story);

This works for happy paths but doesn't handle paths hidden by conditions. Example:

=== some_knot ===
{ external_function(variable): -> some_true_knot | -> some_false_knot }

or

=== some_knot ===
{ external_function(variable): 
- "Banana": -> some_true_knot
- "Pajama": -> some_false_knot
}

since the return value for external_function(variable) is true, the script doesn't traverse some_false_knot

I'm trying a figure out a way that I can intercept conditions to change the result of the story without having to modify external functions because we have a lot of them with many variations. Basically, the end goal is to traverse through every path of the story, but I'm not sure how based on the documentation.

I was trying to mock some of the internal functions as a last resort, but I'm not sure I'm modifying the correct code:

  const original = story.PerformLogicAndFlowControl.bind(story);
  story.PerformLogicAndFlowControl = function (contentObj) {
    if (contentObj instanceof Divert) {
      if ((contentObj as typeof Divert).isConditional) {
        story.state.PopEvaluationStack();
        return false;
      }
    }
    return original(contentObj);
  };

fawcilize avatar Oct 19 '22 20:10 fawcilize