New DictionaryPlugin with !antonym, !pronounce, !etymology, !difficulty,
and !rhyme commands. Integrate antonyms into !define (concurrent 500ms
fetch), difficulty tier into Hangman headers, and etymology into WOTD.
Fix rhyme limit bug (request 50, display 7), variable shadowing, and
add spec-required emoji prefixes to all dictionary command outputs.
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>
- Overlevel penalty reduces loot and XP when effective level exceeds location minimum (gap >3: -15%/level, floor 5%)
- 3-hour per-location cooldown after successful runs, persisted via activity log
- Applies to all activity types (dungeons, mining, foraging, fishing)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rotate WOTD between Portuguese, French, and English daily with cognate filtering
- Replace LLM-based fancy word detection with DreamDict frequency data (batch API + cache)
- Track fancy word usage per user and add Wordsmith archetype
- Restore full arena combat flavor text and add player miss actions
- Consolidate death logic into Kill() method with 2-hour lockout
- Fix arena death XP grant missing level-up check
- Fix LLM wotd_used classification by injecting actual WOTD into prompt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WOTD: Require both English and French translations, validate before
display, fall back to English word if pt-PT search exhausts 100 attempts.
LLM passive: Inject actual WOTD into classification prompt instead of
letting LLM guess at "unusual words". Add DreamDict-based fancy word
detection using frequency data — react with 🎓 for rare vocabulary.
Arena: Reduce death lockout from next-midnight-UTC to 2 hours.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single first-match archetype with comprehensive multi-tag system
spanning 25 archetypes across 8 categories (Communication, Temporal,
Emotional, Economy, Games, Adventure, Social). Archetypes are computed
nightly via cron job querying 15+ tables and cached in user_archetypes.
Thresholds calibrated against real community data. Integrates with
!personality, !superstatsexplusalpha, !whois, and milk carton flavor text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
UNO addbot:
- !uno addbot / !uno removebot for lobby bot management (WinBee, GwinBee)
- Bots ante from community pot, increasing the total pot
- Single human can start a game if bots fill remaining slots
- Per-bot display names throughout (replaces global unoBotName)
Audit fixes:
- Lobby display now always shows both humans and bots (was omitting bots on join)
- Slot check accounts for bots (was only counting humans)
- Color Roulette bot victim name fixed (was showing acting bot's name)
- Lobby display built under lock to prevent stale reads
- Bot name list separated from env var to prevent duplicates
- Extracted shared buildLobbyDisplay helper
- Inlined unnecessary nameOf closure in sudden death
Other:
- T5 masterwork drop rate reduced from 1.5% to 0.5%
- Added fishing stats to !superstatsexplusalpha
- Updated README with all new features
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>
Standalone HTTP client for the DreamDict service supporting word
lookup, random word generation, and cross-language translation
(en/fr/pt-PT). Used by hangman, lookup, and WOTD plugins.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2-player UNO (especially No Mercy) regularly stalls past 100 turns.
Sudden death announces at turn 80 with a 20-turn countdown, then
scores hands by card point values — lowest total wins. Applies to
solo (vs bot) and multiplayer when 2 active players remain.
Also adds "It's X's turn" labels to bot plays in multiplayer,
matching the format human plays already had, and adds sudden death
checks to all turn advancement paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Wordnik/LibreTranslate references with DreamDict throughout.
Add multilingual hangman and !wotd force docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace LibreTranslate-based !translate with DreamDict cross-language
lookup (en/fr/pt-PT) with auto-detect and 5-per-lang cap
- Add multilingual hangman mode (!hangman <lang> [--clue <lang>]) using
DreamDict RandomWord/Translate with retry logic and race-safe placeholder
- Rewrite WOTD to pick pt-PT words with Portuguese definitions and
en/fr translations, add !wotd force for moderators
- Move DreamDict client init earlier in main.go for broader availability
- Wire dictClient into LookupPlugin, HangmanPlugin, and WOTDPlugin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Market plugin (#49): daily index snapshots (Yahoo Finance + Finnhub fallback),
Ollama-generated summaries, !howsthemarket, !marketstatus, !marketreport commands,
exchange hours with DST support, 30-min room cooldown
- Adventure arena: 5-tier combat gauntlet with 20 monsters, risk-reward cashout,
death lockout changed from 24h to midnight UTC across all code and flavor text
- Adventure holidays: double daily actions on holidays
- Adventure DM fix: 15-minute response window prevents bare numbers from triggering
adventure during UNO games
- Adventure scheduler: jitter between morning DMs to avoid Matrix rate limits
- Adventure revive: wire up adv_revived achievement on admin revive
- Column migration system for existing databases (holiday_action_taken)
- Fix italic markdown rendering after newlines
- Fix holdem DMs broken by space groups including DM rooms
- UNO No Mercy: remove stacking escalation rule (any draw card stacks on any other)
- UNO multiplayer: add turn announcements after stack absorption and turn passes,
jitter between rapid-fire messages with safe mutex handling
- Birthday: add €1,000 gift and 10 XP + €100 community celebration bonus
- Market: guard against division by zero, nil pointer, and timezone errors
- README updates: plugin count 48→49, all new commands, feature flags, architecture
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New plugins: encrypted Markov chain generation (9 commands), emojiboard
reaction stats (5 views), Miniflux RSS feed integration (8 commands),
and 48 new achievements across 9 categories. Adventure startup now
unconditionally resets daily actions and respawns expired deaths to
handle missed resets from SQLite contention. README updated with all
new features.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Forex: add CAD to tracked currencies, add cross-pair syntax (EUR/USD,
EUR|JPY, etc.) for both !fx rate and !fx report with full historical
analysis computed from stored USD-base rates.
Adventure: fix midnight reset silently failing due to SQLite busy
contention with the reminder fire loop — propagate errors so the job
isn't marked complete on failure, add retry with backoff, and add
startup catch-up for missed resets and expired death timers.
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>
Add !twinbeeboard command (GogoBee's trophy wall) with unified
bot_defeats table tracking losses across Blackjack, UNO solo, and
UNO multiplayer. Fix No Mercy audit bugs: wild card color choice
routing, bot Color Roulette double-advance, missing DM notifications
for roulette victims and 7-0 swap targets, autoplay Color Roulette
effect. Remove dead code. Update README with full UNO documentation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
168-card deck with new card types (Skip Everyone, Discard All,
Wild Reverse Draw Four, Wild Draw Six/Ten, Wild Color Roulette),
draw stacking, draw-until-playable, mercy elimination at 25 cards,
and optional 7-0 hand swap/rotation rule. Works in both solo and
multiplayer. Includes blackjack max player increase to 4.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- When a WD4 is played, the victim can challenge or accept
- Challenge succeeds if the WD4 player had a card matching the
previous color — they draw 4 instead
- Challenge fails: victim draws 6 (4 + 2 penalty)
- Bot as victim: challenges probabilistically based on opponent
hand size (10-70% chance, more cards = more likely to challenge)
- Bot as player: 20% chance to illegally play WD4 when it has
matching color cards, making challenges meaningful against it
- Auto-play defaults to accepting (safe option)
- Challenge phase integrates with existing turn timer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Blackjack:
- Fix handValue soft flag for multi-ace hands (A+A+5 returned soft=false,
causing dealer to incorrectly stand on soft 17)
- Fix loss display showing €-50 instead of -€50
- Round down Blackjack 1.5x payout per requirements (math.Floor)
- Restrict !bjboard to games room like all other game commands
- Fix leaderboard showing misleading W/L (pushes counted as losses)
- Notify user when bet is capped to max instead of silently capping
- Fix bet max message to use min(MaxBet, maxAvailable)
- Rework to simultaneous play: all players hit/stand independently
with one shared round timer, reminders at 30s and 10s remaining
- Add !blackjack deal to skip the 60s join wait
- Add mid-round forfeit via !blackjack leave during play
- Set minimum 5s delay for reminder timers to avoid spam on low timeouts
Multiplayer UNO:
- Fix lobby race conditions: move euro debit inside mutex lock to
prevent lobby overwrites and missed refunds
- Extract shared applyCardEffects to deduplicate card effect logic
from applyAndAnnounce, botMultiTurn, and applyAutoEffects
- Add 10-minute game inactivity timeout with refunds (was in
requirements but not implemented)
- Add card count to all "draws a card, turn passes" room messages
so spectators can track hand sizes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Matrix edits arrive as m.room.message with m.replace relation. Without
filtering these out, each edit was re-triggering URL previews and
incrementing user stats as if it were a new message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Multiplayer UNO: lobby system (2-4 humans + bot), DM-based turns,
30s auto-play timer, winner-takes-all pot, forfeit handling
- Solo UNO: refactor bot AI to shared standalone functions, support
starting games from DM, passive UNO call system
- Room sentiment: new room_sentiment_stats table and !roomsentiment
command showing per-room sentiment breakdown with percentages
- Stop purging llm_classifications (retain indefinitely for analytics)
- Fix multiplayer UNO audit issues: dead code in initMultiGame,
double game.turns++ on human plays, missing !uno status command
- Update README with UNO commands, config, and architecture
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add full UNO game plugin (1v1 vs bot via DM, community pot, bot personality)
- Move hangman into threads with direct reply guessing (no !hangman prefix needed)
- Fix DM room duplication by checking m.direct account data with in-memory cache
- Auto-draw when player has no playable cards instead of requiring manual draw
- Remove forced UNO call phase — players are penalized naturally if they forget
- Fix mutex held during network I/O in hangman start
- Fix infinite loop when both sides have no playable cards and deck is empty
- Fix Wild Draw Four penalty being skipped when UNO prompt triggered
- Fix hangman displayPhrase word boundary clarity (triple-wide gaps for spaces)
- Add UNO env vars, db tables, and README updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All new plugins used Base{Client: client} instead of NewBase(client),
leaving Prefix empty so no !commands matched. Also fixes hangman UTF-8
safety (use runes not byte indices), euro race conditions, blackjack
deck/timer bugs, and adds difficulty selection to hangman start.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Euro economy: virtual currency earned passively per message (tiered by
word count, 30s cooldown). Starting balance seeded from corpus character
count. Balance, leaderboard, and transfer commands. Debt system with
configurable limit.
Hangman: collaborative game with phrase pool loaded from file. ASCII
gallows display, tiered scoring (Easy/Medium/Hard/Extreme), early
solution bonus, participant tracking with DM verification. Community
phrase submission with LLM screening.
Blackjack: 1-2 players vs dealer. Standard casino rules (hit soft 17).
Auto-play on timeout. Bet validation against balance and debt limit.
Blackjack pays 1.5x. Separate leaderboard.
Games channel restriction: all game commands (trivia, hangman, blackjack,
flip) restricted to GAMES_ROOM. Dice (!roll) exempt. Trivia also
restricted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deterministic-only detection (no LLM): word list with precompiled
leetspeak variation matching, text/image flood, wall of text, repeated
messages (Levenshtein similarity), mention flooding, link rate limiting
for new members, invite flooding, join/leave cycling detection.
Three-strike response ladder: warn + redact → temp mute → permanent ban.
Strikes expire after configurable period. Admin room notifications with
context cards. DMs over public callouts.
Admin commands: !mod warn/mute/unmute/ban/strikes/forgive/history/reload/
status/test. All require ADMIN_USERS membership.
Feature-flagged: disabled by default, set FEATURE_MODERATION=true to
enable. All thresholds configurable via env vars. New member grace
period with stricter thresholds. Word list hot-reload via !mod reload.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Space groups: automatic room grouping via membership overlap percentage.
Rooms with sufficient shared members are grouped together so leaderboards,
trivia scores, and stats aggregate across the community. Uses strict
clique-based algorithm (every room must meet threshold with every other
room in group). Configurable via SPACE_GROUP_THRESHOLD env var. Persisted
to SQLite, recomputed hourly and on startup.
HLTB scraper: rewrote for new howlongtobeat.com API (two-step token auth
via /api/finder/init + /api/finder endpoint).
Quote wall: fix E2EE decrypt flow for reply-to-save (ParseRaw before
Decrypt, skip ParseRaw after Decrypt returns pre-parsed event). Fix
subcommand matching for delete/search. Remove broken star-reaction handler
and old quote handler from user.go.
Other fixes:
- Strip Matrix reply fallback before command detection (main.go)
- Increase Ollama context window to 8192
- Improve tarot spread prompts (~4x longer, narrative arc)
- Add "cards are props" instruction to tarot LLM prompt
- Fix movies.go CommandDef name mismatch
- Add Community category to !help
- Remove daily horoscope broadcast cron
- Update README with all changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New features:
- !tarot and !tarotspread commands with LLM-powered readings (zodiac-aware)
- !quote system with AES-256-GCM encryption at rest, reply-to-save, search, and quoteboard
- Shared crypto utility (internal/crypto) for AES-256-GCM encrypt/decrypt/HMAC
- ResolveUser now matches display names via room membership as fallback
- !vibe and !tldr show bot uptime when insufficient messages buffered
Bug fixes:
- Fix duplicate quotes table schema that would crash quotewall at runtime
- Fix biased random selection in quote retrieval (use rand.Intn)
- Fix XP rank calculation to handle tied scores with COUNT(DISTINCT xp)
- Scope all leaderboards to room members (repboard, pottyboard, insultboard, firstboard, rankings, emojiboard)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All scheduled post dedup keys (wotd, holidays, gaming, anime, movies,
concerts, birthdays) were global — after posting to the first room,
the job was marked complete and the second room was skipped. Fixed by
including the room ID in each dedup key so posts go to all broadcast
rooms. Birthday XP grants and DMs remain once-per-user-per-year.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generates milk carton style "missing person" PNG images using gg library
with embedded Go fonts. Tracks inactive members via daily_activity, with
configurable thresholds (MISSING_THRESHOLD_DAYS, MISSING_MAX_DAYS,
MISSING_MIN_MESSAGES, MISSING_EXCLUDE_USERS). Rate limited to 1 carton
per room per day. Derives flavor text characteristics from user stats
and sentiment data. Avatar fetching with 3-tier fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add anime daily releases at 10:00 UTC
- Add movie daily releases at 11:00 UTC
- Add concert weekly digest at 12:00 UTC Sunday
- Prefetch holidays alongside WOTD at 00:05 UTC
- Reorder jobs chronologically
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Expand LLM sentiment classification from 3 to 10 categories: positive,
negative, neutral, excited, sarcastic, frustrated, curious, grateful,
humorous, supportive — with emoji reactions for each
- Add daily DB maintenance job at 03:00 UTC to purge stale caches,
expired rate limits, old logs, and run SQLite optimize
- Add migrate.sql for upgrading existing databases
- Update README: add !sentiment command, maintenance job, rate limit
config, in-memory message buffer docs, SDK migration history,
remove references to previous private repo
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete rewrite of the Freebee Matrix bot as GogoBee using mautrix-go.
- E2EE with goolm (pure Go, no CGo/libolm) and cross-signing bootstrap
- 35+ plugins with dependency injection and ordered registration
- SQLite storage via modernc.org/sqlite (no CGo)
- Scheduler via robfig/cron for WOTD, holidays, birthdays, releases, etc.
- Optional LLM integration (Ollama) for sentiment, profanity, roasts, vibes
- Threaded trivia, three-tier profanity tracking, WOTD usage verification
- Multi-country holiday support with deduplication
- Quadratic XP curve, configurable bot display name, encrypted DMs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Level-up announcements with Twinbee/Parodius-themed messages and emoji flair
- New plugins: !howami (LLM stat roast), !vibe (room energy), !tldr (conversation summary)
- !game command as primary game lookup with !retro as alias
- Prefetch system: API data cached at 00:05 UTC for reliable scheduled posts
- Nightly maintenance job: prunes old data across 15+ tables
- Sentiment aggregation: new sentiment_stats table with backfill migration
- Access token moved from .env to device.json for security
- Retry logic (sendReact/sendWithRetry) for transient connection failures
- Trivia crash fix: optional chaining on threadEventId across all locations
- Bug fixes: COALESCE for NULL SUM in howami, unused params in vibe, dead try-catch in fun
- License updated from ISC to MIT
- README: weather section expanded, prefetch/maintenance documented
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-featured Matrix bot with E2EE via matrix-js-sdk, 32+ plugins,
LLM-powered passive classification, XP/leveling, trivia, game releases,
anime/movie tracking, and more.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>