The Mysteries of Aaron Reed's Remembering Extension (and a solution)

Hmmm. I see this unexpected problem has also been encountered before in the discussion thread you referenced above.

From what I can make out through experimentation, it’s not possible within an Understand grammar token to have both ‘any’ and a reference to ‘visible/invisible/not visible’ or an adjective defined in terms of one of these, or indeed in terms of the visibility relation- such as ‘if the player can see it’, without causing an overflow.

I wonder if this might have something to do with the confused double-meaning of ‘visible’ in Inform, where in action declarations it means ‘in scope for the actor’ but elsewhere usually has the subtly different meaning of ‘within direct sight of the player’. As I understand it, ‘any’ in this context means ‘whether in scope or not’, so shouldn’t be adversely affected by including it alongside the more restricted meaning of ‘visible’ etc. but…

2 Likes

What about adding:

Instead of remembering something when the actor can see the noun:
	try the actor examining the noun instead.

or the like?

EDIT: Ah, that would only handle the examining action. I’ll try again.

Possibly not in this context, as this is supposed to be a helpful and informative replacement for the ‘You can’t see any such thing’ response when the player refers to objects that have been previously encountered but are now out of scope. Things previously encountered but now in closed containers in the location are enclosed by the location but are nevertheless out-of-scope and will still trigger ‘You can’t see any such thing’, whereas ideally we really want to include them in the ‘Remembering’ action to trigger the response (for example) ‘You look around but don’t see the golden sword. Last you remember it was in the treasure chest.’

1 Like

So given the caveats and the tradeoffs:

  • You must innumerate every verb grammar you want Remembering to apply to
  • It doesn’t work with multiple objects
  • There are unresolved problems with the grammar around seen and visible

This begs the question: Is there a more elegant way to hook in the basic functions of this extension without hijacking the action? Rather hijacking the parser’s “rule for printing a parser error when the latest parser error is the can’t see any such thing error”?

Or is this a fine way but needs a little reworking?

So originally, I didn’t care about the last remembered location. That was just a nice extra feature that fit well into my game world. I just was just trying to solve this problem:

> x grandpa
You don’t see that anywhere around here.

“That?” Grandpa is “that?” I just wanted to make the error message pronoun-aware and stumbled into a larger can of worms.

Just for fun, here’s another approach.

Leave out the Remembering extension and just include Epistemology and proceed as follows:

Include Epistemology by Eric Eve.

Definition: A thing is absent if it is seen and it is not enclosed by the location of the player.

After deciding the scope of the player:
	repeat with item running through absent things:
		place item in scope.

Before doing something to an absent thing:
	say "You can't see [the noun] here." instead.
	
The Field is a room.

The pail is in the Field. The description of the pail is "A standard wooden pail."

Grandpa is a man in the Field.

The Forest is north of the Field.

The log is in the Forest. The description of the log is "It's a log."

This does seem to work for the immediate use case, and the nice thing is that Inform knows the noun at that stage, so we can print “[the noun]”, which correctly gives us “You can't see Grandpa here” and so on.

But caveats apply:

  • I haven’t tested it extensively
  • It seems a bit hacky and inefficient, and slightly absurd, because we basically add every (absent) thing to the scope just for the explicit purpose of saying that the player can not actually do anything with it. :thinking: :slightly_smiling_face:

Hm. I’m actually considering a variation of the Cave Troll example. If it can’t find a matching thing, set flag, reparse with a rule bringing everything in the world into scope but not allowing reach, and tweak the “can’t reach” error message.

That ought to reduce overhead, at least. Whether it is performant is another question, of course.

This seems to work, although I haven’t tested it fully to destruction:

"Recovered Memory" by PB

Book - Example of Remembering by Aaron Reed tweaked to work with 6M62

Chapter - Stage and Props

Lab is a room.
The workbench is here. The sideboard is here. The CD box is a closed opaque openable container. It is on the workbench. The Hotel California CD is in the box. The knife, the fork, the apple, the salad server and the cruets are things on the sideboard. The cruets are plural-named. The thingumajig is nowhere. In the Lab is a person called Mr Darcy. Darcy is proper-named. Mr Darcy wears a blue frock coat. The initial appearance of Mr Darcy is "Mr Darcy haughtily haunts the hall in a blue frock coat."
Dispensary is north of Lab. The blue medicine is in the Dispensary.


