Passages and Navigation
In interactive fiction, a passage is a single story unit: a room, scene, dialogue beat, combat node, or cutscene.
Choicekit does not dictate rendering, so each passage can store whatever payload your UI needs.
Passage shape
Section titled “Passage shape”Each passage has:
name: unique id for navigationdata: content payload (string, markdown, rich object, etc.)tags?: optional labels for filtering/querying
{ name: "Hallway", data: "Two doors. One is locked.", tags: ["hub", "act-1"]}Defining starting passages
Section titled “Defining starting passages”With ChoicekitEngineBuilder, the first passage in withPassages(...) is the starting passage.
const engine = await new ChoicekitEngineBuilder() .withName("daves-adventure") .withPassages( { name: "Start", data: "You wake in a dim corridor.", tags: ["intro"] }, { name: "Hallway", data: "Two doors. One is locked.", tags: ["hub"] }, ) .withVars({ hasKey: false }) .build();You can add passages later as content unlocks:
engine.addPassage({ name: "SecretRoom", data: "Dusty relics line the walls.", tags: ["secret"],});Reading current location
Section titled “Reading current location”engine.passageId: current passage idengine.passage: current passage object
These are what your renderer should use to display story content.
Navigating
Section titled “Navigating”Use navigateTo(passageId) to resolve a choice and move story flow.
engine.navigateTo("Hallway");For rewind/forward UX, use:
engine.backward(step?)engine.forward(step?)
Passage events
Section titled “Passage events”Subscribe with typed engine events:
const unsubscribe = engine.on("passageChange", ({ oldPassage, newPassage }) => { console.log("from", oldPassage?.name, "to", newPassage?.name);});
// laterunsubscribe();Navigation also changes visible state history, so stateChange can fire around passage transitions too. This is expected and useful for reactive UIs.
IF design tip
Section titled “IF design tip”Treat passage ids as durable story keys (e.g. act1_hub, forest_edge) instead of display text. It makes migrations, analytics, and save compatibility much easier as the narrative evolves.