Adv 2.0 L5c: NPC counters/debuffs migration off AdvCharacter

Thirteen player_meta columns: misty/arina_last_seen,
misty_buff_expires, misty_debuff_expires, arina_buff_expires (all
nullable DATETIME), npc_msg_count + npc_msg_count_date,
misty/arina_roll_target, misty_encounter_count, misty_donated_count,
thom_animal_line_fired, robbie_visit_count.

NPCState struct with HasNPCActivity() marker + load/upsert/backfill/
projection helpers. Dual-writes wired at every NPC mutation site:
processNPCEncounters msg-count save, npcFireEncounter last-seen,
resolveMisty (insufficient balance, debit failure, buff/donated,
declined-debuff), resolveArina buff, adventure_robbie visit count,
adventure_housing Thom animal line.

Hidden discovery mechanic — buffs/debuffs and counters never surface
in player-facing output.

Tests: TestPlayerMetaNPCStateBackfill_Idempotent,
TestLoadNPCState_FallsBackToAdvCharacter,
TestUpsertPlayerMetaNPCState_RoundTrip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 11:24:55 -07:00
parent d5b4834d44
commit c83b73b655
8 changed files with 435 additions and 1 deletions

View File

@@ -169,6 +169,7 @@ func (p *AdventurePlugin) robbieVisitPlayer(userID id.UserID, displayName string
if err == nil {
char.RobbieVisitCount++
_ = saveAdvCharacter(char)
_ = upsertPlayerMetaNPCState(userID, npcStateFromAdvChar(char))
}
// Send DM