[I7] Reachability Problems

I’m having problems restricting reachability.

Let’s say I want the player to be able to get to a window only if he first gets on a shelf under the window by pushing a crate near the window. The player shouldn’t be able to reach things which are on the floor if he’s on the shelf either.

I tried creating a shelfside property for the crate to test whether it’s near the shelf, then I created an elevated property to restrict access to the shelf, like so …


The Shed is a room. The description is "A window is above a shelf."

The doodad is in the Shed.

A supporter can be elevated. A supporter is usually not elevated.

A rule for reaching outside a supporter:
	if the player is on an elevated supporter:
		if the noun is on a not elevated supporter: 
			deny access;
		otherwise: [the noun is on an elevated supporter]
			continue the action;
	otherwise: [player is on a not elevated supporter]
		if the noun is on an elevated supporter: 
			deny access;
		otherwise: [the noun is on a not elevated supporter]
			continue the action.	

The crate is in the Shed. The crate is enterable, a supporter, and elevated. The description is "It's heavy, and it looks wide enough and sturdy enough to support you." The crate can be shelfside. The crate is not shelfside.

Instead of pushing or pulling the crate:
	if the crate is shelfside:
		now the crate is not shelfside;
		say "You push the crate away from the shelf.";
	otherwise:
		now the crate is shelfside;
		say "You pull the crate over to the shelf.".

After entering the crate:
	if the crate is shelfside:
		now the crate is elevated;
		continue the action;
	otherwise:
		continue the action.

After getting off the crate:
	if the crate is elevated:
		now the crate is not elevated;
		continue the action;
	otherwise:
		continue the action.
		
The shelf is in the Shed. The shelf is enterable, a supporter, elevated, and not described. The description is "It's higher than your head, but it looks wide enough and sturdy enough to support you." 

The window is on the shelf. The window is fixed in place.

And this is what happens:

Shed
A window is above a shelf.

You can see a doodad and a crate here.

>get on the shelf
You get onto the shelf.

On the shelf you can see a window.

>take the doodad
Taken.

>get off the shelf
You get off the shelf.

Shed
A window is above a shelf.

You can see a crate here.

>get on the crate
You get onto the crate.

>get on the shelf
(getting off the crate)
You get onto the shelf.

On the shelf you can see a window.

>get off the shelf
You get off the shelf.

Shed
A window is above a shelf.

You can see a crate here.

>push the crate
You pull the crate over to the shelf.

>get on the crate
You get onto the crate.

>showme crate
crate - supporter
yourself - person
doodad
location: in the Shed
singular-named, improper-named; unlit, inedible, fixed in place; enterable, elevated; shelfside …

I thought this would work a little better than it is. What did I do wrong?

It looks like you’re trying to use the rule for reaching inside to restrict whether the player can enter the shelf? Rules for reaching inside/outside can’t do that, I don’t think. A rule for reaching inside a box will affect whether you can interact with things inside the box, but it won’t affect whether you can interact with the box itself.

Take this implementation of an extremely disgusting scene from Trainspotting, please forgive me

"Deep Blue Day" by Matt Weiner

The world's most disgusting lavatory is a room.

A toilet is an enterable fixed in place container in the lavatory. A suppository is in the toilet.

Rule for reaching inside the toilet: 
	say "Unfortunately your arm isn't long enough.";
	deny access.

After entering the toilet: say "Steel guitars play as you dive in...."

Results:

world’s most disgusting lavatory
You can see a toilet (in which is a suppository) here.

get suppository
Unfortunately your arm isn’t long enough.

enter toilet
Steel guitars play as you dive in…

look
world’s most disgusting lavatory (in the toilet)
In the toilet you can see a suppository.

get suppository
Taken.

exit
You get out of the toilet.

world’s most disgusting lavatory
You can see a toilet (empty) here.

Apologies if that’s not what the issue was! (Also, really, sorry about that example, it was the only case I could think of with an enterable container you can’t reach inside.)

