A-code undo/redo facility

If the game defines UNDO as a verb, then the undo/redo A-code mechanism gets activated for that game. The REDO verb is then defined automatically, though it can be also defined by the game explicitly as a verb. In such circumstances, defining REDO as anything other than a verb is treated as an error. REDO can be used immediately after an UNDO command, to undo some or all of the UNDO.

The general form of UNDO and REDO commands is as follows:

verb UNDO [{||ALL|UNDO}
verb REDO [{||ALL}

The default number of turns to undo or redo is one, though a specific number can be specified. ALL means just that – undo all collected turn history or undo all of the preceding UNDO. "UNDO UNDO" is equvalent to REDO ALL.

Information on the effects of an UNDO/REDO command is returned by an automatic variable UNDO.STATUS, which may but need not be explicitly defined by the game's code. The variable is considered to have four automatically declared flags:

UNDO.INFO
This flag is defined but not used by the kernel. It may be used by the game's code e.g. to enable or disable use of UNDO and REDO commands.

UNDO.TRIM
Set if requested number of turns has been trimmed. The value of UNDO.STATUS is ste to the actual number of turns undone or redone.

UNDO.INV
Set if inventory contents changed, so that the game can note the fact. There is no equivalent flag for change of location, because that can be checked by the game's code by preserving the HERE value in a local variable and then it with the value of HERE after the UNDO/REDO.

UNDO.BAD
Set if the UNDO/REDO is given an illegal argument.

Undo history is saved and restored as a part of game saving and restoring. However, should the game's number of objects, locations or global variables change, the undo history of games saved by an earlier version will be quietly ignored.

Here is a simple example of using UNDO:

action undo
  local uhere
  set uhere, here       # Preserve value of HERE in a local variable
  undo arg2             # Do the UNDO!
  ifgt undo.status, 0   # Something got undone
    ifflag undo.status, undo.trim
      say "Cannot undo that many turns!"
    fin
    say "Turns undone: $\n.", undo.status
    ifne here, uhere
      say "You have relocated!"
    fin
    ifflag undo.status, undo.inv
      say "Your possessions have changed!"
    fin
    quit
  else                  # Nothing undone
    quip "Nothing happens."
  fin

Back to the A-code page

To the Mipmip home page
Feel free to leave a comment!
Mike Arnautov (26 February 2019)