Fiddly backdrop...

In my game, I have a backdrop–a set of bookcases–that occupies adjacent rooms. It’s an obstacle, and I have it occupy two rooms because once you get on the other side of it, it can be easily moved (after which it actually goes ‘nowhere’). However, ideally, the player would be able to see the backdrop from a couple of other rooms, via a textual condition ‘[if the bookcases are in Stairs]’ (Stairs is one of the rooms the backdrop occupies) When they are not there, they are not mentioned in those room descriptions, etc. However, on testing, the bookcases don’t seem to appear in those descriptions (though they are where they are supposed to be when I go to where they are), and even funnier, they suddenly appear in the descriptions after I locate them on the Stairs. I changed the condition to [if the bookcases are in Apartment Area], thinking it was some ambiguity of the location that was causing this, and it did the same thing. Finally, I tried [if the bookcases are not nowhere]–this worked perfectly. Is there some ambiguity about the location of backdrops when it is referred to in an ‘if’ clause?? Should we avoid doing this, except when we move them ‘off stage’ and then say ‘if the (backdrop) is nowhere’ or ‘not nowhere’?


So this is a weird quirk of Inform.

Objects are stored as a tree, so each object has to be contained by exactly one other object. This is a problem for backdrops, which need to be in multiple places. So what actually happens when a backdrop is “in” multiple rooms, is that whenever the player enters one of those rooms, the backdrop moves there too.

Which means a backdrop will always be “in” the most recent location of the player, within its “range”.

There should be a way to test whether a backdrop is in a particular room or not, without moving the player there (by calling its Inform 6 “found_in” routine). But I don’t think there’s such a thing in the standard library. I should make an extension.

A bit of poking reveals that the “on-stage” / “is nowhere” property of backdrops is implemented separately from their location (as the “absent” flag in I6), which is why that part works. Similarly you can test if a backdrop is “everywhere” and that’ll work successfully.

And a bit more poking indicates that you should be able to test whether a backdrop is “in” another location by calling “BackdropLocation(backdrop, room)”. Which makes me wonder why it’s not working in your example.

I think I’ve seen this kind of thing recommended before:

To decide whether (B - a backdrop) is present in (R - a room):
	let L be the holder of the player;
	let R_visited be whether or not R is visited;
	move the player to R, without printing a room description;
	let B_present be whether or not B is in the location;
	move the player to L, without printing a room description;
	if R_visited is false, now R is not visited;
	if B_present is true, decide yes;
	decide no.

But there are all sorts of things that could go wrong with this. It would be be much better to do it with an I6 check if that’s possible.

Actually this seems to work (following Draconis’s suggestion).

To decide if (F - a backdrop) is present in (R - a room):
	(- (BackdropLocation({F},{R}) == {R}) -).

The I7 phrase “the location of (backdrop)” calls BackdropLocation(backdrop). This produces, in order of preference: the location (if the backdrop is present); the first-declared room with the backdrop (assuming it’s somewhere); and nothing. (It doesn’t return the last visited room with the backdrop.)

BackdropLocation(backdrop, room), with the extra argument, returns the room if the backdrop is in it; otherwise nothing. As far as I can tell this version of the routine can’t be accessed natively in I7.

Thanks a lot! Thank you for letting me know about the object hierarchy, now I have a better perspective on how it works.

Don’t forget “update backdrop positions” which will do this when the player doesn’t move.

§8.8. Moving backdrops