Complex reachability and making it apply to NPCs

This is a follow-up to my earlier thread.

It turns out what I said in that thread is no longer quite true:

I don’t really plan to have other actors taking unreachable things though, and so far I don’t mind them leaping through unreachable trapdoors in the ceiling.

In fact, I still don’t mind if an offscreen NPC (or your sidekick while following you) reaches through unreachable trapdoors on the ceiling, but there are definitely cases where reach should come into play for an NPC. For example, when the hostile NPC tries to grab you, it should fail if you’re floating well his head. Or if you ask your sidekick to do something, it should fail if the item is out of reach.

The general requirements haven’t significantly changed since that thread:

  • Each item in a “logical room[1]” has a specific access level. For example, most things have access level 0, but a security camera or a trapdoor on the ceiling or a clock placed above the door would have access level 1.
  • Without anything else in play, the player can only access things on the same access level as themselves.
  • However, if the player obtains telekinesis, they can now access things one level higher than themselves.
  • I was thinking some people might be declared as “tall”, with the same effect as above. Or there could be an “extensible claw” which, when worn or carried, has the same effect.
  • If you stand on a “booster” (a kind of enterable supporter), your access level increases by 1.
  • If you ask someone to “hoist” you, your access level increases by 1.
  • If you obtain levitation, you can increase your access level arbitrarily within the room’s “float limit”.

I also have a few other rules which aren’t quite as complex (as they can use the pre-existing reaching inside/outside rules) but might be useful to know as part of this topic:

  • If you’re reclining on a bed, you can’t reach anything outside it.
  • Some rooms have a large container (eg a gazebo) that’s almost a separate room but not quite.
  • There is one area that’s a large “logical room” composed of 9 “technical rooms”, where you can see the other rooms but not touch them.

There is also one place where it would be problematic for the reach rules to apply to an NPC – your sidekick would have trouble following you through trapdoors on the ceiling. This is probably manageable though.


Okay, that’s the basic requirements out of the way. A number of different approaches to this problem have been mentioned.

  1. A custom reachability rulebook. I have that working, but it’s not quite satisfactory: it doesn’t allow for “you need to get your sidekick to stand on a booster and then hoist you” which I want as an alternative to flying for one puzzle.
  2. Each “access level” as a separate “technical room”. This creates a ton of new problems, but might ultimately simplify the concept.
  3. I spotted a post by Otistdog talking about custom “reaching through” and “reaching across” rulebooks, which sounded like they might be applicable to my problem. I have no idea where the mentioned extension could be found though.
  4. Custom “instead” rules for every case. I think this has difficulty dealing with NPCs though. That said, it’s not like it can’t possibly deal with them.

Several people in the previous post already stated that approach 1 seems excessive. If anyone has ideas on how to make it satisfy the requirement of stacking conditions, I’d like to hear them.

I’m also interested in exploring approach 2 in more detail. I think every current room would need to become a region (so that I can still test if someone is in a given “logical room”), so the number of regions would skyrocket and the number of rooms would at least quadruple – not sure if that’s an issue given the number of rooms I already have (146, which is probably a lot). I would need to override vision so that you can still see unreachable objects, but that’s something I already need to do in some other places (the previously-mentioned large room, or the lookout tower), so needing to do it here might also help me do it in the other places. I think standing on a booster would then mean moving the booster to the room above with you on it, and your sidekick hoisting you would also mean moving you to the room above. Telekinesis, tall, or extensible claws could probably be handled by a reaching outside rule. Levitation would be reduced to a simple going action. There would need to be logic for dropping items to not end up floating in mid-air. Is there anything that I’m missing in this approach?

And, does anyone know if the extension Otistdog mentioned was actually released somewhere?


  1. By this, I mean something you would describe as a room to the player, not necessarily something that is defined as a room in the source. ↩︎

1 Like

I dealt with this in part in the second-to-last area of my game Never Gives Up Her Dead, which is a large party in a room that has several sub-locations. My divisions were horizontal, though.

I heavily used the Inform example ‘Emma’: Ex. 353. Emma

It has groups of people that rate the attractiveness of different spaces and move to what’s ‘most attractive’ (with attractiveness being defined as who’s present, for instance). I shamelessly copied this wholesale and just put my own people in it.

You might make this work under your approach by assign ratings based on gravity or supports and then moving things if they are under the effects of gravity and not supported.

1 Like

