Add to scope

maybe a dumb question, but why doesn’t this work?

(on every tick)
               *(animate $NPC)
                (the $NPC)(line)
                (add $NPC to scope)

the intent is to keep all NPCs in scope in order to implement the ability to see if an NPC is in the next room, or to follow an NPC who left the room.

the above outputs all the animate objects but, afterward, they still don’t seem to be in scope (can’t ‘examine’ or "talk to’ if not in the room, for instance).

never mind, figured it out.

(add *(animate $) to scope)

in a separate rule head.

Your (add $NPC to scope) searches for predicates defined in your code to check if the object is in scope. It does not add the object to the scope. If you want to add an object to scope define this:

(animate *)
(add * to scope)

If you want to add all animate objects to scope you can define this predicate:

(add *(animate $) to scope)

And lastly, your code outputs all the animate objects, because you have not defined (add $ to scope) for your NPC’s yet. So the last query fails and backtracks to the multiquery for the next NPC.

If you want to add something to the scope under certain conditions, just insert the conditions in the defined predicate:

(add *(animate $Obj) to scope)
	~($Obj is nowhere)

Edit: You figured it out yourself, just before I posted. Oh well.
Edit 2: Typo.
Edit 3: Added the multiquery in the first trait example.


so i’ve added all the NPCs to scope. i can examine, them, for instance when they’re not in the room.

but now i can’t seem to create a new action with these newly-in-scope NPCs.

(grammar [xyzxyz [any animate]] for [xyzxyz $])
(perform [xyzxyz $NPC])
                do something here with the NPC...

if i type “xyzxyz marylou”
the output is still “marylou isn’t here.”

By default all actions will be refused if the object is unreachable, due to this rule in the library:

(refuse $Action)
	*($Obj is one of $Action)
	(object $Obj)
	~(direction $Obj)
	~(relation $Obj)
		(when $Obj is not here)
		(or) (when $Obj is out of reach)

To counteract this you can inspect the [examine $] action in the library, specifically this:

~(refuse [examine $]) %% No need for reachability.

So you need:

~(refuse [xyzxyz $]) %% No need for reachability.

Edit: Typo.

thanks so much, that did the trick.

Be aware that there is a bug in the library with (add $ to scope). Actions that accept all/everything will try to repeat the actions twice for all the objects that are both reachable and have an (add $ to scope) rule for them. To get rid of the multiple actions, the following rule needs to be fixed with this:

(parse basic noun [all/everything] as $Result (nonempty $Policy) 1)
	(collect $Obj)
		*($Obj is in scope)
		~(excluded from all $Obj)
		~($Obj is hidden)
		(verify object policy $Policy $Obj)
	(into $ResultWithDup)
	(remove duplicates $ResultWithDup $Result)