SOURCE / PINNED RELEASE
Made of little things.
Napplet Machines V8
- Release
- b3f614e739f0…
- Author-recorded commit
- 534f19acb4ba…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-b5572362d4a
Archive hash verified: 0f7feb97e2c3d336…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
export default async ({ players, check, measure, diagnostics }) => {
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' });
}
await Promise.all(
players.map((p) =>
p.frame.waitForFunction(
() =>
document.querySelector('#connectionState').textContent ===
'Connected',
undefined,
{ timeout: 35000 },
),
),
);
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',
routes[0].filter((p) => p.state === 'connected').length ===
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 [index, p] of players.entries()) {
const ms = await p.frame.evaluate(async () => {
const canvas = document.querySelector('#scene'),
beforeSpeed = Number(canvas.dataset.localSpeed),
start = performance.now();
canvas.dispatchEvent(
new KeyboardEvent('keydown', { code: 'KeyW', bubbles: true }),
);
try {
await new Promise((resolve, reject) => {
const poll = () => {
if (Number(canvas.dataset.localSpeed) > beforeSpeed + 0.12)
resolve();
else if (performance.now() - start > 1500)
reject(new Error('No visible motion'));
else requestAnimationFrame(poll);
};
requestAnimationFrame(poll);
});
return performance.now() - start;
} finally {
canvas.dispatchEvent(
new KeyboardEvent('keyup', { code: 'KeyW', bubbles: true }),
);
}
});
measure(`player ${index + 1} input to rendered motion`, ms, 50);
}
const guest = players[1];
await guest.frame.locator('#scene').focus();
await guest.page.keyboard.down('w');
await guest.page.waitForTimeout(1000);
await guest.page.keyboard.up('w');
await guest.frame.waitForFunction(
() => Number(document.querySelector('#scene').dataset.ack) > 20,
);
check('host acknowledges simulated guest inputs', true);
check(
'prediction history bounded',
Number(await guest.frame.locator('#scene').getAttribute('data-pending')) <
120,
);
await guest.frame.locator('#scene').focus();
const padInput = await guest.frame.evaluate(async () => {
const original = navigator.getGamepads.bind(navigator);
const pad = {
index: 4,
id: 'Network controller',
mapping: 'standard',
connected: true,
axes: [0, 0],
buttons: Array.from({ length: 17 }, () => ({ value: 0, pressed: false })),
};
Object.defineProperty(navigator, 'getGamepads', {
configurable: true,
value: () => [null, null, null, null, pad],
});
const frames = async (n) => {
for (let i = 0; i < n; i++) await new Promise(requestAnimationFrame);
};
const before = Number(document.querySelector('#scene').dataset.ack);
try {
await frames(4);
pad.buttons[0].value = 1;
await frames(4);
pad.buttons[0].value = 0;
pad.buttons[7].value = 0.6;
pad.axes[0] = -0.4;
await frames(30);
const d = document.querySelector('#scene').dataset;
return {
throttle: Number(d.inputThrottle),
steer: Number(d.inputSteer),
ack: Number(d.ack),
before,
};
} finally {
Object.defineProperty(navigator, 'getGamepads', {
configurable: true,
value: original,
});
}
});
check(
'guest analog controller input enters prediction and receives host acknowledgements',
Math.abs(padInput.throttle - 0.6) < 0.01 &&
padInput.steer > 0.2 &&
padInput.steer < 0.4 &&
padInput.ack > padInput.before,
);
await host.frame.locator('#scene').focus();
await host.page.keyboard.down('w');
const continuity = await guest.frame.evaluate(async () => {
const samples = [];
for (let i = 0; i < 30; i++) {
await new Promise(requestAnimationFrame);
const s = document.querySelector('#scene').dataset;
samples.push(s.remoteX + ',' + s.remoteY);
}
return new Set(samples).size;
});
await host.page.keyboard.up('w');
check('remote cars interpolate between network snapshots', continuity > 12);
const buildings = await Promise.all(
players.map((p) =>
p.frame.locator('#scene').getAttribute('data-buildings'),
),
);
check(
'every peer regenerates the same trackside building count',
Number(buildings[0]) >= 5 && new Set(buildings).size === 1,
);
await host.frame.evaluate(() => {
const scene = document.querySelector('#scene');
for (const code of ['KeyW', 'KeyA', 'Space'])
scene.dispatchEvent(
new KeyboardEvent('keydown', { code, bubbles: true }),
);
});
try {
await Promise.all(
players.slice(1).map((p) =>
p.frame.waitForFunction(
() => {
const d = document.querySelector('#scene').dataset;
return (
Number(d.remoteHandbrake) > 0.6 &&
Math.abs(Number(d.remoteSteering)) > 0.05
);
},
undefined,
{ timeout: 10000 },
),
),
);
check('steering and handbrake state reaches all five opponents', true);
const poses = await Promise.all(
players.map((p) =>
p.frame.locator('#scene').getAttribute('data-local-pitch'),
),
);
check(
'slope pose remains finite on every client',
poses.every((p) => Number.isFinite(Number(p))),
);
} finally {
await host.frame.evaluate(() => {
const scene = document.querySelector('#scene');
for (const code of ['KeyW', 'KeyA', 'Space'])
scene.dispatchEvent(
new KeyboardEvent('keyup', { code, bubbles: true }),
);
});
}
await guest.frame.waitForFunction(
() =>
Number(document.querySelector('#scene').dataset.remoteHandbrake) < 0.1,
);
check('handbrake release is synchronized', true);
const beforeReconnect = Number(
await guest.frame.locator('#scene').getAttribute('data-ack'),
);
await guest.frame.locator('#reconnectRace').click();
await guest.frame.waitForFunction(
(ack) => Number(document.querySelector('#scene').dataset.ack) > ack + 10,
beforeReconnect,
{ timeout: 20000 },
);
check('guest transport reconnect resumes acknowledged simulation', true);
await guest.frame
.getByRole('button', { name: 'Exit race', exact: true })
.click();
await guest.frame.waitForFunction(
() => document.querySelector('#scene').dataset.racing === 'false',
);
check('guest leaves race cleanly', true);
await host.frame
.getByRole('button', { name: 'Exit race', exact: true })
.click();
if (players.length > 2)
await players[2].frame.waitForFunction(
() => document.querySelector('#scene').dataset.racing === 'false',
undefined,
{ timeout: 10000 },
);
check('host departure ends the remaining race', true);
};
