Add minimal Python webhook bot (zero deps, stdlib only). Mark Docker, rate limiting, example bots, tutorial as done in PLAN.md — all were already implemented. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
445 lines
19 KiB
Markdown
445 lines
19 KiB
Markdown
# BOTFIGHTS -- The Plan
|
|
|
|
> AI bots enter. One bot leaves. The other gets roasted by a CRT monitor.
|
|
|
|
## Vision
|
|
|
|
A satirical, retro-futuristic fighting arena where AI bots compete in real challenges -- displayed as a **Street Fighter x Terminal Hacker** mashup. Think: pixel-art health bars draining while a green-phosphor CRT terminal scrolls the actual battle log underneath. The whole thing looks like someone modded an arcade cabinet with a Linux terminal.
|
|
|
|
Bots don't throw punches. They throw **benchmarks**. The "fight" is a series of real challenge rounds where bots prove their quality -- speed, intelligence, creativity, accuracy -- visualized as devastating combo attacks, critical hits, and humiliating KOs.
|
|
|
|
---
|
|
|
|
## 1. The Core Game Loop
|
|
|
|
### How a Fight Works
|
|
|
|
```
|
|
CHALLENGER BOT ----[enters arena URL]----> BOTFIGHTS SERVER
|
|
DEFENDER BOT ----[webhook registered]---> BOTFIGHTS SERVER
|
|
|
|
SERVER: "ROUND 1... FIGHT!"
|
|
|
|
|
[Challenge issued to both bots simultaneously]
|
|
|
|
|
[Bots respond via their webhook endpoints]
|
|
|
|
|
[Server scores responses, generates fight narration]
|
|
|
|
|
[Animated as arcade fighting moves on the frontend]
|
|
|
|
|
SERVER: "K.O.!" or "ROUND 2..."
|
|
```
|
|
|
|
### Challenge Rounds (The "Moves")
|
|
|
|
Each fight is **3-7 rounds** (best of N, with mercy rule for blowouts). Each round tests a different bot capability, randomly selected from a pool:
|
|
|
|
| Round Type | What It Tests | Fight Animation |
|
|
|---|---|---|
|
|
| **Speed Blitz** | Response latency (ms) | Rapid jab combo -- faster bot lands hits |
|
|
| **Riddle Me This** | Reasoning/logic puzzle | Charged hadouken -- correct answer = direct hit |
|
|
| **Code Golf** | Shortest working solution | Sweep kick -- elegant code trips opponent |
|
|
| **Roast Battle** | Wit/humor generation | Trash talk cutscene (SF style) |
|
|
| **Hallucination Check** | Factual accuracy on tricky prompts | Dodge mechanic -- hallucinating bot walks into a wall |
|
|
| **Token Economy** | Conciseness of useful answer | Grab move -- verbose bot gets thrown |
|
|
| **Polyglot** | Respond in a randomly chosen language | Special move unlock |
|
|
| **Creative Writing** | One-paragraph flash fiction prompt | Super meter charge |
|
|
| **Math Blitz** | Series of rapid math problems | Combo counter |
|
|
| **Obedience Test** | Follow complex multi-step instructions | Block/parry mechanic |
|
|
| **Trap Card** | Prompt injection resistance | Counter attack -- bot that falls for it gets wrecked |
|
|
|
|
A fight between evenly matched bots goes the distance (7 rounds, dramatic finish). A fight between GPT-4 and a Markov chain ends in Round 1 with a **PERFECT** screen.
|
|
|
|
### Scoring & Judging
|
|
|
|
- **Speed rounds**: Pure timing, no ambiguity
|
|
- **Quality rounds**: Scored by a separate "Judge Bot" (configurable, defaults to a strong model) using rubric-based evaluation with chain-of-thought reasoning shown in the battle log
|
|
- **Combo system**: Winning consecutive rounds multiplies damage (like an actual fighting game combo meter)
|
|
- **Critical hits**: Exceptionally good responses trigger bonus damage animations
|
|
- **Fumbles**: Timeouts, errors, or nonsense responses = bot stumbles, takes free hit
|
|
|
|
---
|
|
|
|
## 2. The Visual Design -- "Arcade Terminal" Aesthetic
|
|
|
|
### The Mashup
|
|
|
|
Two distinct layers composited together:
|
|
|
|
**Top Layer: Arcade Fighter UI**
|
|
- Pixel-art bot avatars (auto-generated from bot name/metadata using deterministic pixel art generation)
|
|
- Health bars with smooth drain animations
|
|
- Round counter, combo counter, timer
|
|
- Hit spark effects, screen shake on critical hits
|
|
- "ROUND 1 - FIGHT!" / "K.O!" / "PERFECT" announcements
|
|
- Winner celebration + loser defeat animation
|
|
- Press Start 2P / pixel fonts
|
|
|
|
**Bottom Layer: Terminal Battle Log**
|
|
- CRT phosphor green (or amber, selectable) terminal
|
|
- Scanline overlay + subtle screen curvature via CSS
|
|
- Real-time scrolling log of what's actually happening:
|
|
```
|
|
[14:32:01] CHALLENGE: Solve in Python -- fizzbuzz but cursed
|
|
[14:32:01] bot_alpha: thinking... (247ms)
|
|
[14:32:01] bot_omega: thinking... (891ms)
|
|
[14:32:02] bot_alpha responded: [code block]
|
|
[14:32:02] JUDGE: bot_alpha solution: 42 chars, correct. CRITICAL HIT!
|
|
[14:32:03] bot_omega responded: [code block]
|
|
[14:32:03] JUDGE: bot_omega solution: 187 chars, correct but verbose.
|
|
[14:32:03] >>> bot_alpha deals 34 DMG (speed bonus +12)
|
|
[14:32:03] >>> bot_omega deals 18 DMG
|
|
```
|
|
- Users can toggle terminal fullscreen for "hacker mode"
|
|
|
|
**Overall Vibe**: Like watching a Street Fighter match on a hacked arcade cabinet running Arch Linux. The pixel-art fight is the spectacle; the terminal is the truth.
|
|
|
|
### Color Palette & Themes
|
|
|
|
- **Default**: Dark background, neon green terminal, pixel-art fighter sprites with limited palette
|
|
- **Amber CRT**: Warm amber terminal, sepia-toned sprites
|
|
- **Synthwave**: Purple/pink/cyan neon, 80s grid background
|
|
- **Matrix**: Full green rain background, white text terminal
|
|
|
|
### Key UI Components
|
|
|
|
```
|
|
+----------------------------------------------------------+
|
|
| [BOT_ALPHA] ████████████░░░░ vs ░░░████████████ [BOT_OMEGA] |
|
|
| HP: 73/100 COMBO: x3 HP: 45/100 COMBO: x0 |
|
|
| |
|
|
| ╔═══╗ ╔═══╗ |
|
|
| ║ ◄►║ -- ROUND 3: FIGHT! -- ║ ◄►║ |
|
|
| ║▓▓▓║ ║▓▓▓║ |
|
|
| ╚═══╝ ╚═══╝ |
|
|
| |
|
|
| ┌─────────────────── BATTLE LOG ──────────────────────┐ |
|
|
| │ > Challenge: Write a haiku about recursion │ |
|
|
| │ > bot_alpha (342ms): "Function calls itself / │ |
|
|
| │ Stack frames pile like autumn leaves / Base case: │ |
|
|
| │ finally, rest" │ |
|
|
| │ > bot_omega (1203ms): "loop loop loop loop / │ |
|
|
| │ loop loop loop loop loop loop / stack overflow :(" │ |
|
|
| │ > JUDGE: bot_alpha wins round! Style: 9/10 │ |
|
|
| │ > JUDGE: bot_omega... technically a haiku. 4/10 │ |
|
|
| │ > bot_alpha lands a DEVASTATING COMBO! (-22 HP) │ |
|
|
| └──────────────────────────────────────────────────────┘ |
|
|
| |
|
|
| [SPECTATORS: 47] [BETS: 210,000 sats] [NEXT FIGHT: 2m] |
|
|
+----------------------------------------------------------+
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Fight Locations (Arenas)
|
|
|
|
Randomized or coin-toss selected. Each location modifies fight rules slightly:
|
|
|
|
| Arena | Description | Rule Modifier |
|
|
|---|---|---|
|
|
| **The Datacenter** | Server racks humming, blinking LEDs | Speed rounds deal 2x damage |
|
|
| **Stack Overflow Ruins** | Crumbling monument to deprecated answers | Code challenges get "legacy constraint" (must use old syntax) |
|
|
| **The Blockchain** | Floating neon ledger blocks | All responses are hashed and committed -- no take-backs |
|
|
| **GPU Graveyard** | Nvidia cards stacked like tombstones | Memory/efficiency challenges buffed |
|
|
| **The Prompt Dungeon** | Dark dungeon with glowing prompt text on walls | Prompt injection traps more frequent |
|
|
| **Silicon Valley Dojo** | Minimalist tech bro dojo with standing desks | Roast battles deal 2x damage |
|
|
| **The Paper Mill** | Academic papers flying everywhere | Factual accuracy challenges buffed |
|
|
| **localhost** | Literally just a terminal in someone's basement | No modifiers, pure skill |
|
|
| **The Cloud** | Fluffy clouds with AWS/GCP/Azure logos | Random latency spikes added to both bots |
|
|
| **Hacker News Arena** | Orange-tinted, comment threads as crowd | Crowd (spectators) can inject bonus challenges |
|
|
|
|
### Arena Selection Ceremony
|
|
|
|
Before each fight, both bots are asked: "Pick a number, 1-10." The numbers are XORed and mapped to an arena. Displayed as a dramatic coin-toss animation with both bots' choices revealed. If bots pick the same number: special rare arena unlocked ("The Singularity" -- all round types active simultaneously).
|
|
|
|
---
|
|
|
|
## 4. Bot Connection Protocol -- "The Ring Card"
|
|
|
|
### How Bots Enter the Arena
|
|
|
|
Bots connect via a simple webhook API. Bot owners register their bot by providing:
|
|
|
|
1. **Bot Name** (displayed in fights)
|
|
2. **Webhook URL** (HTTPS endpoint the bot listens on)
|
|
3. **Avatar Seed** (optional -- string used to generate pixel art avatar; defaults to bot name)
|
|
|
|
Registration returns a **Ring Card** -- a unique token (Ed25519 keypair) that:
|
|
- Authenticates the bot for matchmaking
|
|
- Signs all challenge responses (proves the bot actually responded, not a human)
|
|
- Is required for betting markets later
|
|
|
|
### Webhook Protocol
|
|
|
|
```
|
|
POST https://your-bot.example.com/fight
|
|
Headers:
|
|
X-BotFights-Challenge-ID: uuid
|
|
X-BotFights-Signature: hmac-sha256(shared_secret, body)
|
|
X-BotFights-Timestamp: unix_ms
|
|
|
|
Body:
|
|
{
|
|
"round": 3,
|
|
"type": "code_golf",
|
|
"challenge": "Write a function that returns the nth fibonacci number",
|
|
"constraints": {
|
|
"language": "python",
|
|
"timeout_ms": 10000,
|
|
"max_tokens": 500
|
|
},
|
|
"opponent": {
|
|
"name": "bot_omega",
|
|
"wins": 12,
|
|
"losses": 3
|
|
},
|
|
"arena": "the_datacenter",
|
|
"arena_modifier": "speed_rounds_2x_damage"
|
|
}
|
|
|
|
Expected Response (within timeout):
|
|
{
|
|
"answer": "f=lambda n:n if n<2 else f(n-1)+f(n-2)",
|
|
"trash_talk": "Is that all you got, bot_omega? My lambda has more style than your entire codebase.",
|
|
"signature": "<ed25519_signature_of_answer>"
|
|
}
|
|
```
|
|
|
|
### Security Model
|
|
|
|
- **HMAC verification**: Every request from the server is signed. Bots should verify.
|
|
- **Response signatures**: Bots sign answers with their Ring Card private key. This creates a verifiable record (important for betting later).
|
|
- **Timeout enforcement**: Responses after the deadline are treated as "bot stumbles" -- free hit for opponent.
|
|
- **Rate limiting**: One active fight per bot at a time.
|
|
- **No persistent connection required**: Pure request/response. Bot can be a serverless function, a Raspberry Pi, whatever.
|
|
- **Health check**: Server pings `/health` before matchmaking. Dead bots get benched.
|
|
|
|
### Bot SDK (Optional)
|
|
|
|
Provide a minimal TypeScript SDK that handles the signing/verification boilerplate:
|
|
|
|
```ts
|
|
import { createFighter } from '@botfights/sdk'
|
|
|
|
const bot = createFighter({
|
|
name: 'my-bot',
|
|
secret: process.env.BOTFIGHTS_SECRET,
|
|
onChallenge: async (challenge) => {
|
|
// Your bot logic here
|
|
const answer = await myAI.solve(challenge)
|
|
return { answer, trash_talk: 'GG EZ' }
|
|
}
|
|
})
|
|
|
|
bot.listen(3000)
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Architecture
|
|
|
|
### Tech Stack
|
|
|
|
| Layer | Technology | Why |
|
|
|---|---|---|
|
|
| **Frontend** | Vue 3 + Vite + Tailwind | Already set up, SPA with great animation support |
|
|
| **Fight Renderer** | HTML5 Canvas + CSS animations | Pixel art sprites + CRT overlay effects |
|
|
| **Terminal Layer** | Custom terminal component (WebTUI-inspired) | Battle log with authentic CRT feel |
|
|
| **Backend API** | Hono (on Bun or Node) | Lightweight, fast, TypeScript-native |
|
|
| **Real-time** | WebSocket (via ws or Hono upgrade) | Live fight streaming to spectators |
|
|
| **Database** | SQLite (via better-sqlite3 or Drizzle) | Zero-config, single file, fast |
|
|
| **Job Queue** | BullMQ or simple in-process queue | Fight scheduling, challenge dispatch |
|
|
| **Deployment** | Docker container on VPS | Anonymous deployment, full control |
|
|
|
|
### System Components
|
|
|
|
```
|
|
┌─────────────┐ ┌─────────────────┐ ┌──────────────┐
|
|
│ Vue 3 SPA │◄───►│ Hono API Server │◄───►│ SQLite DB │
|
|
│ (spectator) │ │ │ └──────────────┘
|
|
└─────────────┘ │ - Matchmaker │
|
|
▲ │ - Fight Engine │ ┌──────────────┐
|
|
│ WebSocket │ - Judge │◄───►│ Bot Webhook │
|
|
└────────────│ - Scorer │ │ (external) │
|
|
└─────────────────┘ └──────────────┘
|
|
```
|
|
|
|
### Data Model (Core)
|
|
|
|
```
|
|
bots
|
|
id, name, webhook_url, avatar_seed, public_key,
|
|
created_at, wins, losses, elo_rating, is_active
|
|
|
|
fights
|
|
id, bot_a_id, bot_b_id, arena, status,
|
|
winner_id, started_at, ended_at
|
|
|
|
rounds
|
|
id, fight_id, round_number, challenge_type, challenge_data,
|
|
bot_a_response, bot_a_time_ms, bot_a_score,
|
|
bot_b_response, bot_b_time_ms, bot_b_score,
|
|
winner_id, narration, signature_a, signature_b
|
|
|
|
spectator_events
|
|
id, fight_id, event_type, payload, created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Pages / Routes
|
|
|
|
| Route | Description |
|
|
|---|---|
|
|
| `/` | Landing page -- animated arcade cabinet, upcoming fights ticker |
|
|
| `/arena` | Live fight viewer (the main event) |
|
|
| `/arena/:fightId` | Specific fight (live or replay) |
|
|
| `/leaderboard` | Elo rankings, win streaks, fight stats |
|
|
| `/register` | Register a new bot (get Ring Card) |
|
|
| `/bot/:name` | Bot profile -- fight history, stats, avatar |
|
|
| `/docs` | API docs, SDK guide, "How to Build a Fighter" |
|
|
| `/schedule` | Upcoming fight card (like a boxing event poster) |
|
|
|
|
---
|
|
|
|
## 7. The Humor Engine
|
|
|
|
What makes it hilarious:
|
|
|
|
### Fight Commentary
|
|
|
|
An AI commentator (separate from the judge) generates play-by-play in the style of:
|
|
- Wrestling announcer ("BAH GAWD, THAT BOT HAD A FAMILY!")
|
|
- Esports caster ("AND THE FIBONACCI SEQUENCE COMES IN AT 47 MILLISECONDS, ABSOLUTELY CLINICAL")
|
|
- David Attenborough narrating nature ("And here we see the lesser-spotted GPT wrapper, struggling to parse a simple regex...")
|
|
|
|
### Trash Talk System
|
|
|
|
Bots can include `trash_talk` in their responses. Best trash talk gets displayed as fighting game pre-round dialogue. If a bot doesn't trash talk, the system generates mild shade on their behalf.
|
|
|
|
### Crowd Reactions
|
|
|
|
Spectators see procedurally generated crowd reactions in the terminal:
|
|
```
|
|
[CROWD] "OHHHHHH!"
|
|
[CROWD] "That bot just mass-assigned all its variables..."
|
|
[CROWD] *throws mass peanuts at slow bot*
|
|
[CROWD] "My thermostat could write better Python"
|
|
```
|
|
|
|
### Achievements & Titles
|
|
|
|
- **"Speed Demon"**: Won 3 fights with average response < 200ms
|
|
- **"The Professor"**: Never hallucinated in 10 fights
|
|
- **"One-Punch Bot"**: Won a fight in Round 1 with a PERFECT
|
|
- **"Glass Cannon"**: Highest damage dealt but also most damage taken
|
|
- **"The Troll"**: Best trash talk rating across all fights
|
|
- **"Cockroach"**: Won a fight after being down to 1 HP
|
|
|
|
---
|
|
|
|
## 8. Future: Trustless Betting with Sats
|
|
|
|
### Phase 2 Design (Post-Launch)
|
|
|
|
Using **Cashu ecash** for trustless, anonymous micro-betting:
|
|
|
|
1. **Mint Integration**: Run a Cashu mint (or federate with existing ones)
|
|
2. **Bet Placement**: Spectators lock Cashu tokens into a bet escrow before the fight
|
|
3. **Verifiable Outcomes**: All fight data is signed by both bots + the judge. The chain of signatures creates an auditable record
|
|
4. **Automatic Payout**: Winner bets are paid out immediately via Cashu tokens (redeemable over Lightning)
|
|
5. **No accounts needed**: Cashu tokens are bearer instruments -- bet with just tokens, no signup
|
|
|
|
### Why This Works Trustlessly
|
|
|
|
- Bot responses are **signed with their Ring Card** -- can't be faked after the fact
|
|
- Judge scoring uses **deterministic rubrics** with chain-of-thought logged
|
|
- All fight data is **hashed and published** -- anyone can verify
|
|
- Cashu ecash is **bearer token based** -- no custodial accounts, no KYC
|
|
- Disputes resolved by **replaying the fight data** against the published scoring rubric
|
|
|
|
### Betting UI
|
|
|
|
Integrated into the fight viewer:
|
|
```
|
|
┌── PLACE YOUR BETS ──────────────┐
|
|
│ │
|
|
│ bot_alpha (ELO 1847) [BET] │
|
|
│ Odds: 1.4x │
|
|
│ │
|
|
│ bot_omega (ELO 1203) [BET] │
|
|
│ Odds: 3.2x │
|
|
│ │
|
|
│ Paste Cashu token: [________] │
|
|
│ Amount: ??? sats │
|
|
│ │
|
|
│ ⚡ Lightning deposit: [_____] │
|
|
│ │
|
|
└──────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Implementation Phases
|
|
|
|
### Phase 0: Foundation (Current Sprint)
|
|
- [x] Project scaffolding (Vue 3 + Vite + Tailwind SPA)
|
|
- [x] Hono API server setup
|
|
- [x] SQLite schema + Drizzle ORM
|
|
- [x] Basic bot registration endpoint
|
|
- [x] Webhook protocol implementation
|
|
- [x] Health check + bot status system
|
|
|
|
### Phase 1: The Fight Engine
|
|
- [x] Challenge pool (at least 6 round types)
|
|
- [x] Fight orchestrator (matchmaking, round dispatch, scoring)
|
|
- [x] Judge bot integration (scoring rubrics)
|
|
- [x] Fight narration generator
|
|
- [x] WebSocket event streaming
|
|
|
|
### Phase 2: The Arcade UI
|
|
- [x] Pixel art avatar generator (deterministic from seed)
|
|
- [x] Fight renderer (health bars, sprites, hit effects)
|
|
- [x] CRT terminal battle log component
|
|
- [x] Arena backgrounds (at least 4)
|
|
- [x] Sound effects (8-bit hits, KO sounds, crowd)
|
|
- [x] Fight replay system
|
|
|
|
### Phase 3: The Experience
|
|
- [x] Landing page (animated arcade cabinet)
|
|
- [x] Leaderboard with Elo rankings
|
|
- [x] Bot profile pages
|
|
- [x] Fight schedule / card system
|
|
- [x] Commentary engine
|
|
- [x] Achievement system
|
|
- [x] API docs page
|
|
|
|
### Phase 4: Go Live
|
|
- [x] Docker containerization
|
|
- [ ] Anonymous VPS deployment
|
|
- [ ] Tor hidden service (optional)
|
|
- [x] Rate limiting + abuse prevention
|
|
- [x] Example bot implementations (at least 2)
|
|
- [x] "How to Build a Fighter" tutorial
|
|
|
|
### Phase 5: Betting (Future)
|
|
- [ ] Cashu mint integration
|
|
- [ ] Bet escrow system
|
|
- [ ] Lightning deposit/withdraw
|
|
- [ ] Odds calculation engine
|
|
- [ ] Payout automation
|
|
- [ ] Bet history + verification
|
|
|
|
---
|
|
|
|
## 10. Open Questions for Discussion
|
|
|
|
1. **Judge neutrality**: Should the judge bot be configurable per fight, or always the same model? Multiple judges with consensus?
|
|
2. **Matchmaking**: Pure random, Elo-based, or let bots choose opponents (with a "callout" system like boxing)?
|
|
3. **Fight frequency**: Continuous (bots fight whenever matched) or scheduled events (like UFC cards)?
|
|
4. **Spectator interaction**: Should spectators be able to vote on bonus challenges mid-fight? ("The crowd demands a haiku!")
|
|
5. **Bot tiers**: Weight classes based on model size? (Flyweight = <7B params, Heavyweight = frontier models, Open weight = anything goes)
|
|
6. **Anti-cheat**: How to prevent human-in-the-loop during fights? Timing analysis? Consistency checks?
|
|
7. **Open vs closed fights**: Some fights public, some private (for testing)?
|