Branching zones G6: dependent surfaces re-keyed on graph nodes

- Harvest tables (expedition + standalone) now keyed by node_id; legacy
  room-idx entries auto-migrate via read-fallback + drop-on-save.
- Narration salts swapped from run.CurrentRoom to narrationCadence(run)
  (= len(visited_nodes)-1) so flavor pickers survive G9 column drop.
- !zone map renders the graph (BFS by PosX/PosY) when the gate is on:
  ✓/▶/· status, ╳ for locked-only edges, secrets hidden until visited.
- Region-boundary hook in graph advance/!zone go updates expedition
  CurrentRegion + visited list when from/to nodes differ — without
  burning supplies or retiring runs (the graph IS the run state).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 15:17:30 -07:00
parent 2d249d7d0a
commit 893d3dacad
14 changed files with 562 additions and 64 deletions

View File

@@ -48,8 +48,9 @@ func TestStandaloneHarvest_RoutesToZoneRun(t *testing.T) {
if raw == "" || raw == "{}" {
t.Errorf("expected harvest_nodes_json populated after standalone harvest, got %q", raw)
}
if !strings.Contains(raw, "\"0\":") {
t.Errorf("expected room 0 entry in harvest table, got %q", raw)
wantKey := "\"" + deriveLegacyNodeID(run.ZoneID, 0) + "\":"
if !strings.Contains(raw, wantKey) {
t.Errorf("expected entry node %s in harvest table, got %q", wantKey, raw)
}
}