diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b209f10 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,60 @@ +# Dialog IDE manual (Antora source) + +This directory is a self-contained [Antora](https://antora.org) documentation component for the +Dialog IDE VS Code extension. It is authored here, in the extension's own repository, so it stays in +sync with the code, and is consumed by the main Dialog website's Antora build as an additional +content source. + +## Layout + +``` +docs/ + antora.yml component descriptor (name: dialog-ide, versionless) + modules/ROOT/ + nav.adoc the manual's table of contents + pages/*.adoc one file per chapter + partials/*.adoc fragments reused across chapters + images/ screenshots; MANIFEST.adoc is the shot-list +``` + +## Wiring into the Dialog website playbook + +In the Dialog site's `antora-playbook.yml`, add this repo under `content.sources` with `start_path` +set to `docs`: + +```yaml +content: + sources: + # ...existing Dialog sources... + - url: https://github.com/hlship/dialog-ide.git + branches: [main] # or a release branch/tag once one exists + start_path: docs +``` + +The component id is `dialog-ide`; cross-links from elsewhere on the site use +`xref:dialog-ide::index.adoc[]` (and so on). + +## Local preview + +There is no committed playbook for local builds. To preview: + +1. `npm i -g @antora/cli@3 @antora/site-generator@3` +2. Create a throwaway `local-playbook.yml`: + ```yaml + site: + title: Dialog IDE (local preview) + start_page: dialog-ide::index.adoc + content: + sources: + - url: . + start_path: docs + ui: + bundle: + url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable + snapshot: true + output: + dir: ./docs/_preview + ``` +3. `antora --fetch local-playbook.yml` and open `docs/_preview/index.html`. + +`docs/_preview/` and any local playbook are build artifacts — do not commit them. diff --git a/docs/antora.yml b/docs/antora.yml new file mode 100644 index 0000000..b2c104e --- /dev/null +++ b/docs/antora.yml @@ -0,0 +1,11 @@ +name: dialog-ide +title: Dialog IDE +version: ~ +start_page: ROOT:index.adoc +nav: + - modules/ROOT/nav.adoc +asciidoc: + attributes: + experimental: '' + idprefix: '' + idseparator: '-' diff --git a/docs/modules/ROOT/images/add-feelie-flow.png b/docs/modules/ROOT/images/add-feelie-flow.png new file mode 100644 index 0000000..59283d5 Binary files /dev/null and b/docs/modules/ROOT/images/add-feelie-flow.png differ diff --git a/docs/modules/ROOT/images/add-file-picker.png b/docs/modules/ROOT/images/add-file-picker.png new file mode 100644 index 0000000..319c930 Binary files /dev/null and b/docs/modules/ROOT/images/add-file-picker.png differ diff --git a/docs/modules/ROOT/images/command-palette.png b/docs/modules/ROOT/images/command-palette.png new file mode 100644 index 0000000..6684940 Binary files /dev/null and b/docs/modules/ROOT/images/command-palette.png differ diff --git a/docs/modules/ROOT/images/configure-exports-wizard.png b/docs/modules/ROOT/images/configure-exports-wizard.png new file mode 100644 index 0000000..3aa22e7 Binary files /dev/null and b/docs/modules/ROOT/images/configure-exports-wizard.png differ diff --git a/docs/modules/ROOT/images/dialog-json-with-categories.png b/docs/modules/ROOT/images/dialog-json-with-categories.png new file mode 100644 index 0000000..61abc55 Binary files /dev/null and b/docs/modules/ROOT/images/dialog-json-with-categories.png differ diff --git a/docs/modules/ROOT/images/diff-rendering.png b/docs/modules/ROOT/images/diff-rendering.png new file mode 100644 index 0000000..2d39be0 Binary files /dev/null and b/docs/modules/ROOT/images/diff-rendering.png differ diff --git a/docs/modules/ROOT/images/dynamic-state-chips.png b/docs/modules/ROOT/images/dynamic-state-chips.png new file mode 100644 index 0000000..273270e Binary files /dev/null and b/docs/modules/ROOT/images/dynamic-state-chips.png differ diff --git a/docs/modules/ROOT/images/export-success-toast.png b/docs/modules/ROOT/images/export-success-toast.png new file mode 100644 index 0000000..c052fd7 Binary files /dev/null and b/docs/modules/ROOT/images/export-success-toast.png differ diff --git a/docs/modules/ROOT/images/extensions-view.png b/docs/modules/ROOT/images/extensions-view.png new file mode 100644 index 0000000..6f3b486 Binary files /dev/null and b/docs/modules/ROOT/images/extensions-view.png differ diff --git a/docs/modules/ROOT/images/first-skein-session.png b/docs/modules/ROOT/images/first-skein-session.png new file mode 100644 index 0000000..d20a4e8 Binary files /dev/null and b/docs/modules/ROOT/images/first-skein-session.png differ diff --git a/docs/modules/ROOT/images/generated-dialog-json.png b/docs/modules/ROOT/images/generated-dialog-json.png new file mode 100644 index 0000000..1d6d1e7 Binary files /dev/null and b/docs/modules/ROOT/images/generated-dialog-json.png differ diff --git a/docs/modules/ROOT/images/hero-skein-beside-editor.png b/docs/modules/ROOT/images/hero-skein-beside-editor.png new file mode 100644 index 0000000..cbd6609 Binary files /dev/null and b/docs/modules/ROOT/images/hero-skein-beside-editor.png differ diff --git a/docs/modules/ROOT/images/init-command-palette.png b/docs/modules/ROOT/images/init-command-palette.png new file mode 100644 index 0000000..c5b220e Binary files /dev/null and b/docs/modules/ROOT/images/init-command-palette.png differ diff --git a/docs/modules/ROOT/images/keystroke-input.png b/docs/modules/ROOT/images/keystroke-input.png new file mode 100644 index 0000000..05dc9de Binary files /dev/null and b/docs/modules/ROOT/images/keystroke-input.png differ diff --git a/docs/modules/ROOT/images/knot-menu-open.png b/docs/modules/ROOT/images/knot-menu-open.png new file mode 100644 index 0000000..4a7c198 Binary files /dev/null and b/docs/modules/ROOT/images/knot-menu-open.png differ diff --git a/docs/modules/ROOT/images/marketplace-extension-page.png b/docs/modules/ROOT/images/marketplace-extension-page.png new file mode 100644 index 0000000..be501f9 Binary files /dev/null and b/docs/modules/ROOT/images/marketplace-extension-page.png differ diff --git a/docs/modules/ROOT/images/navgraph-annotated-spine-vs-branches.png b/docs/modules/ROOT/images/navgraph-annotated-spine-vs-branches.png new file mode 100644 index 0000000..7b21971 Binary files /dev/null and b/docs/modules/ROOT/images/navgraph-annotated-spine-vs-branches.png differ diff --git a/docs/modules/ROOT/images/navgraph-closeup.png b/docs/modules/ROOT/images/navgraph-closeup.png new file mode 100644 index 0000000..044730a Binary files /dev/null and b/docs/modules/ROOT/images/navgraph-closeup.png differ diff --git a/docs/modules/ROOT/images/replay-all-progress.png b/docs/modules/ROOT/images/replay-all-progress.png new file mode 100644 index 0000000..1285143 Binary files /dev/null and b/docs/modules/ROOT/images/replay-all-progress.png differ diff --git a/docs/modules/ROOT/images/run-skein-picker.png b/docs/modules/ROOT/images/run-skein-picker.png new file mode 100644 index 0000000..465a52d Binary files /dev/null and b/docs/modules/ROOT/images/run-skein-picker.png differ diff --git a/docs/modules/ROOT/images/scaffolded-explorer-tree.png b/docs/modules/ROOT/images/scaffolded-explorer-tree.png new file mode 100644 index 0000000..b4794b2 Binary files /dev/null and b/docs/modules/ROOT/images/scaffolded-explorer-tree.png differ diff --git a/docs/modules/ROOT/images/search-results.png b/docs/modules/ROOT/images/search-results.png new file mode 100644 index 0000000..a44a458 Binary files /dev/null and b/docs/modules/ROOT/images/search-results.png differ diff --git a/docs/modules/ROOT/images/skein-panel-annotated.png b/docs/modules/ROOT/images/skein-panel-annotated.png new file mode 100644 index 0000000..80f9d00 Binary files /dev/null and b/docs/modules/ROOT/images/skein-panel-annotated.png differ diff --git a/docs/modules/ROOT/images/status-bar-item.png b/docs/modules/ROOT/images/status-bar-item.png new file mode 100644 index 0000000..cc98417 Binary files /dev/null and b/docs/modules/ROOT/images/status-bar-item.png differ diff --git a/docs/modules/ROOT/images/trace-panel-with-source-preview.png b/docs/modules/ROOT/images/trace-panel-with-source-preview.png new file mode 100644 index 0000000..41652e3 Binary files /dev/null and b/docs/modules/ROOT/images/trace-panel-with-source-preview.png differ diff --git a/docs/modules/ROOT/images/uncovered-source-badge-quickfix.png b/docs/modules/ROOT/images/uncovered-source-badge-quickfix.png new file mode 100644 index 0000000..7757308 Binary files /dev/null and b/docs/modules/ROOT/images/uncovered-source-badge-quickfix.png differ diff --git a/docs/modules/ROOT/images/vscode-download-page.png b/docs/modules/ROOT/images/vscode-download-page.png new file mode 100644 index 0000000..e9b03cb Binary files /dev/null and b/docs/modules/ROOT/images/vscode-download-page.png differ diff --git a/docs/modules/ROOT/images/vscode-first-window.png b/docs/modules/ROOT/images/vscode-first-window.png new file mode 100644 index 0000000..6e8208e Binary files /dev/null and b/docs/modules/ROOT/images/vscode-first-window.png differ diff --git a/docs/modules/ROOT/images/web-export-in-browser.png b/docs/modules/ROOT/images/web-export-in-browser.png new file mode 100644 index 0000000..b26e152 Binary files /dev/null and b/docs/modules/ROOT/images/web-export-in-browser.png differ diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc new file mode 100644 index 0000000..a7384b8 --- /dev/null +++ b/docs/modules/ROOT/nav.adoc @@ -0,0 +1,16 @@ +* xref:index.adoc[Introduction] +* Getting set up +** xref:installing-vscode.adoc[Installing Visual Studio Code] +** xref:installing-the-extension.adoc[Installing the Dialog IDE Extension] +** xref:initializing-a-project.adoc[Starting a New Project] +** xref:project-sources.adoc[Organizing Your Sources] +* The Skein +** xref:skein-concepts.adoc[How the Skein Works] +** xref:creating-and-using-a-skein.adoc[Creating a Skein and Touring the Panel] +** xref:dynamic-state-and-trace.adoc[Dynamic State and Trace] +** xref:multiple-skeins.adoc[When to Use More Than One Skein] +* Shipping +** xref:building-and-exporting.adoc[Building and Releasing Your Project] +* Advanced +** xref:command-line-dgbuild.adoc[Command-Line Testing with dgbuild] +** xref:troubleshooting.adoc[Troubleshooting and Known Limitations] diff --git a/docs/modules/ROOT/pages/building-and-exporting.adoc b/docs/modules/ROOT/pages/building-and-exporting.adoc new file mode 100644 index 0000000..70fca1a --- /dev/null +++ b/docs/modules/ROOT/pages/building-and-exporting.adoc @@ -0,0 +1,107 @@ += Building and Releasing Your Project +:navtitle: Building and Releasing + +Building turns your source into a story file a player can run: a `.zblorb`, a bare `.z8`, or an +AAmachine `.aastory`. Dialog IDE organises this around *named export configurations* stored in +`dialog.json`, plus a separate command that wraps a build into a complete downloadable web page. + +== Export configurations + +Run *Dialog IDE: Configure Exports...*. It is a small wizard that maintains the `exports` array in +`dialog.json`. Each configuration has: + +`name`:: What you call it in the picker. +`format`:: `zblorb`, `z8`, or `aa`. The resulting files are `.zblorb`, `.z8`, and `.aastory` +respectively. +`includeDebug`:: Whether to compile the `debug` sources in. Usually *no* for a release build. +`output`:: The path to write the story file to, relative to the project root. +`dialogcOptions`:: Optional. Extra `dialogc` flags for this configuration alone. + +The same wizard also sets a project-wide *default* set of `dialogc` options, stored as the +top-level `dialogcOptions` key. Any configuration without its own options uses these, and so does +*Export Web Page*. A common use is raising limits — `--heap 2000 --aux 1000` — for a project that +has outgrown the defaults. + +The wizard cannot yet edit an existing configuration in place; to change one, remove it and add it +again. + +[NOTE] +==== +Export configurations are just data in `dialog.json` — the `exports` array, plus the top-level +`dialogcOptions`. You can edit them directly in the editor: change an `output` path, adjust the +options, reorder the list. The wizard is a convenience, not the only way in. +==== + +image::configure-exports-wizard.png["the format QuickPick (zblorb / z8 / aa) in the wizard"] + +== Building a story file + +Run *Dialog IDE: Export Dialog Project...*, pick a configuration, and it compiles with `dialogc`. +On success it offers to reveal the output file in Finder or File Explorer. A compilation error is +reported with its `file:line`, so you can jump straight to it. + +The sources handed to the compiler are expanded using that configuration's `includeDebug` setting +and its `format`, so a file named `something.zblorb.dg` is included in a `zblorb` build and left +out of the others (see xref:project-sources.adoc[]). + +image::export-success-toast.png["the 'Exported ... to ...' notification with the Reveal button"] + +== Cover image + +If a file named `cover.png` exists at the project root, a `zblorb` build embeds it automatically — +there is nothing to configure. *Initialize Dialog Project* seeds a placeholder `cover.png`; replace +it with your own artwork. Unlike a feelie, a missing `cover.png` is simply skipped rather than +treated as an error. + +== The downloadable web page + +Run *Dialog IDE: Export Web Page...*. It asks which export configuration should build the story +file, then assembles a complete web page in `out/web/`, with a matching `.zip` in `out/`. The page +includes: + +* the story file, compiled fresh with the chosen configuration's settings; +* an in-browser player powered by https://github.com/dialog-if/aamachine[AAmachine]; +* the cover image, plus a generated thumbnail; +* the project's feelies (below); +* if `default.skein` contains a knot labelled `WALKTHROUGH`, a walkthrough transcript running from +the root to that knot, with any command beginning with `*` omitted. + +The title, author, blurb, release number, and IFID shown on the page are read live from your +project's own `(story $)` directives via `dgdebug`. + +This command needs `aambundle`, from AAmachine, in addition to `dgdebug` and `dialogc` — see +xref:installing-the-extension.adoc[]. + +image::web-export-in-browser.png["out/web/index.html open in a browser: cover, bibliography, Play button, feelie links"] + +== Feelies + +A *feelie* is any file linked from the exported web page. The tradition is a "how to play +interactive fiction" PDF for newcomers, but it can be anything — a map, a manual, an in-world +document. Feelies appear only in the web export; they are not part of a `.zblorb`. + +Feelies are stored in `dialog.json` as a `feelies` array, each entry a `path` (relative to the +project root) and a `name` (the link text on the page). *Initialize Dialog Project* seeds two PDFs +and wires them in. + +To add one, run *Dialog IDE: Add Feelie...* and choose a file, or right-click a file in the +Explorer and choose *Dialog IDE: Add Feelie*; either way you are then asked for a display name. +*Dialog IDE: Remove Feelie...* takes one out again. A configured feelie whose file is missing is a +*hard error* when you export — fix the path in `dialog.json`, or remove the entry. + +image::add-feelie-flow.png["the Explorer right-click menu with 'Dialog IDE: Add Feelie' highlighted"] + +== Story metadata + +The project's bibliographic details live in your source as `(story $)` directives — `(story title +$)`, `(story author $)`, `(story blurb $)`, `(story noun $)`, `(story release $)`, and `(story ifid +$)`. *Initialize Dialog Project* writes a starter set into `main/meta.dg`, including a generated +IFID, which the `zblorb` format requires. + +This metadata surfaces in the compiled story file's bibliographic record and, for the web export, +in the page's title, author line, description, and its closing "created with Dialog, IFID ..." +note. + +== What's next + +xref:command-line-dgbuild.adoc[] — running tests and skein checks from a terminal or CI. diff --git a/docs/modules/ROOT/pages/command-line-dgbuild.adoc b/docs/modules/ROOT/pages/command-line-dgbuild.adoc new file mode 100644 index 0000000..3e4878e --- /dev/null +++ b/docs/modules/ROOT/pages/command-line-dgbuild.adoc @@ -0,0 +1,107 @@ += Command-Line Testing with dgbuild +:navtitle: Command-Line Testing with dgbuild + +`dgbuild` runs the same project checks the extension does — unit tests, skein replay, source +listing — from a terminal, with no editor involved. Its purpose is scripting and continuous +integration: gating a merge on a green test run, or rebuilding a release automatically. + +== What it is, and installing it + +`dgbuild` is a command-line tool that ships *inside* the `dialog-ide` npm package. It is named to +sit with the rest of the toolchain — `dgdebug`, `dialogc`, `aambundle` — rather than after the +extension. + +Install it globally: + +[source,console] +---- +npm install -g dialog-ide +---- + +or run it without installing: + +[source,console] +---- +npx -p dialog-ide dgbuild +---- + +[WARNING] +==== +Do not run plain `npx dgbuild`. There is an unrelated, older package of that name on npm, and that +is what plain `npx dgbuild` will fetch. Always go through `-p dialog-ide`. +==== + +The npm package contains no binaries. `dgbuild` needs the Dialog toolchain — at least `dgdebug` — +on your `PATH`, or a `binDir` set in `dialog.json`. Run it from the project root, or point it +elsewhere with `-p ` / `--project `. + +== dgbuild test + +Runs the project's unit tests, by invoking `dgdebug --unit-test`, and exits with `dgdebug` 's own +exit code. It exits non-zero on any test failure — and also if `dialog.json` declares no `test` +sources at all, since having nothing to run is treated as a failure rather than a silent pass. + +`--no-debug` leaves the `debug` sources out of the run (they are included by default, matching the +extension's *Run Tests*). Anything after the options is passed straight through to `dgdebug`. + +[source,console] +---- +dgbuild test +dgbuild test --no-debug +dgbuild test -p ./my-project -- --width 80 +---- + +Writing the tests themselves — the `(test $)` and `(assert $)` objects — is covered in the "Testing +and Debugging" chapter of the Dialog manual, not here. + +== dgbuild run-skein + +Replays one or more saved skeins against a fresh `dgdebug` process each, comparing every knot's +live response to its blessed response. With no arguments it replays `default`. + +For each skein it prints a summary line — `name: valid/new/error (valid/new/error)` — and, when you +pass more than one skein, a `total:` line as well. Any knots that came out in error are listed +above the summary. + +It exits non-zero *only if some knot is in error*. Unblessed *new* knots do not fail the run, so if +you want continuous integration to require every knot be blessed, bless them first. `-v` / +`--verbose` adds the underlying `dgdebug` lifecycle logging, which is quiet by default. + +[source,console] +---- +$ dgbuild run-skein +default: 200/0/1 (valid/new/error) + +$ dgbuild run-skein combat parser endings +---- + +This is the command-line equivalent of the panel's *Replay All*. + +== dgbuild sources + +Prints the project's fully expanded source list — exactly the files the compiler would receive. +`-d` / `--debug` and `-t` / `--test` add those categories; `-T ` / `--target ` +filters by target suffix; `-1` / `--single-line` prints the paths colon-joined on one line, for +feeding into another command. + +[source,console] +---- +dgbuild sources -d +dgbuild sources -1 -T zblorb +---- + +== In continuous integration + +A minimal release gate in a GitHub Actions workflow: + +[source,yaml] +---- +- run: npx -p dialog-ide dgbuild test && npx -p dialog-ide dgbuild run-skein +---- + +The runner also needs the Dialog toolchain available — install `dgdebug` onto its `PATH`, or point +`dialog.json`'s `binDir` at a copy you provide. + +== What's next + +xref:troubleshooting.adoc[] — known limitations and the common reasons a project will not run. diff --git a/docs/modules/ROOT/pages/creating-and-using-a-skein.adoc b/docs/modules/ROOT/pages/creating-and-using-a-skein.adoc new file mode 100644 index 0000000..ba34879 --- /dev/null +++ b/docs/modules/ROOT/pages/creating-and-using-a-skein.adoc @@ -0,0 +1,196 @@ += Creating a Skein and Touring the Panel +:navtitle: Creating and Using a Skein + +This chapter is a tour of the Skein panel, control by control: how to create and open a skein, the +four regions of the panel, the per-knot menu, the navbar, replaying, search, and the keyboard +shortcuts. It assumes you have read xref:skein-concepts.adoc[] and know what knots, the spine, and +blessing are. + +== Creating and opening a skein + +A skein is stored in a `.skein` file at the project root. A project can have several; the commands +below all work through the Command Palette. + +[cols="2,3",options="header"] +|=== +| Command | What it does + +| *Dialog IDE: New Skein...* +| Creates a skein. Prompts for the engine (`dgdebug`, `frotz`, or `frotz-release`), a random seed, +and a file name — the name defaults to `default.skein`. Then starts the session. + +| *Dialog IDE: Run Default Skein* +| Starts a session from `default.skein`, if that file already exists. + +| *Dialog IDE: Run Skein...* +| Lets you pick from every `.skein` file in the project. + +| *Dialog IDE: Open Skein* +| Brings the panel for the running session back into view. + +| *Dialog IDE: Save Skein* +| Writes the tree back to its `.skein` file. This is the only action that writes to disk. + +| *Dialog IDE: Stop Skein* +| Stops the running session. Stopping never saves. +|=== + +Only one session runs at a time; starting another prompts you to stop the current one. The status +bar shows the running session's file and engine, and clicking it opens the panel (or, when nothing +is running, starts the default skein). + +`default.skein` is the file the extension reaches for by default. It is the name *New Skein...* +suggests, the only file *Run Default Skein* will start, and the skein *Export Web Page* reads when +it looks for a `WALKTHROUGH`-labelled knot. When to keep more than one skein is covered in +xref:multiple-skeins.adoc[]. + +== The four regions of the panel + +The panel is a fixed-height column. Across the top is the *navbar*, which never scrolls. Below it, a +row holds the *nav graph* on the left and the *transcript* on the right, each scrolling +independently. Along the bottom is the *command input*. + +image::skein-panel-annotated.png["the whole panel with each region labelled: navbar, nav graph, transcript, command input"] + +== The transcript + +The transcript renders the spine — root to selected leaf — one row per knot, each showing the +command and its response. + +The active knot has a blue left border. Every knot also has a status-coloured left border: grey for +valid, yellow for new, red for error. A valid knot's response is shown with its real styling, so +bold and colour from your project come through. A new or error knot is shown instead in a +fixed-width font with *visible whitespace* — dots for spaces, a marker for newlines — and, for an +error knot, a *word-level diff*: removed text struck through in red, added text in blue. + +At the top-right of each row is a cluster: a lock icon if the knot is locked, a marker dot if it is +marked, a label chip if it is labelled, and always the *"..."* button that opens the knot's actions +menu. A knot reached by answering a single-keystroke prompt shows its keystroke as a small pill. + +Clicking anywhere on a row except the menu button makes that knot the active knot. There is no +right-click menu; the "..." button is the only way into a knot's actions. + +image::diff-rendering.png["a transcript row in the error state showing a red/blue word-level diff and visible whitespace"] + +== The command input + +Most of the time the command input is a single text field prefixed with `>`. Type a command and +press kbd:[Enter]. After each command the field clears, refocuses, and scrolls back into view. + +When a knot's response ends on a single-keystroke prompt — a "press any key" pause, a disambiguation +menu — the input changes to a one-character field labelled *Key:*, with *Enter*, *Space*, and +*Backspace* buttons beside it. Any single printable key you type is sent immediately. + +image::keystroke-input.png["the keystroke variant of the command input with its three buttons"] + +== The nav graph + +The nav graph on the left shows the *entire* tree, not just the spine. Nodes are coloured by status +the same way transcript rows are, and a valid node with a troubled descendant is given a faded tint +of that descendant's status, so problems in collapsed branches are still visible. + +Each node is a pill showing the status icon, any lock, marker, or label, the command text, and a +compact "..." button. Click a pill — or focus it and press kbd:[Enter] — to make that knot active; +the transcript redraws to the path down to it. + +A node with children has a small expand/collapse control beneath it; kbd:[Option+X] / kbd:[Alt+X] +toggles it for the active knot. New skeins start fully expanded. Connector lines are drawn behind +the pills and redrawn whenever the tree changes. + +To move around a large tree: *drag* the background of the pane to pan it, and use the *mouse wheel* +to zoom in and out centred on the pointer. A *+* / *−* button pair at the bottom-right zooms centred +on the middle of the view. The divider between the nav graph and the transcript can be dragged to +change their split, and the position is remembered. + +image::navgraph-closeup.png["a branching nav graph with an active node, a collapsed node, and a tinted ancestor"] + +== The per-knot actions menu + +Every knot's *"..."* button opens the same menu, in either pane. Opening it does not change which +knot is active. The keyboard shortcut shown for each item applies to the *active* knot. + +[cols="2,4,1",options="header"] +|=== +| Item | What it does | Key + +| Bless Knot | Accepts this knot's current response as correct. Disabled if nothing is pending. | kbd:[⌥B] +| New Child | Starts a new command from this knot — the time-travel action. | kbd:[⌥A] +| Replay to Here | Re-runs root-to-here and checks each response against what is blessed. | kbd:[⌥R] +| Trace | Opens the Trace panel for this knot. On the root, traces game startup. | kbd:[⌥T] +| Edit Label... | Sets, changes, or clears the knot's label. | kbd:[⌥L] +| _marker swatches_ | Sets one of four marker colours, or clears the marker. | — +| Edit Command... | Changes this knot's command text. | kbd:[⌥E] +| Toggle Lock | Locks or unlocks the knot against deletion. | kbd:[⌥K] +| Insert Parent... | Splices a new knot in above this one. | — +| Splice Out | Removes this knot, reattaching its children to its parent. | — +| Delete | Deletes this knot and everything beneath it. | kbd:[⌥D] +|=== + +On the root knot every item is disabled except Trace, which becomes "trace startup". Trace and +Insert Parent are also unavailable on a knot reached through a keystroke prompt. Delete refuses, +with a brief error, if the knot or any descendant is locked or labelled. + +image::knot-menu-open.png["the actions menu open on a knot in the transcript"] + +== The navbar + +From left to right, the navbar holds: + +* *Status counts* — a green *ok* count, and clickable yellow *new* and red *error* counts. Clicking +*new* or *error* jumps to the next knot of that status anywhere in the tree, cycling round with +wraparound and remembering where it left off for each status. +* *Search* — described below. +* *Dynamic State* — a toggle that shows, inline after each knot, what changed in the game world. +Available only with the `dgdebug` engine; see xref:dynamic-state-and-trace.adoc[]. +* *Marker filter* — four colour swatches. Each narrows the nav graph to branches that contain that +marker colour; clicking the active one again clears the filter. +* *Save* (kbd:[⌘S]), *Replay All* (kbd:[⌥⇧R]), and *Bless Transcript* (kbd:[⌥⇧B]). + +== Replaying + +Replaying re-runs recorded commands against the interpreter and checks the responses against what +you have blessed. It is how you confirm a change to your source did what you meant it to. + +*Replay to Here* (kbd:[⌥R]) re-runs from the root through the active knot and checks each response +along that one path. *Replay All* (kbd:[⌥⇧R]) does the same for every leaf in the tree at once, in +parallel, behind a progress notification you can cancel. Use Replay All to confirm the whole skein +still holds together, not just the path you happen to be looking at. + +Replay always compiles against the *current* files on disk, including any `.dg` files you have added +or removed since the session started — you do not need to restart the session first. See +xref:project-sources.adoc#live-source-tracking[Live source tracking]. + +image::replay-all-progress.png["the Replay All progress notification with its Cancel button"] + +== Search + +The search box is in the navbar; kbd:[Option+F] / kbd:[Alt+F] jumps to it. Searching is +incremental. Every whitespace-separated term must match (the terms are combined with AND), and the +match is against each knot's label and its response text. + +Results appear in a dropdown, each showing the command, a label chip if there is one, and a snippet +with the matched terms highlighted. Arrow keys move through the results; kbd:[Enter] opens the +selected one, scrolling the transcript to it; kbd:[Esc] clears the search. + +image::search-results.png["the search dropdown with a few results and highlighted matches"] + +== Keyboard shortcuts + +The Skein is designed to be usable without a mouse. On macOS the modifier is Option (⌥); on Windows +and Linux it is Alt. Where the table below shows ⌘, use Ctrl on Windows and Linux. + +include::partial$keyboard-reference.adoc[] + +== Saving and version control + +A `.skein` file is plain, line-oriented text at the project root, laid out to produce small, readable +diffs. *Commit your skeins alongside your source.* They are as much a part of the project as the +`.dg` files. + +Saving is explicit. Nothing else writes the `.skein` file — not stopping the session, not switching +skeins, not closing the panel. If the file changes on disk while a session is open (a colleague's +commit, a branch switch), the extension prompts you to reload it. + +== What's next + +xref:dynamic-state-and-trace.adoc[] — the two inspection tools that need the `dgdebug` engine. diff --git a/docs/modules/ROOT/pages/dynamic-state-and-trace.adoc b/docs/modules/ROOT/pages/dynamic-state-and-trace.adoc new file mode 100644 index 0000000..2a45cb9 --- /dev/null +++ b/docs/modules/ROOT/pages/dynamic-state-and-trace.adoc @@ -0,0 +1,76 @@ += Dynamic State and Trace +:navtitle: Dynamic State and Trace + +Two tools help you understand *why* a command did what it did: *Dynamic State*, which shows what +changed in the game world, and *Trace*, which shows which rules fired. Both need the `dgdebug` +engine, and neither is available for a command that ends on a single-keystroke prompt — the +debugger cannot be interrupted mid-keystroke to gather the information. + +== Dynamic State + +Dynamic State answers the question "what changed in the world as a result of this command?". + +Turn it on with the *Dynamic State* toggle in the navbar. It is a display toggle only — the +information is captured after every command regardless — and it is disabled for the `frotz` engines. + +With it on, each transcript knot gains a row of chips after its response: + +* a green chip, `+name`, for a flag or variable that became true or came into existence; +* a yellow chip, `-name`, for one that became false or went away; +* a blue chip, `name = value`, for a variable whose value changed. + +image::dynamic-state-chips.png["a transcript with the toggle on, showing +/-/changed chips under a couple of knots"] + +The comparison is against the nearest ancestor knot that has a captured snapshot — usually the +parent, but not always. A freshly loaded skein, or a knot reached through a keystroke prompt, has +no snapshot of its own, so the diff reaches further up the tree to find one. + +=== Where the information comes from + +After each command the extension runs `dgdebug`'s `@dynamic` query and parses its four sections: +global flags, per-object flags, global variables, and per-object variables. The `(has parent $)` +and `(has relation $)` predicates are combined into a single synthesised location predicate, +`($ is $ $)`, per object, so an object moving from one place to another reads as one change rather +than two. + +These snapshots live only in the running session. They are never written to the `.skein` file, but +they do travel with undo and redo, since re-running a command is itself an undoable edit. + +== Trace + +Trace answers "which predicates were tried for this command, in what order, and where is each one +defined?". + +Open it from a knot's *"..."* menu → *Trace*, or with kbd:[Option+T] / kbd:[Alt+T]. On the root +knot, Trace instead traces the project's *startup*. The Trace panel opens in the panel area, +alongside Terminal, Output, and Debug Console, and reveals itself automatically when you request a +trace. Tracing does not move the active knot and never changes the skein — the trace is regenerated +from scratch each time you ask for one. + +=== Reading a trace + +A trace is a tree of predicate calls. Each row shows an expand control (if it has children), a +*type badge*, the predicate expression, and the `file:line` where it is defined, relative to the +project root. The badges are *ENTER* (blue), *QUERY* (grey), *FOUND* (green), and *NOW* (yellow). +*Expand All* and *Collapse All* buttons sit in the panel's header. + +image::trace-panel-with-source-preview.png["the Trace panel with an expanded call tree and a syntax-highlighted source-preview popover hovering over one row"] + +=== Filtering and jumping to source + +The filter box at the top of the panel is incremental. It highlights matching rows and +automatically expands their ancestors so the matches are visible; pressing kbd:[Enter] jumps to the +next match, cycling round at the end. + +Hover a row for a moment and a popover appears with a syntax-highlighted snippet of that source, +following the pointer. Click a row to open the file at that line in the editor. + +=== How the trace is produced + +For a knot, the extension replays the interpreter to the knot's *parent*, turns tracing on, sends +the knot's command, captures the output, and turns tracing off. A startup trace relaunches +`dgdebug` with its `--trace` option to capture the banner. + +== What's next + +xref:multiple-skeins.adoc[] — when one skein is not enough. diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000..edcdb86 --- /dev/null +++ b/docs/modules/ROOT/pages/index.adoc @@ -0,0 +1,76 @@ += Dialog IDE +:navtitle: Introduction + +Dialog IDE is an extension for Visual Studio Code that turns the editor into a workshop for +interactive fiction written in the https://github.com/dialog-if/dialog[Dialog] language. You write +your source the way you would write any code — in files, with syntax highlighting and an outline — +and you run it through a panel called the *Skein*, which is where this manual spends most of its +time. + +A note on words: the Dialog tooling, and this manual, say *project* rather than *game*. Plenty of +interactive fiction is not a game, and "project" covers all of it. + +image::hero-skein-beside-editor.png["VS Code with a .dg file open on the left and the Skein panel (nav graph + transcript + command box) open beside it on the right. The reference 'money shot'"] + +== The Skein in one paragraph + +When you play a piece of interactive fiction you type a command, read the response, and the world +moves on. At an ordinary prompt that history scrolls away. The Skein keeps it. Every command you +have ever typed, and the response it produced, is stored as a *knot* on a tree that only ever grows. +Because the whole history is retained, you can jump back to any earlier moment, try a different +command, and keep *both* paths; you can mark a response as correct and be told later if a code +change alters it; and you can re-run every path you have recorded in a few seconds to check that a +change broke nothing. + +== What the Skein gives you + +Time travel:: Move back to any earlier point in play and enter a different command without losing +the path you already explored. Every branch you create is kept. See xref:skein-concepts.adoc[]. + +Blessing:: Mark a knot's response as correct. From then on, if a change to your source produces a +different response for that command, the knot is flagged and you are shown exactly what changed. +See xref:skein-concepts.adoc[]. + +Replay All:: Re-run every command on every recorded path against a fresh interpreter, and confirm +each response still matches what you blessed. See xref:creating-and-using-a-skein.adoc[]. + +Trace:: For a single command, see which predicates were tried, in what order, and why, each with a +link into your source. See xref:dynamic-state-and-trace.adoc[]. + +Dynamic state:: After each command, see which flags, variables, and relations changed in the game +world. See xref:dynamic-state-and-trace.adoc[]. + +== Who this manual is for + +The manual assumes you have *never used Visual Studio Code*. The next chapter starts at downloading +it and explains the few pieces of its interface that the rest of the manual relies on. If you +already use VS Code, skip ahead to xref:installing-the-extension.adoc[]. + +Authors who want to run their tests and skein checks from a terminal or a continuous-integration +pipeline, with no editor involved, want xref:command-line-dgbuild.adoc[]. + +== How to read it + +The four "getting set up" chapters — install VS Code, install the extension, initialize a project, +and organize your sources — are meant to be read once, in order. After that the manual is +reference material: the Skein chapters describe the panel control by control, and you can dip into +whichever part you need. xref:troubleshooting.adoc[] collects the current limitations and the +common reasons a project will not run. + +== What Dialog IDE does not do + +It does not replace the Dialog compiler or debugger. It drives the existing toolchain — `dgdebug` +to run your project, `dialogc` to build it — and gives you a place to work with the results. + +Editing source is mostly ordinary VS Code. The extension contributes `.dg` syntax highlighting, +code folding, bracket and indentation handling, an Outline view, and project-wide "Go to Symbol", +then stays out of your way. Everything else in this manual is about *running* the project through +the Skein. + +This is also not the Dialog language manual. For the language itself — and for writing the +`(test $)` and `(assert $)` objects that xref:command-line-dgbuild.adoc[] runs — see the Dialog +manual that ships with the https://github.com/dialog-if/dialog[Dialog toolchain]. + +== What's next + +xref:installing-vscode.adoc[] — install Visual Studio Code. diff --git a/docs/modules/ROOT/pages/initializing-a-project.adoc b/docs/modules/ROOT/pages/initializing-a-project.adoc new file mode 100644 index 0000000..711986f --- /dev/null +++ b/docs/modules/ROOT/pages/initializing-a-project.adoc @@ -0,0 +1,111 @@ += Starting a New Project +:navtitle: Starting a New Project + +A Dialog project, as far as the extension is concerned, is a folder with a `dialog.json` file in +it. The *Dialog IDE: Initialize Dialog Project* command creates that file, along with a working +directory layout and enough starter source to run immediately. + +== Create and open a folder + +Make an empty folder for the project using Finder, Explorer, or the command line, then open it in +VS Code with menu:File[Open Folder...] (menu:File[Open...] on macOS). The Explorer on the left shows +an empty workspace. Everything from here on happens inside that folder. + +== Run Initialize Dialog Project + +Open the Command Palette (kbd:[Cmd+Shift+P] / kbd:[Ctrl+Shift+P]) and run *Dialog IDE: Initialize +Dialog Project*. It asks one question — the project name, which defaults to the folder's name — and +then scaffolds the project. If a `dialog.json` already exists in the folder, the command stops +without changing anything. + +image::init-command-palette.png["Command Palette with 'Dialog IDE: Initialize Dialog Project' highlighted"] + +== What it creates + +[cols="1,3",options="header"] +|=== +| Path | Purpose + +| `main/` +| Your story sources. Starts with `meta.dg` and `story.dg` (below). + +| `lib/` +| The Dialog standard library and other shared code. Starts with `stdlib.dg`, `stddebug.dg`, and +`unit.dg`, copied from the bundled Dialog library. + +| `debug/` +| Sources loaded only when running under the debugger. Empty to begin with. + +| `test/` +| Sources loaded only when running tests. Empty to begin with. + +| `main/meta.dg` +| Starter `(story $)` directives — title, author, blurb, noun, release — plus a freshly generated +`(story ifid)` value. An IFID is required to build the `.zblorb` format. + +| `main/story.dg` +| A minimal room and player object: the least source that will start an interactive prompt. + +| `cover.png` +| A placeholder cover image at the project root. Replace it with your own artwork; a `.zblorb` +build picks it up automatically (see xref:building-and-exporting.adoc[]). + +| `introduction-to-if.pdf`, `play-if-card.pdf` +| Two "how to play interactive fiction" documents, wired into `dialog.json` as *feelies* for the +web export (see xref:building-and-exporting.adoc[]). + +| `dialog.json` +| The project descriptor, described next. +|=== + +When the command finishes, `main/story.dg` opens in the editor so you have somewhere to start +writing. + +image::scaffolded-explorer-tree.png["Explorer showing main/ lib/ debug/ test/, dialog.json, cover.png, and the two PDFs"] + +== The generated dialog.json + +[source,json] +---- +{ + "name": "my-project", + "sources": { + "main": ["main"], + "test": ["test", "lib/unit.dg"], + "debug": ["debug", "lib/stddebug.dg"], + "library": ["lib/stdlib.dg"] + }, + "feelies": [ + { "path": "introduction-to-if.pdf", "name": "Introduction to IF" }, + { "path": "play-if-card.pdf", "name": "IF in One Page" } + ] +} +---- + +The `sources` object lists, per category, the directories and files that make up the project. Each +entry is either a directory (every `.dg` file directly inside it) or a single file path. The four +categories, the rules for ordering, and the rest of `dialog.json` are covered in +xref:project-sources.adoc[]. + +image::generated-dialog-json.png["the file open in the editor with syntax coloring"] + +== Run it for the first time + +Click the *Dialog Skein* item in the status bar, or run *Dialog IDE: Run Default Skein*. The Skein +panel opens beside your editor. The first thing it shows is the interpreter's startup banner — this +is the tree's root, called `START`. Type a command into the box at the bottom, press kbd:[Enter], +and the response comes back as a new knot below the root. + +That is the whole loop. xref:creating-and-using-a-skein.adoc[] tours every control in the panel. + +image::first-skein-session.png["Skein panel just after one command, root + one child knot"] + +== Opening an existing project + +There is nothing special to do: menu:File[Open Folder...] on any folder that contains a +`dialog.json`. If the folder has a `.dg` file that no source category covers, the extension points +it out — see the uncovered-source warning in xref:project-sources.adoc[]. + +== What's next + +xref:project-sources.adoc[] — how `dialog.json` organizes sources. diff --git a/docs/modules/ROOT/pages/installing-the-extension.adoc b/docs/modules/ROOT/pages/installing-the-extension.adoc new file mode 100644 index 0000000..4a5658c --- /dev/null +++ b/docs/modules/ROOT/pages/installing-the-extension.adoc @@ -0,0 +1,77 @@ += Installing the Dialog IDE Extension +:navtitle: Installing the Extension + +With VS Code installed, adding Dialog IDE takes a minute. This chapter also covers what the Dialog +toolchain needs on your particular platform, since that varies, and how to confirm the extension is +working. + +== Install from the Extensions view + +. Open the Extensions view with kbd:[Cmd+Shift+X] / kbd:[Ctrl+Shift+X]. +. Search for *Dialog IDE*. The entry you want is published by `hlship`; its marketplace identifier +is `hlship.dialog-ide`. +. Click *Install*. + +image::marketplace-extension-page.png["the Dialog IDE marketplace page inside VS Code's Extensions view, Install button visible; if the unverified-publisher note shows, include it in the crop"] + +During or after installing you may see a note that the publisher is *not verified* — the wording is +along the lines of "hlship is not a verified publisher" or "This publisher has not verified +ownership of a domain". This refers only to domain verification, a marketplace feature Dialog IDE +has not set up. It is not a security warning and it does not affect how the extension works. +Continue with the installation. + +// TODO(flesh-out): confirm VS Code's exact current wording for the unverified-publisher note and +// quote it verbatim. + +== Other ways to install + +If you prefer the command line, and set up the `code` command in +xref:installing-vscode.adoc#the-code-command[the previous chapter]: + +[source,console] +---- +code --install-extension hlship.dialog-ide +---- + +On a machine with no marketplace access, or to install a pre-release build, use a `.vsix` file: +open the *"..."* menu at the top of the Extensions view and choose *Install from VSIX...*, or run +`code --install-extension dialog-ide-.vsix`. + +== What the Dialog toolchain needs on your platform + +The extension does not interpret or compile Dialog itself. It runs external binaries: `dgdebug` to +run a project, `dialogc` to build one, and — for a couple of features — `aambundle` and `dfrotz`. +Whether you have to install those yourself depends on your platform. + +include::partial$requirements-matrix.adoc[] + +If your platform is not one of the bundled ones, or you want the extension to use a specific build +of the toolchain, set a `binDir` in the project's `dialog.json` pointing at the directory that +contains the binaries. `binDir` overrides both the bundled toolchain and anything on your `PATH`. +This is covered in xref:project-sources.adoc#pointing-at-a-specific-toolchain-bindir[the next +chapter]. + +== If you had dialog-language-support installed + +If you previously installed the separate +https://marketplace.visualstudio.com/items?itemName=sideburns3000.dialog-language-support[`dialog-language-support`] +extension, Dialog IDE notices at startup and offers to help you disable or uninstall it. Do so. +Running both leads to inconsistent `.dg` highlighting and a duplicated "Compile to..." entry in the +editor's context menu. Dialog IDE now bundles the same grammar, so you lose nothing by removing the +older extension. + +== Confirm it is working + +Open any `.dg` file. You should see syntax coloring, and pressing kbd:[Cmd+Shift+O] / +kbd:[Ctrl+Shift+O] should list the file's symbols. At the bottom-left of the window, a status-bar +item reading *Dialog Skein* appears; when no session is running it shows a play icon and starts the +default skein if you click it. + +image::status-bar-item.png["bottom-left status bar showing the idle 'Dialog Skein' item"] + +If highlighting works but the *Dialog IDE:* commands fail when you run them, the cause is almost +always a missing toolchain — check the table above, and see xref:troubleshooting.adoc[]. + +== What's next + +xref:initializing-a-project.adoc[] — scaffold a new project. diff --git a/docs/modules/ROOT/pages/installing-vscode.adoc b/docs/modules/ROOT/pages/installing-vscode.adoc new file mode 100644 index 0000000..29bf82d --- /dev/null +++ b/docs/modules/ROOT/pages/installing-vscode.adoc @@ -0,0 +1,76 @@ += Installing Visual Studio Code +:navtitle: Installing VS Code + +Visual Studio Code — usually shortened to *VS Code* — is a free, open-source code editor from +Microsoft that runs on macOS, Windows, and Linux. It is not the same product as "Visual Studio", +and you do not need a Microsoft account to use it. If you already have it installed, skip to +xref:installing-the-extension.adoc[]. + +== Download and install + +. Open https://code.visualstudio.com in a browser. The site detects your operating system and +offers the matching download. ++ +image::vscode-download-page.png["code.visualstudio.com with the platform download buttons visible"] +. Install it the usual way for your platform: ++ +-- +*macOS* — the download is a `.zip`. Open it, then drag *Visual Studio Code* into your Applications +folder and launch it from there. + +*Windows* — run the `.exe` installer and accept the defaults. Leave *Add to PATH* checked; that is +what lets you type `code` in a terminal later. + +*Linux* — use the `.deb` or `.rpm` package, or the Snap, as described on the download page for your +distribution. +-- + +[[the-code-command]] +=== The `code` command (optional) + +A few steps later in this manual use a `code` command in a terminal — for example +`code --install-extension`. It is optional, but convenient to set up now. + +* *Windows*: already done by the installer. +* *macOS*: launch VS Code, open the <>, and run +*Shell Command: Install 'code' command in PATH*. +* *Linux*: the package installs it automatically. + +== VS Code works on a folder + +VS Code always works against a *folder*, which it calls a *workspace*. There is no habit here of +creating a loose file and saving it anywhere on disk; instead you open the folder your project +lives in, and everything — the file list, search, the Dialog IDE commands — is relative to that +folder. + +To open one, use menu:File[Open Folder...] (on macOS, menu:File[Open...]). The *Explorer* on the +left — the top icon in the Activity Bar, or kbd:[Cmd+Shift+E] / kbd:[Ctrl+Shift+E] — shows the +folder's contents. You will open a Dialog project this way in xref:initializing-a-project.adoc[]. + +image::vscode-first-window.png["a fresh VS Code window, Welcome tab, Activity Bar on the left labeled"] + +[[the-command-palette]] +== The Command Palette + +The *Command Palette* is a searchable list of every command VS Code and its extensions provide. +Open it with kbd:[Cmd+Shift+P] on macOS, or kbd:[Ctrl+Shift+P] on Windows and Linux. + +This manual runs almost everything from the Command Palette. Every action the extension adds is a +command whose name begins with *Dialog IDE:* — for example *Dialog IDE: Initialize Dialog Project*. +Start typing any part of a command's name to filter the list, press kbd:[Enter] to run the +highlighted one, or kbd:[Esc] to dismiss the palette without running anything. + +image::command-palette.png["palette open, 'Dialog IDE' typed, the extension's commands listed"] + +== The Extensions view + +The *Extensions view* is where you find, install, and manage extensions. Open it from the Activity +Bar icon that looks like stacked squares, or with kbd:[Cmd+Shift+X] / kbd:[Ctrl+Shift+X]. From here +you can search the marketplace, install or uninstall an extension, and disable one without removing +it. The next chapter uses this view to install Dialog IDE. + +image::extensions-view.png["Extensions sidebar open with the search box focused"] + +== What's next + +xref:installing-the-extension.adoc[] — install the Dialog IDE extension. diff --git a/docs/modules/ROOT/pages/multiple-skeins.adoc b/docs/modules/ROOT/pages/multiple-skeins.adoc new file mode 100644 index 0000000..1ea9404 --- /dev/null +++ b/docs/modules/ROOT/pages/multiple-skeins.adoc @@ -0,0 +1,41 @@ += When to Use More Than One Skein +:navtitle: Multiple Skeins + +A project can hold as many `.skein` files as you like. Each is an independent tree with its own +engine and seed. Most projects are fine with just `default.skein`, but a few situations call for +more. + +== How it works + +Every `.skein` file at the project root is a separate skein. *Dialog IDE: Run Skein...* lists them +all for you to choose from, and *Dialog IDE: New Skein...* creates a new one. Only one session runs +at a time, so opening a second skein prompts you to stop the first. The name of the active skein +appears in the panel's tab. + +image::run-skein-picker.png["the Run Skein... QuickPick listing several .skein files"] + +== Reasons to keep more than one + +A clean canonical playthrough.:: Keep `default.skein` as the tidy, fully blessed walkthrough of the +project — including the knot labelled `WALKTHROUGH` that *Export Web Page* turns into an embedded +transcript — and do rough, exploratory testing somewhere else. That keeps the file the web export +depends on from filling up with dead ends. + +A different seed or engine.:: A skein's engine and random seed are fixed when it is created. To +test your project under a different random seed, or to compare the `frotz` and `frotz-release` +engines against `dgdebug`, you need a separate skein for each. + +Focused regression suites.:: One skein per feature or area — `combat.skein`, `parser.skein`, +`endings.skein` — keeps each tree small enough to review in a diff, and `dgbuild run-skein` can +replay them all together in a single continuous-integration step (see +xref:command-line-dgbuild.adoc[]). + +== Keeping them tidy + +Name a skein for what it covers. Commit the skeins you care about — they diff cleanly and belong in +version control next to the source. A skein you only spun up for a throwaway experiment does not +need to be committed. + +== What's next + +xref:building-and-exporting.adoc[] — turning the project into something you can distribute. diff --git a/docs/modules/ROOT/pages/project-sources.adoc b/docs/modules/ROOT/pages/project-sources.adoc new file mode 100644 index 0000000..5fcda2e --- /dev/null +++ b/docs/modules/ROOT/pages/project-sources.adoc @@ -0,0 +1,140 @@ += Organizing Your Sources +:navtitle: Organizing Your Sources + +`dialog.json` sits at the root of your project folder and tells the extension which files make up +the project. This chapter covers the parts of it you touch most: the `name`, the `sources` object, +and `binDir`. The `exports`, `dialogcOptions`, and `feelies` fields are covered in +xref:building-and-exporting.adoc[]. + +The file is plain JSON. When the extension edits it for you — adding a source, adding a feelie — it +preserves your existing formatting and key order. + +== The four source categories + +`sources` is an object with up to four keys. Each key's value is a list, and each item in that list +is either a directory or a single file. + +[cols="1,3,2",options="header"] +|=== +| Category | What it holds | When it is compiled + +| `main` +| Your story sources. This is the default category and the only one that is required. +| Always. + +| `library` +| Shared library code, including the Dialog standard library. +| Always. + +| `debug` +| Extra sources for use under the interactive debugger — debugging helpers, layout tweaks. +| Skein sessions, *Debug in Terminal*, and *Run Tests*. + +| `test` +| Unit-test sources: the objects that drive `(test $)` / `(assert $)` checks. +| *Run Tests* and `dgbuild test` only. A running Skein never loads them. +|=== + +The *Dialog IDE: Add File to dialog.json...* command shows these same one-line descriptions when it +asks which category a file belongs in. + +== Directory entries and file entries + +A *directory* entry contributes every `.dg` file that sits *directly* inside that directory. It +does not descend into subdirectories, and the files come in *sorted* (lexical) order. + +A *file* entry contributes exactly that one file, in the position you list it. + +Because a directory's files arrive in sorted order, you do not have fine control over their +sequence. When the order between two files matters — and in Dialog it often does — list those +files individually, in the order you need them, rather than relying on a directory entry. + +A path that does not exist on disk is skipped quietly; it is not an error. + +image::dialog-json-with-categories.png["a realistic dialog.json with several files across the four categories"] + +== Why order matters + +The extension hands the compiler one flat list of files, built by concatenating the categories in a +fixed order: `main`, then `test`, then `debug`, then `library`. + +Dialog resolves rules from the top of that list down, and the first matching rule wins. So put your +*exceptions before the default rules* they override, and put any file that needs to override +library behaviour *before* the library itself. + +[[live-source-tracking]] +== Live source tracking + +The extension watches your project's files the whole time it is running. Editing a `.dg` file, +adding a new one, deleting one, or renaming one is picked up automatically — there is no "refresh +sources" or "reload project" action, and you never need to restart a Skein session because the +source changed. + +Because a directory entry in `dialog.json` is re-expanded every time the project is compiled, a +file you drop into `main/` (or `debug/`, or any watched directory) is part of the very next build, +and a file you delete is gone from it, with no edit to `dialog.json`. + +A running Skein always compiles against the *current* files on disk. The next command you send, and +the next *Replay* or *Replay All*, use the latest source. The uncovered-source and duplicate-source +warnings described below also re-evaluate live as files and `dialog.json` change. + +== Per-format source suffixes + +A file whose name ends `..dg` is included *only* when building for that format: + +* `colors.zblorb.dg` is compiled into a `.zblorb` export and nowhere else. +* `layout.dgdebug.dg` is loaded only when running against `dgdebug` — a Skein session, +*Debug in Terminal*, or *Run Tests*. + +The recognised formats are `zblorb`, `z8`, `aa`, and `dgdebug`. A file with no such suffix, or with +a suffix that does not match any format the extension builds for, is always included. + +Use this to keep per-target tweaks — colours, screen layout, debugging shortcuts — from leaking +into builds where they do not belong. + +== The uncovered-source warning + +If you create a `.dg` file that no category covers, the extension flags it two ways: a dismissible +notification, and a badge on the file in the Explorer. Both offer a one-click *Add to dialog.json* +fix that prompts for a category and edits the file for you. + +Turn this off with the `dialog-ide.warnOnUncoveredSource` setting if it gets in your way. + +image::uncovered-source-badge-quickfix.png["Explorer showing the badge on an uncovered .dg file, with the quick-fix action visible"] + +== The duplicate-source warning + +If a file appears in more than one category — or twice in one category, through overlapping +directory entries — the extension flags it. Because order matters, a file compiled twice is rarely +harmless. Turn this off with `dialog-ide.warnOnDuplicateSource`. + +== Adding a file from the Command Palette + +Run *Dialog IDE: Add File to dialog.json...*. It offers the file currently open in the editor, or +lets you browse for one, then asks which category to add it to and edits `dialog.json` in place. + +image::add-file-picker.png["the category QuickPick showing the four categories and their descriptions"] + +[[pointing-at-a-specific-toolchain-bindir]] +== Pointing at a specific toolchain (binDir) + +Add a `binDir` field whose value is a directory containing `dgdebug`, `dialogc`, and (if you use +the web export) `aambundle`: + +[source,json] +---- +{ + "name": "my-project", + "binDir": "/opt/dialog/bin", + "sources": { "main": ["src"] } +} +---- + +A relative path is resolved against the project root; an absolute path is used as-is. `binDir` takes +priority over everything else — the extension's bundled toolchain and anything on your `PATH`. Use +it for a locally built `dgdebug`, or on a platform the extension does not bundle a toolchain for +(see xref:installing-the-extension.adoc[]). + +== What's next + +xref:skein-concepts.adoc[] — the ideas behind the Skein, before you start using it. diff --git a/docs/modules/ROOT/pages/skein-concepts.adoc b/docs/modules/ROOT/pages/skein-concepts.adoc new file mode 100644 index 0000000..1265f09 --- /dev/null +++ b/docs/modules/ROOT/pages/skein-concepts.adoc @@ -0,0 +1,139 @@ += How the Skein Works: Time Travel and the Tree of Timelines +:navtitle: How the Skein Works + +The Skein is worth a few minutes of theory before you start clicking around in it. The panel makes +much more sense once you have the model in your head, and the model is not complicated: it is a +permanent, branching record of everything you have ever tried, plus a viewpoint you can move +anywhere within it. + +== The core idea + +Running a piece of interactive fiction is a loop. You type a command, the interpreter prints a +response, the world changes, and you go again. At an ordinary prompt that history is +write-once-and-forget: scroll up and you can read it, but you cannot re-enter it. + +The Skein keeps the history and makes it branching. Every command you have ever typed, together +with the response it produced, is stored as a *knot*. The knots form a tree that only ever grows. +The Skein itself is that tree plus a live interpreter process; this chapter is about the tree. + +== Knots + +A knot is one command and the response it produced. + +The same command text can appear as many different knots, because the same input means different +things in different situations. `take lamp` in the cave, `take lamp` in the shop, and `take lamp` +after you already picked it up are three separate knots, each with its own response, each sitting +at a different point in the tree. + +A knot also carries a few pieces of state you can set yourself: an optional *label*, an optional +*marker* colour, a *locked* flag, and — once you bless it — a *blessed* response that is kept +distinct from the knot's current one. + +== The tree + +Every skein has a single synthetic *root* knot, shown as `START`. Its "response" is the +interpreter's startup banner: the text your project prints before the first prompt. + +A knot's children are the commands you have tried from that point. The tree grows only downward and +outward — trying a new command adds a child, and nothing is ever removed to make room for it. + +image::navgraph-annotated-spine-vs-branches.png["a nav-graph screenshot annotated to point out the root, the current spine, the active knot, and an off-spine branch"] + +== The spine and the active knot + +At any moment one path through the tree is special: the *spine*, which runs from the root down to a +single leaf. The transcript on the right of the panel always shows the spine, root to leaf, as a +readable play session. + +Mechanically, each knot remembers which of its children is "selected". Follow those selected-child +pointers from the root and you trace out the spine. + +Separately, the *active knot* is where your viewpoint is — the last knot you clicked or navigated +to. It can sit anywhere along the spine, or above it, without shortening the spine. Clicking a knot +re-points the spine to run through it, and then extends the spine downward through any unbroken run +of single-child knots until it reaches a branch or a leaf. In other words, selecting a knot on a +straight stretch of history carries you to the end of that stretch. + +== Siblings + +Siblings are knots that share a parent. They are ordered *alphabetically by command text*, not by +the order you created them. This is the order the keyboard's "previous sibling" and "next sibling" +keys move through, and it is the left-to-right order the nav graph draws them in. + +Two siblings can never have the same command. Re-running a command that you have already tried from +a given knot simply re-selects the existing child rather than creating a duplicate. + +== Time travel + +Move the active knot to any earlier point in the tree, enter a different command, and you have a +new branch. The path you were previously on is still there in full; it is just no longer the +displayed spine. Every branch is a timeline that continues to exist. Choosing a different branch +only changes which selected-child pointers the spine follows — it does not disturb anything. + +Under the surface, the interpreter cannot rewind. When you act from a knot that is not where the +interpreter currently sits, the extension quietly stops the interpreter, starts a fresh one, and +replays the commands from the root down to your chosen knot before sending the new command. This +happens constantly and is not something you trigger or confirm — it is simply how the Skein stays +in step with wherever you have pointed it. + +== Blessing + +*Blessing* a knot records that its current response is correct. + +From then on, the knot is a check. If a change to your source ever makes that command produce +different text, the knot is flagged as an error and the transcript shows you a word-level diff: +what was removed, what was added. If the response goes back to matching, the flag clears. + +There are two blessing actions. *Bless Knot* blesses a single knot. *Bless Transcript* blesses +every not-yet-valid knot from the root down through the whole visible transcript, which is the +quick way to accept a batch of intended changes at once. Either way, blessing replaces the knot's +stored "correct" response with its current one and marks the knot valid. + +== Knot status and tree status + +Each knot has a status: + +new:: No response has been blessed yet. Shown in yellow. +valid:: The current response matches the blessed one. Shown in grey. +error:: The current response differs from the blessed one. Shown in red. + +Separately, every knot has an aggregated *tree status*: the worst status found among that knot and +all of its descendants, where error outranks new and new outranks valid. The nav graph uses this +to tint the ancestors of a troubled knot, so a red or yellow node deep in a collapsed branch still +shows up as a coloured hint on the branch above it. A knot's own status and its tree status are +deliberately different things. + +== Undo and redo + +Undo and redo are unlimited, and always instant. + +They cover *structural* edits to the tree: running a new command, blessing and unblessing, +deleting and splicing, editing a command, inserting a parent, and changing a label, lock, or +marker. They do *not* cover plain navigation — moving the active knot, expanding or collapsing +nodes, running a replay. Undo never re-runs anything; because the tree is stored as a sequence of +immutable versions, undoing is just a matter of pointing back at the previous one. + +== Labels, locking, and markers + +A *label* is a short name you give a knot. Labels are unique within a skein, which makes them +useful as anchors — for instance, a knot labelled `WALKTHROUGH` is what *Export Web Page* follows +to build the walkthrough transcript it embeds (see xref:building-and-exporting.adoc[]). + +*Locking* a knot protects it from deletion. A labelled knot is treated as locked for this purpose +too. Deleting a knot is refused outright if that knot, or anything beneath it, is locked or +labelled — so a lock on a leaf also protects the path that leads to it. + +A *marker* is one of four colours, or none. It has no effect on anything; it is a visual note to +yourself that a knot needs attention. Markers are saved in the `.skein` file, and the navbar has a +filter that narrows the nav graph to just the branches carrying a given colour. + +== Fixed for the life of a skein + +Two things are chosen when a skein is created and can never change afterward: the *engine* +(`dgdebug`, `frotz`, or `frotz-release`) and the *random seed*. If you need to test your project +against a different seed, or compare the `frotz` and `frotz-release` engines, you do that in a +second skein — see xref:multiple-skeins.adoc[]. + +== What's next + +xref:creating-and-using-a-skein.adoc[] — create a skein and tour every control in the panel. diff --git a/docs/modules/ROOT/pages/troubleshooting.adoc b/docs/modules/ROOT/pages/troubleshooting.adoc new file mode 100644 index 0000000..5d173ca --- /dev/null +++ b/docs/modules/ROOT/pages/troubleshooting.adoc @@ -0,0 +1,62 @@ += Troubleshooting and Known Limitations +:navtitle: Troubleshooting + +This chapter collects the extension's current limitations and the handful of problems that come up +often, with their fixes. + +== Known limitations + +* The `frotz` and `frotz-release` engines need `dfrotz` on your `PATH` or in `binDir`. Unlike +`dgdebug` and `dialogc`, it is not bundled on any platform yet. +* When a `.skein` file changes on disk, the extension offers to reload it, but there is no finer +"merge from disk" beyond that. +* Dynamic State and Trace require the `dgdebug` engine, and neither works for a command that ends on +a single-keystroke prompt. +* *Export Web Page* needs `aambundle`, from AAmachine, in addition to `dgdebug` and `dialogc`. +* An export configuration cannot be edited through the wizard — remove it and add it again, or edit +`dialog.json` directly. +* Intel Macs and Linux on ARM have no bundled toolchain; install Dialog yourself (see +xref:installing-the-extension.adoc[]). + +== "dgdebug not found", or a command that does nothing + +The toolchain is missing or was not found. Either your platform has no bundled toolchain, or the +bundled one did not resolve. + +Put `dgdebug` and `dialogc` on your `PATH`, or add a `binDir` to `dialog.json` pointing at the +directory that holds them (see +xref:project-sources.adoc#pointing-at-a-specific-toolchain-bindir[Pointing at a specific +toolchain]). `binDir` wins over everything else. `aambundle` is only needed for *Export Web Page*, +and `dfrotz` only for the `frotz` engines. + +== A `.dg` file "isn't being compiled" + +* Check that some `sources` category covers it. The extension shows an Explorer badge and a +notification for any uncovered `.dg` file, with a one-click fix. +* Check the file name. A `something..dg` suffix restricts the file to that one build target. +* Check the ordering. Categories are concatenated `main`, `test`, `debug`, `library`, and the first +matching rule wins — a rule you expected to fire may be shadowed by an earlier one. + +See xref:project-sources.adoc[] for all three. + +== The Skein and the files on disk disagree + +Saving a skein is always explicit, so the two can drift. If you edited the `.skein` file outside the +editor, accept the reload prompt. If you changed *source*, run *Replay* or *Replay All* to +re-check the blessed responses against the new code. + +== Where things are written + +[cols="1,2",options="header"] +|=== +| What | Where +| Skeins | `*.skein` at the project root. Commit them. +| Compiled story files | Wherever each export configuration's `output` points. +| Web export | `out/web/`, plus a `.zip` in `out/`. +| Frotz session builds | A temporary directory, rebuilt each time a `frotz` session starts. +|=== + +== Getting help + +The Interactive Fiction Community Forum has a thread for Dialog IDE: +https://intfiction.org/t/dialog-ide-0-0-1/81465. diff --git a/docs/modules/ROOT/partials/keyboard-reference.adoc b/docs/modules/ROOT/partials/keyboard-reference.adoc new file mode 100644 index 0000000..28f1ee9 --- /dev/null +++ b/docs/modules/ROOT/partials/keyboard-reference.adoc @@ -0,0 +1,35 @@ +// Reused by creating-and-using-a-skein.adoc; can also be pulled into troubleshooting or an appendix. +// Modifier is Option (⌥) on macOS, Alt on Windows/Linux. ⌘ = Ctrl on Windows/Linux. + +.Tree-wide +[cols="1,3",options="header"] +|=== +| Keys | Action +| `⌘S` | Save skein +| `⌘Z` / `⌘⇧Z` | Undo / Redo (structural edits only; instant) +| `⌥⇧R` | Replay All +| `⌥⇧B` | Bless Transcript +| `⌥F` | Focus the search box +| `⌥⇧↑` / `⌥⇧↓` | First knot (root) / last knot (leaf) +| `⌘⇧A` | Open the Command Palette from inside the Skein / Trace panel +|=== + +.Active knot +[cols="1,3",options="header"] +|=== +| Keys | Action +| `⌥↑` / `⌥↓` | Parent / child knot +| `⌥←` / `⌥→` | Previous / next sibling (alphabetical) +| `⌥B` | Bless Knot +| `⌥R` | Replay to active knot +| `⌥A` | New Child (time travel) +| `⌥E` | Edit Command +| `⌥L` | Edit Label +| `⌥K` | Toggle Lock +| `⌥D` | Delete +| `⌥X` | Toggle expand / collapse in the nav graph +| `⌥T` | Trace +|=== + +* *Insert Parent* and *Splice Out* are in the "..." menu with no accelerator. +* The navbar new / error seek badges, zoom, pan, and pane resize are mouse-only. diff --git a/docs/modules/ROOT/partials/requirements-matrix.adoc b/docs/modules/ROOT/partials/requirements-matrix.adoc new file mode 100644 index 0000000..23fcfcf --- /dev/null +++ b/docs/modules/ROOT/partials/requirements-matrix.adoc @@ -0,0 +1,18 @@ +// Reused by installing-the-extension.adoc. + +[cols="1,3",options="header"] +|=== +| Your platform | What you need + +| Windows (x64), Apple Silicon Mac, Linux (x64) +| Nothing extra. `dgdebug`, `dialogc`, and `aambundle` are bundled with the extension. + +| Intel Mac, Linux ARM, other platforms +| Install the https://github.com/dialog-if/dialog[Dialog toolchain] yourself, with `dgdebug` / + `dialogc` on `PATH` (or set `binDir` in `dialog.json`). `aambundle` from + https://github.com/dialog-if/aamachine[AAmachine] is needed only for *Export Web Page*. + +| Any platform, `frotz` / `frotz-release` engine +| Additionally needs `dfrotz` (from https://gitlab.com/DavidGriffith/frotz[frotz]) on `PATH` / + `binDir` — not bundled on any platform yet. +|=== diff --git a/docs/screenshot-manifest.adoc b/docs/screenshot-manifest.adoc new file mode 100644 index 0000000..52dff41 --- /dev/null +++ b/docs/screenshot-manifest.adoc @@ -0,0 +1,139 @@ += Screenshot shot-list +:page-role: -toc + +// Not a published page (it lives outside modules/, so Antora ignores it) — a working checklist for +// capturing the manual's screenshots. Each row is one `image::.png[]` macro in a chapter; +// the current file is a generated placeholder. To do a real capture, follow the row and overwrite +// modules/ROOT/images/.png. +// +// Surfaces: +// VS CODE — VS Code window chrome (Explorer, Command Palette, notifications, status bar). +// Cannot be automated; capture by hand (macOS ⇧⌘4, Windows Snipping Tool). +// WEBVIEW — the Skein or Trace panel. It is a localhost web page; can be captured by hand in +// VS Code, or driven headlessly against the `src/dialoged/skein/__fixtures__/project/ +// dgsample` fixture (dgdebug is on PATH). See the plan's "open questions". +// BROWSER — a plain web browser (the exported web page). +// +// Style: light theme, default VS Code UI, window ~1400px wide, no personal info on screen. +// Annotations (arrows / labels) are added after capture; note them in "annotate". + +[cols="1,1,2,3,2",options="header"] +|=== +| slug | surface | page / section | capture | annotate + +| hero-skein-beside-editor | WEBVIEW+VS CODE | index — What Dialog IDE is +| A `.dg` file open in the editor, the Skein panel open beside it with a small populated tree. +| none (clean hero) + +| vscode-download-page | BROWSER | installing-vscode — Downloading +| code.visualstudio.com with the OS download buttons visible. +| none + +| vscode-first-window | VS CODE | installing-vscode — First launch +| A fresh VS Code window (Welcome tab), nothing opened. +| label the Activity Bar and the Explorer icon + +| command-palette | VS CODE | installing-vscode — The Command Palette +| Palette open with `Dialog IDE` typed, showing the extension's commands. +| none + +| extensions-view | VS CODE | installing-vscode — The Extensions view +| Extensions sidebar open, search box focused/empty. +| none + +| marketplace-extension-page | VS CODE | installing-the-extension — Installing from the Extensions view +| The Dialog IDE page in the Extensions view, Install button visible. +| none + +| status-bar-item | VS CODE | installing-the-extension — Confirming it is active +| Bottom-left status bar, idle "Dialog Skein" item. +| circle/arrow the item + +| init-command-palette | VS CODE | initializing-a-project — Run "Initialize Dialog Project" +| Palette with "Dialog IDE: Initialize Dialog Project" highlighted. +| none + +| scaffolded-explorer-tree | VS CODE | initializing-a-project — What gets scaffolded +| Explorer after init: `main/ lib/ debug/ test/`, `dialog.json`, `cover.png`, the two PDFs. +| none + +| generated-dialog-json | VS CODE | initializing-a-project — Reading the generated dialog.json +| The generated `dialog.json` open in the editor. +| none + +| first-skein-session | WEBVIEW | initializing-a-project — First run +| Skein panel right after one command: root + one child knot, response visible. +| none + +| dialog-json-with-categories | VS CODE | project-sources — Pointing at a specific toolchain (end of page) +| A realistic `dialog.json` with several files across `main` / `test` / `debug` / `library`. +| none + +| uncovered-source-badge-quickfix | VS CODE | project-sources — Uncovered-source warning +| Explorer with the warning badge on an uncovered `.dg` file; the "Add to dialog.json" action shown. +| arrow to the badge + +| add-file-picker | VS CODE | project-sources — Adding files from the palette +| The category QuickPick (four categories + descriptions). +| none + +| navgraph-annotated-spine-vs-branches | WEBVIEW | skein-concepts — The tree +| A nav graph with at least two branch points and a collapsed node. +| label: root, current spine, active knot, off-spine branch + +| skein-panel-annotated | WEBVIEW | creating-and-using-a-skein — Panel layout +| The whole Skein panel, tree of ~10-15 knots, transcript populated. +| label: navbar, nav graph, transcript, command input + +| diff-rendering | WEBVIEW | creating-and-using-a-skein — The transcript +| A transcript row in the error state with a red/blue word-level diff and visible whitespace. +| none + +| keystroke-input | WEBVIEW | creating-and-using-a-skein — The command input +| The keystroke variant of the input (Key: field + Enter / Space / Backspace). +| none + +| navgraph-closeup | WEBVIEW | creating-and-using-a-skein — The nav graph +| Close crop of a branching graph: active node, a collapsed node, a tinted ancestor. +| none + +| knot-menu-open | WEBVIEW | creating-and-using-a-skein — The per-knot actions menu +| The "..." menu open on a transcript knot, all items visible. +| none + +| replay-all-progress | WEBVIEW | creating-and-using-a-skein — Replaying +| The Replay All progress notification with the Cancel button. +| none + +| search-results | WEBVIEW | creating-and-using-a-skein — Search +| The search dropdown with a few results and highlighted matches. +| none + +| dynamic-state-chips | WEBVIEW | dynamic-state-and-trace — Dynamic State +| Transcript with the toggle on, +/-/changed chips under a couple of knots. +| none + +| trace-panel-with-source-preview | WEBVIEW | dynamic-state-and-trace — Trace +| Trace panel with an expanded call tree and a hovering syntax-highlighted source-preview popover. +| none + +| run-skein-picker | VS CODE | multiple-skeins — The mechanics +| The Run Skein... QuickPick listing several `.skein` files. +| none + +| configure-exports-wizard | VS CODE | building-and-exporting — Export configurations +| The format QuickPick (zblorb / z8 / aa) inside the wizard. +| none + +| export-success-toast | VS CODE | building-and-exporting — Compiling a story file +| The "Exported ... to ..." notification with the Reveal button. +| none + +| web-export-in-browser | BROWSER | building-and-exporting — The downloadable web page +| `out/web/index.html` in a browser: cover, bibliography, Play button, feelie links. +| none + +| add-feelie-flow | VS CODE | building-and-exporting — Feelies +| Explorer right-click menu with "Dialog IDE: Add Feelie" highlighted. +| none +|===