Tcl Interactive Fiction Engine

being revised May 2006
Google site search


1   Introduction

This project is a Tcl/Tk version of an IF authoring system. This system uses a Tcl text widget as the space in which the IF is "read". Tcl text widgets can display more than simple text. Text can be formatted according to special tags. In addition windows and widgets can be embedded in a text widget. While this allows plenty of scope for development, the text widget is essentially a one dimensional medium consisting of lines of objects. It does not have the two dimensional properties of a canvas widget or of an HTML page. For the purpose of Interacive Fiction, this is no handicap, because fiction is by nature a one-dimensional stream of information. It is the way that this stream is manipulated that is the interesting aspect of Interactive Fiction.

2   Overall Design

Tcl provides a lot of simple underlying structures which help make building an Engine (Authoring System) quite easy. In particular it has excellent error tracing facilities. It also allows for the generation of new objects and structures on the fly as required. Being an intretive language there is no compile phase as with other IF engines.

The basic requirement for reading IF is a console system. The Fiction is written out on the console until a prompt is produced, prompting the reader to issue a command. Tcl's Window shell (wish) is an ideal console system except for one small problem. The reader needs to be able to write in a protected environment in which all commands are particular to the IF system. The wish console does not provide this hemetic environment, because as well as the Fiction commands, it also responds to Tcl commands. For example, the command [exit] is a Tcl command which is also commonly used in IF. Therefore the reader needs to be protected from accidentally invoking Tcl commands, or of the IF server inadvertently replacing Tcl commands that it needs to have access to, with Fiction commands used in the story. This is managed by using a slave interpreter under the main engine which has all its Tcl commands removed and only IF commands implemented. Then all the players commands are executed in the slave intepreter.

The Wish Console is a slave interpreter for which the master interpreter is not accessible in order to implement the kinds of features that are required. Instead, the equivalent slave interpreter console is implemented in a text widget. The master intepreter code is accessible in the Tcl code and can be altered as required to create the hemetic environment for the reader.

The master interpreter owns the text widget and monitors the writing of the reader's commands into the text widget. The master interpreter also creates the shell slave interpreter which is created with the full set of Tcl and Tk commands. Every command line entered by the reader is caught by the master interpreter which evaluates the command inside the shell slave interpreter. A handful of shell slave interpreter commands are redefined. In particular the [puts] command is altered so that its results are output to the text widget instead of stdout.

The shell slave is then equipped with all the commands required to support the IF being run. This consists mainly of an object handling mechanism. It creates new objects of every type, including characters, the reader, places, clothes, movable objects, containers etc. The object handler does not recognise these different types of objects however, it is rather more general than that. It simply allows attributes to be assocaited with objects, and for actions to be defined which effect objects and their attributes in ways which are generally appropriate.

Finally, come the game or Interactive Fiction itself. This consists of two parts. Additional support for the specifics of how objects in this particular game operate, for instance places, clothes and moveable objects. Finally come the commands that the reader uses to interact with the story. This "language" is placed in its own namespace so that its commands do not replace other shell commands with the same name.

The master interpreter checks that a reader's command is a valid command in the namespace command and then executes it in the reader's command namespace of the shell intepreter. Because the commands are executed in their namespace, procedures in the name space have to reference Tcl commands explicitly as [::command] in order to avoid potential conflicts with local commands.

3   The Text Widget Console

4   The Slave Interpreter

5   Objects

The [object] command manages objects. An object is quite literally that, any thing, that can be used as a noun in a sentence.

5.1   NAME

object - Create and manipulate Interactive Fiction objects


object name function ?options?


An object has a name and eight kinds of attribute; description, classes, contents, functions, exits, wears, location, state and article. In practice some attributes apply only to particular classes of object, for example exits tends to apply only to the place class, and wears only to the actor class. But there really are no rules here.

desc - Description is the detailed description of the object rendered by a reader's verb such as look or examine. A description can be set setdesc or described describe.

class - Classes is a list of words that represents classes that this object belongs to. Tests are then made against the object's classes to determine if it is of an appropriate class to be subject to some particular kind of treatment. An example is the attribute place for all locations, or actor for all characters. Attributes can be set using the -class option of the new function, added to using addclass, removed using remclass, listed using getclass. The object may be queried for a list of attributes using hasclass.

