You must supply a noun (even when you don't want to)

I have been trying to reduce the number of actions in Speech Motivations, but I have been thwarted at every turn. Check this out:

Test is a room. Bob is a man in Test.

Persuasion: Persuasion succeeds.

Discussing is an action applying to one thing. Understand "discuss" as discussing. Understand "discuss [something]" as discussing.

Report an actor discussing: say "[The actor] discuss[if the actor is not the player]es[end if] [the noun]."

For supplying a missing noun when discussing:
	if the person asked is the player, say "You ramble.";
	[otherwise keep silent;]
	stop the action.
	
Every turn:
	try Bob discussing the noun;
	
test me with "discuss bob/discuss/bob, discuss"

It appears that if you decline to say anything when supplying a missing noun, and then you stop the action, the parser decides that it really wants to say SOMETHING, so it tells you “you must supply a noun.” Previously, I had this logic in a check rule for a dedicated action, and I was quite happy for it to say nothing at all when an NPC had nothing to say. Is there a way to make this work, or do I have to bring my dedicated action back?

Your “supplying a missing noun” rule only runs when the player is the actor. This seems to fix it:

For supplying a missing noun when an actor discussing:
	if the person asked is the player:
		 say "You ramble.";
	otherwise:
		say "[The person asked] rambles.";
	[otherwise keep silent;]
	stop the action.

UPDATE: Right, you don’t want it to print anything when another person discusses nothing. Changing the otherwise clause to

	otherwise:
		say "";

seems to work, but I’m not sure why it doesn’t work when you just omit it completely. Anyway, I think you still need to change the rule header.

SUPER-CONFUSING UPDATE: OK, this:

Test is a room. Bob is a man in Test.

Persuasion: Persuasion succeeds.

Discussing is an action applying to one thing. Understand "discuss" as discussing. Understand "discuss [something]" as discussing.

Report an actor discussing: say "[The actor] discuss[if the actor is not the player]es[end if] [the noun]."

For supplying a missing noun when an actor discussing:
	if the person asked is the player:
		 say "You ramble.";
	otherwise:
		say "";
	[otherwise keep silent;]
	stop the action.
	
Every turn:
	try Bob discussing the noun;
	
test me with "discuss bob/sing/discuss/sing/bob, discuss/sing"

works as desired, except perhaps for extra spaces.

This:

Test is a room. Bob is a man in Test.

Persuasion: Persuasion succeeds.

Discussing is an action applying to one thing. Understand "discuss" as discussing. Understand "discuss [something]" as discussing.

Report an actor discussing: say "[The actor] discuss[if the actor is not the player]es[end if] [the noun]."

For supplying a missing noun when an actor discussing:
	if the person asked is the player:
		 say "You ramble.";
	otherwise:
		say "[run paragraph on]";
	[otherwise keep silent;]
	stop the action.
	
Every turn:
	try Bob discussing the noun;
	
test me with "discuss bob/sing/discuss/sing/bob, discuss/sing"

sprouts "You must supply a noun"s everywhere. But the only difference is that I replaced “” with “[run paragraph on]”! I have no idea what can possibly be happening.

Yeah, I forgot the “an actor” in my example, even though I had one in the original code.

I have a suspicion about what’s going on. I looked at how the Standard Rules handle writing a paragraph about, and there’s this little bit of chicanery:

if a paragraph break is pending, say "[conditional paragraph break]"; carry out the writing a paragraph about activity with the item; if a paragraph break is pending: increase the locale paragraph count by 1; now the item is mentioned; say "[command clarification break]";
It seems that Inform is communicating with itself via paragraph breaks…

Yeah. This is implicit in the manual where it describes the “printing a locale paragraph” activity:

The only library-detectable difference between doing nothing and printing a paragraph is that the latter contains a paragraph break.

But why is this affecting the “supplying a missing noun” rules?

It’s Bob’s discussing the noun every turn that results in a line break those turns when he has nothing to discuss. So only invoking that rule when he does, prevents the line break.

[code]For supplying a missing noun when an actor discussing:
if the person asked is the player, say “You ramble.”;
otherwise say “”.

Every turn when the noun is not nothing:
try Bob discussing the noun.[/code]

That’s a good solution, but I’m still curious what’s going on under the hood. Why does the supplying a missing noun activity care whether you’ve printed anything?

The relevant check is in the I6 routine ActionVariablesNotTypeSafe: if (say__p) rtrue; return L__M(##Miscellany, 59); But more importantly, stop the action'' does not do what it looks like it does here, because it's a synonym forrule fails’’ and not meant for an activity’s rule (see WI 18.10). That’s why the error messages are appearing in the first place: the action carries on even though the for-supplying-a-missing-noun rule didn’t supply any noun.

So what’s the deal? The supplying a missing noun activity has to say something in order to stop the action? What if it says something clarifying, intending to continue the action?

I’d be tempted to do something like this:

[code]The showstopper is an thing.

Before doing something when the showstopper is the noun or the showstopper is the second noun:
stop the action.

For supplying a missing noun when an actor doing something (this is the stop the action silently rule):
if the actor is not the player, now the noun is the showstopper;[/code]

The I6 templates are often written so that I7 activities replace the default behaviour (in case the author has written any rules for the activity). But the supplying a missing noun activity does not work like that.

The I6 routine ActionVariablesNotTypeSafe calls the rulebooks for that activity; the activity rules do their work; and then control returns to the calling I6 routine, which decides whether or not to print the library message “You must supply a noun”.

This decision is taken depending on what, if anything, happened during the activity: if a noun was supplied, the action processing will continue as normal; if no noun was supplied, but something was printed, the I6 routine stops short (it returns true); if none of this happened, the routine prints the library message “You must supply a noun” and stops.

(The supplying a missing second noun activity works analogously.)

As for the I7 phrase ‘Stop the action’, it’s just a name for an I6 ‘rtrue’ statement. I would have thought that what happens is that it does stop the activity and returns control to the ActionVariablesNotTypeSafe routine, which then decides what to do as per above.

All right, I’ve made my peace with this. Almost.

Now I’m wondering how to handle this situation:

[code]Informing it about is an action applying to two visible things.
Understand “tell [someone] about [any known thing]” as informing it about.
Understand “tell [someone] that [any known thing]” as informing it about.
Understand “tell [someone] [any known thing]” as informing it about.
Understand “talk to/with [someone] about/regarding [any known thing]” as informing it about.

Understand “to/with” and “[so out loud] to/with” as “[so out loud to]”.
Understand “talk [so out loud to] [something]” as informing it about.
Understand “answer [someone]”, “answer [so out loud to] [something]” as informing it about.

For supplying a missing second noun when informing something about (this is the voice concerns when vaguely informing rule):
if the concern of the player is nothing, continue the activity;
now the second noun is the concern of the player;

For supplying a missing second noun when informing something about (this is the greet the new interlocutor when vaguely informing rule):
if the noun is the interlocutor of the player, continue the activity;
now the second noun is hello;

For supplying a missing second noun when informing something about (this is the let’s talk about you when vaguely informing rule):
now the second noun is the noun;[/code]

I had an action called “talking with” that would redirect to “informing it about,” but I got rid of it, once again thinking I could use these “supplying a missing noun” rules. But that’s not quite right. You see that there are three rules for supplying a missing noun. Only the first one should really end up as the informing it about action. The second one (greet the new interlocutor…) should be redirected to an action called “exclaiming it to.” The third should be redirected to “quizzing it about.” Should I bring back the “talking with” action so I can handle the redirection in check rules? Or is there a clever way to trigger the redirection from within the supplying a missing second noun activity?

The supplying-a-missing-noun activity isn’t really designed for redirecting actions. You could change the verb at this point, but if you did so you would violate the implicit contract of the activity, and you might break other people’s code. Bringing back the talking with action seems like a safer bet to me.