Replacing procedural rules

With procedural rules now deprecated and marked for removal in the next major release of Inform 7, what is the best way to deal with procedural rules that apply only during certain activities, ie, those beginning “Procedural rule when XXX:”

I would like to update my patrollers extension to remove the deprecated phrases it uses but I cannot see an elegant way to do this. Would it be better to wait until the next major release on the basis that there will be a new mechanism to achieve this result?

Part of the point of deprecating procedural rules (rather than simply abolishing them) is precisely to find out where they provide functionality that we need to replace somehow.

The approach we’ve taken with Procedural rule when XXX: … is to replace the rule that the Procedural rule was going to ignore, and build in the conditions into the replacement. (You can see an example of this happening in the built-in Locksmith extension.)

If this doesn’t work or isn’t enough for some reason, we’d like to hear about your problems doing away with procedural rules, as these will likely guide syntax for future builds. If you have ideas you’d like to share about this, you can email me and Graham, or add a suggestion at the suggestion forum (inform7.uservoice.com/)

Because this seems to be a widespread concern, I’ve written up some notes on it on the Inform news feed, here:

inform7.com/news/2010/06/16/6e59 … ral-rules/ .

There is also already a suggestion on the uservoice forum proposing some alternate syntax. It can be found here:

inform7.uservoice.com/forums/573 … ?ref=title

User thoughts on this continue to be welcome.

So I have a kind called dispensers. They dispense an unlimited quantity of another object. For example, a lake may dispense cupfuls of water. A stack of paper dispenses single sheets of paper. Etc. (The dispensed item – the “prize” – is a singleton. Denial messages of the form “You already took one” appear if taking a second prize is attempted, so I don’t bury the world in single sheets of paper.)

Some actions, such as TAKE, are redirected from the dispenser to the prize. This involves surreptitiously moving the prize from off-stage to on-stage, then “try taking the prize instead”. However, for the purposes of nice messages, I actually want most of the Check Taking rules ran for the dispenser before handing off to the prize. This is because, for example, if the whole pile of things is unreachable for some reason – on a high shelf, or the PC is tied up, etc. – I want the denial message to say “You can’t reach the lake from here.” rather than “You can’t reach the handful of water from here.” So I do the re-direct from “Last check taking a dispenser”. But, that Last Check rule won’t be hit because of the can’t take what’s fixed in place rule (among one or two others, I think). So I’ve been using a procedural rule to ignore some of the check rules for dispensers, knowing it’ll be re-directed to the prize which won’t have problems of being fixed in place.

Secondly, but less convincingly, I have several light-up pushbuttons on a thing. (Think of the Caps Lock and Num Lock buttons on your keyboard.) Since each light-up button can be on or off, each button is itself a device. (The keyboard itself, to which they’re attached, is just a Thing.) But a player won’t enter SWITCH ON BIG RED BUTTON, they will enter PUSH BIG RED BUTTON. So I implement the pushing action for the device kind, a carry out rule calling the switching on or switching off actions as appropriate.

The tricky part is that, unlike Caps Lock, pressing some buttons affects other buttons, possibly switching them off/on. (Why yes, it is a part of a puzzle, how did you know?) I want reporting the changes to be in one seamless, well-narrated paragraph, so it is easiest to write a single Report Pushing rule that narrates the whole result regardless what button was pushed and which direction its being switched. (The report uses past tenses, like “if the big red button was switched off…”, to know what changed.)

However, I also use the pushing action normally, for pushing around crates and furniture, which obviously requires the pushed item not be fixed in place. My pushbuttons are fixed in place, so, when pushing a device, ignore the can’t push what’s fixed in place rule.

I should add that I rewrote the pushbutton case as follows. “First check pushing a device” will re-direct to the appropriate switching action “instead”, and the master Report rule was named so it could be listed in two rulebooks simultaneously: report switching on & report switching off.

It’s probably cleaner that way, hence a less convincing case for Ignore.

I was curious about how much I actually use procedural rule manipulation, so I looked at the main project I was working on several months ago. Searching for the word “procedural” in the source text (in a project perhaps only fifty-percent complete) turned up the following:

[code]Procedural rule for examining a backdrop: ignore the general report examining rule.

Procedural rule for an actor searching an underside: ignore the standard search containers rule.

