The fundamental problem:
>X ALICE
You see no alice here.
I’ve previously implemented a number of partial fixes to this in a couple of places. I was in the process of re-factoring one of them to use with the memoryEngine
module I’m working on and discovered a couple of corner-cases that needed fixes. That resulted in a bunch of digging through parser internals, and that in turn produced enough stuff that I think it probably should be a standalone module.
The Problem
The basic problem with the just-fiddle-with-the-scope fixes I’d used previously is that the underlying behavior (outputting the generic “You see no [typed word] here” failure message) comes from more than one place in the code. I.e.:
>x alice
You see no alice here.
>alice, take pebble
You see no alice here.
>give pebble to alice
You see no alice here.
In the first case the message is coming from noun resolution by a resolved Action
instance, in the second case it’s coming from ActorResolveResults
(via the parser’s exception handler) when actor resolution fails in the parser’s inner loop, and in the last case it’s in the completely separate noun resolution logic in TIAction
.
A Solution
The approach I settled on here is to wrap the message (on in this case playerMessages
).
The method takes the noun phrase the parser didn’t like, creates a new command with it as the only noun phrase, tokenizes, parses, and resolves the action for it, then marks the Action
instance with a flag that puts all Person
objects in scope, and then attempts noun resolution. If noun resolution succeeds, it’s checked if there’s exactly one direct object and that it is a Person
. If so, we output our bespoke failure messages:
>x alice
There isn't anyone named Alice here.
>alice, take pebble
There isn't anyone named Alice here.
>give pebble to alice
There isn't anyone named Alice here.
This is one of those things where the solution is just a couple hundred lines of code but it took way too much fiddling around with parser internals to figure out all the weird corner cases.
Anyway, here’s the repo: personScope github repo.
The behavior is enabled by setting usePersonScope = true
on the player character. That is, on the Actor
instance that issues the commands, not the actor or actors being referred to in the commands.