next-steps plan for cross-conversation dialogue state: WorldState as the serialized source of truth, Ink books as disposable views. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
50 lines
2.3 KiB
Markdown
50 lines
2.3 KiB
Markdown
# 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.
|