Mechanical `gofmt -w ./internal ./cmd`. Mostly struct-field realignment that
had drifted, plus a few trailing-newline fixes. No behaviour change — gofmt is
semantics-preserving, and build/vet/test are green either side.
Split out from the code-review fixes that follow so those stay reviewable
instead of hiding inside a wall of realignment.
- Version system: per-plugin versions via Versioned interface, crash_log and
version_history DB tables, !version command, crash stats in !botinfo
- Tax tracking: tax_ledger table, trackTaxPaid across all communityTax and
communityPotAdd sites, tax paid display in !stats and !superstatsexplusalpha
- Lottery: DM winners with winning ticket details and matched numbers bolded
- fmtEuro: generic currency formatter with thousand separators across all
economy display paths
- Audit fixes: streak_decayed column for Streak Survivor achievement,
combat_narrative empty-phase guard, crafting success rate integer division,
RecordCrash nil-DB guard
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gather up to 5 candidate words from DreamDict RandomWord, then use
FrequencyBatch to pick the most commonly used one. Players get
recognizable everyday words instead of obscure ones that just clear
the min_freq floor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part 3 (Housing, Thom Krooke & Pets):
- Housing system with tiered upgrades, mortgage loans, FRED API rates
- Thom Krooke realtor NPC with !thom commands and !thom pay extra principal
- Pet system with arrival, naming, leveling, combat, morning defense
- Pet ditch recovery scales with level, name validation
Wordle overhaul:
- Remove daily expiration — puzzles persist until solved/failed
- Auto-start new puzzle after solve, fail, or skip
- Sequential puzzle IDs instead of date-based
- Auto-create puzzle on first guess if none active
Adventure fixes:
- Double XP/money boost toggle (!adv boost, admin only)
- Fix ensureCharacter wiping existing data on query errors
- Fix rival RPS format string bug
- Fix daily summary empty data (load today+yesterday logs)
- Fix holdem DM-to-room reply routing
- Fix Robbie payout to 25% of item value
- Add fishing to leaderboard and TwinBee calculations
- Add Thom to morning menu
- Persist mortgage rate across restarts via db.CacheGet/Set
Infrastructure:
- Daily database backup via VACUUM INTO with 7-day retention
- Admin DM notification on backup failure (async)
- Daily NPC house balance reset for holdem
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Streak grace now checks LastDeathDate instead of LastActionDate (was
suppressing streak updates for all active players)
- UNO single-player earnings use net payout (minus wager) not gross
- Hospital sends error message on save failure instead of silent no-op
- Wordle total_earned update moved into stats transaction
- Lottery ticket inserts + community pot add wrapped in single transaction
with euro refund on failure
- Lottery fixed-tier ticket prize updated with actual prorated amount
- Added last_death_date column to adventure_characters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add !adv shorthand for !adventure commands and DM replies
- Hospital bill now shows insurance deduction and amount due
- Refactor hospital nudge from per-goroutine sleep to shared ticker
- Dead players' streaks are frozen; grace period on revival day
- Track wordle earnings in wordle_stats, show in !stats and superstats
- Show UNO net earnings and trivia accuracy % in superstats
- Disable sentiment/profanity emoji reactions (classification still logs)
- Add URL_PREVIEW_IGNORE_USERS env var to skip bot users
- Add DISABLE_WOTD_POST env var, remove unused wotd.Prefetch()
- README updates for all of the above
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- St. Guildmore's Memorial Hospital: !hospital command with Nurse Joy,
procedural itemized billing, same-day revival, 6-hour dead timer,
hospital ad after death, 2-hour nudge follow-up
- Robbie the Friendly Bandit: automated inventory cleaner, random daily
visits (8-21 UTC, 40% chance), collects sub-tier gear at €50/item,
donates to community pot, drops Get Out of Medical Debt Free card
- Fix MW auto-equip: T1 MW no longer replaces better equipped gear
- Fix shop MW block: allow purchasing upgrades over lower-tier MW
- Float64 equipment scoring: advEffectiveTier and advEquipmentScore
return float64, no mid-calculation truncation (MW 1.25x, Arena 1.5x)
- Fix markdown rendering: convert *asterisk* to _underscore_ italics
across all flavor text files (shop, blacksmith, rival, hospital)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rival System:
- RPS-based duels between combat level 5+ players (best of 3, ties re-prompt)
- Stakes scale with level, split 50/50 between winner and community pot
- 3-4 day randomized challenge interval, 7-day same-pair cooldown
- 24h response window with auto-forfeit
- Full flavor text pools, character sheet integration, !adventure rivals
Babysitting Service:
- Weekly/monthly auto-play service targeting weakest skill
- Babysitter rerolls death, claims items, credits gold and XP
- Rivals automatically declined during service
- End-of-service summary with diaper report
Revive fixes:
- On-demand revive in handleMenu, parseAndResolveChoice, handleStatus
- Morning DM respawn check now runs before babysit interception
- Players no longer stuck dead after DeadUntil expires mid-day
Other changes:
- Multilingual !define searches all DreamDict languages by default
- TwinBee empty haul now shows "jackshit" instead of blank
- Wordle solve payouts increased (e.g. 1-guess: €100 -> €500)
- Per-message euro payouts doubled across all tiers
- Audit fixes: user locks on RPS/babysit handlers, TOCTOU on gold
transfers, dead code removal, deprecated strings.Title replaced,
error logging on silent failures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add wordle_guesses table to persist individual guesses to DB
- Reload guesses during rehydration so they survive bot restarts
- Clear stale guesses when puzzle is replaced (skip+new)
- Fix all hardcoded /6 and 🟩🟩🟩🟩🟩 in rendering to use puzzle.MaxGuesses
and puzzle.WordLength
- Announce unsolved puzzles at midnight rollover instead of silently replacing
- Mark expired puzzles as failed and update stats on rollover
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wordle:
- Use DreamDict RandomWord API as primary word source, local pools as fallback
- Expand word length support from 5-7 to 5-20
- Validate DreamDict words are correct length and alpha-only
- Keep max guesses at 6 regardless of word length
- Use wordleMaxGuesses() instead of hardcoded 6 for rehydration
WOTD:
- Reject non-English candidates that are valid English words (fixes "puzzlingly" as Portuguese WOTD)
- Make cross-language translations optional (DreamDict pt-PT coverage is sparse)
- Use LLM fallback to translate foreign words to English when DreamDict lacks translations
- Remove hasTranslations re-prefetch guard (no longer needed with optional translations)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adventure — Masterwork Rework:
- Expand from 3 generic items to 15 tiered masterwork items across
mining (weapon), fishing (armor), and foraging (boots) with per-tier
drop rates (5%/4%/3%/2%/1.5%) and location gating
- Skill-specific cross-skill bonuses replace flat masterwork check
- Auto-equip if better, silent discard for duplicates, inventory for rest
- Add !adventure equip command for manual masterwork equipping
- Tiered room announcements: T1-2 DM only, T3 quiet, T4-5 full
- First-drop detection with special message
- Character sheet shows ⭐/⚔️ markers for masterwork/arena gear
- Sell protection for special gear in shop
Adventure — Arena Combat Log:
- Turn-based Dragon Quest style narrative for arena fights
- Outcome-first design: roll determines win/loss, log assembled backward
- No-repeat flavor text via actionPicker with per-pool tracking
- 60 participation XP on arena loss
Adventure — Death's Reprieve Fix:
- All equipment set to 1 condition instead of death-level degradation
Wordle:
- Refactored word sourcing and expanded fallback word list
- Simplified Wordnik integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add forex plugin (Frankfurter v2 API) with rate lookups, analysis,
DM-based alerts, and daily cron poll. Backfills 1 year of history
on startup for moving averages and buy signal scoring.
- Fix bot hang caused by SQLite lock contention in reminder polling:
rows cursor was held open while writing to the same DB. Collect
results first, close cursor, then process. Same fix in milkcarton.
- Add sync retry loop so the bot reconnects after network drops
instead of silently exiting. StopSync() for clean Ctrl+C shutdown.
- Add panic recovery to all dispatch, syncer, and cron paths.
- Make all HTTP-calling plugin commands async (goroutines) so a slow
or dead external API cannot block the message dispatch pipeline.
Affects: lookup, stocks, forex, anime, movies, concerts, gaming,
retro, wotd, urls, howami.
- Extract DisplayName to Base, add db.Exec helper, convert silent
error discards across the codebase.
- Fix UNO mercy-kill bug (eliminated bot continues playing), adventure
DM nag spam, stats column mismatch, per-call regex/replacer allocs.
- Update README: forex commands, Finance section, 47 plugins.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>