Beginners question: Local vs Global

There isn’t anything close to consensus on how to organize your code beyond “some way that’s understandable to you”. Some past threads are I7 Code Organization and Efficiency, Splitting the story into multiple files . How to Structure I7 Code is one answer.

When you just say “check pushing” or “carry out pushing”, those rules will be triggered any time the player tries to push anything, anywhere, any time. There’s a subtle default restriction lurking there: they apply to the player only. If you have NPCs taking actions, those rules wouldn’t automatically apply. You would have to write “check an actor pushing”, “carry out an actor pushing”, etc.

There’s a default “Nothing obvious happens” for pushing things; if you’re happy with that instead of “nothing happens…” your code could be:

A teleport button is a kind of thing.
A teleport button can be working or broken.
A teleport button is usually working.
A teleport button is usually fixed in place.

The Studio is a room.
The red button is a teleport button in the Studio.
The purple button is a broken teleport button in the Studio.
The chartreuse button is a thing in the Studio.

The Alien's Chamber is a room.
The blue button is a teleport button in the Alien's Chamber.

Check pushing a broken teleport button:
  instead say "Some crackled noises tell you that the button isn't working properly.";

Carry out pushing a working teleport button:
  if the noun is the red button, move the player to the Alien's Chamber, without printing a room description;
  if the noun is the blue button, move the player to the Studio, without printing a room description;

Report pushing a working teleport button:
  say "After a flash of light, you find yourself in...";
  try looking;
  stop the action;

There are a zillion ways to do things, and some of the choices above are arbitrary. Instead of looking at red vs. blue button, it could have been if the location is the Studio, move the player to the Alien's Chamber. Others have specific reasons.

The intent of Check rules is to verify that an action can happen, so I don’t want to do anything with them but output an appropriate message and stop the action if some condition doesn’t apply. I would avoid having the successful “After a flash of light, you find yourself in…” message there. After all, it hasn’t happened yet, and it’s not impossible you could write some Check Pushing rule in the future that forbade it.

A general principle is that Carry Out rules produce output when the whole point of the command is output, e.g., looking, examining, inventory, and that output should be avoided in Carry Out rules otherwise. Here I was tempted to ignore that principle and put the “After a flash of light” message here… but I also knew I needed to do something to suppress the default “Nothing obvious happens” message, and an After or Report rule was the most obvious thing. And since I was going to have one anyway, it had might as well take care of the output. So in the Carry Out rule, I went to the bother of suppressing the room description that would normally happen when moving the player.

I could have used an After rule instead of a Report rule, and I wouldn’t have needed “stop the action”. But the intent of Report rules is that they’re where the output happens, so I followed that.

In general, I’d suggest putting thought into whether there are easy ways to make your rule preambles more restrictive. A really easy class of error is allowing nonsensical things to happen because your preambles are too broad – for instance, there’s a hidden key that’ll be revealed when the player searches the flower pot, so you start with the key out of play and write: Carry out searching the flower pot: move the key to the flower pot. And when you try it, it works and you move on. But if the player drops the key in the attic and searches the flower pot again… pouf, teleporting key. Carry out searching the flower pot when the key is off-stage would be better (unless you know the key might be destroyed in play and you were accomplishing that by making it off-stage again…)

Since you were also asking generally about locality vs. globality…

Actions, Activities, and Rulebooks can have variables that are local to that action, activity, or rulebook (see Writing in Inform 12.10, 18.6, 19.10). This is as close to namespaces as I7 gets.

There are six constructs allowing code blocks: Rules, To-decide phrases, To-say phrases, Definitions, and things beginning At or When. Variables created with “let” inside of one of those are local to that code block. (And it’s to that whole block even if the “let” is inside a repeat or if.) Variables defined outside of those things are all global (other than action, activity, or rulebook variables.)

In general things are global… so think ahead when naming things that they’re distinctive enough to not be likely to create collisions later.

7 Likes