From c320792a9c6760f0ab36018b18dbf7f9e8e5f6c4 Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 21 Sep 2026 01:54:34 +0000 Subject: [PATCH] Assert server-authoritative multiplayer combat --- tests/wiring.test.mjs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/tests/wiring.test.mjs b/tests/wiring.test.mjs index cfb1170..38f8248 100644 --- a/tests/wiring.test.mjs +++ b/tests/wiring.test.mjs @@ -263,7 +263,7 @@ test('environment physics adds wind, soft island collision, turbulence, and proj assert.match(source, /windSpeed: this\.environmentWind\?\.strength/); }); -test('multiplayer transport uses Keycloak tickets and renders remote Sparrows without physics authority', async () => { +test('multiplayer transport uses Keycloak tickets with server-authoritative movement and PvP', async () => { const [game, entry, multiplayer, pkg, server] = await Promise.all([ read('src/game-v4.js'), read('src/game-entry.js'), @@ -276,18 +276,28 @@ test('multiplayer transport uses Keycloak tickets and renders remote Sparrows wi assert.match(pkg, /"keycloak-js"/); assert.match(multiplayer, /clientId: 'airship-web'/); assert.match(multiplayer, /\/api\/ws-ticket/); - assert.match(multiplayer, /Authorization:/); - assert.match(multiplayer, /new WebSocket/); + assert.match(multiplayer, /type: 'input'/); + assert.match(multiplayer, /type: 'fire'/); + assert.doesNotMatch(multiplayer, /type: 'state'/); assert.match(game, /airship:multiplayer-snapshot/); - assert.match(game, /this\.remotePlayers = new Map\(\)/); - assert.match(game, /window\.airshipMultiplayer\?\.sendState/); - assert.match(game, /this\.add\.sprite\([\s\S]*?'player-airship'/); - assert.match(server, /CREATE TABLE IF NOT EXISTS player_profiles/); - assert.match(server, /a\.tickets\.consume/); - assert.match(server, /clampFloat\(msg\.X, 0, 3600\)/); - assert.match(server, /time\.NewTicker\(100 \* time\.Millisecond\)/); + assert.match(game, /syncAuthoritativeSelf/); + assert.match(game, /syncMultiplayerProjectiles/); + assert.match(game, /updateMultiplayerPredictedPlayer/); + assert.match(game, /window\.airshipMultiplayer\?\.sendInput/); + assert.match(game, /window\.airshipMultiplayer\?\.fire/); + assert.match(game, /this\.multiplayerDead/); + assert.match(server, /type inputState struct/); + assert.match(server, /func \(h \*hub\) updateInput/); + assert.match(server, /func \(h \*hub\) fire/); + assert.match(server, /func \(h \*hub\) step/); + assert.match(server, /stepPlayer\(&c\.state, c\.input/); + assert.match(server, /target\.state\.Hull = clampInt/); + assert.match(server, /target\.state\.RespawnAt/); + assert.match(server, /time\.NewTicker\(simTick\)/); + assert.match(server, /snapshotTick/); + assert.doesNotMatch(server, /msg\.X/); + assert.doesNotMatch(server, /msg\.Hull/); }); - test('mobile controls enter a dock hub before shipyard, trade, or missions', async () => { const [game, hud, index, entry, dockUi] = await Promise.all([ read('src/game-v4.js'),