worldboss: spawn the monthly Siege without the day-1 deadlock

The Siege has never once spawned in prod. `select count(*) from
world_boss` is 0 and daily_prefetch has no worldboss_spawn row at all.

worldBossTick only auto-spawned when now.Day() == 1. The world boss
landed on main 2026-07-10..13 and the first deploy carrying it was after
July 1, so prod has never run a first-of-the-month tick with the code in
it. The feature has been live and unreachable for weeks, and the next
natural spawn would have been August 1.

The same gate also silently skipped any month where the bot happened to
be down or redeploying across the 1st, with no catch-up — one missed
minute costs the town a month.

The month key is already the whole dedup, so drop the day check and let
the rule be what it always read as: one Siege per calendar month, as
early as the process is up to run it. A missed 1st now self-heals on the
next tick.
This commit is contained in:
prosolis
2026-07-20 23:52:03 -07:00
parent ca2d1a8ea3
commit 690ff758fe
+15 -8
View File
@@ -398,10 +398,10 @@ func (p *AdventurePlugin) spawnWorldBoss(eventKey string) (*worldBossState, erro
return boss, nil return boss, nil
} }
// worldBossTick rides the 1-minute event ticker. It auto-spawns a boss on the // worldBossTick rides the 1-minute event ticker. It auto-spawns the month's
// first of each UTC month and resolves a live boss whose window has lapsed. The // boss and resolves a live boss whose window has lapsed. The defeat path is not
// defeat path is not here — a bout crossing the pool to zero resolves inline // here — a bout crossing the pool to zero resolves inline (W2), because the
// (W2), because the ticker never sees the pool between two 60s reads. // ticker never sees the pool between two 60s reads.
func (p *AdventurePlugin) worldBossTick() { func (p *AdventurePlugin) worldBossTick() {
boss, err := loadActiveWorldBoss() boss, err := loadActiveWorldBoss()
if err != nil { if err != nil {
@@ -423,10 +423,17 @@ func (p *AdventurePlugin) worldBossTick() {
} }
return return
} }
// No boss camped — auto-spawn on the 1st of the month, once. // No boss camped — spawn this month's Siege, once.
if now.Day() != 1 { //
return // The month key below is the whole dedup, so the rule is simply "one Siege
} // per calendar month, as early as the process is up to run it." It used to
// additionally require now.Day() == 1, which deadlocked the entire feature:
// the world boss shipped mid-July 2026 and prod never once ran a first-of-
// the-month tick with the code in it, so `select count(*) from world_boss`
// was still 0 weeks later. The day gate also silently skipped any month
// where the bot happened to be down or redeploying across the 1st, with no
// catch-up. Dropping it makes a missed 1st self-heal on the next tick
// instead of costing the town a month.
monthKey := now.Format("2006-01") monthKey := now.Format("2006-01")
if db.JobCompleted("worldboss_spawn", monthKey) { if db.JobCompleted("worldboss_spawn", monthKey) {
return return