Table of Contents

Implementation notes

Design and rationale notes for DialogueDown's compiler. Each note covers one component; this README is the reading guide to them.

Cross-cutting conventions live in their own notes rather than here, so this file stays an index. The one every component shares is the Error model — read it alongside the Core notes.

Table of contents

How the notes are laid out

Each area below is a folder, so the tree matches this guide and a note sits beside the ones it is read with. Visualization is the largest area by far, so it is split again by surface.

design-notes/
├── core/           the compiler pipeline, stage by stage
├── runtime/        playing a compiled script
├── language/       one script-language construct per note
├── configuration/  the options seam and its TOML edge
├── diagnostics/    collecting and reporting problems
├── cli/            the ddown command-line tool
├── visualization/
│   ├── report/     the report shell and its stage tabs
│   ├── editor/     the Source editor's highlighting and completions
│   ├── graph/      reading and navigating a rendered graph
│   └── session/    the served shell: serving, editing, browsing
└── other/          spikes and project-level notes

Reading guide

The notes below are grouped by area and ordered for reading. Start with Core — those explain the compiler itself and are worth reading in full. Read Command-line interface or Visualization only when you work on that surface: both document tools built on top of the core, so they are optional for understanding the compiler. Each note keeps a one-line summary and a status (Implemented, Partially implemented, Proposed, or Explored — not adopted), which matches the status line at the top of the note itself.

Tip

New here? Read the Core notes in order, then the Error model. That is enough to understand and change the compiler.

Two overlaps in this corpus are on purpose. A guide page and a design note may share an example — the guide teaches the syntax, and a note repeats an example only where a decision turns on its exact shape. And the agent instruction files (AGENTS.md, .github/copilot-instructions.md) repeat the build commands so an agent can act without following links. Keep the overlap and the claims single-homed: a number two documents must agree on (a coverage floor, a threshold) belongs in one of them, with the others pointing at it.

Core: the compiler pipeline

Essential — read in full. These trace a script through the compiler, one stage per note, in pipeline order; the facade note ties the stages together.

flowchart LR
    FE["1. Markdown Front-End"] --> TR["2. Transpiler"]
    TR --> DS["3. Desugar"] --> SA["4. Semantic Analyzer"]
    SA --> SF["5. Script Compiler Facade"] --> GR["6. Dialogue Graph"]
    GR --> RT(["Runtime →"])
Order Note What it covers Status
1 Markdown Front-End Source text → Markdown AST (Markdig adapter) Implemented
1a Unmodeled Markdown Handling A front-end detail: which unmodeled Markdown is ignored or kept as dialogue text Implemented
2 Markdown to Dialogue AST Transpiler Markdown AST → Dialogue AST Implemented
3 Desugar Dialogue AST → normalized Dialogue AST (jump assembly, control lines) Implemented
4 Semantic Analyzer Desugared AST → semantic model (speakers, scenes, resolved jumps) Implemented
5 Script Compiler Facade One IScriptCompiler seam over the stages, AddDialogueDown DI, and the success-or-failure result of a compile Implemented
6 Dialogue Graph Semantic model → the immutable flow graph a runtime walks Implemented

| — | Error model | The cross-cutting convention: collect a diagnostic, throw only when a stage cannot continue | Implemented |

The Error model is a convention every stage adopts rather than a stage itself — read it alongside the six pipeline stages above.

Runtime: playing a compiled script

Read when you work on anything after the graph. The architecture note fixes the cross-cutting decisions — the artifact, the execution model, the protocol — and each component note applies them to one piece.

flowchart LR
    RA["1. Runtime Architecture"] --> PF["2. Playbook Format"]
    PF --> RR["3. Playbook Reader Rules"]
    RR --> CC["4. Conformance Corpus"]
    CC --> SPT["5. Speech as Plain Text"]
    SPT --> RN["6. Runner"]
    RN --> AW["7. Asking the World"]
    AW --> SL["8. Speaking a Line"]
    SL --> RUN(["players, adapters"])
Order Note What it covers Status
1 Dialogue Runtime Architecture The umbrella: the portable playbook, the runner that plays it, and the protocol and seams a host implements Partially implemented
2 Playbook Format Graph → a versioned JSON playbook, and the reader that loads one back Implemented
3 Playbook Reader Rules The reader's structural rules beyond the schema: a node's ways out, and a branch's arm order Implemented
4 Conformance Corpus Language-neutral fixtures every runtime must reproduce, and the harness that runs them against the reference reader and runner Implemented
5 Speech as Plain Text One public flattening of a line's fragments to plain text, shared by the conformance harness, the report, and a host's fallback rendering Implemented
6 Runner The C# runner: the play state, the step that advances it, waiting on the host for a command, and the refusals Partially implemented
7 Asking the World How the runner asks the world: Resolve answered by Supply, for conditions, block conditions, and queries in speech Implemented
8 Speaking a Line How the runner plays a line's words and commands in written order, stopping inside the line only before a query written after a command Implemented

