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:
@@ -62,7 +62,7 @@ func (p *AdventurePlugin) advanceTransitionGraph(run *DungeonRun, zone ZoneDefin
|
||||
if len(choices) == 1 && len(unlocked) == 1 {
|
||||
// Plain auto-advance — no fork to prompt for.
|
||||
chosen := choices[0]
|
||||
if aerr := advanceZoneRunNode(run.RunID, chosen.To); aerr != nil {
|
||||
if _, aerr := advanceZoneRunNode(run.RunID, chosen.To); aerr != nil {
|
||||
err = aerr
|
||||
return
|
||||
}
|
||||
@@ -184,7 +184,8 @@ func (p *AdventurePlugin) zoneCmdGo(ctx MessageContext, rest string) error {
|
||||
if cerr != nil {
|
||||
return p.SendDM(ctx.Sender, cerr.Error())
|
||||
}
|
||||
if aerr := advanceZoneRunNode(run.RunID, chosen.To); aerr != nil {
|
||||
nextIdx, aerr := advanceZoneRunNode(run.RunID, chosen.To)
|
||||
if aerr != nil {
|
||||
return p.SendDM(ctx.Sender, "Couldn't advance: "+aerr.Error())
|
||||
}
|
||||
markActedToday(ctx.Sender)
|
||||
@@ -194,7 +195,6 @@ func (p *AdventurePlugin) zoneCmdGo(ctx MessageContext, rest string) error {
|
||||
nextNode := g.Nodes[chosen.To]
|
||||
fireGraphRegionTransition(run.UserID, fromNode, nextNode)
|
||||
nextRoom := nodeKindToRoomType(nextNode.Kind)
|
||||
nextIdx := run.CurrentRoom + 1
|
||||
var b strings.Builder
|
||||
if kind := autoBreakCampOnMove(ctx.Sender); kind != "" {
|
||||
b.WriteString(fmt.Sprintf("⛺ Camp struck (**%s**) — the party moved on.\n\n", kind))
|
||||
|
||||
Reference in New Issue
Block a user