TADS 2 verb problems, throw a rock into a pond

I have what I assume are some laughably basic questions.

I’m implementing an old game in TADS 2. The original game required “throw rock” in the pond room so the rock enters the water. There’s also some ducks. I’d like to allow “throw rock”, “throw rock into pond”, and perhaps “throw rock at pond”.

Why cannot a room be also a noun? Before I added the “pond_desc” decoration, I added noun = 'pond' to the pond room, but the noun “pond” was not known. Is adding this decoration the correct way to add this noun? Seems weird to have to define a new object for this, so I’m wondering if I’m missing something.

Before adding the pond_desc, when I say “throw rock” the parser says supplies the ducks as the indirect object. After adding the pond_desc it asks “What do you want to throw the rock at?”

Also, it doesn’t understand “throw rock into pond” or “throw rock in pond”, and “throw rock at pond” produces “The pond isn’t important.”

Any suggestions about how to do this? I’m wondering if I made a poor choice to make the pond a decoration?

Do I need to create a new verb? I’m hazy on why Throw isn’t working and ThrowAt is being triggered (and how to prevent that).

I have tried reading both adv.t and chapter 4 and I am still quite confused.

pond: room
  sdesc = "pond"
  ldesc = "You're standing at the edge of a pond..."
  noun = 'pond'
  south = meadow
;

pond_desc: decoration
  sdesc = "pond"
  ldesc = "The pond is..."
  noun = 'pond'
  location = pond
;


rock: item
  sdesc = "small rock"
  noun = 'rock"
  adjective = 'small'
  location = meadow
  doThrow(actor) = {
    if( actor.location = pond ) {
      "Splash! The rock... ";
    } else {
      pass doThrow;
    }
  }
;

ducks: decoration
  sdesc = "ducks"
  isThem = true
  noun = 'duck' 'ducks'
  location = pond
;

Perhaps you need ThrowThrough ?

cfr. GC: A Thrashing Parity Bit of the Mind:

louis_window: window
        location = louisoffice
        adjective = 'east'
        doLookthru(actor) =
                "Louis's second story window overlooks a small pond to the east
                of the mathematics and artificial intelligence building.  The
                reflecting sun on the water prevents a good look, but you think
                you see the flashing scales of some red fish in the water."
        doordest = nil
        checktravel(actor) = {
                "What?  And risk defenestration?  Surely you jest.\n";
                return nil;
        }

        ioThrowThrough(actor, dobj) = {
                if (dobj <> paperplane) {
                        "You throw <<dobj.thedesc>> through <<self.thedesc>>, and watch it fly
                         away from you.";
                        dobj.moveInto(self.doordest);
                }
                else {
                        "You throw <<dobj.thedesc>> through <<self.thedesc>>, and watch
                        it fly.  <<dobj.thedesc>> circles gently down until it comes to rest
                        at surface of the pond, at which point a red fish lunges
                        towards it, takes one giant gulp, and swallows it whole before
                        submerging. ";
                        dobj.moveInto(self.doordest);
                }
        }
;

pond: ourdecoration
        sdesc = "pond"
        ldesc = "You can't see the small pond very well from here."
        noun = 'pond'
        adjective = 'small'
        location = louisoffice

I suggest calling the location “pond shore”, and put the pond decoration there…

HTH and happy coding !

Best regards from Italy,
dott. Piergiorgio.

Thanks!

I still don’t understand why “throw rock” gets interpreted as “throw rock at”? If I type “throw rock” it still assumes I mean “throw rock at ducks”.

But I found Lab 6 of Mark Engelberg’s tutorial helpful (see below) and even moreso Kevin Forchione’s VT “game” that generates a template that I add to the game. Although I don’t know how to answer the VT question “Does this verb disambiguate the direct object first (yes or no)?”.

But I still don’t understand whether it was a mistake to make the pond a decoration item (which I think you are endorsing). I couldn’t avoid “The pond isn’t important” message, so I changed it to a fixeditem and then when I’d implemented the verb correctly, things worked.

When the player types “dig sand with shovel”, the following methods are invoked by TADS:
• shovel.verIoDigWith(Me)
• sand.verDoDigWith(Me, shovel)
• shovel.ioDigWith(Me, sand)

When I was trying different things, I triggered the error below by constructing the verXXX, doXXX, and/or ioXXX routines with the wrong arguments. Is there a way to supply the symbols or otherwise find where in my code I have a bug in the number of arguments?

