THINK verb...

I’m looking to implement a THINK verb. Anybody have good examples of how to do this?

I’m not finding it in the docs, but I know it’s a common notion.

I’m looking for three functions:

  • THINK: Gives a kind of in-character hint, to nudge the player along, on request.

  • THINK ABOUT: This is more like a conversation with oneself, for an inward dialog. – I guess the trick here is to create some kind of invisible object – Brain, or something – that in effect the player can converse with.

  • SPONTANEOUS THOUGHT: This is a response to something environmental, and not to user input.

What I have so far is that this is probably best done with the Consultable class. Any leads?

Conrad.

I wouldn’t bother with a Consultable class, though that would certainly be one way of doing it. I also wouldn’t bother with a Brain. (I’m a Scarecrow at heart!)

Here’s a ThinkAbout implementation. It uses the new <> syntax in TADS 3.1:

[code]DefineTAction(ThinkAbout)
objInScope( obj ) { return true; }
;
VerbRule(ThinkAbout)
((‘think’ (‘about’ | )) | ‘ponder’ | ‘contemplate’) singleDobj
: ThinkAboutAction
verbPhrase = ‘think/thinking (about what)’
;

modify Thing
thoughtMsg = ‘You <>consider<>ponder<>think about<> ’ + theName + ‘, but
<>nothing comes to mind<>no useful ideas come to you<>your mind remains obstinately
blank<>the subject doesn’t lead to any fresh insights<>. ’
dobjFor(ThinkAbout) {
preCond = []
verify() { logical; }
action() {
say (thoughtMsg);
}
}
;[/code]
The use of objInScope insures that the player can think about ANY game object. An object that has its own thoughtMsg will give a meaningful output; anything that doesn’t will produce a random "I’m tryin’ to think, but nuttin’ happens!" message.

Many thanks, Jim! I’ll try it out and report back. – I imagine I’d similarly update the Topic class, to allow the player to contemplate non-objects?

Conrad.

Topics are not derived from Thing, but the verb processing seems to think you must be trying to think about a Thing. I’m not sure how you’d modify Topic itself, but this works:

[code]class MyTopic: Topic, Thing
;

potato: MyTopic ‘potato’ ‘potato’
;[/code]
If you define a new Topic class this way, then you can think about instances of the class. Whether this would have side effects with normal usage of Topics, I don’t know. It seems not. I’m able to get an NPC’s AskTellTopic to respond to the potato.

The downside of my little scheme for this command … see, I wrote this very, very early in the development of my WIP, and haven’t tested or expanded it since. The problem, I have now discovered, is horrible. Let’s suppose you have an NPC named Bob, who inconveniently dies at some point and is replaced by an inanimate object called Bob’s body. This object will still have ‘bob’ as a vocabWord. So the result is:

think about bob
Which bob do you mean, Bob or Bob’s body?

A pretty bad spoiler, yes? This will happen EVERY time two objects share a vocabWord. There are ways to work around it, but they’re messy. On the whole, I think sticking with Topics and skipping the in-game objects entirely is probably a whole lot safer and easier!

The topic of a ThinkAbout action is mentioned briefly in “How to Create Verbs” in the Technical Manual. Unfortunately, the example given simply parrots what the player types. It doesn’t try to find a matching Topic object at all, which sort of sucks. That article says, “getTopic() returns an object of class ResolvedTopic…” But what it doesn’t say is how the author is to relate an object of class ResolvedTopic to an actual in-game author-supplied Topic object.

Wiser heads will have to prevail. I’m stumped.

Jim,

Did you read down to the next example, “Verbs with one object plus a topic,” containing a dictionary – The topic handling more complexly responds with a string, which is stowed away in a table indexed to the topic. This brings us back to Consultables…

–Frankly, I’m not at all certain why the following doesn’t work, and as you seem further along in understanding ResolvedTopic, I wonder if you’d comment:

[code]DefineTAction(ThinkAbout)
objInScope( obj ) { return true; }
;
VerbRule(ThinkAbout)
((‘think’ (‘about’ | )) | ‘ponder’ | ‘contemplate’) singleDobj
: ThinkAboutAction
verbPhrase = ‘think/thinking (about what)’
;

modify Thing
thoughtMsg = 'You <>consider<>ponder<>think about<> ’ + theName + ', but
<>nothing comes to mind<>no useful ideas come to you<>your mind remains obstinately
blank<>the subject doesn’t lead to any fresh insights<>. ’
dobjFor(ThinkAbout) {
preCond = []
verify() { logical; }
action() {
say (thoughtMsg);
}
}
;

modify Topic
thoughtMsg = 'You <>consider<>ponder<>think about<> ’ + theName + ', but
<>nothing comes to mind<>no useful ideas come to you<>your mind remains obstinately
blank<>the subject doesn’t lead to any fresh insights<>. ’
dobjFor(ThinkAbout) {
preCond = []
verify() { logical; }
action() {
say (thoughtMsg);
}
}
;

//////////////////////////////////////////////////////////////////////////////////////

meaningOfLifeTopic: Topic ‘meaning of life’
thoughtMsg = 'How much time`ve you got? ’

;[/code]

The output:

think about guy
You ponder the guy, but your mind remains obstinately blank.

think about suit
You consider the suit of armor, but no useful ideas come to you.

think about meaning of life

–This crashes the game. Which is oddly pleasing to me, but not the intended outcome. I get a nil object reference.

Conrad.

edited to add – the dictionary demo code, which I asked about – does not run. There’s something wrong with it beyond my ability to untangle.

Ok, the above code did not work because the Topic family does not like being referred to by the parser. They only like to be wrapped up and handled by ConvNodes and suchlike.

Why? I don’t know. However, realizing this implied a solution:

A combination class, Thinkum.

class Thinkum : Topic, Unthing;

–This is utterly batshit. But, it solved all the problems, and allowed Jim’s Thing code to be adapted to Topics, thus:

class Thinkum : Topic, Unthing
    thoughtMsg = 'You <<one of>>consider<<or>>ponder<<or>>think about<<at random>> ' + theName + ', but
        <<one of>>nothing comes to mind<<or>>no useful ideas come to you<<or>>your mind remains obstinately
        blank<<or>>the subject doesn\'t lead to any fresh insights<<at random>>. '
    notHereMsg = 'That\'s odd... why am I thinking about that? '
    notImportantMsg = 'How odd...  I don\'t know why I\'d have such a thought... '
    dobjFor(ThinkAbout) {
        preCond = []
        verify() { logical; }
        action() {
            say (thoughtMsg);
        }
    }
;

Thinkum objects are put inside Actors so that different, switchable actors have different thoughts about abstract topics.

Remaining problems: Thinkum thoughtMsgs are trumped by Thing thoughtMsgs, which is the opposite of what I’d like. Also I have to tinker with scope, such that I can have Thinkums floating around loose in the game world, kind of like Platonic forms, and the PC’s mind will latch onto whatever’s closest.

This’ll be a long-term project. I’m bouncing to the next task thread for the time being.

Many thanks, Jim, for the help.

Conrad.