Context: where we use this
"Creature Dialog" covers how different video-game entities, such as Space Marines or Nihilist Droids, exchange knowledge and feelings, such as "might you know where is the extra food", "i am seriously hungry", or "give me your food now". Creatures can communicate in many ways, including speaking words, smiling, waving hands, or lobbing grenades. Often in our games or simulations, we code communication as giving the listening creature read-access to the speaking creature's data, such as 'here is the location of the rebel base' or 'my emotion state is angry'. In a multi-threaded world, this is probably a copy of that information instead of just 'read-access', but in either case that information can be used to make future creature decisions. This style of perfectly understood communicating makes creature dialogs predictable and easy to design and debug, which is a universally good thing(tm). However, while coding a large predator-prey-producer ecosystem simulation (imagine a dinosaur-world or insect-realm), that same comfortable predictability eliminated surprises and withered any enthusiasm for observing creature interactions. This dullness helped us to realize how important misunderstandings were to recreating believable and interesting interactions. We needed a way to code miscommunication to diversify each dialog and still be able to easily design/debug the system.
Goals: what we need
- A service that lets a speaker creature deliver a message to a listener creature. We will call this transaction-system a 'dialog', but it may be implemented as more than mere words such voice-tone, body-language or released-scents.
- A means to model misunderstandings that can result in complex but trackable (log-gable!) responses.
Solutions: how we tried
Technique: Predefined Confusion
We support queries (give me your knowledge), responses (answers to queries), and commands (add this behavior to your plan list of behaviors). All of those message types have a single piece of information which may have a misunderstanding built in to the information, such as the wrong location of the rebel base (an ambush) or begging for food (when the creature is already full). It seems that many classic CRPGs follow a similar route in the dialog trees when players are communicating to NPCs.
Pros: Straightforward to understand what will happen and easy to control outcomes.
Cons: Doesn't really give any variety, just a separation between the truth (such as where the base is really located or how hungry are you) and a lie.
We support queries (give me your knowledge), responses (answers to queries), and commands (add this behavior to your plan list of behaviors). All of those message types have a single piece of information which may have a misunderstanding built in to the information, such as the wrong location of the rebel base (an ambush) or begging for food (when the creature is already full). It seems that many classic CRPGs follow a similar route in the dialog trees when players are communicating to NPCs.
Pros: Straightforward to understand what will happen and easy to control outcomes.
Cons: Doesn't really give any variety, just a separation between the truth (such as where the base is really located or how hungry are you) and a lie.
Technique: Probability of Confusion
Building on the previous method, each dialog message has three possible outcomes depending on whether the listener is friendly (positive), unknown (neutral), or enemy (negative). Each creature has a limited memory of creatures (a top ten list) and a -1..+1 value to describe like/dislike. Before any query, response, or command is issued a random number is generated and scaled by the like/dislike value (if the listener is known) and classified as positive/neutral/negative. This approach seems to follow classic pen & paper RPGs (like Dungeons &Dragons) alignment match ups or recent CRPGs like Bioware's Mass Effect or Knights of the Old Republic. This needs to be augmented with a system that allows the like/dislike values to readily change based on interactions, which should be left to the reader-
Pros: Manageable complexity and a nice set of diversity compared to a fixed outcome.
Cons: Requires any piece of information, such as a location or hunger level to have 3 possible values to return depending on the like/dislike value for any queries. Some of this 'false-data' can be auto generated to be the opposite of the truth or 'close to the truth', but many discrete items like 'what is the name of the traitor' or 'where are you going' need coding-rules or fixed designer-choices to make sense in the world.
Building on the previous method, each dialog message has three possible outcomes depending on whether the listener is friendly (positive), unknown (neutral), or enemy (negative). Each creature has a limited memory of creatures (a top ten list) and a -1..+1 value to describe like/dislike. Before any query, response, or command is issued a random number is generated and scaled by the like/dislike value (if the listener is known) and classified as positive/neutral/negative. This approach seems to follow classic pen & paper RPGs (like Dungeons &Dragons) alignment match ups or recent CRPGs like Bioware's Mass Effect or Knights of the Old Republic. This needs to be augmented with a system that allows the like/dislike values to readily change based on interactions, which should be left to the reader-
Pros: Manageable complexity and a nice set of diversity compared to a fixed outcome.
Cons: Requires any piece of information, such as a location or hunger level to have 3 possible values to return depending on the like/dislike value for any queries. Some of this 'false-data' can be auto generated to be the opposite of the truth or 'close to the truth', but many discrete items like 'what is the name of the traitor' or 'where are you going' need coding-rules or fixed designer-choices to make sense in the world.
Survivor: who proved best & why
Technique: Emotion_Vector Confusion
Instead of using the scalar like/dislike and a random value to select between 3 possible outcomes of any given message, here we store an 'emotion-vector', such as x = angry, y = scared, z = tender, w = excited, s = happy, t = sad, which is attached to each dialog-msg that is sent. For any dialog-msg, we dot product the listener's and speaker's emotion vector for each other to accumulate a "certainty" or trust value for msg. This trust value can be used in any creature decisions such as "go to the rebel base" vs "its a trap" or "give the beggar food" vs "do not share". Note that the emotion vectors can be retained for each pairing of creatures so it forms a more complex version of like/dislike for each creature-combo. This is not ideal but approximates the ability for speaker and listener to relate to each other or to deceivingly attempt to relate.
Pros: Gives us quite a range of diverse behaviors. When the emotions attached messages are allowed to influence the 'current-thinking' state of the listener's emotion_vector relative to itself, it follows expected models of anger begetting anger or fear, happiness cheering up sad or not-excited being dismissed by a listener.
Cons: Not only requires coding-rules or fixed designer-choices to provide believable misinformation as before, but now also requires initializing an emotion vector for various creatures or groups/archtypes of creatures so that cats start off being scared of dogs and dogs are angered by cats, etc. Future: Refine this approach into a means to visualize all the creature-creature interactions as a sea of dialog and be able to watch trends (if any).
Instead of using the scalar like/dislike and a random value to select between 3 possible outcomes of any given message, here we store an 'emotion-vector', such as x = angry, y = scared, z = tender, w = excited, s = happy, t = sad, which is attached to each dialog-msg that is sent. For any dialog-msg, we dot product the listener's and speaker's emotion vector for each other to accumulate a "certainty" or trust value for msg. This trust value can be used in any creature decisions such as "go to the rebel base" vs "its a trap" or "give the beggar food" vs "do not share". Note that the emotion vectors can be retained for each pairing of creatures so it forms a more complex version of like/dislike for each creature-combo. This is not ideal but approximates the ability for speaker and listener to relate to each other or to deceivingly attempt to relate.
Pros: Gives us quite a range of diverse behaviors. When the emotions attached messages are allowed to influence the 'current-thinking' state of the listener's emotion_vector relative to itself, it follows expected models of anger begetting anger or fear, happiness cheering up sad or not-excited being dismissed by a listener.
Cons: Not only requires coding-rules or fixed designer-choices to provide believable misinformation as before, but now also requires initializing an emotion vector for various creatures or groups/archtypes of creatures so that cats start off being scared of dogs and dogs are angered by cats, etc. Future: Refine this approach into a means to visualize all the creature-creature interactions as a sea of dialog and be able to watch trends (if any).
Survivor_Datastructs
//===
//PSUEDOCODE
enum Purpose_Msg_t
{
Msg_Query_k, //seeks a 'statement' response
Msg_Statement_k, //has info
Msg_Command_k, //the info is a behavior script or value to change
}
typdef float Norm_t; //value from -1..+1
struct Emotion_Vec_t
{
Norm_t Angry_f;
Norm_t Scared_f;
Norm_t Tender_f;
Norm_t Excited_f;
Norm_t Happy_f;
Norm_t Sad_f;
}
struct Dialog_Msg_t
{
Purpose_Msg_t purpose;
Time_t Delivery_Duration__time;
Percent_t Speaker__Clarity_f;
//how easy was the message to understand
//(adds a random +/- deviation to the emotion vector prior to dot product)
Percent_t Listener__Trust_f;
//stores the results of the dot product of the emotion vectors to associate
//the information with a trust aka certainty level
Emotion_Vec_t Emotion_vec;
//adds a means to filter/misunderstand
Percent_t Intensity_f;
//if higher than 50% or so,
//it is an 'exclamation' in the traditional sense
Name_t Info_name;
//such as "Rebel_base location" or "i am hungry"
Infotype_t Info_type;
//such as "location" or "hunger-level"
Data_t Info_value;
//such as "lat 42, long 12" or "very-hungry" but not used when a query
};