Formalising aural and visual adjacency between rooms.

I would consider that an abuse, and would not attempt to support it.

Although that behavior isn’t so weird that I can’t understand it. Cramped Bedroom is inwards from the lamp, so when you’re there, the way through the lamp-door is out. So “enter lamp” translates to “go out.” And you’ve already declared that the room outwards from the lamp is Cave of Wonders.

What surprises me is that it’s possible to manually move a door without generating a compilation error, or at least a runtime error. There are quite a few restrictions on what you can do with doors.

Now that’s entertaining. It’s pretty obvious that Inform doesn’t know what do do with it, though - the rules that end up getting triggered don’t make any sense in context, especially if you attempt to enter the lamp while it’s in the glass chest with you. I’m pretty comfortable calling that an unsupported case.

I just dealt with this issue myself, and I want to clarify something that I didn’t understand before.

The basic accessibility rule is not an accessibility rule. The basic accessibility rule is an action processing rule that runs the accessibility rulebook. An accessibility rule can allow access by ending successfully (although not with the “allow access” result). But the basic accessibility rule can’t. All it does is stop the action if the accessibility rulebook fails. It’s written in I6 and should probably not be interfered with.

I think “basic” was perhaps a poor naming choice for the visibility and accessibility master-rules. Perhaps “determine accessibility” would have been a better name.

I’m beginning to see that. The feedback I7 provides with RULES and ACTIONS turned on seems to be incomplete in some cases - sometimes it just informs you that the basic accessibility rule has failed without mentioning which subsidiary rule or rulebook was involved. This had misled me into thinking that some types of checks were being performed by the basic accessibility rulebook itself. Now that I have a better grasp of how the touchability rules work, I’ve started weeding out references to basic accessibility and replacing them with more specific alternative rules.

Incidentally, I have to thank you writing that Scope Caching extension. It’s allowed me to avoid a couple of potential recursions when checking whether the actor can see a given viewport, and provides a very easy mechanism for determining whether in-scope objects are seen, or merely heard.

I’ve run into something that’s got me stumped. Consider the following:

[code]The Red Room is a room.

The Green Room is a room. It is west of the Red Room.

The Wooden Door is a door. It is west of the Green Room and east of the Blue Room.

The Blue Room is a room.

The player is in the Red Room.

After deciding the scope for the player:
place the Wooden Door in scope;[/code]

In the above example, why does “enter door” work when I’m in the Red Room? Is reachability not checked for doors?

Wow, I think you’re right. You should file this as a bug. Things like “push door” work too. I suppose some special behavior is necessary because a door technically is in only one room, but has to be accessible from either side. (If you look in the index, I think you’ll find that the Wooden Door is in the Blue Room.) But they missed an edge case.

This might be a workaround:

[code]Check an actor going when the door gone through is not nothing (this is the must reach door rule):
if the location is not the front side of the door gone through and the location is not the back side of the door gone through [you probably already have a short phrase for that]:
say “You can’t reach [the door gone through].” instead.

The must reach door rule is listed before the can’t go through closed doors rule in the check going rulebook.[/code]

So far I’ve checked to see that this doesn’t let you open the door if you’re in a transparent closed container. It seems as though the rules catch the case where you try to enter a door from a transparent container that isn’t in a room adjacent to the door, but they miss the edge case of trying to enter an in-scope door from a nonadjacent room when there are no other impediments.

ETA: Note that this will only affect going through the door; if you want to avoid weird responses to “push door” and the like – and worse yet, remote unlocking of the door – you need something else. I’d go for Flexible Action Requirements.

If you try SHOWME DOOR in-game, the result suggests that the door is actually off-stage as long as the player is in the Red Room, and in either the Green or the Blue Room respectively as long as the player is in any of them. So, while in the Red Room you really pull a door out of play into scope.
IIRC Inform implements all objects that seem to be in more than one room (backdrops and two-sided doors) in this way, i.e. by moving them around as needed.

You’re right – I was misreading the way that the index handles doors.

