Message parameter substitution & custom verb

I have created a custom verb “What Is” and it is intended to work with both Topics and Things. It works otherwise well, but for some reason the message parameter substitution doesn’t.

> what is chair
// Expected:
> The chair is what it is
// Actual:
> {The dobj/he} {is} what {it/he} {is}.

The code for the verb:

DefineTopicAction(WhatIs)
	execAction() {
		local obj;
		obj = gTopic.getBestMatch();
		if (obj) {
			"<<obj.whatIs>>";
			return;
		}
		"I have no thoughts about that. ";
	}
;
VerbRule(WhatIs) ('what' 'is') singleTopic: WhatIsAction
	verbPhrase = 'what is (what)'
;

The relevant part of the code for Thing:

modify Thing
	whatIs = '{The dobj/he} {is} what {it/he} {is}. '
;

What am I doing wrong?

I could be wrong, but my best guess is that there is no dobj in a TopicAction. The Topic is not a dobj, because it’s not an object at all.

I think you have a couple of options. If the chair is in scope (that is, in the room with the player), you can use a simple TAction and skip the bit with gTopic.getBestMatch(). If you want the player to be able to ask the software about things that don’t exist at all, you can create Topic objects for them. Note, however, that a Topic object is not derived from the Thing class, so modifying Thing will have no effect. You could modify Topic to provide this property, but since a Topic doesn’t have a name property, only vocabWords, you’ll have to do some more work to get your new property to provide the right output.

Thanks for your reply.

I have a similar suspicion. My first attempt was to use TAction, but I couldn’t figure out how to get it to work with topics. conradcook had very similar problem here:

https://intfiction.org/t/think-verb/3591/1

and he ended up writing a new class, which doesn’t feel right to me. I have a gut feeling that what I’m trying to do is correct in principle, but it’s just missing something. Also, official guides seem to suggest that this type of case should/could be handled with TopicAction:

tads.org/t3doc/doc/techman/t3scope.htm, section “Using Topics for non-spoilery Scope Extension”
tads.org/howto/t3verb.htm, section “Verbs with a “topic” object”

Is there any way to tell the parser that obj == dobj?

I just realized that the way I use the “what is” verb doesn’t really require Topics. It seemed logical class for abstract things that can be pondered about but are not available anywhere, but by using Thing as the base class works (for my scenario, at least) equally well and is much easier to implement:

DefineTAction(WhatIs)
	objInScope( obj ) {
		if ( obj.isAvailableAsTopic ) {
			return true;
		}
		return nil;
	}
;

VerbRule(WhatIs) ('what' 'is') singleDobj: WhatIsAction
	verbPhrase = 'what is (what)'
;
// --------------------------------------------

meaningOfLifeTopic: Thing '(the) meaning of life' 'meaning of life'
	whatIs = 'If I knew that I would be a very rich indeed. '
	thinkAbout = 'I thought about the meaning of life, but realized I wasn\'t drunk enough. '
;
// ---------------------------------------------

modify Thing
	dobjFor( WhatIs ) {
		precond = []
		verify() {
			logical;
		}
		action() {
			"<<whatIs>>";
		}
	}
	whatIs = '{The dobj/he} {is} what {it/he} {is}. '
	isAvailableAsTopic = true
;

Now there are a few things that may need some smoothing over, but otherwise this works well enough. I even implemented “think about” verb using the same principle, just in case players need more introspection. :slight_smile:

It would still be nice to know for sure why the message parameter substitution fails in the execAction() of TopicAction, just for future reference.