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:
But for our game, we really need the definition of openVerb to look like this:openVerb : deepverb verb = 'open' sdesc = "open" doAction = 'Open' ;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:openVerb : deepverb verb = 'open' sdesc = "open" doAction = 'Open' 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.modify openVerb ioAction( withPrep ) = 'OpenWith' ;
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?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: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.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?verDoScreamat(actor) = { "You scream at the wand, but it just sits there, unmoved. "; }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:
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.wand : itemFor example, if you look for the definition of the item class in adv.t, you'll see that the first line is:
Let's look up the definition of another class you use a lot, fixeditem, in adv.t. The first line of fixeditem is:class item : thingInteresting! 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.class fixeditem : thingSo 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:
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:modify thing verDoScreamat(actor) = { "You scream at <<self.thedesc>>, but it just sits there, unmoved. "; } ;Ah, much better.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.See the Sample Source Code
Go on to Lesson Nine
Go Back to Lesson Seven
See the Table of ContentsThe Text Adventure Development System
Version 2.2
This page is part of Mark Engelberg's TADS Tutorial
Copyright © 1999 Mark Engelberg