Procedural rule for examining a bodycomponent that is embodied by a person: ignore the standard examining rule; ignore the general report examining rule.

Procedural rule for examining a gemstone: ignore the general report examining rule.

Procedural rule for examining a person: ignore the standard examining rule; ignore the general report examining rule.

Procedural rule for examining a backdrop (called cfaroff):
unless cfaroff is backdropinteractive:
ignore the general report examining rule;
otherwise:
continue the activity.

Procedural rule for someone examining when the person asked is vision-impaired or the person asked is hearing-impaired: substitute the diminished xing capability rule for the report other people examining rule.

Procedural rule for an actor taking something when the noun is enclosed by a broke person (this is the corpse-looting rule): ignore the can’t take people’s possessions rule.

Procedural rule while eating something (called AA) (this is the skip stupid eating restrictions rule):
if the player can touch AA:
if AA is not enclosed by something worn by a not broke person and AA is not enclosed by something carried by a not broke person and AA is not worn by a not broke person and AA is not carried by a not broke person:
ignore the carrying requirements rule.

Procedural rule for an actor putting something on a subpole: ignore the can’t put onto something being carried rule.

Procedural rule for an actor connecting something to a subchain: ignore the broke check for connecting second part rule.

Procedural rule for trying entering a subchain: ignore the how many angels can dance on the head of a pin rule.

Procedural rule for someone trying entering a subchain: ignore the how many npcs can dance on the head of a pin rule.

Procedural rule for examining a subchain: ignore the after xing a supporter rule.

Procedural rule for examining a bodycomponent (called thegoods) that is embodied by a person:
ignore the general report examining rule;
unless thegoods is a skinsign:
ignore the standard examining rule;
otherwise:
continue the activity.

Procedural rule for an actor drying a person with something:
ignore the report drying rule.

Procedural rule for an actor connecting a power-plug to a power-socket: ignore the generic connectblock rule.

Procedural rule for an actor disconnecting a power-plug from a power-socket: ignore the generic disconnectblock rule.

Procedural rule for an actor connecting a beltish thing to a belt: ignore the generic connectblock rule.

Procedural rule for an actor putting something on an idholder: ignore the can’t put onto something being carried rule.

Procedural rule for an actor putting something on a dtchain1:
ignore the limiting keychains rule.

Procedural rule for examining a dtchain1:
ignore the list included keys rule.

Procedural rule for an actor putting something on a belt: ignore the can’t put onto something being carried rule.

Procedural rule for an actor disconnecting a beltish thing from a belt: ignore the generic disconnectblock rule.

Procedural rule for an actor connecting a riflestrap to a firearm: ignore the generic connectblock rule.

Procedural rule for an actor disconnecting a riflestrap from a firearm: ignore the generic disconnectblock rule.

Procedural rule for an actor connecting a gpq47 to an msgrifle: ignore the generic connectblock rule.

Procedural rule for an actor disconnecting a gpq47 from an msgrifle: ignore the generic disconnectblock rule.

Procedural rule for examining a closed folding pocket knife: ignore the check that blade rule.

A procedural rule for an actor touching a biometric scanner:
ignore the report touching things rule.

Procedural rule for examining a lipstick: ignore the general report examining rule.

Procedural rule for an actor wearing a lipstick: substitute the lipstick-wearing step-1 rule for the standard wearing rule; ignore the standard report wearing rule.

Procedural rule for an actor unlocking the prddoor4-2 with something: ignore the can’t unlock without the correct key rule.

Procedural rule for an actor ringing the prfdbell: ignore the std useless ringing rule.

Procedural rule for an actor ringing the prfdkno: ignore the std useless ringing rule.

Procedural rule for an actor unlocking the prdentrance-2 with something: ignore the can’t unlock without the correct key rule.

Procedural rule for an actor searching the prfdpeep: ignore the can’t search unless container or supporter rule.

Procedural rule for examining the prstairs1: ignore the xing a door rule.

Procedural rule for examining the vjboxfiller: ignore the general report examining rule.

Procedural rule for an actor folding the pratticladder: ignore the general block useless folding rule.

Procedural rule for an actor unfolding the pratticladder: ignore the general block useless unfolding rule.

Procedural rule for examining the hubstairs: ignore the xing a door rule.[/code]
The above is intended as an example of how often I use this sort of syntax, and for what purposes; I’m not looking for any help rewriting or redesigning anything.

