Dialogmark: one home for dialog handling
Extracing dialog parsing and simulation out into a single shared crate, replacing two separate implementations across the editor and the backend.
Grindshell’s dialogs are Markdown files with embedded Luau code blocks: headings are nodes, paragraphs are narration, and code blocks drive the branching. Until now, two separate pieces of code knew how to read and run them: one in the editor, one in the backend, and they had drifted apart.
Dialogmark fixes that. It’s a single Rust crate that owns the whole job: parsing the Markdown and frontmatter, building the dialog tree, validating it, and walking it against a Luau VM. It becomes the one source of truth, and both the editor and the backend will lean on it instead of their own copies.
Check out the source on GitHub.
Two surfaces, one parser
The crate exposes two surfaces built from the same parse.
The runtime surface is lean and for actual gameplay. It assumes a dialog has already been validated, so it skips HTML rendering, trace collection, and re-validation, and walks the tree as cheaply as possible.
The editor surface, behind a Cargo feature, is the full toolkit: parse plus HTML rendering, complete validation, and a step-by-step simulation with a trace of every block.
What it deliberately doesn’t do
Dialogmark owns no Luau VM. Every function that runs code takes a VM the caller supplies. That keeps game-specific extensions (filesystem access, JSON helpers, and the like) out of the library and in the consumer that needs them. The editor hands in a bare VM. The backend hands in its sandboxed one. The library stays focused on dialogs and nothing else.