TADS Overview: The Language

TADS approaches IF design from a programmer's perspective. Creating Interactive Fiction is an unusual hybrid of writing prose (the Fiction part) and programming a computer (the Interactive part). The two aspects are not only essential by themselves, but intertwined; much of the text has to be infused with live behavior, meaning programming code, and the programming code is ultimately all about generating text. The goal of any IF authoring system is to unify the two tasks in a way that less specialized tools cannot. With TADS, we set out to take the kinds of tools that programmers already know, and specialize them for writing IF.

TADS starts with a programming language that closely resembles C, C++, Java, and Javascript. TADS is faithful to C's core procedural syntax, and even includes meticulously complete support for ANSI C macros. If you know C or Javascript, you pretty much already know the TADS procedural syntax.

  local sum = 0;
  for (local i = 1 ; i <= lst.length() ; ++i)
    sum += lst[i];

  return sum;

The programming model is similar to Javascript's. It's highly dynamic and excels at incremental development, which is how most people write IF. TADS doesn't force you to deal with low-level memory management details, as C and C++ do, and it doesn't have a rigid compile-time type system like Java's. Instead, like Javascript, TADS has run-time typing, high-level datatypes such as strings and lists and lookup tables, anonymous functions (closures), and an automatic garbage collector that takes the drudgery (and most of the common pitfalls) out of memory management. TADS has a prototype-based object model with multiple inheritance. It also has advanced features such as variadic functions, reflection, regular expressions, and high-precision arithmetic.

The big thing that sets IF authoring apart from ordinary programming is that an IF has at least as much data as code. Not just text, but also the structured objects that define the geography and contents of the game world. General-purpose languages almost all treat data as something external that's held at arm's length from the code. IF languages like TADS recognize that the code and data are both integral parts of the game and must be defined together.

A lot of the data in an IF can be thought of in terms of the physical objects that make up the game world: rooms, items, creatures, characters. TADS caters to this way of organizing a game, providing concise syntax for entering one-off object definitions.

path: Room 'Path'
    "Frequent foot traffic has worn a clear north-south path
    through the underbrush here. "

    north = clearing
    south = outsideCave

    cannotTravel() {
      "Tangles of bramble bush make it too difficult to
      stray from the path. ";
+ Decoration 'bramble bush/bramblebush/underbrush/brush' 'underbrush'
    "Tangles of bramble bush line the forest floor, broken
    only by the narrow path. "

Note how we've mixed code and data in the room definition. TADS doesn't divide things up into classes with code and instances with data, as traditional OO languages do. The prototype model allows code and data to mingle freely at the object level.

In addition to creating structured objects, writing IF also involves writing a lot of text. Most C-like languages make it tedious to enter long text passages; TADS makes it easier by letting a quoted string go on for as many lines as it needs.

"A deep, concrete-lined canal is to the east; metal rungs
are set into the wall, forming a ladder down into the canal.
A tall fence topped with razor wire is to the north.

<p>Pipes and conduits are everywhere, packed so tightly
together that they form walls.  Narrow openings in the pipes
allow travel to the southeast and southwest.  To the west, a
cylindrical tower rises up out of the pipes and looms several
stories overhead; a spiral stairway encircling the tower
leads up.  The ground is replaced by a metal grating for the
ten feet around the tower. ";

The text in IF isn't necessarily static, either. A lot of the text in a game describes locations or items that can change in the course of a session. Such text has to change along with what it describes. Sometimes that means a simple insertion at a strategic point:

desc = "The sphere is pulsating with a glowing <<color>> light. "

Other times it's a conditional:

desc = "The door is currently <<isLocked ? "locked" : "unlocked">>
   and <<isOpen ? "open" : "closed">>. "

This just scratches the surface, of course. The TADS language has many other subtle and not-so-subtle specializations designed to make IF authoring easier and faster.

Overview Main | Next: Object Library