When you’re standing on the shelf and try to take the doodad, this is not blocked by your rule’s logic because while the player is on an elevated supporter, the doodad is just in the room (and thus the noun is on a not elevated supporter is false). Perhaps you meant the noun is not on an elevated supporter instead?

Also note that when denying access to the player, you should say something to explain why their action fails, otherwise nothing is printed and they’ll be left confused.

Just as a point of style, if you’re going to continue the action in both cases then you can put that outside of the if:

After entering the crate:
	if the crate is shelfside:
		now the crate is elevated;
	continue the action.

But also, rather than having an After rule that has to explicitly continue the action, you could just write a Carry Out rule instead:

Carry out entering the crate when the crate is shelfside:
	now the crate is elevated.

(You also don’t need to explicitly continue the action in the reachability rule, since that’s the default if you just exit the rule without explicitly allowing or denying access. But it’s fine if you prefer to be explicit about it.)

1 Like

Here’s a complete working example which I think demonstrates what you were trying to do:

The Shed is a room. The description is "A window is above a shelf."

The doodad is in the Shed.

A supporter can be elevated. A supporter is usually not elevated.

A rule for reaching outside a supporter:
	if the player is on an elevated supporter:
		if the noun is not elevated and the noun is not on an elevated supporter: 
			say "You can't reach that from here.";
			deny access;
	otherwise: [player is not on an elevated supporter]
		if the noun is elevated or the noun is on an elevated supporter: 
			say "You stretch as high as you can, but you can't reach that from here.";
			deny access;

The crate is in the Shed. The crate is enterable and a supporter. The description is "It's heavy, and it looks wide enough and sturdy enough to support you." The crate can be shelfside. The crate is not shelfside.

Instead of pushing or pulling the crate:
	if the crate is shelfside:
		now the crate is not shelfside;
		say "You push the crate away from the shelf.";
	otherwise:
		now the crate is shelfside;
		say "You pull the crate over to the shelf.".

Check entering the shelf when the player is not on the crate:
	say "The shelf is too high for you to climb onto it, without assistance." instead.

Carry out entering the shelfside crate: now the crate is elevated.
Carry out getting off the elevated crate: now the crate is not elevated.
		
The shelf is in the Shed. The shelf is enterable, a supporter, elevated, and not described. The description is "It's higher than your head, but it looks wide enough and sturdy enough to support you." 

The window is on the shelf. The window is fixed in place.

Test me with "get on shelf / enter crate / get on shelf / exit / push crate / get on crate / get on shelf / get doodad".

Of note is that you need to define an explicit rule to block entering the shelf when not on the crate (your reachability rule doesn’t apply there as the player isn’t on any supporter at the time, so isn’t “reaching outside” anything). And the logic for denying access to non-elevated things needs to avoid denying access to the shelf (because while the shelf is itself elevated, it’s not on an elevated supporter).

2 Likes

As a further aid to readability, you can introduce a new adjective for the combination of states:

Definition: a thing is raised if it is elevated or it is on an elevated supporter.

A rule for reaching outside a supporter:
	if the player is raised:
		if the noun is not raised: 
			say "You can't reach that from here.";
			deny access;
	otherwise: [player is not raised]
		if the noun is raised: 
			say "You stretch as high as you can, but you can't reach that from here.";
			deny access;
1 Like

Another thing is that it might be easier for you to split up the rule for reaching outside into different rules for each case:

A rule for reaching outside an elevated supporter:
		if the noun is not elevated and the noun is not on an elevated supporter: 
		say "You can't reach that from here.";
		deny access.
A rule for reaching outside a not elevated supporter:
	if the noun is elevated or the noun is on an elevated supporter: 
		say "You stretch as high as you can, but you can't reach that from here.";
		deny access.

Another thing–do you want the player to be able to reach something on an elevated supporter from the room, when they’re not on any supporter at all? Because if the player is just in the room, none of these versions of reaching outside will run–the player isn’t in/on anything, so they’re not reaching outside.

