Problems using "Now [the door] is locked" during a custom scene

Hello, while trying to familiarize myself with how scenes work I noticed that locking a door during a scene I created was not behaving as expected, such as when a door is locked when play begins. Here is a scenario that illustrates my problem:

"Locked in the closet"

Laboratory is a room.

Closet is a room.

In the laboratory is a door called oak door. It is north of laboratory and south of closet.

Lock the door is a scene.

Lock the door begins when the player is in the closet for the first time.

When Lock the door begins:
    now the oak door is locked.

Instead of examining a door:
    say "The door is [if locked]locked[otherwise]unlocked[end if]."

[When play begins:
    now the oak door is locked.]

test me with "n / x door/ s / x door"

Perhaps I am missing something vital but it appears to me that during my created scene even though the door is recognized as locked by inform and prints that it is is locked when checking it’s state, it still allows for the player to enter the door. However using the same line of code “Now the oak door is locked” does seem to work within a when play begins rule. This was especially confusing to me when reading through the inform 7 documentation to see that When play begins is also a scene.

If anyone has any insight into why this might be behaving this way and any way around it, that would be greatly appreciated.

Locked vs Unlocked and Open vs Closed can be set completely independently from each other. When the player’s trying to do things, there are Check rules in the Standard Rules enforcing things like that you can’t lock something that’s open. But there’s nothing stopping the author from writing rules that set any combination of locked/unlocked and open/closed.

So your door is being locked; it’s just that it’s still open.

3 Likes

Thank you so much, the open/closed state didn’t even cross my mind.

1 Like

Glad to help. The SHOWME debugging command is helpful in a case like this when things are strange: it’ll show you what properties are set for a thing and, so, would have told you the door was locked and open.

1 Like

By the way, I’ve never seen this syntax:

I only know this:

Is the first part adding anything? Is the door actually in the room?

You don’t have to say anything like “Door X is in Room Y”… you can just define it in terms of directions. But, yes, any given door is always in a room. An example:

Doors are always enclosed by the rooms on both sides of it, initially contained (and thus held) by the room they’re first defined relative to, and subsequently contained/held by whatever room the player was most recently in that encloses the door.

But in writing this sample, I found one thing that surprised me. If you uncomment the line about Oak door is in the lab. then initially:

The location of the oak door is Conservatory.
Oak Door is in Lab.
Lab holds the oak door.
Lab encloses the oak door.
--
Conservatory encloses the oak door.

The oak door’s location is different from what contains it!

1 Like

Okay, now you have to tell me how you embed the inform interpreter in the forum… :heart_eyes: :sunglasses:

snippets.borogove.app. Compile something, select “Share”, then copy the “Forum code/embedded” iframe tag it presents and paste it here.

6 Likes

If this seems confusing, it’s because it is… It’s (probably the sole) exception to the rule that to enclose something, an object must also either directly or indirectly hold it.

This is due to the specific hard-coding for the location of a door in the I6 routine [LocationOf], which defines the location of an object:

[ LocationOf o;
	if (~~(o ofclass K1_room or K2_thing)) return nothing;
	if (o ofclass K4_door) {
		if (parent(o) == real_location) return real_location;
		return FrontSideOfDoor(o);
	}
	if (o ofclass K7_backdrop) {
		! print "(deciding ", (the) O, " is at ", (the) BackdropLocation(o), ") ";
		return BackdropLocation(o);
	}
	while (o) {
		if (o ofclass K1_room) return o;
		o = CoreOfParentOfCoreOf(o);
	}
	return nothing;
];

This (somewhat unexpectedly) will always return the location of a two-sided door as the front side of the door (being the room in which the door is first defined in source to be found, or more technically, the first element of the I6 found_in array property of the door) unless the door happens to currently be in the same room as the player, in which case that room is returned

1 Like

I just discovered that the details are even a little weirder than this. If a door is between rooms X and Y, then which of X or Y contains it and is the location of it is set by conventionally going to either of X or Y from another room via a direction, per se. Those values persist until the player conventionally goes to the other one: it’s not about where the player currently is or which room the player was most recently in. If the player is teleporting between rooms, these things don’t get updated. (And going between X and Y themselves isn’t special: it’s going to either of them from any room.)

Interesting! Can you provide code demonstrating this? The I6 function shown above would seem to contradict what you’re saying here, and this transcript seems to behave in the way I described (in Inform 10.1.2 at least):

"Teleporting" by PB