Although I don’t really understand the mechanics of the “enhancing performance” angle (we’re not talking about developing <insert title of latest blockbuster 3D twitch-gaming clickfest here>), I can see why the developers may want to get rid of procedural rule manipulation for aesthetic purposes. Procedural rule manipulation horribly clutters the rulebooks; if you want a rule to function differently than its default state, just rewrite the relevant rule. Simple, right?

The problems with this development change are all on the end-user’s side, and I think mainly fall into two categories.

The first is that working with rulebooks is in my view the most sophisticated sort of use of I7, and far out of reach of beginners or even those with intermediate-level skills. Procedural rule manipulation is a quick and easy tool that’s very helpful in allowing those with a non-expert understanding of I7 to affect changes to unhelpful or unattractive (from the perspective of the particular end-user) aspects of the Standard Rules. Attempting to explain to someone with only a moderate I7 skillset why and how they must comprehensively rewrite some portion of the Standard Rules for what may seem like a minor effect may result in some potential end-users writing the program off as too abstruse and not fulfilling its promise of being an easy and simple coding platform. I think it’s a mistake to understimate these sorts of concerns.

Related to but distinct from this first point is the reality that, even for advanced end-users, the prospect of extensively rewriting large sections of the Standard Rules to incorporate changed functionality or allow small exceptions of the sort Ron mentioned above is tedious at best and daunting at worst. For example, consider several lines from the example I posted above:

[code]Procedural rule for examining a backdrop: ignore the general report examining rule.

Procedural rule for examining a bodycomponent that is embodied by a person: ignore the standard examining rule; ignore the general report examining rule.

Procedural rule for examining a gemstone: ignore the general report examining rule.

Procedural rule for examining a person: ignore the standard examining rule; ignore the general report examining rule.

Procedural rule for examining a backdrop (called cfaroff):
unless cfaroff is backdropinteractive:
ignore the general report examining rule;
otherwise:
continue the activity.

Procedural rule for examining a bodycomponent (called thegoods) that is embodied by a person:
ignore the general report examining rule;
unless thegoods is a skinsign:
ignore the standard examining rule;
otherwise:
continue the activity.

Procedural rule for examining a lipstick: ignore the general report examining rule.

Procedural rule for examining the vjboxfiller: ignore the general report examining rule.[/code]
We can quickly begin to see the sort of serpentine form that my rewritten “general report examining rule” will take, with many exceptions both for broad categories of objects as well as individual items. While it’s trivially true that I was in fact already “rewriting” the rule anyway with each procedural exception, the experience will now be quite different as I will need to do the work formerly performed for me by Inform. Each time I require another changed consideration, I will have to rewrite an increasingly lengthy and complex rule rather than just add a simple “Procedural rule for…” line to the section of code I’m currently working on; just because I have the ability to do such a thing doesn’t mean I’ll look fondly upon the prospect of so doing.

Another example of this concern can be found at the link posted above by emshort, with:

Procedural rule when putting something on a keychain: ignore the can’t put onto something being carried rule.
to now be replaced with:

[code]The keychain-aware carrying requirements rule is listed instead
of the carrying requirements rule in the action-processing rules.

This is the keychain-aware carrying requirements rule:
if locking or unlocking something with something which is on a keychain which is carried by the actor:
continue the action;
abide by the carrying requirements rule.[/code]
A requirement to now write 51 words where 17 words would formerly do certainly doesn’t seem like a very worthwhile improvement or enhancement from the average end-user’s perspective.

While eliminating procedural rule manipulation may streamline the rulebooks from the perspective of a disinterested observer, any particular end-user is much less likely to have trouble deciphering what may be considered (to an onlooker) an abstruse (i.e. filled with procedural exceptions) rulebook from their own particular project.

In general, then, I think the phase-out of procedural rule manipulation is a step away from user-friendliness (which is stipulated as a major feature of Inform 7). While I personally will be able (with extra effort) to work within these new constraints, I think this change will present yet another stumbling-block to encouraging potential new end-users to make the leap from toying around with I7 for a few days to create a small project rather than delving in and creating something truly interesting. I can appreciate that the decision has been made, though, so having now aired my opinion I’ll be quiet about the whole thing.

