Objects that change their descriptions and names.

Hello,

I am very new to TADS 3, and am wondering how I can make objects change their descriptions and names depening on player actions.

A very simple example first; let’s assume the PC holds the book to begin with.

> x book
The book is thick and leather bound, with gilded letters on its spine.

> read spine
Hermetica.

> x book
The book is thick and leather bound, the gilded letters on the spine read Hermetica.

And similarly, the object’s name.

> drop hermetica
Dropped.

> look
…and Hermetica lies on the floor.

That is, not only can the description change according to PC actions, but the game refers to (some subset of) objects according to which synonym the player typed in, from that point on.

Can this be done at all, with TADS 3?

Anything can be done in TADS :slight_smile: Yes, you can variate text descriptions, there is a special syntax for embedding conditionals in strings, like:

book: Thing 'book/spine' 'book' "The book is thick and leather bound, <<if gRevealed('book-spine')>>the gilded letters on the spine read Hermetica. <<else>>with gilded letters on its spine. " ;
Then you just add tag <.reveal book-spine> to your read description of spine object. See chapter 7.1.3 of Learning TADS 3 for revealing and end of chapter 4.4 for special things you can put into strings.

You can also change the name of an object, it’s a property called name (and few others derived from name), preferably see examples how to change name of Actors in manual, which is similar. And you can also change vocabulary dynamically (there are special methods for that, changing vocabWords is not enough for that), but that is more advanced.

With the adv3 library, which is standard T3, the cmdDict() method is used to change vocabulary. I don’t remember where it’s documented – it’s a bit obscure, but it does work. (In adv3lite, other methods are used to get this result.)

If you want to add additional vocabulary to an object (for example, because the player now knows more information about the object), you can just call initializeVocabWith(). For example, when the player reads the spine and “Hermetica” is revealed to the player, you can do:

readDesc()
{
    "Hermetica. ";
    book.initializeVocabWith('hermetica');
}

Note that this adds vocabulary. It does not replace it. The existing vocabulary (“book”, etc) will continue to work. Also, duplicates are cleaned up automatically. So in the above code, you don’t have to check if you already added “hermetica” to the vocabulary.

The string you pass to initializeVocabWith() uses the same syntax as normal vocabWords strings. That is, “adj adj noun/noun*plural plural”.

Ok, first the success story.

The code so far.

[code]library: Room ‘Library’
"The library is filled with books. "
;

  • Fixture ‘desk’ ‘desk’
    "The desk is ornately carved. "
    ;

++ tarzan1: Thing ‘leather bound book/volume’ ‘book’
"It’s a leather bound volume with flourished gilded letters on the
spine<< if gRevealed(‘tarzan1-spine’) >> which read Tarzan of the Apes<< end >>. "
;

+++ spine: Readable, Component ‘gilded flourished flowery curved letters/spine/shapes’ ‘spine’
"The letters on the spine are intricately curved in various flowery shapes
<< if gRevealed(‘tarzan1-spine’) >> which read Tarzan of the Apes<< end >>. "
readDesc() {
“The letters are hard to read, but you make out Tarzan of the Apes.”;
gReveal( ‘tarzan1-spine’ );
tarzan1.name = ‘Tarzan of the Apes’;
tarzan1.isQualifiedName = true;
}
;[/code]

Which results in pretty much what I want.

However, this is where it fails.

Of course I want the book to be openable – otherwise it makes no sense (to me).

And, to make it possible to refer to the book by name (preferably only after the name has been discovered) I tried this, adapted from something I found on the 'net.

grammar qualifiedSingularNounPhrase(tarzan1): 'tarzan' 'of' 'the' 'apes' : SpecialNounPhraseProd getMatchList = [tarzan1] getAdjustedTokens = ['tarzan', &noun, 'of', &miscWord, 'the', &miscWord, 'apes', &noun] ;

However, it fails with this error message:

The symbol "SpecialNounPhraseProd" is undefined. This symbol is used as a superclass in the definition of the object "qualifiedSingularNounPhrase(tarzan1)". Check the object definition to ensure that the superclass name is spelled correctly, and check that the superclass's object definition is correct.

Am I using it wrong? Or is this some obsolete feature that’s no longer relevant?

How do I make the phrase “Tarzon of the Apes” refer to the book?

How do I make the book openable, and subsequently readable?

Ok, apparently I don’t need the complex noun phrase in the grammar; at least not immediately, so I’m leaving that for later.

It is sufficient to

tarzan1.initializeVocabWith( 'tarzan of the apes' );

and then I can

The next exercise is to make it some sort of a readable object, that requires opening before it can be read.

Later on I hope I can make it a container for thin objects, like a sheet of paper or a bookmark.

EDIT: If I just make it a OpenableContainer then I can’t read the spine without opening it first. I guess that’s the first hurdle to overcome; separate the “inside” of it from the “outside.”

You can do this by making it a complex container. Look at the page for ComplexContainer in the Tour Guide.