Language constructs

Read when you add or change a script-language construct. Each note designs one writer-facing syntax — its grammar, semantics, Markdown interaction, and diagnostics — layered on the pipeline above. Read the relevant Core stage notes first, since a construct threads through them.

Note What it covers Status
Progression Order How a script progresses (reading-order fall-through), the divert and detour jump roles, and the #END terminator Partially implemented
Random Choice A choice list with per-option `%` weights that the engine resolves to one option at random Implemented
Conditions The condition (`key?`) and every place it attaches — a line, a jump, a choice option — with its grammar and how each resolves Implemented
Unquoted Keys Let a condition (`IsAngry?`) and a dynamic weight (`Luck%`) drop the quotes around their key, keeping quotes as the escape Implemented
Symbol Escape One literal-punctuation rule: a backslash escapes the next character, so #word and => are written as prose Implemented
Block Controls Connected blockquotes that group mutually-exclusive if/elseif/else branch bodies Implemented
Control Line An effect-only line (a bare jump or a silent command) with no speaker, so an effect is never attributed to the default speaker Implemented
Cross-File Jump Resolution Resolve a jump that targets a scene in another script (chapter-02.dialogue.md#meet-bob) across a project, via a linker Proposed

Configuration

Read when you configure the compiler or add a config knob. A cross-cutting core concern — an immutable CompilerOptions seam threaded into the stages — and its file edge, a satellite that reads a dialogue.toml into those options.

Order Note What it covers Status
1 Configuration The CompilerOptions seam: compilation mode, configured speakers, and unmodeled-Markdown handling projected into their stages Implemented
2 Configuration Loader The TOML edge: reads dialogue.toml into a CompilerOptions, validating with located errors, in its own satellite assembly Implemented
3 CLI Configuration Threads a project's dialogue.toml through the ddown CLI into compile and visualize (and the report's autocompletion) Implemented
4 Compilation Mode Configuration Makes the compilation mode settable in dialogue.toml and shown in the Config tab Implemented

Diagnostics

Read when you work on collecting or reporting problems. A cross-cutting core concern that lets the compiler describe every problem it finds — errors and warnings — in a structured, located form, so an author can see them all at once instead of one throw per run. Start with the umbrella note; focused notes then cover individual rules and the surfaces that render them.

Order Note What it covers Status
1 Diagnostics and Validation The whole effort: the diagnostic model, the collect-and-continue collection seam, the validator and rules, and the renderer Implemented
2 Choice Nesting Diagnostic A style warning for choice branches nested beyond the recommended depth Implemented
3 Styled Speaker Prefix Diagnostic A warning when a styled name (*Alice*:) looks like a speaker prefix but is not recognized as one Implemented
4 Dangling Arrow Diagnostic A warning when a => has no link after it, so the intended jump degrades to plain text Implemented
5 Ignored Markdown Diagnostic A neutral note when the front end ignores unmodeled Markdown, such as a table or a divider Implemented
6 CLI Diagnostic Rendering Renders collected diagnostics on the ddown CLI (rich Errata blocks or greppable one-liners), sets the exit code, and exposes --mode Implemented

Command-line interface

Read when you work on the ddown CLI. These build on the core through Spectre.Console.Cli; they are not needed to understand the compiler.

Order Note What it covers Status
1 Command-Line Interface The ddown CLI: compile and visualize, and the Live server as a library Implemented
2 Compile CLI — Emit DOT compile --emit dot emits each stage's graph as portable Graphviz text Implemented
3 Compile CLI — Fix Mode compile --fix applies a diagnostic's preferred fix in place, then verifies by recompiling Implemented

Visualization

Read when you work on the interactive report or the served session. An optional TypeScript client that renders each compiler stage; not needed to understand the compiler. This is the largest area, so its notes are split four ways — read only the one you are working in, starting from its first row.

flowchart LR
    RP["Report and stage tabs"] --> ED["Source editor"]
    RP --> GR["Graph interaction"]
    RP --> SS["Served session"]

Report and stage tabs

The report shell and what each tab shows — one per compiler stage, plus the Playbook and Config tabs and the conventions every table shares.

