-
Notifications
You must be signed in to change notification settings - Fork 19
6.2. Dialogue
Dialogue toml all use a naming format of ".c.toml". Each table corresponds to text that displays in the dialogue box. Dialogues can be found in the /t2/Conversations/ folder.
refresh determines how often the dialogue can be repeated. Other than the self-explanatory strings of "instantly" and "never", the value is a string consisting of a number followed by a unit. Units are given by d, w, m, or y for days, weeks, months, or years respectively. (You can also think of “months” as seasons.) As an example, the string "2d" would mean it refreshes in 2 days.
requires is one of the most important attributes of dialogue tomls. Here’s an example from Hayden’s Banked lines for context:
[adeline_and_eiland_wear_white]
refresh = "never"
requires = [
{ npc = "hayden" },
{ location = "haydens_farm" },
{ date_time = "1y", comparator = "<" },
{ adeline_is_at_location = "haydens_farm", comparator = "!=" },
{ eiland_is_at_location = "haydens_farm", comparator = "!=" },
{ quest_repair_haydens_barn_complete = false }
]
portrait = "neutral"
local = "Adeline and Eiland don't make it down to the farm much, but I don't blame them... they wear a lot of white and my farm's got a mess of mud!"We can see that requires is a table (defined with square brackets) with several assertions encased in curly braces. The first assertion, npc , tells the game who’s speaking. location gives us a requirement for where the dialogue is spoken. For assertions that are not looking for equal values, we can also use comparator to change the logic, as is the case with asserting that Ari has been in Mistria for less than a year. These logical assertions must all be true for the dialogue to trigger. If you want a logical expression to equate to an “OR” operation, you can use any , like so:
requires = [
{ npc = "march" },
{ any = [{ season = "fall" }, { season = "winter" }] }, # the season is winter or fall
{ weather = "pleasant" },
{ march_heart_level = 4, comparator = ">=" }
]There are many different uses for requires and many assertions that the game and we can use to filter in what context our dialogue should display and who should say it. For more information on this, see the appendix of this page below.
The npc’s portrait to be displayed with the line.
Adds an effect to the portrait, such as "sweat" or "music_notes".
This is the actual dialogue displayed in the dialogue box.
To use the player’s name, just use [Ari] within the dialogue string. To use the player’s pronouns, use tags for <he></he>, <they></they>, <it></it>, etc. If you need to use quotation marks, you can begin and end your string with three quotations: """. This line from Balor illustrates all three of these:
local = """They're saying things like "[Ari] is really something" and "<he>he's</he><she>she's</she><they>they're</they><it>it's</it><none>[Ari]'s</none> going to do big things in Mistria"!"""Mistria also supports 3 colors of text highlighting for different purposes, as well as shaky text for emotion. Special characters are used on either side, e.g. = for "=Golden Butter=".
| Special character | Text effect | Example |
|---|---|---|
$ |
Turns text yellow. Used for general purposes, such as game hints, non-gifted items, etc. |
"It looks like the claw once $held something in its grip$.", "Oh, excellent, the $Shards$ I asked for!"
|
= |
Turns text pink. Used for loved and liked gift dialogue. They are also sometimes used for quest turn-ins, like $. (The game isn't that consistent, so don't overthink it.) |
"Oh, a =Lemon=! They're my favorite fruit, you know." |
^ |
Turns text purple. Used for ~magical dialogue~ such as inscriptions, translated scrolls, and Priestess dialogue. | "^Hero... Help...^" |
# |
Makes text shake. Used for characters yelling or for emphasis. |
"Step right up, #step right up#!", "Not after... #The Incident.#"
|
The next line of dialogue. This will be a string of the name of the next line, usually a number. The next line of dialogue can then have its own local attribute, change portraits, etc.
Besides prompt, there is another way to create branching dialogue. By instead defining an array of targets with requires statements, we can branch dialogue using game logic. Take the following example (provided by pixie):
[march_five_hearts_pt2]
kind = "gameplay_triggered"
speaker = "march"
portrait = "neutral"
local = "Hey, [Ari]."
next = [
{target = "1_kissed", requires = [{ march_kissed = true }]},
{target = "1_nokiss", requires = []}
]Rather than a simple next = "1", we instead define an array of targets and requirements. In this example, if march_kissed is true, the dialogue will proceed to entry [march_five_hearts_pt2.1_kissed]. Otherwise, it will proceed to [march_five_hearts_pt2.1_nokiss]. If the first assertion made by requires is not true, it will proceed to the next target until the final one, where the requires array MUST BE EMPTY. If the final target's requires is not left empty, the game will crash when it gets to the dialogue.
Consider the following pseudocode:
if (A)
{
go to dialogue_A
}
else if (B)
{
go to dialogue_B
}
else
{
go to dialogue_C
}Using target, this would become:
[target_dialogue_example]
# ...
local = "First line of dialogue."
next = [
{ target = "a", requires = [{ A = true }] }, # note that your requires statement can be many different things, as mentioned above
{ target = "b", requires = [{ B = true }] },
{ target = "c", requires = [] }
]This is used for dialogue that Ari responds to. Ari’s possible responses and where the next dialogue leads to are provided as follows:
[four_to_five_0.1]
portrait = "wink"
local = "Got any tips?"
prompts = [{ local = "Hard work and lots of it!", next = "2" }, { local = "Hmm... got any dragon statues on your property?", next = "4" }] The maximum number of possible prompts is 3. Any more crashes the game with an array out of bounds exception. If your dialogue mod is crashing with this error (usually trying to reference index 3, meaning a fourth prompt counting from 0), it's probably because you've added too many prompt options.
If you wish to edit the prompts used in vanilla dialogue without rewriting the prompt line, you can use MOMI operations like so:
[[march_post_endgame_0_high_hearts_8r.prompts]]
MOMIidentify = { local = "It's fine March, really." }
local = "Eh, it's not like I really tried to change your perception of me."
next = "9"(example from ATD's farmer mod)
Mostly used for “barks”, which are the small speech bubbles that appear over npc’s heads sometimes during dialogue. Here’s an example of a bark command:
actions = [{ bark = { bark = "heart", npc = "hayden" } }]Here's a quick list of common types of barks used in dialogue:
- ellipses
- heart
- sweat_drop
- blush
- cute_face
- relationship_status
- angry
If you want a full list, check out animations/UI NEW/Barks and look through the icons.
Some lines can be given priority, which determines when they are selected over other lines. The default priority is "normal". When you see lines referred to as “basement”, that is a type of priority that is meant to be the lowest, so when an npc truly has nothing to say to Ari, that will be their default line. Here are the types of priorities:
-
"basement": (low)/ fallback -
"normal"(defined by default) -
"max"(immediate)
This is used to write to variables defined in t2.meta.toml. Often they are used in dialogue that relies on other dialogue that precedes it, such as following up to a date. When accompanied by expires, it returns to its previous value after the specified amount of in-game time. These interactions can be tricky, so be careful, especially when editing values originally defined by the vanilla t2 toml.
Used in specific types of dialogue, like flavortext that is meant to appear on interact with objects. This kind is set to "gameplay_triggered" and is often accompanied by no_speaker = true .
Set to true if there is no speaker (as in the case of object interact flavortext, signs, etc). Otherwise assumed false.
Used by dialogue with multiple speakers. Otherwise the speaker is whoever Ari is interacting with.
Dialogue comes in many forms, most of which are organized in the Conversations folder by name. This section is meant to give you an idea of generally what is possible in the current game’s dialogue system.
This section, located under Bank/<NPC>/Banked Lines is for dialogue that’s generally not dependent on Ari’s relationship to the NPC. They’re often repeatable.
These files are sorted by each type of date, containing acceptance lines as well as follow-up dialogue. Acceptance uses kind = "date_acceptance" and writes to a gate boolean to trigger follow-up dialogue at max priority within the following day.
These files are the NPC’s gift reactions. They use kind = "gift" as well as requires = [{ gift_given }]. requires can also use gift_desire. Here’s an example:
[golden_cheese]
refresh = "2w"
kind = "gift"
requires = [
{ npc = "hayden" },
{ gift_desire = "loved" },
{ gift_given = "golden_cheese" },
]
portrait = "neutral"
local = "This =Golden Cheese= is top notch!"Relationship lines are specifically grouped because they progress in a particular order. They are split into the Relationship folder and the Basement folder. The Relationship folder is for dialogue with progression, whereas the Basement folder is for low priority “basement” dialogue indicative of your relationship with the NPC.
Group dialogue usually requires all npcs be in the same place, usually by checking if their zones are equal to each others’. For example:
[animal_festival_march_olric]
...
requires = [
{ any = [{ npc = "march" }, { npc = "olric" }] },
{ march_zone = "<olric_zone>" },
...
]Dialogue with multiple npcs also uses the speaker attribute to determine which npc is speaking. (Otherwise it would just be the npc that Ari interacted with).
Threads are still being figured out, but from what we can understand, threads make use of specific variables like "thread_mutex" and "thread_delay" to control the flow of dialogue story progression. From what we can gather, the thread_mutex’s purpose is to make sure there is only one thread active for romanceable npcs at maximum and one thread active for non-romanceable npc’s at maximum. The thread_delay seems to determine how long until the player sees the next dialogue in the thread.
By appending to the t2.meta.toml, we can add custom variable to use with requires. Using vanilla dialogue as an example, we can make gates for dialogue, counters for types of interactions, and more!
Below is a non-exhaustive list of common assertions that can be made with requires. For the full list, check out t2.meta.toml.
| variable | description | usage |
|---|---|---|
npc |
Which npc or npcs should say this line. Most of the time this should just be one npc, although there are some general use lines with neutral portraits that are used in vanilla. | npc = "hayden" |
day_time |
The current time in 12 hour format. | day_time = "2:00pm", comparator = "<=" |
time_of_day |
The current time of day in general terms. Can be "morning", “afternoon”, "evening", or "night". |
time_of_day = "evening" |
weather |
The current day’s weather. [TODO: possible values] | weather = "pleasant" |
is_inside |
Can be true or false. | is_inside = false |
location |
Current location of Ari. For a full list of possible locations, see [TODO] | location = "haydens_farm" |
season |
Current season. Can be "spring", "summer", "fall", or "winter". |
season = "spring" |
thread_mutex , nd_thread_mutex
|
Used by threads to avoid conflicting dialogue. | For examples, see above. |
_heart_level (e.g. eiland_heart_level ) |
The heart level of the npc. |
{ hayden_heart_level = 3, comparator = ">=" }, { hayden_heart_level = 8, comparator = "<" } (hayden heart level 3 through 7) |
_is_dating , _is_best_friend, _is_partner , _is_fiance , _is_spouse , _is_ex (e.g. eiland_is_dating , etc) |
The relationship status between Ari and the npc. We assume that “partner” is true for fiance, spouse, and dating. | eiland_is_dating = true |
<npc>_routine |
The npc’s current routine . These are defined in the schedules section. |
march_routine = "forge_work_solo" |
<npc>_is_traveling |
The npc in question is walking from one location to another. | march_is_traveling = true |
<npc>_is_at |
The npc is at a specific trellis point. | hayden_is_at = "haydens_house/Hayden Counter" |