The performance angle is–every time any rulebook is run (which is many times per turn, e.g. before, during, after every activity, every action, etc.), Inform has to check every one of your procedural rules to see whether it applies. It’s a lot of overhead, especially when the vast majority of things that people do with procedural rules are more cleanly done by directly targeting the rules they want to change.

–Erik

Thanks for the feedback – this is an interesting angle.

Two comments:

First, the performance is definitely an issue: while it’s not a problem for downloaded interpreters, it’s one of the major reasons why I7 games run more slowly on browser interpreters, and in particular the current maintainer of Parchment believes he could significantly improve behavior there if he doesn’t have procedural rules to contend with. This is a fairly widespread concern, since more and more people are interested in sharing their games in a context which does not require the user to download or install anything.

Second, I’m interested in the line that procedural rules make things easier for new authors; what we have mostly heard about this is that procedural rules are a bit mystifying, and that they introduce further complications in the rulebook handling (what’s the difference between consider and follow? where can I safely use “ignore” and “move” to control rules?) that new users find completely opaque. I’ve gotten quite a few questions from novices that turned out to be due to a misunderstanding or misapplication of procedural rule syntax. Getting rid of the procedural rule layer would reduce the total amount of syntax to learn and the complexity of the way the system fits together. So I’d definitely be interested to hear whether there are other authors who share your experience of the learning curve.

I’ve never used procedural rules, and honestly I am kind of relieved that they are being phased out – one less thing for me to feel bad about not understanding. My games are arguable fairly simple, though.

It’s a simple concept: “I like the dogs can’t talk rule, but I’d like it to be ignored when Timmy falls down a well.” That’s a natural way to think, and “ignore” is pretty clear. However, when he casts it as a procedural rule, his across-the-board assertion becomes “The dogs can’t talk rule is ignored when Timmy falls down a well and the procedural rules are now in effect.” Well, when is that?

Then we read the manual, and there’s consider and follow and oh boy how complicated it all is.

As I try to wean myself from using procedural exceptions, I was hoping someone could verify that I’m using an optimal technique (as demonstrated by the following).

I intensely dislike implicit actions of any sort (others disagree, and that’s fine; I’m not trying to argue about that issue here). I don’t ever want any sort of implicit actions in any project I’m creating, and thus was instantly unsatisfied with the change in the new version of the Standard Rules governing the behavior of doors (unlocked openable doors are now implicitly opened when the player attempts to enter them). Therefore instead writing “Procedural rule for…” as I would have in the past, I wrote the following after spending a few minutes trying to figure out which particular rulebook held the relevant standard rule:

[code]The closed doors are closed rule is listed instead of the can’t go through closed doors rule in the check going rulebook.

This is the closed doors are closed rule:
if the door gone through is not nothing and the door gone through is closed:
say “[The door gone through] is closed.”;
stop the action;
otherwise:
continue the action.[/code]

Is there a better way of going about this whole thing (whether in general or in some particular detail), or does the method I used seem to cover all bases?

Thanks.

You got it right. A more succinct version might be:[code]
The closed doors are closed rule is listed instead of the can’t go through closed doors rule in the check going rulebook.

This is the closed doors are closed rule:
if the door gone through is not nothing and the door gone through is closed, say “[The door gone through] is closed.” instead.
[/code]

Alternately, if the new rule needs to have conditions attached, such as making it only apply to the player or to NPCs, then it could be very slightly different:[code]
The closed doors are closed rule is listed instead of the can’t go through closed doors rule in the check going rulebook.

Check an actor going when the actor is not a ghost (this is the closed doors are closed rule): if the door gone through is not nothing and the door gone through is closed, say “[The door gone through] is closed.” instead.
[/code]

Thanks, Ron.

Here’s a different sort of issue where I may have formerly used a procedural exception, intended mainly as another example since it’s not something with which I actually need help.

Let’s say I have device that is sort of like a “glow-stick” or lantern, whose function is intended to be (very slightly) mysterious until the player succeeds in turning it on for the first time (sorry for the crytpic item names found below).

[code]A lightstick01 is in the whitebox01. The lightstick01 is a device. The lightstick01 is privately-named. The printed name of the lightstick01 is “cylinder filled with viscuous green liquid”. Understand “lightstick” or “light stick” or “light-stick” or “light” or “cylinder” or “green liquid” as the lightstick01. The description of the lightstick01 is “[unless the lightstick01 has been lit]A transparent cylinder, apparently made of an ultra-hard polymer material. The cylinder is about eight inches long and filled with what seems to be a viscuous green liquid. A small sealed seam runs around the middle of the cylinder[otherwise]A light-stick made of a very hard and transparent polymer material. Twisting the ends of the cylinder either causes the thick gel inside to emit a dull green light, or causes the device to stop emitting light if it is currently so doing[end if].”

