From 87d08f0151e643951769e323995f1c5ed89ee200 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Fri, 18 Sep 2026 01:50:17 -0400 Subject: fix: harden economy recovery, shutdown concurrency, world validation, and inventory-loss paths --- internal/game/account_txn.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'internal/game/account_txn.go') diff --git a/internal/game/account_txn.go b/internal/game/account_txn.go index 2a420ca..cf31dea 100644 --- a/internal/game/account_txn.go +++ b/internal/game/account_txn.go @@ -39,15 +39,22 @@ func (g *Game) newTxn() *persistence.Transaction { // first connection and are re-saved so subsequent authorizations can use // them. Called from the owner goroutine only. func (g *Game) adoptCharacterIdentity(p *player.Player, accountName string) { + assignedID := "" if p.ID == "" { p.ID = newCharacterID() + assignedID = p.ID } if p.Account == "" { p.Account = accountName } if err := g.AccountStore.SaveCharacter(p); err != nil { - // Identity backfill is best-effort: the character remains usable, - // but membership validation falls back to the account list. + // Identity backfill is best-effort, but a NON-DURABLE ID must never + // become an economy key: a later startup's backfill would assign a + // different ID and strand every journal record written under this + // one. Fall back to the durable character name instead. + if assignedID != "" { + p.ID = "" + } log.Printf("identity backfill for %s: %v", p.Name, err) } } -- cgit v1.2.3