feat: add 9 new games and update help/README
Lint / Shell (shellcheck) (push) Successful in 8s
Lint / JS (eslint) (push) Successful in 6s
Lint / Python (ruff) (push) Failing after 5s
Lint / Python deps (pip-audit) (push) Successful in 41s
Lint / Secret scan (gitleaks) (push) Successful in 5s

New commands: numguess/ng, wordchain/wc/endwc, acronym/ac,
20q/q/answer, nhie, hottake, ttt/move, blackjack/hit/stand,
triviaduel/da. All per-room with AI-generated content where
applicable. callbacks.py wired up for new reaction handlers
(acronym votes, nhie, hottake). Help and README updated with
full command reference.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 16:29:23 -04:00
parent e29263c3e2
commit 54c73535b8
3 changed files with 1260 additions and 2 deletions
+69
View File
@@ -522,6 +522,75 @@ Periodic `TLS/TCP socket error: Connection reset by peer` in coturn logs. Normal
---
## LotusBot
LotusBot (`@lotusbot:matrix.lotusguild.org`) is a Matrix bot running on LXC 151 at `/opt/matrixbot/`.
All commands use the `!` prefix. Run `!help` in any room for the full list.
### AI / Fun
| Command | Description |
|---------|-------------|
| `!ask <question>` | Ask the AI anything |
| `!fortune` | Get a fortune cookie |
| `!8ball <question>` | Magic 8-ball (yes/no/maybe, funny style). `--debug` shows raw AI output |
| `!roast @user` | Roast someone |
| `!story <prompt>` | Generate a short story |
| `!debate <topic>` | AI argues both sides of a topic |
### Games
| Command | Description |
|---------|-------------|
| `!wordle` | Daily Wordle-style word game |
| `!trivia [category]` | Trivia question (gaming/tech/movies/music/science/anime/etc.) |
| `!rps <rock\|paper\|scissors>` | Rock Paper Scissors |
| `!poll <question> \| option1 \| option2...` | Create a reaction poll |
| `!hangman [--hard] [--extended]` | Hangman — `--hard` uses long words, `--extended` adds more body parts |
| `!guess <letter or word>` | Guess a letter or the full word in hangman |
| `!scramble` | Unscramble the word before time runs out |
| `!wyr` | Would You Rather — two AI-generated options, vote with reactions |
| `!riddle` | AI generates a riddle — try to solve it! |
| `!numguess` | Number Guess — bot picks 1100 |
| `!ng <number>` | Guess in an active number game (temperature hints included) |
| `!wordchain` | Word Chain — each word must start with the last letter of the previous |
| `!wc <word>` | Add a word to the chain |
| `!endwc` | End the word chain and see the final score |
| `!acronym` | AI picks an acronym — submit the funniest expansion with `!ac` then vote |
| `!ac <expansion>` | Submit an acronym expansion |
| `!20q` | 20 Questions — AI thinks of something, you ask yes/no questions |
| `!q <question>` | Ask a yes/no question in 20Q |
| `!answer <guess>` | Guess the answer in 20Q |
| `!nhie` | Never Have I Ever — react 🙋 (have) or 🙅 (never) |
| `!hottake` | AI generates a hot take — react 🔥 (agree) or 💧 (disagree) |
| `!ttt @user` | Tic-Tac-Toe — challenge someone |
| `!move <1-9>` | Make a move in Tic-Tac-Toe |
| `!blackjack` | Play Blackjack against the dealer |
| `!hit` | Draw another card in Blackjack |
| `!stand` | Stand — dealer plays out |
| `!triviaduel @user` | Trivia Duel — first-to-3 battle |
| `!da <A/B/C/D or answer>` | Answer in a Trivia Duel |
### Random
| Command | Description |
|---------|-------------|
| `!flip` | Flip a coin |
| `!roll [NdN]` | Roll dice (e.g. `!roll 2d6`) |
| `!random <min> <max>` | Random number in range |
| `!champion` | Pick a random champion |
| `!agent [role]` | Pick a random Valorant agent |
### Server
| Command | Description |
|---------|-------------|
| `!minecraft` | Check Minecraft server status |
| `!ping` | Check bot latency |
| `!health` | Bot health + uptime stats |
---
## Tech Stack
| Component | Technology | Version |
+16 -1
View File
@@ -4,7 +4,16 @@ from functools import wraps
from nio import AsyncClient
from config import BOT_PREFIX, MATRIX_USER_ID
from commands import COMMANDS, metrics, check_scramble_answer, check_riddle_answer, record_wyr_vote
from commands import (
COMMANDS,
metrics,
check_scramble_answer,
check_riddle_answer,
record_wyr_vote,
record_acronym_vote,
record_nhie_reaction,
record_hottake_reaction,
)
from welcome import handle_welcome_reaction, handle_space_join, SPACE_ROOM_ID
logger = logging.getLogger("matrixbot")
@@ -82,6 +91,9 @@ class Callbacks:
await handle_welcome_reaction(self.client, room.room_id, event.sender, reacted_event_id, key)
record_wyr_vote(reacted_event_id, event.sender, key)
record_acronym_vote(reacted_event_id, event.sender, key)
record_nhie_reaction(reacted_event_id, event.sender, key)
record_hottake_reaction(reacted_event_id, event.sender, key)
async def unknown_event(self, room, event):
"""Fallback handler for UnknownEvent — catches any m.reaction not parsed by nio."""
@@ -103,6 +115,9 @@ class Callbacks:
await handle_welcome_reaction(self.client, room.room_id, event.sender, reacted_event_id, key)
record_wyr_vote(reacted_event_id, event.sender, key)
record_acronym_vote(reacted_event_id, event.sender, key)
record_nhie_reaction(reacted_event_id, event.sender, key)
record_hottake_reaction(reacted_event_id, event.sender, key)
async def member(self, room, event):
"""Handle m.room.member events — watch for Space joins."""
+1175 -1
View File
File diff suppressed because it is too large Load Diff