Modding:Dialogue: Difference between revisions
imported>BarleyZP →Roommate dialogue: Formatting fixes after migration |
imported>DolphinIsNotaFish No edit summary |
||
| (20 intermediate revisions by 7 users not shown) | |||
| Line 8: | Line 8: | ||
===Characters\Dialogue directory=== | ===Characters\Dialogue directory=== | ||
====Characters\Dialogue\{{t|NPC}}.xnb==== | ====Characters\Dialogue\{{t|NPC}}.xnb==== | ||
An NPC's named file in <samp> | An NPC's named file in <samp>Characters\Dialogue</samp> contains most of their dialogue. The game will select dialogue from one of the sections below, in the order shown. This means keys listed earlier in each table are checked first (and thus have higher priority), but note that some keys only apply in certain circumstances or have a random chance to be chosen, in which case lower-priority entries may appear. | ||
=====Special dialogue===== | =====Special dialogue===== | ||
| Line 30: | Line 30: | ||
|- | |- | ||
| <samp>GreenRain</samp> | | <samp>GreenRain</samp> | ||
| | | Shown on [[Weather#Green Rain|green rain]] days, unless overridden by <samp>GreenRain_2</samp>. | ||
|- | |- | ||
|- | |- | ||
| <samp>GreenRain_2</samp> | | <samp>GreenRain_2</samp> | ||
| | | Shown on [[Weather#Green Rain|green rain]] days in year two and subsequent years. If not set, defaults to <samp>GreenRain</samp>. | ||
|- | |- | ||
| <samp>HitBySlingshot</samp> | | <samp>HitBySlingshot</samp> | ||
| Line 42: | Line 42: | ||
| Possible dialogue lines shown above the NPC's name when they enter the named {{t|location}}, with a 50% chance. This dialogue entry can contain multiple options separated by <code>/</code>; the game will randomly choose one to display.<br /><small>Example: <samp>SeedShop_Entry: "Hi, Pierre!/Now, what do I need.../Ah, that looks good!/Makin' my special sauce tonight!/Pierre! What's fresh?/Pierre! Waddya got for me?"</samp></br>Note: This key is not to be confused with [[Modding:Dialogue#Speech_bubbles]]. | | Possible dialogue lines shown above the NPC's name when they enter the named {{t|location}}, with a 50% chance. This dialogue entry can contain multiple options separated by <code>/</code>; the game will randomly choose one to display.<br /><small>Example: <samp>SeedShop_Entry: "Hi, Pierre!/Now, what do I need.../Ah, that looks good!/Makin' my special sauce tonight!/Pierre! What's fresh?/Pierre! Waddya got for me?"</samp></br>Note: This key is not to be confused with [[Modding:Dialogue#Speech_bubbles]]. | ||
|- | |- | ||
| <samp>Resort</samp><br /><samp>Resort_Bar</samp><br /><samp>Resort_Chair</samp><br /><samp>Resort_Dance</samp><br /><samp> | | <samp>Resort_Entering</samp><br /><samp>Resort</samp><br /><samp>Resort_{{t|random}}</samp><br /><samp>Resort_Bar</samp><br /><samp>Resort_Bar_{{t|random}}</samp><br /><samp>Resort_Chair</samp><br /><samp>Resort_Chair_{{t|random}}</samp><br /><samp>Resort_Dance</samp><br /><samp>Resort_Dance_{{t|random}}</samp><br /><samp>Resort_Shore</samp><br /><samp>Resort_Shore_{{t|random}}</samp><br /><samp>Resort_Towel</samp><br /><samp>Resort_Towel_{{t|random}}</samp><br /><samp>Resort_Umbrella</samp><br /><samp>Resort_Umbrella_{{t|random}}</samp><br /><samp>Resort_Wander</samp><br /><samp>Resort_Wander_{{t|random}}</samp><br /><samp>Resort_Leaving</samp> | ||
| Various dialogue keys used when an NPC is visiting the Ginger Island Resort. | | Various dialogue keys used when an NPC is visiting the Ginger Island Resort. {{t|random}} is a number between 2 and N (dynamically determined by existing keys of the same type, provided that all from 2 to N are defined). Keys with a {{t|random}} require a base key (without a suffix) to be defined. The game rolls a number from 1 to N, and if 1 is chosen, the base key is used. | ||
|- | |- | ||
| <samp>SpouseFarmhouseClutter</samp> | | <samp>SpouseFarmhouseClutter</samp> | ||
| Line 96: | Line 96: | ||
| | | | ||
|- | |- | ||
| <samp>RejectBouquet_NotDatable</samp><br /><samp>RejectBouquet_NpcAlreadyMarried</samp><br /><samp>RejectBouquet_AlreadyAccepted_Engaged</samp><br /><samp>RejectBouquet_AlreadyAccepted_Married</samp><br /><samp>RejectBouquet_AlreadyAccepted | | <samp>RejectBouquet_NotDatable</samp><br /><samp>RejectBouquet_NpcAlreadyMarried</samp><br /><samp>RejectBouquet_AlreadyAccepted_Engaged</samp><br /><samp>RejectBouquet_AlreadyAccepted_Married</samp><br /><samp>RejectBouquet_AlreadyAccepted</samp><br /><samp>RejectBouquet_Divorced</samp><br /><samp>RejectBouquet_VeryLowHearts</samp><br /><samp>RejectBouquet_LowHearts</samp><br /><samp>RejectBouquet</samp> | ||
| Shown when the NPC rejects a [[bouquet]]. | | Shown when the NPC rejects a [[bouquet]]. | ||
A specific dialogue is shown if possible: | A specific dialogue is shown if possible: | ||
| Line 113: | Line 113: | ||
| <samp>RejectItem_{{t|id}}</samp><br /><samp>RejectItem_{{t|tag}}</samp> | | <samp>RejectItem_{{t|id}}</samp><br /><samp>RejectItem_{{t|tag}}</samp> | ||
| If set, the NPC will refuse to accept any matching item and show this dialogue instead. This can be by item ID (like <samp>RejectItem_(O)128</samp>) or context tag (like <samp>RejectItem_category_fish</samp>). This can prevent gifting, movie tickets, bouquets, mermaid pendants, etc. However it won't prevent accepting an item for an active quest or special order.<br /><br />Note: These dialogue keys will take precedence over the gift acceptance dialogue keys even if the rejection key is for a tag (less specific) and the acceptance key is for the ID (more specific). This means you cannot use these keys to reject a group of items (via a tag like <samp>category_gem</samp>, for example) and then use an <samp>AcceptGift_{{t|id}}</samp> to accept only one item from within that group. Instead, you must individually reject all the unwanted items within that group. | | If set, the NPC will refuse to accept any matching item and show this dialogue instead. This can be by item ID (like <samp>RejectItem_(O)128</samp>) or context tag (like <samp>RejectItem_category_fish</samp>). This can prevent gifting, movie tickets, bouquets, mermaid pendants, etc. However it won't prevent accepting an item for an active quest or special order.<br /><br />Note: These dialogue keys will take precedence over the gift acceptance dialogue keys even if the rejection key is for a tag (less specific) and the acceptance key is for the ID (more specific). This means you cannot use these keys to reject a group of items (via a tag like <samp>category_gem</samp>, for example) and then use an <samp>AcceptGift_{{t|id}}</samp> to accept only one item from within that group. Instead, you must individually reject all the unwanted items within that group. | ||
|- | |||
|- | |||
| <samp>''(Obsolete)'' give_pendant</samp> | |||
| Would show when an NPC accepted a [[Mermaid's Pendant|mermaid's pendant]] pre-1.6 update. | |||
As a workaround, add <samp>{{t|NPCInternalName}}_Engaged</samp> as an entry to Strings/StringsFromCSFiles instead. | |||
|- | |- | ||
| <samp>RejectMermaidPendant_AlreadyAccepted_Engaged</samp><br /><samp>RejectMermaidPendant_AlreadyAccepted_Married</samp><br /><samp>RejectMermaidPendant_AlreadyAccepted</samp><br /> | | <samp>RejectMermaidPendant_AlreadyAccepted_Engaged</samp><br /><samp>RejectMermaidPendant_AlreadyAccepted_Married</samp><br /><samp>RejectMermaidPendant_AlreadyAccepted</samp><br /> | ||
| Line 200: | Line 205: | ||
Unlike daily dialogue, location dialogue is endlessly repeatable as long as the trigger conditions are fulfilled, ''e.g.,'' Being in the location. They will not remove daily dialogue from an npc's dialogue rotation, but will merely overwrite it when the NPC is in the specified location. | Unlike daily dialogue, location dialogue is endlessly repeatable as long as the trigger conditions are fulfilled, ''e.g.,'' Being in the location. They will not remove daily dialogue from an npc's dialogue rotation, but will merely overwrite it when the NPC is in the specified location. | ||
'''Note:''' For location dialogue to work, an NPC must be giftable. If the NPC is not giftable (either because they lack gift tastes or have <samp>CanSocialize</samp> set to false), one workaround is to set their <samp>SocialTab</samp> field to <samp>AlwaysShown</samp>. | |||
{| class="wikitable" | {| class="wikitable" | ||
| Line 236: | Line 241: | ||
|- | |- | ||
| <samp>{{t|dayOfMonth}}</samp> | | <samp>{{t|dayOfMonth}}</samp> | ||
| Dialogue shown on the given day of month in the '''first year only.'''<br />'''WARNING: this first-year-only behavior is different from other keys and often catches unsuspecting modders!'''<br /><small>Example: <samp>10: "Did you watch the game last night?#$b#Or wait, do you even have a TV set...?"</samp></small> | | Dialogue shown on the given day of month in the '''first year only.'''<br />'''WARNING: this first-year-only behavior is different from other keys and often catches unsuspecting modders!''' You usually want <samp>{{t|dayOfMonth}}_*</samp> instead.<br /><small>Example: <samp>10: "Did you watch the game last night?#$b#Or wait, do you even have a TV set...?"</samp></small> | ||
|- | |- | ||
| <samp>{{t|dayOfMonth}}_{{t|firstOrLaterYear}}</samp> | | <samp>{{t|dayOfMonth}}_{{t|firstOrLaterYear}}</samp> | ||
| Dialogue shown on the given day of month in the [[#First/later year|first/later year]].<br /><small>Example: <samp>2_1: "My husband Kent is a soldier, working overseas. That's why he's not here right now.#$b#I know he'll come back safe once his tour is over!!#$e#Need something?"</samp></small> | | Dialogue shown on the given day of month in the [[#First/later year|first/later year]].<br /><small>Example: <samp>2_1: "My husband Kent is a soldier, working overseas. That's why he's not here right now.#$b#I know he'll come back safe once his tour is over!!#$e#Need something?"</samp></small> | ||
|- | |||
| <samp>{{t|dayOfMonth}}_*</samp> | |||
| Dialogue shown on the given day of month in any year.<br /><small>Example: <samp>18_*: "I try not to make too much noise down here. Imagine if the townspeople heard my weird sounds coming from the sewer drain..."</samp></small> | |||
|- | |- | ||
| <samp>{{t|dayOfWeek}}{{t|hearts}}_{{t|firstOrLaterYear}}</samp> | | <samp>{{t|dayOfWeek}}{{t|hearts}}_{{t|firstOrLaterYear}}</samp> | ||
| Line 318: | Line 326: | ||
|- | |- | ||
| <samp>OneKid_{{t|random}}</samp> | | <samp>OneKid_{{t|random}}</samp> | ||
| Dialogue shown when standing in the kitchen, if they have one child. {{t|random}} is a number 0–4, used to randomly select an entry.<br /><small><samp>OneKid_1</samp>: "''I wonder if %kid1 will grow up to be a farmer like you?''"</small> | | Dialogue shown when standing in the kitchen, if they have one child. {{t|random}} is a number 0–4, used to randomly select an entry.<br /><small>Example: <samp>OneKid_1</samp>: "''I wonder if %kid1 will grow up to be a farmer like you?''"</small> | ||
|- | |- | ||
| <samp>TwoKids_{{t|random}}</samp> | | <samp>TwoKids_{{t|random}}</samp> | ||
| Dialogue shown when standing in the kitchen, if they have two children. {{t|random}} is a number 0–4, used to randomly select an entry.<br /><small><samp>TwoKids_2</samp>: "''I had a dream that %kid2 will grow up to be a famous monster hunter. I've already been thinking about a little armor set.''"</small> | | Dialogue shown when standing in the kitchen, if they have two children. {{t|random}} is a number 0–4, used to randomly select an entry.<br /><small>Example: <samp>TwoKids_2</samp>: "''I had a dream that %kid2 will grow up to be a famous monster hunter. I've already been thinking about a little armor set.''"</small> | ||
|- | |||
| <samp>NoBed_{{t|random}}</samp> | |||
| Dialogue shown if there was no bed available the previous night. {{t|random}} is a number 0–3, used to randomly select an entry.<br /><small>Example: <samp>NoBed_3</samp>: "''Did something happen to our bed...?$s''"</small> | |||
|- | |- | ||
| <samp>{{t|affection}}_{{t|random}}</samp> | | <samp>{{t|affection}}_{{t|random}}</samp> | ||
| Line 465: | Line 476: | ||
|- | |- | ||
| <samp>{{t|NPC name}}_Engaged</samp></br><samp>{{t|NPC name}}_EngagedRoommate</samp> | | <samp>{{t|NPC name}}_Engaged</samp></br><samp>{{t|NPC name}}_EngagedRoommate</samp> | ||
| Shown | | Shown when the NPC accepts an engagement item (e.g. [[Mermaid's Pendant|mermaid's pendant]] or [[Void Ghost Pendant|void ghost pendant]] for vanilla NPCs), after accept/reject checks are complete. | ||
|} | |} | ||
| Line 510: | Line 521: | ||
| <samp>*</samp> | | <samp>*</samp> | ||
| Stands for "quickResponseDelineator". Converted in code to <samp>#$b#</samp>. Use in <samp>$y</samp> (dialogueQuickReponse) to achieve the effects of <samp>#$b#</samp>. You can use double asterisks <samp>**</samp> to escape a literal asterisk. | | Stands for "quickResponseDelineator". Converted in code to <samp>#$b#</samp>. Use in <samp>$y</samp> (dialogueQuickReponse) to achieve the effects of <samp>#$b#</samp>. You can use double asterisks <samp>**</samp> to escape a literal asterisk. | ||
|- | |||
| <samp>||</samp> | |||
| Stands for "rotateWeeklyDelimiter". Defines any number of dialogues to cycle through based on the in-game week number. (This is ''only'' based on the week number; it doesn't matter whether you've seen the previous week's dialogue.) | |||
For example, let's say you have this: | |||
<syntaxhighlight lang="js"> | |||
"Rainy_Night": "I love rain.$h||I like rain.$h||I adore rain.$h" | |||
</syntaxhighlight> | |||
You'll see the first dialogue during the entire first week, the second in the second week, the third in the third week, and then it loops back to the first dialogue on the fourth. | |||
|- | |- | ||
| <samp>^</samp> | | <samp>^</samp> | ||
| Line 602: | Line 623: | ||
"Mon": "$query !PLAYER_VISITED_LOCATION Current Mine#Did you know there's an old abandoned mine up in the mountain? Apparently it's crawling with monsters!|I heard you went into the old mines up in the mountain!#Did you find anything tasty?$h" | "Mon": "$query !PLAYER_VISITED_LOCATION Current Mine#Did you know there's an old abandoned mine up in the mountain? Apparently it's crawling with monsters!|I heard you went into the old mines up in the mountain!#Did you find anything tasty?$h" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
'''⚠ Careful:''' the query is checked when the dialogue is parsed, which isn't always when the player speaks to the NPC. For example, the NPC may check its dialogue after it finishes pathfinding somewhere. You shouldn't expect the query to be realtime (e.g. checking the player's location or equipped items may reflect an earlier point in the day). | |||
|- | |- | ||
| <samp>$r {{t|response ID}} {{t|friendship}} {{t|reaction}} {{o|observerfriendship}}#{{t|answer text}}</samp> | | <samp>$r {{t|response ID}} {{t|friendship}} {{t|reaction}} {{o|observerfriendship}}#{{t|answer text}}</samp> | ||
| Line 1,272: | Line 1,295: | ||
| 4 days | | 4 days | ||
| Set when the player divorces for the second time. | | Set when the player divorces for the second time. | ||
|- | |||
| <samp>LeoDeparture</samp> | |||
| same day | |||
| Set when [[Leo]] moves to the island (during the departure event at the island docks). | |||
|- | |- | ||
| <samp>pamHouseUpgrade</samp> | | <samp>pamHouseUpgrade</samp> | ||
Latest revision as of 23:07, 20 May 2026
← Index
This page explains how the game stores dialogue text, its format, and how the game parses it. This is an advanced guide for mod developers.
Dialogue data
Character dialogue is stored in many different files: The Characters\Dialogue directory is where the majority of NPC-specific dialogue is stored. Data\ExtraDialogue.xnb, Strings\Characters.xnb, Strings\Events.xnb, Strings\SpeechBubbles.xnb, and Strings\StringsFromCSFiles.xnb contain various other pieces of dialogue, some generic, and some NPC-specific.
Characters\Dialogue directory
Characters\Dialogue\<NPC>.xnb
An NPC's named file in Characters\Dialogue contains most of their dialogue. The game will select dialogue from one of the sections below, in the order shown. This means keys listed earlier in each table are checked first (and thus have higher priority), but note that some keys only apply in certain circumstances or have a random chance to be chosen, in which case lower-priority entries may appear.
Special dialogue
There are a few predefined keys for specific cases:
| key format | description | |
|---|---|---|
| breakUp | An NPC's response to being broken up with by giving them a wilted bouquet. | |
| divorced | Dialogue shown when you speak to your divorced spouse. | |
| DumpsterDiveComment | Shown when the NPC catches the player digging through a trash can. Defaults to a generic dialogue based on the NPC's age. | |
| GreenRain | Shown on green rain days, unless overridden by GreenRain_2. | |
| GreenRain_2 | Shown on green rain days in year two and subsequent years. If not set, defaults to GreenRain. | |
| HitBySlingshot | Shown when the player shoots them with a slingshot. Defaults to a generic dialogue. | |
<location>_Entry
|
Possible dialogue lines shown above the NPC's name when they enter the named <location>, with a 50% chance. This dialogue entry can contain multiple options separated by /; the game will randomly choose one to display.Example: SeedShop_Entry: "Hi, Pierre!/Now, what do I need.../Ah, that looks good!/Makin' my special sauce tonight!/Pierre! What's fresh?/Pierre! Waddya got for me?" Note: This key is not to be confused with Modding:Dialogue#Speech_bubbles. | |
| Resort_Entering Resort Resort_ <random>Resort_Bar Resort_Bar_ <random>Resort_Chair Resort_Chair_ <random>Resort_Dance Resort_Dance_ <random>Resort_Shore Resort_Shore_ <random>Resort_Towel Resort_Towel_ <random>Resort_Umbrella Resort_Umbrella_ <random>Resort_Wander Resort_Wander_ <random>Resort_Leaving |
Various dialogue keys used when an NPC is visiting the Ginger Island Resort. <random> is a number between 2 and N (dynamically determined by existing keys of the same type, provided that all from 2 to N are defined). Keys with a <random> require a base key (without a suffix) to be defined. The game rolls a number from 1 to N, and if 1 is chosen, the base key is used.
| |
| SpouseFarmhouseClutter | Shown by an NPC spouse when they couldn't pathfind to their kitchen standing spot in the farmhouse. | |
| SpouseGiftJealous | Shown by an NPC spouse if they become jealous after the player gives a gift to another NPC that the player is dating. Spouses have a 20-40% chance to become jealous of the gift-giving if the giftee is of the same gender as the spouse (unless it's the giftee's birthday). You can use {0} in the dialogue for the other NPC's name, and {1} for the gifted item name. | |
| Spouse_MonstersInHouse | Shown by an NPC spouse when they're in the farmhouse and there's a monster close to them. | |
| SpouseStardrop | Shown when receiving the stardrop from your spouse. | |
| WipedMemory | Shown the first time you talk to the NPC after erasing their memory using the Dark Shrine of Memory. |
Item dialogue
These keys apply when you present an item to an NPC:
| key format | description | |
|---|---|---|
AcceptBirthdayGift_<id>AcceptBirthdayGift_ <tag>AcceptBirthdayGift_ <taste>_<context tag>AcceptBirthdayGift_ <taste>AcceptBirthdayGift_Negative AcceptBirthdayGift_Positive AcceptBirthdayGift |
Shown when receiving a birthday gift from the player. If omitted, defaults to the generic translations for all NPCs. These keys will override AcceptGift_<id> and AcceptGift_<tag> even if the birthday key is less specific.
The first matching dialogue is used in this order:
| |
| AcceptBouquet | Shown when the NPC accepts a bouquet from the player. Defaults to a generic dialogue. | |
AcceptGift_<id>AcceptGift_ <tag>AcceptGift_ <taste>_<context tag>AcceptGift_ <taste>AcceptGift |
Shown when receiving a non-birthday gift from the player. If omitted, defaults to the dialogue in Data/NPCGiftTastes.
The first matching dialogue is used in this order:
| |
| MovieInvitation | An NPC's response to being invited to the Movie Theater. If not defined, the NPC will use a generic line from Strings\Characters.xnb depending on the NPC's manners. | |
| RejectBouquet_NotDatable RejectBouquet_NpcAlreadyMarried RejectBouquet_AlreadyAccepted_Engaged RejectBouquet_AlreadyAccepted_Married RejectBouquet_AlreadyAccepted RejectBouquet_Divorced RejectBouquet_VeryLowHearts RejectBouquet_LowHearts RejectBouquet |
Shown when the NPC rejects a bouquet.
A specific dialogue is shown if possible:
If the specific dialogue isn't set, the game will use the RejectBouquet dialogue (if set), else it'll default to generic dialogue for each case. | |
| RejectGift_Divorced | Shown when the NPC rejects a gift because you divorced them. | |
RejectItem_<id>RejectItem_ <tag>
|
If set, the NPC will refuse to accept any matching item and show this dialogue instead. This can be by item ID (like RejectItem_(O)128) or context tag (like RejectItem_category_fish). This can prevent gifting, movie tickets, bouquets, mermaid pendants, etc. However it won't prevent accepting an item for an active quest or special order. Note: These dialogue keys will take precedence over the gift acceptance dialogue keys even if the rejection key is for a tag (less specific) and the acceptance key is for the ID (more specific). This means you cannot use these keys to reject a group of items (via a tag like category_gem, for example) and then use an AcceptGift_ <id> to accept only one item from within that group. Instead, you must individually reject all the unwanted items within that group.
| |
| (Obsolete) give_pendant | Would show when an NPC accepted a mermaid's pendant pre-1.6 update.
As a workaround, add | |
| RejectMermaidPendant_AlreadyAccepted_Engaged RejectMermaidPendant_AlreadyAccepted_Married RejectMermaidPendant_AlreadyAccepted RejectMermaidPendant_Divorced |
Shown when the NPC rejects a mermaid's pendant.
A specific dialogue is shown if possible. The cases are checked in this order:
If the specific dialogue isn't set, the game will use the RejectMermaidPendant dialogue (if set), else it'll default to generic dialogue for each case. | |
| RejectMovieTicket_AlreadyInvitedBySomeoneElse RejectMovieTicket_AlreadyWatchedThisWeek RejectMovieTicket_Divorced RejectMovieTicket_DontWantToSeeThatMovie RejectMovieTicket |
Show when the NPC rejects a movie ticket.
A specific dialogue is shown if possible:
If the specific dialogue isn't set, the game will use the RejectMovieTicket dialogue (if set), else it'll default to generic dialogue for each case. | |
| RejectRoommateProposal_AlreadyAccepted RejectRoommateProposal_NpcWithSomeoneElse RejectRoommateProposal_PlayerWithSomeoneElse RejectRoommateProposal_LowFriendship RejectRoommateProposal_SmallHouse RejectRoommateProposal |
(Optional) Shown when the NPC rejects a roommate proposal because the player doesn't meet a specific requirement:
If the specific dialogue isn't set, the game will use the RejectRoommateProposal dialogue (if set), else it'll default to generic dialogue. | |
accept_<item_id>reject_ <item_id>
|
(Obsolete) These are specialized keys meant for the pirate lady quest. Use AcceptGift_* and RejectItem_* instead. |
Festival dialogue
| key format | description |
|---|---|
| Fair_Judging | Shown at the Stardew Valley Fair while Lewis is judging the grange displays. If omitted, the NPC will keep their normal festival dialogue.
If this is set without Fair_Judged*, the NPC will keep this dialogue after judging is done. |
| Fair_Judged_PlayerLost_PurpleShorts Fair_Judged_PlayerLost_Skipped Fair_Judged_PlayerLost Fair_Judged_PlayerWon Fair_Judged |
Shown at the Stardew Valley Fair after Lewis finishes judging the grange displays.
The first matching dialogue is used in this order:
|
| FlowerDance_Accept_Roommate FlowerDance_Accept_Spouse FlowerDance_Accept |
Shown at the Flower Dance when the NPC agrees to dance. The game will prefer the _Roommate (if roommates) or _Spouse (if married) variant if applicable, else it'll check for the normal key. If omitted, defaults to a generic accept dialogue. |
| FlowerDance_Decline |
Shown at the Flower Dance when the NPC declines to dance. (A different dialogue is used if they've already agreed to dance with another player.)
danceRejection is a deprecated older name (which still works as a fallback). |
| WinterStar_GiveGift_Before_Roommate WinterStar_GiveGift_Before_Spouse WinterStar_GiveGift_Before WinterStar_GiveGift_After_Roommate WinterStar_GiveGift_After_Spouse WinterStar_GiveGift_After |
Shown at the Feast of the Winter Star when the NPC gives the player their gift (before and after the player opens it). The game will prefer the _Roommate (if roommates) or _Spouse (if married) variant if applicable, else it'll check for the normal key. If omitted, the before/after dialogues each separately default to a generic translation for all NPCs. |
WinterStar_ReceiveGift_<id>WinterStar_ReceiveGift_ <tag>WinterStar_ReceiveGift |
Shown at the Feast of the Winter Star when receiving their gift from the player. This can be by item ID (like WinterStar_ReceiveGift_(O)128), context tag (like WinterStar_ReceiveGift_category_fish), or for any item (like WinterStar_ReceiveGift). If omitted, defaults to the generic translation for all NPCs. |
Location dialogue
Otherwise the game will choose dialogue in this order.
Variants:
- Each key can optionally be prefixed with a season name, like springMountain_47_23.
The game will check variants in this order: <season><key>, and <key>. The variants aren't listed below for simplicity.
Unlike daily dialogue, location dialogue is endlessly repeatable as long as the trigger conditions are fulfilled, e.g., Being in the location. They will not remove daily dialogue from an npc's dialogue rotation, but will merely overwrite it when the NPC is in the specified location.
Note: For location dialogue to work, an NPC must be giftable. If the NPC is not giftable (either because they lack gift tastes or have CanSocialize set to false), one workaround is to set their SocialTab field to AlwaysShown.
| key format | description |
|---|---|
<location>_<x>_<y>
|
Dialogue shown in the named location when the NPC is standing at tile position <x>, <y>.Example: Mountain_47_23: "I come here for the peace and quiet." |
<location>_<dayName>
|
Dialogue shown in the named location on the given day of week. Example: Saloon_Fri: "Business has been really good tonight. I'm pleased." |
<location><hearts>
|
Dialogue shown in the named location if you have at least <hearts> hearts with them. The <hearts> will be checked in the order 10, 8, 6, 4, 2 (no other value will be recognised).Example: Saloon8: "Hi there @. I'm glad to see you! You're always welcome here." |
<location>
|
Dialogue shown in the named location. Example: Saloon: "Now that I'm here I can finally relax and socialize a bit."
|
Generic dialogue
Otherwise the game will choose a dialogue using one of these key formats (in precedence order):
<season>_<key>_inlaw_<spouse><season>_<key><key>_inlaw_<spouse><key>
For each variation above: <season> is a season name (like spring_14); _inlaw_<spouse> matches if the player is married to the named NPC, regardless of whether the speaking NPC is related to the named one (like Sat_inlaw_Abigail); and <key> is one of the formats listed below.
| key format | description |
|---|---|
<dayOfMonth>
|
Dialogue shown on the given day of month in the first year only. WARNING: this first-year-only behavior is different from other keys and often catches unsuspecting modders! You usually want <dayOfMonth>_* instead.Example: 10: "Did you watch the game last night?#$b#Or wait, do you even have a TV set...?" |
<dayOfMonth>_<firstOrLaterYear>
|
Dialogue shown on the given day of month in the first/later year. Example: 2_1: "My husband Kent is a soldier, working overseas. That's why he's not here right now.#$b#I know he'll come back safe once his tour is over!!#$e#Need something?" |
<dayOfMonth>_*
|
Dialogue shown on the given day of month in any year. Example: 18_*: "I try not to make too much noise down here. Imagine if the townspeople heard my weird sounds coming from the sewer drain..." |
<dayOfWeek><hearts>_<firstOrLaterYear>
|
Dialogue shown on the given day of week if you have at least <hearts> hearts with them, in the first/later year. The <hearts> will be checked in the order 10, 8, 6, 4, 2 (no other value will be recognised).Example: Thu2_2: "Well, my Dad is back. Have you met him?#$b#I'm just glad he's okay." |
<dayOfWeek><hearts>
|
Dialogue shown on the given day of week if you have at least <hearts> hearts with them. The <hearts> will be checked in the order 10, 8, 6, 4, 2 (no other value will be recognised).Example: Sun4: "Hey, @.#$e#How's your day going?" |
<dayOfWeek>_<firstOrLaterYear>
|
Dialogue shown on the given day of week in the first/later year. Example: Sat_1: "Dad's coming back soon!#$b#I hope he brings me some toys.$u" |
<dayOfWeek>
|
Dialogue shown on the given day of week. Example: Mon: "Oh, hey. Taking a break from work?" |
Specific NPCs
| NPC | key format | description |
|---|---|---|
| Gil | ComeBackLater Snoring |
Gil's dialogue when you haven't completed any new Adventure Quest goals. ComeBackLater will be shown once, and all subsequent dialogues will show Snoring. |
Rain dialogue
Characters\Dialogue\rainy.xnb contains one dialogue entry per NPC. There's a roughly 50% chance they'll use this dialogue if a special or location dialogue doesn’t match, it's raining, and you're not married to or divorced from them.
Marriage dialogue
Characters\Dialogue\MarriageDialogue.xnb contains dialogue text for all spouses, and each NPC may optionally have their own dialogue file like Characters\Dialogue\MarriageDialogueAbigail.xnb. When looking up a dialogue key, it will use the one in the NPC's file if it exists, else the one in the generic file, else a default text (usually blank).
Each dialogue entry has a key with one of these formats:
| key format | description |
|---|---|
<season>_<day>
|
Dialogue shown when the day starts, if <season> and <day> match the current date.Example: fall_1: "The scent is unmistakable... mushroom, rotting leaves, pumpkin. It's fall, alright. Isn't it lovely?" |
patio_<spouse>
|
Dialogue shown when the NPC is standing on the patio. |
<weather>_Day_<random>
|
Daily dialogue added when the day starts, based on the <weather> (Rainy if it's raining, else Indoor even if they're not indoors) and <random> (a random number between 0 and 4). If the game chooses a <random> value that doesn't have a dialogue, it'll use the default text instead.
|
Rainy_Night_<random>
|
Daily dialogue in the farmhouse after 6pm when it's raining. <random> is a number between 0–5 inclusively or the NPC name, each of which has an equal chance of being randomly chosen. If the game chooses a <random> value that doesn't have a dialogue, it'll use the default text instead.Example: Rainy_Night_3: "On nights like this, I like to turn the light down low and just listen...$8" |
Indoor_Night_<random>
|
Daily dialogue in the farmhouse after 6pm when it's not raining. <random> is a number between 0–4 inclusively or the NPC name, each of which has an equal chance of being randomly chosen. If the game chooses a <random> value that doesn't have a dialogue, it'll use the default text instead.
|
funLeave_<spouse>
|
Dialogue used when leaving the farmhouse (except when using the hardcoded marriageJob schedule key) |
jobLeave_<spouse>
|
Dialogue used when leaving to go to their job. Only used for Maru, Penny, and Harvey. |
funReturn_<spouse>
|
Dialogue shown after 1pm when they enter the farmhouse but before reaching their target position (except when using the hardcoded marriageJob schedule key) Example: funReturn_Abigail: "Hey! Did you have a good day? Mine went well. It was refreshing to take a walk.$h" |
jobReturn_<spouse>
|
Dialogue shown after 1pm when for Maru, Penny, and Harvey enter the farmhouse but before reaching their target position, when using the hardcoded marriageJob schedule key. Example: jobReturn_Penny: "#$c .5#Good evening. My day was fine, thanks! How was yours?$h#$e#Jas and Vincent weren't behaving very well today. I'm still all wound up..." |
<season>_<spouse>
|
Dialogue shown at 9+ heart levels with a 5% chance each day. Example: fall_Abigail: "Do I smell pumpkin on you? Maybe I'm just dreaming...$h" |
Outdoor_<spouse>
|
Dialogue shown on the farm with a 20% chance. Example: Outdoor_Abigail: "I'm just going to hang out here, okay?#$e#There's a lot of interesting bugs and things out here. *chuckle*$h" |
Outdoor_<random>
|
Dialogue shown on the farm with an 80% chance. <random> is a number 0–4, used to randomly select an entry.Example: Outdoor_3: "It's pretty cool that we have a cave on our property. It's something I always dreamed about.$h" |
spouseRoom_<spouse>
|
Dialogue shown when the NPC is in their room. Example: spouseRoom_Abigail: "$c .5#I got up a little before you and fed David Jr. He's very active this morning.#$e#I hope you don't mind the guinea pig smell." |
OneKid_<random>
|
Dialogue shown when standing in the kitchen, if they have one child. <random> is a number 0–4, used to randomly select an entry.Example: OneKid_1: "I wonder if %kid1 will grow up to be a farmer like you?" |
TwoKids_<random>
|
Dialogue shown when standing in the kitchen, if they have two children. <random> is a number 0–4, used to randomly select an entry.Example: TwoKids_2: "I had a dream that %kid2 will grow up to be a famous monster hunter. I've already been thinking about a little armor set." |
NoBed_<random>
|
Dialogue shown if there was no bed available the previous night. <random> is a number 0–3, used to randomly select an entry.Example: NoBed_3: "Did something happen to our bed...?$s" |
<affection>_<random>
|
Dialogue shown inside the farmhouse between 11am and 6pm, or when the day starts if a different dialogue isn't selected. <affection> is randomly Bad or Neutral if they have less than 9 hearts; 50% chance of Good if you have 10 hearts, 87.5% chance of Good if you have 11 hearts, and 99.4% chance of Good if you have 12+ hearts; else Neutral <random> is a number 0–9, used to randomly select an entry.Example: Good_5: "I was just admiring the mermaid's pendant you gave me... I'll proudly wear this to my grave.$l" |
Roommate dialogue
The game's marriage logic can treat any NPC (including custom NPCs), not just Krobus, as a roommate.
These keys apply before they move in:
| content file | key | effect |
|---|---|---|
| Strings/StringsFromCSFiles | <NPC name>_EngagedRoommate
|
The NPC's roommate proposal accept dialogue. ⚠ Ignored if you don't specify Data/EngagementDialogue: <NPC name>Roommate0.For example: A Void Ghost pendant! How did you...?$3#$b#Oh, wow.$7#$b#@... yes, I'll come live with you, if you like. But we have to keep it secret from everyone.#$b#I'll be at your house in a few days... okay?$h |
| Strings/Characters | MovieInvite_NoTheater | The NPC's roommate proposal rejection text when you don't meet the requirements (i.e., min friendship + house upgrade level, and not already having a roommate/spouse). This is the same dialogue used when you can't invite someone to the movies. |
| Data/EngagementDialogue | <NPC name>Roommate0<NPC name>Roommate1
|
The NPC's normal dialogue after accepting the proposal, but before moving in. The Roommate0 variant is always used on the day the NPC accepted; on subsequent days the NPC randomly chooses Roommate0 or Roommate1. If the Roommate0 variant isn't defined, the NPC will use the normal <NPC Name>0 and <NPC Name>1 keys. If the Roommate0 variant is defined, Roommate1 must be set too to avoid errors.For example: @... I'm afraid we'll have to keep this a secret... Neither my people nor yours would accept us living together. |
And after they move in:
| content file | key | effect |
|---|---|---|
Characters/Dialogue/MarriageDialogue<NPC name>Roommate
|
all keys | Equivalent to Characters/Dialogue/MarriageDialogue<NPC name>, but only applies if the NPC is a roommate. If the file exists, it completely replaces the spouse version; otherwise the game defaults to the spouse version.
|
| Characters/Dialogue/MarriageDialogue | *Roommate | Keys with the Roommate suffix take priority if they exist (only in this file, not the MarriageDialogue<NPC name> files).
|
| Data/Festivals/* | <NPC name>_roommate
|
The NPC's normal dialogue at the festival if they're a roommate. If the key isn't defined, they'll use <NPC name>_spouse instead.
|
And for other NPCs:
| content file | key | effect |
|---|---|---|
| Characters/Dialogue/* | *_roommate_* | Equivalent to the *_inlaw_* infix in generic dialogue, used if you're a roommate with the NPC. If not defined, the game will fallback to the non-infixed dialogue (it won't use the *_inlaw_* variant). |
Data directory
Engagement dialogue
Similar to the rain dialogue, Data\EngagementDialogue.xnb contains entries in the form of <NPC>0 and <NPC>1, which are used when you are engaged but not yet married to an NPC, or, in the case of a roommate, when they have been invited but have not yet moved in.
Event files
Data\Events\*.xnb contains event scripts, including any dialogue in the event (see Modding:Event data).
Extra dialogue
Data\ExtraDialogue.xnb contains miscellaneous strings, some of which are NPC specific:
| key format | description |
|---|---|
| PurchasedItem_* | Randomly shown by a non-child town NPC after you sell an edible item to a shop. These keys are hardcoded, and you can't add new keys with a similar pattern.
For keys with a number infix (like PurchasedItem_5_Cooking), the number is selected as such:
|
| Town_DumpsterDiveComment_Child Town_DumpsterDiveComment_Teen Town_DumpsterDiveComment_Adult Town_DumpsterDiveComment_Linus |
Shown when an NPC catches you rummaging through trash cans, depending on the NPC's age. Linus has his own dialogue, but other NPCs don't. |
SummitEvent_Dialogue3_<spouse>
|
Shown for your NPC spouse near the start of the perfection cutscene. |
Movie theater dialogue
An NPC's reaction to a movie is stored in Data\MoviesReactions.xnb, which is structured far differently from every other dialogue file. See Modding:Movie theater data for more details.
Strings directory
Animation descriptions
Strings\animationDescriptions.xnb contains short bits of dialogue to go with certain schedule points. Not to be confused to Data\animationDescriptions.xnb, which contains the data of animations, rather than the strings for their description.
Characters
Strings\Characters.xnb contains miscellaneous dialogue, some of which is NPC-specific:
| key format | description |
|---|---|
MovieInvite_Spouse_<NPC name>
|
Shown when the NPC accepts a movie ticket when they're married to you. If missing, defaults to a MovieInvite_Invited_* key. |
MovieInvite_Invited_<NPC name>MovieInvite_Invited_ <manner>MovieInvite_Invited_ <socialAnxiety>MovieInvite_Invited_ <optimism>MovieInvite_Invited_ <age>MovieInvite_Invited |
Shown when the NPC accepts a movie ticket. The NPC will use the first key that exists in the order listed here.
The |
| Phone_* | Shown when calling a shop owner NPC on the telephone. These keys are hardcoded, so new keys with the same pattern will be ignored. |
Events
Strings\Events.xnb contains miscellaneous dialogue related to events and festivals, some of which is NPC-specific.
Speech bubbles
Strings\SpeechBubbles.xnb contains dialogue spoken by NPCs through speech bubbles when the player enters a given location. This is distinct from the <location>_Entry field in an NPC's Characters\Dialogue\*.xnb file, which is triggered when the NPC enters a given location.
These keys are hardcoded, so new keys with the same pattern will be ignored.
Strings from CS files
Strings\StringsFromCSFiles.xnb contains miscellaneous strings, such as dialogue that's shared between multiple characters, dialogue for some hardcoded events like marriage, etc.
The file has entries in the form "<key>": "dialogue string", where the key is an arbitrary unique identifier. These must exactly match the key expected by the game, but the keys are just unique identifiers — even though most keys look like <file name>.<line number>, that's just the convention originally used to assign IDs and it has no meaning or effect (nor does it even necessarily match the current file name or line number).
In most situations, if the game is unable to find a string for an NPC to say, it will default to NPC.cs.4061 (English version: "Hi.").
Some other useful NPC-specific strings stored here are as follows:
| key format | description |
|---|---|
<NPC name>_AfterWedding
|
Shown after marrying an NPC, when you talk to them on the farm on the same day. |
<NPC name>_Engaged<NPC name>_EngagedRoommate
|
Shown when the NPC accepts an engagement item (e.g. mermaid's pendant or void ghost pendant for vanilla NPCs), after accept/reject checks are complete. |
Algorithm
The game finds dialogue as follows:
- Event dialogue is read from the appropriate event commands (see Modding:Event data).
- Location-specific dialogue is read from StringsFromCSFiles
<location>.cs. - Else character dialogue is read from the character-specific files.
- If no dialogues were found, the game resorts to hardcoded dialogue from the StringsFromCSFiles files (specifically keys prefixed with NPC.cs NPC.cs).
Format
Dialogue text can contain tokens and commands which control the dialogue box, change the text (e.g., switch between gender-specific strings), inject values, etc. These are parsed by the Dialogue class.
Gender switch
| syntax | description |
|---|---|
| ${male^female}$ ${male^female^non-binary}$ |
Change text depending on the player's gender. The non-binary value is only used if a mod overrides the player's gender, since the in-game UI only allows male or female.
This is applied before most other commands or parsing, so it can safely be used in cases where ^ might have a different meaning (e.g. mail text). You can also use ¦ instead of ^, in which case any ^ characters are left as-is. Example: |
Special tokens
| character | description |
|---|---|
| # | Separates two commands in a dialogue string. |
| { | TODO. Stands for "breakSpecialCharacter". |
| % | Turns the dialogue box into a generic text box. Example: "%Abigail is lost in her music."
|
| * | Stands for "quickResponseDelineator". Converted in code to #$b#. Use in $y (dialogueQuickReponse) to achieve the effects of #$b#. You can use double asterisks ** to escape a literal asterisk. |
| || | Stands for "rotateWeeklyDelimiter". Defines any number of dialogues to cycle through based on the in-game week number. (This is only based on the week number; it doesn't matter whether you've seen the previous week's dialogue.)
For example, let's say you have this: "Rainy_Night": "I love rain.$h||I like rain.$h||I adore rain.$h"
You'll see the first dialogue during the entire first week, the second in the second week, the third in the third week, and then it loops back to the first dialogue on the fourth. |
| ^ | (Deprecated) Most code should use the newer ${...} form above, which is supported in more places.
Gender switch character. The text before it is shown for male farmers, the text after it for female farmers. |
Portrait commands
These set the portrait shown in the dialogue box for the current line of dialogue. If there's no portrait command, the neutral portrait is used.
Portraits are numbered left-to-right and top-to-bottom, starting at $0. The first six portraits are standard, and can be identified by the number (like $2) or a unique alias (like $s). All potential spouses and many other characters have these six portraits, but it's not fully consistent; for example, Caroline only has four.
| numbered | alias | description |
|---|---|---|
| $0 | Use their neutral portrait. | |
| $1 | $h | Use their happy portrait. |
| $2 | $s | Use their sad portrait. |
| $3 | $u | Use their unique portrait. This is different for each NPC: grumpy (Abigail), holding football (Alex), angry (Caroline), sick (Governor), etc. |
| $4 | $l | Use their love portrait. |
| $5 | $a | Use their angry portrait. |
$<id>
|
A custom portrait beyond the standard six. |
Portrait commands should be at the end of a dialogue line:
"fall_Fri6": "When I was a little girl, my father abandoned us.$s#$b#I'm sorry to make things uncomfortable for you...$u#$e#Anyway... How's the farming life going?",
Dialogue commands
| command | description |
|---|---|
$action <action>
|
Run a trigger action string, like $action AddMoney 500 to add |
| $b | Indicates pauses in dialogue, where the player will need to click for the next part to load in a new dialogue box. |
$c <probability>#<text1>#<text2>
|
Show <text1> with a <probability> between 0 and 1; otherwise, show <text2>. E.g. $c 0.9 for a 90% chance of <text1> and a 10% chance of <text2>. NOTE: Replacer commands (see below) do not work in <text1>. This does not need to be the first command in a dialogue string. It is unaffected by daily luck.
|
$d <state id>#<text1>|<text2>
|
Show one of two dialogue strings based on a predefined condition: bus (whether the bus is repaired), joja (whether the Joja Mart is still in business), cc or communitycenter (whether the Community Center is accessible), or kent (whether Kent has returned to the valley). The dialogue string must start with $d, everything up to the first | symbol is shown if the condition matches, and everything after that is shown if the condition doesn't match.
For example: "Mon2": "$d kent#Yesterday I visited Yoba's Altar to give thanks for my husband's safe return.|Yesterday I visited Yoba's Altar to ask for my husband's safe return.#$e#I'm trying to stay positive, but it's hard sometimes.$s"
|
| $e | Ends the current dialogue, closing the dialogue box and resuming player control. The dialogue following $e will require a new interaction with the NPC. |
| $k | Short for dialogueKill. Removes all dialogue messages after the current one. |
$p <response ID>#<match text>|<no-match text>
|
Stands for "dialoguePrerequisite". Shows different text depending on whether the player gave a particular answer to a previously-asked question. If <response ID> matches an answer the player gave, <match text> is shown; otherwise, <no-match text> is shown. These texts are separated by | and only <no-match text> can contain additional commands. This does not need to be the first command in the dialogue string.
You can check multiple response IDs. For example, this will show the first dialogue if the player chose dialogue answer 17, 18, or Apple: $p 17|18|Apple#I guess you think nothing would happen, right?$u|Maybe a wicked ghost would appear! |
$q <response IDs> <fallback>#<text>
|
Show a dialogue box containing the given question text. If <response IDs> (a list delimited by /) contains an answer already given, the question is skipped (along with the rest of this dialogue line), and instead the dialogue entry identified by <fallback> will be appended to whatever precedes this $q command. The <fallback> dialogue typically uses a $p command to adjust the text based on the player's answer to this question. NOTE: dialogue questions must use unique IDs, similar to events. See the event data page for more information.
|
$query <query>#<if true>|<if false>
|
Show different dialogue text depending on the game state query in <query>. For example:
"Mon": "$query !PLAYER_VISITED_LOCATION Current Mine#Did you know there's an old abandoned mine up in the mountain? Apparently it's crawling with monsters!|I heard you went into the old mines up in the mountain!#Did you find anything tasty?$h"
⚠ Careful: the query is checked when the dialogue is parsed, which isn't always when the player speaks to the NPC. For example, the NPC may check its dialogue after it finishes pathfinding somewhere. You shouldn't expect the query to be realtime (e.g. checking the player's location or equipped items may reflect an earlier point in the day). |
$r <response ID> <friendship> <reaction> [observerfriendship]#<answer text>
|
Define a response option to a $q question dialogue. <answer text> is the text shown. <response ID> is used to group responses for future reference (multiple answers can share an answer ID). <friendship> defines the change in friendship value with the speaker, positive or negative, if this response is selected. <reaction> names the dialogue entry from the NPC's Content\Characters\Dialogue\*.xnb file that will be the NPC's reaction if this response is selected by the player. [observerfriendship] is an underscore (_) separated string which, if included, affects the friendship with another NPC if this response is selected. It takes the format of friend_NPCID_Integer, e.g. "friend_George_-20" or "friend_Penny_40".
|
$t <topic ID> [day length]
|
Add a conversation topic for the next [day length] days (default 4 days).
|
$v <event id> [check preconditions] [skip if seen]
|
Immediately start an event and end the current dialogue, subject to the conditions:
If the event is not played, the dialogue continues to the next line instead. For example, Note: The command will only work if it is at the very start of the dialogue. Adding any dialogue or other commands before it will cause it not to trigger the event and display the event commands as dialogue instead. |
$y '<answer>_<reply>'
|
Stands for "dialogueQuickResponse"; A simpler form of question. Works like $q, but within one and the same text line. It doesn't have response IDs that can be used with "dialoguePrerequisite" ($p). It can't be used for friendship point changes. It can be triggered indefinitely. It doesn't have to be the first command in a dialogue string as long as the dialogue before it ends with #$e# or #$b#. It can have more than two answer/reply pairs. Example: Penny: "$y 'Breakfast?_Yes please._Here you go._No, I'm good_More for me then!'" |
$1 <letter ID>#<1st-time text> #$e# <nth-time text>
|
Creates a line of dialogue which the character will only see once (at most). <1st-time text> is shown only if <letter ID> has not been marked as sent yet (and this marks it as sent); otherwise, <nth-time text> is shown. <letter ID> should not correspond to an actual piece of mail (because it will not be sent), but it can be referenced by events or other dialogue lines.
|
| %fork | Sets the the specialEventVariable1 variable, which can be checked by a later fork event command. Mainly useful in reaction dialogue for $q questions during events. |
%revealtaste:<NPC name>:<item ID><NPC><object ID> |
Reveals the named character's gift taste for an object in their social menu profile. For example, %revealtaste:Lewis:(O)258 will update Lewis's profile to show that he likes blueberries. This only works if it's in the first message in a dialogue box (i.e., before any #$b# break, though #$e# breaks are fine).
The second form is deprecated and only works with unqualified numeric item IDs. |
[<id>+]
|
Gives the player a random item, from the pool of item IDs within the brackets. For example, "I spent the afternoon daydreaming about the ocean. So I decided to cook some seafood. [(O)198 (O)202 (O)727 (O)MossSoup]$h"
Each one can be a qualified or unqualified item ID. |
Question example
To understand how $q, $r, and $p work, an example may be helpful. Note how you can format the script to be easier to read:
summer_Fri:
"I think I'll go to the beach tomorrow!
#$q 305/306 beachquestion_followup#Would you like to go with me?
#$r 305 15 beachquestion_yes#Sure, I would love to!
#$r 306 0 beachquestion_sorry#Oh, sorry, I've already made plans with someone else...
#$r 306 -10 beachquestion_no#No thank you.
",
"beachquestion_yes": "Good! It's a date.$h",
"beachquestion_sorry": "Oh. Darn. Okay.$6",
"beachquestion_no": "Oh. Um. Sorry.$s",
"beachquestion_followup":
"$p 305
#Tomorrow should be a lot of fun!$h
|Hmm, I wonder if I can get someone to go with me...$s
",
summer_Sat:
"The beach is lovely this time of year...
#$p 305
#Thanks for coming with me today.$h
|Oh, hi @, how's it going?
",
The dialogue above triggers on any Friday in the summer. The NPC begins with a response that is always shown: "I think I'll go to the beach tomorrow!"
Next they ask you a question.
#$q 305/306 beachquestion_followup#Would you like to go with me?
$q starts the question. 305/306 checks to see if this question has been asked before, and if it has it sends you to the dialogue key beachquestion_followup. (Note that you can name your dialogue keys whatever you like which makes it easier to read.)
Next are the responses the player can give. You can add any number of $r lines; here we have three:
#$r 305 15 beachquestion_yes#Sure, I would love to!
#$r 306 0 beachquestion_sorry#Oh, sorry, I've already made plans with someone else...
#$r 306 -10 beachquestion_no#No thank you.
If you say yes (first option), the game will store ID 305 as the answer given to this question. Next, your friendship with that person increases by 15. beachquestion_yes tells the script which dialogue key continuation to use as a response to your answer.
If you say no (second and third option) the game will store ID 306 as the answer given, then depending on which answer you gave will either not change your friendship with the person, 0, or reduce it, -10. Then it will use either beachquestion_sorry or beachquestion_no to continue the dialogue.
Now we need to make dialogue keys for each response:
beachquestion_yes: "Good! It's a date.$h",
beachquestion_sorry: "Oh. Darn. Okay.$6",
beachquestion_no: "Oh. Um. Sorry.$s",
beachquestion_followup:
"$p 305
#Tomorrow should be a lot of fun!$h
|Hmm, I wonder if I can get someone to go with me...$s
",
Of note here is beachquestion_followup. If the player talks to the NPC again, $q 305/306 will check that the question has already been answered and instead go directly to this key.
$p 305 begins a variable response which means "if the player chose yes, say this line, else say this line instead". If the player answered yes, the NPC responds happily. Otherwise, they will comment that they need to find someone to go with them.
There is another variable response the next day:
summer_Sat:
"The beach is lovely this time of year...
#$p 305
#Thanks for coming with me today.$h
|Oh, hi @, how's it going?
",
Once again the first line (The beach is lovely...) always shows up when the player talks to the NPC, but the next line depends on whether or not they've answered yes the previous day.
Here is another example from Haley's existing dialogue file. Note how the script formatting is harder to read, but the game is able to process both.
summer_Sat: "Farming sounds so boring...#$q 42/43 summer_Sat_old#What do you even do all day?#$r 42 10 summer_Sat_12#Care for plants#$r 42 10 summer_Sat_12#Explore the caves#$r 43 -10 summer_Sat_13#Snoop around in your room#$r 42 10 summer_Sat_12#Dig for treasure" #!String
summer_Sat_old: "#$p 43#Hey, you better not be snooping around in my room anymore!$a|But I guess it could get you in pretty good shape." #!String
summer_Sat_12: "Hmm... sounds like a lot of work." #!String
summer_Sat_13: "What? You'd better not be doing that!$a" #!String
The first time the summer_Sat dialogue is chosen, neither response 42 nor 43 will have been given (because this question is the only one which has them as responses), so Haley will say, "Farming sounds so boring... What do you even do all day?" The player can select among these responses:
- Care for plants
- Explore the caves
- Snoop around in your room
- Dig for treasure
The third response, $r 43 -10 summer_Sat_13#Snoop around in your room, sets response ID 43, reduces Haley's friendship by 10 points, and brings up the dialogue summer_Sat_13 (Haley says, "What? You'd better not be doing that!"). All of the other responses set response ID 42, increase Haley's friendship by 10 points, and bring up the dialogue summer_Sat_12 ("Hmm... sounds like a lot of work.").
The next time summer_Sat is chosen, one of the response IDs listed in the $q command will have been given (either 42 or 43). Therefore, the $q and everything after is scrapped, and dialogue summer_Sat_old is put in its place. This new dialogue uses the $p command to change Haley's dialogue based on whether or not you gave response ID 43 to any previous question. If you answered "Snoop around your room," everything before the | will be used, so Haley will now say, "Farming sounds so boring... Hey, you better not be snooping around in my room anymore!" If response ID 43 has not been given (in this case, you must have given response ID 42, i.e., one of the other three responses to the previous question), everything after the | will be used, so Haley will instead say, "Farming sounds so boring... But I guess it could get you in pretty good shape."
Replacer commands
Replacer commands will be replaced with the relevant string. Note that in mail entries, only the @ replacer works.
| command | description |
|---|---|
| @ | Farmer's name. Example: Hi there @!
|
| %adj | Random adjective. (Defined in StringsFromCSFiles.xnb) |
| %noun | Random noun. (Defined in StringsFromCSFiles.xnb) |
| %place | Random place name. (Defined in StringsFromCSFiles.xnb) |
| %spouse | The name of Farmer's spouse. |
| %name | A randomly-generated name. |
| %firstnameletter | The first half of the farmer's name (rounded down), like Nat if the farmer's name is Natalie. |
| %time | Current time. |
| %band | The name of Sam and Sebastian's band. |
| %book | The title of Elliott's book. |
| %pet | The name of Farmer's pet. |
| %farm | Farm name. |
| %favorite | The Farmer's favorite thing. |
| %kid1 | The name of Farmer's first child. |
| %kid2 | The name of Farmer's second child. |
Values
The game uses these predefined values in some dialogue keys. This section is linked from above where needed.
Days of week
- Mon
- Tue
- Wed
- Thu
- Fri
- Sat
- Sun
Seasons
- spring
- summer
- fall
- winter
First/later year
In some cases the game uses a "first/later year" value for dialogue conditions. This only has two possible values:
| value | meaning |
|---|---|
| 1 | Occurs in the first year. |
| 2 | Occurs in any year after the first (not only year 2). |
Response IDs
A response ID identifies an answer chosen by the player in response to a question dialogue. In some cases a question may have several answers with the same ID (e.g., several variations of "yes"), or use the same ID for every question (in which case the ID just shows whether the player has answered the question).
Mods can add their own response IDs, but here are the vanilla IDs as of 1.3.36¹:
- Dialogue
NPC question answers Abigail fall_Sun
I was thinking about dyeing my hair again... what do you think?27: Dye it black.
27: Why not blonde?
27: How about bubblegum pink?
28: I like your hair just the way it is!Abigail summer_Sun
Okay... pretend you just won a free vacation. Where would you go?25: The beach
26: In a dark cave
26: The old, gnarled forest
25: Joja Mega-MallAbigail Sun2
@, What do you think happens to us after we die?17: I have no idea.
18: We come back as spooky ghosts.
17: We go to Heaven.
18: Our energy bodies enter the astral plane.
17: Nothing. We just cease to exist.Abigail winter_Sun
I made these two drawings. What do you think?29: I like the jungle island and the tiger.
30: I like the orc with the battleaxe.
29: I don't like either of them.Alex fall_Wed
Do you think the ladies like my haircut?^What do you think about my haircut?54: It looks very fashionable.
55: It looks like some kind of fungal growth.Alex summer_Wed
Do you think I'll ever turn pro?52: You're destined to be a sports legend
52: Maybe, if you practice a lot
53: No, you'll most likely fail and become a salesmanAlex Wed
I'd ask you to throw the ball around, but you don't really seem like the sports type.^If you weren't a girl I'd ask you to play catch.6: I'm fine just watching you from a distance.
5: I want to play catch with you!
5: (angry) What's that supposed to mean?Clint Mon
I bet you can't guess what my great-grandfather was...9: A blacksmith.
9: A silly clown.
9: A sarcastic jerk.Haley fall_Sat
*sigh*...what do you think I should do today?44: Watercolor painting
44: Relax and read a magazine
44: Stop being a selfish crybabyHaley summer_Sat
What do you even do all day?42: Care for plants
42: Explore the caves
43: Snoop around in your room
42: Dig for treasureLeah Mon
So why did you become a farmer?21: I want to make tons of money.
22: It's more "real" than living in the city.
211132: To follow in grandpa's footsteps.
22: I wanted to escape my old life.Maru summer_Thu
I've decided I'm going to build a robot someday.35: That should be very easy for you
36: You should be more realistic
35: It sounds challengingMaru Sun
Do you have fun working on the farm?3: Yes.
4: No.Penny Mon4
But it's best not to dwell on bad things, right?7: Right. It's best to be positive!
8: I think it's good to be realistic.Sam Wed
Hey.. What do you think my new song should be about?20: Farming, mining, and chopping wood.
8820: A city in the sea.
8821: Trains.
19: Choose anything. It'll still be a horrible song.Sebastian fall_Fri
Do you read, @?62: Yep. The classics.
63: Only Sci-fi and Fantasy
62: I like a good Romance
63: No, I don't read booksSebastian Fri2
So what do you do when you aren't working?15: More Farming
16: Comic books
15: Shopping
15: Sports
- Events
event question answers Abigail's 4-heart event @! Why are you out here in the rain?$7 32: Just doing some work
32: Enjoying the weather
32: I could ask you the same questionAbigail's 6-heart event You've used a sword before, haven't you? 847951: Yes, and it's exciting!
847951: Yes, but only in self-defense
847951: Yes, but it's dangerous. You should stay safe.
847951: NoAbigail's 10-heart event *sniff*$s 776589: What happened?
776589: Are you okay?Abigail's 10-heart event I guess I'm not as tough as I thought...$8 34: You're safe with me.
34: I get scared too.
34: You're crying like a little baby. Stop.Alex's 5-heart event I'm worthless...$s 57: That's crazy. You're a genius!
57: We all have our strengths and weaknesses
57: Worthless? Yeah, that about sums it up.Clint's 3-heart event Got any tips?^What advice can you give me? 211: Impress women with your strength and charm
211: Act crazy, to keep people guessing
211: Just act natural... be yourself
211: Treat women the same as menDemetrius's 6-heart event How would you classify a tomato? 59: Vegetable
59: FruitElliott's 2-heart event A question... What kind of books do you like, @? 958699: Mystery
958700: Romance
958701: Sci-FiElliott's 4-heart event Wait. I propose a toast! To... 28376: To Pelican Town!
28376: To our friendship!
28376: To my good health!
28376: To your doom!Emily's 6-heart event So... *gasp*... what did you think?$h 213: That was amazing!
213: That was embarrassing...
213: (Say nothing and do a slow clap)Evelyn's 4-heart event Well, what do you think? 51: It's delicious!
51: It was like chewing on a hockey puckGus's 4-heart event @, what's going on here? 207: You need to pay your tab right now!
208: The saloon isn't doing well, financiallyHaley's 2-heart event It's only because I cleaned them last week!$a 46: Stop whining and just clean it!
45: Haley, why not have this be your one weekly job?
46: Emily, take the high road and do it this time.Haley's 4-heart event Say... you're pretty strong, aren't you? 47: Yes
47: NoHaley's 6-heart event I'll never find another one like it...$s 48: Relax, I'll just buy you a new one!
48: I'm really sorry...Harvey's 2-heart event @, what do you think George should do? 84: George should follow Dr. Harvey's advice.
85: George knows what's best for his own body.Harvey's 4-heart event Hmm... Your pulse is high.$u 86: I'm a little nervous...
86: I'm out of breath from working on the farm.
86: Are you really a doctor? My pulse is fine!Kent's 3-heart event (Say something to Kent)$s 215: Jodi's to blame... she should've known better!
215: I know you're hurting... but don't blame your wife.
215: (Lie) Blame me... I asked for popcornLeah's 4-heart event Was that selfish of me, @?$s 83: No, it had to be done.
83: No, and your ex sounds like an idiot.
83: No, but you would've been better off staying in the city.
83: Yeah, a little.
83: Yeah, but it's natural to care about yourself first.Lewis's 6-heart event @...You overheard everything, didn't you?$s 200: Yes... but I'll keep it a secret.
201: Yes... and I'm going to tell everyone.Maru's 2-heart event Right, @? 15933: (Say nothing)
15933: Actually, your Dad was being weird.Maru's 4-heart event @, what should I do? 38: Just scoop it off the floor. He won't know the difference.
39: Tell Harvey it was my fault.
38: Tell Harvey it was an accident.Maru's 6-heart event What do you see? 40: A beautiful planet.
40: A cold, dark abyss.Maru's 8-heart event I'm so sorry.$8 41: It's okay, it doesn't even hurt.
41: You'd better be. This hurts like crazy!Maru's 10-heart event Well, what do you think, @? 18981: I'm so impressed with your inventions.
18981: I'm disappointed... You should've made that robot your slave.
18981: So is your Dad okay with 'us' now?
18981: (Just stare at Maru and say nothing)Maru's 10-heart event You must have a good reason for saying that...$a 18982: MarILDA's just a piece of machinery designed to act human.
18982: I was just kidding. MarILDA deserves her freedom.
18982: I would've put her to work on the farm.Penny's 2-heart event @? You were watching us? 71: I was. You did a kind thing there, Penny.
71: You should've left him alone. Now he's grumpy.
71: I'm just taking a walk, minding my own business.Penny's 6-heart event ...well? 72: (Lie) Mmm! That was delicious!
73: Uh... can I get the rest to go?
73: Well it's definitely unique... how did you get it so rubbery?Pierre's 6-heart event Promise me you won't tell anyone about this. 50: Your secret is safe with me.
50: Your wife deserves to know about this.Robin's 6-heart event Have you ever made anything out of wood, @? 66: Yes
66: NoSam's 2-heart event Say, @... what kind of music do you like? 76: Cheerful pop music.
77: Experimental noise rock.
78: Hi-Energy dance music.
79: Honky-tonky country music.Sam's 4-heart event ...Tell her, @.$s 80: Sam dropped the snack as he was handing it to me.
80: Sam handed me the snack and then I dropped it.
81: Sam dropped it on purpose. He thought it would be funny.
¹ Extracted using this LINQPad script.
Conversation topics
A conversation topic is a temporary flag which can be checked in event preconditions and game state queries and can trigger one-time NPC dialogue (if they have a matching dialogue key). They're stored in Farmer.activeDialogueEvents while active, and are moved from there into Farmer.previousActiveDialogueEvents once they expire.
Since they are temporary, they are very useful for scheduling delays between events: for example, once a topic is added, you can have a subsequent event precondition only satisfied if the topic is not active, so the topic's duration in days must elapse before the event can be viewed.
A conversation topic can be started in a number of ways:
- using the
addConversationTopicevent command - using the
AddConversationTopictrigger action - using the
$tdialogue command - using the
%item conversationTopicmail command - in code by calling
Farmer.activeDialogueEvents.TryAdd(string, int)
A conversation topic lasts four days by default. All methods listed above can optionally specify a preferred duration instead.
Topic memory
In addition to the normal active time, the game also keeps track of how long ago topics were set and automatically generates additional topics after a certain number of days. These topics always use the original key and append _memory_<time> to it (please note: the game checks for keys to contain the string "_memory_" to control its behavior here, so you should avoid using that string in your topic IDs if possible).
Here are the keys and how long they take to appear. All of them last for four days.
| id | days since original key |
|---|---|
<key>_memory_oneday
|
1 |
<key>_memory_oneweek
|
7 |
<key>_memory_twoweeks
|
14 |
<key>_memory_fourweeks
|
28 |
<key>_memory_eightweeks
|
56 |
<key>_memory_oneyear
|
104 |
Note that the _memory_oneyear key entry is not a typo, and starts after 104 days, which is slightly less than one full year (112 days).
Generic topics
These topics are generated by the game in response to the player fulfilling certain conditions. These topics automatically cover any mods that add data alongside vanilla, so (for example) any mod-added events will generate eventSeen_ topics, any NPCs will generate married_ when the player marries them, etc. Combined with topic memory, this gives you a lot of power to time events and coordinate NPC behavior without having to do any extra work.
All of these topics last for four days.
| id | trigger |
|---|---|
achievement_<id>
|
Player earns the given achievement for the first time. |
cropMatured_<object id>
|
Player has harvested a fully-grown crop of the given type for the first time. |
dating_<npc internal name>
|
Player begins dating the given NPC for the first time (only set when the player gives the NPC a bouquet and it is accepted; other means of changing the relationship do not count). |
divorced_<npc internal name>
|
Player divorces the given NPC for the first time (only set when using the book in the Mayor's Manor; does not apply to roommates). |
eventSeen_<id>
|
Player sees the given event for the first time. |
firstVisit_<location name>
|
Player enters the given location for the first time. |
fishCaught_<id>
|
Player catches the given fish for the first time. |
houseUpgrade_<level>
|
Player upgrades their house to the given level (e.g. 2). |
married_<npc internal name>
|
Player marries the given NPC for the first time (only set by watching the wedding event with that NPC; other means of changing the relationship do not count). |
mineArea_<area>
|
Player enters the given mine area (an integer) for the first time. This is 0 for floors 1-10, 10 for floors 11-39, 40 for floors 40-79, 80 for floors 80-120, 121 for any Skull Cavern floors, and 77377 for the Quarry Mine. (FIXME: there may be other values for MineShafts with level == -1) |
purchasedAnimal_<type>
|
Player buys the given animal type for the first time. |
questComplete_<id>
|
Player completes the given quest for the first time. |
roommates_<npc internal name>
|
The given NPC moves in as the player's roommate for the first time. |
structureBuilt_<type>
|
Player builds the given type of farm building for the first time. |
Specific topics
These topics are generated by the game in response to specific events and don't use any variables in their keys.
| id | duration | trigger |
|---|---|---|
| Bundles | ||
| cc_Begin | 4 days | Set in the Wizard's cutscene after reading the first Junimo note in the community center. |
| cc_Complete | 4 days | Community Center completed. (Does not apply to JojaMart path.) |
| cc_Boulder | 7 days | Mountain boulder is removed through community center bundle or Joja improvement form. |
| cc_Bridge | 7 days | Quarry bridge is repaired through community center bundle or Joja improvement form. |
| cc_Bus | 7 days | Bus is repaired through community center bundle or Joja improvement form. |
| cc_Greenhouse | 3 days | Greenhouse is constructed through community center bundle. (Does not apply to JojaMart path.) |
| cc_Minecart | 7 days | Minecarts are unlocked through community center bundle or Joja improvement form. |
| joja_Begin | 7 days | First time that player opens the Joja Community Development Form. |
| movieTheater | 3 days | movie theatre is constructed. |
| Spouse events | ||
| elliottGone | 6 days | Set when Elliott's fourteen-heart event starts. |
| ElliottGone1 ElliottGone2 ElliottGone3 ElliottGone4 ElliottGone5 ElliottGone6 ElliottGone7 |
same day | Part of Elliott's fourteen-heart event. The first flag is set when it starts; the subsequent flags are set by subsequent letters from Elliott. |
| emilyFiber | 2 days | Part of Emily's fourteen-heart event. Set after completing the quest. |
| haleyCakewalk1 haleyCakewalk2 |
same day | Part of Haley's fourteen-heart event. |
| leahPaint | same day | Set when Leah's fourteen-heart event starts. |
| pennyRedecorating | 2 days | Part of Penny's fourteen-heart event. |
| samJob1 samJob2 |
2 days | Part of Sam's fourteen-heart event. |
| samJob3 | 3 days | Part of Sam's fourteen-heart event. |
| sebastianFrog | same day | Set when Sebastian's fourteen-heart event starts. |
| sebastianFrog2 | 6 days | Part of Sebastian's fourteen-heart event. |
| shaneSaloon1 shaneSaloon2 |
same day | Part of Shane's fourteen-heart event. |
| Other events | ||
| gotPet | 4 days | Set if the player chooses to adopt the first pet when Marnie brings it to their front porch. |
| dumped_Guys dumped_Girls |
7 days | Set after the corresponding ten-heart group event (e.g., see Abigail#Group Ten-Heart Event). |
| secondChance_Girls secondChance_Guys |
14 days | Set after the corresponding ten-heart group event (e.g., see Abigail#Group Ten-Heart Event). |
| GreenRainFinished | 2 days | Set after the Green Rain event in year one. |
| dating | 4 days | Set when the player starts dating an NPC for the first time. |
| married | 4 days | Set when the player marries for the first time. |
| married_twice | 4 days | Set when the player marries for the second time. |
| divorced_once | 4 days | Set when the player divorces for the first time. |
| divorced_twice | 4 days | Set when the player divorces for the second time. |
| LeoDeparture | same day | Set when Leo moves to the island (during the departure event at the island docks). |
| pamHouseUpgrade | 4 days | Set after seeing the Pam house upgrade event, if the player chose to be revealed as the donor. |
| pamHouseUpgradeAnonymous | 4 days | Set after seeing the Pam house upgrade event, if the player chose to be anonymous. |
| willyCrabs | 4 days | Set after Willy's six-heart event. |
| wonEggHunt | 4 days | Set when the player wins the Egg Hunt for the first time. |
| wonGrange | 4 days | Set when the player wins the Grange Display showcase for the first time. |
| wonIceFishing | 4 days | Set when the player wins the Ice Fishing Contest for the first time. |
| Other | ||
| Introduction | 6 days | Farmer is created (e.g., starting a new save, or joining a multiplayer game for the first time). |
| FullCrabPond | 14 days | First time any fish pond contains 10 crabs. |
For C# mods
Dialogue class
A sequence of NPC dialogues is represented by a Dialogue instance. Some useful fields/methods include:
| member | usage |
|---|---|
| dialogues | The 'dialogue lines' to display. Each entry is shown in a single dialogue box (but isn't necessarily a single line or sentence).
Each dialogue line can have text to show, a side effect (i.e. code to run when it's displayed), or both. If an entry has a side-effect, it's applied as soon as that dialogue entry is shown in the dialogue box. If the entry has no text, the game skips to the next entry in the list (if any) after applying the side-effect. |
| speaker | The NPC instance speaking the dialogue line, if applicable. |
| CurrentEmotion | The portrait command for the current dialogue line. |
| TranslationKey | The translation key from which the current dialogue line was taken, if applicable. |
| getCurrentDialogue() | Get the formatted dialogue text currently being displayed. |
| getPortraitIndex() | The index from the NPC's portraits spritesheet to display for the current dialogue line. |
| isOnFinalDialogue() | Whether the dialogue is currently showing last dialogue line which has text to display. |
| isDialogueFinished() | Whether all dialogue lines have been shown. |
| convertToDwarvish() | Replace the current dialogue line with the Dwarvish translation (as spoken by Dwarf when the player doesn't have the dwarvish translation guide). |
The Dialogue class also provides a number of static methods for working with dialogues. Some of the main ones include:
| method | usage |
|---|---|
| TryGetDialogue(…) | Create a dialogue for a given NPC and translation key, or return null if the translation key isn't found.
This is commonly used to implement fallback dialogues. For example: Dialogue? dialogue =
Dialogue.TryGetDialogue(npc, $"Charaxters\\Dialogue\\{npc.Name}:SomeKey_{relationship}")
?? Dialogue.TryGetDialogue(npc, "Charaxters\\Dialogue\\{npc.Name}:SomeKey");
Note that this is somewhat low-level. In most cases, you should use the equivalent NPC.TryGetDialogue method which reads from the NPC's dialogue file. For example: Dialogue? dialogue =
npc.TryGetDialogue($"SomeKey_{relationship}")
?? npc.TryGetDialogue("SomeKey");
|
| FromTranslation(…) | Create a dialogue for a given NPC and translation key. This is similar to TryGetDialogue, but an invalid dialogue key is shown as-is instead. |
| GetFallbackForError() | Get a fallback dialogue to show when an error happens and a suitable dialogue can't be loaded. This is some variation of "..." depending on the language. |
| applyGenderSwitchBlocks(…) | Process gender switch blocks in a given text. This works with any text by design, not just dialogue text. You can either use the current player's gender, or specify a gender to use.
For example: string text = Dialogue.applyGenderSwitchBlocks("Hello ${lad^lass}$!"); // results in "Hello lad!" or "Hello lass!"
|
| convertToDwarvish(text) | Get the Dwarvish translation for a given dialogue line (as spoken by Dwarf when the player doesn't have the dwarvish translation guide). |
DialogueBox class
DialogueBox is the menu shown in-game when a message box is displayed. This is usually an NPC dialogue, but it's also used for some non-NPC messages.
Some useful fields include:
| field | usage |
|---|---|
| characterDialogue | If this is a standard NPC dialogue, the Dialogue instance being shown. |
| dialogues | If this is a custom dialogue, the dialogue lines being shown. |
| isPortraitBox() | Whether the dialogue box has an NPC portrait. |
For NPC dialogues, you can use the MenuChanged event to detect when a specific dialogue is shown. For example:
private void OnMenuChanged(object sender, MenuChangedEventArgs e)
{
bool isAbigailDanceRejection =
e.NewMenu is DialogueBox dialogueBox
&& dialogueBox.characterDialogue is {} dialogue
&& dialogue.speaker?.Name == "Abigail"
&& dialogue.TranslationKey == "Characters\\Dialogue\\Abigail:danceRejection";
}