I7 - creating categories of player commands?

I want to make something happen if the player does something loud, while the sleeping ghost is nearby. Something like this:

Instead of being noisy when sleeping-ghost is visible:

But how do I define certain commands as being noisy?

This should help:

https://intfiction.org/t/similar-rules-giving-different-outcomes/8562/1

Oh, this looks easy - Thanks for digging that up!

I just ran into a new problem. I want to allow the player to being-noisy in the presense of the Sleeping Ghost. But after that, the game should Say “(You really shouldn’t be doing that. The sleeping ghost might awake.)” Like this:

>dance
Dancing! Nice-nice funny!!!
(You really shouldn’t be doing that. The sleeping ghost might awake.)

However, I can only get the game to say that warning before the report of dancing. Not after.

[code]Dancing is an action applying to nothing. Dancing is making-noise. Understand “dance” as dancing.
Persuasion rule for asking a person to try dancing: persuasion succeeds.
Report an actor dancing: Say “Dancing! Nice-nice funny!!!”.

Echo Chamber is a room.
Jinxie is a person in Echo Chamber.
Sleeping Ghost is a person in the Echo Chamber.

After an actor making-noise when the Sleeping Ghost is visible:
Say “(You really shouldn’t be doing that. The sleeping ghost might awake.)”;
Continue the action;
[/code]

So the problem is that After rules run before Report rules… and the other problem is that you can’t write Report rules for kinds of action, only about specific actions, and there isn’t any obvious action-specific rulebook that does run after Report rules.

The easiest thing to do here is to write an Every turn rule:

Every turn when the current action is an actor making-noise and the Sleeping Ghost is visible: Say "(You really shouldn't be doing that. The sleeping ghost might awake.)".

You could make it “First every turn…” to make sure the message prints before the other messages from Every Turn rules.

If for some reason this doesn’t work, you might try creating a rulebook that runs after the Report rules and put the rule there. One case in which it doesn’t work: I created an alarm clock and a rock, and made taking the alarm clock making-noise. When I typed “Take clock and rock” the message didn’t print, because by the time the game gets to the Every Turn rules the current action is “taking the rock,” not “taking the alarm clock.”

You could try something like this… though I’m a bit nervous about whether I’ve done it right:

[code]After Reporting rules is a rulebook.

After reporting when the current action is an actor making-noise when the Sleeping Ghost is visible:
Say “(You really shouldn’t be doing that. The sleeping ghost might awake.)”.

This is the After Reporting stage rule: Abide by the After Reporting rules.

The After reporting stage rule is listed after the report stage rule in the specific action-processing rules.[/code]

However! Now, because the After reporting rules run so late, they won’t trigger if you have an After rule. I wrote an “After taking the alarm clock” rule, and since After rules end in success, it cut the action off before it got to the Report and After Report rules, and my After Report rule didn’t run. So this is not an ideal solution anyway! If you don’t have any cases where making-noise is part of a multiple action (taking, dropping, and removing it from, in the Standard Actions) then I think the Every Turn solution should work best.

BTW, I noticed you had “an actor making-noise” in your rule and the message said “You shouldn’t be doing that.” When “an actor” is in the rule header that’s meant to cover cases where the actor isn’t the NPC–if you only mean it to apply to PC actions you don’t need “an actor.”

Nice work! Adn your second code also reacts when the player tells Jinxie to dance! (This was what I was after by including ‘an actor’.) But then again, you described some kinda problem with it that rulebook which I didn’t quite get.

But I kinda feel like just letting that stupid text appear first - this little problem seem to require a bit too much work, like doing brain surgery to cure a hangover.

Oh, if you want to have the message appeared when telling Jinxie to dance, you definitely want “an actor.” I was thinking that the “You shouldn’t do that…” message wouldn’t be appropriate when someone else was the actor, but if you’ve just told Jinxie to dance it makes sense.

I was maybe unclear about what the problem was. Action processing runs through these rulebooks in order:

For each action [before-instead-check action-carry out action-after-report action]
At the end of the turn: [every turn]

as per the chart in Writing with Inform 12.2. The reason the messages appeared in the wrong order was because your “after acting-noisy” rule runs in the after rules, before the “report” rule runs.

The problem I was talking about with the “every turn” rules was this: If you have more than one action taking place in the same turn, like when you type TAKE ALL, then you cycle through first set of rules multiple times before you get to the every turn rules. So your every turn rule might not run if you performed a noisy action and then another action the same turn.

