SOURCE / PINNED RELEASE
Made of little things.
Napplet Machines V8
- Release
- f041ff5dc40c…
- Author-recorded commit
- 71c68951e1dd…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-b5572362d4a
Archive hash verified: 996282af7a380b0d…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
export async function benchmark(
{ players, check, measure, diagnostics, network },
conditions = {},
) {
const host = players[0];
await host.frame.locator('#trackSelect').selectOption('4');
await host.frame.getByRole('button', { name: 'Workshop', exact: false }).click();
await host.frame.locator('#widthInput').fill('20.8');
await host.frame.locator('#widthInput').dispatchEvent('input');
await host.frame.locator('#wallThicknessInput').fill('1.7');
await host.frame.locator('#wallThicknessInput').dispatchEvent('input');
await Promise.all(
players.map(async (p, i) => {
await p.frame.getByRole('button', { name: 'Rooms', exact: false }).click();
await p.frame.locator('#playerName').fill(`Driver ${i + 1}`);
}),
);
await host.frame.getByRole('button', { name: 'Host game', exact: false }).click();
await host.frame.locator('#activeRoom').waitFor({ state: 'visible' });
const room = await host.frame.locator('#activeCode').inputValue();
check('host receives a room code', room.length > 10);
for (const p of players.slice(1)) {
await p.frame.locator('#roomCode').fill(room);
await p.frame.getByRole('button', { name: 'Join room', exact: true }).click();
await p.frame.locator('#activeRoom').waitFor({ state: 'visible' });
}
try {
await Promise.all(
players.map((p) =>
p.frame.waitForFunction(
() => document.querySelector('#connectionState').textContent === 'Connected',
undefined,
{ timeout: 35000 },
),
),
);
} catch (e) {
console.log(
'CONNECT_FAILURE',
await Promise.all(players.map((p) => p.frame.locator('body').innerText())),
);
throw e;
}
await Promise.all(
players
.slice(1)
.map((p) => p.frame.getByRole('button', { name: 'Ready up', exact: true }).click()),
);
await host.frame.waitForFunction(() => !document.querySelector('#startRoom').disabled);
check('all members ready', true);
const routes = await diagnostics();
check(
'host star connects every guest',
new Set(routes[0].filter((p) => p.state === 'connected').map((p) => p.peer)).size ===
players.length - 1 &&
routes.slice(1).every((rows) => rows.some((p) => p.state === 'connected')),
);
await host.frame.getByRole('button', { name: 'Start race', exact: true }).click();
await Promise.all(
players.map((p) =>
p.frame.waitForFunction(() => document.querySelector('#scene').dataset.countdown === '0'),
),
);
check('race starts on all players', true);
check(
'large track and positions beyond the old world boundary reach all peers',
(
await Promise.all(
players.map(
async (p) =>
(await p.frame.locator('#sceneTitle').textContent()) === 'Switchback Summit' &&
Math.abs(Number(await p.frame.locator('#scene').getAttribute('data-local-x'))) > 100,
),
)
).every(Boolean),
);
check(
'20.8 m point width and section thickness reach every guest',
(
await Promise.all(
players.map(
async (p) =>
(await p.frame.locator('#widthInput').inputValue()) === '20.8' &&
(await p.frame.locator('#wallThicknessInput').inputValue()) === '1.7',
),
)
).every(Boolean),
);
for (const p of players)
await p.frame.evaluate(() => {
window.netMeter = { bytes: 0, messages: 0, binary: 0, sizes: [], sent: new Map(), ackMs: [] };
const remember = (seq) => {
if (!window.netMeter.sent.has(seq)) window.netMeter.sent.set(seq, performance.now());
};
window.netMeterTimer = setInterval(() => {
const m = window.netMeter,
ack = Number(document.querySelector('#scene').dataset.ack);
if (m.sent.has(ack)) m.ackMs.push(performance.now() - m.sent.get(ack));
for (const seq of m.sent.keys()) if (seq <= ack || m.sent.size > 240) m.sent.delete(seq);
}, 5);
const api = window.napplet.webrtc,
original = api.send.bind(api);
api.send = (id, payload) => {
if (payload.type === 'input') for (const c of payload.commands) remember(c.seq);
const n = new TextEncoder().encode(JSON.stringify(payload)).length;
window.netMeter.bytes += n;
window.netMeter.messages++;
window.netMeter.sizes.push(n);
return original(id, payload);
};
if (api.sendBytes) {
const bytes = api.sendBytes.bind(api);
api.sendBytes = (id, value) => {
const raw = Uint8Array.from(atob(value), (c) => c.charCodeAt(0)),
view = new DataView(raw.buffer);
if (raw[3] === 2)
for (let i = 0; i < raw[20]; i++) remember(view.getUint32(21 + i * 9, true));
const n = raw.length;
window.netMeter.bytes += n;
window.netMeter.messages++;
window.netMeter.binary++;
window.netMeter.sizes.push(n);
return bytes(id, value);
};
}
});
const guest = players[1];
await guest.frame.locator('#scene').focus();
await guest.page.keyboard.down('w');
const phases = [];
for (const latencyMs of [50, 200, 50]) {
await network({ latencyMs, jitterMs: 15, ...conditions });
const pending = [],
positions = [];
for (let i = 0; i < 50; i++) {
const row = await guest.frame.evaluate(() => ({
...document.querySelector('#scene').dataset,
}));
pending.push(Number(row.pending));
positions.push(row.remoteX + ',' + row.remoteY);
await guest.page.waitForTimeout(100);
}
pending.sort((a, b) => a - b);
phases.push({
latencyMs,
pendingP50: pending[25],
pendingP95: pending[47],
pendingMax: pending[49],
});
}
await guest.page.keyboard.up('w');
const traffic = await Promise.all(
players.map((p) =>
p.frame.evaluate(() => {
clearInterval(window.netMeterTimer);
const m = window.netMeter;
m.ackMs.sort((a, b) => a - b);
m.sizes.sort((a, b) => a - b);
return {
ackMsP50: m.ackMs[Math.floor(m.ackMs.length * 0.5)],
ackMsP95: m.ackMs[Math.floor(m.ackMs.length * 0.95)],
bytes: m.bytes,
messages: m.messages,
binary: m.binary,
p95Bytes: m.sizes[Math.floor(m.sizes.length * 0.95)],
};
}),
),
);
console.log(
'NETWORK_BENCHMARK ' + JSON.stringify({ phases, traffic, diagnostics: await diagnostics() }),
);
check(
'benchmark completes with bounded prediction history',
phases.every((p) => p.pendingMax < 120),
);
}
export default (context) => benchmark(context);