Note What it covers Status
Compilation Visualization The report's architecture: every stage tab, the payload, the projections and renderers, unavailable stages, and stage tooltips Implemented
AST Stage Tabs The Dialogue AST and desugared AST as two graph tabs from one projection Implemented
Semantic Model Visualization Tab The semantic model as an analytics tab: scene-tree graph and cross-linked tables Implemented
Dialogue Graph Visualization Tab The compiled dialogue graph: every node in graph order, typed edges, and orphans made visible Implemented
Playbook Tab The compiled playbook a runtime loads, read-only, beside its header, speaker, anchor, and node tables Implemented
Playbook Nodes Table Every node as one row that reads as a sentence: its kind in the graph's color, what it holds, and where it leads Implemented
Playbook Summary Segments A node's summary sent as labeled segments, so the client draws each part by its role Implemented
Navigating the Playbook From a table into the JSON, and from a reference in the JSON to the definition it names Implemented
Configuration Tab The applied dialogue.toml: view, edit with autocompletion, and create one in place Implemented
Table Cell Conventions One rule per cell concern across every table: an absent value, a tag capsule, and what copies on click Implemented
Collapsing Across the Report One contract and one glyph for folding on every surface, with each surface keeping its own unit and state Implemented

Source editor

The authoring surface: what the editor highlights, completes, and marks, all projected from the compiler rather than a client-side grammar.

Note What it covers Status
Compiler-Projected Editor Semantics Highlighting tokens and completions projected from the compiler's own parse Implemented
Diagnostics Overlay Diagnostics as squiggles, gutter markers, and tooltips on an LSP-shaped projection, with co-located diagnostics ordered once Implemented
Diagnostic Quick Fixes A diagnostic's suggested repair offered as an editor action Implemented
Heading Anchors Copy a scene heading's jump target from a preview link or an active-line hint Implemented
Unmodeled Markdown Highlighting The editor marks the Markdown its policy ignores and styles comments as writer-only notes Implemented
Front Matter Source Highlighting Leading front matter highlighted as YAML Implemented
Ignored Markdown Preview Toggle Show or hide ignored blocks and inline spans per region, or all at once Implemented
Construct Marks in the Source Preview The rendered preview marks the compiler's constructs in the editor's own vocabulary Implemented
Mermaid Authoring Diagrams Fenced Mermaid authoring aids rendered in every Markdown preview, loaded on demand Implemented
Line Debugger UI A CodeMirror debugger presentation layer behind a runtime-neutral controller seam; the runtime adapter is not built Partially implemented

Graph interaction

Reading and navigating a rendered graph: what it remembers, what it reveals, and how a scene folds.

Note What it covers Status
Graph Position Preservation Per-graph zoom, pan, and fold memory, and a root-centered default Implemented
Node Inspector Read a graph node's source and preview, and jump to it in the Source tab Implemented
Jump to Stage From a Source selection to the enclosing node in a later stage, via Jump to ▸ <stage> Implemented
Dialogue Graph Region Fold Collapse a scene in the Dialogue Graph to one box the flow still passes through Implemented
Region-Aware Graph Layout Give every scene its own run of rows, so no two scene bands cross Implemented
Keyboard Navigation Navigate a graph by its edges, with a keymap per tab shape Implemented

Served session

The served shell around the report: the server, editing and saving, browsing the project, and the window's chrome.

Note What it covers Status
Served Shell The one loopback server behind ddown visualize: its routes, roots, security, View and Edit, and the watcher Implemented
Live Edit and Autosave Editing the source in the report and saving it: Auto and Manual modes, conflicts, and save-before-navigation Implemented
Explorer The project tree, the Files toggle, and opening a script without reloading the page Implemented
Chrome and Layout Zen mode, the narrow-screen layout, and the Problems panel Implemented
Served Client Packaging How the served page loads its client: hashed assets, and Mermaid fetched on demand Implemented

Other notes

Optional context. Exploration spikes and project-level notes that sit outside the pipeline and its tools.

Note What it covers Status
Target Frameworks Multi-target the shipped libraries so a Godot game keeps its runtime while the toolchain moves to .NET 10 Implemented
Namespace Layout An architecture rule capping how many types an assembly's root namespace may hold Implemented
Enum Wire Names Every JSON enum wire name pinned by a hand-written converter, so no shipped build needs a .NET 9+ package Implemented
Development Cycle Optimization Local and CI feedback time, cut through measured, behavior-preserving increments Implemented
BBCode Rendering Render a line's speech fragments as BBCode (Godot), terminal, and web text Proposed
Interactive Playthrough Play a script as a text adventure to check its branching; what the exploration found Explored — not adopted