Enter to Release more Text and other questions

In Tads 3; how would I go about doing something like this:

Opening Scene/Show Intro:
“1st text line”
Player inputs any button/Press Any Key
“2nd text line comes up”

Think something like Metamorphoses by Emily Short, the opening scene. How would I do that in Tads 3?

I know how to do something like this in C#, but not sure how it would work in Tads 3/Adv3 Lite.

Other Questions include.
-Keeping Track of Time in Tads 3: If I wanted to have some sort of timer in Tads 3 or a counter; that kept track of time from when the game began, that looped like a clock and set events off, or changed room descriptions; how would I do that?

-Dynamically Changing Rooms: How do I go about changing room titles & descriptions; one idea I had was to create a class for Room with a description, and to figure out what I needed to do to trigger an event that would call upon the classes. But didn’t know if that would work.

In answer to the first question, check p. 159 of LearningT3Lite. I suspect what you want is inputManager.pauseForMore().

To the second question, do you mean real time or game time (i.e., turn count)? For the latter, a daemon will work nicely.

To the third question, you can always change the name and description of any object. You can also create a method in the object (or in the class) that will do what you want. You don’t even need to create a derived class from Room – you can just modify Room directly. Create something like a changeTheRoom() method and then store whatever data you want it to access in some convenient place – either in the individual room object itself, or in some other object.

Thanks Jim that clears up alot; ok, so my new question is:

Currently I have a modified FinishgameMsg, called EndingMsg, it works.

It goes off when I remove the {curly brackets} that surround the multiple lines of code surround Testing Message, etc.; But it doesn’t go off if the player has taken the Blue Crystal and then gone into the room; I thought that maybe I was using the wrong action. That roomAfterAction, only works if you do the action inside the room, but it didn’t work. What am I doing wrong?

[code]Precipice: Abyss ‘The Precipice’
“You stand at the edge of a precipice, surrounded by a sea of clouds.
Behind you sits a crooked tree. The Wind blows strong here.”
east = Western_Meadow

roomAfterAction()
{
    if(BlueCrystal.isIn(me))
    {
        "Testing message. ";
        finishGameMsg(EndingMsg,[finishOptionUndo]);
    }
}

;
[/code]

I want to test the game over feature, so that when the player takes the Blue Crystal which is in another room, and goes into this room (posted here), the player having the object in their inventory triggers the game over message; but this doesn’t happen, it either doesn’t go off at all; or if I remove the curly brackets on the inside completely, then it goes off as soon as the player enters the room; but not with the desired action (having it in their inventory); so I know it’s got to be something I’m doing wrong within what code I’m trying to use, (don’t know how to formulate that thought).

I thought to use check() instead of roomAfterAction(), but checking seems to be related to actions the player is doing. What’s the proper way to write this code; or the proper code to call in order for this to happen?

Curly braces are important. They delimit a block of commands that are executed when the condition is evaluated as true. If you remove them, only one command after if(…), that is only the doubly quoted string would be made conditional and the rest (finishGameMsg) would be executed always without paying attention to the condition. So definitely keep you curly braces in.

But the problem is that the condition BlueCrystal.isIn(me) never becomes true and the reason lies somewhere else in your code. I don’t know why because you didn’t published a definition of your blue crystal. But I suggest to double check the spelling of your object name. Also keep attention to lowercase and uppercase letters. Anyway, it would be more consistent to name your objects with lowercase initial letter as class names usually starts with uppercase letters in TADS.

Oh thank you; that was what I was trying to verbalize, that it wasn’t evaluating to true.

Here is my Code for the Object Crystal

//Exploring Classes
class Crystal: Thing
    vocab = 'black crystal; glowing black crystal'
    desc = "The small crystal glows black."
;

BlueCrystal: Crystal
    vocab = 'blue crystal; glowing blue crystal'
    desc = "The small crystal glows blue."
;

Here is where it is Located:

Crystal_Caves: Caves 'Crystal Caves'
    "Crystal Caves"
    out = Northern_Meadow
    east = Crystal_Cavern
;

+BlueCrystal
;

Here is the room where it’s supposed to say, game finished:

Precipice: Abyss 'The Precipice'
    "You stand at the edge of a precipice, surrounded by a sea of clouds. 
    Behind you sits a crooked tree. The Wind blows strong here."
    east = Western_Meadow

 
    roomAfterAction()
    {
        if(BlueCrystal.isIn(me))
        {
            "Sirens are Screaming. ";
            finishGameMsg(EndingMsg,[finishOptionUndo]);
        }
    }
    
;

It’s a pretty simple set up, just a bunch of rooms, with a single object in it; but not sure why it’s not evaluating to true?

I’m a bit mystified. Could you show us a transcript of the output that you get when you play the game? If possible, the output from the time you pick up the blue crystal, then go into the Precipice, then run an inventory command to make sure you’re carrying it.