Study is a room.  "Panelled with cracked oak, dark with age and decades of soot deposited by reed lamps long past. [A dilapidated door] leads east and a narrow passage southeast.".
Library is a room. "A clutter of dusty shelves and fragmenting ancient tomes. [A dilapidated door] leads west and a low, crooked opening to the southwest.".
The dilapidated door is a door. It is east of Study and west of Library.
The Kitchen is southeast of the Study and southwest of the Library. "Cracked old tables and a broken sink are all that remain.  Crooked low-ceilinged passages lead northeast and northwest.".  

every turn:
	say "The dilapidated door is contained by [if Study contains the dilapidated door]the Study[else if Library contains the dilapidated door]the Library[else]Nowhere[end if].";
	say "The location of the dilapidated door is [if the location of the dilapidated door is the Study]the Study[else if the location of the dilapidated door is the Library]the Library[else]Nowhere[end if].";
	
Teleporting is an action applying to one visible thing.
Understand "Teleport to/-- [any room]" as teleporting.

Check teleporting:
	If the noun is the location, say "You're already there!" instead.
	
Carry out teleporting:
	say "In a swirl of kaleidoscopic colours, you are transported elsewhere...[paragraph break]";
	Now the player is in the noun.
	
Test me with "e/sw/ne/superbrief/w/teleport to Kitchen/teleport to Library/teleport to Kitchen/teleport to Study".
Teleporting
An Interactive Fiction by PB
Release 1 / Serial number 220914 / Inform 7 v10.1.2 / D

Study
Panelled with cracked oak, dark with age and decades of soot deposited by reed lamps long past. A dilapidated door leads east and a narrow passage southeast.

>test me
(Testing.)

>[1] e
(first opening the dilapidated door)

Library
A clutter of dusty shelves and fragmenting ancient tomes. A dilapidated door leads west and a low, crooked opening to the southwest.

The dilapidated door is contained by the Library.
The location of the dilapidated door is the Library.

>[2] sw

Kitchen
Cracked old tables and a broken sink are all that remain.  Crooked low-ceilinged passages lead northeast and northwest.

The dilapidated door is contained by the Library.
The location of the dilapidated door is the Study.

>[3] ne

Library
A clutter of dusty shelves and fragmenting ancient tomes. A dilapidated door leads west and a low, crooked opening to the southwest.

The dilapidated door is contained by the Library.
The location of the dilapidated door is the Library.

>[4] superbrief
Teleporting is now in its "superbrief" mode, which always gives short descriptions of locations (even if you haven't been there before).

>[5] w

Study
You can see a dilapidated door here.

The dilapidated door is contained by the Study.
The location of the dilapidated door is the Study.

>[6] teleport to kitchen
In a swirl of kaleidoscopic colours, you are transported elsewhere...

Kitchen
The dilapidated door is contained by the Study.
The location of the dilapidated door is the Study.

>[7] teleport to library
In a swirl of kaleidoscopic colours, you are transported elsewhere...

Library
You can see a dilapidated door here.

The dilapidated door is contained by the Library.
The location of the dilapidated door is the Library.

>[8] teleport to kitchen
In a swirl of kaleidoscopic colours, you are transported elsewhere...

Kitchen
The dilapidated door is contained by the Library.
The location of the dilapidated door is the Study.

>[9] teleport to study
In a swirl of kaleidoscopic colours, you are transported elsewhere...

Study
You can see a dilapidated door here.

The dilapidated door is contained by the Study.
The location of the dilapidated door is the Study.

oops, my bad. I did my experimentation with abstract self to [room] and it turns out the behavior I was seeing was a function of moving via abstract and not the same as you get with an implementation of teleporting with move the player to or now the player is in. Thanks for setting me straight on this!

On teleporting, for debugging I use this device for quick traversal:

[from WI, 8.7; also a convenient shortcut during testing.]
the teleport circle is fixed in place in the outside cottage. The description of the teleport circle is "a bit-sized version of the Gate, this teleport ring on the floor leads to the winding path between the enchanted grove and the mystical grove.".
instead of entering the teleport circle: move the player to winding path.

of course, in the winding path another enterable allows return to the outside cottage, whose is the starting room.

(the code is from my main inform 7, now inform 10 messing arena, active at least since inform 7/6L02; the comments point also to the relevant pages of the WI, RB and Writing with Inform because I use it as reference)

Best regards from Italy,
dott. Piergiorgio.

Ah.

The reason that behaves differently is because abstracting the player doesn’t update real_location to the new location of the player.