After vs Report rules timing

I have a question but I’m not really sure where it fits (or even if it’s a sensible question at all - a search of the forums hasn’t pulled up the specific question, although I think I’ve read responses on it before). My question is in relation to the relative timing of report vs after rules and where to include specific bits of text to ensure that they are printed to the player in the right order.

Here’s my problem:
I’m implementing a messaging system where characters can message each other on smart phones. I handle this through a “messaging someone with a phone” action (and rules to determine the text of the message and an activity to store it - but that’s not important). I want the player to receive two reports of the message being sent: 1) a beep when someone, anywhere, sends them a message; 2) if they can be seen, a description of the NPC typing the message on their phone. I had implemented the notification beep as an after rule and the description of the NPC typing as a report rule. So fine, I get the beep message every time the action completes successfully and the report rule when the player can see the NPC. The problem is that as after rules fire before the report rules, the player gets told of the beep and then sees the NPC typing, thus implying the message has travelled faster than light to reach the player…

My question is - what is the most elegant way to solve this? Should I just move the report rule into the carry out rule, with a check for visibility? That feels ugly and counter to the style guidance in the documentation, which tells us to only put the actual changes in the carry out rules. I’m not sure I see an alternative at the moment though.

The two rules in question:

Report someone messaging someone with:
	say "You see [the person asked] typing on [the second noun]."
	
After someone messaging someone with:
	if the noun is the player, say "[The message-receiver of the player] beeps, indicating a message has been received.";
	continue the action.

Off the top of my head, have you tried,

  1. Switching which one is the after rule and which one is the report rule? I know that doesn’t really fit with the schema, but still…
  2. Combining them into one big report rule? Like:
Report someone messaging someone with:
	say "You see [the person asked] typing on [the second noun]."
	if the noun is the player, say "[The message-receiver of the player] beeps, indicating a message has been received.";
  1. (what I usually do) create a flag like ‘playermessaged’, and have an every turn rule like
every turn:
   if playermessaged is true:
        say "[The message-receiver of the player] beeps, indicating a message has been received.";

This guarantees it only fires at the end of the turn, and also makes it easier to combine multiple messages.

The problem is that a report rule only happens if the character is visible - so if I combined the rules, the beep would only happen if the player could see the sender.I could duplicate a big after and a big combined rule, but that feels inelegant.

Which is also my issue with the global flag. I’m writing this in an extension and I would rather not create new variables unless I really have to. Although maybe an every turn rule that fires (only!) once if a message has been received is the best way to go. I’ll think about it, thanks.

1 Like

Does this do the kind of thing you want?

“Texting”

Place is a room.

Bob is a man in Place.

Other Place is east of Place.

Alice is a woman in Other Place.

Messaging it with is an action applying to one visible thing and one topic. Understand "message [anyone] with [text]" as messaging it with.

Carry out an actor messaging someone with:
	say "<MESSAGE SENT: [actor] -> [noun]>[line break]".

After someone messaging someone with when the player can see the actor:
	say "You see [the person asked] typing on her device.";
	continue the action.

Report someone messaging someone with when the player can see the noun:
	say "The device of [the noun] beeps, indicating a message has been received.";

Every turn:
	let P be a random person that is not Alice;
	try Alice messaging P with "TEST".

After deciding the scope of someone while messaging with:
	repeat with P running through people: [who have devices]
		place P in scope.

Test me with "z / z / z / z / e / z / z / z / z / w / z / z / z / z".

Some relevant things of which you may not yet be aware:

  • The after rules, despite their name, are processed before the report rules. In addition, they are default success, so any rule that is fired will halt action processing unless continue the action is used, thus preventing execution of report rules at all.

  • There is a rulebook within the action-processing rules, called the player's action awareness rules, that I’m not sure is discussed anywhere in WWI or RB. These rules decide whether or not the report rulebook should be fired for a given action occuring in the game world, and they decide no unless the player can see one of: the actor, the noun or the second noun.

  • The basic accessibility rule applies to actions by actors other than the player, and this will prevent an NPC from completing the action unless the action is set up correctly (with the misleadingly-named visible label in the action definition). Scope modification may also be necessary when the actor is an NPC.

1 Like

I’d make it a flag on the message-receiver, then do a repeat through them every turn and make them beep then. Then you can have lots of people messaging each other on the same turn, and any visible devices will beep when they receive a message.

