feat: v2 — queue matchmaking, procedural audio, sprite archetypes, auth

- Add queue-based matchmaking with Elo-proximity and 10s timeout
- Procedural sound engine (SFX, voice announcer, 4-track music)
- Sprite system refactored into 6 archetypes (standard, lobster, sheep, cyborg, blob, tank)
- 42+ fight choreographies with themed/generic/wild card selection
- 4 KO finish styles, super-speed mode, hyperdetail close-ups
- Auth routes, JoinBout page, bot profile with stats
- 7-tier ranking system (Baby through Legend)
- Arena and challenge system expansions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-06 22:13:19 +00:00
co-authored by Claude Opus 4.6
parent 335c148866
commit 47d20fbe66
82 changed files with 14011 additions and 741 deletions
+12
View File
@@ -17,8 +17,10 @@ sqlite.exec(`
name TEXT NOT NULL UNIQUE,
webhook_url TEXT NOT NULL,
avatar_seed TEXT NOT NULL,
archetype TEXT NOT NULL DEFAULT 'standard',
secret_hash TEXT NOT NULL,
public_key TEXT,
profile_pic_url TEXT,
elo_rating REAL NOT NULL DEFAULT 1200,
wins INTEGER NOT NULL DEFAULT 0,
losses INTEGER NOT NULL DEFAULT 0,
@@ -63,5 +65,15 @@ sqlite.exec(`
);
`)
// Migrations for existing databases
const migrations = [
`ALTER TABLE bots ADD COLUMN archetype TEXT NOT NULL DEFAULT 'standard'`,
`ALTER TABLE bots ADD COLUMN profile_pic_url TEXT`,
]
for (const sql of migrations) {
try { sqlite.exec(sql) } catch { /* column already exists */ }
}
console.log('[botfights] database migrated')
sqlite.close()
+4 -2
View File
@@ -5,8 +5,10 @@ export const bots = sqliteTable('bots', {
name: text('name').notNull().unique(),
webhookUrl: text('webhook_url').notNull(),
avatarSeed: text('avatar_seed').notNull(),
archetype: text('archetype').notNull().default('standard'),
secretHash: text('secret_hash').notNull(),
publicKey: text('public_key'),
profilePicUrl: text('profile_pic_url'),
eloRating: real('elo_rating').notNull().default(1200),
wins: integer('wins').notNull().default(0),
losses: integer('losses').notNull().default(0),
@@ -24,8 +26,8 @@ export const fights = sqliteTable('fights', {
arena: text('arena').notNull(),
status: text('status', { enum: ['scheduled', 'live', 'finished', 'cancelled'] }).notNull().default('scheduled'),
winnerId: text('winner_id').references(() => bots.id),
botAHp: integer('bot_a_hp').notNull().default(100),
botBHp: integer('bot_b_hp').notNull().default(100),
botAHp: integer('bot_a_hp').notNull().default(200),
botBHp: integer('bot_b_hp').notNull().default(200),
totalRounds: integer('total_rounds').notNull().default(0),
scheduledAt: text('scheduled_at'),
startedAt: text('started_at'),