# Dialogue consequences — next steps Design for dialogue trees with consequences across conversations ("talk again does something else", NPC A affects NPC B, dialogue opens doors). Builds on the existing narrator (Ink) setup — see `dialogue_manager.lua`, `dialogable.lua`. ## Core principle **Books are disposable views; a global `WorldState` table is the single source of truth.** Each Ink book reads flags in and writes flags out; it holds no authority, so it can be re-`init`ed and thrown away without losing anything. This resolves book-per-character's weakness (book A's visit counts are invisible to book B) — B branches on a `WorldState` flag, not on A's runtime state. Mirrors the existing world-vs-room split (`world.lua`: "the world is only a layout; rooms own their puzzle state"). Narrative progress is a third, global category with its own save file. Keep book-per-character (`Dialogable.book`), add a stable `self.storyId`. ## The bug to fix first `Dialogue.open` re-`init`s the story every bump (`dialogue_manager.lua:31-33`), discarding all state — so there's no "again" to hang consequences on. ## Steps 1. Add a global `WorldState = {}` (flags + counters). 2. `saveProgress` / `loadProgress` → `save/progress.sav` via TSerial + `readFromSource` / `writeToSource` (helpers already exist, used in `world.lua` / `world_seed.lua`). Shape: `{ version = 1, flags = WorldState }`. Flat table, no per-book blobs initially. 3. `Dialogue.bridge(story)` on open: - `story:bind("flag", fn)` — read a WorldState flag from Ink. - `story:bind("setflag", fn)` — write one back. - gameplay binds, e.g. `give_color` / `open_door` calling into `currentRoom`. 4. Cache the live story per `storyId` in the Dialogue module (stop re-init'ing). 5. Hook `saveProgress` into the existing autosave points (near `room.lua:814`). "Talk again does X" = increment an own `WorldState` counter (e.g. `sage_talk_count`) on open, branch on it in Ink. No reliance on Ink visit-count persistence. ## Deferred Persisting `story:save_state()` (plain table, keyed by `storyId`) only buys in-book niceties — consumed sticky choices, resume mid-conversation across a hard quit. Skipped initially: it couples the save file to book structure and forces narrator's `migrate` hook on every `.ink` edit. `WorldState` flags don't — a renamed flag just reads `nil`/false.