I tried to solve this by sticking another kind of rule after the Report rules. (It needs to be another kind of rule because Check, Carry Out, and Report rules can’t apply to kinds of action–there’s actually a separate check/carry out/report rulebook for each action. So I needed new rulebook that runs after the Report rules for any given action.) The problem with this is, After rules ordinarily stop processing of the action in its tracks–that’s why you had to put “continue the action” in your After rule. So when I wrote an After rule, the action didn’t get to the Report rules, or to the new rules I’d written to go with them.

The Every turn rules still run fine–when the After rule stops the action rules it kicks you to the Every turn rules. Unfortunately, I can’t see (or remember?) how to make the Every turn rules understand that this kind of action applies to actions by any actor.

Another way to take care of this is to use your After rule to set a flag reminding us that someone has made noise, and then check that flag in the Every turn rules to print the message about noise then:

[code]Noise flag is a truth state that varies.

After an actor making-noise when the sleeping ghost is visible:
now noise flag is true;
continue the action.

Every turn when noise flag is true:
say “Careful! You’ll wake the sleeping ghost!”;
now noise flag is false.[/code]

If there are going to be multiple such actions a creating a one-shot rulebook might be the way to go here:

previous action is a stored action that varies.
reporting on previous action is a rulebook.

this is the store an action rule:
	now previous action is the current action.
the store an action rule is listed first in the before rules.

every turn:
	follow reporting on previous action rules.

This will provide a nice way to report the previous action whether or not it succeeded (which would have been otherwise been stopped before getting to the after stage rules). Now you could use something like:

reporting on previous action when previous action is noisy and sleeping giant is visible:
    say "Perhaps less noise would be prudent around the sleeping giant.".
"noise test" by Bugs R Us

Lorem Ipsum is a room.
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

previous action is a stored action that varies.

reporting on previous action is a rulebook.

this is the store an action rule:
	now previous action is the current action.
the store an action rule is listed first in the before rules.

every turn:
	follow reporting on previous action rules.

dancing is an action applying to nothing.
understand "dance" as dancing.
report an actor dancing:
	if the actor is the player:
		say "You rat-a-tat a lively dance.";
	otherwise:
		say "[the actor] dances about.".
dancing is being noisy.

giant is a person in Lorem Ipsum.
giant is not proper-named.
giant can be asleep or awake.
giant is asleep.
rule for printing the name of giant:
	say "[if asleep]sleeping [end if]giant".

Jinxie is a person in Lorem Ipsum.
persuasion rule for asking Jinxie to try dancing:
	rule succeeds.

reporting on previous action when previous action is an actor being noisy and giant is visible and giant is asleep:
	say "(Maybe it would be prudent to make less noise around the sleeping giant.)".

Full working example using a generalized “reporting on previous action” rulebook.

Edit: I found a fix to make the condition trip for any actor being noisy rather than just the player.

So now you can add more rules so if you want to have thumping actions (say like jumping) and have a “thin crystyal floor” (like in journey to the center of the earth) in the room it’s now trivial to add a reporting on previous action rule to the rulebook for pounding type actions.

This is some solid code! I been gawking at it for a while, moving stuff around, renaming bits … I almost understand it. Congrats! :slight_smile:

The part you want to leave intact is the bit that sets up the rulebook, associated global variable and the before rule to store the last action to the global variable.

previous action is a stored action that varies.

reporting on previous action is a rulebook.

this is the store an action rule:
	now previous action is the current action.
the store an action rule is listed first in the before rules.

every turn:
	follow reporting on previous action rules.

Everything else is basically just the test case glue to utilize the rulebook.
The key part, that is, the part that actually puts a rule into the reporting on previous action rulebook is the last two lines:

reporting on previous action when previous action is an actor being noisy and giant is visible and giant is asleep:
	say "(Maybe it would be prudent to make less noise around the sleeping giant.)".

One important note is that this rulebook fires even if an action fails at some point in its processing, such as attempting travel in an undefined map direction (thus travelling in an undefined map direction would trigger something like ‘reporting on previous action when previous action is going: say “(Wandering too far may attract the attention of security.)”.’). So in the noise example even attempting something like playing a trumpet (assuming it’s defined as being noisy) when the player does not hold the trumpet will trigger the warning. However this is not easily changed as the mechanic that allows it to fire on an action processing path that fails midstream is precisely the same mechanic which allows it to fire when an action succeeds midstream (since both failure and success may cut the action processing short). In this case incurring the warning on the attempted action isn’t terribly out of place (since a playing a trumpet would indeed have been noisy had it succeeded) but YMMV for other kinds of actions.