Instead of an actor turning the lightstick01:
if the lightstick01 is switched on:
try the actor switching off the lightstick01;
otherwise:
try the actor switching on the lightstick01.

Carry out switching on the lightstick01:
now the lightstick01 is lit.

Carry out switching on the lightstick01 for the first time:
now the printed name of the lightstick01 is “light stick”.

Carry out switching off the lightstick01:
now the lightstick01 is unlit.[/code]
I’ve never cared much for the way the standard examine devices rule works, and I always delist it (I usually like to build a comment about whether a device is on or off into the actual description of said device). In actuality for this particular item I’ve now written:

[code]The examine devices rule is not listed in any rulebook.

Report examining the lightstick01:
if the lightstick01 has been lit:
say “[The noun] is currently [if switched on]turned on, emitting a pale green glow[otherwise]turned off[end if].”[/code]
so its nature won’t immediately be revealed after examining it the first time or two.

Let’s say, however, that I generally thought the examine devices rule was fairly groovy but didn’t want it to apply in the particular case of this glow-stick (since its purpose is intended to be vaguely mysterious). In the past I may have just written:

Procedural rule for examining the lightstick01: ignore the examine devices rule.
And made some variation of my own report examining rule as shown above, or else simply incorporated the current status of the item into its normal description. Now however, according to my understanding I would need to find the examine devices rule and begin rewriting it in the following manner:

[code]The full of exceptions device rule is listed instead of the examine devices rule in the carry out examining rulebook.

This is the full of exceptions device rule:
if the noun is a device:
now examine text printed is true;
if the noun is the lightstick01:
say “[The noun] is currently [if switched on]turned on, emitting a pale green glow[otherwise]turned off[end if].”;
otherwise:
issue library message examining action number 3 for the noun.[/code]
I would then continue adding more clauses to this rule for each new kind of device or individual device for which I wanted a custom reporting option.

I think this example illustrates one of the points I was making earlier–while an I7 user with moderate skills may have little trouble identifying the “examine devices rule” from the Actions Index and writing a procedural rule to ignore it in certain cases, it seems somewhat unreasonable to expect such a person to open the Standard Rules, find the relevant rule, and quickly understand what is meant by obscure phrases such as “now examine text printed is true” or “issue library message examining action number 3.” Much more importantly, it seems quite unreasonable to expect such an intermediate-level user to quickly comprehend how such statements interact with other statements and rules in the Standard Rules, which is necessary to avoid making a terrible mess of things when one starts modifying/customizing the rule. The end result may well be that such a person says “This is too complicated” if (i.e. when) they get themselves into trouble, causing them to set I7 aside completely.

Hopefully any future redesign of the I7 architecture will take such considerations into account, as they seem to me just as important as optimizing the program’s output for play in web-based javascript interpreters (I’ve never used one of those, but I’ll gladly accept ektemple’s and emshort’s evaluations regarding the technical issues associated with such). Such innovations for players won’t have much purpose if new content creators fail to find I7 generally appealing, or if they aren’t able to easily climb the learning curve to the point where they can create compelling content.

I take your point, but there’s a less maddening way to deal with this problem. Any time you have a situation where you are likely to issue lots of individual custom messages, it’s time to break out an activity. Like this (simplified down from the “Aftershock” example in the Manual):

[code]Lab is a room.

The lightstick is a switched on device. The lamp is a switched on device. The player carries the lightstick and the lamp.

Showing action of something is an activity.

Rule for showing action of the lightstick:
say “[The noun] is currently [if switched on]turned on, emitting a pale green glow[otherwise]turned off[end if].”

Rule for showing action of something (called item):
if the item is switched on, say “[The item] is switched on.”;
otherwise say “[The item] is switched off.”

The new described devices rule is listed instead of the examine devices rule in the carry out examining rules.

This is the new described devices rule:
if the noun is a device:
carry out the showing action activity with the noun;
now examine text printed is true.
[/code]

