Problems with Subject Familiarity

Using Eric Eve’s Epistemology and Conversation Framework, I haven’t been able to get even this little test to work, such that I’m sure I’m fundamentally misunderstanding something:

[code]Include Epistemology by Eric Eve.
Include Conversation Framework by Eric Eve.

Secret code is an unfamiliar subject.

Knowledge checking is an action applying to one topic. Understand “what [text]” as knowledge checking.

Carry out knowledge checking:
if the topic understood is a topic listed in the Table of Knowledge and the subject is familiar:
say “[explanation entry]”;
otherwise:
say “You don’t know about that.”.

Table of Knowledge
topic explanation
“secret code” “The secret code is 5402GHU.”[/code]
I’ve been stuck on this for quite a while; the command what secret code always prints the explanation entry.

I’ve thought that maybe the subject being identical to the topic leads the knowledge check to ignore the subject check entirely, since the knowledge checking action is instructed to apply to a topic, but I’m not sure how else I could tie a topic to a subject (or otherwise use familiarity with a topic). Not that I haven’t been experimenting with that, too.

There are two secret codes in your program. There is a thing (subkind: subject, as defined in Epistemology chapter 2) called secret code that you have defined with the line “Secret code is an unfamiliar subject”, and there is a topic “secret code” that you have defined by putting it in the Table of Knowledge. Things and topics are completely different, and there is nothing in your knowledge checking action that makes your program understand that it should take a look at the secret code thing as well as at the topic.

To give you sound advise about a better implementation, I’d need to know a bit more about what you want to use this familiarity stuff for.

Of course, that makes sense to me, and as alternatives I’ve tried things like changing all the references to a topic to instead refer to a subject, but an action can only apply to things or to kinds of value, so I then thought I could do something like:

[code]Secret code is an unfamiliar subject.

Knowledge checking is an action applying to one thing. Understand “what [thing]” as knowledge checking.

Carry out knowledge checking:
if the thing is a subject listed in the Table of Knowledge and the subject is familiar:
say “[explanation entry]”;
otherwise:
say “You don’t know about that.”.

Table of Knowledge
subject explanation
secret code “The secret code is 5402GHU.”[/code]
But then:

Anyway, what I intend to use the familiar/unfamiliar/known/unknown stuff for is to allow the player to effectively ask themselves questions about in-world knowledge, and for the response to depend on whether or not their character has been exposed to that knowledge.

I thought the secret code test was a good example, but perhaps just as illustrative would be to be able to ask ‘What is a grue?’ and receive no informative answer unless having read The Book of Dark Things.

I can see ways to do it by writing known/unknown conditionals for every subject (‘if secret code is known… if secret code is unknown… if grue is known… if grue is unknown…’), but I want to exhaust the possibility of just calling on a table like this before resorting to that! :open_mouth: Especially as I strongly suspect I’ve just gone codeblind.

What you should probably do is make a table with three columns: one for the topic that the player can ask about, one for the object that must be familiar (I’ll call it “relevant item” in the example below), and one for the text that the player will see. Then you can write something like

if the topic understood is a topic listed in the Table of Knowledge: choose row with a topic of topic understood in the Table of Knowledge; let item be relevant thing entry; if item is unfamiliar: say "You don't know anything about that yet."; otherwise: say "[explanation entry]"; otherwise: say "You don't know anything about that.".
You might need to tweak that code a bit, as I have no Inform open to compile and test it. This code assumes that ever topic has exactly one relevant thing; if there are more sources of the same information, you’ll need to repeat through the table instead.

[ON PREVIEW: Victor’s approach may be better, but you should really know about “the noun” and “one visible thing” anyway, so do read.]

In this line:

 if the thing is a subject listed in the Table of Knowledge and the subject is familiar:

“the thing” and “the subject” aren’t doing what you want them to. Inform treats “the thing” as the same as “a thing,” so this will check if any thing is a subject listed in the table of knowledge, and then it will check if any subject is familiar. This is why the error message writes that this “may perhaps result from a misunderstanding such as writing the name of a kind where an individual object is intended?”

What you want in this case is “the noun”; that refers to the thing entered in the player’s command.
Hence:

 if the noun is a subject listed in the Table of Knowledge and the noun is familiar:

However, if you just make that change you’ll discover this won’t work, because knowledge checking only works if the subject is in the room with you. You have to tweak the definition and understand lines a bit:

[code]Include Epistemology by Eric Eve.
Include Conversation Framework by Eric Eve.

Lab is a room.

Secret code is an unfamiliar subject. Known code is a familiar subject.

Knowledge checking is an action applying to one visible thing. Understand “what [any thing]” as knowledge checking.

Carry out knowledge checking:
if the noun is a subject listed in the Table of Knowledge and the noun is familiar:
say “[explanation entry]”;
otherwise:
say “You don’t know about that.”.

Table of Knowledge
subject explanation
secret code “The secret code is 5402GHU.”
known code “The known code is xyzzy.”
[/code]

“one visible thing” means the action applies to anything the player can refer to, and “[any thing]” means any thing in the model world, whether or not it’s in scope. Put together it allows you to check any subject without putting it in a room with you.

Victor, thanks for that. Choose row is new to me and opens up a lot, although in this case I removed that line to avoid an ‘ingredients in this phrase do not fit it’ error, but it’s working just fine without it.

Thanks to Matt, as well. I was under the impression that ‘the thing’ and ‘the subject’ in that sort of line necessarily referred to whatever thing or subject was specified in the [text] when triggering the action, if it was valid at all (which ‘the subject’ apparently was). Earlier on, I was trying to use ‘the subject in the player’s command’ or ‘if the player’s command includes “[a familiar subject listed in the Table of Knowledge]”’, but I7 didn’t care for those, either.

I also had been trying something similar in spirit to your implementation, there, but I had been screwing up the syntax concerning ‘the noun’ with stuff like ‘if the noun is known’ and ‘if the player’s command includes “[a familiar noun]”’—d’oh.

Anyway, with cleaner logic, we’re now working like science. Onward! :nerd:

Just to be clear, when you invoke an understand line that has a “[text]” token, what you get back is a topic (a string, more or less) that you can access with “the topic understood.” When the understand line has “[something]” or “[any thing]” or “[someone]” or something like that, then it returns a thing or an object (like a direction), and you can access that with “the noun” (or “the second noun,” if the action applies to two things).