71 lines
2.4 KiB
JavaScript
71 lines
2.4 KiB
JavaScript
// Smoke test: two bot clients join, aim at each other, and fight.
|
|
// Verifies welcome/state flow, phases, hits, deaths, round ends, scoring.
|
|
// Usage: start the server first, then `node tools/smoke.mjs`
|
|
import WebSocket from 'ws';
|
|
|
|
const URL = process.env.SMOKE_URL || 'ws://localhost:3000/ws';
|
|
const seen = { phases: new Set(), events: new Set(), scores: new Set() };
|
|
|
|
function bot(name) {
|
|
const ws = new WebSocket(URL);
|
|
let me = null;
|
|
let latest = null;
|
|
|
|
ws.on('open', () => ws.send(JSON.stringify({ t: 'join', name })));
|
|
ws.on('message', (d) => {
|
|
const m = JSON.parse(d.toString());
|
|
if (m.t === 'welcome') {
|
|
me = m.id;
|
|
console.log(`[${name}] welcome, id=${m.id}, seed=${m.seed}`);
|
|
return;
|
|
}
|
|
if (m.t !== 'state') return;
|
|
latest = m;
|
|
seen.phases.add(m.phase);
|
|
for (const e of m.events) {
|
|
seen.events.add(e.kind);
|
|
if (['die', 'roundEnd', 'matchEnd'].includes(e.kind)) {
|
|
console.log(`[${name}] event:`, JSON.stringify(e));
|
|
}
|
|
}
|
|
const mine = m.players.find((p) => p.id === me);
|
|
if (mine) seen.scores.add(`${name}:${mine.score}/${mine.hp}`);
|
|
});
|
|
ws.on('error', (e) => { console.error(`[${name}] ws error:`, e.message); });
|
|
|
|
// aim at nearest opponent, shuffle around, hold fire
|
|
setInterval(() => {
|
|
if (ws.readyState !== 1 || !latest) return;
|
|
const mine = latest.players.find((p) => p.id === me);
|
|
if (!mine) return;
|
|
const others = latest.players.filter((p) => p.id !== me && p.alive && p.inRound);
|
|
let angle = Math.random() * Math.PI * 2;
|
|
if (others.length > 0) {
|
|
const t = others[0];
|
|
angle = Math.atan2(t.y - mine.y, t.x - mine.x);
|
|
}
|
|
ws.send(JSON.stringify({
|
|
t: 'input',
|
|
up: Math.random() < 0.3,
|
|
down: Math.random() < 0.3,
|
|
left: Math.random() < 0.3,
|
|
right: Math.random() < 0.3,
|
|
angle,
|
|
fire: true,
|
|
}));
|
|
}, 60);
|
|
}
|
|
|
|
bot('Alpha');
|
|
setTimeout(() => bot('Bravo'), 400);
|
|
|
|
setTimeout(() => {
|
|
console.log('\n--- smoke summary ---');
|
|
console.log('phases seen :', [...seen.phases].join(', '));
|
|
console.log('events seen :', [...seen.events].join(', '));
|
|
console.log('score/hp samples:', [...seen.scores].slice(0, 12).join(' '));
|
|
const ok = seen.phases.has('round') && seen.events.has('throw') && seen.events.has('hit');
|
|
console.log(ok ? '✅ SMOKE OK' : '⚠️ smoke inconclusive (check output above)');
|
|
process.exit(0);
|
|
}, Number(process.env.SMOKE_MS || 25000));
|