After rules and text order

So say your code is something like this:

[code]The generic room is a room.

A box is in the generic room. It is a closed, openable container.

A cat is in the box.

After opening the box:
say “The cat jumps out at you!”;
continue the action.[/code]

The result is:

How do you get the text accompanying the “after” action to display after the normal text, assuming you want both to display?

I’ve often wondered that myself. Most of the examples I’ve seen involve faking it:

After opening the box: say "You open the box, revealing a cat.[paragraph break]The cat jumps out at you!";

All After rules are always before Report rules, so make your rule a Last Report

Last report opening the box: say “The cat jumps out at you!” instead.

IIRC the standard Report rule doesn’t have the ‘instead’ so it will fall through to your final report rule. (But if not, then yes, you’ll need to fake it.)

So if there’s more to the After rule than just the reporting, you must need to break it into two rules?

For instance, if the code is:

After opening the box: now the cat is in the generic room; say "The cat jumps out at you!"

You instead have to say:

[code]After opening the box:
now the cat is in the generic room.

Last report opening the box:
say “The cat jumps out at you!”[/code]

You needn’t do so. I don’t think there’s any harm in sticking both effects into the same Last Report rule.

(Theoretically, it’s cleaner to separate narration from simulation, but go with what works for you. Besides, if you stick the cat-moving phrase in a separate rule than the say phrase, then how’s the say phrase’s rule going to know to say itself? The cat will have been moved out of the bag already by the time it gets considered.)

That’s what I thought, but when I tried making a “last report” rule, it never fired.

“Last report” isn’t working for me. I’m using Inform 7, and the cat-box example with Last Report yields “You open the box, revealing a cat.”

Is it an extension or something?

The last report opening rule doesn’t work because the standard library stops the action when it reports about the cat inside:

Report an actor opening (this is the reveal any newly visible interior rule): if the actor is the player and the noun is an opaque container and the first thing held by the noun is not nothing and the noun does not enclose the actor, stop the action with library message opening action number 4 for the noun.
(It stops the action so that any other library messages won’t be displayed.) Possibly the easiest way to go around this is to write an after rule that includes the library message and everything else you want it to do:

After opening the box when the cat is in the box: issue actor-based library message opening action number 4 for the box; say "[line break]The cat jumps out at you!"; now the cat is in the location.

That…is very obscure. How on Earth would I generalize that to other situations?

And why would the last report rule even exist if it’s never actually reported?

This is a kind of special case because 1) you want to preserve the original library message and 2) the action is stopped in the report rules. In practice case 1 is rare because in similar cases you usually replace the library message completely (“You open the box and a cat jumps at you!”), although this depends on the author’s style, and case 2 applies only to some standard actions. For example if the action would have been the switching on action the last report rule method would’ve worked.

Do you mean the concept of “last report rule” in general? It doesn’t work in this particular case because the action is stopped before it has a chance to run. It’s just a method of defining the order in which rules apply. For example:

[code]Foobaring is an action applying to nothing. Understand “foo” as foobaring.

Report foobaring:
say “This message is shown first because it’s listed first in the source code.”

Last report foobaring:
say “This message is shown last because of the ‘last’ keyword.”

Report foobaring:
say “This message is not shown last because the ‘last report’ rule goes after it.”[/code]

What should I do if I want a message to display last and I can’t fake it (or it would be very unwieldy to fake it)? For instance, I have conversations that take place when you enter a room with two NPCs; they should take place after you enter the room, but I can’t just tack them onto the room description because it could be any room.

An “every turn” rule will work.

The general case is “every turn when in the Salon: say ‘The NPCs babble…’” That comes out in the right place in the turn sequence. Then you customize it to happen only once, under whatever circumstances.