Continuing the discussion from Typical Beginner's Mistakes in Parser Game Programming:
This might be an interesting question for other authors, so I made a separate thread:
Continuing the discussion from Typical Beginner's Mistakes in Parser Game Programming:
This might be an interesting question for other authors, so I made a separate thread:
Let’s think about the entering action. It’s a framework for entering things that applies to a wide variety of situations. Now, I could make a game with 30 enterable containers (or even not enterable containers, since instead doesn’t check that), but troubleshooting them individually gets hard after a while. I also can’t track them with things like
after entering something:
increment the enter count;
continue the action;
There can be a cost to opting out of built in behaviors, even if it seems that there is no practical difference.
Before rules are quite powerful, they can ignore accessibility rules. That is, they can apply to things that are visible but not touchable (items in closed transparent containers), objects (like directions). They can set values at the very beginning of a turn. They don’t have to stop anything, and they often don’t.
before doing something:
unless clicking:
now the pending action is "frob";
A lot of this stuff isn’t obvious at first. In a short game, INSTEAD can feel like everything we need. But we’re missing out on learning about the full capabilities of Inform, whether it’s choreographing the player’s turn or else managing the state of the world.
I haven’t said anything about the other turns; I don’t want to write a thesis! But you asked about them. I could come back later and update. I’d be interested to see what others say, though, this isn’t a comprehensive answer re: INSTEAD.
Here’s how I would summarize the I7 action-processing model:
Or for a shorter summary:
I defer to Draconis’s expertise, though I usually use INSTEAD for actions that stop and BEFORE for actions that continue. I wrote this on my blog maybe six months ago.
I’m still learning, though, and the post might be different today.
E: it might be helpful to think of things in terms of wide and narrow:
I found this nice table: Action Processing — Summary - I7 Handbook
Some examples, imagine a game where you can CAST [SPELLNAME]:
Before casting a spell:
if playerclass is not "mage":
say "You aren't the wizarding type, [playerclass]." instead.
[ie don't even bother running these rules]
Instead of casting armageddon:
end the story saying "The entirety of existence ends, as expected.";
[note the BEFORE rule prevents this if the player is not a mage]
First before casting armageddon when playerclass is not "mage":
if a random spellcaster is in the location:
say "[Spellcaster] goes white as a sheet, "Don't even joke about that!".
Check casting supernova:
if the location is enclosed:
say "Ignoring the advice of your mentor, you cast Supernova inside the tight quarters of [the location]...there is a deafening KER-BLAOW but you are vaporized before you hear it.";
end the story saying "That was an unusual strategy..."
First check casting supernova when Mentor Todd is in the location and the location is enclosed:
say "Sensing what you are about to do, Mentor Todd claps his hand over your mouth. "Not...here..." he hisses in your ear.";
stop the action.
Carry out casting electrozap:
now the location is lit.
Report casting electrozap:
say "The room lights up with sparks of harmless electricity."
After casting electrozap when the player is wet:
say "The room lights up with - OW THAT HURTS.";
decrease HP by 1;
evaluate the player's health.
[overrides Report rules by running first; After by default stops the action so the player won't see the Report rule, but the spell effects have already been carried out previously]
First report casting breeze when the location is stanky:
say "You pinch your nose as the breezes rise..."
[Report does not stop the action by default]
Last carry out casting breeze when the location is stanky and the number of living people in the location is not 0:
[assuming "living people" is defined as not including the player]
repeat with soul running through living people in the location:
now soul is in the Flower Shop;
now notifyfled is true.
Report casting breeze:
say "Gentle breezes ruffle your hair and light loose objects around you."
Last report casting breeze when the location is stanky and nofifyfled is true:
say "Anyone alive around you begins coughing and backing away due to the funk you've stirred up in the room, then bolts toward the Flower Shop.";
now notifyfled is false.
I vibe with that chart! It lines up with my own interpretation. I use instead to stop things and before rules usually continue (though sometimes there is a need to preempt INSTEAD). I enjoy hearing about how people use these rules, as there’s a lot to learn from the experience of others.
EDIT: just to add some data, Marbles, D, and the Sinister Spotlight has 29 before rules, 293 instead rules, 214 carry out rules, and 19 after rules. It has around 57,000 words
This is a great thread… Thanks
Since this was prompted by the perennial discussion about how newcomers to Inform 7 tend to overuse Instead rules, I thought it might help to list some of the situations where (to my understanding) an Instead rule isn’t the best choice:
But you might want to use one in these situations:
I haven’t written anything hugely substantial in Inform 7, so am I on the right track?
A good yardstick: If your Instead rule gets really tall requiring more than 3-5 lines of conditions to prevent breaking other rules and actions and is making huge alterations in the model world, you’re probably better off doing it another way.
Good:
Instead of entering the waterlogged canoe: say "Nope. Too dangerous."
Bad: (might work for a one off, but breaks parsing if the canoe is used multiple times)
Instead of entering the waterlogged canoe:
if the player is in the canoe:
say "You're already in the canoe.";
if the location is River:
say "You can't get more in the river than this unless you dive overboard.";
if the player's sailing ability is greater than 5:
if the player carries an oar:
say "You got this!"
now the player is in the canoe;
now the canoe is in River;
start the leak timer;
otherwise:
say "You'd be up the creek without a paddle. You need an oar.";
otherwise:
say "Your boatmanship is not up to snuff to handle this watercraft."
Honestly, I don’t think overuse of Instead rules is as big of a problem as it’s sometimes made out to be. After reading a command rules are a much bigger issue, imo.
My rule of thumb is:
In other words, most authors don’t need to write Check rules for the standard actions, only for new actions they’re implementing from scratch. I would only recommend doing it if you’re making a fundamental change to how the action works as a whole, for example:
Check going a nautical direction when the location is not nautical:
say "Nautical directions only have meaning when you're on a ship." instead.
This is a fundamental change to how the going action works, so a Check rule is more appropriate than an Instead one.
Is it bad to write: check eating the rock: say "You can't eat that!" instead instead of making an Instead rule? I’m reading all of these Instead usecases and I’ve realized that I’ve used check...instead for all of them.
You can definitely get yourself in way more trouble with after reading a command rules, but I think in practice beginners are way more likely to trip themselves up with Instead rules, in part because of how the docs are organized; instead rules are in the first substantive section in the actions chapter, so go figure that they’re the thing people just getting a grip on Inform tend to overuse! Meanwhile, check/carry out/etc. are only discussed in detail in the advanced actions chapter (13, vs. 7 for basic actions), and reading a command I think is just mentioned in chapter 18 – if you’ve made it that far, you’re probably making 201-level mistakes ![]()
Nah I think that’s pretty solid style.
As a matter of style, I prefer to keep Check for general rules for the action and Instead for specific situations for the game, but nothing will actually break if you cross the streams. That’s just my particular preference.
Yeah, to be clear, when I say I like something better, that’s all I’m saying. IMO any code that works well that the author can troubleshoot and read well is “good code.”
The issue I have with overuse of instead by beginners is the opportunity cost of delays to understanding action processing, inability to manage world state around actions, etc.
This thread split off from a thread about mistakes beginners make, so I’ve really just focused on helping people learn initially. Anyone who has a handle on action processing will settle on a personal style that works for them. (I hardly ever use check personally but that’s not because it’s bad)
My style is like this, and extremely check-heavy in general. And my WIP is approaching half a million words and travelling solidly.
If I ask myself why I’m so check heavy, it started out that I never liked the carry out / report / after nexus somehow, at least for irregular actions. I often felt I was restating conditions across multiple rules. So instead I’d hit all the conditions and the outcomes in one check rule so they were attached to each other. I think now (a decade+ later!) I understand things better and would be less phased by the initial situation.
There was also a period where I and others were scared of having too many Befores and Insteads and Afters for lag-avoiding reasons, because those are all consulted every move whereas the other books aren’t. But if it ever was a potential concern, Inform evolved and it no longer was. Still, I thought I might be writing the longest Inform game ever, so I had to think about things like that before I found out it was a problem too late.
-Wade
Trying to summarise what I understand of that which has been said so far:
before and instead, and this is what makes those two rulebooks different, even if the before rule is given a stop the action.before rules, we can redirect a inadmissible action to an admissible action with a before rule, but not with an instead rule.Combined with the idea that check/carry out/report is used only for standard, generic behaviour, and before/instead/after is used for special cases, that paints a fairly clear picture of when to use each sort of rule.
That said, there seems to be some active debate around this last division between generic behaviour and special cases. There are no strong arguments in favour of either side, that I can find, and it seems like personal preference dominates. For example, HanonO’s spellcasting example violates that principle in multiple locations:
before rulebook, rather than check. Are we expecting that some accessibility rule will give a misleading response to non-wizarding types?carry out rulebook, unlike electrozap. With the supernova spell, the game-ending action is in check instead, which also seems inconsistent.check rule rather than an instead rule. I was under the impression that such special cases would be the domain of instead.This debate ties in to Hidnook’s question about a rock eating failure rule: this is not part of the normal eating behaviour, so according to the division of rules it should be an instead rule, but if one does not believe in the division of rules, a check rule works just as well.
Though as Drew Cook clarifies: the overuse of instead rules has more to do with failing to manually implement normal check and carry out behaviour. Whereas the proper rule might be
After taking the apple:
now the player is cursed;
say "As you pick it up, you notice an unnatural sheen on its skin."
a beginner might be inclined to write
Instead of taking the apple:
now the player is cursed;
now the player is carrying the apple;
say "As you pick it up, you notice an unnatural sheen on its skin."
which can yield a transcript like
>get apple
As you pick it up, you notice an unnatural sheen on its skin.
>i
You are carrying:
an apple
>get apple
As you pick it up, you notice an unnatural sheen on its skin.
instead of what we get with the after rule, which is the intended
>get apple
As you pick it up, you notice an unnatural sheen on its skin.
>get apple
You already have that.
Being a beginner myself, I still make this mistake a lot!
Instead of [action]: [do something else] is theoretically equivalent to Check [action]: [do something else] instead. but the check rule is less open-ended than instead.
INSTEAD rules by design cause the parser to relinquish control and let the author ignore most of the world-model rules and parsing (except for stuff like scope/reachability) for the duration.
CHECK is notating a potentially closed road on the bus route for the driver; INSTEAD is grabbing the wheel and saying “lemme navigate us around this construction despite you having all the bus-driving expertise…[tires squeal]”
Right, which is basically what I’m saying: Check rules are rules about how the action works in general, Instead rules override the general ones for specific situations in the game. Check rules say you can’t eat something that’s inedible; Instead rules say that if you eat the magic beans you die horribly.
Given all of this… I’d like opinions on the best way to open a “shade”… I currently did it the newbie way of “instead of opening” and then I describe the view out of the window since it’s just a scenery item. (similar instead for closing) It’s just a scenery item, so it doesn’t need to actually “open” and “close”… This seems to work fine. Perhaps players could find a way that this does not work well… Opinions on the best “shade” approach for a window with a view? (but no entrance/exit, eg: it’s not a door)
While I think I get it, does an instead rule grab the wheel more than a check rule with an instead qualifier at the end? I don’t feel that it does.
Unless we are talking about potential reach/scope (the wide/narrow distinction I made above)! Instead can do things like
instead of doing something other than examining or taking to the apple:
Which check cannot. So while check can be general about nouns, it cannot be equally general about actions. So I often think about these things in terms of their reach.