-
-
Notifications
You must be signed in to change notification settings - Fork 2
Dialogue
English | 日本語
The Dialogue library is DragNWash.ModFramework.Dialogue.dll, in the namespace DragNWash.ModFramework.Dialogue. It tells your mod which line of dialogue or option is about to be shown, with its Yarn line ID, speaker and node. It also helps a mod find its data for a line again after a game update has edited that line.
[BepInDependency(GameDialogue.Guid, BepInDependency.DependencyFlags.HardDependency)]GameDialogue.NodeStarted += node => Logger.LogInfo($"Node {node}");
GameDialogue.LineShowing += line =>
Logger.LogInfo($"{line.LineId} {line.Speaker}: {line.Text}");
GameDialogue.OptionShowing += option =>
Logger.LogInfo($"Option {option.LineId} available={option.IsAvailable}: {option.Text}");Handlers run just before the text appears. If one throws, the exception is logged and the others still run.
| Property | Meaning |
|---|---|
string LineId |
Yarn line ID, for example line:6046bedf. It stays the same across languages and across game updates that only fix typos |
string Speaker |
The character's name as written in the script (Ryan), or null. The game's script doesn't name a speaker in most lines, so this is empty for nearly every line; see SpeakerGuess below |
string Text |
The text without the name |
string FullText |
The text with the name, as the script has it (Ryan: Hello) |
IReadOnlyList<string> Metadata |
Yarn tags, for example lastline
|
string Node |
The Yarn node, when known |
TMP_Text Component |
The component the text is about to go into |
bool IsOption |
True for an option the player can pick |
bool IsAvailable |
For options: false when it's struck through |
Experimental. This came in with framework 1.4.0 and may change or go away in a later version.
Dialogue 1.2.0 adds two properties to DialogueLine:
| Property | Meaning |
|---|---|
string SpeakerGuess |
Who says the line: Speaker when the script names one, else a guess from the node's name (the part before the first _: Ryan_1_intro is Ryan), and Kobold (the player) for an option. Null when there's nothing to go on |
string SpeakerFrom |
Where the guess came from: script, node, option, or null |
Use Text to change the text, and TryGetLine to find out which line the rewriter is looking at:
GameText.AddRewriter(MyMod.Guid, context =>
{
if (GameDialogue.TryGetLine(context.Component, context.Source, out DialogueLine line)
&& line.LineId == "line:6046bedf")
{
context.Text = "Hello there!";
}
});TryGetLine only matches while the component is still showing that line (with or without the name, or struck through), so whatever the component shows later won't match.
Experimental. This came in with the Dialogue library 1.1.0 (released 2026-09-17).
If your mod keeps data about a line of dialogue (a translation, a bookmark, a chapter marker), it needs to find that line again after a game update. Keying by the exact English text breaks on the smallest edit. The September 14, 2026 update fixed typos in 24 lines, and every translation of those lines fell back to English. Keying by the Yarn line ID alone breaks when the developers re-tag or recreate lines. So LineKey and LineResolver key a line four ways and try the strongest first.
LineKey computes them, and tools/linekeys.py in the repository computes the same keys with the same definitions. None of them contain the text, so a repository that ships them doesn't ship any of the game's script.
| Key | Definition | Survives |
|---|---|---|
| Line ID | Yarn's line:xxxxxxxx tag, as DialogueLine.LineId gives it |
any edit to the text |
| Hash | first 16 hex digits of SHA-256 over the UTF-8 text, exactly as the component receives it (tags included) | nothing; this is the key translation packs use |
| Normalized hash | the hash of the normalized text: <tags> removed, ASCII letters lowercased, everything but letters, digits and spaces dropped, runs of whitespace collapsed to one space |
edits to punctuation, capitalisation, spacing and TextMeshPro tags |
| Fingerprint | a 64-bit SimHash of the normalized text: every 3-character window is hashed with FNV-1a 64 and votes on each bit | small edits; similar texts are a few bits apart (LineKey.Distance) |
Yarn line IDs are tags the Yarn compiler writes into the script file once, so they stay put when the developers edit a line's text. They only change when a line is recreated or the script is re-tagged.
LineResolver holds your mod's records (a LineRecord has the keys above, the node and speaker the line was seen with, and any payload you like) and answers Resolve(line, displayedText):
-
Line ID. If a record has the line's ID, it wins. If the record's hash differs from the text on screen, the match is flagged
NeedsReview, since the text changed and the mod's data for it may be out of date. - Hash. This matches the exact displayed text.
- Normalized hash. It's only used when exactly one record has it. Texts like "Yes." that several lines share are never guessed.
-
Fuzzy. Among the records of the same node (or all records when the node is unknown, and none when the node has no records), it takes the one with the nearest fingerprint. That only happens if it's within 10 bits, nothing else is that near (ties are broken by speaker, otherwise refused), and both texts are at least 12 characters after normalization. The match is flagged
NeedsReview.
Anything else returns null. The resolver would rather show nothing than the wrong line.
We measured this on the game's 1,839 dialogue lines, using the game's own data and keeping it local (the repository holds only the results):
- Across the September 14 update, 0 line IDs disappeared, and 24 lines kept their ID while their text changed. The line ID alone would have kept all 24 translated.
- We edited 300 random lines three ways (a one-character typo, punctuation, capitalisation). The normalized hash and the fingerprint recovered 68% / 93% / 91% of them, and the rest were refused as too short or ambiguous. No edit was matched to the wrong line.
var resolver = new LineResolver();
// From your data file: keys the tool wrote, plus what you keep for the line.
resolver.Add(new LineRecord { LineId = "line:6046bedf", Hash = "84f325bca745e504", NormalizedHash = "…", Fingerprint = 0x…, NormalizedLength = 10, Node = "Ryan_1_intro", Speaker = "Ryan", Payload = "素晴らしい!" });
GameDialogue.LineShowing += line =>
{
LineMatch match = resolver.Resolve(line, line.FullText);
if (match != null)
{
Use((string)match.Record.Payload);
if (match.NeedsReview) Log($"{line.LineId}: text changed, check the translation");
}
};To make records from text you saw on screen, use LineResolver.RecordFor(text, lineId, node, speaker, payload), which computes every key for you. Outside the game, python tools/linekeys.py "text" prints the same keys, and python tools/linekeys.py --check checks the Python against ci/linekey-vectors.json. The repository's CI checks the C# side against that same file.
Experimental. This came in with framework 1.4.0 and may change or go away in a later version.
Dialogue 1.2.0 registers two read operations in the Operations registry, and you can run them with the Console's op command:
| Operation | Returns |
|---|---|
dialogue.current |
The conversation now: whether one is running (running), its node, whether options are on screen (options_showing), the last line shown, and whether this game build lets the library see lines and options at all (hooks) |
dialogue.recent |
The last lines and options shown this session (up to 100 are kept), newest last, each with its kind, line ID, node, speaker, where the speaker came from, and text. Parameters: text (only lines that contain it) and max (1 to 100, 20 when left out) |
| Member | Meaning |
|---|---|
const string Guid |
"com.tomxv.dragnwash.modframework.dialogue" |
const string Version |
The library's version |
bool LinesAvailable |
True when the hooks for spoken lines are installed |
bool OptionsAvailable |
True when the hooks for options are installed |
string CurrentNode |
The Yarn node that started most recently, or null |
- Patch Yarn Spinner's line or option presenters yourself.
- Ship the game's script text in your mod or repository. Refer to lines by
LineId, or by the stable line keys above.
Players
Mod authors
- Getting started
- Playing well with others (the guide)
- Going online
- Installer
- Mod reload
- Overrides (no code)
- Graphs (no code, makes things happen)
Tools (F1, developer tools)
- Inspector
- Console
- Code graph
- Bridge (AI clients, MCP)
API
日本語
- ホーム
- プレイヤー向け · ランチャー · FAQ · クラッシュレポート
- はじめての Mod · ほかの Mod と一緒に動かす · 外と通信する Mod · インストーラー · Mod の再読み込み · Overrides · Graphs
- Inspector · Console · コードのグラフ · Bridge
- 中核 API · 操作の登録簿 · Text · Dialogue · Tool window · Assets · Flags and saves · GameEvents · SettingMeta
Links
- Repository
- Releases
- Changelog
- Design records: DESIGN · ROADMAP · CONTENT_POLICY