The Dreaded Inform Carriage Return Problem

I’m attempting to write a fairly complex agenda for an NPC. This consists of several if-statements in a row – but not with otherwise/else, because I may need two of them (or possibly even three) to fire in a single turn.

It looks more or less like this:

Every turn:
     consider Betsy's agenda.

To consider Betsy's agenda:
    if (some complex condition):
        say "Boo.";
    if (another complex condition):
        say "Bah."

What I’m finding is that if only one of the agenda items fires, the carriage returns in the output are fine. But if two of them fire in a single turn, there’s a missing carriage return. The two messages are printed one below the other, without a blank line space between them:

Boo.
Bah.

I could fix this the stupid way, by adding a (global) truth state that would test whether another message had been printed from the routine this turn, and if so, add a “[line break]”, but maybe there’s a better way. Can anyone suggest a general solution to the problem?

–JA

Hopefully I’m understanding the question here instead of misusing electrons… but couldn’t you end them all in “[run paragraph on]”, then at the conclusion print a single “[line break]”?

Electrons are cheap … but to answer your question, that would work if I wanted everything in one long paragraph. However, I don’t. The outputs are intended to be rather separate in tone and topic, and require separate paragraphs.

In that case, end each with a paragraph break rather than a line break.

–Erik

…also, on thinking about it, there are times when NO output will be printed. So you’d still have to test whether any output had been printed before you’d know whether to print the “[line break]”.

What scares me is that this may be one of those places where the fundamental design of Inform sort of stutters and stumbles a bit. In TADS 3, this is never a problem, because (from what little I know about it … I’m guessing here) T3 buffers and organizes its output in a different way before sending it to the screen. It looks to me as if that final blank line in the Inform 7 output is being inserted not by an output buffer manager but as a prelude to the next command prompt. Or something like that. This is one of those edge cases where it may make a difference.

But maybe if I wrote my “consider … agenda” code differently, the problem would go away. I simply don’t know.

But each paragraph does end with a paragraph break. It ends with this type of thing:

…last words.";

That’s a paragraph break, as far as Inform is concerned, right? The problem seems to be what happens after the paragraph break – namely, that sometimes Inform adds an extra blank line, and sometimes it doesn’t.

I could be wrong. I’ll have to whip up a clear test case to explore the problem.

Not quite. As I understand it: Within a single routine, the period is treated as running on–because a single routine should generally produce a single paragraph. The paragraph break token allows you to override this, hence my suggestion.

To showcase the distinction, here’s some perfectly useless code, but with the two conditions broken out into two every turn rules:

[code]Test is a room.

Every turn:
consider the agenda with regard to applesauce;

Every turn:
consider the agenda with regard to mayonnaise;

To consider the agenda with regard to applesauce:
if the player is a thing:
say “Boo.”

To consider the agenda with regard to mayonnaise:
if the player is a person:
say “Bah.”[/code]

Now the line-ending periods produce line breaks, because each period is effectively the output of its own rule.

–Erik

For what it’s worth, this is one of those cases where I’d use a rulebook, like so:

[code]Every turn:
consider Betsy’s agenda rules.

Betsy’s agenda rules are a rulebook.

A Betsy’s agenda rule:
if 1 > 0:
say “Betsy waves.”

A Betsy’s agenda rule:
say “Betsy frowns.”[/code]

You get the paragraph breaks automatically, and if no rule prints anything, you get silence. You can give every character his/her own behavior rulebook and call them all automatically. I also find rulebooks more robust to work on if I’ve got a large number of possible cases in mind, vs. a really long if statement. This may be a matter of personal preference.

It would indeed be nice if we had an output buffer; this is something I wanted to add from the very early days of development. Unfortunately, as I understand it, it’s not possible to do such a buffer systematically within the limitations of the z-machine. You can kind of fake a buffer in local cases – Eric Eve’s “Text Capture” extension demonstrates one way of doing this – but for the specific task you’re discussing it would be a case of killing a gnat with a shotgun.

Thanks, Emily. That’s the solution I needed. It’s only a tiny bit more verbose, and it keeps the outputs separate.

My one question is, will the rules in the rulebook always run in the order they’re declared in the source code? That could be significant in some cases.

They will run in the source order unless you add conditions to them (such as “when/while”), in which case they’ll sort themselves by priority.

Having the rulebook structure also allows you to specify some rules as “first” or “last”, which can sometimes also be useful for grouping.

As Emily said, and also – if you define this as a rulebook, you’ll be able to examine it in the rules tab of the index, and see exactly how the rules were sorted out. You can then use explicit rule-listing statements to make fine adjustments if necessary.

If you’d like to see something similar in action, I did similar things in Child’s Play. All of the babies have rulebooks (like the “ZK Fussing Rules”), and in some cases I hand-sorted the rules to get the order right (as in the “ZK Cooperating Rules”).