Skip to content

Debugging & Mistakes

Using the dev debugger, and what the engine does when you make a mistake.

Dev Debugger

The dev debugger is always available under npm run dev. Press ` (backtick) to toggle it open. It is also bundled into the production build, where the (debugger:) config decides whether it responds (see In the built game below).

Panels

PanelContents
TraceRecent passage navigation history (read-only).
VarsAll $ global variables with live editable values. Temp vars (_name) from the last passage execution appear below as a read-only section.
PassagesSearchable list of all passages in the game (display only).
HooksWrappers and hook injections registered for the current passage.

Below the tab panels sits a permanent Eval section, always visible regardless of which tab is active. Type any Ana expression or macro call and press Ctrl+Enter (or the Run button). Results accumulate as a scrollable history log; click any past entry to re-populate the textarea.

The debugger state (open/closed, active panel) persists across page reloads via localStorage.

In the built game

Because a built game is a single file that you and modders test (and that players can open directly), the debugger ships inside every build. What it does there is up to you, set in GameInit with (debugger:):

  • (debugger: enabled) (the default) keeps it fully available.
  • (debugger: disabled) makes the backtick toggle do nothing, so players can't open it.
  • (debugger: cheater) keeps it available but, as a nod to the no-save-scumming design, flags the playthrough and disables further achievements the moment the player changes a variable through the Eval panel. Reading values is always free, and loading a save made before the cheat clears the flag.

When You Make a Mistake

Ana's error behavior, in one place:

SituationWhat happens
(set:) a variable to a different type than declaredHard runtime error, surfaced in the dev console with passage + line.
(get:) a property that doesn't existReturns undefined and never throws. (if: (get: $item, _id, "poisoned")) is just falsy.
(goto:) / (update:) / (action:) to a passage that doesn't existLogged as a navigation error; in dev the validator flags it ahead of time. In production the navigation is a no-op rather than a crash.
Rendering to a zone the current layout doesn't defineThe output is discarded with a console warning (dev).
Overlapping schedule entries for the same groupThrows at registration time, so you catch it during authoring.
(break:) / (continue:) outside a loopIgnored, with a dev warning and a validator warning.

Run npm run parse and open the dev debugger (backtick) early and often; most mistakes surface there before a player ever sees them.