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

I started using aaronius’s Remembering and it works great for anything I’ve seen but is not visible:

Include Remembering by Aaron Reed.

The Remembering specific report remembering rule response (A) is 
"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]".

For example:

> x grandpa
You look around, but don’t see Grandpa. Last you remember, he was at “Grassy Clearing”

However, some mysteries have emerged.

Mystery One

Visible things also trigger the replaced parser error:

> i
You are carrying your pail.

> x pail
You look around, but don’t see your pail. Last you remember, it was in the possession of yourself.

> x me
You look around, but don’t see yourself. Last you remember, you was right here.

> x sky
You can’t see the sunlight any more

I looked through the source and the required Eric Eve’s Epistemology to see if there were any obvious properties that were in conflict with my code. Didn’t see any.

I included Epistemology without Remembering, and everything worked as expected, so concluded it wasn’t something in Epistemology.

In Aaron’s source, I see that remembering applies to any [seen thing]. Does Eric’s Epistemology exclude visual things from “seen things?” It doesn’t look like it:

> showme pail
your pail - open container
bunch of ripe berries
location: carried by yourself in Blackberry Tangle
singular-named, proper-named; unlit, inedible, portable, handled, seen, familiar, floating, unclimbable, dry; opaque, open, unopenable, unlocked

And if not, is that why remembering is being triggered by anything including things that are visible?

Did these two extensions fall out of sync or change? Any idea on a work-around?

Mystery Two

Verbs other than the ones Aaron has called out don’t trigger the Remembering error text:

> talk to grandpa
You can’t see any such thing.

Do I just need to hack Aaron’s Remembering understand statement?

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

The above “understand” statement from Remembering seems awkward. If you have various actions that one has created, one would have to hack in quite a few actions. Kissing, thanking, throwing, yelling at, etc. along with all their verbal variations. And some of those take multiple nouns.

Is there a more elegant way to hijack the parser’s “rule for printing a parser error when the latest parser error is the can’t see any such thing error” without enumerating every single possible verb here?

(Should this question be under Extensions>Development or somewhere else?)

2 Likes

This is, like, actually really deep.

10 Likes

I just see no visibility testing (in Inform’s technical sense) in ‘Remembering’.

Although its instructions say…

“We do this with a new internal verb, “to remember,” which is triggered by any attempt to examine, take, or drop a “seen” but not visible (my emphasis) noun. (“Seen” is defined in the required Epistemology by Eric Eve extension.)”…

…Seen as defined in Epistemology is an on/off variable that’s set once you’ve seen something.

The grammar lines in Remembering fire on all ‘seen’ things, and once you’ve seen something, it stays seen. You see yourself in turn one of the game, so attempts to X ME will go to the remembering action forever more, etc.

I doubt Epistemology ever tracked visibility dynamically in figuring the ‘seen’ flags in any past version, though it could have. So, could it just be an oversight in Remembering? Seems unlikely this one would have slipped by, though.

Remembering didn’t seem to work when I tried it in a vanilla z8 project, either. It would claim you couldn’t see something anymore even if it was in the room.

-Wade

1 Like

Since the Remembering extension is from 2014-04-30, it’s from before I7 6L02 (three versions ago), so it’s possible that it has fallen out of sync with I7 as well as with Epistemology (it references v6, but the current version is 9).

Here’s one workaround for Mystery One; we want to consider only objects which were once seen but are not present at the moment, so we include this in our source:

Section - New Grammar Line (in place of Section - Grammar Line in Remembering by Aaron Reed) 

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

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.

There are probably more elegant ways, which also address the other mysteries, but maybe it helps or can serve as a starting point. :slightly_smiling_face:

Edited to add two remarks:

  • for cross-reference, the problem was reported before (but apparently not solved): Remembering by Aaron Reed

  • test everything thoroughly, because the devil is in the details, as always… for example, I just found out that >TAKE ALL can result in problems, because if that action tries to take something, but then “remembers” it, it won’t continue taking the objects that are actually there:

Better might be:

Definition: A thing is absent if it is seen and it is not visible.
1 Like

Hmmm, that results in an error for me (in the built-in interpreter in the Windows IDE):

Glulxe fatal error: Stack overflow in store operand.

Also, it makes kind of sense that things are not absent even if it is dark or they are in a closed opaque container in the current room.

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!

3 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. Conversely, for characters other than the player doors and backdrops are visible (in the light) and in scope only if their current location happens to coincide with that of the non-player character.

  • 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.

  • Interestingly, a combination of rules (5) & (6) does not lead to a similar anomaly- a player in a transparent shower cubicle will be unable to find the soap if the bathroom light is switched off, even though they can open or close the cubicle.

  • Rule (6) refers only to the direct contents of (O)- so anything enclosed by an opaque, closed container that is in (O) will, as might be expected, be out of scope.

  • 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, particularly as it seems a contradiction to small print 1. in that it seemingly doesn’t matter whether the dwarf can see the sword.

  • 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. An item which is concealed via the I7 concealment relation is not ‘visible’ or in scope, but an undescribed item is both ‘visible’ and in scope. An exception is immediate possessions that the player conceals, which (following rule (2)) are nevertheless in scope- but anything they themselves conceal and the contents thereof are not (i.e. rule (6) is overridden). This last point reflects a more general rule that objects enclosed by concealed objects are also out of 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.
    6. in the case of characters other than the player who are in darkness, things which would be in scope for that character in the light.
  • 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.