I’m not sure how well that applies to my current situation, but it does seem like it’s worth exploring.

Maybe what I need to do is make a small mini-story just to test these things out…

1 Like

You’re right, there’s a lot going on in that example. The main thing it does is to treat one continuous space as separate Inform ‘rooms’ and to give rules for visibility and motion that allow you to interact with other parts of the room. It also adds a rule that dictates the motion of a certain class of object every turn. If those parts of your problem have already been solved, then there’s nothing else useful in that example.

Just somewhere in my files – it was never released since it’s alpha. I’ll try to locate it and get back to you.

1 Like

I would call attention to this thread, where related issues were discussed at length:

This is unfortunately not something that Inform handles very well out of the box. I think the best approach would be to put a new rule in the accessibility rulebook that denies access if the level of the “person reaching” and the level of the “particular possession” don’t match, and the person reaching doesn’t have some particular attribute (call it “tall” or “telekinetic” or what have you). Then you can have all the rest of your rules affect people’s levels and tallness and so on.

1 Like

That seems like it would be easier than the “every access level is a room” approach, so I think I’ll give it a try.

Okay, so I’ve come up with two alternative approaches, but I think I still prefer the rulebook-based one. This is fairly different from my previous rulebook-based approach – in fact, it’s written such that one reachability rule handles nearly every case.

Rulebook Version (code)

Include Postures by Emily Short.
Include Auxiliary Phrases by Stefan O'Halloran.

Section 1 - General Mechanics

To reach is a verb. To allow is a verb.

A booster is a kind of supporter.
A booster is usually portable.
A booster is always enterable.

A person can be strong or weak.
A person is usually weak.

Every booster allows standing.

Definition: a person (called they) is boosted:
	if they are not on a booster, no;
	if they are not standing, no;
	yes.

Boosting is an action applying to one thing.
Understand "boost [person]" as boosting.
Understand "hoist [person]" as boosting.

Hoisting relates one person to one person.
The verb to hoist means the hoisting relation.

Instead of an actor dropping someone (called the load) who is hoisted by the actor:
	if the holder of the actor is a container or the holder of the actor is a room:
		now the load is in the holder of the actor;
	otherwise:
		now the load is on the holder of the actor;
	now the actor is not hoisting the load;
	say "[The actor] [set] [the load] back down [on the holder of the actor]."

