There was a question about implementing a door at the end of staircase in Inform 7 subforum.
Two approaches were suggested, one more simulational (by HanonO) than the other one (by DeusIrae).
I am not conversant in Inform 7 (barely know it in read-only mode), but I wanted to try my hand in implementing both suggestions in Dialog. The names of the variables and literals are stolen (without shame) from HanonO’s example code in the thread mentioned above.
Here is the idea by HanonO, where the stairs is an object that can (and must) be actually climbed on from the staircase side to interact with the door.
#laboratory
(room *)
(name *) Laboratory
(look *) (descr #staircase)
(from * go #up through #f-door to #forbiddenroom)
#forbiddenroom
(room *)
(name *) Forbidden Room
(from * go #south through #f-door to #laboratory)
(narrate leaving * #south)
You walk south through the forbidding door and climb down the staircase.
#f-door
(door *)
(lockable *)
(name *) forbidding door
(descr *) It's a perfectly ordinary and
{
(* is locked) locked
(or)
(* is closed) closed
(or)
open
}
door.
(refuse $Action) %%Forbidding any interaction with the door
(* is one of $Action) %%if the player is not on the staircase
(current player $Player)
($Player is in room #laboratory)
~($Player is #on #staircase)
You'll need to climb the stairs first to reach that forbidding door.
#staircase
(name *) staircase
(dict *) steps stairs stairway
(actor supporter *)
(descr *) An eerie staircase climbs along the wall and
ends at a forbidding door.
(* is #in #laboratory)
(narrate climbing *)
You climb the rickety stairs one by one...
(narrate leaving *)
You climb down the rickety stairs...
(before [go #up])
(current player $Player)
($Player is #on *)
(just) %%Preventing other before rules, because one of them makes
(#f-door is closed) %%the player leave the stairs (first leaving the staircase)
(first try [open #f-door])
(instead of [go #up])
(current player $Player)
($Player is #on *)
(narrate leaving #laboratory #up)
(enter #forbiddenroom) %%Leaving to upstairs without getting off the staircase
(instead of [put $Obj #on *])
(The $Obj) fall(s $Obj) down the stairs to the ground.
(now) ($Obj is #in #laboratory)
(now) ($Obj is handled)
%%Items dropped on the stairs falls into laboratory
(perform [drop $Obj]) %%Not essential, just a detail
(current player $Player)
($Player is #on *)
(try [put $Obj #on *])
#key
(item *)
(name *) forbidden key
(* is handled)
(* unlocks #f-door)
(* is #in #laboratory)
#player
(current player #player)
(* is #in #laboratory)
Here is the idea by DeusIrae, where the door is a simple one between two rooms, and it looks different depending on where you stand with regards to its faces (and just a couple of action redirects):
#laboratory
(room *)
(name *) Laboratory
(look *) An eerie staircase climbs along the wall and
ends at a forbidding door.
(from * go #up through #f-door to #forbiddenroom)
#forbiddenroom
(room *)
(name *) Forbidden Room
(from * go #south through #f-door to #laboratory)
(narrate leaving * #south)
You walk south through the forbidding door and climb down the staircase.
#f-door
(door *)
(lockable *)
(name *) forbidding door
(descr *) (if) (current room #laboratory) (then) %%We vary the looks of the
(look #laboratory) %%door, depending on location
(endif)
The door is
{
(* is locked) locked
(or)
(* is closed) closed
(or)
open
}
.
#staircase
(name *) staircase
(dict *) steps stairs stairway
(descr *) (descr #f-door)
(* is #in #laboratory)
(instead of [climb *]) %%Redirecting climb staircase action
(try [go #up])
(grammar [go [object]] for [climb *]) %%Just to provide a synonym for climb action
(current room #laboratory) %%as well as the [go #door] action
#key
(item *)
(name *) forbidden key
(* is handled)
(* unlocks #f-door)
(* is #in #laboratory)
#player
(current player #player)
(* is #in #laboratory)
Edit: Mistyping.
Edit:
*(* is one of $Action)
The multi-query was unnecessary, since we already know the object we are looking for. So I changed the line to a simple query:
(* is one of $Action)