Quoll Work Thread, 2025-02-17 - 2025-02-17 18:50
Long time no update, I know, but I have been working on this bug when I have found the energy away from day job, and I am glad that I have decided on a workaround. But I wanted to (re-)explain the issue and how I ended up fixing it for posterity, so here we are…
(WARNING: This post contains slight optional puzzle spoilers for the First sublevel of Glitch’s Non-Breaking Space, but not the actual solution.)
So, for this sublevel, I have introduced the first of Ada’s “old” roommates that have been created by Glitch to represent the various people of the past that Ada may end up affecting with her magic as she performs Chronomancy, Taffany. There is an optional puzzle for Taffany where she wants Ada to find one of several just-bought CDs to bring back to her. Of course, one of the major verbs of this game are the conversational verbs of ASK and TELL, so the CDs are themselves something Ada will want to use those verbs for.
In general, Ada is unable to converse about Things that are not known
to her, meaning that she is either familiar
with it or has seen
it. So how could Ada “ASK ABOUT CDS” then if she hasn’t seen them or been told about them in some
other fashion? Well, there are a group of Subjects for the CDs, a Subject being a special type of Thing to represent
conversation topics and pieces of knowledge:
GNBSP-1-Missing-CDs-Subject is a privately-named unfamiliar subject.
[...]
GNBSP-1-Unfamiliar-CDs-Subject is a privately-named subject.
There are two different Subjects because Ada doesn’t start out knowing that the CDs are Taffany’s problem, merely that she has some problem, and I wanted to do a cool thing in case the Playerr types something like "ASK ABOUT CDS" before Ada is aware that it’s the CDs specifically where Ada acknowledges her lack of knowledge. Mainly out of feeling the need to have the Playerr keep in mind that Ada’s knowledge of the world is not the same as the Playerr’s.
You may also note that GNBSP-1-Missing-CDs-Subject
is unfamiliar
, while GNBSP-1-Unfamiliar-CDs-Subject
is
unspecified, meaning that it is familiar
because Subjects are familiar
by default. I mark them as
privately-named
because I don’t want the parser to latch onto these names as it does by default, but instead tell
the parser itself what to understand as the subjects:
Understand "problem" or "issue" or "[taffany-possessive-token] problem" or "[taffany-possessive-token] issue" as
GNBSP-1-Missing-CDs-Subject.
Understand "missing/desired/unimplemented/-- [gnbsp-1-cd-singular-token]" or
"[taffany-possessive-token] missing/desired/unimplemented/-- [gnbsp-1-cd-singular-token]" or
"missing/desired/unimplemented/-- [gnbsp-1-cd-plural-token]" or
"[taffany-possessive-token] missing/desired/unimplemented/-- [gnbsp-1-cd-plural-token]"
as "[gnbsp-1-missing-cd-token]".
Understand "[gnbsp-1-missing-cd-token]" as GNBSP-1-Missing-CDs-Subject when GNBSP-1-Missing-CDs-Subject is familiar.
Understand "[gnbsp-1-missing-cd-token]" as GNBSP-1-Unfamiliar-CDs-Subject when GNBSP-1-Missing-CDs-Subject is
unfamiliar.
Either way, because Ada is familiar
with GNBSP-1-Unfamiliar-CDs-Subject
at the start of the game, she can
successfully “ASK ABOUT CDS” without having seen the physical CD Things that are defined like so:
The CD-Album-White is a CD-Color-White compact disc album. The description is "TODOTODO: White CD Description.". It is
in the black plastic bag.
The CD-Album-Yellow is a CD-Color-Yellow compact disc album. The description is "TODOTODO: Yellow CD Description.". It
is in the black plastic bag.
The CD-Album-Green is a CD-Color-Green compact disc album. The description is "TODOTODO: Green CD Description.". It is
in the black plastic bag.
The CD-Album-Blue is a CD-Color-Blue compact disc album. The description is "TODOTODO: Blue CD Description.". It is in
the black plastic bag.
The CD-Album-Black is a CD-Color-Black compact disc album. The description is "TODOTODO: Black CD Description.". It is
in the black plastic bag.
So that’s nice, but what happens if she has seen the physical CDs?
Well, my hope was that she would then just ASK ABOUT the physical CDs, which would redirect to the same responses as the subject. I thought I had this working, but it turns out that my testing never tested something like “ASK ABOUT CDS” after Ada had seen the physical CDs. And when I added a test that accidentally hit this scenario, to my horror it fired the Default Response that is printed when I have not prepared a response for a character on that particular topic. Why did that happen?
Well, let me show off a bit from Conversation Framework by Eric Eve, where the relevant implicit-asking
and
implicit-quizzing
Actions for the “ASK ABOUT” command is defined:
Implicit-asking is an action applying to one topic.
Understand "ask about [text]" or "a [text]" as implicit-asking.
[...]
Implicit-quizzing is an action applying to one visible thing.
Understand "ask about [any known thing]" or "a [any known thing]" as implicit-quizzing.
Now you might be surprised to see that two different Actions are mapped to “ASK ABOUT”, but there is a very good
reason for this. Basically, there are Things in the model world that the parser knows about and is able to map input to.
For example, if the Playerr types “ASK ABOUT HOODIE”, the the parser can map “HOODIE” to the (say)
Glitchtech collegiate hoodie
that Ada wears in Glitch’s Non-breaking Space.
But if the Playerr tries something that has no parallel in the model world such as “ASK ABOUT JEANS”? By default, this would result in something like “I can’t see any such thing.”, which is especially confusing in the case of trying to converse because you can certainly talk about something you can’t currently see.
This is where the two different Actions come in. In the first case where there is a model-world Thing, the
implicit-quizzing
Action is used, because that matches the "ask about [any known thing]"
Understanding. In the
second case, the implicit-asking
Action is used based on the "ask about [text]"
Understanding, which would treat
“JEANS” as just an arbitrary text string.
(By the way, the “implicit” part of these Actions are to discern them from explicitly commanding who to ask such as “ASK TAFFANY ABOUT CDS”.)
What was happening was that “ASK ABOUT CDS” was being directed to the textual implicit-asking
Action despite the fact
there were multiple known
Things Ada could have asked about, the Subjects and the physical CD Things. I’ll get to
the “why” in a bit, but let me go over a few things I tried.
When there are multiple possible Actions that could be taken for the same input command, Inform 7 decides between them based on what Things are nearby and carried or touchable. If it can’t decide between the possible Actions, it will usually then ask the Playerr to disambiguate between them. However, there might be cases where the parser really should favor (or disfavor!) one possible Action over others, and this can be accomplished by a special type of Rule:
Does the player mean doing something with a compact disc album: it is very likely.
Does the player mean conversing when the second noun is a compact disc album: it is likely.
Does the player mean implicit-quizzing a compact disc album: it is likely.
Does the player mean implicit-informing a compact disc album: it is likely.
[...]
Does the player mean quizzing someone about GNBSP-1-Missing-CDs-Subject: it is very likely.
Does the player mean implicit-quizzing GNBSP-1-Missing-CDs-Subject: it is very likely.
Does the player mean informing someone about GNBSP-1-Missing-CDs-Subject: it is very likely.
Does the player mean implicit-informing GNBSP-1-Missing-CDs-Subject: it is very likely.
Does the player mean quizzing someone about GNBSP-1-Unfamiliar-CDs-Subject: it is very likely.
Does the player mean implicit-quizzing GNBSP-1-Unfamiliar-CDs-Subject: it is very likely.
Does the player mean informing someone about GNBSP-1-Unfamiliar-CDs-Subject: it is very likely.
Does the player mean implicit-informing GNBSP-1-Unfamiliar-CDs-Subject: it is very likely.
Note that the goal of these Rules is to favor the Subjects when conversing versus the physical compact disc album
s
when doing anything else. Note that for the compact disc album
, all the Rules around conversing say that
it is likely
versus it is very likely
for the conversing Rules around the Subjects.
When I got to fixing this issue I had noticed that I hadn’t written these Rules to favor the Subjects when conversing, so that was my first attempt to fix this. It didn’t work.
I was surprised that this didn’t work, and in a fit, I basically erased the implicit-asking
Action that was getting
called. This worked out because it revealed that the reason that the Parser was not choosing implicit-quizzing
was
because implicit-quizzing
only works on one thing, not multiple things, by printing out a parser error. If Ada
instead was told to ask about a singular CD with “ASK ABOUT CD”, it worked fine.
That convinced me to look around the Inform 7 documentation and I found
example #295, The Left Hand of Autumn where the
“EXAMINE” command was extended to account for examining multiple things by pointing to a multiply-examining
Action. I
tried to implement my own version of this with a multiply-implicit-quizzing
Action but it didn’t work. One of the
fun headaches I had was that I had defined my multiply-implicit-quizzing
Action as:
Multiply-implicit-quizzing is an action applying to one thing.
Understand "ask about [known things]" and "a [known things]" as multiply-implicit-quizzing.
But I really should have defined it as:
Multiply-implicit-quizzing is an action applying to one visible thing.
Understand "ask about [any known things]" and "a [any known things]" as multiply-implicit-quizzing.
because by default a thing
only refers to Things that Ada can touch, you instead need to refer to visible things
to
get other Things that may be in scope (and not necessarily visible
, either). The same reason is for the
[any known things]
versus [known things]
. But this didn’t work and gave me the same parser error, and in some cases
had knock-on effects for say, asking about one of the now multiple skunk characters in the game.
The parser error in question was written out as “You can’t use multiple objects with that verb.”, and is referred to
as the can't use multiple objects error
in the code. This then gave me the idea to use a newer extension I’ve added,
Smarter Parser by Aaron Reed, which introduces a bunch of rules that are meant to run before a parser error is printed
to try to salvage the command.
But this wasn’t going to work, either, because while I had disabled the implicit-asking
Action for my testing
purposes, I would need to re-enable it so it can be there to catch arbitrary text I haven’t accounted for to redirect
to the Default Response. Like it works fine for what it’s there for— it just isn’t what I want in this case.
Regardless, if I re-enabled the implicit-asking
Action, then the parser error would never get printed because the
parser would instead try that Action.
In the end, I chose to attack that Action directly and prevent it from its normal behavior:
Before implicit-asking (this is the gnbsp 1 fix trying to implicit-ask about cds rule):
unless the current sublevel is greater than 0, make no decision;
if the topic understood matches "[gnbsp-1-missing-cd-token]":
if GNBSP-1-Missing-CDs-Subject is familiar:
try implicit-quizzing GNBSP-1-Missing-CDs-Subject instead;
otherwise:
try implicit-quizzing GNBSP-1-Unfamiliar-CDs-Subject instead.
And this finally worked! I had put a lot of effort in trying to stop the parser from choosing this Action, and it really was for naught, because it was easier to just make the Action do the right thing instead.
(The part about the current sublevel
is there so the rule doesn’t need to run until the first sublevel. Mostly just
a pre-optimization for performance. It may have been better to actually put that check in the preamble to the Rule…)
So there you go. I’ll be honest, this bug has been so basically frustrating that it is severely making me reconsider how many more of the games in this series are going to be written in Inform 7. There is so much I love about doing it like this, but this is just one of many issues I’ve had directly related to working around the archaic parser. And I know from watching Playerrs that even with all my work it still makes huge mistakes.
Oh well, I feel stuck into this for at least this zeroth game in the series, but we’ll see what the future holds. For now, I am at least overjoyed to finally be in a position where I can just write all of these responses I have scaffolded. Writer brain has been itching for this for over a year at this point and I’m hoping it will be really fun. Be on the look out for updates! (Though not today, I’m done with this for today.)