Chapter - Remembering

Section - Defining Absence
	
Out_of_scope is a list of objects that varies.

After reading a command when the reading a command activity is going on:
	now Out_of_scope is the list of invisible objects.
[this list is used later to define absent objects without inducing recursion by use of 'any visible' or similar in the 'Understand grammar tokens]
['when the reading a command activity is going on' is required to avoid the rule firing after disambiguation questions]

Definition: an object is absent rather than present if it is listed in Out_of_scope and it is seen.

Rule for deciding whether all includes an absent thing when remembering (this is the block all including absent things when remembering rule): it does not. 

Chapter - Inclusion

Include Remembering by Aaron Reed.

Section - Remove Avoiding Disambiguation (in place of Section - Avoiding Disambiguation in Remembering by Aaron Reed)

To placehold:
	do nothing.
[this was buggy already, and made worse by 6M62, so removed.  Probably wasn't a good idea anyway IMHO]
	
Section - New Grammar Line (in place of Section - Grammar Line in Remembering by Aaron Reed) 

Understand
"examine [any absent thing]" or
"x [any absent thing]" or
"look at/for [any absent thing]" or
"take [any absent thing]" or
"get [any absent thing]" or
"pick up [any absent thing]" or
"pick [any absent thing] up" or
"drop [any absent thing]" or
"put down [any absent thing]" or
"put [any absent thing] down" or
"drop [any absent thing] away" or
"drop away [any absent thing]" or
"find [any absent thing]" or
"where is/are [any absent thing]" as remembering.

[ [any absent thing] catches any thing out of the player's scope, but since these grammar lines take precedence over the originals, we re-declaring them as applying to [something present] so that if the player refers to an ambiguous noun (in this example e.g. 'examine cd') the action applying to the object in scope will take precedence, rather than remembering the object that is absent.]
Understand "examine [something present]" or "x [something present]" or "look at [something present]"as examining.
Understand "take [something present]" or  "get [something present]" or "pick up [something present]" or "pick [something present] up" as taking.
Understand "drop [something present]" or "put down [something present]" or "put [something present] down" or "drop [something present] away" or "drop  away [something present]" as dropping.

Chapter - Testing

test exam with "open box / take cd / hotel / n / drop cd / x cd / take cd"

test me with "x medicine / x cd / open box / x cd / hotel / close box / x cd / n / where is Darcy / where is cd / box / look for thingumajig / take all / take all / drop all / where are cruets / find blue / look for blue / look at blue / s / take medicine / take all"
2 Likes

I think the following covers your intended cases, and it’s not difficult to add in the functionality to indicate where something was last seen.

Unavailable Things
"Unavailable Things"

[Doesn't use Remembering because you said your actual goal was simpler.]
Include Epistemology by Eric Eve. [for "seen"]

Place is a room.

Other Place is east of Place.

A red ball is in Place.

An open openable container called a box is in Place.

A blue ball is in Other Place.

[An alternative to scope testing via direct object tree inspection]
To decide whether (X - thing) has line of sight to (Y - thing):
	let CA be the common ancestor of X with Y;
	if CA is nothing, decide no;
	let checked be an object;
	now checked is X;
	while checked is not CA:
		now checked is the holder of checked;
		if checked is a closed opaque container, decide no;
	now checked is Y;
	while checked is not CA:
		now checked is the holder of checked;
		if checked is a closed opaque container, decide no;
	decide yes.

To decide whether (X - thing) does not have line of sight to (Y - thing):
	if X has line of sight to Y:
		decide no;
	otherwise:
		decide yes.

Definition: a thing is unavailable if it is seen and the player does not have line of sight to it.

After deciding the scope of the player:
	repeat with X running through unavailable things:
		place X in scope.

[Uses before rules to intervene ahead of visibility checks]
Before doing something when the noun is unavailable:
	say "[The noun] [are] nowhere to be seen." instead.

Before doing something when the second noun is unavailable:
	say "[The second noun] [are] nowhere to be seen." instead.

test me with "x red ball / x blue ball / e / x red ball  / x blue ball / w / put red ball in box / x red ball / close box / get red ball / open box / get ball / e / put red ball in box".

which yields:

Place
You can see a red ball and a box (empty) here.

>test me
(Testing.)

>[1] x red ball
You see nothing special about the red ball.

>[2] x blue ball
You can't see any such thing.

>[3] e

Other Place
You can see a blue ball here.

>[4] x red ball
The red ball is nowhere to be seen.

>[5] x blue ball
You see nothing special about the blue ball.

>[6] w

Place
You can see a red ball and a box (empty) here.

>[7] put red ball in box
(first taking the red ball)
You put the red ball into the box.

>[8] x red ball
You see nothing special about the red ball.

>[9] close box
You close the box.

>[10] get red ball
The red ball is nowhere to be seen.

>[11] open box
You open the box, revealing a red ball.

>[12] get ball
(the red ball)
Taken.

>[13] e

Other Place
You can see a blue ball here.

>[14] put red ball in box
The box is nowhere to be seen.

Why did you have to use this rather than a simple test for visibility?

It looks like this won’t intervene if the noun is not recognized which is fine for my purposes.

I appreciate that you use the before rules which could replace the broken and limited new remembering action in Aaron’s Remembering.

Do you see any performance issues with it, or likely conflicts with other extensions?

The ideas of “in scope” and “actor can see it” (visibility) are intertwined in the Inform worldview in a way that can cause issues like the stack overflows that the other people reported. (I still don’t fully understand the details. Someone else might chip in to the benefit of us both.) The “has line of sight” phrase directly inspects the world model for the relevant aspects of visiblity without involving questions of scope.

Note that the phrase can be rewritten in a much more Inform 7-appropriate style as:

To decide whether (X - thing) has line of sight to (Y - thing):
    if the common ancestor of X with Y is nothing, decide no;
    if Y is enclosed by a closed opaque container that does not enclose X, decide no;
    if X is enclosed by a closed opaque container that does not enclose Y, decide no;
    decide yes.

Since the definition of “unavailable” is relatively limited, and since it can only apply to things (and should therefore be ignored for directions or in cases where the noun or second noun is nothing), I wouldn’t expect any interference to pop up. I could be wrong; testing was cursory.

The I7-style version may be a bit more computationally-intensive, but I would expect either version to be relatively quick in most cases. In a large game, there is the hit of adding all unavailable items to scope for every command, but I don’t think that can be avoided given the functionality that you’re looking to get.

1 Like

Coming in late to this conversation. I expect the new issues are to do with the various Inform upgrades since I touched this: I’m pretty sure it worked as expected circa 2012 or whenever. I did avoid using “visible” intentionally for the reason Peter Sjölund intuited above: I didn’t want “remember” to kick in for an object in a closed satchel you were carrying or while in a dark room or whatever. Also I seem to recall “visible” checks were slower on very large games at the time (this may no longer be true) which made a noticeable difference to the runtime speed of Blue Lacuna.

I don’t remember the specific reason for the long list of actions, other than there was some reason I couldn’t just do “anything except x,” and also I didn’t really care if it was definitive or not: I just wanted it to catch several of the most common ways you might try to interact with something not present.

Sorry not to have any more helpful advice-- in a world with 28 hour days I would really love to go back and bring all my old extensions up to date!

2 Likes

As I suspect you’ve noticed, the I7 documentation avoids detailed discussion of scope, referring interested writers to the I6 DM4 documentation, which at least implies that the definition hasn’t changed between I6 and I7. The DM4 has this to say:

Time to say what "in scope’’ means. This definition is one of the
most important rules of play, because it decides what the player
is allowed to refer to. You can investigate this experimentally by
compiling any game with the debugging suite of verbs included (see
§7) and typing "scope’’ in interesting places.

"In scope’’ roughly means "the compass directions, what you’re carrying and what you can see’'.

It exactly means this:

(1) the compass directions;
(2) the player’s immediate possessions;
(3) if there is light, then the contents of the player’s visibility ceiling (see §21 for
definition, but roughly speaking the outermost object containing the player which
remains visible, which is usually the player’s location);
(4) if there is darkness, then the contents of the library’s object thedark (by default
there are no such contents, but some designers have been known to move objects
into thedark: see `Ruins’);
(5) if the player is inside a container, then that container;
(6) if O is in scope and is see-through (see §21), then the contents of O;
(7) if O is in scope, then any object which it "adds to scope’’ (see below).

with the proviso that the InScope entry point (see below) can add to or replace
these rules, if you write one.

It’s significant that rule (3) doesn’t just say "whatever is in the current
location’'. For instance, if the player is in a closed cupboard in the Stores
Room, then rule (3) means that the contents of the cupboard are in scope, but
other items in the Stores Room are not.
Even in darkness the player’s possessions are in scope, so the player can
still turn on a lamp being carried. On the other hand, a player who puts the
lamp on the ground and turns it off then loses the ability to turn it back on
again, because it is out of scope. This can be changed; see below.

Compass directions make sense as things as well as directions, and they respond
to names like "the south wall’’ and "the floor’’ as well as "south’’ and "down’'.

  • The concealed attribute only hides objects from room descriptions, and doesn’t
    remove them from scope. If you want things to be unreferrable-to, put them somewhere
    else!

  • The small print:

  1. For "player’‘, read "actor’‘. Thus "dwarf, drop sword’’ will be accepted if the dwarf can see the sword even if the player can’t.
  2. Scope varies depending on the token being parsed: for the [multi-] tokens, compass directions are not in scope; for [multiexcept] the other object isn’t in scope; for [multiinside] only the contents of the other object are in scope.

Some further notes expanding on scope in the context of I7:

  • Rule (1) is hard-coded outside of the main scoping system, such that testing directions such as ‘North’ for being in scope (using the I6 routine TestScope) anomalously returns false unless they are manually added to scope, e.g. ‘Place North in scope’ in an ‘After deciding the scope’ rule.

  • Regions and Rooms, including the current location, are never ‘visible’ and are in scope only if manually added to scope in an ‘After deciding the scope’ rule. Placing a Region in scope does not bring rooms or anything else in that region into scope.

  • Doors and Backdrops in the location are both ‘visible’ and in scope when there is light (unless the player is in an opaque, closed container), but neither when in darkness.

  • Objects placed in scope (directly- or indirectly such as the contents of a room placed in scope) with the phrase ‘place (object) in scope’ in an ‘After deciding the scope’ rule do not become ‘visible’ as a result.

  • A combination of Rules (2) & (6) leads to a bug which remains uncorrected- the contents of a carried closed transparent container (e.g. a starfish in a closed jam-jar) is no longer ‘visible’ but remains in scope when in darkness.

  • For characters other than the player, objects that are not possessions can remain in scope even in darkness. Thus, although ‘take the sword’ will fail, ‘dwarf, take the sword’ followed by ‘dwarf give me the sword’ will succeed if player, dwarf and sword are together in a dark room- as long as the dwarf is placed in scope to be spoken to and the rule that usually blocks giving of things is disabled! ‘If the dwarf can see the sword’ is false, however. This also feels like a bug.

  • When in darkness, Rule (4) suggests that the contents of the I6 object ‘thedark’ are in scope. Its I7 equivalent name is ‘(darkness object)’ (brackets included) but this object is not generally accessible when writing in I7. Should the author finesse this by making an I7 variable equivalent to the I6 object “thedark”, or through other hackery, it turns out that in I7 objects in the dark are considered ‘off-stage’ so remain out of scope unless deliberately ‘placed in scope’.

  • The closest functional I7 equivalent of the I6 property ‘add_to_scope’ referenced here is the incorporation relation (‘is a part of’) - although differently implemented.

  • The I6 ‘concealed’ attribute is equivalent to the better-named I7 ‘undescribed’ property, not the concealment relation. A concealed item is not ‘visible’ or in scope, but an undescribed item is both ‘visible’ and in scope.

  • Some of the same I6 routines are used in determining both scope and visibility, which is why it’s easy to get tangled in recursive stack overflows if both are mentioned in the same condition or rule.

  • As noted above, there is a large overlap between ‘visible’ and ‘in scope’ but there are exceptions where objects in scope are not visible:

    1. objects directly or indirectly brought into scope by 'Place (object) in scope’.
    2. when in darkness, the player and objects enclosed by the player (unless the enclosed objects are in a closed, opaque container, in which case they’re both out of scope and invisible.)
    3. when in darkness and in an enterable container, the container.
    4. directions- which are peculiar in not being visible but always treated as being in scope even though they don’t ordinarily test as such.
    5. when grammar tokens prefaced by ‘any’ are being considered (e.g. ‘Understand “Go to/-- [any room]” as routegoing’ then all objects matching the description are brought into scope, overriding the usual scoping rules.
  • Conversely, when certain grammar tokens (as noted above) are being considered, some ‘visible’ objects may be excluded from scope.

  • As in I6, you can test for the current scope when playing an (unreleased) I7 story by typing ‘scope’. (The list produced of ‘in scope’ objects does not include the compass directions.)

  • I7 does not call or compile an I6 InScope() routine.

1 Like

No. The I7 equivalent of add_to_scope is the “place (obj) in scope” phrase described in 18.29. There is no I6 equivalent of the incorporation relation.

Well, I guess I’m overstating it, but functionally I understood it as how to get a similar effect to incorporation in I6 as far as scoping goes, being an object-oriented feature. ‘Place (obj) in scope’ is rule-oriented and not conducive to adding an object to scope when another object is in scope (and calls I6 PlaceInScope(obj) not AddToScope(obj)) so perhaps it’s not really equivalent either?

So we have all the pieces here if some ambitious person wants to update Aaron’s Remembering extension:

Chapter - New Can't See That Report

[
	Remembering last seen locations

	From Aaron Reed's remembering

	Replaces 'You can't see any such thing' for a seen but out-of-scope 
        noun with a message acknowledging that the parser recognizes the 
        object.
]

Every thing has an object called the remembered location.
	The remembered location of a thing is usually nothing.

Last when play begins (this is the Remembering update remembered positions for first turn rule):
	follow the Remembering update remembered positions of things rule.

Every turn (this is the Remembering update remembered positions of things rule):
	unless in darkness:
		repeat with item running through things that are enclosed by the location:
			if remembered location of item is not holder of item:
				if item is visible:
					now the remembered location of item is the holder of item.

To decide whether (item - an object) acts plural:
	if the item is plural-named or the item is ambiguously plural:
		yes;
	no.

To say was-were of (N - an object):
	if the story tense is future tense:
		say "will have been";
	otherwise if N acts plural:
		say "were";
	otherwise:
		say "was".

To say at the (place - an object):
	carry out the saying the location name activity with place.

saying the location name of something is an activity on objects.

For saying the location name of a room (called place) (this is the Remembering saying room name rule): say "at '[the place]'" (A).
For saying the location name of the location (this is the Remembering saying current location name rule): say "right here" (A).
For saying the location name of a person (called subject) (this is the Remembering saying person name rule): say "in the possession of [the subject]" (A).
For saying the location name of a person who is the player (this is the Remembering saying player name rule): say "in your possession" (A).
For saying the location name of a container (called the holder) (this is the Remembering saying container name rule): say "in [the holder]" (A).
For saying the location name of a supporter (called the holder) (this is the Remembering saying supporter name rule): say "on [the holder]" (A).

[
	my mods to remembering
]

A room has some text called casual_name.

The Remembering saying room name rule response (A) is "[the casual_name of the place]".

[
	Deciding scope and Reporting

	Courtesy of @otistdog https://intfiction.org/t/remembering-mysteries/49840/15?u=wmodes
]

[An alternative to scope testing via direct object tree inspection]
To decide whether (X - thing) has line of sight to (Y - thing):
    if the common ancestor of X with Y is nothing, decide no;
    if Y is enclosed by a closed opaque container that does not enclose X, decide no;
    if X is enclosed by a closed opaque container that does not enclose Y, decide no;
    decide yes.

To decide whether (X - thing) does not have line of sight to (Y - thing):
	if X has line of sight to Y:
		decide no;
	otherwise:
		decide yes.

Definition: a thing is unavailable if it is seen and the player does not have line of sight to it.

After deciding the scope of the player:
	repeat with X running through unavailable things:
		place X in scope.

[Uses before rules to intervene ahead of visibility checks]
Before doing something when the noun is unavailable:
	[say "[The noun] [are] nowhere to be seen." instead.]
	say "You look around, but don't see [the noun]. Last you remember, [they] [was-were of noun] [at the remembered location of noun].[line break]" instead.

Before doing something when the second noun is unavailable:
	[say "[The second noun] [are] nowhere to be seen." instead.]
	say "You look around, but don't see [the second noun]. Last you remember, [they] [was-were of noun] [at the remembered location of noun].[line break]" instead.

It could be improved. For instance, a check to make sure casual_name is defined could/should be added if you use it.

It works for me:

> drop train penny
Dropped.

> x coin
The train rolled over your penny and turned it into a flattened oval.

> x grandpa
You can’t see any such thing.

> x bucket
You can’t see any such thing.

> d
Grassy Clearing
This is a pleasant clearing carpeted with stubbly grass under a sycamore tree.

You see your grandpa and the big bucket here.

> x grandpa
Grandpa is, well, Grandpa.

> x bucket
There’s a big bucket that Honey and Grandpa have been putting their berries into, about half full now.

> give coin to grandpa
You look around, but don’t see the flattened train penny… Last you remember, it was lost in the brambles.

> d
Blackberry Tangle
There are paths through the brambles, a maze with tantalizing fruit.

> say hello to grandpa
You look around, but don’t see Grandpa. Last you remember, he was at the grassy clearing.

> x bucket
You look around, but don’t see the big bucket. Last you remember, it was at the grassy clearing

> i
You are carrying your pail.

> x pail
This is a purple pail with a yellow handle.

> x me
What’s to say? You are eight and a half, and you are going into 4th grade in the fall.

Thanks for all the help and great discussion.

1 Like

I know neither of these are yet published extensions and that the topic is marked as solved, but I’ve found a problem with OtisTDog’s Unavailable Things.

If you have two objects with similar names and one of them is in a container, Inform will try to disambiguate between the two even when one is now off-stage.

"Test 2" by "J. J. Guest" 

Include Epistemology by Eric Eve.

Chapter 1 - Room

Storeroom is a room. The description is "You are in a storeroom."

A pink ball is in the storeroom. The description of the pink ball is "It's pink."

A wooden box is an openable closed container in the storeroom.

Casting plugh is an action applying to one visible thing.
Understand "plugh [something]" as casting plugh.

Carry out casting plugh:
	say "[The noun] disappears in a puff of smoke.";
	now the noun is nowhere.
	
A blue ball is in the wooden box. The description of the blue ball is "It's blue."

The result of this is:

Test 2
An Interactive Fiction by J. J. Guest
Release 1 / Serial number 210929 / Inform 7 build 6M62 (I6/v6.33 lib 6/12N) SD

Storeroom
You are in a storeroom.

You can see a pink ball and a wooden box (closed) here.

>x ball
It's pink.

>plugh ball
The pink ball disappears in a puff of smoke.

>open box
You open the wooden box, revealing a blue ball.

>x ball
Which do you mean, the blue ball or the pink ball?

>get blue
Taken.

>x ball
(the blue ball)
It's blue.

>drop ball
(the blue ball)
Dropped.

>get ball
(the blue ball)
Taken.

>put ball in box
(the blue ball in the wooden box)
You put the blue ball into the wooden box.

>x ball
Which do you mean, the blue ball or the pink ball?

>

@J_J_Guest, As you’ve gathered, this wasn’t a formally published extension so much as a suggestion to help get the desired effect.

The issue can be partially addressed by adding:

Does the player mean doing something when the noun is unavailable:
    it is very unlikely.

Does the player mean doing something when the second noun is unavailable:
    it is very unlikely.

However, this leaves constant disambiguation messages like:

>X BALL
(the blue ball)

even when the blue ball is the only one in the player’s presence, and also the inclusion of unavailable things in disambiguation questions, such as (assuming that there is also a yellow ball in the open box after removing the pink ball from play):

>X BALL
Which do you mean, the blue ball, the yellow ball or the pink ball?

in which the pink ball arguably doesn’t belong. Those are deeper problems.

1 Like

The Capgras Syndrome extension by Fusiform Gyrus is known to cause this behavior.

This intertwining between “in scope”, “actor can see it”, and “object is lit” was the most painful part of writing Wear Gloves. I doubt too many players ever try to reach through a closed dark container from inside of a different closed dark container, but I got it to work!

There’s the heart of an advanced visibility extension in there somewhere.

2 Likes

I’ve meant to mention that there is a current Friends of I7 repo extension with working Remembering functionality: Expanded Understanding by @xavid (as one part of a very broad extension).

It takes the interesting tack of not putting all the remembered things into scope every turn; instead it hooks into printing a parser error when the latest parser error is the can't see any such thing error.

3 Likes