Assert server-authoritative multiplayer combat

This commit is contained in:
Admin 2026-09-21 01:54:34 +00:00
parent 711d9cd884
commit c320792a9c

View File

@ -263,7 +263,7 @@ test('environment physics adds wind, soft island collision, turbulence, and proj
assert.match(source, /windSpeed: this\.environmentWind\?\.strength/); 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([ const [game, entry, multiplayer, pkg, server] = await Promise.all([
read('src/game-v4.js'), read('src/game-v4.js'),
read('src/game-entry.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(pkg, /"keycloak-js"/);
assert.match(multiplayer, /clientId: 'airship-web'/); assert.match(multiplayer, /clientId: 'airship-web'/);
assert.match(multiplayer, /\/api\/ws-ticket/); assert.match(multiplayer, /\/api\/ws-ticket/);
assert.match(multiplayer, /Authorization:/); assert.match(multiplayer, /type: 'input'/);
assert.match(multiplayer, /new WebSocket/); assert.match(multiplayer, /type: 'fire'/);
assert.doesNotMatch(multiplayer, /type: 'state'/);
assert.match(game, /airship:multiplayer-snapshot/); assert.match(game, /airship:multiplayer-snapshot/);
assert.match(game, /this\.remotePlayers = new Map\(\)/); assert.match(game, /syncAuthoritativeSelf/);
assert.match(game, /window\.airshipMultiplayer\?\.sendState/); assert.match(game, /syncMultiplayerProjectiles/);
assert.match(game, /this\.add\.sprite\([\s\S]*?'player-airship'/); assert.match(game, /updateMultiplayerPredictedPlayer/);
assert.match(server, /CREATE TABLE IF NOT EXISTS player_profiles/); assert.match(game, /window\.airshipMultiplayer\?\.sendInput/);
assert.match(server, /a\.tickets\.consume/); assert.match(game, /window\.airshipMultiplayer\?\.fire/);
assert.match(server, /clampFloat\(msg\.X, 0, 3600\)/); assert.match(game, /this\.multiplayerDead/);
assert.match(server, /time\.NewTicker\(100 \* time\.Millisecond\)/); 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 () => { test('mobile controls enter a dock hub before shipyard, trade, or missions', async () => {
const [game, hud, index, entry, dockUi] = await Promise.all([ const [game, hud, index, entry, dockUi] = await Promise.all([
read('src/game-v4.js'), read('src/game-v4.js'),