Input Scripts

The TADS Interpreter normally reads its input directly from the computer's human input devices - primarily the keyboard, but sometimes also the mouse, if one is present and the local Interpreter supports it.

Sometimes, though, it's useful to be able to read from a previously prepared list of inputs rather than from the user. One situation where this is helpful is during development: you can use a script to enter all of the commands needed to reach the part of the game you're actively working on, saving you the trouble of re-entering those commands manually every time you start a new test run after making changes. Another situation is testing: you can use a script to run through the game to make sure that it produces the correct output.

The Interpreter provides "script" files for this purpose. A script file is simply a text file with a list of command inputs. When you tell the Interpreter to read from a script file, it reads the commands from the file, and returns them to the game as though they were coming directly from the keyboard. The game doesn't know the difference; as far as the game is concerned, the user is typing the commands.

Replaying a script

There are two way to replay a script: via the interpreter command line, or through a call to the setScriptFile() function.

Replaying via the interpreter command line

You can start reading a script immediately when you start the game by using the Interpreter's -i option. Refer to Running Programs for information on this option.

The Interpreter -i option causes the game to read from the script starting with the very first command line. On operating systems with "batch" or "command script" features, this lets you create automated processes, such as test suites, that run without any user intervention.

Replaying via setScriptFile()

The intrinsic function setScriptFile() lets you start reading from a script under program control. Refer to the tads-io Function Set for details on this function.

The adv3 library uses setScriptFile() to implement the REPLAY command, which you can use to invoke a script from the game's command prompt.

Recording a script

The Interpreter has a couple of features that let you record a session as you play through a game manually. The interpreter creates a file containing the commands and events you enter as you play.

To create a script from an entire session, use the Interpreter's -o option. This causes the Interpreter to write events throughout the session to the file. See Running Programs for details on Interpreter options.

If your game is based on the adv3 library, you can use the RECORD command to record a script. This command starts recording events starting with the next command line.

You can also start recording a script under program control, using the setLogFile() function with the LogTypeCommand or LogTypeEvent type codes. LogTypeCommand creates a Command-line script, and LogTypeEvent creates an Event script (see below). The adv3 RECORD command uses this function internally.

Script file structure

This section explains how to create a script file manually. In most cases, you'll probably want to create your script files using one of the "recording" features (such as the -o Interpreter option, or the adv3 RECORD command), but you might sometimes want to create a script file on your own, or edit a script you recorded.

There are two kinds of script files: Command-line scripts and Event scripts. Interpreters prior to 3.0.13 only support Command-line scripts; 3.0.13 and later versions support both kinds of script.

Command-line scripts

A command-line script contains regular input lines. This means that when the Interpreter is reading from a command-line script, it must still pause for user input, directly from the keyboard or mouse, whenever the game attempts to read any other kind of input event - inputEvent(), inputDialog(), inputFile(), and so on.

Each line of a command-line script is either a comment or an input line.

An input line starts with a > character (a greater-than sign) as its very first character; the rest of the line is the text of the input. The interpreter reads the line and returns it to the game as though the user had typed it at the keyboard and pressed Enter.

Any line that doesn't start with > is a comment line. The interpreter simply ignores these lines.

Here's a sample Command-line script.

This is a comment, since it doesn't start with ">"

>look
>inventory
>quit
>yes

Event script

Unlike a Command-line script, an Event script can contain any type of input event that the game can read. This means that an Event script can run without any user input.

Event scripts are supported only in version 3.0.13 and later of the Interpreter.

An event script is identified with this text as its very first line:

<eventscript>

When the Interpreter starts reading a script, it checks the first line to see if it contains this text. If so, it treats it as an Event script; if not, it treats the script as a regular Command-line script.

After the initial <eventscript> line, the rest of the file contains event lines and comment lines. An event line starts with an event type tag; everything else is a comment line. The Interpreter ignores comment lines.

An "event tag" is one of the following:

Here's a sample Event script.

<eventscript>
<line>look
<line>inventory
<line>save
<file>test.t3v
<line>help
<key>[down]
<key>[enter]
<key>[esc]
<line>quit
<line>y

Overwrite warnings in <file> events

When inputFile() reads a <file> event from a script, the function checks the following conditions:

If all of these conditions are true, then inputFile() momentarily suspends the script playback and displays a warning dialog to the user. This dialog is displayed interactively, even though a script is being played back, and the user must respond before script playback can continue.

The dialog warns that the script might be about to overwrite the named file, and asks if you'd like to proceed. You have three options: Yes, No, or Cancel:

The reason for this extra interactive prompt is to prevent script playback from overwriting a file without the user's knowledge or consent. The whole point of script playback is to reproduce the same sequence of events repeatedly, but this can be problematic when one of the events supplies a filename that's then used to create a new file: if the script is run more than once, the file will be created anew on each subsequent run, overwriting any data written to the file on previous runs.

In some cases, you might want to skip the interactive prompt, but still overwrite any existing copy of the file. This is especially likely if you're using a script for automated testing. In such a case, you probably specifically designed the test to create the same output file on each run, so you specifically intend for the test to overwrite the file each time; and you want the test to run automatically, with no user intervention. In such a case, you can put instructions directly in the script that the overwrite is to proceed without a prompt. To do this, edit the script file, and add the "overwrite" attribute to the <file> element:

<file overwrite>myfile.txt

This tells the script reader that you explicitly intend to overwrite the file on each run, so no interactive prompt is necessary. Note that adding the "overwrite" attribute doesn't require the file to exist - it merely suppresses the warning if it does.