DialogueTreeFormat_V2_Contract.json defines the Phase 72 dialogue tree data
format for authored conversations. The format is intentionally graph-first:
nodes describe what happens at a point in the conversation, and edges describe
transitions, including the conditions that decide whether a transition is
available.
Source Of Truth#
- Contract:
V2/ue/Content/V2/Gameplay/Dialogue/DialogueTreeFormat_V2_Contract.json - Sample tree:
V2/balance/dialogue/trees/asha-storm-market-intro.v2dialogue.json - Localization table:
V2/balance/dialogue/localization/asha-storm-market-intro.v2dialogueloc.json - Validator:
V2/ue/Tools/check-v2-dialogue-tree-format.py - CI workflow:
.github/workflows/v2-build.yml - Horde job:
V2/ue/Build/Horde/v2-buildgraph-job.json
Dialogue tree assets use schema v2.dialogue.tree.v1, formatVersion: 1, and
stable ids. Dialogue ids start with dlg., node ids start with n., edge ids
start with e., choice ids start with choice., and player-facing line ids
start with loc.dialogue..
Top Level Shape#
Every tree contains these fields:
| Field | Purpose |
|---|---|
schema |
Must be v2.dialogue.tree.v1. |
dialogueId |
Stable authoring id for save keys, telemetry, imports, and redirects. |
formatVersion |
Data format version, starting at 1. |
title |
Authoring title for editor/search surfaces. |
startNodeId |
Node id where traversal begins. |
participants |
Player, NPC, narrator, or system speakers with display line ids. |
variables |
Local, persistent per-NPC, and global story variable declarations. |
nodes |
Graph nodes with one of the canonical node kinds. |
edges |
Directed transitions between nodes with ordered conditions. |
localization |
Source locale and required line ids. |
voice |
Voice bank root, cue fields, and subtitle fallback policy. |
metadata |
Authoring owner, review status, priority, and tags. |
Node Kinds#
The canonical node kinds are:
| Kind | Required fields | Runtime meaning |
|---|---|---|
text |
id, kind, speakerId, lineId |
Display one localized speaker line. |
choice |
id, kind, speakerId, promptLineId |
Present player choices from outgoing edge metadata. |
condition |
id, kind, predicate |
Evaluate game-state predicates without displaying text. |
action |
id, kind, actions |
Run side effects before traversal continues. |
random |
id, kind, seedScope |
Pick a deterministic weighted outgoing edge. |
Terminal text nodes set terminal: true and must have no outgoing edges.
Non-terminal nodes must be able to reach a terminal node.
Edge Transitions#
Edges carry the transition contract:
- Required transition fields are
id,from,to,priority, andconditions. conditionsis always present. Use an empty array for unconditional edges.- Lower
priorityedges are considered first when multiple edges are available. - Edges from a
choicenode also includechoiceId,choiceLineId, andchoiceTags. - Edges from a
randomnode include positiveweightvalues. - Edges may include side-effect
actionswhen a transition needs an atomic choice consequence.
The first format version supports these condition references: quest_state,
inventory_count, relationship_value, time_of_day, player_stat,
local_variable, persistent_variable, global_story_variable, and
choice_history.
The first format version supports these action references: set_variable,
emit_event, grant_item, modify_relationship, play_animation,
spawn_entity, and start_quest.
Localization And Voice#
Authoring uses line ids for player-facing text. Inline English may appear only in comments, tooling diagnostics, or non-shipping editor previews. Display names for speakers use line ids as well, so runtime localization can resolve player, NPC, narrator, and system labels the same way it resolves dialogue lines.
Voiced text nodes provide voiceCue and subtitleTimingId. If a localized
voice cue is missing, the runtime falls back to localized subtitles through the
tree voice.fallbackPolicy.
Runtime localization tables use schema v2.dialogue.localization.v1. Each table
declares a source locale, repeats every required loc.dialogue.* line id for
every shipped locale, and stores per-locale voiceCue and subtitleTimingId
references for voiced lines. Dialogue runtime code resolves display text by line
id and locale, then falls back to the table source locale when a requested
locale is unavailable.
Save And History#
Save data records stable ids rather than authored order:
- Visit state is keyed by
dialogueIdand node id. - Player choice history is recorded by
choiceId. - Random selections are recorded by edge id for deterministic reload.
- Local variables persist for the active conversation.
- Persistent variables use an NPC or object scope.
- Global story variables use a story scope.
These rules let later Phase 72 tasks implement runtime traversal, conditions, actions, variables, consequence tracking, localization, and save/load without changing the tree format.
Validation#
Run these commands after changing the dialogue tree format:
python3 V2/ue/Tools/check-v2-dialogue-tree-format.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 -m json.tool V2/ue/Content/V2/Gameplay/Dialogue/DialogueTreeFormat_V2_Contract.json
python3 -m json.tool V2/balance/dialogue/trees/asha-storm-market-intro.v2dialogue.json
python3 V2/tools/validate-v2-docs.py
npx prettier --check V2/docs/modes/dialogue-tree-format.md V2/ue/Content/V2/Gameplay/Dialogue/DialogueTreeFormat_V2_Contract.json V2/balance/dialogue/trees/asha-storm-market-intro.v2dialogue.json