TAME (Text Adventure Module Engine) is an Interactive Fiction Engine that assists in the creation of Interactive Fiction. What sets TAME apart from most authoring tools is that it is not so much an all-in-one-authoring package with audio-visual hooks, but rather a single piece of logic that maintains a game state and interprets user input.
TAME Modules are written in a language called TAMEScript.
TAMEScript is what every TAME Module is written in. Through TAMEScript, you can define every part of your world: the players inside it, what rooms the players can visit, the objects in the world, and what happens when you interact with them via actions. In essence, you are creating the rules and the environment in which your piece of Interactive Fiction takes place.
A TAMEScript module can be as small as:
world
{
start()
{
textln("Hello, world!");
}
}
Or it can contain a bunch of things!
module
{
title = "A Small Adventure";
author = "Matthew Tropiano";
email = "email@somesite.com";
}
action general a_quit named "quit";
action general a_look named "look around", "look", "l";
action transitive a_take named "take", "pick up", "t", "p";
action transitive a_examine named "look at", "examine", "x";
action transitive a_open named "open", "o";
action ditransitive a_use named "use" uses conjunctions "with", "and";
// The KEY!
object o_key named "key", "small key"
{
onAction(a_examine)
{
textln("Looks like a small key.");
}
onAction(a_take)
{
if (!hasObject(player, this))
{
giveObject(player, this);
textln("You take the key.");
}
else
textln("You already have this.");
}
onRoomBrowse()
{
textln("There's a key, here.");
}
onPlayerBrowse()
{
textln("A key.");
}
}
// The DOOR!
object o_door named "door" uses determiners "the"
{
init()
{
locked = true;
}
onAction(a_examine)
{
textln("Looks like a wooden door.");
addObjectName(this, "wooden door");
}
onActionWith(a_use, o_key)
{
if (locked)
{
locked = false;
textln("You unlocked the door!");
}
else
{
textln("The door is already unlocked.");
}
}
onAction(a_take)
{
textln("You can't pick up a door.");
}
onAction(a_open)
{
queue a_use, this;
}
onAction(a_use)
{
if (locked)
textln("The door is locked.");
else
{
textln("You open the door.");
world.win = true;
}
}
onRoomBrowse()
{
textln("There's a wooden door, here.");
}
}
// YOU!
player p_guy
{
function oops()
{
local x = irandom(3);
if (x == 0)
textln("I can't do that.");
else if (x == 1)
textln("I don't understand.");
else
textln("I don't think so.");
}
onUnhandledAction()
{
oops();
}
onMalformedCommand()
{
oops();
}
onUnknownCommand()
{
oops();
}
onIncompleteCommand()
{
oops();
}
}
// The ROOM!
room r_startroom
{
init()
{
giveObject(r_startroom, o_key);
giveObject(r_startroom, o_door);
}
}
// HELLO, WORLD!
world
{
init()
{
win = false;
}
afterSuccessfulCommand()
{
if (win == true)
{
textln("You escaped the room!");
quit;
}
else if (objectCount(player) > 0)
{
textln("You have:");
browse(player);
}
}
start()
{
setRoom(p_guy, r_startroom);
setPlayer(p_guy);
textln("Escape the room!");
browse(room);
}
}
A TAME Module's code runs in a thing called a Virtual Machine. It is the thing that figures out a user's input, translates it into an action, finds a relevant entry point into the module, and executes the code. Simply put, the Virtual Machine is just another word for the brains that make TAME work.
A TAME Module itself is immutable, which means once it is defined, it cannot be changed. You cannot add code to a module as it runs, and you can't add new rooms or objects or containers or players during its execution.
"But," you say, "doesn't the world change with my actions?" Of course! When you run a TAME Module, the module gets loaded into memory, and that doesn't change. What DOES change, however, is a chunk of data created from the module, called a Context.
A Context is the thing that changes when changes to the game occur. A module's full context contains:
Nearly every command and function in TAME affects the context. A module context is tied to one module.
A Context can also be saved and restored. Nearly every implementation of TAME contains a way to do this.
The way that the user interacts with TAME in order to make things happen or change is through a Shell.
Since TAME, in essence, is just an engine-plus-context, there must be a way to interface with it. The most common way is typing commands to it like,
pick up lamp look at dog scream
This part of TAME is called the Shell. It is the thing that enables a user to interact with TAME, as well as the part that renders TAME's output in a human-understandable way. Technically, the Shell does not have to be a text interface. While TAME provides text interfaces out-of-the-box, it can also be point-and-click, or even a 3D environment. It is up to the implementor of the Shell to provide or change this.
But no matter how it is set up, every TAME Implementation follows a Request-Response cycle.