This has some advantages over the procedural rule method. One, it’s briefer to substitute new text for old (because you only have to write the activity rule, not text-printing rule + procedural rule to swap it into place); two, it means your index contains an orderly list of all the rules that affect the device description, rather than a big swamp of different procedural rules.

(I grant you it requires a tiny bit of knowledge about what else is going on in the Standard Rules to set the activity up in the first place, but in fact this particular example is already written up for you, and the majority of SR actions are simpler than this one.)

Does that help? If not, what do you see as still being the major design concerns?

@emshort

The activity-based approach you suggested is good idea and easier to implement over a large number of cases than the example I looked at in my last post. A technique I have often used in the past when writing novel actions that only apply to a few particular items was to make a simple check rule to block the new action in all cases and then make individual exception rules for the things to which the action was meant to apply. This technique will no longer be very practical under the new design scheme, but the activity-based approach is an effective substitute that is conceptually similar and has the many of the same advantages.

One of my main concerns is that I often make extensive use of automated text in a variety of contexts, and that I also frequently make large numbers of general and specific exceptions to such usage. For example in one project I had a rule called the “general report examining rule” that looked like this (the latest version of this rule is even more complex and much longer, but I’ll spare everyone the tedium of browsing through its cryptic verbiage as I’m not looking for any suggestions about improving it):

Report examining something (this is the general report examining rule): let runondesc be 0; let addondesc be ""; let rsummary be a list of text; let rsummary be {}; unless the noun is a backdrop: if the noun is colorish: if the noun is submaterialish: say "[The noun] [is-are] [color of the item described]-colored and made of [unless the submaterial of the item described is smundef][submaterial of the item described][otherwise]an unknown substance[end if][run paragraph on]"; otherwise: say "[The noun] [is-are] [color of the item described]-colored and generally made of [propermaterial for the noun][run paragraph on]"; if the noun is not colorish: if the noun is submaterialish: say "[The noun] [is-are] made of [unless the submaterial of the item described is smundef][submaterial of the item described][otherwise]an unknown substance[end if][run paragraph on]"; otherwise: say "[The noun] [is-are] generally made of [propermaterial for the noun][run paragraph on]"; if the noun provides the property open or the noun provides the property closed: if the noun is open: change addondesc to "currently open"; add addondesc to rsummary; if the noun is closed: change addondesc to "currently closed"; add addondesc to rsummary; if the noun is broke: change addondesc to "broken"; add addondesc to rsummary; if the noun is soiled: change addondesc to "[currentsoilstate of the item described]"; add addondesc to rsummary; if the noun provides the property switchreportable: if the noun is switched on: change addondesc to "currently turned on"; add addondesc to rsummary; if the noun is switched off: change addondesc to "currently turned off"; add addondesc to rsummary; if the temperature of the noun is less than 32: change addondesc to "very cold"; add addondesc to rsummary; if the temperature of the noun is greater than 149: if the temperature of the noun is greater than 149 and the temperature of the noun is less than 201: change addondesc to "scalding hot"; add addondesc to rsummary; otherwise if the temperature of the noun is greater than 200 and the temperature of the noun is less than 401: change addondesc to "dangerously hot"; add addondesc to rsummary; otherwise if the temperature of the noun is greater than 400: change addondesc to "glowing hot"; add addondesc to rsummary; if rsummary is empty: unless the noun is a backdrop: say "."; if rsummary is not empty: unless the noun is a backdrop: say ". [Cap it-they of the noun] [is-are] [rsummary]."; otherwise: if the noun is backdropinteractive: say paragraph break; say "[Cap it-they of the noun] [is-are] [rsummary].".
The rule was utilized for a large number of things, but an equally large number of things either had their own unique examine rule (usually with similarly complex clauses) or used the standard report examining rule. The prospect of combining this “general report examining rule” with other particular examining rules as well as the standard report examining rule into one epic rule, and then doing similar patch-work for a large number of other actions and contexts, and then keeping in mind a clear idea of how each of these epic rules function when the time comes for further modification seems like something that may require more time than I’d care to devote to the matter. Hopefully it will be much easier and manageable to adapt the activity-based approach you’ve suggested than ponder revised Standard Rules that run for hundreds of lines.

off-topic p.s.:
I didn’t look at the current bug-list thingy to see if this was already reported (feel free to just smack me), but both your Locksmith and your Deluxe Doors extensions require a number of syntax changes in order to work with 6E59 while the “Use no deprecated features” option is active.

