Files
syncer/packages/shared/test/dead-air.test.mjs
Syncer Deploy 8a274ecd30
All checks were successful
build / image (push) Successful in 39s
fix dead air strafe direction
2026-08-31 13:32:00 -04:00

146 lines
4.7 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
DEAD_AIR_ARTIFACT_SPAWN,
DEAD_AIR_EXTRACTION,
DEAD_AIR_SNAPSHOT_RATE,
DEAD_AIR_TICK_RATE,
DEAD_AIR_WARDEN_ID_BASE,
deadAirGame,
} from "../dist/index.js";
function input(overrides = {}) {
return {
forward: 0,
strafe: 0,
yaw: 0,
pitch: 0,
fire: false,
sprint: false,
reload: false,
interact: false,
toggleFlashlight: false,
throwDecoy: false,
...overrides,
};
}
test("DEAD AIR runs through the generic multiplayer contract", () => {
assert.equal(deadAirGame.tickRateHz, DEAD_AIR_TICK_RATE);
assert.equal(deadAirGame.snapshotRateHz, DEAD_AIR_SNAPSHOT_RATE);
const server = deadAirGame.createServer();
server.addPlayer(1);
const player = server.currentState.players.find((candidate) => candidate.id === 1);
player.x = DEAD_AIR_ARTIFACT_SPAWN.x;
player.z = DEAD_AIR_ARTIFACT_SPAWN.z;
assert.deepEqual(server.submitInput(1, {
sequence: 1,
targetTick: 1,
observedTick: 0,
input: input({ interact: true }),
}), { accepted: true });
const grabbed = server.step();
assert.equal(player.carryingArtifact, true);
assert.ok(grabbed.events.some((event) => event.type === "artifact" && event.action === "grabbed"));
player.x = DEAD_AIR_EXTRACTION.x;
player.z = DEAD_AIR_EXTRACTION.z;
const extracted = server.step();
assert.equal(player.extractions, 1);
assert.ok(extracted.events.some((event) => event.type === "artifact" && event.action === "extracted"));
});
test("an occluded warden never appears in snapshots and becomes anonymous sound", () => {
const server = deadAirGame.createServer();
server.addPlayer(1);
const viewer = server.currentState.players.find((player) => player.id === 1);
const hidden = server.currentState.players.find((player) => player.id === DEAD_AIR_WARDEN_ID_BASE);
for (const player of server.currentState.players) {
if (player.bot && player.id !== hidden.id) player.alive = false;
}
viewer.x = -25;
viewer.z = 0;
viewer.yaw = Math.PI / 2;
viewer.flashlight = true;
hidden.x = -10;
hidden.z = 0;
hidden.flashlight = false;
const snapshot = server.createSnapshot(1, 0).state;
assert.equal(snapshot.players.some((player) => player.id === hidden.id), false);
assert.equal(JSON.stringify(snapshot).includes(hidden.id.toString()), false);
const perception = server.createPerceptions(1, [{
id: 777,
type: "shot",
sourceId: hidden.id,
x: hidden.x,
z: hidden.z,
yaw: hidden.yaw,
pitch: 0,
}])[0];
assert.equal(perception.type, "sound");
assert.equal(perception.cue, "gunshot");
assert.equal("sourceId" in perception, false);
assert.equal("x" in perception, false);
assert.equal("z" in perception, false);
assert.ok(Number.isInteger(perception.direction));
});
test("private objective coordinates are redacted outside sight", () => {
const server = deadAirGame.createServer();
server.addPlayer(1);
const viewer = server.currentState.players.find((player) => player.id === 1);
viewer.x = -28;
viewer.z = 28;
viewer.yaw = Math.PI;
viewer.flashlight = false;
const snapshot = server.createSnapshot(1, 0).state;
assert.deepEqual(snapshot.artifact, {
visible: false,
x: null,
z: null,
carrierId: null,
});
assert.equal("artifactX" in snapshot, false);
assert.equal("nextEventId" in snapshot, false);
});
test("visible wardens expose pose but redact combat inventory", () => {
const server = deadAirGame.createServer();
server.addPlayer(1);
const viewer = server.currentState.players.find((player) => player.id === 1);
const visible = server.currentState.players.find((player) => player.id === DEAD_AIR_WARDEN_ID_BASE);
viewer.x = -30;
viewer.z = 30;
viewer.yaw = Math.PI / 2;
visible.x = -25;
visible.z = 30;
visible.health = 31;
visible.magazine = 2;
const replicated = server.createSnapshot(1, 0).state.players.find((player) => player.id === visible.id);
assert.ok(replicated);
assert.equal(replicated.x, visible.x);
assert.equal(replicated.health, null);
assert.equal(replicated.magazine, null);
assert.equal(replicated.reserve, null);
});
test("DEAD AIR strafe-right matches the first-person camera's screen right", () => {
const server = deadAirGame.createServer();
server.addPlayer(1);
const player = server.currentState.players.find((candidate) => candidate.id === 1);
player.x = 0;
player.z = 25;
player.yaw = 0;
assert.deepEqual(server.submitInput(1, {
sequence: 1,
targetTick: 1,
observedTick: 0,
input: input({ strafe: 1, yaw: 0 }),
}), { accepted: true });
server.step();
assert.ok(player.x < 0, `camera-right at yaw 0 should reduce world x, saw ${player.x}`);
});