Check an actor boosting when the actor is weak (this is the weak people can't boost rule):
	if the actor is the player:
		say "[We]['re] not strong enough." (A);
	stop the action.

Carry out an actor boosting (this is the standard boosting rule):
	now the actor hoists the noun;

Report an actor boosting (this is the report boosting rule):
	say "[The actor] [allow] [us or the noun] to climb onto [regarding the actor][their] shoulders." (A);

Check going when the player is hoisting someone (called the load) (this is the player can't move while boosting rule):
	say "Not while carrying [the load]!" (A).

First carry out going when a person (called the passenger) is hoisted by the actor (this is the set down load before going rule):
	now the actor is not hoisting the passenger;
	if the passenger is the player:
		say "[The actor] [set] [us] down." (A);
	otherwise:
		say "[The actor] [set] down [the passenger]." (B);

[Though the above two rules mean an actor can't go while hoisting, a specific game could choose to disable that rule. So, in that case, allow matching "going by" the person in rules.]
Setting action variables for going when the actor is hoisting someone (called the load) (this is the moving while hoisting is like a vehicle rule):
	now the vehicle gone by is the load.

First carry out going when a person (called the helper) is hoisting the player (this is the get off your helper before going rule):
	if the noun is not up:
		say "(first getting off of [the helper])[command clarification break]" (A);
	now the helper is not hoisting the actor;
	if the helper hoists the player, stop.

First carry out someone going when a person (called the helper) is hoisting the actor (this is the set them down so they can go rule):
	if the noun is not up:
		say "[We or the actor] [get] off of [the helper]." (A) instead;
	now the helper is not hoisting the actor;
	if the helper hoists the actor, stop.

First carry out an actor exiting when a person (called the helper) is hoisting the actor (this is the convert exit to getting off the helper rule):
	now the helper is not hoisting the actor;
	say "[We or the actor] [get] off of [the helper]." (A) instead;

A person can be tall. A person is usually not tall.

Section 2 - Reach Mechanics

A thing has a number called the access height.

To decide what number is the effective access height of (T - a thing):
	[if T is the player, say "checking access height.";]
	let height be the access height of T;
	[say "native height [height].";]
	let H be the holder of T;
	while H is a thing:
		[if T is the player, say "held by [H].";]
		if the access height of H is greater than height:
			[if T is the player, say "boosted to [H]'s level.";]
			let height be the access height of H;
		if H is a booster:
			[if T is the player, say "boosted above [H]'s level.";]
			increase height by 1;
		let H be the holder of H;
	if T is a person and T is hoisted by someone (called the helper):
		[if T is the player, say "hoisted by [the helper].";]
		increase height by 1;
		if the helper is tall:
			[if T is the player, say "[the helper] is tall.";]
			increase height by 1;
	decide on height.

To decide what number is the minimum access height of (P - a person):
	let n be the effective access height of P;
	if P is wearing the extensible claw, decide on n - 1;
	decide on n.

To decide what number is the maximum access height of (P - a person):
	let n be the effective access height of P;
	if P is tall, increase n by 1;
	if P is wearing the extensible claw, decide on n + 1;
	decide on n.

Check reachability is an object based rulebook. The check reachability rules have outcomes in reach (success) and out of reach (failure). Reporting failure to reach something is an activity on objects

To decide whether (P - a person) can reach (T - a thing):
	now the person reaching is P;
	follow the check reachability rules for T;
	if the outcome of the rulebook is the out of reach outcome:
		if the player can see P:
			carry out the reporting failure to reach activity with T;
		no;
	yes.

To decide whether (P - a person) cannot/can't reach (T - a thing):
	if P can reach T, no;
	yes.

An action-processing rule (this is the checking reach rule):
	if the current action is going and the door gone through is a door:
		if the actor cannot reach the door gone through, stop the action;
	if the action requires a touchable noun:
		if the actor cannot reach the noun, stop the action;
	if the action requires a touchable second noun:
		if the actor cannot reach the second noun, stop the action.

For reporting failure to reach something (called the item) (this is the standard report reach failure rule):
	say "[We or the person reaching] [can't reach] [regarding the item][those]." (A).

For reporting failure to reach an open door (called the portal) while going (this is the report open door reach failure rule):
	say "[We or the person reaching] [can't reach] the opening of [the portal]." (A).

For reporting failure to reach a closed door (called the portal) while going (this is the report closed door reach failure rule):
	say "[We or the person reaching] [can't reach] [the portal]." (A).

Check reachability for someone hoisted by the person reaching (this is the ignore reachability for hoisted people rule):
	in reach.

Check reachability for someone hoisting the person reaching (this is the ignore reachability for the person hoisting rule):
	in reach.

Check reachability for something enclosed by the person reaching (this is the ignore reachability for held items rule):
	in reach.

Check reachability for a door (called the portal) when the direction of the portal from the location of the person reaching is down (this is the doors to the down always have access height zero rule):
	if the minimum access height of the person reaching is at most 0:
		in reach;
	out of reach.

Check reachability for something (called the item) (this is the standard reachability rule):
	let min be the minimum access height of the person reaching;
	let max be the maximum access height of the person reaching;
	[say "[min] ≤ [effective access height of the particular possession] ≤ [max].";]
	if the effective access height of the item is between min and max:
		in reach;
	out of reach.

The stand up before going rule does nothing when the noun is up.
The can't travel in what's not a vehicle rule does nothing when the noun is up.

Section 3 - Scenario

The Shaft is a room.

Bob is a tall strong person in the Shaft.
The chair is a fixed in place booster in the Shaft.
The shelf is a supporter in the Shaft. The access height of the shelf is 2.
On the shelf is silver key. The silver key unlocks the box.
The box is a transparent closed openable locked container in the Shaft. The access height of the box is 3.
In the box is an extensible claw. The extensible claw is wearable.
The trapdoor is a door. It is up from the Shaft and down from the Surface. It has access height 4.
Yourself carries a rope and a strength pill. The strength pill is edible.

Persuasion rule for asking Bob to try doing something: rule succeeds.
The block giving rule does nothing.
Carry out an actor giving: now the second noun carries the noun.

To tie is a verb.

Check tying the rope to something:
	say "[We] [tie] [the rope] to [the second noun].";
	rule succeeds.

After eating the strength pill:
	now the player is strong;
	say "[We] [feel] stronger!".
Rulebook Version (sample transcript)
Shaft
You can see a trapdoor, Bob, a chair, a shelf (on which is silver key) and a box (closed) (in which is an extensible claw) here.

>take key
You can't reach that.

>tie rope to key
You can't reach that.

>take Bob
I don't suppose Bob would care for that.

>take chair
That's fixed in place.

>open box
You can't reach that.

>stand on chair
You are now standing on the chair.

>take key
You can't reach that.

>open box
You can't reach that.

>Bob, stand on chair
Bob is now standing on the chair.

>Bob, take key
Bob picks up silver key.

>Bob, open box
Bob can't reach that.

>boost Bob
You're not strong enough.

>eat pill
You feel stronger!

>boost Bob
You allow Bob to climb onto your shoulders.

>Bob, open box
Bob is unable to do that.

>Bob, unlock box with key
Bob unlocks the box.

>Bob, lock box with key
Bob locks the box.

>drop Bob
You set Bob back down on the chair.

>Bob, boost me
Bob allows you to climb onto his shoulders.

>Bob, give me key
Bob gives silver key to you.

>give Bob key
You give silver key to Bob.

>Bob, give me key
Bob gives silver key to you.

>up
You can't reach the trapdoor.

>unlock box with key
You unlock the box.

>take claw
The box isn't open.

>open box
You open the box.

>take claw
Taken.

>open trapdoor
You can't reach that.

>wear claw
You put on the extensible claw.

>open trapdoor
You open the trapdoor.

>take off claw
You take off the extensible claw.

>up
You can't reach the opening of the trapdoor.

>give claw to Bob
You give the extensible claw to Bob.

>up
You can't reach the opening of the trapdoor.

>Bob, wear claw
Bob puts on the extensible claw.

>up
You can't reach the opening of the trapdoor.

>Bob, take off claw
Bob takes off the extensible claw.

>Bob, give me claw
Bob gives the extensible claw to you.

>wear claw
You put on the extensible claw.

>up

Surface
You can see a trapdoor here.

>
Room Version (code)
"Room Based" by Stefan O'Halloran

Include Postures by Emily Short.
Include Auxiliary Phrases by Stefan O'Halloran.

Section 1 - General Mechanics

To reach is a verb. To allow is a verb.

A booster is a kind of supporter.
A booster is usually portable.
A booster is always enterable.

A person can be strong or weak.
A person is usually weak.

Every booster allows standing.

Definition: a person (called they) is boosted:
	if they are not on a booster, no;
	if they are not standing, no;
	yes.

Boosting is an action applying to one thing.
Understand "boost [person]" as boosting.
Understand "hoist [person]" as boosting.

Hoisting relates one person to one person.
The verb to hoist means the hoisting relation.

Instead of an actor dropping someone (called the load) who is hoisted by the actor:
	if the holder of the actor is a container or the holder of the actor is a room:
		now the load is in the holder of the actor;
	otherwise:
		now the load is on the holder of the actor;
	now the actor is not hoisting the load;
	say "[The actor] [set] [the load] back down [on the holder of the actor]."

Check an actor boosting when the actor is weak (this is the weak people can't boost rule):
	if the actor is the player:
		say "[We]['re] not strong enough." (A);
	stop the action.

Carry out an actor boosting (this is the standard boosting rule):
	now the actor hoists the noun;

Report an actor boosting (this is the report boosting rule):
	say "[The actor] [allow] [us or the noun] to climb onto [regarding the actor][their] shoulders." (A);

Check going when the player is hoisting someone (called the load) (this is the player can't move while boosting rule):
	say "Not while carrying [the load]!" (A).

First carry out going when a person (called the passenger) is hoisted by the actor (this is the set down load before going rule):
	now the actor is not hoisting the passenger;
	if the passenger is the player:
		say "[The actor] [set] [us] down." (A);
	otherwise:
		say "[The actor] [set] down [the passenger]." (B);

[Though the above two rules mean an actor can't go while hoisting, a specific game could choose to disable that rule. So, in that case, allow matching "going by" the person in rules.]
Setting action variables for going when the actor is hoisting someone (called the load) (this is the moving while hoisting is like a vehicle rule):
	now the vehicle gone by is the load.

First carry out going when a person (called the helper) is hoisting the player (this is the get off your helper before going rule):
	if the noun is not up:
		say "(first getting off of [the helper])[command clarification break]" (A);
	now the helper is not hoisting the actor;
	if the helper hoists the player, stop.

First carry out someone going when a person (called the helper) is hoisting the actor (this is the set them down so they can go rule):
	if the noun is not up:
		say "[We or the actor] [get] off of [the helper]." (A);
	now the helper is not hoisting the actor;
	if the helper hoists the actor, stop.

First carry out an actor exiting when a person (called the helper) is hoisting the actor (this is the convert exit to getting off the helper rule):
	now the helper is not hoisting the actor;
	say "[We or the actor] [get] off of [the helper]." (A);

A person can be tall. A person is usually not tall.

Section 2 - Reach Mechanics

An area is a kind of region.

To decide what number is the minimum access height of (P - a person):
	let n be 0;
	if P is on a booster, increase n by 1;
	if P is hoisted by someone, increase n by 1;
	if P is hoisted by someone tall, increase n by 1;
	if P is wearing the extensible claw, decrease n by 1;
	decide on n.

To decide what number is the maximum access height of (P - a person):
	let n be 0;
	if P is on a booster, increase n by 1;
	if P is hoisted by someone, increase n by 1;
	if P is hoisted by someone tall, increase n by 1;
	if P is tall, increase n by 1;
	if P is wearing the extensible claw, increase n by 1;
	decide on n.

After deciding the scope of a person (called they):
	if they are regionally in an area (called it):
		repeat with R running through rooms	regionally in it:
			[say "[R] is in scope.";]
			place the contents of R in scope.

Rule for reaching inside a room (called the destination):
	[say "Reaching into [the destination].";]
	let min be the minimum access height of the person reaching; 
	let max be the maximum access height of the person reaching;
	let here be the location of the person reaching;
	let the height difference be zero;
	while here is not the destination:
		[say "--Checking [here].";]
		let thataway be the best route from here to the destination;
		if thataway is up and the height difference is at least zero:
			increase the height difference by 1;
		otherwise if thataway is down and the height difference is at most zero:
			decrease the height difference by 1;
		let here be the room thataway from here;
	[say "--Height difference is [height difference].";]
	[say "--Min reach is [min] and max reach is [max].";]
	if height difference < 0 and height difference < min:
		[say "--Fails - too low";]
		make no decision;
	if height difference > 0 and height difference > max:
		[say "--Fails -- too high";]
		make no decision;
	[say "--Succeeds";]
	allow access.

The reach tester is a thing.

Check an actor going a direction (called thataway):
	let here be the location of the actor;
	if here is in an area (called there):
		let R be the room thataway from here;
		if R is regionally in there:
			while the room thataway from R is regionally in there:
				let R be the room thataway from R;
			now the reach tester is in R;
			if the actor cannot touch the reach tester:
				say "[We] [can't reach] that exit." instead.

Carry out an actor going (this is the determine regional map connection rule):
	let temp be the room gone from;
	[say "Going from [room gone from]...";]
	follow the determine map connection rule;
	if the room gone from is regionally in an area (called there):
		while the room gone to is a room and the room gone to is regionally in there:
			now the room gone from is the room gone to;
			[say "...through [room gone from]...";]
			follow the determine map connection rule;
	[say "...to [room gone to].";]
	now the room gone from is temp;

[This should really be "The determine regional map connection substitutes for the determine map connection in the check going rulebook." but that doesn't work.]
The determine map connection rule is not listed in the check going rulebook.
The determine regional map connection rule is listed before the can't go that way rule in the check going rules.


The stand up before going rule does nothing when the noun is up.
The can't travel in what's not a vehicle rule does nothing when the noun is up.

Section 3 - Scenario

ShaftBottom, ShaftOne, ShaftTwo, ShaftThree, ShaftCeiling are rooms.
The Shaft is an area. ShaftBottom, ShaftOne, ShaftTwo, ShaftThree, ShaftCeiling are in Shaft.
ShaftCeiling is above ShaftThree. ShaftThree is above ShaftTwo. ShaftTwo is above ShaftOne. ShaftOne is above ShaftBottom.

Bob is a tall strong person in ShaftBottom.
The chair is a fixed in place booster in ShaftBottom.
The shelf is a supporter in ShaftTwo.
On the shelf is silver key. The silver key unlocks the box.
The box is a transparent closed openable locked container in ShaftThree.
In the box is an extensible claw. The extensible claw is wearable.
The trapdoor is a door. It is up from ShaftCeiling and down from the Surface.
Yourself carries a rope and a strength pill. The strength pill is edible.

Persuasion rule for asking Bob to try doing something: rule succeeds.
The block giving rule does nothing.
Carry out an actor giving: now the second noun carries the noun.

To tie is a verb.

Check tying the rope to something:
	say "[We] [tie] [the rope] to [the second noun].";
	rule succeeds.

After eating the strength pill:
	now the player is strong;
	say "[We] [feel] stronger!".
Room Version (sample transcript)
ShaftBottom
You can see Bob and a chair here.

>take key
You can't reach into ShaftTwo.

>tie rope to key
You can't reach into ShaftTwo.

>take Bob
I don't suppose Bob would care for that.

>take chair
That's fixed in place.

>stand on chair
You are now standing on the chair.

>take key
You can't reach into ShaftTwo.

>open box
You can't reach into ShaftThree.

>Bob, stand on chair
Bob is now standing on the chair.

>Bob, take key
Bob picks up silver key.

>Bob, open box
Bob is unable to do that.

>boost Bob
You're not strong enough.

>eat pill
You feel stronger!

>boost Bob
You allow Bob to climb onto your shoulders.

>Bob, unlock box with key
Bob unlocks the box.

>drop Bob
You set Bob back down on the chair.

>Bob, boost me
Bob allows you to climb onto his shoulders.

>Bob, give me key
Bob gives silver key to you.

>give Bob key
You give silver key to Bob.

>Bob, give me key
Bob gives silver key to you.

>lock box with key
You lock the box.

>unlock box with key
You unlock the box.

>up
You can't reach that exit.

>open box
You open the box.

>take claw
Taken.

>up
You can't reach that exit.

>wear claw
You put on the extensible claw.

>Bob, close box
Bob is unable to do that.

>close box
You close the box.

>open trapdoor
You open the trapdoor.

>take off claw
You take off the extensible claw.

>up
You can't reach that exit.

>wear claw
You put on the extensible claw.

>take off claw
You take off the extensible claw.

>give claw to Bob
You give the extensible claw to Bob.

>Bob, wear claw
Bob puts on the extensible claw.

>up
You can't reach that exit.

>Bob, take off claw
Bob takes off the extensible claw.

>Bob, give me claw
Bob gives the extensible claw to you.

>wear claw
You put on the extensible claw.

>up

Surface
You can see a trapdoor here.

>

Notes:

  • Section 1 in both examples is exactly the same.
  • Those examples include a private extension that defines a bunch of phrases, so they’re not quite fully standalone examples that you can paste in and run. The specific phrases used are shown below (I think that’s all of them):
Auxiliary Phrases Excerpt
To say us or the (culprit - an object):
	if the culprit is the player, say "[us]";
	otherwise say "[the culprit]".

To say We or the (culprit - an object):
	if the culprit is the player, say "[We]";
	otherwise say "[The culprit]".

To say in/on the (table - a supporter):
	say "on [the table]".

To say in/on the (box - a container):
	say "in [the box]".

To say in/on the (T - a thing):
	say "[the T]".

To decide whether (N - a number) is between (min - a number) and (max - a number), exclusive or low exclusive or high exclusive:
	let real-min be min;
	let real-max be max;
	if max < min:
		let real-min be max;
		let real-max be min;
	if exclusive or low exclusive:
		increase real-min by 1;
	if exclusive or high exclusive:
		decrease real-max by 1;
	decide on whether or not real-min <= N and N <= real-max.

Does anyone see anything wrong with either of these approaches?

The room-based one was actually easier than I expected, but it has the downside of exploding the total number of rooms… and I didn’t finish working out how to make descriptions work in a sensible manner (it would need to show all items in the same “area” region).

So I think I still prefer a rulebook-based approach. This new rulebook-based approach works better than the old one though, and seems to be fine for NPCs.

Sooo after some pondering and fiddling around, I came up with another completely different rulebook-based approach. This time, the intent was to leverage the existing reach rules as much as possible. It only took the following three rules in pre-existing rulebooks to make it work:

Reaching inside something (called the barrier) when the barrier is out of range of the person reaching:
	say "It's too high up.";
	deny access.

Reaching across a room (called the locale) when the item reached for is in the locale and the item reached for is out of range of the person reaching:
	say "It's too high up.";
	deny access.

Instead of going through a door (called the portal) when the actor cannot touch the portal:
	do nothing.

(Note: reaching across is a rulebook from the Otistdog’s extension mentioned in the opening post, so it is “pre-existing” in the sense that I didn’t define it myself.)

So instead of having a check reachability rulebook, the access height of objects is determined by a pair of custom rulebooks:

Deciding the access height rules are an object based rulebook producing a number.
Deciding the access range rules are a person based rulebook producing a number.

To decide what number is the/-- access height for/of the/a/an/-- (obj - an object):
	let N be the number produced by the deciding the access height rules for obj;
	decide on N.

To decide what number is the/-- access range for/of the/a/an/-- (who - a person):
	let N be the number produced by the deciding the access range rules for who;
	decide on N.

To decide whether (obj - an object) is in range of (them - a person):
	let end-height be the access height of obj;
	let start-height be the access height of them;
	if start-height is end-height, yes;
	let range be the access range of them;
	let diff be start-height minus end-height;
	if diff >= range, yes;
	no.

To decide whether (obj - an object) is not in range of (them - a person):
	if obj is in range of them, no;
	yes.

To decide whether (obj - an object) is out of range of (them - a person):
	if obj is in range of them, no;
	yes.

TO decide whether (obj - an object) is not out of range of (them - a person):
	if obj is in range of them, yes;
	no.

Deciding the access height of something in a container (called the box):
	rule succeeds with result the access height of the box.

Deciding the access height of something on a supporter (called the shelf):
	rule succeeds with result the access height of the shelf.

Deciding the access height of something carried by someone (called the holder):
	let base height be the access height of the holder;
	if the holder is tall:
		rule succeeds with result base height plus one;
	rule succeeds with result base height.

Deciding the access height of something worn by someone (called the wearer):
	let base height be the access height of the wearer;
	if the wearer is tall:
		rule succeeds with result base height plus one;
	rule succeeds with result base height.

Deciding the access height of someone hoisted by someone (called the helper):
	let base height be the access height of the helper;
	if the helper is tall:
		rule succeeds with result base height plus one;
	rule succeeds with result base height.

Deciding the access height of someone on a booster (called the chair):
	let base height be the access height of the chair;
	if the person reaching is standing:
		rule succeeds with result base height plus one;
	rule succeeds with result base height.

Deciding the access height of someone tall (called the reacher):
	now the reacher is short;
	let base height be the access height of the reacher;
	now the reacher is tall;
	rule succeeds with result base height plus one.

Deciding the access height of someone (called the reacher) who wears the extensible claw when the reacher is the person reaching:
	now the reacher carries the extensible claw;
	let base height be the access height of the reacher;
	now the reacher wears the extensible claw;
	rule succeeds with result base height plus one.

Last deciding the access height of something:
	rule succeeds with result 0.

Deciding the access height of a room:
	rule succeeds with result 0.

Deciding the access range of someone tall:
	rule succeeds with result 1.

Deciding the access range of someone (called the reacher) who wears the extensible claw:
	now the reacher carries the extensible claw;
	let base range be the access range of the reacher;
	now the reacher wears the extensible claw;
	rule succeeds with result base range plus two.

Last deciding the access range of someone:
	rule succeeds with result 0.

I’ve yet to put it to the test outside my little test scenario (the Shaft one), but so far it seems even simpler than the version with the Check reachability rulebook (especially since that version got quite a bit more complicated since I posted a working version in the previous post).

The only downside is that specifying the access height of a fixed object becomes more verbose:

[Before]
The access height of the the narrow ventilation opening is 3.
[After]
Deciding the access height of the narrow ventilation opening:
	rule succeeds with result 3.

Which is kind of unfortunate when it’s a constant value.

You could always give things a numeric property that defaults to -1, then write a general rule that checks and returns that property if it’s not -1 (and makes no decision if it is).

I suppose the way to make a “nullable property” would be with a relation? Technically not a property, but more or less serves the same function.

You could, but I find it’s often easier to just use a property with a sentinel value.

I don’t know if it’s easier or harder than a property with a sentinel value, but this doesn’t look too bad to me:

Access level relates one number to various things.
The verb to be at level means the reversed access level relation.

Last deciding the access height of something (called it):
	if a number relates to it by the access level relation:
		rule succeeds with result the number that relates to it by the access level relation;
	rule succeeds with result 0.

The shelf is at level 2. The box is at level 3.

Too bad I can’t use this on doors, as they want to have a different access level on both sides…

1 Like