1 Like

Thanks all . @otistdog that is very close. I have fallen foul of the after rules firing before the report rules before - but it’s always good to list the intricacies out again. Adding the extra conditions might just do it. I’ll play around and see.

@Stephen that has an appeal too, having a catch all rule at the end of the turn to cycle through all such devices. That way I’d be able to control exactly how many and how the “beeps” are happening. That might also be easier for users of the extension to modify if they need to. I’ll let you know what solution I go for in the end.

1 Like

There is a diagram at the start of WWI 12.2 How actions are processed that is very useful for understanding what happens during action processing.

I should point out that the carry out rule in my example is intended for testing/debugging and can be safely removed. It’s there as a fallback to make sure you can see some output for every messaging it with action. It could be modified to increment a messages-this-turn counter on a device instead of issuing any text output, per Stephen’s suggestion.

Regarding your original question about which rulebook is best for which purpose: As can be understood by examining the player's action awareness rule (and their name), the implicit purpose of a report rule is to provide output based on the PC’s awareness via “physical” presence in the game world. If an action occurs but the PC can’t see any of its moving parts, the whole rulebook is skipped by default. As such, it is better suited to messages about what the PC sees and hears as a result of its position in the modeled world (seeing someone typing for example) than any other rulebook.

I used an after rule in the example above in an attempt to illustrate how its execution was not governed by the player's action awareness rulebook, but this probably wasn’t very clear, and in any case it’s not necessary. Since the output about beeping is a report of what the PC can see and hear, it can also be placed in the report rulebook. Because report rules default to make no decision, multiple applicable report rules can be run for a single action. Rules ordering directives (see WWI 19.4 Listing rules explicitly) can be used to ensure that any output about NPC typing comes before output about device beeping for a given single action, but you would need something more complex (along the lines of Stephens’s suggestion) for output that lists all typing first and then all beeping if more than one NPC can perform a message-sending action within sight of the PC during a given turn.

On second thought, the when the player can see the noun condition in the report rule’s preamble is not really suited to your setup because the device is not necessarily involved in the action parameters (i.e. not the actor, noun or second noun). If putting down devices is possible, you would want to change it to when the player can see the message-receiver of the noun and also write a new player's action awareness rule that runs the report rule when appropriate. Something like

A player's action awareness rule
	(this is the player aware of received messages rule):
	if the player can see the message-receiver of the noun, rule succeeds.

is a start, but it would also need to check whether the noun has an associated message-receiver (perhaps message-receiver of the noun is not nothing, depending on your setup).

The best use of an after rule is a little less clear-cut to me than it is for report rules. The after rulebook is frequently used as an override to report rules for specific conditions in example code, but is also used as a way of providing additional player output or world-state changes in combination with continue the action. The fact that it is a single combined rulebook for all actions implies a general-purpose utility, but the fact that it defaults to success (and therefore halts action processing) seems tuned to habitual use in the specific-case output override role. An after rule can usefully be applied in both roles.

For what it’s worth, I agree that carry out rules should not output text. I would argue that the Standard Rules shouldn’t do this for the examining and looking actions! As a practical matter, avoiding this is sometimes a bit of a hassle; action variables (see WWI 12.10 Action variables) are useful to purists here.

There is no formal style guide for Inform. In general, the guiding principle of most successful authors that I’ve seen on this forum is: Do what works and don’t worry overmuch about elegance. Inform is a flexible system that will support a variety of coding styles. Since you’re writing an extension, more attention to the niceties is desirable, but the theory of the extension is that the author who uses it doesn’t have to care about how it was coded. You can always update it if bugs are found.

2 Likes

Indeed; I sometimes think it would be more useful for all output of “After” rules to be buffered (with Text Capture) until after all the action-processing is finished, then printed. That’s where I generally want to add new code “after” an action (i.e. after it’s been processed and reported).

Eventually I’ll actually make my Aftereffect extension, which will add a new rulebook for exactly that. The aftereffect of going through an automatic door is the door closing, which will be reported after the going finishes.

3 Likes

My fantasy is an even more general mechanism by which there’s no incremental output: all of the turn’s events would be buffered and an output routine could decide what to do with them at the very end, basically isolating View from Model/Controller instead of having all three tied in knots.

2 Likes