objs - Objects is a list of object names that this object contains. A room may contain actors, including the reader, and a box may contain small objects. This list is also used by actors for holding objects which are "taken". This list is manipulated during the course of the story as the reader moves from place to place and moves objects from one place to another. The functions insobjs, remobjs, getobjs and hasobjs work like the similar attribute functions.

Functions is a list of procedures (methods) which are available for this object. As an example, the reader command might be use axe on dwarf. use is the function which was defined, axe is the object for which the function was defined and on dwarf is the argument list args passed to the function. To set this up object dwarf define use { command body using args } is used. The command body would typically identify the target of the axe and output appropriate action depending on the type of target. Each object function generates a procedure called $object-$function. Methods are added using the define function, and are invoked using the do function.

exits - Exits is a list of place objects that is immediately accessable from this place object. This list is manipulated by the functions addexits, remexits, getexits and hasexits.

wears - Wears is a list of "wear" class objects which the actor is wearing. Typically the process of "wearing" is a special version of "taking" in which, once taken, the object is checked to see if it is a "wear" object, in which case it is moved to the Wears attribute list. The corresponding functions addwears, remwears, getwears and haswears are used to manipulate this attribute.

Location is initially defined using the new -where option. It would typically be a singleton list of a place object. In some games, an object may be able to exist in multiple places if the author chooses to allow for this. The moveto, enter and exit functions are used to manipulate the location of objects.

State is used as a linguistic convenience to describe the objects relationship to its location. in a room, on a table, under a bed and so on. It is typically used in phrases such as $object is state location. It is accessed using the functions setstate and state.

Article is also used as a linguistic convenience. An article is initially set using new -article and its value accessed using the article function. This attribute cannot be manipulated.


name new ?options?
Creates an object known as name and initialises its nine attribute lists. All attributes default to "" the null list, except for State which defaults to "in" and Article which defaults to "a". The nine attribute lists may be initialised by using option pairs to set their values:
  • -desc list to set the Description attribute
  • -class list to set the Classes attribute
  • -contents list to set the Contents attribute
  • -where list to set the Location attribute
  • -exits list to set the Exits attribute
  • -wears list to set the Wears attribute
  • -define list to set the Define attribute
  • -article list to set the Article attribute
  • -state list to set the State attribute

name setstate args
Sets the State attribute, overwriting the previous value. Returns the new attribute value.

name state
Returns the State attribute value.

name article
Outputs the current Article attribute value.

name setdesc args
Sets the Description Attribute overwriting the previouc value. Returns the new attribute value.

name describe
Returns the Article and Description attributes as a noun phrase.

name addexits args
Adds these exits to the Exit attribute list. Returns the value of the entire list.

name remexits args
Removes elements from the Exits attribute list. Elements may be referred to by numeric index or by exact character value. Returns a null value.

name getexits
Returns the value of the Exits attribute.

name hasexits args
Returns 1 if all the args exist in the Exits attribute list.

name addattrs args
Adds the attributes to the Attributes attribute list. Returns the value of the entire list.

name remattrs args

name getattrs

name hasattrs args

name insobjs args

name remobjs args

name getobjs

name hasobjs args

name where

name take args

name drop args

name don args

name doff args

name wearing

name has_on args

name moveto args

The moveto function can be used to move objects to accessable places, or from one place to another. It handles several cases:

  • A defined moveto function for that object.
  • Moving the reader to another place accessable from this place.
  • Moving the reader or an object to another object in contained in the object. As in put umbrella on hallstand. This is in fact the enter function.

    name enter args

    name exit ?args?

    name define args

    name do function ?args?

  • 5.5   Object design

      There are three main features associated with object design:
    1. The way that objects may relate to each other in the story
    2. The way that objects may be manipulated in the story.
    3. The linguistic requirements for rendering the story.

    The way that objects relate to each other depends rather on the types of objects which are required to be manipulated by the story. The adventure genre favours maze-like locations. But more developed IF depends more on event synchronicity.

    Nevertheless, location, is a primary structure in any story. The idea of stories which are devoid of location is an interesting exercise. Objects typically have only one location, and locations themselves typically have only one parent location (region).

    6   An Interactive Fiction Engine

    Larry Smith has provided a base engine to use to write stories. With the Tcl plugin you can play a game right here.
    ©2000 - 2006 WEBSCOOL This page last updated 19 May 2006. All rights reserved - including copying or distribution of any portion of this document in any form or on any medium without authorisation. For more regarding the copyright.