I can see two possibilities: Maybe you’re not actually carrying the blue crystal, or maybe there’s something odd happening with respect to roomAfterAction() being called.

Don’t remove the curly braces, though. They’re needed.

Transcript listed here. In this transcript I pass the Precipice, go into the Cave, I take the crystal, and go back into the Precipice where the code is meant to be; but nothing happens. I don’t receive any errors. Without the curly brackets, it will execute as soon as I enter the Precipice so I know for instance that the message works (don’t worry not removing them); but as tomas b mentioned; for some reason it’s not evaluating to true; and I’m not certain as to why.

[spoiler]The Abyss

Cloud and smoke surrounds you. Go down.

d

A gust of wind blew.

The Precipice

You stand at the edge of a precipice, surrounded by a sea of clouds. Behind you sits a crooked tree. The Wind blows strong here.

e

Meadow

Western Meadow.

ne

A bird flies by.

Meadow

Northern Meadow

in

Bat’s fly over your head.

Crystal Caves

Crystal Caves.

You can see a blue crystal here.

Darkness creep all around you.

take crystal

Taken.

You shiver in the cold.

out

A cloud passed over the sun.

Meadow

Northern Meadow

The sun came out again.

w

A gust of wind blew.

Meadow

North Eastern Meadow

s

A cloud passed over the sun.

Meadow

Western Meadow.

The sun came out again.

w

A cloud passed over the sun.

The Precipice

You stand at the edge of a precipice, surrounded by a sea of clouds. Behind you sits a crooked tree. The Wind blows strong here.

The sun came out again.

i

You are carrying a blue crystal.

A gust of wind blew.

[/spoiler]

I suppose I should ask whether your player character object is actually called me. If not, then BlueCrystal.isIn(me) won’t become true when the blue crystal is taken. It’s sometimes safer to write BlueCrystal.isIn(gPlayerChar) which avoids the problem of the player character being called something else. Note that as stated in a previous post, TADS 3 is case-sensitive, so that, for example, if you called the player character object Me instead of me, obj.isIn(me) will never be true.

That was one of the first things I tried, because the original one I saw said self, but I knew the character was ‘me’ . The only thing I can think of is if it’s not capitilized; but alas:

+ me: Thing 'you'     
    isFixed = true       
    person = 2  // change to 1 for a first-person game
    contType = Carrier    
;

and in the gameMain: gameMainDef

initialPlayerChar = me

I don’t see any problems with your code. I tested it, and it works fine for me.

-places head on desk- then I don’t know what’s causing it. It’s not working for me; I’m not sure why the code will not work, there are no other objects inside the locations, just the player, the blue crystal, and that. I have unused classes and methods (NPCs and objects I’m testing one by one) that have not been called; but there is no way they should be interfering with it. :-/

Not sure really what else to do.

This may not be relevant, but I wonder about code like this:

Precipice: Abyss 'The Precipice'
    "You stand at the edge of a precipice, surrounded by a sea of clouds. 
    Behind you sits a crooked tree. The Wind blows strong here."
    east = Western_Meadow

 
    roomAfterAction()
    {
        if(BlueCrystal.isIn(me))
        {
            "Sirens are Screaming. ";
            finishGameMsg(EndingMsg,[finishOptionUndo]);
        }
    }    
;

Is there some reason you don’t simply use the Room class here? How is the Abyss class defined?

But I suspect the point has come where we need to see your entire game code (or at least, a stripped-down version of it that still gives the problem) to work out what’s going wrong here, otherwise we’re all reduced to simply guessing.

How is the Abyss class defined? That’s the key point. Eagle-eyed Eric doesn’t miss a thing.

This is the problem:

// You make a new class named "Crystal" (object #1)
class Crystal: Thing
    vocab = 'black crystal; glowing black crystal'
    desc = "The small crystal glows black."
;

// Then a new object "BlueCrystal" (object #2).
BlueCrystal: Crystal
    vocab = 'blue crystal; glowing blue crystal'
    desc = "The small crystal glows blue."
;

Crystal_Caves: Caves 'Crystal Caves'
    "Crystal Caves"
    out = Northern_Meadow
    east = Crystal_Cavern
;

// And because TADS classes are in an essence just objects, here you make an another object #3
// which is anonymous children of the BlueCrystal (#2). But #2 and #3 are different objects!
+BlueCrystal
;

Just change definition to the “+ blue: BlueCrystal” and then the condition to “if(blue.isIn(me))”.

Hey Eric; Abyss has no features of it’s own, it inherits from Special_Rooms; I’m still trying to figure out Regions so I just ended up doing it like below, and was mainly testing inheritance.

[code]class Special_Rooms: Room, CyclicEventList