If you want to prevent the player from taking something from an elevated supporter unless they’re on an elevated supporter, the thing to do is use a rule for reaching inside:

A rule for reaching inside an elevated supporter:
	unless the player is on an elevated supporter:
		say "You stretch as high as you can, but you can't reach that from here.";
		deny access.

However, this won’t take care of the case where the player is in the room and they want to do something to an elevated thing that is also in the room–since the player and the elevated thing are both in the room, there is no reaching outside or reaching inside happening here. I think you have to write special rules for these cases.

And, if I’m understanding your intentions correctly, you probably don’t want to completely prevent the player from dealing with elevated things unless they’re on an elevated supporter–since the crate is elevated, that would prevent the player from getting on the crate in order to reach the shelf! So you’d need a special case for getting on the shelf.

(I haven’t tested the code, and I copied some stuff from Gavin’s post and then tried to fix the tabs by hand, so apologies if some of it doesn’t work!)

1 Like

I fixed that in my example – the crate shouldn’t initially be elevated, because elevation gets added or removed when entering/exiting it (which is needed to allow accessing the shelf from the crate, as in the original example). It also doesn’t make the crate elevated unless it’s already shelfside, to require that you push it first. (Otherwise you’d be able to get onto the shelf with the crate in the wrong position.)

This does mean that while on the crate you can still pick up the doodad – unless you pushed the crate shelfside first, and then you mysteriously can’t. If you want to be able to fix that, then you’d have to make even more special cases, or decide that this either/or “elevated” concept isn’t really sufficient – you’d probably need to give each thing a numeric or enumerated “elevation” instead (so that the crate and shelf can have different elevation levels) and selectively block things based on the relative difference in elevation.

Here’s an expanded example that keeps the crate elevated but special-cases allowing accessing the shelf from the shelfside crate instead. This fixes the problem with inconsistent accessibility of the doodad from on top of the crate – but introduces a new problem that while on the crate (in either position) you would be able to access something on the shelf, because both are elevated. (This goes back to what I was saying about possibly needing to model multiple elevation levels to do this properly.)

The Shed is a room. The description is "A window is above a shelf."

The doodad is in the Shed.

A supporter can be elevated. A supporter is usually not elevated.

Definition: a thing is raised if it is elevated or it is on an elevated supporter.

A rule for reaching inside an elevated supporter:
	if the player is not raised:
		say "You can't reach that from here.";
		deny access.

A rule for reaching outside a supporter:
	if the player is raised:
		if the noun is not raised: 
			say "You can't reach that from here.";
			deny access;
	otherwise: [player is not raised]
		if the noun is raised: 
			say "You stretch as high as you can, but you can't reach that from here.";
			deny access;

A rule for reaching outside the shelfside crate:
	if the noun is the shelf, allow access.

The crate is in the Shed. The crate is enterable, a supporter, and elevated.
The description is "It's heavy, and it looks wide enough and sturdy enough to support you." The crate can be shelfside. The crate is not shelfside.

Instead of pushing or pulling the crate:
	if the crate is shelfside:
		now the crate is not shelfside;
		say "You push the crate away from the shelf.";
	otherwise:
		now the crate is shelfside;
		say "You pull the crate over to the shelf.".

Check entering the shelf when the player is not on the shelfside crate:
	say "The shelf is too high for you to climb onto it, without assistance." instead.

The shelf is in the Shed. The shelf is enterable, a supporter, elevated, and not described.
The description is "It's higher than your head, but it looks wide enough and sturdy enough to support you." 

The window is on the shelf. The window is fixed in place.

Test me with "get on shelf / enter crate / get on shelf / exit / push crate / get on crate / get on shelf / get doodad".

You can fix accessing items on the shelf from the crate by making the crate non-elevated (keeping everything else in this example the same), but then this allows you to access the doodad from the crate (although it’s consistent about it, unlike the prior example). Without more elevation levels (or special casing even more stuff), you need to pick your battles, though.

