Re: insteads. Without seeing your code, it could be a sign you’re doing things suboptimally… but that’s only really true if the instead rules are causing problems for you.
I feel like by the time you’ve got 271, you’d probably have noticed yourself if they were making it unnecessarily tedious to track or fix bugs. An example could be: do you find yourself adding ‘if’ clauses to your instead rules, or just more instead rules, to account for circumstances that might have been headed off automatically if a common action had been allowed to proceed through the check stage? That’s the kind of problem they could be creating. This is why they often get newbies in trouble if they start out over-insteading their way to glory.
But it’s also possible you’re just programming in a way that suits the content of your game.
My own foible is having a zillion check rules. They often complete the whole action; I am not a fan of having output text divvied off to Report or After rules that may need to restate the circumstances that lead to them. Occasionally this habit causes me problems, but mostly it suits how my brain works.
If you’d like a point of comparison, in Sub Rosa, a medium-large puzzle game in Inform7, the breakdown of rules is:
0 Instead
6 Before
311 Check
44 Carry out
33 Report
31 After
4 Understand “x” as a mistake
Many of those Check rules are essentially doing the same job as your Instead rules (they’re usually phrased "Check doing blah: say “no blah” instead).
For actions that successfully change the the world state, I don’t think you should use Instead:
Conceptually it’s muddled. You’re basically coding stuff like “Instead of pushing the button, you push the button”.
For testing, you get more information about action reporting if you structure your actions correctly. Instead will always appear as an action failing.
Using the full range of the rules allows you to properly order the effects. You know that check will trigger before carry out which triggers before report etc. This helps prevent bugs and makes parts of the code clearer: you always know, when looking at a rule, whether it’s meant to be checking pre-conditions or it’s meant to be changing the game state.
Sounds pretty normal to me. It really depends what those Instead rules are doing. The purpose of the Instead rulebook is to introduce special cases into the action handling, for things unique to your game. And depending on the size of your game, 271 special cases isn’t an absurd number.
I could maybe see lots of INSTEAD rules in a game that implements many new verbs and custom actions which need to redirect to each other and from the players input. instead of jumping: try superjumping. instead of jumping over something: try vaulting the noun.
@severedhand and @Joey are right on for the reasons you don’t want to do that and the warning signs; if you’re continuously having to comb and groom INSTEAD rules that go on more than two or three lines and include tricky IF statements, you might be doing the parser’s work unnecessarily.
Not that you can’t do that, but you can probably break up a complicated instead into other rules.
Instead of jumping: say "The gravity here is too strong. You'd break your ankle."
That’s a good use of Instead - blanket disallowing an action. It’s functionally equivalent to:
Check jumping: say "The gravity here is too strong. You'd break your ankle." instead.
You want to avoid stuff like:
instead of jumping:
if the player wears the jetpack:
if the jetpack is fueled:
if the jetpack is not broken:
try blastingoff;
otherwise if the jetpack is broken:
say "You'll need to repair the jetpack first;
stop the action;
otherwise say "The jetpack has no gas.";
stop the action;
otherwise if the player does not wear the jetpack;
try wearing the jetpack;
if the jetpack is fueled:
if the jetpack is not broken:
[...]
If this huge rule fails or doesn’t work correctly, Inform can’t really explain why.
Instead of jumping: try blastingoff.
Before blastingoff (this is the buckle up rule):
if the player does not wear the jetpack:
if the jetpack is touchable:
try wearing the jetpack.
Check blastingoff (this is the jetpack is necessary to fly rule):
if the player cannot touch the jetpack:
say "You won't get far just flapping your arms." instead.
Check blastingoff (this is the first repair the jetpack rule):
if the jetpack is broken:
say "You'll need to repair the jetpack first." instead.
Check blastingoff (this is the jetpack needs gas rule):
if the jetpack is not fueled:
say "You'll need to visit the gas station for some rocket fuel first." instead.
Carry out blastingoff:
now the player is in The Sky.
Report blastingoff:
say "Thrusters: ENGAGE!"
[etc]
The advantage here is if you turn on actions and the command fails, the IDE will say something like “Blastingoff - failed the jetpack needs gas rule” instead of “Jumping - failed the instead of jumping rule”
Right, Hanon makes a very good point here. Regardless of what rule type you’re using, splitting up your rules into manageable, well-described chunks is better than having one super rule to cover all behaviour. Here’s an example from the earlier game Calm in which we made this mistake constantly. There’s not an instead rule in sight, but the code is still bad:
Check smashing it with (this is the standard check smashing it with rule):
if the noun is the player, say "Things may be bad, but that isn't the way to end it all." instead;
if the noun is in the compound, say "The cameras are ubiquitous here. That would certainly go on your report." instead;
if the noun is cuttable, try cutting the noun with the second noun instead;
if the noun is the queen, try attacking the noun instead;
if the noun is soft begin;
say "([the second noun] is unneeded)[command clarification break]";
try attacking the noun instead;
end if;
if the noun is the second noun and action loop is false, say "You can't break something with itself." instead;
if the second noun is soft and action loop is false, say "[The second noun] [is-are]n't exactly suited to the task of breaking other things." instead;
if the second noun is fixed in place and action loop is false, say "You won't be able to pick up [the second noun] in order to break [the noun]." instead;
if the noun is unbreakable, say "[The second noun] bounces off [the noun]. You're not exactly sure what you've achieved by this exercise." instead;
if the noun is the vicar begin;
if the noun is broken, say "The vicar is already dead. He doesn't need to be any more dead than that." instead;
otherwise;
if the noun is broken, say "[The noun] [is-are] broken enough as it is." instead;
end if;
if the noun is small begin;
if the second noun is medium, say too big instead;
if the second noun is large, say too big instead;
otherwise if the noun is medium;
if the second noun is small, say too small instead;
if the second noun is large, say too big instead;
otherwise if the noun is large;
if the second noun is small, say too small instead;
if the second noun is medium, say too small instead;
end if;
if the noun is the second noun or the second noun is soft or the second noun is fixed in place begin;
if action loop is false begin;
say "Breaking [the noun] with [the second noun] should have been dealt with by now, so you should not see this message." instead;
otherwise if attack count is greater than five;
now attack count is zero;
now action loop is false;
say "You can't break [the noun] with just your bare fists." instead;
otherwise;
increase attack count by one;
try attacking the noun instead;
end if;
end if.
I thought I was further along, but THAT’S me. It’s not that I didn’t know that check, carry out and report existed, I just never considered using it extensively.
That makes direct sense to me!
@HanonO, thanks for the blastingoff example, it really explains very well how I can get out of my impasse! For me, it has also always been unclear whether I sort the game logic to the objects or to the verbs, but I have usually put it to the objects. So close to the IFComp I probably won’t change it completely, but from now on I’ll try to approach it differently right away!