feat: omni-morph sprite swap, bullet time showboats, music tuning, server hardening
- Creator omni-morph now generates actual sprite sheets for morphed archetypes - 3 new Creator showboats: bullet time attack, ₿ throne summon, disco dance - Music: subtle tempo shift (+10 BPM max), longer phrases (8/16/24 bars), smoother crossfades, less chaotic hi-hat at high intensity - Server: security headers, body size limit, production error masking, CORS origin warning, graceful shutdown with drain - Payments: atomic consume (eliminates SELECT/UPDATE race), release reverts DB - Fight loop: round events for live TUI, retro displayPrompt - Frontend: pass pubkey in payment/queue requests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0acfa4417f
commit
e12fb94ae7
@@ -1,6 +1,7 @@
|
||||
import { db, schema } from '../db/index.js'
|
||||
import { runMockFight } from './mock.js'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { fightEvents } from './events.js'
|
||||
|
||||
export interface FightResult {
|
||||
fightId: string
|
||||
@@ -23,6 +24,7 @@ export interface FightLoopOptions {
|
||||
matchmakingStyle?: 'random' | 'elo_close' | 'mixed'
|
||||
onFightStart?: (botAName: string, botAElo: number, botBName: string, botBElo: number) => void
|
||||
onFightComplete?: (result: FightResult) => void
|
||||
onRoundComplete?: (data: { round: number; hp: { a: number; b: number }; challengeType: string; winnerId: string | null }) => void
|
||||
onError?: (err: Error) => void
|
||||
}
|
||||
|
||||
@@ -33,6 +35,7 @@ export async function startFightLoop(options: FightLoopOptions = {}): Promise<vo
|
||||
matchmakingStyle = 'mixed',
|
||||
onFightStart,
|
||||
onFightComplete,
|
||||
onRoundComplete,
|
||||
onError,
|
||||
} = options
|
||||
|
||||
@@ -67,7 +70,23 @@ export async function startFightLoop(options: FightLoopOptions = {}): Promise<vo
|
||||
onFightStart(botA.name, botA.eloRating, botB.name, botB.eloRating)
|
||||
}
|
||||
|
||||
// Subscribe to round events for live TUI updates
|
||||
let unsub: (() => void) | undefined
|
||||
if (onRoundComplete) {
|
||||
unsub = fightEvents.onAll((event) => {
|
||||
if (event.type === 'round_end') {
|
||||
onRoundComplete({
|
||||
round: event.data.round as number,
|
||||
hp: event.data.hp as { a: number; b: number },
|
||||
challengeType: (event.data.result as any)?.challengeType || '',
|
||||
winnerId: (event.data.result as any)?.winnerId || null,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const fightId = await runMockFight(botA.id, botB.id)
|
||||
unsub?.()
|
||||
|
||||
// Fetch result
|
||||
const fight = await db.select({
|
||||
|
||||
Reference in New Issue
Block a user