It seems that doors and backdrops are explicitly excluded from the way other off-stage objects are handled by the Access through barriers rule in the I6 Light Template §11 (line 5 of the code for the routine).

That’s interesting. I wonder if there’s a reason for that?

In any case, I’ll have to use some sort of workaround. If the player can see into a room, logically they should be able to examine any doors in that room. matt w’s suggestion seems to work - thanks for that.

Basically, it appears to be a hack. Quote from Appendix B (the annotated Inform 6 templates for Inform 7) under the spoiler tag:

I just realized that my workaround only prevents going through the door, not other actions requiring touchability. So you still would be able to unlock the door from the next room.

The best solution might be to include Flexible Action Requirements and then rewrite my workaround to block any action that isn’t flexible about touching the noun. Or something like that.

Hmm. Possibly just an oversight, then? While we may not know the “real” location of a door (or other floating object) is at any given time, we do always know which two rooms a door is connected to, and it seems simple enough to check whether the actor is actually located in one of those rooms before entering the door. I’m trying to think of a scenario in which this wouldn’t be a safe assumption, and coming up blank.

Or simply block any action other than examining for doors that aren’t connected to the actor’s location, as a quick fix.

That should work if you don’t add any extra actions – all the other actions that apply to “visible things” in the Standard Rules seem to be things we want to block, like “show x to door.” If you define any new actions that apply to visible things (like telling people about things) you might want to use a kind of action.

Hello - I think I just stumbled across something interesting. It seems that two-faced doors don’t float. That is, if you define a pair of doors like this:

[code]The Red Room is a room.

The blue door is a door. It is south of the Red Room. Through the blue door is the Blue Room.

The Blue Room is a room.

The red door is a door. It is north of the Blue Room. Through the red door is the Red Room.[/code]
… then the respective doors aren’t treated as floating objects, and have normal location, reachability and visibility properties regardless of where the player is.

I suspect this is of limited utility in many cases, especially since supplementary code would be required to force their open/closed and locked/unlocked states to remain in sync, but requiring viewports to be defined this way would vastly simplify my code. I could simply check whether a given object is in scope for a viewport’s opposite face, rather than messing about trying to fake it with enclosure rules. As an added bonus, this would allow stuff like one-way glass to be defined with no additional overhead (i.e., by making only half of the door-door pair visually transparent).

As I’m writing this, it occurs to me that there’s probably an existing extension to facilitate handling doors in this fashion.

… yep. Deluxe Doors by Emily Short. Handy, that.

Wow! I’m flattered that people are talking about my extensions, but I’m a little embarrassed that I haven’t really polished any of them.

There’s another one that might come in handy: it’s my update of Conditional Backdrops. The latest version is not up on the inform7 site, but it’s here:

eyeballsun.org/i/Conditional%20Backdrops.i7x

What’s most useful here is not the ability to define your own types of floating objects, but to have better control over when backdrops are moved. You can invoke the “moving floating objects” activity whenever you want and write After rules for the activity to modify how objects are moved or respond to their movement.

I’ll take a look. I’d tried messing with the positioning of floating objects, but I couldn’t get it to work as intended when it came to sensory interaction by proxy; e.g., scenarios where the player in room A asks an NPC in room B to perform an action that requires them to be able to see an item in room C. Setting up non-floating door pairs is a pain for the game designer, but it’s the only way I could get it to work reliably.

On the subject of your extensions, however, I’m having a slight issue with Scope Caching that you may be able to shed some light on. Sorry about the length - I’ve tried to trim out everything that’s not directly relevant.

[code]Include Scope Caching by Mike Ciul.

A thing can be audible only.

A thing can be noisy or quiet. A thing is usually quiet.

A container can be soundproof. A container is usually not soundproof.

Audibility relates a thing (called the listener) to a thing (called the subject) when the listener can hear the subject. The verb to be able to hear (he is heard) implies the audibility relation.

To decide whether (the listener - a thing) can hear (the subject - a thing):
if the listener is the subject:
decide yes;
if the location of the listener is the location of the subject:
if a closed soundproof container that encloses the listener does not enclose the subject:
decide no;
otherwise if a closed soundproof container that encloses the subject does not enclose the listener:
decide no;
otherwise:
decide yes;
otherwise:
decide no;