eventList = [
            'A gust of wind blew. ',
            '',
            'A cloud passed over the sun. ',
            'The sun came out again. '
            ]
cannotGoThatWayMsg = 'Insert Fog here. '

;

class Abyss: Special_Rooms
;

class Caves: Special_Rooms, CyclicEventList
eventList = [
'Bat’s fly over your head. ',
'Darkness creep all around you. ',
'You shiver in the cold. ’
]
;[/code]

Tomasb that worked! I have a new question now…why did it work? Let me see if I understood correctly:

In essence I hear you saying, that I created 3 Objects, and that #1 and #2 are separate from each other. When I placed the BlueCrystal into the room, I thought I was placing #2 into the room, but I was actually creating a new object #3, and it was not the same as #2. So when I called what I thought was #2, the Room saw only that I had #3 in my hand and didn’t know who that was, because #3 was just some random child object of #2.

(I understood that correctly)?

Now my Question is you used “blue: BlueCrystal” in order to call it, similar to if I were to call, “crystal: Thing”…which means in order to call the BlueCrystal, as BlueCrystal without having to create a 3rd object, I need to put the BlueCrystal inside the actual room, ex. via location, INSTEAD of putting one with the same name in the cave…-places head on desk-

…So basically I fixed it by doing this in the file where I made the objects…

BlueCrystal: Crystal
    vocab = 'blue crystal; glowing blue crystal'
    desc = "The small crystal glows blue."
    location = Crystal_Caves
;

somehow I feel like I may have gone overkill with the objects now o.O That worked. coughs

Yes or almost. There are two distinct hierarchies you must take into an account. An inheritance hierarchy which you define by specifying a superclass(es) when you create an object and containment hierarchy which you define by plus sign or location property.

