___________________________________

A TADS Tutorial: Lesson Eight

Modifying Adv.t

___________________________________

Adv.t

As has been mentioned in past lessons, much of the default behavior of TADS is contained in the file adv.t. I have encouraged you to look directly in this file whenever you have any questions about how the default classes work. Over the past several weeks, you have learned many techniques for creating your own interactive story in TADS, and for extending its capabilities. But if what you want to change the default behavior?

One option would be to just open adv.t and modify it directly. But this is considered uncool. Doing this would potentially make your game incompatible with other people's source code and future releases of TADS.

TADS provides a way of modifying the default behavior contained in adv.t without actually tampering with the adv.t file, using the keyword modify. Let's take a look at some examples of this technique in action.

___________________________________

Example 1: OPEN CRATE WITH CROWBAR
Let's say you want the command "OPEN CRATE WITH CROWBAR" to be a valid command in your game. The first step is to check to see if this is already provided for in the default TADS classes. A quick look at Appendix A of the manual, or the list at the end of Lesson 6, reveals that TADS already provides a verb template for:

OPEN DIRECT-OBJECT

but not

OPEN DIRECT-OBJECT WITH INDIRECT-OBJECT

This could pose a problem. Opening adv.t, we search the file for the word "open" until we get to the definition of the verb open. This allows us to confirm for ourselves how the verb is currently implemented:

openVerb : deepverb
    verb = 'open'
    sdesc = "open"
    doAction = 'Open'
;

But for our game, we really need the definition of openVerb to look like this:
openVerb : deepverb
    verb = 'open'
    sdesc = "open"
    doAction = 'Open'
    ioAction( withPrep ) = 'OpenWith'
;

The only difference between the TADS version of openVerb, and the version we would like to include in our game is one line. If we write the new version of openVerb from scratch, TADS will get confused because open is then defined in two different places, once in adv.t, and once in your program. As discussed before, if you just make the change in adv.t, you are risking incompatibility with other people's source code. Fortunately, there is a way to add this line without having to tamper with adv.t. You just include, somewhere in your program, the following instruction:
modify openVerb
  ioAction( withPrep ) = 'OpenWith'  
;

Once this is included in your program, you can use all the techniques discussed in Lesson 6 to make your objects respond to the "OPEN ... WITH ..." command.

___________________________________

Example 2: Default behavior for "SCREAM AT"
Last week, we talked about how to program an entirely new verb called "scream," and we set up a verb template for SCREAM AT DIRECT-OBJECT. Then we programmed a response for when the player types specifically SCREAM AT FROG. If you typed in the sample code, did you also try screaming at other objects in the room? What happened?
Cave
   You are standing in a cave.
   You see an ugly frog and a magic wand here.

>SCREAM AT FROG
Startled, the frog jumps several feet into the air.  When it lands, it glares at
you, blinking its protruding eyes.

>SCREAM AT WAND
I don't know how to scream at the magic wand.

It doesn't know how to scream at the magic wand? That's not a very descriptive message! One option would be to program a separate "scream at" message for the wand. For example, we could add the following method to the wand:
verDoScreamat(actor) = 
  {
    "You scream at the wand, but it just sits there, unmoved. ";
  }

Okay, well what if the player screams at the ground, or the princess, or any of the other objects we've put in our game? Do we really want to have to add a verDoScreamat method to every single object in the game?

No! That would become extremely tedious.

What we really want to do is program one default response for all the objects that don't have an especially descriptive response (like the frog). If only there was a way to change the behavior of every single item and fixeditem in the game ... But there is!

Before I tell you the trick, let's review what you know about classes. As you know when, you program an object, the first line gives the programming name for the object, and the name of the class from which it derives its behavior, for example:

wand : item

But what you may not have realized is that classes also derive their behavior from other classes. This idea that classes inherit behavior from other classes is called a class hierarchy.

For example, if you look for the definition of the item class in adv.t, you'll see that the first line is:

class item : thing

Let's look up the definition of another class you use a lot, fixeditem, in adv.t. The first line of fixeditem is:
class fixeditem : thing

Interesting! So both items and fixeditems derive much of their behavior from one class called thing. items are essentially the portable things, and fixeditems are things that you can't pick up.

So if we want to make a change to all items and fixeditems, we really need to make a change to the definition of thing. Again, we could just edit adv.t and change the definition of thing to anything we want, but this would be distasteful. Instead, we'll use the safer technique of using the modify command:

modify thing
  verDoScreamat(actor) = 
  {
    "You scream at <<self.thedesc>>, but it just sits there, unmoved. ";
  }
;

So this adds the verDoScreamat method directly to the thing class, effectively adding it to all items and fixeditems in your game! Now let's run the game again with this modification:
Cave
   You are standing in a cave.
   You see an ugly frog and a magic wand here.

>SCREAM AT WAND
You scream at the magic wand, but it just sits there, unmoved.

Ah, much better.
See the Sample Source Code
Go on to Lesson Nine
Go Back to Lesson Seven
See the Table of Contents

The Text Adventure Development System
Version 2.2
This page is part of Mark Engelberg's TADS Tutorial
Copyright © 1999 Mark Engelberg