Game Help


Since my other post was to a specific question I thought I’d create a new topic that was more general. That way if I run into questions I can ask them here. Anyone who sifts through can learn as well :slight_smile:

I’m wondering two things at the moment.

How do I randomize text output. Is there a short hand for saying “one of”, like in Inform? Also is there a short hand for room descriptions that are entered for the first time, like “if unseen”?


See pages 50 and 51 of “Learning TADS 3.” It’s almost identical to Inform 7:

"As you glance at the crystal it seems to sparkle <<one of>>red<<or>>blue <<or>>green<<or>>orange<<or>>purple<<at random>>. "

To make a room description different the first time, you would do something like:

"<<one of>>The great hall stuns you with its magnificence<<or>>Ho hum. The great hall again<<stopping>>. "
As in Inform, positioning the punctuation correctly is necessary.

That’s interesting. Could you explain what the second one is doing? Why does the <> command make it work like that? When using one of with <> how does it now not to be random in this case?

Thanks again for your help. I was able to find the first example, but not the second. I was stuck on looking for <> or <> with an else. Not sure why they would opt for the stopping method, it’s far less descriptive.

I’m not finding a good discussion of <> in the documentation. It functions exactly as it does in Inform 7: The first item or series of items separated by <> will fire off in order. The last item in the list (the one followed by <> will be used on ALL subsequent passes.

T3 doesn’t define unvisited, but you could use <<if !seen>> … <> in a room description. However, it’s possible (I’d have to test it) that by the time the desc is being printed, the room is already marked as seen. Another way to do it would be like this:

visited = nil desc { if (!visited) { "First room description! "; visited = true; } else "Default room description. "; }

For more complex situations, you may want to look at the StopEventList and ShuffledEventList classes, which do the same thing as <> but with more code.

It’s the <> part that is indicating what type of list it is. <> indicates that the game is to display each entry in order and when the end of the list is reached display the final one every time the sting is displayed after that.

You can find more information by searching for “Random (and other) selections with <>” in the String Literals article of the System Manual.

Thanks :slight_smile:

I’m interesting in making this a game where you can shop, and quite possibly and rpg with basic d20 rules. I got some questions about classes. How does one define a custom class.

If php I would do something like:

class pShop{

 private $goods = [];
 private $prices= [];

 public function add_good($goodSet, $priceSet)
  array_push($this->goods, $goodSet);
 array_push($this->price, $priceSet);


How would I do this in TADS. Also would this be a thing? What I would do is add this shop item to every room a user could shop. I suppose the shop would say all the goods by a number, and the user could buy whatever.

Actually I think I got the format.

[code]shop : object

goods = []
prices = []

add_good(goodSet, priceSet)


Is there a way to capture my character entering a room, to fire a function to populate the object?

Looks like you’re making a room. (I’m guessing based on “Shop.”) You’d start with something like this [edited!!!]:

class Shop: Room 'The Pet Shop' goods = [] prices = [] ; petShop: Shop 'The Pet Shop' "Many small animals are for sale here. " north = mall ;
I don’t think you can make properties private in TADS. The article on List in the System Manual is the place to go to learn about list element handling; you don’t need to define your own methods to manipulate the lists. (Note that it would make sense to give each of the possible goods its own price property. Defining a separate list of prices would probably be more overhead and more prone to bugs.)

I would not want, personally, to use a numbered menu system for buying, but that’s just my own taste. I would prefer a method such as ‘buy sword’, possibly followed by ‘give ten coins to shopkeeper’. I’ve never used numbered menus, so I can’t help you with that.

No, you don’t want to derive directly from the object class. See my previous post. Oops. there’s a problem there … gotta go fix it.

Okay, that’s better. Here’s the thing, though: I think you’re getting a little ahead of yourself, or trying to apply your knowledge of other OO languages to T3. Writing IF is a little different, in that most objects are unique. For this reason, there’s not a lot of point in using something like an append method in a class definition. Just put the objects that will be on sale in some particular shop in that shop object (location) while writing the game.

Seriously … I’d suggest spending an evening or two reading ALL of “Learning TADS 3.” Even though you won’t remember it all, it will orient you to the TADS way of thinking about stuff.

Okay, so it’s not more ergonomical to use an object? I suppose in this case it’s already so simplified in the room that you don’t need a reusable class for this?

Everything is objects. But in-game stuff is not derived directly from the object class, it’s derived (mostly) from the Thing class, which gives you a whole big bunch of functionality for free.

If you’re going to have ten shops, then you might want to create a Shop class, derived from the Room class. But there would be no need to do that unless you want certain specific things to be present in Shops that aren’t present elsewhere.

My endless Work In Progress has about 30 shops. I know I defined a Shop class, but I’ll have to go look at the 2-year-old code to figure out why I did it that way. I think it was so that an annoying NPC would stop you if you tried to enter a shop.

Lol, yeah a shop class seems useful. Little slow here. So I’ve inherited shop from my room. I’m just wondering. How do I capture the room being entered? Is there a macros for that?

I’ve tried


but that’s not it…

Not a macro, no – a method. Include the method enteringRoom(traveler) when creating the code for your room. Note that this runs before the room description is displayed. See p. 209 in “Learning TADS 3.”

there is a function on the Room class called enteringRoom(traveler) this is called when an Actor enters the room. The Actor entering will be passed to the function. You can put your shop initialization code there.

how come neither of these put text in the room when entered?

          "\b\bEnter action working";
          say('\b\bEnter action working');

The code needs to be on the room object itself. This 2 room code example triggers the function

startRoom: Room 'Start Room'
    "This is the starting room. "
north = NorthRoom
+ me: Actor 'person' 'person'
NorthRoom: Room 'North Room'
    "This room is the Room North of where you started. "
    south = startRoom
    enteringRoom(traveler) {
        "enteringRoom triggered";           

I had it on the room. I’ll just show my actual code so far. I changed what happens inside the function, but I’m not sure if it’s populating the lists, as I didn’t get the string output to show me the function was even firing. You’ll notice I defined a wares action, but it’s not really doing anything. I have to find more info on reporting. Right now instead of reporting “You’re looking at wares” It says Nothing special happens… likely this is reporting inherited from Action?

leakyTub : Room, Shop 'Leaky Tub' 'Leaky Tub'
    "<<one of>>As soon as you enter Leaky Tub you're hit with the scent of ale, sweat, and strange sea foods. There's a small 
    party raging around the place. Clinking cups chatter about the tables, as people eat and drink. All in an instant the entire party seems
    to stop as they notice your arrival. Surrounded by dead silence, everyone stares at you as if you were a wraith walked in from the grave. \n \b
    A vision flashes in your mind, as the place fades from sight. You see yourself with a gold bearded man inside a seedy little bar. 
    He seems an age old friend, of renown stature and great strength. You're both held up
    at the table with sword and shields tucked away beside you.
    <q>You don't look so good, pal! You drink too much? Ha-ha!<q> He laughs. \n \b
    You come back to reality. The patrons of the Leaky Tub go back to their business-- drinking, and chatting-- as if they
    were slightly embarrassed of the moment.
    <<or>>Leaky Tub is lively with customers. Drinking patrons enjoy themselves at the wooden tables scattered about the room. An old
    bar maid<<one of>>-- dirty rag in hand-- wipes down the counter.<<or>> looks about with a stern look on her face. <<or>> seems to be enjoying her work.<<at random>> You see a drunken sailor sitting at the front counter on a wooden stool. He looks 
    like he's had one too many ales, as his head bobs up and down in a sleepy kind of way. Another chap looks a bit out of place. He seems more of a book type. There's a 
large white feather stuck in his hat, and a book satchel sitting across his knee. After eyeing his cup a moment you could swear he was drinking milk.
        goods = ['ale', 'strong spirits', 'urchin wine', 'red wine', 'fish chowder', 'lobster rolls', 
                'lobster chowder', 'baked urchin', 'steamed clams', 'steamed mussels', 'clam platter', 'seafood platter'];
        prices = [4, 6, 12, 14, 8, 12, 8, 12, 8, 8, 12, 18];
    east = mainRoad1StormPort

class Shop : Room 'shop'
    goods = []
    prices = []
    add_good(goodSet, priceSet)

//custom actions
     execAction() { 
           "listing wares";

     'wares' | 'list' 'wares' | 'list' 'goods'| 'list' 'items'
     : Action
     verbPhrase = 'examine/examining'

Your code for enteringRoom() looks fine. I would tend to assume that your lists are indeed being populated. (Note that the lists will be populated every time you enter the room, which means that anything you send into the list via your add_good() method will disappear from the list the next time the player enters the room.

You should read “How to Create Verbs” in the Technical Manual. After the colon in the VerbRule you want ExamineWaresAction, not just Action.

The lists being reset each visit can be fixed by checking if the lists are still empty []. If the list is empty apply the initial list otherwise just leave the list alone.