[TADS-1026: wrong number of arguments to user function "<NO SYMBOL TABLE>.<NO SYMBOL TABLE>"]

I tried “-ds” and “-ds2” (and “-ds+” and “-ds2+”); I’m using this compiler:

TADS Compiler v2.5.17 Copyright (c) 1993, 2012 Michael J. Roberts
TADS for POSIX/Unix/MS-Windows [POSIX_UNIX_MSWINDOWS] patchlevel 1.0
Nikos Chantziaras (email redacted) maintains this port.

I also found an error in Mark’s tutorial, the “if (dobj == trophy)” should be “if (dobj = trophy)” but the compiler error was “error TADS-300: expected right paren (‘)’)” which confused me for a while:

trophyCase : container, fixeditem
  location = startroom
  noun = 'case'
  adjective = 'trophy'
  sdesc = "trophy case"
  
  ioPutIn (actor, dobj) = 
  {
    if (dobj == trophy)
    {
      "As you place the trophy in the case, the case briefly glows. ";
      incscore(20);
      pass ioPutIn;
    }
    else
    {
      pass ioPutIn;
    }
  }
;

on Mark’s tutorial, please note that TADS use both Pascal and C syntax in the assignment and comparision, switchable via #pragma $C[+|-]

(I confess that I joked on this in my comments (“pragmatic sanctioning”…) )

very often, strange issues are linked to wrong language sanctioning… :wink: so, perhaps is a good idea doing a pragmatic reassessing of your issues :smiley:

(Addenda: I’m sure you have RTFineM (I want to be polite… :wink: ) and I point to you to this paragraph of ch. 10:

To help the player avoid wasting a lot of time trying to manipulate the books, we put in some special messages that let the player know that the books can’t be manipulated. When you create a decoration object, it’s always a good idea to think of all of the things that the player might want to do with it, and provide messages that make it clear that the object isn’t important to the game. In this case, we’ve made it clear that the collection of books can’t be read or taken.

Hence, what matters is the role of the pond in your narration in deciding if should be a decoration or a fixedItem…

Best regards from Italy,
dott. Piergiorgio.

Yes, good point. I see that I can turn on C syntax, although the default for FrobTADS is Pascal. That point had escaped me.

Thanks for your pointer to Chapter 10. I should re-read it, but I think my question about a decoration item was whether someone with more experience could render their experienced judgment about whether I’m doing it the hard way to over-ride the “The pond’s not important.” I’m beginning to think it is a mistake to use that object type. If I don’t want the “The pond’s not important” message, then I should use fixeditem, because a player may take some other action, like “search pond” or “take pond” and get the message that the pond is unimportant which would mislead the player.

But one of the things that confuses me in general is where these messages come from. I think I’ve found the answer to my question about “Throw rock” in the Book of the Parser. When I try “throw rock” it always assumes I mean “throw rock at ducks” and I didn’t understand why it adds the “at” and then looks for a DO (and finds the ducks). But I think it’s because that verb has no action().

well, seems that you are still studying TADS 2… an important core of the TADS 2 programming is that the standard library can be easily altered by the two instruction modify and replace.

The message you find annoying is in the class definition of decoration:

class decoration: fixeditem
    ldesc = "\^<<self.thatdesc>> <<self.isntdesc>> important."
    dobjGen(a, v, i, p) =
    {
        if (v <> inspectVerb)
        {
            "\^<<self.thedesc>> <<self.isntdesc>> important.";
            exit;
        }
    }
    iobjGen(a, v, d, p) =
    {
        "\^<<self.thedesc>> <<self.isntdesc>> important.";
        exit;
    }
;


so, basically, you need to modify or completely replace the definition of the decoration class… whose is a subclass of fixeditem.

If you give a ldesc to your decoration, it will override the stock ldesc of decoration (and fixeditem don’t have a default ldesc)

so, if you want a description of the pond in response to EXAMINE, you have only to add a ldesc in the definition of the pond, but you already know it.

on the origin of the messages, try to find them in the library; ^F, grep, you got the idea, I hope. but consider the heavy usage of embedded expression in the library: as you can see above, for the “The pond’s not important.” you should search for “important”.

best regards from Italy,
dott. Piergiorgio.

(re-edited & completed because of a major NMI from hungry cats…)