§19.11. Success and failure
Though we have blurred over this point so far, each rule must ordinarily end with one of three outcomes: success, failure and neither ("no outcome").
When a rulebook is followed, what happens is that each of its rules is followed in turn until one of them ends in success or failure - if ever: it is possible that each rule is tried and each ends with no outcome, so that the rulebook simply runs out of rules to try.
For some rulebooks, these are not useful ideas: "every turn" rules, for instance, never produce an outcome, which is why the "every turn" rulebook always runs through all its rules at the end of each turn. But for other rulebooks, such as "check taking", it's important that a rule which fails will stop the whole rulebook. For instance, we might find that the "can't take yourself rule" produces no outcome (because we aren't trying to do that), and then likewise the "can't take other people rule" (ditto) but that the "can't take component parts rule" prints up a complaint, and fails the action: the rulebook stops, and never goes on to (for instance) the "can't take scenery rule". This is good, because an impossible action often fails for several reasons at once, and we only want to print up one objection, not a whole list.
To follow the working of this mechanism, we need to be able to predict the outcome of any given rule. Sometimes this is easy to spot. For instance, in a rule which works on actions:
continue the action; means "end this rule with no outcome"
stop the action; means "end this rule in failure"
... instead; means "end this rule in failure"
("Success" and "failure" are technical terms here: they do not mean that the player has or hasn't got what he wanted.) This is why the rule:
Before taking something: say "The sentry won't let you!" instead.
ends in failure, and therefore stops the "before" rulebook. Another easy-to-spot case is when a rule makes use of the explicit phrases:
rule succeeds
This causes the current rule to end immediately, with its outcome considered to be a success. That means the rulebook being worked through will also end, and also be a success.
rule fails
This causes the current rule to end immediately, with its outcome considered to be a failure. That means the rulebook being worked through will also end, and also be a failure.
make no decision
This causes the current rule to end immediately, but with no outcome. That means the rulebook being worked through will continue to run on, beginning with the next rule.
But what happens if a rule simply doesn't say whether it succeeds, fails or has no outcome? In that case it depends on the rulebook. For almost all rulebooks, a rule which doesn't make a choice has no outcome, as in the following example:
Before taking something: say "The sentry looks at you anxiously!"
This rule, if it takes effect, ends with no outcome - so the action continues. But other rulebooks have a different convention: the most important is "instead", where a rule making no explicit choice is deemed to end in failure. For instance:
Instead of taking something: say "The sentry prods you with his rifle!"
This rule, if it takes effect, ends in failure and therefore stops the action.
We call this the default outcome of a rulebook. The default outcome of "before" (and of almost all rulebooks, in fact) is no outcome; the default outcome of "instead" is failure; the default outcome of "after" is success. The few exceptional cases with default outcome success or failure are marked as such in the Rules index.
When we create a rulebook, it will default to "no outcome". But we can specify otherwise with sentences like so:
The cosmic analysis rules are a rulebook. The cosmic analysis rules have default failure.
Finally, note that the default outcome for a rulebook is really the default outcome for any rule in that rulebook: if no rules in the rulebook ever apply, for instance if there aren't any and the rulebook is empty, then the rulebook ends with no outcome at all.
We can test the latest outcome like so:
if rule succeeded:
This condition is true if the most recently followed rule ended in success. Example:
follow the hypothetical clever rule;
if rule succeeded:
...
if rule failed:
This condition is true if the most recently followed rule ended in failure. Example:
follow the hypothetical clever rule;
if rule failed:
...
Note that this is not the opposite of "rule succeeded", because there's a third possibility: that it ended with no outcome.
|
Suppose we want to expand the function of the existing THROW SOMETHING AT command so that a thrown object actually does make contact most of the time. A glance at the Actions index tells us that the Throwing it at rulebook currently looks like this:
Some of those still look useful. We want to leave the "implicitly remove thrown clothing" rule, for instance -- no fair having the player throw a hat that's on his head. On the other hand, the "futile to throw things at inanimate objects rule" is going to have to go, because that would prevent us from ever being able to complete the throwing command. So let's get rid of that:
That "block throwing at" rule also looks sinister: any "block..." rule in the standard actions library is there to print a message telling the player he can't do what he's asked to do. But it's not enough to ignore it, the way we did the "futile" rule. Since we are only expanding the command to affect inanimate objects, let's replace the "block throwing at" rule with a different one which will only prevent the player throwing things at people:
Now we've changed the command so that some action can sometimes be carried out here -- but we don't have any rules for what happens. It's time to create some rules for our model world.
If we're actually going to allow throwing, we might want to add a couple of extra checks to the rulebook to make sure that this happens when it ought:
And then the rules for the action itself:
That "rule succeeds" ends the action here, if the noun is flat. If not, Inform goes on to the next rule in the carry out throwing it at rulebook:
These rules are assuming some backup information, so let's provide that as well:
Now suppose we'd like to add some further cases for what happens if the player breaks a fragile door this way:
This works, except that objects will continue to "strike" open, unopenable doors, with the result that the player can smash the same door over and over. What we need is another rule, after the aerodynamics rule and before the contact rule, that tells Inform how to handle throwing things at open doors.
If the original rulebook is one we wrote ourselves, we could just add that rule in the proper spot in order. If we got it from an extension, though, we might need to put it in the right place explicitly:
The magic of rulebooks is that they allow authors to amend each other's work (or the Standard Rules) with a fair amount of freedom. A well-written extension will give individual names to its rules, to allow subsequent authors to modify the function of the extension without too much trouble. Now for an actual scenario with which to test this:
|
|
Suppose we want to expand the function of the existing THROW SOMETHING AT command so that a thrown object actually does make contact most of the time. A glance at the Actions index tells us that the Throwing it at rulebook currently looks like this:
Some of those still look useful. We want to leave the "implicitly remove thrown clothing" rule, for instance -- no fair having the player throw a hat that's on his head. On the other hand, the "futile to throw things at inanimate objects rule" is going to have to go, because that would prevent us from ever being able to complete the throwing command. So let's get rid of that:
That "block throwing at" rule also looks sinister: any "block..." rule in the standard actions library is there to print a message telling the player he can't do what he's asked to do. But it's not enough to ignore it, the way we did the "futile" rule. Since we are only expanding the command to affect inanimate objects, let's replace the "block throwing at" rule with a different one which will only prevent the player throwing things at people:
Now we've changed the command so that some action can sometimes be carried out here -- but we don't have any rules for what happens. It's time to create some rules for our model world.
If we're actually going to allow throwing, we might want to add a couple of extra checks to the rulebook to make sure that this happens when it ought:
And then the rules for the action itself:
That "rule succeeds" ends the action here, if the noun is flat. If not, Inform goes on to the next rule in the carry out throwing it at rulebook:
These rules are assuming some backup information, so let's provide that as well:
Now suppose we'd like to add some further cases for what happens if the player breaks a fragile door this way:
This works, except that objects will continue to "strike" open, unopenable doors, with the result that the player can smash the same door over and over. What we need is another rule, after the aerodynamics rule and before the contact rule, that tells Inform how to handle throwing things at open doors.
If the original rulebook is one we wrote ourselves, we could just add that rule in the proper spot in order. If we got it from an extension, though, we might need to put it in the right place explicitly:
The magic of rulebooks is that they allow authors to amend each other's work (or the Standard Rules) with a fair amount of freedom. A well-written extension will give individual names to its rules, to allow subsequent authors to modify the function of the extension without too much trouble. Now for an actual scenario with which to test this:
Suppose we want to expand the function of the existing THROW SOMETHING AT command so that a thrown object actually does make contact most of the time. A glance at the Actions index tells us that the Throwing it at rulebook currently looks like this:
Some of those still look useful. We want to leave the "implicitly remove thrown clothing" rule, for instance -- no fair having the player throw a hat that's on his head. On the other hand, the "futile to throw things at inanimate objects rule" is going to have to go, because that would prevent us from ever being able to complete the throwing command. So let's get rid of that:
That "block throwing at" rule also looks sinister: any "block..." rule in the standard actions library is there to print a message telling the player he can't do what he's asked to do. But it's not enough to ignore it, the way we did the "futile" rule. Since we are only expanding the command to affect inanimate objects, let's replace the "block throwing at" rule with a different one which will only prevent the player throwing things at people:
Now we've changed the command so that some action can sometimes be carried out here -- but we don't have any rules for what happens. It's time to create some rules for our model world.
If we're actually going to allow throwing, we might want to add a couple of extra checks to the rulebook to make sure that this happens when it ought:
And then the rules for the action itself:
That "rule succeeds" ends the action here, if the noun is flat. If not, Inform goes on to the next rule in the carry out throwing it at rulebook:
These rules are assuming some backup information, so let's provide that as well:
Now suppose we'd like to add some further cases for what happens if the player breaks a fragile door this way:
This works, except that objects will continue to "strike" open, unopenable doors, with the result that the player can smash the same door over and over. What we need is another rule, after the aerodynamics rule and before the contact rule, that tells Inform how to handle throwing things at open doors.
If the original rulebook is one we wrote ourselves, we could just add that rule in the proper spot in order. If we got it from an extension, though, we might need to put it in the right place explicitly:
The magic of rulebooks is that they allow authors to amend each other's work (or the Standard Rules) with a fair amount of freedom. A well-written extension will give individual names to its rules, to allow subsequent authors to modify the function of the extension without too much trouble. Now for an actual scenario with which to test this:
|