Lab is a room. Garden is north of Lab.
A shirt is a kind of wearable thing.
The player carries the red shirt. The red shirt is a shirt.
The player wears the blue shirt. The blue shirt is a shirt.
Check going north from the lab when the player wears the blue shirt:
say "The blue shirt seems to be okay.";
Check going somewhere when the player wears a shirt:
say "You can't go there wearing a shirt." instead;
This doesnât work because the second check rule will always fire. AFAIK thereâs no way for a successful check rule to short-circuit the rulebook and cause the other check rules not to run.
One way to get around this problem is to exclude special cases from the second check rule. But say I want my shirt code to be in an extension, so it needs to be general.
How can I produce the behavior of âskipping past the check rulesâ in this case? How can I make it so the player can pass between rooms while wearing the blue shirt, but not while wearing the red shirt?
The quickest way to deal with this one is to put the rules together. In other words, have one rule that deals with all the shirt-checking:
Check going somewhere when the player wears a shirt:
if going north in the lab and player wears the blue shirt:
say "The blue shirt seems to be okay.";
otherwise:
instead say "You can't go there wearing a shirt.";
Note that âinsteadâ at the head of the âYou canât go thereâŚâ line. That stops the whole action process dead as it prints the message. The prior check, saying âThe blue shirt seems to be okayâ, has no instead and so lets the action continue its flow through the rulebooks.
If you need to add other exceptions later, you can keep poking them into this rule. e.g.
Check going somewhere when the player wears a shirt:
if going north in the lab and player wears the blue shirt:
say "The blue shirt seems to be okay.";
otherwise if going west in the beer garden and player wears red shirt:
say "The red shirt will be fine for the beer garden.";
otherwise:
instead say "You can't go that way wearing a shirt.";
If you keep adding exceptions and the rule becomes too cumbersome for your taste, there are other mechanisms you can replace it with. Like setting up an object based rulebook for shirts; see the example that starts with the line âThe flotation rules are an object based rulebookâ in 19.9 of the docs. You could say âThe dress code rules are an object based rulebookâ, then create rules for each special shirt and the room it lets you into. But to begin with, what Iâve suggested will be fine.
Ah, this is what I want. The problem with the initial approach is that I want the general shirt handling code to be in an extension, and the exceptions to be in the actual story using the extension. The rulebook approach offers the extensibility I need.
@Zed would doubtless say that you should create a various to various relation property here, relating shirts to roomsâŚ
Lab is a room. Garden is north. Potting Shed is east.
A shirt is a kind of wearable thing.
The player wears a shirt called the red shirt.
The player carries a shirt called the blue shirt.
A room has a relation of a shirt to a room called dress-restriction.
When play begins:
now the dress-restriction of the Lab relates the red shirt to the Garden.
Definition: a room (called the target) is inaccessible:
repeat with shrt running through worn shirts:
if the dress-restriction of the location relates shrt to the target, yes.
Check going to an inaccessible room:
say "[We] [can't] go there dressed like that." instead.
To seem is a verb.
First report going when the player wears a shirt:
[only say something if there is at least one shirt restricting this movement]
if a shirt relates to the room gone to by the dress-restriction of the room gone from:
say "[The list of shirts worn by the player] [seem] to be okay.".
Test me with "n/remove red. wear blue/n/e".
Ah yes. I did note you making this point in the first post, but I realise that what often happens when Iâm giving a long answer is, I start writing a bit of an essay, realise itâs going the wrong way, erase it, start again. And by the time Iâve done all that Iâve lost track of details from the original query
Check going when the player encloses something pluggable (called
the plug) and something (called the socket) accepts the plug and
the player does not enclose the socket:
The rules engine does not loop over all pluggable things enclosed by the player. It chooses one, and if that one doesnât satisfy the rest of the conditions, well, too bad for you.
I am sometimes capable of considering something to be overkill.
Iâm guessing your intent is to check for the player trying to take a plugged-in thing out of the room without also enclosing the thing itâs plugged into. So maybe something likeâŚ
Lab is a room.
Parlor is north of lab.
The socket is a thing in the lab.
The player holds the plug.
Plugging relates one thing to one thing.
The verb to be plugged into means the plugging relation.
Definition: a thing is plugged in if it is plugged into something.
Definition: a thing is tethered:
if the player does not enclose it, no;
if it is not plugged in, no;
let socket be the thing to which it relates by the plugging relation;
if the player does not enclose the socket, yes;
no;
Check going when the player encloses a tethered thing:
instead say "nyet".
instead of jumping: now the plug is plugged into the socket.
test me with "n / s / jump / n"
doh. Right. Works for carry out and report, but not the others (and, of course, ending the action and ending the report rules arenât terribly distinct from each other).
For those interested in the minutiae of why, see this post:
tldr: the rules calling the Carry out and Report rulebooks follow those rulebooks, whereas the others abide by the rulebooks they call (and therefore there can be no simple way to prevent a rule that explicitly terminates Before, Instead, Check, or After from terminating the calling rulebook and thereby the whole action)*.
* except by modifying and replacing the Before stage rule, Instead stage rule etc. so that they too follow rather than abide by the relevant rulebook, which opens a whole new can of worms
The Check rulebook is a bunch of possible reasons an action might fail (or at least stop-with-a-message). Itâs supposed to be additive â that is, adding a new Check rule shouldnât require you to think about all the others. Except for deciding what order theyâre checked in.
It would be weird if there were a âskip the rest of the checksâ feature. Youâd wind up in a situation where you added a completely separate check (say, âCheck going when the player is chained to the wallâ) but it got skipped because you were wearing the right color shirt.
Creating a new rulebook is the right solution here.
(This kind of thing is a known problem with Informâs âevery turnâ rulebook, which is also supposed to be additive, but you can skip some every-turn rules if you write ârule succeedsâ in one of them. This inevitably leads to bugs.)
It looks like youâre going with an object based rulebook, which sounds right for your needs. For completeness, I would add that you can always add special exceptions in your game code to ignore a particular rule from an extension in certain cases.
Lab is a room. Garden is north of Lab.
A shirt is a kind of wearable thing.
The player carries the red shirt. The red shirt is a shirt.
The player wears the blue shirt. The blue shirt is a shirt.
Check going north from the lab when the player wears the blue shirt (this is the blue shiprt exception rule):
say "The blue shirt seems to be okay.".
Check going somewhere when the player wears a shirt (this is the Shirt Extension must not wear shirts rule):
say "You can't go there wearing that shirt." instead.
The Shirt Extension must not wear shirts rule does nothing if the player wears the blue shirt and the player is in the lab.
test me with "n / s / take off shirt / s / wear red / n".
Yeah, I didnât mention it- but I moved the code to report on successful movement-with-a-shirt to the Report stage, where it more naturally would sit. As a general rule, text printed in Check rules reports on actions that failed a check and were therefore halted at the Check stage. (A rule, like all coding rules, made to be broken if circumstances demand.)