mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
R1: split "where am I" from "how far have I walked"
Backtracking (revisit R2) breaks the assumption every zone-run caller quietly relied on: that CurrentRoom == len(VisitedNodes)-1. Position and progress have been the same number only because navigation was forward-only. Split them. CurrentRoom is now the first-entry index of CurrentNode in VisitedNodes -- the room number the player was shown on the way in, and the salt that enemy/trap/harvest/encounter keys hash. A revisited room therefore resolves to the same room. RoomsTraversed is a new monotonic step counter, persisted, backfilled from visited_nodes for in-flight rows. The audit found only two progress-shaped reads. narrationCadence moves to RoomsTraversed so a backtracking player draws fresh flavor rather than replaying the entry-room lines. The other was a latent bug: zoneCmdGo labelled the room it moved into as CurrentRoom+1, which is only correct at the frontier; advanceZoneRunNode now returns the true path index. VisitedNodes becomes an ordered set and RoomsCleared becomes idempotent -- both no-ops while navigation is forward-only, both load-bearing after R2. No player-visible behavior change. Nothing to route off RoomsTraversed for threat/SU: verified at HEAD that movement charges neither. Threat comes from combat, supplies burn per day. The revisit plan's cost model claimed otherwise and has been corrected -- R2's "discount" is really a net-new cost decision.
This commit is contained in:
@@ -330,16 +330,26 @@ func eliteRoomEntryLine(zoneID ZoneID, runID string, roomIdx int) string {
|
||||
return "🎭 **TwinBee:** " + line
|
||||
}
|
||||
|
||||
// narrationCadence returns the salt index used to seed narration
|
||||
// pickers — the count of nodes visited so far (0-based, matching the
|
||||
// pre-G6 CurrentRoom semantics). Both linear-mode and graph-mode
|
||||
// advance bump len(VisitedNodes) in lockstep with CurrentRoom, so this
|
||||
// preserves existing pick determinism while letting G9 drop the legacy
|
||||
// current_room column without re-keying every flavor pool seed.
|
||||
// narrationCadence returns the salt index used to seed narration pickers —
|
||||
// the number of rooms walked so far, 0-based. This is a *progress* read, not
|
||||
// a position read (revisit R1's audit split): flavor should keep moving
|
||||
// forward as the player does, so a backtrack draws fresh lines rather than
|
||||
// replaying the ones they already read on the way in.
|
||||
//
|
||||
// Forward-only runs have RoomsTraversed == len(VisitedNodes), so this stays
|
||||
// numerically identical to the pre-R1 derivation and every existing pick
|
||||
// keeps landing on the same line. It is stable while the player stands
|
||||
// still, which is what lets a re-read of `!status` print the same prose.
|
||||
//
|
||||
// The len(VisitedNodes) fallback covers rows that predate the R1 column and
|
||||
// have yet to be swept by bootstrapRoomsTraversed.
|
||||
func narrationCadence(run *DungeonRun) int {
|
||||
if run == nil {
|
||||
return 0
|
||||
}
|
||||
if run.RoomsTraversed > 0 {
|
||||
return run.RoomsTraversed - 1
|
||||
}
|
||||
if n := len(run.VisitedNodes); n > 0 {
|
||||
return n - 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user