All three objects (#1, #2 and #3) are all distinct separate objects connected by inheritance. #1 is a parent of #2 which means that #2 have all the same properties and methods as #1 with only exception that those that are defined on #2 itself overshadows the ones inherited. And #2 is parent of #3. #3 is also distinct and separate object, it just didn’t have a global name.

Placing object into a room means using containment hierarchy. You originally placed #1 and #2 nowhere and #3 into the room, so the #3 was only object that the player can find and manipulate.

Yes, this is possible. If you are not planing to have more than one blue crystal, than you can merge #2 and #3 together. Your example would work fine, but at the same time you can take an advantage of the plus syntax if you lay out the code this way:

[code]
class Crystal: Thing
vocab = ‘black crystal; glowing black crystal’
desc = “The small crystal glows black.”
;

Crystal_Caves: Caves ‘Crystal Caves’
“Crystal Caves”
out = Northern_Meadow
east = Crystal_Cavern
;

  • blueCrystal: Crystal
    vocab = ‘blue crystal; glowing blue crystal’
    desc = “The small crystal glows blue.”
    ;[/code]

But maybe there is yet one catch, but I don’t know Adv3Lite that much. Eric, isn’t vocab property combined together as are wocabWords in Adv3? So instead of redefining from black to blue, doesn’t blueCrystal end up with combined vocabulary?

Good catch, Tomas.

This is an example of why it’s so useful to define in-game objects with a lower-case first letter, and class names with a capital letter, so as to keep the two separate in your mind.

On the other hand, making the object lower-case both when it’s defined and when using the ‘+’ system to put it in the room wouldn’t help. You’d still have the problem. Here’s what I don’t understand: Why doesn’t the compiler complain that you’ve created two separate objects with the same code name? If the second BlueCrystal in the code creates a new object … oh, I get it. The second BlueCrystal object is an ANONYMOUS object – it has no code name at all. It’s simply an instance of the class BlueCrystal, because in TADS a previously defined object can also function as a class definition.

I think this qualifies as an anonymous object gotcha. Not a bug, but certainly something to be wary of in T3. You can create objects in a separate code block (perhaps in a separate file) and use the location property on the objects to define where they start the game; or you can use the ‘+’ method and define the in-game object in place. But you mustn’t define the object in a separate code block and then use the ‘+’ notation to put it in a room, because that will create a new, anonymous object.

Aha yeah that was a good catch; I’ve taken note of that (literally). One thing’s for sure, I definitely learned how objects work and have a better understanding of class inheritance than I did when I started, in the engine; aha which is why I was working with classes to learn. :smiley: This perspective changes entirely how I approach programming in Tads 3/adv3 Lite; pretty awesome and helpful realization.

I’m chuckling: how I was trying to call the object but instead creating new objects that the program didn’t recognize. Thought it was a bug myself, but nope, just the way Tads 3 thinks in objects :slight_smile:. So it wasn’t evaluating to true because it had a different object. That was a really awesome catch.

In this instance, it effectively would; the BlueCrystal would also have the adjective ‘black’. The vocabWords property is not quite straightforwardly additive, however, the complete rules are:

  1. If the name section (before the first semicolon) of a Thing contains a + sign, the inherited name is inserted into the object’s name at that point.

  2. Unless the adjectives (second) section of a Thing starts with a - sign, any adjectives defined in the corresponding section of any of its superclasses are added to the adjectives defined on the object.

  3. Unless the nouns (third) section of a Thing starts with a - sign, any nouns defined in the corresponding section of any of its superclasses are added to the nouns defined on the object.

  4. If the pronouns (fourth) section of a Thing is left undefined, or if it includes a + sign, the pronouns defines on any of its superclasses are added to the pronouns (or used as the pronouns) defined on the object.

The logic behind this is effectively that the vocab property inherits everything from its superclass except the name bit, on the assumption that individual instances of a class are likely to want their own distinctive names.

But while we’re at it, there’s a further point here, since the vocab property is being misused in a way that seems to be quite common (judging from code I’ve seen posted on this list) so it may be worth drawing attention to:

BlueCrystal: Crystal
    vocab = 'blue crystal; glowing blue crystal'
    desc = "The small crystal glows blue."
    location = Crystal_Caves
;

This definition defines ‘blue’ as an adjective twice over and makes ‘crystal’ an adjective as well as a noun (which is grammatically possible, of course, but I suspect not what is intended). The whole point of the vocab property in adv3Lite is that you don’t have to repeat words that are already part of the name, so it should be defined:

BlueCrystal: Crystal
    vocab = 'blue crystal; glowing'
    desc = "The small crystal glows blue."
    location = Crystal_Caves
;

Now, if you wanted to use the vocab inheritance feature based on the Crystal class, the way to do it would be this:

class Crystal: Thing
    vocab = 'crystal; glowing'  
;

Crystal_Caves: Caves 'Crystal Caves'
    "Crystal Caves"
    out = Northern_Meadow
    east = Crystal_Cavern
;

+ blueCrystal: Crystal
    vocab = 'blue +; small'
    desc = "The small crystal glows blue."
;

This would give the blueCrystal a name of ‘blue crystal’ while at the same time allowing it to be referred to as ‘glowing blue crystal’ or ‘small blue crystal’ or ‘small glowing blue crystal’ (and so on) in player input.

Ohhhhh that’s really good to know because I was confused on that. I got lost a little bit when you mentioned based on the Crystal Class, so I’ll have to stare at it for a really long time. I have another question; as it relates to Scenes.

general scene question
I do have another question, but it pertains to Scenes. I actually don’t quite understand Scenes or their benefit, when it comes to story progression. Inform 7 says, “Scenes enable the player to organize games around scenes rather than location.” but I’m not sure what that means;

The way I see it is as a : “Location vs. Scene vs. Object” type progression–Is it just a different way to think about or approach programming? What’s the traditional way people approach programming games?

And How does that contrast to what we traditionally do in Tads 3?

When it comes to how the different software build scenes:
Inform 7
Finally Inform 7 scenes, allow you to define a room, that’s the starting location, a list of the objects in that scene, and you can start and end it there.

Adv3Lite
But in Tads 3; adv3Lite, the code I see surrounds when the scene starts, and ends, how do I add objects, trigger events that are only specific to that scene? I’ve been looking at the adv3Lite Manual and the Library, and then I figured the “Methods” for afterAction(), beforeAction() in scenes propel that forward.

I went around searching for any open-source game that used Adv3Lite scenes so I could see it in action, and how it would work, but was having a hard time finding examples of it. If I had an example of it I could dissect the game there more easily. Does anyone have any example

Side note: Rambling
Right now game progression so far in my head works like, on an object/action based kind of thing. Like when player does X, and if player puts X here, then this triggers that. I’m not quite sure how game progression works when it comes to scenes, and how scenes can be integrated into story on a programming level in action. Merging gameplay with scenes yet. Like the way inform 7 makes it sound is that scenes encapsulate all those actions, but in my head the way I see it, as scenes themselves are, like the showintro bit at the beginning–It’s just, I’m confused.

One thing I wanted to do was be able to have scenes (that encapsulated levels) or something else that was similar to that, when triggered update the room and area; kinda like in C# calling a method that loads a whole level into it;

that was complicated for me to figure so I just made a bunch of more rooms, and each set of rooms just represented different levels, there’s so much I want to explore there. Like I wanted to update room descriptions which would contain atmosopheric scenery as part of the description,

when that specific scenery was there, certain objects relative to it would appear in the room but only with that scene description. The scene description would cycle through an eventlist.

I’m not that great a programmer lol, I’m working with what I know how to do now and building my way up; but my hope is that, I will eventually be able to do that. As it seems in my head simple insomuch as I just have to write a lot of things into account to do it.

Right now I’m just trying to make a very small game that works before expanding on rooms descriptions and the likes (this is me rambling).