In this demo, you can stand upstairs on the balcony and examine the cat. An ‘understand as…when visible’ phrase lets you call the cat ‘animal’ if it’s visible, but if you use ‘animal’ when the cat’s not in the room, the game freezes.
Doing the ‘test me’ is kind of pointless as it just stops immediately without showing you the commands.
Go down, then ‘examine animal’, then up, then ‘examine cat’, then ‘examine animal’ - then it stops.
There is a room called balcony. downstairs is down from balcony.
the cat is an animal in downstairs.
Understand “animal” as cat when cat is visible.
After deciding the scope of the player when location is balcony:
place cat in scope.
The game goes into an infinite loop, placing the cat in scope again and again. I don’t know exactly how the parsing mechanism works, but it’s probably tightly coupled with the scope checking mechanism so things like this can confuse it.
Saying “Understand … as X when X is visible” is redundant anyway, because understand phrases apply only to things in scope. I can’t think of a situation where you’d need to “limit” the understand phrase to only visible things.
I think scope is designed for placing a room in scope, the objects in that room. When I was using scope in a game, I could not place an object in scope unless it was in a room. I had to create a hidden room I called “imagination” then placed that room in scope.
If that’s not correct it may be true that scope is buggy.
I think the infinite loop is a bug. You’re doing a scope search (“the cat is visible”) inside a parsing routine, which is called from inside another scope search (the parser looking for objects to match “x animal”). I expect that to be inefficient, but not to hang.
However, as Juhana said, there’s no reason to use the “cat is visible” test there, so just delete it.
I gave this example because actually editing out the part of my game that causes this was too hard. But I have a reason to use this construction.
Say there are cats and dogs running all over the place. They’ve all got names. Then you climb to a vantage point, a room which places animals from all over the game in scope.
I had code saying ‘understand ‘animal’ as jonesy (a cat) when jonesy is in location’ - so that ‘animal’ would only act on jonesy if jonesy was present. I need this because I’ve got actions that work on people that are out of scope as well, and I was trying to eradicate disambiguation. Typing ‘(out-of-scopecommand animal)’ would otherwise bring up disambiguation of all animals in the game.
If I’m at my vantage point where I can see tons of animals, all the cats or dogs are in scope, but none are in the room, so ‘x animal’ says ‘you can’t see any such thing.’ That’s why I tried adding the ‘visible’.
After all that mucking around, I’m still stuck with my initial problem — I want to allow some commands to refer to out of scope creatures, but not if you haven’t met those creatures yet. Otherwise you can type (outofscopecommand cat) and get a free list of all cats in the game as it says ‘do you mean jonesy or tommy or?..’. This is bloody hard to eradicate, because inform does this before it looks at any code of mine.
A cat is a kind of animal. A cat can be met or unmet. A cat is usually unmet. A cat is usually proper-named. Understand "cat" as a cat when the item described is met.
When play begins: now all visible cats are met.
Every turn: now all visible cats are met.
Calling is an action applying to one visible thing. Understand "call [any cat]" as calling.
Report calling: say "[Noun] is a cat and ignores you."
[UPDATE: Added the “when play begins” rule, so that cats visible when play begins will be met for the first turn (and thereafter, even if you move away on the first turn).]
Sounds like the easiest solution would be to use the Epistemology extension to track which cats the player has met. (This is the exact same problem that any conversation system that uses things as topics faces, so you might want to look at some conversation extensions and see how they solve it.)
Thanks. When matt posted his reply, I’d started a solution involving tagging people like he posted. His worked by letting everyone be tagged, and letting the command refer to everyone. I had already split my commands up to refer to the tagged, the untagged and folks in the room with you. I had a lot of inveigling to do because I have a bunch of commands with tricky physical requirements (and I’d be describing my whole game if I went into it all), but I got there in the end.
I was offline last week and got behind, so I just noticed this post. Curiously, I had exactly the same problem in my WIP, and came up with a totally different solution.
This is thanks to Zarf, who explained how to do it several months ago. I’ve wrapped up the solution into an extension called “Scope Caching.” Normally, Inform runs the entire scope loop for every single object each time one scope test is made. Scope Caching just does it once at the beginning of a turn and then saves the result in a property called “marked visible.”
I just posted a thread about it, which includes an example that should solve the OP’s problem. Please comment:
Speaking of Epistemology, would Eric like to make use of Scope Caching in future versions…?
[code][ It might seem more straightforward simply to write “Now everything visible in the location is seen.” but
this turns out to be unacceptably slow in practice. The following code does approximately the same thing
but much faster.]
Carry out looking (this is the mark items as seen when looking rule):
unless in darkness begin;
repeat with item running through things that are enclosed by the location begin;
if the item is not enclosed by an opaque closed container, now the item is seen;
Carry out opening a container (this is the mark items as seen on opening a container rule):
repeat with item running through things that are enclosed by the noun begin;
if the item is unseen and the item is visible, now the item is seen;
The mark items as seen on opening a container rule is listed after the standard opening rule in the carry out opening rules.
I think this whole section could be replaced with:
[code]After reading a command (this is the mark visible items as seen rule):
Now every marked visible item is seen;
The mark visible items as seen rule is listed after the cache scope after reading a command rule in the after reading a command rulebook.[/code]
…although there may be some extra fiddling needed when objects are revealed during multiple actions - I think that may already be true.
I’m wondering if anyone can tell me whether it’s redundant to add the “marked as seen” rules to the looking and opening rules in addition to the “after reading a command” rules. Are there cases where after reading a command would miss that?