Table of Contents

Chatter

Chatter lines data is used with chatter ability to allow the trinket to "speak". It's important to keep in mind that the Chatter system has nothing to do with the vanilla NPC dialogue keys beyond ability to reuse the same strings via translation key.

Chatter data is stored on the tinker asset, as Dictionary<string, ChatterLinesData>, while the portrait, NPC, or display name is stored with variants. On ability activation, one set of ChatterLinesData will be picked based on priority and Condition, then one line out of the list will be chosen.

Relevant Variant Data

See variants for more info

Property Type Default Notes
Portrait string null A portrait texture, required to display a portrait and a name.
NPC string null An NPC name (key of Data/Characters) to associate this variant with, used to derive the display name.
Name string null A display name, used if there's no NPC.

The reason why Portrait/NPC/Name is stored with variants is so that you can associate portraits with their sprite, much like the appearance system in vanilla.

For trinkets that are meant to reuse a real NPC's portraits, using the NPC field is preferred as it will make the dialogue box compatible with portraiture.

Sample Chatter Lines

Sample

{
  "Action": "EditData",
  "Target": "mushymato.TrinketTinker/Tinker",
  "TargetField": [
    "{{ModId}}_Sample"
  ],
  "Entries": {
    "Chatter": {
      "<chatter key 1>": {
        "Condition": "<game state query>",
        "Priority": 0,
        "Lines": [
          "literal text (via {{i18n: key}})",
          "translation key (e.g. Strings/Asset:Key)",
          "tokenized text (e.g. [LocalizedText Strings/Asset:Key])"
        ],
        "Responses": {
          "<response key 1>": "{{i18n: key}}/Strings/Asset:Key/[LocalizedText Strings/Asset:Key]",
          "<response key 2>": "{{i18n: key}}/Strings/Asset:Key/[LocalizedText Strings/Asset:Key]",
        }
      },
      // more chatter entries
    }
  }
}

ChatterLinesData

Property Type Default Notes
Condition string "TRUE" A game state query used to check if this chatter should be picked. If you want to have chatter exclusively activate through ability with ProcChatterKey, use "FALSE".
Priority int 0 Sort priority of this chatter, higher number have their conditions checked first.
Lines List<string> null List of dialogue for this entry, this can be:
Responses Dictionary<string, string> null Response keys, needed only if your dialogue has $q that point to responses.

Choosing the next Dialogue Line

The Chatter system picks the next line to display by this logic.

  1. If the previous dialogue has not finished (i.e. $e is used), finish that dialogue first.
  2. If a ProcChatterKey has been set and exists, skip the rest of the steps and pick that Chatter.
  3. Chatter data is sorted by Priority (highest to lowest)
  4. The first Chatter data that fits these conditions is picked:
    • Key starts with ChatterPrefix (if set)
    • Condition evaluates to true
    • There are at least 1 Lines in this Chatter
  5. A random dialogue from Lines is chosen with equal chance.

Lines may freely repeat, so it's a good idea to use Condition to gate what lines you'd like to show.

Using $q in Chatter

Question depend on having key'd responses. To utilize this with Chatter, question goes in Lines, while matching response keys go in Responses.

(The following example is adapted from the official wiki)

Example:

"DialogueWithQuestion": {
  "Lines": [
    "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."
  ],
  "Responses": {
    "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",
  }
}

Response keys ARE remembered, so after the first time the question is asked and answered, dialogue box will fall back to beachquestion_followup instead of offering choices.