add dialogue consequences design notes
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>
This commit is contained in:
parent
5413823b26
commit
e73f63b5d4
1 changed files with 50 additions and 0 deletions
50
docs/dialogue-consequences.md
Normal file
50
docs/dialogue-consequences.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue