Adv 2.0 L4b: rival migrates RivalPool + gate/stake off AdvCharacter

Gate switches from CombatLevel >= 5 to D&D Level >= 3; stake formula
becomes (level / 3) * 1000 (Level 3 → €1000 mirrors legacy CL5 → €1000,
tops €6000 at L20). RivalPool / RivalUnlockedNotified dual-write to
player_meta; readers in selectRivalPair, handleRivalsCmd, and morning
DM render flip to loadRivalState. Backfill wired into Init, idempotent.

Migration doc note about porting rival combat to simulateCombat was
wrong — rival uses RPS, no combat_engine port needed. Doc corrected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 09:53:31 -07:00
parent 730f16580a
commit a4b4a74ab4
7 changed files with 285 additions and 18 deletions

View File

@@ -194,6 +194,11 @@ func runMigrations(d *sql.DB) error {
// HospitalVisits moves to player_meta; AdvCharacter.hospital_visits
// keeps dual-writing during soak (gogobee_legacy_migration.md §6.1).
`ALTER TABLE player_meta ADD COLUMN hospital_visits INTEGER NOT NULL DEFAULT 0`,
// Adv 2.0 Phase L4b — Rival migration off AdvCharacter.
// RivalPool / RivalUnlockedNotified move to player_meta; AdvCharacter
// columns keep dual-writing during soak (gogobee_legacy_migration.md §6.2).
`ALTER TABLE player_meta ADD COLUMN rival_pool INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE player_meta ADD COLUMN rival_unlocked_notified INTEGER NOT NULL DEFAULT 0`,
}
for _, stmt := range columnMigrations {
if _, err := d.Exec(stmt); err != nil {