Character Mutations
Overview
The purpose of character mutations is to make agent fields mutable and give you more control over the character. This feature makes it possible to implement characters with temporary changes.
Mutations are part of the goals system. It allows you to modify the current active character as a goal action. To enable or disable a goal using the Unity or Unreal Engine SDK, see Enable Goals.
It is possible to specify multiple actions as a part of a single goal, mutations will then be applied to the character after the remaining actions are executed in order. For example, if a goal has two actions; “greet the player”, and “set_motivation: ‘sell sword to the player’”, then the motivation field will be updated after the character greets the player.
Functional Boundaries
This section outlines the functional boundaries and characteristics of character mutations.
Variability Across Sessions
- Mutations are currently scoped to the session.
- You can apply various mutations to the same character across different sessions.
- Mutations are not retained beyond the current session. They are permanently lost when the session expires.
Mutation Application
- Multi-Field Mutation: A single mutation within the goal may mutate multiple fields.
- Sequential Execution: When a goal comprises multiple actions, mutations are applied after executing all other actions in the specified order. For instance, if a goal includes actions like greeting the player and then setting a motivation, the mutation affecting the motivation field will occur post-greeting.
- Direct Values or Templates: Each mutation field must contain the exact value to set or a template. If a template is used, it is compiled using known trigger parameters. The compiled results are validated before being applied to mutate the character field.
- Reset: There is no function to reset a field to its original value after a mutation. To reset a field to its original value, you must explicitly call a mutation with the original value.
Field References
Name | type(s) | limits | Comment |
---|---|---|---|
set_emotion | String, enum | NEUTRAL , DISGUST , CONTEMPT , BELLIGERENCE , DOMINEERING , CRITICISM , ANGER , TENSION , TENSE_HUMOR , DEFENSIVENESS , WHINING , SADNESS , STONEWALLING , INTEREST , VALIDATION , AFFECTION , HUMOR , SURPRISE , JOY | Values are case insensitive. |
set_motivation | String | 512 chars | |
set_dialogue_style | String | UNSPECIFIED , DEFAULT , BUBBLY , FORMAL , BLUNT , INQUISITIVE , COMMANDING , EMPATHETIC , ENTERTAINING , HYPOCHONDRIAC , LAIDBACK , LONG_WINDED , MORAL , MYSTERIOUS , RACONTEUR , SARCASTIC , TENACIOUS , VILLAINOUS , | Values are case insensitive. |
set_personality: negative_positive aggressive_peaceful cautious_open introvert_extravert insecure_confident | String, number | Integer 1-9 inclusive, or strings “1”-”9”. | Each field may be specified or omitted separately. If no field specified - there would be no effect. |
set_mood: sadness_joy anger_fear disgust_trust anticipation_surprise | String, number | Integer 1-9 inclusive, or strings “1”-”9”. | This is not a constant ‘mood’ setting it can be considered the ‘initial mood’ for the character. It is used to set up an emotional state at the start of conversation. Also it sets up ‘target emotion’. Character emotions will slowly slide towards the target emotion during the conversation. |
set_mood: emotional_fluidity | String, float | Float value from -1.0 to 1.0 inclusive. Or string representation of the same value. | -1 means that emotions would not change. +1 emotions change quite quickly. |
set_character_name | String | 512 chars | |
set_core_description | String | 1024 chars | |
set_pronouns | String, enum | Possible values: UNSPECIFIED , SHE/HER , HE/HIM , THEY/THEM , | Case insensitive. UNSPECIFIED has the same behavior as THEY/THEM |
set_alternate_names | List of strings | 10 elements max, 512 chars max each | Character nicknames |
set_example_dialogue | String | 512 chars | Example dialog is a single large string. |
set_wikipedia_url | String | 512 chars | No URL validation |
set_character_traits | List of strings | 10 elements max, 512 chars max each | If not set - character traits will be populated automatically from ‘personality’. |
set_life_stage | String, enum | UNSPECIFIED , INFANCY , TODDLERHOOD , PRESCHOOL , EARLY_SCHOOL , ADOLESCENCE , YOUNG_ADULTHOOD , MIDDLE_ADULTHOOD , LATE_ADULTHOOD , CHILDHOOD | Values are case insensitive. |
set_hobbies_and_interests | List of strings | 10 elements max, 512 chars max each | |
set_character_role | String | 512 chars | |
set_custom_dialogue_style: set_adjectives | List of strings | 3 elements max, 512 chars max each | custom_dialogue_style is mutually exclusive with dialogue_style. Only one of them may be used at the same time. There is a hidden variable that tells which one to use. Therefore, if mutation contains only set_custom_dialogue_style - custom_dialog_style will become ‘enabled. If only set_dialogue_style - dialogue_style will be used. If both - no modifications will be applied. |
set_custom_dialogue_style: set_colloquialism | String | 512 chars | |
set_flaws | String | 512 chars | |
set_voice_data: set_voice | String | 512 chars | Voice names are validated against TTS service at runtime, attempts to set up an unexisting voice will be ignored |
set_voice_data: set_pitch | Float, String | Float in range -0.5 to 1.5 inclusive, to string representation | |
set_voice_data: set_talking_speed | Float, String | Float in range 0.5 to 1.5 inclusive, string representation | |
set_relationship | String, enum | UNKNOWN , ARCHENEMY , ENEMY , ACQUAINTANCE , FRIEND , CLOSE_FRIEND , DATE , RELATIONSHIP , LIFE_PARTNER | Values are case insensitive. Values are mapped back to relationship state variables. Relationship state itself is hidden and not modifiable. |
set_relationship_primitives: trust, respect, familiar, flirtatious, attraction | Number | Integer from -1000 to 1000 inclusive. | Each field may be specified or omitted separately. |
enable_goals | List of strings | 200 elements max, 512 char each | 200 - is a limit to the number of goals we can have in a single agent. enable_goals should contain goals names, case sensitive. If the goal with the given name does not exist - it will be silently ignored. |
disable_goals | List of strings | 200 elements max, 512 char each | |
set_profile_variables: id value | List of objects | 10 elements max, 512 char on id 512 char on value | Allow only the modification of existing profile variables. Unknown variables will be silently ignored. |
enable_common_knowledge | List of strings | 100 elements max, 512 chars each | Contains common_knowledge ids, not common knowledge names. Common knowledge names are not unique. |
disable_common_knowledge | List of strings | 100 elements max, 512 chars each | |
set_scene_description | String | 1024 chars | Replacement for scene triggers. |
Common Knowledge ID
Unique Common Knowledge IDs can be found in URL of each Knowledge section in the Studio.
Templates
Templates in mutations are similar to those used in goals, allowing for dynamic content generation. These templates are based on a syntax that uses placeholders within strings to insert variable values.
Text vs Non-Text Mutations
Mutations may impose specific restrictions on templates that vary based on the type of data being manipulated:
Text Mutations
These support complex templates with multiple variable references and no restrictions. For instance, a template might combine characters, items, and prices in a sentence.
# Example of a text mutation template:
set_motivation: "{{character}} wants to sell {{p.item}} to the player. It costs {{p.price}} gold."
Non-Text Mutations
These are limited to templates with a single variable reference, focusing on straightforward, single-value changes.
# Example of a non-text mutation template:
set_dialogue_style: "{{p.dialogue_style}}"
Validation and Runtime Handling
-
Design-Time Validation: Templates are checked for correctness during the design phase. Any templates with errors cannot be saved.
-
Runtime Processing: During execution, non-text field templates are rendered and parsed into their respective types, such as enumerations or specific value formats. Users are responsible for ensuring that parameter values are correctly set. For the example above, it is set as the example_dialog_style enum. Users are responsible for ensuring that parameter values are correctly set.
Note: If a value cannot be parsed - runtime errors will be propagated to the client.
Mutable Fields YAML
Here is the example of YAML with all mutable fields specified:
goals:
- name: "test"
activation:
trigger:
- "trg"
actions:
- character_changes:
set_emotion: AFFECTION
set_motivation: "motivation"
set_dialogue_style: "Bubbly"
set_personality:
negative_positive: 2
aggressive_peaceful: 3
cautious_open: 4
introvert_extravert: 5
insecure_confident: 6
set_mood:
sadness_joy: 1
anger_fear: 2
disgust_trust: 3
anticipation_surprise: 4
emotional_fluidity: 0.2
relationship_fluidity: 1
set_character_name: "name"
set_core_description: "descr"
set_pronouns: he/him
set_alternate_names:
- "name1"
- "name2"
set_example_dialogue: "hey"
set_wikipedia_url: "url"
set_character_traits:
- "trait1"
- "trait2"
set_life_stage: EARLY_SCHOOL
set_hobbies_and_interests:
- "hobby1"
- "hobby2"
set_character_role: role
set_custom_dialogue_style:
set_adjectives:
- "adj"
set_colloquialism: "set_colloquialism"
set_flaws: "flaws"
set_voice_data:
set_voice: "some voice"
set_pitch: 1.0
set_talking_speed: 1.1
set_relationship: "relationship"
set_relationship_primitives:
trust: -100
respect: -50
familiar: 0
flirtatious: 50
attraction: 100
enable_goals:
- "goal1"
disable_goals:
- "goal2"
set_profile_variables:
- id: "id"
value: "new value"
enable_common_knowledge:
- "id_to_add"
disable_common_knowledge:
- "id_to_remove"
set_scene_description: "scene2"
Enable Goals
Remember, mutations are part of the goals system. To take advantage of the mutations feature, goals must be enabled. Below are instructions are how to enable and disable goals for the Unity SDK and Unreal Engine SDK.
Enable and disable goals in Unreal Engine SDK
To enable a goal in the Unreal Engine SDK, a trigger must be sent with the name of the goal:
Trigger | Description |
---|---|
inworld.goal.enable.{name-of-goal} | Enables an existing goal on the server. |
inworld.goal.disable.{name-of-goal} | Disables an existing goal on the server. |
Enable and disable goals in Unity SDK
The Unity SDK includes a wrapper function for enabling or disabling goals. This convenient wrapper automatically sends the necessary trigger, simplifying the process.
Function | Description | Parameter |
---|---|---|
EnableGoal | Enables an existing goal on the server. | goalName: The name of the goal to enable. |
DisableGoal | Disables an existing goal on the server. | goalName: The name of the goal to disable. |