"What do you want to [verb]?"

I need help changing the default response for when the player doesn’t supply a noun. As an example -

Catching is an action applying to one visible thing. Understand "catch [something]" as catching.

When the player types “catch”, they are asked “What do you want to catch?” which is fine. However, if I add a shortcut, like “Understand “c [something]” as catching”, now they are asked “What do you want to c?” if they only type “c”.

Ideally, I’d like to be able to customize this response, or at the very least, make it so they get asked “catch” instead of “c”. I know if the player just types “x”, they get asked what they want to examine, so that at least is possible.

Thanks!

Instead of Understand "c [something]" as catching. try the following:

    Understand the command "c" as "catch".

I don’t have Inform 7 on this laptop, but I think this is documented in Section 17.2 on the Writing with Inform manual. (I’m using a web reference which is probably out of date.) The chapter title is Understanding and the section title is New commands for old grammar. The web reference is (http://inform7.com/book/WI_17_2.html).

1 Like

That works as a replacement, but it still returns “What do you want to c?”

One thing that’s unusual about the examining action is that you can examine all. or more generally a list of things. That might be how the action traps nothing. There’s a section in the documentation on actions on multiple objects http://inform7.com/book/RB_6_15.html.

The only other practical suggestion I have is to add a section action to handle the missing token:

Nihil-catching is an action applying to nothing.  Understand "catch" as nihil-catching.

Report nihil-catching:
    say "What exactly would you like to catch?"

  [ this makes 'c' behave like 'catch' in the first word of a command. ]
Understand the command "c" as "catch.

I’m not fond of that solution as that adds a new action to the story, and my understanding is that the limit on the number of actions is fairly low.

I’m sorry to report that this is a special case in the I6 code, and rather difficult to customize.

This has the problem that the disambiguation question isn’t really a question. (The player can’t type “ball”.) So that’s another reason to avoid it.

Here is an extremely hacky I6 solution:

To say parser command so far: (- CustomPrintCommand(); -).

Include (-
[ CustomPrintCommand   orig_verb_word;
	orig_verb_word = verb_word;
	if (verb_word == 'c//') verb_word = 'catch';
	PrintCommand();
	verb_word = orig_verb_word;
];
-).

Note that the dict word 'c//' has two slashes because it’s a single letter. (Don’t ask.) If you were adjusting CX to CATCH, the line would look like:

if (verb_word == 'cx') verb_word = 'catch';
3 Likes

Looks like there really isn’t a way to handle this. Thanks anyway folks.

Slightly better, but still requiring an extra action:

Report nihil-catching:
    say "It just isn't clear what you would like to catch.".

There is no difference in play sequence, of course, but this does not suggest that you reply with the missing object. Probably acceptable if you have just one or two abbreviated commands that you want to handle, but a bad idea if you have a lot.

You can detect when the player’s command is c rather than catch and change the text of the command before asking any questions:

After reading a command:
    let T be "[the player's command]";
    replace the regular expression "\bc\b" in T with "catch";
    change the text of the player's command to T.

Incidentally, if you want to customize the clarification question:

The parser clarification internal rule response (E) is "And you want [if the noun is not the player][the noun] [end if]to [parser command so far] [italic type]what[roman type], exactly?"

EDIT: improved regex so c doesn’t have to be the only word in the command.

That would also replace press button c with press button catch, which is not intended.

(Also, in your original suggestion, there was no regular expression at all, so using exactly matching the text would presumably have been a little faster.)

Good point. If you have buttons named with letters, or you take a multiple choice test at some point in the game, this solution either won’t work or will need further tinkering. In general, I suppose, messing with the text of the player’s command is an at-your-own-risk kind of thing.

(Also, "c" is a regular expression - it’s just a very simple one. Just as 3 + 0i is a complex number. :slight_smile: )

Yeah, I think an I6 replacement is going to be the best solution.

This seems to work in Inform 7. The regex “^c\b” means it only catches “c” at the start of the line (so “press button c” is unaffected), and the multiple choice test stuff was just for practice.

"C" by Jonathan

Multiple-choice-test is initially false.

After reading a command when multiple-choice-test is false:
	let T be "[the player's command]";
	replace the regular expression "^c\b" in T with "catch";
	change the text of the player's command to T;
	say "(The command is now '[T]'.)".

After reading a command when multiple-choice-test is true:
	let T be "[the player's command]";
	if T matches the regular expression "<A-Da-d>":
		now T is "circle [T]";
		change the text of the player's command to T;
	say "(The command is now '[T]'.)".
	
Catch Room is a room.

Catching is an action applying to one thing. Understand "catch [something]" as catching.

Check catching:
	say "You can't catch [the noun]." instead.

Test Room is west of Catch Room.

An exam paper is in the Test Room. The description is "The paper says: 'Which is the third letter of the alphabet: A, B, C or D? Circle the correct answer.'"

After examining the paper:
	now multiple-choice-test is true.

Circling is an action applying to one topic. Understand "circle [text]" as circling.

Check circling:
	if multiple-choice-test is false or the topic understood matches the regular expression "<^A-Da-d>":
		say "That's not something you can do." instead;
		
Carry out circling:
	say "You circle answer '[topic understood]' and hand in the paper.";
	now the paper is nowhere;
	now multiple-choice-test is false.

Test me with "catch / the ball / c / the ball / press button c / w / read paper / c / c".
Catch Room

>test me
(The command is now "test me".)

(Testing.)

>[1] catch
(The command is now "catch".)

What do you want to catch?

>[2] the ball
(The command is now "catch the ball".)

You can't see any such thing.

>[3] c
(The command is now "catch".)

What do you want to catch?

>[4] the ball
(The command is now "catch the ball".)

You can't see any such thing.

>[5] press button c
(The command is now "press button c".)
You can't see any such thing.

>[6] w
(The command is now "w".)

Test Room
You can see an exam paper here.

>[7] read paper
(The command is now "read paper".)

The paper says: "Which is the third letter of the alphabet: A, B, C or D? Circle the correct answer."

>[8] c
(The command is now "circle c".)

You circle answer "c" and hand in the paper.

>[9] c
(The command is now "catch".)

What do you want to catch?

This solves the button c problem, but it introduces a problem with compound commands. E.g., wave, c would not work properly.

2 Likes

I’m not sure if this counts as more or less hacky than zarf’s solution (it essentially attacks the same spot, but in a slightly simpler way using an existing extension point), but the following should also work:

Include (-
Replace PrintVerb;
[ PrintVerb verb;
	switch (verb) {
		'c//': print "catch";
		default: rfalse;
	}
	rtrue;
];
-) after "Language.i6t".

I was pondering the idea of making an extension to support doing this in a more user-friendly manner, but that would require somehow storing an I6 'c//' in a table (or otherwise getting hold of that value from something that can be written in I7-land), and I’m not quite sure how to do that. (I don’t think I7 has the same concept of a dictionary word.)

(An alternative idea, which I’m also not quite sure how to arrange, would in part require some I6 code that constructs an I7 text variable from what print (address) verb would have output. But I suspect the performance of this idea would not be as good.)

2 Likes

This has been educational! I would likely use an Inform 6 version as they work better, are more readable, and would be easier to extend to other actions. Here’s the best Inform 7 I could come up with to deal with Friend of Fred’s point:

After reading a command:
	let T be "[the player's command]";
	replace the regular expression "^c\b" in T with "catch";
	replace the regular expression "\,( )*c\b" in T with ", catch";
	replace the regular expression "\.( )*c\b" in T with ". catch";
	change the text of the player's command to T;
	say "(The command is now '[T]'.)".

It works with press button c and either wave, c or wave. c - but would now fail with get a, b, c (and presumably other things).

Ok, I figured that part out. The result works, but is a bit uglier and less efficient. However, it does mean that if it’s put into an extension it could be used from almost-pure (and relatively tidy) I7 code, and could be extended with verb aliases in multiple places instead of everything having to agree on the exact I6 function content in one place.

The user-facing part of the code would end up looking like this:

To decide what number is dictionary c: (- 'c//' -).
A verb replacement printing rule for dictionary c: say "catch".

(You can use whatever name you like instead of dictionary c as long as you use it in both places – e.g. catch abbreviation would also work.)

Let me know if this sounds useful enough to actually put into an extension, or if you just want to know what the backend code would look like but would never actually use it. :wink: (It’s not too far different from what I already posted.)

1 Like