12 Factoids – cFactoid
Factoids make it easy to create a knowledge base for NPCs.
TIP: There are easier ways for NPCs to answer questions.
See pAIQuestionsAndAnswers, or AIListenForEnum(), AIListenForIsValid(),
and AIListenForAct().
Factoids, based on cFactoid, make it easy to create a knowledge
base for NPCs. A factoid is an object that stores a question or
statement that the user speaks, such as "Where does King Rehald live?",
along with a response, "Kind Rehald lives in Burandon." Factoids actually store
a lot more information than the question and response, but those
are the basics.
Each faction (cFaction) maintains a list of factoid objects
known by the faction, and which are ultimately known
by the individual members of the faction.
Individuals can also have their own list of factoids, outside
of what they know from any factions they belong to.
To create a factoid that handles a simple question and answer:
-
Create a new object based on cFactoid. The
object's parent/container should be NULL.
-
Fill in pFactoidParse with the parse string
that causes the factoid to be spoken... This is the phrase
that must be spoken by the player.
At its simplest, pFactoidParse is something like,
["Where does King Rehald live?"]. However, this requires that
the player types in an exact string and doesn't take full
advantage of the parser's abilities.
A better solution would be ["`where", oKingRehald], which
can take advantage of a provided global and become,
[gFactionWhere, oKingRehald]. The rules in rParserConversation
convert "Where X?" questions into "`where X". By using
oKingRehald instead of "King Rehald", the parser interpreting
the factoid not only knows which object is being referred to,
but it knows all the object's parse names (from pNameRealParse),
so the user would be able to type "King Rehald", "Lord
Rehald", "Sirius Rehald IV", etc.
pFactoidParse supports multiple sentences too. For more information
see the documentation.
-
pFactoidSpeak needs to be filled in with the NPC's
response to the question, such as ["Kind Rehald lives in Burandon."].
pFactoidSpeak allows the NPC to do more than just speak. It can
cause it to whisper, yell, emote, or have the narrator speak.
For more information see the documentation.
-
For each faction that would know this information,
fill in the faction's pAIFactoids.
Obviously, any
subject of King Rehald would know this tidbit, as well as
neighbors and educated NPCs around the world. Example:
oFactionResidentOfBurandon.pAIFactoids = [ThisFactoid]; as
well as oFactionScholar.pAIFactoids = [ThisFactoid].
Alternatively, if you wish a NPC to know about a factoid independent
of the factions it belongs to, you need to change the
NPC's pAIFactoids to include the factoid object.
That's all there is to factoids, at the basic level at least.
The only problem with them is that you'll need to create an
awful lot of factoids for a world populated with NPCs.
Factoids can handle more sophisticated parsing that what
I descibed:
-
pFactoidParse can contain several different
parses, as I already mentioned. To do this, create a list
of parses, each parse being a sub-list. For example: [ [gFactoidWhere,
oKingRehald], ["where does", oKingRehald, "(live|reign)"] ].
You can even append a probability to each parse, just like
you set a probability in rule set resources.
-
There are several globals for who, what, why, where, how, etc.
with the names gFactoidXXX, where XXX is replaced
by "Who", etc. I suggest using to the globals to minimize
typing mistakes that will be difficult to find.
-
If you need to define additional rules that do not relate
immediately to the phrase, you can do so by
setting pFactoidParseSyn. For example, if
you wished to convert "the lord of the land" to "King Rehald"
then set pFactoidParseReword to [ ["the lord of the land",
"King Rehald"] ]
-
pFactoidParseReword is similar except that it
rewords an entire sentence.
There are many ways to control what is spoken, and other
NPC reactions:
-
pFactoidSpeak can contain <SpeakScript> resources,
causing the NPC to whisper, emote, or include narration.
-
You can provide different versions of what gets spoken depending
upon the NPC's rank within the faction from which he inhereted
the factoid. This lets the common folk have one version of
events, while nobility might have another. To do this, create
a list with sub-lists for each of the alternative phrases.
Prefix each sub-list by the rank that the NPC needs to be in
order to speak that version of events.
Example: [ ["The king lives up in the palace."], [5, "King
Rehald reigns from the east wing of the Silver Palance."] ].
You don't need a number for the first sub-string since there
is no minimum rank. Any NPC up to rank 5 will speak the first
phrase. Any one with 5 or above will speak the second.
-
pConvElementConversationState controls what the conversation
state will be after the factoid has been spoken.
If you leave this undefined then the state will be set based
upon whatever objects can be found in pFactoidParse and
pFactoidPronoun. It also affects what the conversation state
the factoid will be brought up in.
-
pFactoidEmotionsSet will change the NPC's emotions
when they speak the factoid. For example: Asking a mother about
her lost child might make her sad.
-
pFactoidLikeSet affects how much the NPC's like/trust
of the PC changes after the PC asks the question. For example:
A slanderous comment about King Rehald might go over well with
some factions, but poorly with others.
-
pFactoidMemorySet can be used to set a
memory in the faction's or NPC's memory (using AIMemorySet()).
NOTE: Every time a NPC speaks a factoid, it remembers that it
spoke the factoid. The system does this to ensure that NPCs
don't speak the same factoid over and over, particularly
for questions. (See below.)
-
When factoids are spoken they try to keep track of pronoun
meanings just in case the player uses "he" or "it" in the
next sentence. If pFactoidPronoun has any objects,
they are used for pronouns. If the list is empty,
pronouns are derived from any objects listed
in pFactoidParse.
-
pFactoidConvTree will cause a conversation tree
to be started immediately after the factoid has spoken.
For more information about conversation trees, see the
cConvTree tutorial.
-
pFactoidQuestionFill lets the NPC's speaking of
a factoid spur on some other memories/comments that it
will add to the conversation if given a chance. Just fill
pFactoidQuestionFill with a single factoid object, or a list
of factoid objects. See below for more information about
questions.
-
Some factoids allow the NPC to change the conversation's
direction by using a question from the question list, while
other factoids require that the NPC wait for the player
to speak next. For example: If a factoid were, "The King lives
up in the palace.", the NPC might append a question/statement from
the question list, such as "I visited the palace once.". However, if
the factoid ended in a question then NPC would have to
shut up and wait for the PC to respond, such as "Do you want
to know where the king lives in the summer or winter?".
To prevent the NPC from asking a follow-on question,
set pFactoidWaitForResponse to TRUE. Leave it
undefined to allow a follow-on question.
-
If these properties don't meet your requirements for the
factoid, you can always write your
own FactoidAct() method, which is called
when the factoid is to be spoken.
Even though a NPC is a member of a faction that knows a factoid,
the individual NPC may not know the factoid. Or, the NPC may
not be willing to divulge the factoid to the PC:
-
pFactoidSpeak can be used to limit the factoid's
knowledge to faction members of a specific rank. [ [5, "The king's
first name is Alendre."] ], limits the factoid to only
NPCs with a 5 or higher ranking in their faction. [ ["The emperor
has no clothes.", [4] ], causes all the peasants to realize that
the emperor has no clothes, but anyone with a 4 or higher rank
won't know the factoid.
-
pFactoidEmotionsRequired will cause the NPC to
only speak the factoid when he/she is very happy, very sad,
etc.
-
pFactoidFactionsRequired ensures that the NPC
will only speak the factoid to PCs who are a member of a specific
faction. (Or not a member.)
-
pFactoidHoldRequired will prevent the NPC from
speaking the factoid unless the PC is holding a specific object,
such as a piece of jewelry that idenfifies the PC as a friend.
(Or the reverse.)
-
pFactoidLikeRequired causes the NPC to only
speak the factoid if the NPC's like/trust for the PC is within
a given range.
-
pFactoidMemoryRequired tests a memory of the
NPC or the NPC's faction (see AIMemoryGet()) and uses it
to determine if the factoid will be revealed. For example: If
the PC hasn't declared allegiance to the king (which caused
a memory to be stored), then he won't be told about many factoids.
-
pFactoidRaceRequired will only let the NPC
speak a factoid if the PC is of a specific race. (Or not
of a specific race.)
-
If you wish to impose other tests, you can write
your own FactoidValid() method with your
own test. For example: You may wish a factoid discussing
a rumor about a werewolf to be spoken in the week preceding
a full moon.
Using factoids as conversation questions
Factoids can also be used for conversation questions that
are added using AIConversationQuestionAdd(). There
are two ways to add a factoid to the list of questions in
a conversation:
-
If the NPC speaks on factoid, that may bring up other
memories/thoughts that is will express later, using
the question mechanism. To do this, set
the factoid's pFactoidQuestions to the questions/factoids
that will come to the NPC's mind.
-
If a factoid has pFactoidQuestionFill set then
it will automatically be added as a question when the conversation
begins.
In both cases, factoids will not be
added as factoids if the fail to meet the critera for
the factoid (such as pFactoidLikeRequired), or the factoid
was already spoken to the PC by the NPC.
You can set the question priority by
using pConvElementPriority. As
with an question, the priority
is also affected by how well the factoid's state matches
the current conversation state. The state
is set using pConvElementConversationState. If
left blank, a state will be generated from any objects
listed in pFactoidParse and pFactoidPronoun.
Share with your friends: |