Features

A detailed look at what Knot does today, verified against the codebase. Only SugarCube 2 has full language features; Harlowe, Chapbook, and Snowman are placeholder implementations with the build pipeline working. The current release is v2.1.0 — anything marked Unreleased is in the repository build but not yet in a Marketplace release.

Version-aware SugarCube 2 support

SugarCube has shipped breaking changes across its 2.x life — macros added, deprecated, and removed (2.37.0 alone removed six). Knot's macro catalog is a versioned union catalog: every macro that ever existed in SugarCube 2.x carries its lifecycle (added_in / deprecated_in / removed_in) plus per-era descriptions and argument signatures, sourced from the official docs, upgrade guides, release notes, and the 2.37.3 engine source.

Every user-facing feature resolves through the story's pinned format-version from StoryData:

Stories without a parseable version fail open to the latest known SugarCube — unusual metadata degrades to the full current surface, never to bogus diagnostics.

Structural understanding, not just regex

Unlike tooling that bolts regular expressions onto a text editor, Knot actually parses your project into passages and the links between them. This structural model lets it answer questions that pattern matching gets wrong:

This is the core design principle behind Knot: model the project the way Twine itself models it, and the editor can give you real help instead of approximate help.

Variable tracker

The Variable Tracking panel shows where every variable is set, read, and how it flows across passages. For SugarCube, variable tracking is JavaScript-aware via the oxc parser, so it understands:

This means Knot can warn you about uninitialized variables, unused variables, and variables that are read but never set — all in real time as you type. When JavaScript inside a passage has a syntax error, the parser recovers chunk-by-chunk so one broken block doesn't blind the rest of the file.

Passage diagnostics

A dedicated panel inspects any passage's links, variables, macros, and complexity metrics. Real-time diagnostics are all configurable — each of the 11 checks below can be set to error, warning, info, hint, or off in VS Code settings:

DiagnosticDefaultWhat it flags
knot.diagnostics.broken-linkwarningLinks pointing to passages that don't exist yet
knot.diagnostics.unreachable-passagewarningPassages no other passage links to (excluding Start and special passages); manual entry points for dynamic navigation Unreleased
knot.diagnostics.uninitialized-variablewarningVariables read before they're set anywhere in the project
knot.diagnostics.invalid-passage-namewarningPassage names that break Twine's naming rules
knot.diagnostics.duplicate-passage-nameerrorTwo passages with the same name — Twine resolves these unpredictably
knot.diagnostics.dead-end-passageinfoPassages with no outbound links, where the player has nowhere to go
knot.diagnostics.complex-passagehintPassages whose nesting and branch complexity exceed a threshold
knot.diagnostics.empty-passagehintPassages with no content
knot.diagnostics.large-passagehintPassages that have grown large enough to slow the editor and the reader
knot.diagnostics.redundant-writehintWriting a variable that's never read before it's written again
knot.diagnostics.unused-variablehintVariables that are set but never read

Alongside the diagnostics, the Passage Diagnostics panel surfaces per-passage complexity metrics: word count, link count, macro count, and variable count.

Embedded CSS linting

Twine projects embed CSS in passages more often than they keep it in separate files — and a single typo can make a browser silently drop an entire rule. Knot runs a real CSS parser over every stylesheet surface and reports:

Embedded HTML validation

Passages and StoryInterface files mix prose with markup, so Knot validates the HTML it finds there with tolerance matching the Twine engine's own:

StoryInterface passages get full semantic highlighting — tag names, attributes, entities, and delimiters — via the same token pipeline.

Story Map

An interactive graph visualization of your entire project. Nodes are passages, edges are links. The map is built on @xyflow/react with automatic layout via dagre.

The Story Map is primarily for visualization and navigation at this time. Deeper structural editing from the map — dragging passages to reorganize, creating links visually — is on the roadmap.

Beside the editor, Knot installs a dedicated activity-bar panel (the Knot icon on the left edge of the window) with three views:

Passage Diagnostics

Live inspection of the passage under the cursor: links, variables, macros, and complexity metrics.

Variable Tracking

Where every variable is set and read, and how values propagate across passages.

Project Info

Workspace statistics: passage and word counts, format and version, IFID, graph health.

Incremental analysis

Knot doesn't re-parse your entire project on every keystroke. Only affected passages are re-parsed, and the graph is updated incrementally. This keeps large projects responsive even as they grow into hundreds of passages and thousands of links.

Integrated build pipeline

Knot's build pipeline is designed to "just work" with zero manual setup:

  1. Tweego is auto-downloaded on first build into the extension's global storage. You never need to install it yourself.
  2. Story formats are auto-downloaded based on your project's StoryData format and version. The format is cached per version in <globalStorage>/storyformats/<id>@<version>/.
  3. The workspace is the source directory — put all your .twee, .js, .css, and asset files directly in the workspace. Story formats live separately in the managed folder, so there's no risk of format.js getting bundled as a passage.
  4. The output filename is derived from StoryTitle — if your story is called "The Lost City", the build produces The_Lost_City.html. Falls back to index.html if no StoryTitle passage exists.
  5. Build stats are logged — every build prints Passages: N | Words: N to the Knot Build output channel.

Beyond the defaults, a knot.json file in the workspace root can override the story format and version and declare special passages explicitly.

Watch mode

Toggle auto-rebuild on save. When Watch is on, every save of a .tw, .twee, .js, or .css file triggers a rebuild in the background. This is the recommended workflow for active development: edit, save, refresh the browser.

Supported story formats

FormatStatusWhat worksWhat doesn't (yet)
SugarCube 2 Full support Versioned macro catalog (73-entry union, filtered by your story's format-version), JS-aware variable tracking via oxc, CSS & HTML linting, special passages, completion, hover, signature help, diagnostics, Story Map, build pipeline —
Harlowe 3 Placeholder FormatPlugin trait implemented; build pipeline (via Tweego) Parser quality, link extraction, Story Map, macro catalog, variable tracking, completion, hover
Chapbook 1 Placeholder FormatPlugin trait implemented; build pipeline (via Tweego) Parser quality, link extraction, Story Map, macro catalog, variable tracking, completion, hover
Snowman 2 Placeholder FormatPlugin trait implemented; build pipeline (via Tweego) Parser quality, link extraction, Story Map, ERB template detection, macro catalog, variable tracking, completion, hover

Knot auto-detects the format from your StoryData passage. The Language Status indicator (lower-right of the editor, on .twee files) shows the detected format plus passage, broken-link, and unreachable counts — turning warning-colored when links are broken. Bringing Harlowe, Chapbook, and Snowman to full parity is planned — see the roadmap for details.

Want a feature that isn't here? Knot is still early in development and the codebase is small — this is the ideal time to chime in. Join the Discord or open an issue and tell us what you need.