Goals
A character's Goals determine what a character wants to accomplish, enabling you to set specific triggers that prompt them to respond in a specific way during certain scenarios or interactions.
This area includes a YAML Interface that allows you to enter the various goals associated with the character.
How Goals Work
The Goals system leverages contextual intents as activation conditions, passing real-time information from a client to a character through a set of parameters, which then control when a character delivers a pre-scripted line.
All of these features are defined in a flexible code editor, written in YAML Syntax.
YAML Syntax
YAML is a human-friendly data serialization language that structures information in a format both humans and machines can understand.
Within YAML, syntax indentation matters, as it denotes structure. In addition, sequences such as arrays or lists are denoted by a hyphen (-), and key-value pairs are separated by a colon (:).
The basic structure of a YAML file is shown below:
Key: Value
List:
- Item1
- Item2
Dictionary:
Key1: Value1
Key2: Value2
To learn more about YAML, see: The YAML Project
Goals Key Concepts
A character's Goals consist of three key elements, which are all Required for the system to function:
- Goal
- Activation
- Action
There are also a number of Optional parameters within Activations and Actions, covered in the sections below.
Goal
Required. The Goal operates as a 'consequence mechanism' which gets triggered by an Activation event that initiates a specific Action. This mechanism also monitors the achievement of a character's Goals, issuing a signal to the client upon the completion of a Goal.
For example, if you have a Goal to have a character suggest a quest to the player, your Activation condition might be the player asking about available quests. When this Intent is recognized, the Goal is activated, and the character begins executing the associated actions - in this case describing the quest and instructing the player on how to start it. Once the character finishes these actions, the Goal is marked as completed, and a Trigger is sent to the client.
Example of a Goal:
goals:
- name: 'give_quest'
repeatable: True
actions:
- instruction: 'give {player} a quest to retrieve the ancient candy recipes that were stolen by Lord Toffee'
emotion_change: 'VALIDATION'
activation:
intent: 'quest_request'
trigger: 'give_quest'
Activation
Required. The event that triggers the Goal. An activation can include up to two components: an Intent and a Trigger. Each Activation must include at least one Intent or Trigger, but does not require both.
Intent
Optional. An Intent utilizes a real-time detection engine that scans the player's conversation to identify any intentions that align with those predefined in Training_Phrases. When a match is identified, the Intent is activated and its name is passed to the Goal, triggering it. Note that multiple Intents can trigger the same Goal.
You can only leverage the Intent feature within the Goals & Actions tool to establish an intent detection system.
Trigger
Optional. A Trigger is a user-specified parameter used to initiate the Goal.
Activation by Intent and Trigger:
activation:
intent: 'quest_request'
trigger: 'give_quest'
Intent setup:
intents:
- name: 'quest_request'
training_phrases:
- 'How can I increase my attack damage?'
- 'What equipment should I have for the next quest?'
- 'Where can I get a weapon around here?'
- 'What items do you have to increase strength?'
- "What's the best weapon I can get?"
Multiple Intent examples setup:
activation:
intent: ['quest_request','second_quest_request']
# Another way to represent multiple intents triggering the same goal
activation:
intent:
- 'quest_request'
- 'second_quest_request'
Action
Required. The Action is a set of responses that occur after an Activation condition has been met. Action types include control over character dialogue via Instruction or Say_Verbatim, and client/server communication via Send_Trigger and leveraging parameters within dialogue actions.
An Action cannot include both Instruction and Say_verbatim at the same time - it must use one or the other.
For character state changes, see: Character Mutations
Instruction
Optional. The Instruction field provides specific guidance on how a character should respond after a Goal has been activated. The character will follow the instruction while maintaining their own unique personality.
When writing an Instruction with a direct command (that starts with a verb) it is recommended you phrase it as if you were giving a direct command to an actor.
Say_Verbatim
Optional. This is a text string that characters will recite exactly as written after a Goal has been activated.
Giving an action Instruction and Emotion_Change:
actions:
- instruction: "tell {player} to visit Queen Bee to get a javelin made with a honeybee's stinger"
emotion_change: 'JOY'
Giving an action Say_Verbatim:
actions:
- say_verbatim: 'Welcome to the Shop of Curiosities and Wonders! Are you new around these parts?'
Send_Trigger
Optional. This is a user-defined name that sends a signal back to the developer when a Goal is fired. It can be used in conjunction with the intent detection system to receive a signal when a custom Intent is detected.
Emotion_Change
Optional. This is a Mutation that allows you to set an emotion for the character. When activated, an Emotion_Change influences the character's emotions from the point when it is triggered. This emotion change lasts until either the session ends or the character's emotions are mutated again.
Activation Intent and actions Send_Trigger:
goals:
- name: "pitch_weapon"
activation:
intent: "ask_for_weapon"
actions:
- instruction: "tell {player} to visit Queen Bee to get a javelin made with a honeybee's stinger"
emotion_change: "JOY"
send_trigger: "ask_for_weapon_detected"
Random
Optional. This feature assigns a Probability (a number between 0 and 1) to an Action item such as an Instruction, Say_Verbatim, or Emotion_Change. When a Goal is activated, the Action item is then executed based on this Probability.
In the example on the right, the character has a 20%/50%/30% chance of giving different quests.
If random is used, then say_verbatim, instruction, and emotion_change must all be nested under random with assigned probabilities.
Giving actions using Random:
actions:
- random:
- probability: 0.2
instruction: 'give a quest to retrieve the ancient candy recipes that were stolen by Lord Toffee!'
- probability: 0.5
instruction: 'give a quest to rescue the princess from the clutches of the dragon'
- probability: 0.3
instruction: 'give a quest to uncover who destroyed Candycane Tower'
Customizable Parameters when Changing an Action
If needed, you can write Say_Verbatim and Instruction with parameters that inject real-time information from the client (delivered through the Trigger) to an action at runtime. These parameters can only be used within the context of the Goals file.
An example of this process is shown below:
- Step 1: Write the goal as shown below.
goals:
- name: 'pitch_weapon'
activation:
intent: 'ask_for_weapon'
trigger: 'pitch_weapon'
actions:
- instruction: "tell {player} to visit {{p.place}} to get a javelin made with a honeybee's stinger"
emotion_change: 'JOY'
send_trigger: 'ask_for_weapon_detected' - Step 2: Developers send a request message that includes the Trigger. For example, in API, send:
"triggerEvent": { "trigger": f'{workspace_id}/triggers/pitch_weapon', 'parameters':[{"name":"place", "value":"California"}]}
- Step 3: The Goal instruction is then added to the character's prompt, resulting in:
instruction: "tell {player} to visit California to get a javelin made with a honeybee's stinger"
In this example, the Instruction field incorporates a parameter that determines the location the player is encouraged to visit.
Additional Parameters for a Goal
Repeatable
Optional. Goals can be employed once per conversation session. Setting Repeatable to "True" allows for multiple uses of the same Goal.
Enabled_by_Default
Optional. Goals can be disabled at the start of conversation and then enabled later by a Character_Changes Mutation.
YAML Sample Code
Shown below is an example of a YAML script within a character's Goals:
# intents can be created to help orchestrate character behavior based on when a user says something similar to what is defined
intents:
# intent name is the resource value that can be used as an activation condition for a goal
- name: 'quest_request'
# training phrases should include examples of what an end user could say to trigger the intent
training_phrases:
- 'Do you have any quests for me?'
- 'What quest should I take on next?'
- 'What quests can I take on here?'
- 'Are there any quests I can take to help me level up?'
- 'Give me a quest'
- name: 'ask_for_weapon'
training_phrases:
- 'How can I increase my attack damage?'
- 'What equipment should I have for the next quest?'
- 'Where can I get a weapon around here?'
- 'What items do you have to increase strength?'
- "What's the best weapon I can get?"
# goals get activated by an activation event and initiate a specific action.
goals:
- name: 'greeting'
# activations composed of trigger (client-invoked) or intent
activation:
trigger: 'greeting'
# actions include instruction, say_verbatim, emotion_change, and send_trigger
actions:
- say_verbatim: 'Welcome to the Shop of Curiosities and Wonders! Are you new around these parts?'
character_changes:
enable_goals:
- "give_quest"
- name: 'pitch_weapon'
activation:
intent: 'ask_for_weapon'
actions:
- instruction: "tell {player} to visit Queen Bee to get a javelin made with a honeybee's stinger"
emotion_change: 'JOY'
send_trigger: 'ask_for_weapon_detected'
- name: 'give_quest'
repeatable: True
enabled_by_default: False
activation:
intent: 'quest_request'
trigger: 'give_quest'
actions:
- random:
- probability: 0.2
instruction: 'give a quest to retrieve the ancient candy recipes that were stolen by Lord Toffee!'
- probability: 0.5
instruction: 'give a quest to rescue the princess from the clutches of the dragon'
- probability: 0.3
instruction: 'give a quest to uncover who destroyed Candycane Tower'
Non-Invoke Conversation
There may be scenarios where you wish to activate a certain Goal without prompting the character to speak immediately, such as when deferring a character's response by one or more conversation turns.
This allows for more natural pacing and smoother interactions, preventing the character from abruptly interrupting the flow of the conversation. For these use-cases, you can employ a Non-Invoke Conversation by using an Array in the Actions field.
When defining actions as an Array, subsequent items within the Array are executed turn-by-turn until fully completed. This means that the character won't immediately act on the next item in the Array until the next player response.
Example of a Non-Invoke Conversation
Consider a scenario where a character needs to detect a player's intent but also has a set of instructions to give the player.
Instead of delivering everything at once, the character waits for the player to speak, providing the specified instructions upon the player's next interaction.
goals:
- name: 'acknowledge_and_instruct'
activation:
intent: 'player_action'
actions:
- send_trigger: 'player_action_detected'
- instruction: 'tell {player} to meet the elder at the village center for further guidance.'
In the example above, when the intent Player_Action is detected, the first action that the system executes sends a trigger named player_action_detected back.
Then, when the player interacts again, the character executes the instruction: "tell {player}
to meet the elder at the village center for further guidance."
Entity Extraction
Entities are matched against a player’s query. Any matches (values) can be injected into the Instruction of a character's Goal, and then returned as a parameter of a custom event, which is sent when the Goal is activated.
Entities are not connected to Intent matching, but instead run in parallel with it wherever intents and entities are predicted from the player's speech.
From there, Intent Matching is used to activate the Goal, and Entity Matching is used to insert into the action’s template, returning it back to the client in a custom event if the specified entity is a Goal action.
Types of Entities
There are two (2) types of entity entries available in the YAML: Map Entries and Regex Entries
1. Map Entries
These entries specify a set of Synonyms, which are words or phrases that are matchable from the player’s speech.
When a matched synonym is detected, the Value (machine-readable ID) associated with it is returned in a parameter of a custom event.
The Display_Name is non-unique human readable description, used in LLMs and other natural language tools.
entities:
- name: "fruit"
map_entries:
- value: "apple"
display_name: "apple"
synonyms:
- "green apple"
- "red apple"
- value: "orange"
display_name: "orange"
synonyms:
- "orange"
- "blood orange"
Fuzzy_Match attributes are also available on the MapEntry.
These entries allow for some deviations in the match from a specified entry synonym.
entities:
- name: "fruit"
map_entries:
- value: "apple"
display_name: "apple"
synonyms:
- "green apple"
- "red apple"
fuzzy_match: True
In the example above, if the player's speech has "I want to eat green apple" where the player mistyped apple, it should still be matched with fuzzy_match=True and it won’t be matched without it.
⚠️ Use the fuzzy_match=True attribute at your own risk, as it has the potential to produce false positive matches.
2. Regex Entries
Regex entities allow you to specify regex templates that extract structured data from user utterances.
In the example below, you can see a contact entity with phone_number and email regex entries. These entities are returned to the client by sending a trigger as part of a goal action.
entities:
- name: "contact"
regex_entries:
- value: "phone_number"
display_name: "phone_number"
template: '(\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4})'
- value: "email"
display_name: "email"
template: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
goals:
- name: entity
repeatable: true
activation:
motivation: "{player} mentions about their contact info"
actions:
- instruction: "say they will contact them later at {{p.contact.text}}, making sure to confirm the exact value of the contact information"
send_trigger: "contact_trigger"
trigger_params:
- name: contact
value: '{{p.contact.text}}'
Both Regex and Map entity entries have an optional description attribute where you can provide the explanation of the entry.
Accessing Numeric Parameters
To access a numeric parameter values in within a Regex entry, assure you use the .text type identifier to convert the numbers to string text. Refer to the image below for an example:
Escaped Characters in Regex Entities
When using Escaped Characters within a Regex entity, use single quotations (')
instead of double quotations (")
.
If double quotations are used instead of single quotations, an Invalid Escape Sequence error occurs.
Escaped Characters include the following:
\t
inserts a tab\b
inserts a backspace\n
inserts a new line\r
carriage return\f
form feed\'
inserts a single quote\"
inserts a double quote\\
inserts a backslash
Sample Entity Extraction YAML
# intents can be created to help orchestrate character behavior based on when a user says something similar to what is defined
intents:
# intent name is the resource value that can be used as an activation condition for a goal
- name: "start_race"
# training phrases should include examples of what an end user could say to trigger the intent
training_phrases:
- "lets go racing!"
- "i want to start a race"
- "i want to race"
- name: "confirm_race"
training_phrases:
- "yup thats right"
- "lets do it!"
- "yes thanks"
- "confirmed!"
- "green light!"
- "2 players on jungle please green light"
- "lets go with 4 players on the cloud map. green light!"
- "lets do a 4 player race on the desert map. green light!"
entities:
- name: "number_of_players"
map_entries:
- value: "1"
display_name: "1"
synonyms:
- "one"
- value: "2"
display_name: "2"
synonyms:
- "two"
- "two of us"
- "me and my friend"
- value: "3"
display_name: "3"
synonyms:
- "three"
- value: "4"
display_name: "4"
synonyms:
- "four"
- name: "map"
map_entries:
- value: "jungle"
display_name: "jungle"
- value: "forest"
display_name: "forest"
- value: "desert"
display_name: "desert"
- value: "clouds"
display_name: "cloud"
# goals get activated by an activation event and initiate a specific action.
goals:
- name: "green_light"
activation:
trigger: "green_light"
actions:
- say_verbatim: "Let's race! Starting a {{p.number_of_players}} player race in the {{p.map}}... 3,2,1 here we go!"
send_trigger: "race_started"
- name: "start_race"
# activations composed of trigger (client-invoked), intent, or motivation
activation:
trigger: "start_race"
intent: "start_race"
# actions include instruction, say_verbatim, emotion_change, and send_trigger
actions:
- instruction: "Always tell {player} to say 'green light!' along with the number of players and the map to start the race"
- name: "confirm_race"
activation:
trigger: "confirm_race"
intent: "confirm_race"
actions:
- send_trigger: "green_light"
trigger_params:
- name: "number_of_players"
value: "{{p.number_of_players}}"
- name: "map"
value: "{{p.map}}"
- name: "bump"
activation:
trigger: "bump"
actions:
- instruction: "insult {player}'s driving ability with a witty one-liner because they just crashed into your car while racing!"