Skip to content

Backtracking

SetText supports a system called dialogue backtracking which allows in Dialogue mode to see previous textbox that have been passed in the same SetText call. This system only works correctly in Regular Letter Rendering because in Single Letter Rendering, it will not accumulate any letters to the history.

This system is mainly possible using some important static field of MainManager:

  • currentdialogue: Stores the index of the current textbox text being displayed (counted from 0).
  • diagstring: Stores the textbox backtrack history. This includes the textbox SetText is waiting on if a backtracking is initiated.
  • tempdiag: Accumulates a stripped version of the current textbox text until it is done so it can be added to diagstring.
  • backtacking: Tracks if a backtrack is in progress.

Everything starts by tracking the current textbox using tempdiag which serves as an accumulator. During Dialogue setup, it is set to |size,size.x,size.y| which serves as the starting value using the size values. Then, it will accumulate every letters (except in Single Letter Rendering where it's not supported) and spaces during processing, but only a subset of the commands will be accumulated. These commands are:

Any other command will not be accumulated to this static field.

The storage of the textbox in diagstring only happens upon a next or goto command which delimits what constitutes a textbox in backtracking. At the end of processing either command, currentdialogue is incremented and tempdiag added to diagstring.

Additionally, tempdiag is reset to its starting value which is |size,size.x,size.y|. This is enforced by the ResetDiag method:

private static void ResetDiag()
private static void ResetDiag(bool soft)

Sets tempdiag to |size, + fontdsize + |. This is the starting value of tempdiag where no backtracking is in progress. If soft is false, diagstring is reset to a new empty list and currentdialogue is reset to 0.

The parameterless overload behaves as if soft was true.

Every time next is processed, but before adding the textbox to diagstring, it will yield control to MainManager's Update by grabbing waitinput. This is where the game allows a backtracking to be initiated, but only after at least one textbox has passed. It is also possible to backtrack on the last textbox if an end command has not been processed. Additionally, It is possible to disable any backtracking for happening by using the Lockbacktrack command.

Once a backtrack is initiated, the ShowBackDialogue method gets called:

private static void ShowBackDialogue()

It destroys all the child of textbox and calls SetText in non dialogue mode to show |color,7| followed by diagstring[currentdialogue] (where all double and triple spaces are removes as well as removing the leading space if one is present). This method is used when a backtracking is requested on Update during the course of a SetText call in dialogue mode.

The current line that SetText is waiting on waitinput to be released is added to diagstring, currentdialogue is decremented and backtacking is set to true. The reason adding the current line is done is because since it has already been processed by SetText, waitinput can only come back to false once that current line is passed during a backtrack. The only way for this to happen is if the current line is added to backtracking itself in diagstring.

From there, it is possible to freely go back and forth between the lines in diagstring which is tracked by currentdialogue that gets incremented and decremented accordingly. To render the text, all child of the textbox gets destroyed which blanks it and a separate SetText call is performed with the appropriate line from diagstring. This call is done with the string prepended with |color,7| on the same textbox as the parent. This occurs in non dialogue mode which prevents conflicts with the fields mentioned above. This all happen every time a change in the textbox is performed.

Once the last textbox from diagstring is passed, MainManager's Update detects that currentdialogue and diagstring.Count are the same upon passing the textbox and releases the waitinput. This causes the original SetText call to resume, but since backtacking hasn't been set to false yet, it knows to not add the current textbox since it has been added to diagstring already. At the very end of the next processing, backtacking is finally set to false which allows SetText to continue processing as if nothing happened.