Another possibility that you could consider, that might make some things easier, would be to model the shelf as a separate room. This may sound odd at first, but if you think about it, to Inform a “room” is just an arbitrary division where the player can interact with things inside but not outside, which sounds like what you’re trying to do here – it’ll stop people touching things on the shelf unless they’re on the shelf. You can use scenery items to aid in moving the player there as appropriate, and you can provide ways to see what’s on the shelf from the outside room if you want as well.

1 Like

I started adding your suggestions one by one until I got it working. This seems to do the trick.


The Shed is a room. The description is "A window is above a shelf."

The doodad is in the Shed.

A supporter can be elevated. A supporter is usually not elevated.

A rule for reaching outside a supporter:
	if the player is on an elevated supporter:
		if the noun is not an elevated supporter and the noun is not on a elevated supporter:
			say "You can't reach that from here."; 
			deny access;
	otherwise: [player is on a not elevated supporter]
		if the noun is an elevated supporter and the noun is on an elevated supporter:
			say "You can't reach that from here."; 
			deny access;

A rule for reaching inside an elevated supporter:
	unless the player is on an elevated supporter:
		say "You can't reach [the noun] from here.";
		deny access.

Check entering the shelf when the player is not on an elevated supporter:
	say "The shelf is too high for you to climb onto it." instead.	

Check putting something on the shelf:
	if the player is not on an elevated supporter:
		say "The shelf is so high that you can't reach." instead.

The crate is in the Shed. The crate is enterable and a supporter. The description is "It's heavy, and it looks wide enough and sturdy enough to support you." The crate can be shelfside. The crate is not shelfside.

Instead of pushing or pulling the crate: 
	if the player is on the crate:
		say "You can't move the crate when you're on it.";
	otherwise if the crate is shelfside:
		now the crate is not shelfside;
		say "You push the crate away from the shelf.";
	otherwise:
		now the crate is shelfside;
		say "You pull the crate over to the shelf.".

After entering the crate:
	if the crate is shelfside:
		now the crate is elevated;
	continue the action.

After getting off the crate:
	if the crate is elevated:
		now the crate is not elevated;
	continue the action.
		
The shelf is in the Shed. The shelf is enterable, a supporter, elevated, and not described. The description is "It's higher than your head, but it looks wide enough and sturdy enough to support you." 

The window is on the shelf. The window is fixed in place.

(I had also forgotten to see if the player was on the crate before he moved it.)

Thanks for your advice.

Isn’t this a bit much coding for a fairly common adventure-game puzzle? Did Inform 6 handle this better?

This sort of thing may be common but that doesn’t mean it’s trivial to code. In any system. Scope and reach-handling can be unboundedly messy.

Inform 6 had roughly similar ideas about touchability. (Can’t reach into a closed container, etc.) But it had no way to customize touchability – you couldn’t write a rule to define when an object was touchable. So you had to stick in “before” rules. This was simpler in some sense, but also easier to screw up – you had to check more cases.

1 Like

One thing about this kind of puzzle is that it pushes against the grain of the typical text-adventure world model a bit.

The Inform world model models rooms, but it doesn’t have much of anything built in for modeling where things are within rooms, except for things that are in or on other things. “On the shelf” is a built-in concept, but “near the shelf” isn’t. Ditto for things being high-up in the room versus low down.

So if you want to model “You can’t reach something on the high shelf unless you’re standing on something else that is not as high and is near the shelf,” you’re putting in a lot of stuff that isn’t built in to the model.

Part of what adds the complexity is that you’re using the full world model, so the player can put other things on the shelf, and you have to worry about taking those off, etc. If you don’t want to deal with all that stuff, it might be easier to forbid the player from putting anything on the shelf (“Why would you want to do that?”), and write a special rule for preventing taking the doodad unless the player is on the crate, and so on. Depends on what you’re trying to do!

3 Likes

In addition to everything else: it’s safer to use the person reaching instead of the player when writing reaching and accessibility rules. This ensures that the rules apply equally to all persons in the game. (See Writing with Inform §12.18.)