Suppressing output of specialDesc() and so on when using roomFirstDesc in TADS3/adv3

Is there a convenient pattern/recipe for ensuring that if there’s a roomFirstDesc defined for a room that it’s the only thing that’s displayed when the player enters the room? Specifically I’d like to suppress the printing of any objects/actors with specialDesc output that would otherwise be displayed.

Short of putting logic in all the objects in the room, monkey patching Room.lookAroundWithin(), or elaborate solutions like that.

Since there’s no library property that addresses it, something has to get patched somewhere. Perhaps when roomFirstDesc gets called, set a suppress prop somewhere with a one-turn fuse to turn it back off, and modify Thing.showSpecialDesc to simply return if the suppress flag is in effect. Only one of many possible approaches…

Well, something like this almost does it:

class EventRoom: Room
        lookAroundWithin(actor, pov, verbose) {
                if((verbose == true) && !actor.hasSeen(self))
                        verbose = (LookRoomName | LookRoomDesc);
                inherited(actor, pov, verbose);
        }
;

The problem is that this should only happen if there’s a roomFirstDesc defined on the room. Problem being that Room does this:

    roomFirstDesc { roomDesc; }

…so roomFirstDesc is more or less always defined (that is, unless roomDesc is also nil).

I suppose I could just implement an additional flag or something, but that’s starting to feel kinda kludgy.

Instead of asking if it is defined, you can use the overrides() function to query whether you’ve got a roomFirstDesc situation…

Would it be very complicated to simply use EventRoom for the locs where you want the suppressing, and Room otherwise?

Also, isn’t the verbose flag only used by the wordy/terse meta-option? You’d want this behavior regardless of the setting, right?

Well, in theory that’s what’s going to happen (otherwise it would make more sense to just monkey patch Room), but I don’t want the “suppress object listing” behavior to be determined only by class membership. Because then it becomes a maintenance issue: I put the code on the shelf for a couple months, come back, decide the big confrontation with the NPC (or whatever) is going to be in some other room, and suddenly I have to remember a bunch of bookkeeping rules to keep the game in a consistent state, or I end up with a weird bug that’ll take me forever to track down.

But maybe something like:

class EventRoom: Room
        lookAroundWithin(actor, pov, verbose) {
                if(overrides(self, Room, &roomFirstDesc)
                        && !actor.hasSeen(self))
                        verbose = (LookRoomName | LookRoomDesc);
                inherited(actor, pov, verbose);
        }
;

The twiddling with the verbose argument works like that because Room.lookAroundWithin() checks for equality with boolean true or nil and then re-defines verbose itself:

        /* check for the special 'true' and 'nil' settings for 'verbose' */
        if (verbose == true)
        {
            /* true -> show the standard verbose description */
            verbose = (LookRoomName | LookRoomDesc
                       | LookListSpecials | LookListPortables);
        }
        else if (verbose == nil)
        {
            /* nil -> show the standard terse description */
            verbose = (LookRoomName | LookListSpecials | LookListPortables);
        }

…and then it decides what to output by doing bitwise ANDs on verbose. So if you pass it a value for verbose that’s neither true nor nil it’ll just output whichever bits you want.

So this definitely works-ish. It feels a little brittle, though, because it relies on a quirk of how Room.lookAroundWithin() works internally. Which is probably not a big deal with adv3—I’m not particularly worried about a new version of adv3 suddenly being released and breaking everything. But it’s still something I kinda have a constitutional aversion to.

It also just kinda seems like something the library might provide itself and I’m just missing it, which is really why I posted the question.

It seems to me that the adventure libraries are meant to be heavily modified, overrided and subclassed… they could never come prepackaged with all of the potential shades of variation that authors will want to put in their games!
I get what you’re saying though, and I’m sure that feeling is way stronger for one who’s actually coded in the real world.

My question about the verbose flag was just because your first version of EventRoom had “if (verbose==true)”, and I didn’t think it would be passed as true without the WORDY option set. Now that you set the flag with your own conds, it looks like it should be good…