I can’t find anything in the Dialog standard library that prevents the player from entering or leaving a closed actor container. There’s an attempt made to open it, but if that fails, there’s no prevent-rule to stop it.
But also, I’ve thoroughly hacked up this library, so there might be a mechanism for this that I’ve broken.
Is there anything in the library that prevents you from entering or leaving a closed, locked actor container?
Here are the combinations and behaviours: (actor container *), player can enter and leave at will. (actor container *) (* is closed) player can’t open it, hence fails to enter or leave it. (actor container *) (* is closed) (openable *), player can open it, can enter and leave. (actor container *) (* is closed) (openable *) (* is locked), player can’t open it, hence fails to enter or leave it. (actor container *) (* is closed) (openable *) (* is locked) (lockable *), if player can unlock it, then succeeds in entering or leaving, otherwise can’t.
Failure happens at opening or unlocking actions, which stops the action sequence for entering and leaving. Other than that there are no prevention rules for actor containers with regards to their open/closed nature.
Edit: Ahem convert (closed *) to (* is closed) and (locked *) to (* is locked) above.
Aha, that’s what I’m missing. But how does it cut off the action without a prevent rule? All I can find is the before rule that tries opening the container first, but my understanding is that try always succeeds, no matter what.
Aha! Okay, I see now. Using (stop) when an action fails doesn’t just end a sequence of commands; if an implicit action fails that way, it causes the action that called it to be aborted too. That’s an elegant way to do it.
Correct, although the comment in the library also says that “Try always succeeds”, a more correct phrase would be “Try never fails”; it might succeed or it might not return.
Yeah, Inform’s “stop the action” just ends the current rulebook, while “continue the action” ends the current rule while letting the rulebook continue. Dialog-wise it’s more akin to having a rule succeed or fail, respectively (with a normal query rather than a multi-query or exhaust). The machinery of “try” then watches the outcome of each rulebook, and if a rulebook before carry out returns a result instead of falling through to the end, it stops the whole thing.
I see, that’s quite different than (stop). Those are just a slimmed down versions of C++ exceptions in Dialog, where (stoppable) is try-catch block in one, and (stop) is the throw.
It’s a structured goto mechanism really, and that’s why (stoppable) should be used sparingly in Dialog imho. Library already uses it to break free of action processing and jump to the user prompt, any additional (stoppable) blocks would make following the path of execution burdensome.
Indeed, and it’s a lot more elegant conceptually than how Inform and ZIL do it—they check a global every time an action is about to be processed, and if it’s set, they skip that action. It’s unset again when the prompt is printed.
In ZIL this is used to end a series of actions (N. E. N. N. W.) if something shocking happens, but since it’s only checked at the start of action-processing, it’s no use for handling this implicit action problem. In Inform it’s only used, by default, for things on the level of the player dying.