Thursday, August 4, 2016

Another Rulebook Post (Inform 7)

I wrote last week about getting over the fear of rulebooks in Inform 7, specifically by not using the all-powerful INSTEAD to accomplish everything.  After I read over the post, I remembered one of my specific hangups using rulebooks occurred because I was over-thinking the process: how does Inform know how my additional rules work in order?  How does Inform know what order the rules should go in? Don't I need to write them very specifically so Inform and the compiler don't get confused?

The short answer is not really.  Beyond a few minor sequencing points when polishing the text output, Inform does not care where in the source text we write our rules. And the rulebooks consider every rule in them unless a rule explicitly tells it to stop (with an INSTEAD or "stop the action.")

Imagine creating a shopping list. Unless we're extremely familiar with the grocery store layout, we'll write a list as items occur to us, possibly over a period of time or several days. We might make a little effort grouping frozen foods and produce together since we know they are in the same general area within the building, but as we shop, we're going to run down the list in each location. And theoretically without any specific handling issues, the items in our cart will stack so that the last thing we inserted into it will be the first thing checked out by the cashier, unless we decide to bump something onto the conveyor belt first, perhaps because it's heavy or frozen.

Remember that the source text is only feeding information to the compiler which arranges it for its own use. Any BEFORE rule you write goes into the Before rulebook, and all "before" rules will run before any CHECK rules.  In many cases it doesn't matter what order the rules run in; if the player cannot pick up a boulder for one reason, it doesn't matter whether they also can't pick it up for another reason.

In general, we are encouraged to avoid player messages until the REPORT stage after everything is happened. Sometimes it's nice though to give the player some feedback along the way, such as if the author/parser has taken a shortcut action for them, or to explain why an action failed.

Gauntlets of Hercules is carried by the player. It is wearable. A golden fleece is carried by the player.

some river sticks is a thing. 

Rocky Valley is a room. 

A giant boulder is in Rocky Valley. "A giant boulder here blocks the way north.". The description is "The boulder is taller than you, and more than likely not movable by mortal means." 

Check taking giant boulder (this is the really it's more awkward than heavy rule):
  if the player does not wear the gauntlets of Hercules:
    say "Shyeah, right. You're just going to pick that     boulder up and carry it with you. Har!" instead.

Before taking giant boulder:
  if the player wears gauntlets of Hercules:
    if giant boulder is not handled:
      say "You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers." 

Before taking giant boulder (this is the can't carry anything and the boulder rule):
  if the player carries something:
    say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
    now everything carried by the player is in the location. 
Carry out taking giant boulder:  if river sticks is off-stage:    now river sticks is in the location;    say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."
Carry out taking giant boulder (this is the hard work requires loud noises rule):
  if giant boulder is not handled:
    say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 


Report taking giant boulder:
  say "You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy." 

Check taking something when the player carries giant boulder:
  say "If you reach for [the noun], you'll need to put down the boulder first." instead.
I defined these rules completely out of order as far as the actual logical sequence this would all occur in, but let's try it:

Rocky Valley
A giant boulder here blocks the way north.

>take boulder
(first dropping everything else you're holding: Gauntlets of Hercules, a golden fleece.)

Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

Hmn.  That technically worked, but it didn't make a lot of sense to make the player drop everything when they aren't even going to be able to actually lift the giant boulder. Let's specify the rule order a bit. I want the snarky message to be the only thing the player sees if they aren't wearing the gauntlets. That rule already ends with INSTEAD so let's tell Inform to put it "first" in the Check Taking* rulebook. 

First check taking giant boulder (this is the really it's more awkward than heavy rule):
if the player does not wear the gauntlets of Hercules:
say "Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!" instead.

That way, any other rules I think of and write later, even in the future, won't even be considered until the player is wearing the gauntlets.

I also need to change my "can't carry stuff and the boulder" rule since it's a BEFORE rule that will always occur before a CHECK rule.  It actually makes more sense as CARRY OUT since there's no reason for the player to drop everything until they are actually going to lift the boulder. I will also tell Inform to put that "first" in the CARRY OUT rulebook since I don't want the player to make their mighty grunt and then decide they have to drop everything they have in their hands:

First carry out taking giant boulder (this is the can't carry anything and the boulder rule):
  if the player carries something:
  say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
    now everything carried by the player is in the location.


Rocky Valley
A giant boulder here blocks the way north.

>take boulder
Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

There, that's much better. Continuing...

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

(first dropping everything else you're holding: a golden fleece.)

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Taken.

>take fleece
If you reach for the golden fleece, you'll need to put down the boulder first.

>drop boulder
Dropped.

>take fleece

Taken.

Once again, that worked, but we'd like the text of the player grunting to happen before they lift the boulder and reveal the very important river sticks they will need later.  Once again, we tell Inform what rule should come first:

First carry out taking giant boulder (this is the hard work requires loud noises rule):
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

(first dropping everything else you're holding: a golden fleece.)

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Still not quite right.  The grunt happened, but then the player doesn't drop everything until after that, which is still the wrong order.  Let's check the source text:

First carry out taking giant boulder (this is the can't carry anything and the boulder rule):
if the player carries something:
say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
now everything carried by the player is in the location.
Carry out taking giant boulder:  
if river sticks is off-stage:    
now river sticks is in the location;    
say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."
First carry out taking giant boulder (this is the hard work requires loud noises rule):
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 

So we've defined two "first" rules. What's happened here is reliant on source text order.  We told Inform to put the "can't carry anything and the giant boulder" rule first, which it did.  Then we told it to put the "hard work requires loud noises" rule first also.  Since our previous rule is already the first rule in the rulebook, it is bumped forward a step to make room and let the other be first.

One solution is to switch the order of the rules in the source text.  However, if we write any other rules affecting the boulder later they might get out of order again. The other way is just to combine them into the same rule so they run in correct order as a unit:

First carry out taking giant boulder (this is the drop everything before heaving the boulder rule):
if the player carries something:
say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
now everything carried by the player is in the location;
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it."

For good measure, we can make sure our message about river sticks runs "last".

Last carry out taking giant boulder:  
if river sticks is off-stage:    
now river sticks is in the location;    
say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."

>take boulder
Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

(first dropping everything else you're holding: a golden fleece.)

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Taken.

Almost there.  We want to get rid of that "Taken" message which is the standard report taking response.  We can do that by changing our report taking giant boulder rule to an "after" taking giant boulder rule.  AFTER rules occur before report rules, and will naturally stop and override them (unless appended with "continue the action).

After taking giant boulder:
say "You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy." 

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

>

As things get more complicated, it is actually possible to create a specific rulebook for a complicated action--say a magic box that transforms items into other items.  For this type of information, it's best to read the entire section about rulebooks in the Inform documentation.  There are also many more useful rulebooks beyond what I've only scratched the surface of here.


---

No comments:

Post a Comment