Burble. Yeah, I wouldn’t want to keep track of that either.

Partly I think this is a question of coding instincts which are different for I7 than for many other languages. My aesthetic/design sensibility for Inform 7 says that if I have a rule that runs to more than 10-20 lines, or has numerous if-statements like that, it’s time to break out into a rulebook or activity.

I use activities for printing variable text, because they come with some neat hooks, like
– the ability to say “rule for printing the name of the apple while showing the device operation of the apple corer”
– the ability to add text or processing right before or after the activity, as in “before showing the device operation of the apple corer: play the electric device sound” or "after printing the name of Mr Beebe: say “, Esq.”.

I use rulebooks for many other tasks involving detailed decision-making, because they let you bind together a collection of prioritized rules and track variables that last for the duration of the rulebook processing.

The “Tilt 2” example, which analyzes a group of five cards to see what value it has as a poker hand, is a good example of the kind of very exception-filled, fiddly analysis that would simply be too awful to contemplate as a single continuous piece of code. The discipline of thinking about it in terms of rulebooks helps me figure out what to do:

– consider what variables are going to be important in making this calculation; for instance, in the poker rules, I want to know whether all the cards are the same suit, because that will be important for several decisions later on. Make those into rulebook variables. Make the first rule(s) of my new rulebook calculate the value of those variables.

– create the rulebook to identify (usually) the most specific/complex cases first (a royal flush is a very specific kind of poker hand, so we want to identify it and get it out of the way before we go on to other kinds of straight flush, other kinds of straight, other kinds of flush…)

OK, so far so good. (And as a player, thank you for implementing TURN on that lightstick. I love that.)

But this: Report examining the lightstick01: if the lightstick01 has been lit: say "[The noun] is currently [if switched on]turned on, emitting a pale green glow[otherwise]turned off[end if]."
Has two issues. One, the say phrase needs to end in “instead” so that once this message is printed, no other Report rules will run and say stuff. And two, that if-condition needs to be moved into the rule header, so the rule is listed before more general rules, such as “Report examining the lightstick01” or “Report examining a device”: Report examining the lightstick01 when the lightstick01 has been lit: say "[The noun] is currently turned [if switched on]on, emitting a pale green glow[otherwise]off[end if]." instead.
Since the conditions on this rule are very specific, it will be considered before the examine devices rule. And since the rule uses “instead”, the examine devices rule (among others) won’t be considered afterward, either. So you never need to do that full-of-exceptions business. This is why Inform is rule-based. Exceptions like that lightstick occur constantly. So we write rules that apply specifically to the lightstick, and Inform will re-order all those report rules so that the specific rules are consulted first. And, via that “instead”, that lightstick-specific rule can also say yea or nay to whether the rest of the report rules are even given a chance to run, let alone print.

The procedural rules are problematic in that new users frequently try them when they don’t really need to. Partly this may be the documentation. I myself was un-listing standard report rules before someone told me to just tack on “instead”. I don’t feel that say…instead (or any other time instead can be appended) have really been stressed like it should be. The one place most people are aware of its use is in Check rules.

I’m chagrined about the Locksmith thing – I thought we’d tested that, but it turns out that we had only tested after stripping procedural rules and not a second time after the change to use options. I’ve sent Graham new copies of the built-in extensions for the upcoming build.

The non-built-in extensions, I’m working my way through: there are a lot of them, and I don’t have enough time to do them all at once, so it’s a slow process. If Deluxe Doors is a priority for you, I’ll try to get to it sooner rather than later; alternatively, if you (or anyone, really) want to make the adjustments and send me an updated version, I’ll post it gratefully.

One potential issue is that it’s pretty hard to find the documentation for tacking on “Instead” if you don’t know where to look. That formulation shows up a fair amount in the examples, but searching for “instead” in the documentation to find it is pretty futile – even searching for “instead.” it just took me a fair amount of paging through to get to the “Named outcomes” documentation.

Matt

Okay, interesting point. Where do people feel would be a natural place to introduce the explanation of “instead”? I feel like it’s sufficiently basic that it ought to be somewhere early (and I thought it was mentioned somewhere early, but possibly in a casual/in passing kind of way). Where did you want to learn it and/or where are you looking for it?