Definition: Something is audible rather than inaudible if the player can hear it.

The sense-aware can’t reach inside closed containers rule is listed instead of the can’t reach inside closed containers rule in the reaching inside rules.
This is the sense-aware can’t reach inside closed containers rule:
if listening:
if the person reaching can hear the noun:
allow access;
abide by the can’t reach inside closed containers rule;

[This allows the player to listen to things they can only hear.]
After deciding the scope of the player while listening:
now everything is not audible only;
repeat with the noisemaker running through noisy audible things:
if the noisemaker is not marked visible:
now the noisemaker is audible only;
place the noisemaker in scope, but not its contents;

The Green Room is a room. “It’s very green.”

The wooden box is a closed openable opaque container in the Green Room.

The old radio is a noisy thing in the wooden box. Instead of listening to the radio, say “Tinny pop music [if the old radio is audible only]fills the air[otherwise]issues from [the old radio][end if].”

The player is in the Green Room.[/code]
Try listening to the radio twice. As things are set up now, on the second of two consecutive “listen” actions, the marked visible property seems to go wonky for objects that are audible, but not visible. This doesn’t happen if anything - even a “wait” action - comes between the listens. Can you see what I’m doing wrong?

I don’t have an answer right away, but it can help to visualize how Scope Caching works: After reading a command it does the caching scope activity with the player. Normally, scope depends on a number of things: whose scope is being checked, what is the reason for checking scope, and what action is being performed. If you cache scope in one circumstance, the “marked visible” property may not be appropriate in another circumstance. You can usually fix that by manually running the caching scope activity at the proper time.

Okay - here’s where I’m at now (see attached). I’ve made a great deal of progress, but there are still a few things giving me trouble:

1. I’m trying to set up a “sensory occlusion” relation (i.e., “x is visually occluded from y”/“x is aurally occluded from y”) to make it possible to define an object as being impossible to see from a particular vantage point. However, I’ve defined both sensory adjacency between rooms and sensory connections via doors or other sensory connectors, I can’t figure out a way to define the relevant phrases to cover both relationships.

For example, if room X is visually adjacent to room Y, and I want to say that something in room X is visually occluded from a viewer in room Y, the relation needs to be between a thing and a room. However, if room X is visually connected to room Y via door Z, the relationship would need to be between a thing and a thing instead, since the scope is being checked from the viewpoint of the door, not the viewpoint of the room.

I know I could just use two separate relations, but requiring the author to use different phrases depending on the type of sensory connection involved seems inelegant.

2. I’m trying to set up some grammar so that before/instead/after/while examining rules can be defined in terms of the vantage point of the player, the medium of viewing, or both.

For example, I want to be able to say stuff like “instead of examining X via a security camera”, or “rule for printing the name of X while examining via a door”. There’s an example of doing so in the attached file.

I’ve tried it in two different ways: using definitions, and using a series of internal verbs that pass the subject around among themselves (the latter is what you see in the attached example). The problem is that each approach only covers some of the cases involved. If I use definitions, the while rules work, but before/instead/after rules become complicated and unwieldy to write. If I used the action-passing approach you see in the attached file, the while rules don’t work, since by the while “while” is checked, the action has been passed off to the basic “examine” verb.

I’m open to any suggestions - redirecting actions and such is new territory for me, and I’m quite certain I’m Doing It Wrong.

3. Is there a decent guide available that explains the logic behind how the system determines how to display the contents of a room? I’m trying to puzzle out the best way to display a room’s contents when viewing it remotely, but I can’t seem to make heads or tails of the standard rules in this area.

Finally, if anyone has the time to play with the little sample scenario I’ve included and see if they can get it to break, it would be greatly appreciated. Just let me know what you did to bust it. :slight_smile:
sensory-2.txt (34.9 KB)

Just a note: it’s easier to look at your code if you inline it with code tags, rather than attaching it as a file. If it’s really long you can add spoiler tags outside the code tags.