@quake2ts/test-utils 0.0.1 → 0.0.740

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -443,6 +443,24 @@ function createPlayerEntityFactory(overrides = {}) {
443
443
  movetype: MoveType.Walk,
444
444
  svflags: ServerFlags.Player,
445
445
  viewheight: 22,
446
+ client: {
447
+ inventory: {
448
+ ammo: { counts: [], caps: [] },
449
+ ownedWeapons: /* @__PURE__ */ new Set(),
450
+ powerups: /* @__PURE__ */ new Map(),
451
+ keys: /* @__PURE__ */ new Set(),
452
+ items: /* @__PURE__ */ new Set()
453
+ },
454
+ weaponStates: {
455
+ currentWeapon: null,
456
+ lastFireTime: 0,
457
+ weaponFrame: 0,
458
+ weaponIdleTime: 0,
459
+ states: /* @__PURE__ */ new Map(),
460
+ // Initialize states map correctly
461
+ activeWeaponId: null
462
+ }
463
+ },
446
464
  ...overrides
447
465
  });
448
466
  }
@@ -695,6 +713,33 @@ function createGameImportsAndEngine(overrides) {
695
713
  };
696
714
  return { imports, engine };
697
715
  }
716
+ function createMockGameExports(overrides = {}) {
717
+ return {
718
+ init: vi2.fn(),
719
+ shutdown: vi2.fn(),
720
+ frame: vi2.fn().mockReturnValue({ state: {} }),
721
+ clientThink: vi2.fn(),
722
+ time: 0,
723
+ spawnWorld: vi2.fn(),
724
+ deathmatch: false,
725
+ coop: false,
726
+ gameImports: {},
727
+ gameEngine: {},
728
+ entities: {
729
+ spawn: vi2.fn(),
730
+ free: vi2.fn(),
731
+ find: vi2.fn(),
732
+ findByClassname: vi2.fn(),
733
+ findByRadius: vi2.fn(() => []),
734
+ forEachEntity: vi2.fn(),
735
+ timeSeconds: 0,
736
+ ...overrides.entities
737
+ },
738
+ multicast: vi2.fn(),
739
+ unicast: vi2.fn(),
740
+ ...overrides
741
+ };
742
+ }
698
743
 
699
744
  // src/game/helpers/physics.ts
700
745
  import { MoveType as MoveType2, Solid as Solid2 } from "@quake2ts/game";
@@ -1134,96 +1179,8 @@ function createMockPowerupItem(id, duration, overrides = {}) {
1134
1179
  return { ...base, ...overrides };
1135
1180
  }
1136
1181
 
1137
- // src/game/mocks.ts
1138
- import { vi as vi5 } from "vitest";
1139
- function createMockGameState(overrides) {
1140
- return {
1141
- levelName: "test_level",
1142
- time: 0,
1143
- entities: [],
1144
- clients: [],
1145
- ...overrides
1146
- };
1147
- }
1148
- function createMockGameExports(overrides) {
1149
- return {
1150
- init: vi5.fn(),
1151
- shutdown: vi5.fn(),
1152
- spawnWorld: vi5.fn(),
1153
- frame: vi5.fn().mockReturnValue({ state: {} }),
1154
- clientConnect: vi5.fn().mockReturnValue(true),
1155
- clientBegin: vi5.fn().mockReturnValue({ index: 1, origin: { x: 0, y: 0, z: 0 } }),
1156
- clientDisconnect: vi5.fn(),
1157
- clientThink: vi5.fn(),
1158
- respawn: vi5.fn(),
1159
- entities: {
1160
- getByIndex: vi5.fn(),
1161
- forEachEntity: vi5.fn(),
1162
- findByRadius: vi5.fn(),
1163
- find: vi5.fn(),
1164
- checkAnyCollision: vi5.fn(),
1165
- trace: vi5.fn(),
1166
- pointcontents: vi5.fn(),
1167
- link: vi5.fn(),
1168
- unlink: vi5.fn(),
1169
- spawn: vi5.fn(),
1170
- free: vi5.fn(),
1171
- activeCount: 0,
1172
- world: { classname: "worldspawn" }
1173
- },
1174
- multicast: vi5.fn(),
1175
- unicast: vi5.fn(),
1176
- configstring: vi5.fn(),
1177
- serverCommand: vi5.fn(),
1178
- sound: vi5.fn(),
1179
- soundIndex: vi5.fn(),
1180
- centerprintf: vi5.fn(),
1181
- trace: vi5.fn(),
1182
- time: 0,
1183
- deathmatch: false,
1184
- skill: 1,
1185
- rogue: false,
1186
- xatrix: false,
1187
- coop: false,
1188
- friendlyFire: false,
1189
- random: {
1190
- next: vi5.fn(),
1191
- nextFloat: vi5.fn(),
1192
- range: vi5.fn(),
1193
- crandom: vi5.fn(),
1194
- getState: vi5.fn(),
1195
- setState: vi5.fn()
1196
- },
1197
- createSave: vi5.fn(),
1198
- loadSave: vi5.fn(),
1199
- serialize: vi5.fn(),
1200
- loadState: vi5.fn(),
1201
- setGodMode: vi5.fn(),
1202
- setNoclip: vi5.fn(),
1203
- setNotarget: vi5.fn(),
1204
- giveItem: vi5.fn(),
1205
- damage: vi5.fn(),
1206
- teleport: vi5.fn(),
1207
- registerHooks: vi5.fn(),
1208
- hooks: {
1209
- onMapLoad: vi5.fn(),
1210
- onMapUnload: vi5.fn(),
1211
- onPlayerSpawn: vi5.fn(),
1212
- onPlayerDeath: vi5.fn(),
1213
- register: vi5.fn(),
1214
- onPickup: vi5.fn()
1215
- // Added onPickup mock
1216
- },
1217
- setSpectator: vi5.fn(),
1218
- registerEntitySpawn: vi5.fn(),
1219
- unregisterEntitySpawn: vi5.fn(),
1220
- getCustomEntities: vi5.fn(),
1221
- ...overrides
1222
- };
1223
- }
1224
-
1225
1182
  // src/server/mocks/transport.ts
1226
- import { vi as vi6 } from "vitest";
1183
+ import { vi as vi5 } from "vitest";
1227
1184
  var MockTransport = class {
1228
1185
  constructor() {
1229
1186
  this.address = "127.0.0.1";
@@ -1231,11 +1188,11 @@ var MockTransport = class {
1231
1188
  this.sentMessages = [];
1232
1189
  this.receivedMessages = [];
1233
1190
  this.listening = false;
1234
- this.listenSpy = vi6.fn().mockImplementation(async (port) => {
1191
+ this.listenSpy = vi5.fn().mockImplementation(async (port) => {
1235
1192
  this.port = port;
1236
1193
  this.listening = true;
1237
1194
  });
1238
- this.closeSpy = vi6.fn().mockImplementation(() => {
1195
+ this.closeSpy = vi5.fn().mockImplementation(() => {
1239
1196
  this.listening = false;
1240
1197
  });
1241
1198
  }
@@ -1291,11 +1248,11 @@ var MockTransport = class {
1291
1248
  };
1292
1249
  function createMockUDPSocket(overrides) {
1293
1250
  const socket = {
1294
- send: vi6.fn(),
1295
- on: vi6.fn(),
1296
- close: vi6.fn(),
1297
- bind: vi6.fn(),
1298
- address: vi6.fn().mockReturnValue({ address: "127.0.0.1", family: "IPv4", port: 0 }),
1251
+ send: vi5.fn(),
1252
+ on: vi5.fn(),
1253
+ close: vi5.fn(),
1254
+ bind: vi5.fn(),
1255
+ address: vi5.fn().mockReturnValue({ address: "127.0.0.1", family: "IPv4", port: 0 }),
1299
1256
  ...overrides
1300
1257
  };
1301
1258
  return socket;
@@ -1312,13 +1269,13 @@ function createMockTransport(address = "127.0.0.1", port = 27910, overrides) {
1312
1269
  }
1313
1270
  function createMockNetDriver(overrides) {
1314
1271
  return {
1315
- connect: vi6.fn().mockResolvedValue(void 0),
1316
- disconnect: vi6.fn(),
1317
- send: vi6.fn(),
1318
- onMessage: vi6.fn(),
1319
- onClose: vi6.fn(),
1320
- onError: vi6.fn(),
1321
- isConnected: vi6.fn().mockReturnValue(true),
1272
+ connect: vi5.fn().mockResolvedValue(void 0),
1273
+ disconnect: vi5.fn(),
1274
+ send: vi5.fn(),
1275
+ onMessage: vi5.fn(),
1276
+ onClose: vi5.fn(),
1277
+ onError: vi5.fn(),
1278
+ isConnected: vi5.fn().mockReturnValue(true),
1322
1279
  ...overrides
1323
1280
  };
1324
1281
  }
@@ -1363,7 +1320,7 @@ var MockNetworkTransport = class {
1363
1320
  };
1364
1321
 
1365
1322
  // src/server/mockNetDriver.ts
1366
- import { vi as vi7 } from "vitest";
1323
+ import { vi as vi6 } from "vitest";
1367
1324
  var MockNetDriver = class {
1368
1325
  constructor() {
1369
1326
  this.state = {
@@ -1373,14 +1330,14 @@ var MockNetDriver = class {
1373
1330
  closeHandlers: [],
1374
1331
  errorHandlers: []
1375
1332
  };
1376
- this.connectSpy = vi7.fn().mockImplementation(async (url) => {
1333
+ this.connectSpy = vi6.fn().mockImplementation(async (url) => {
1377
1334
  this.state.connected = true;
1378
1335
  });
1379
- this.disconnectSpy = vi7.fn().mockImplementation(() => {
1336
+ this.disconnectSpy = vi6.fn().mockImplementation(() => {
1380
1337
  this.state.connected = false;
1381
1338
  this.state.closeHandlers.forEach((h) => h());
1382
1339
  });
1383
- this.sendSpy = vi7.fn().mockImplementation((data) => {
1340
+ this.sendSpy = vi6.fn().mockImplementation((data) => {
1384
1341
  this.state.messagesSent.push(new Uint8Array(data));
1385
1342
  });
1386
1343
  }
@@ -1442,7 +1399,16 @@ var MockNetDriver = class {
1442
1399
  // src/server/mocks/state.ts
1443
1400
  import { ServerState, ClientState } from "@quake2ts/server";
1444
1401
  import { MAX_CONFIGSTRINGS, MAX_EDICTS } from "@quake2ts/shared";
1445
- import { vi as vi8 } from "vitest";
1402
+ import { vi as vi7 } from "vitest";
1403
+ function createMockGameState(overrides) {
1404
+ return {
1405
+ levelName: "test_level",
1406
+ time: 0,
1407
+ entities: [],
1408
+ clients: [],
1409
+ ...overrides
1410
+ };
1411
+ }
1446
1412
  function createMockServerState(overrides) {
1447
1413
  return {
1448
1414
  state: ServerState.Game,
@@ -1484,13 +1450,13 @@ function createMockServerClient(clientNum, overrides) {
1484
1450
  incomingSequence: 0,
1485
1451
  outgoingSequence: 0,
1486
1452
  lastReceived: 0,
1487
- process: vi8.fn(),
1488
- transmit: vi8.fn(),
1489
- writeReliableByte: vi8.fn(),
1490
- writeReliableShort: vi8.fn(),
1491
- writeReliableLong: vi8.fn(),
1492
- writeReliableString: vi8.fn(),
1493
- writeReliableData: vi8.fn()
1453
+ process: vi7.fn(),
1454
+ transmit: vi7.fn(),
1455
+ writeReliableByte: vi7.fn(),
1456
+ writeReliableShort: vi7.fn(),
1457
+ writeReliableLong: vi7.fn(),
1458
+ writeReliableString: vi7.fn(),
1459
+ writeReliableData: vi7.fn()
1494
1460
  },
1495
1461
  // Cast as any because NetChan might be complex to fully mock here
1496
1462
  userInfo: "",
@@ -1532,16 +1498,16 @@ function createMockServerClient(clientNum, overrides) {
1532
1498
  }
1533
1499
  function createMockServer(overrides) {
1534
1500
  return {
1535
- start: vi8.fn().mockResolvedValue(void 0),
1536
- stop: vi8.fn(),
1537
- multicast: vi8.fn(),
1538
- unicast: vi8.fn(),
1539
- configstring: vi8.fn(),
1540
- kickPlayer: vi8.fn(),
1541
- changeMap: vi8.fn().mockResolvedValue(void 0),
1542
- getClient: vi8.fn().mockReturnValue(null),
1543
- broadcast: vi8.fn(),
1544
- tick: vi8.fn(),
1501
+ start: vi7.fn().mockResolvedValue(void 0),
1502
+ stop: vi7.fn(),
1503
+ multicast: vi7.fn(),
1504
+ unicast: vi7.fn(),
1505
+ configstring: vi7.fn(),
1506
+ kickPlayer: vi7.fn(),
1507
+ changeMap: vi7.fn().mockResolvedValue(void 0),
1508
+ getClient: vi7.fn().mockReturnValue(null),
1509
+ broadcast: vi7.fn(),
1510
+ tick: vi7.fn(),
1545
1511
  ...overrides
1546
1512
  };
1547
1513
  }
@@ -1603,19 +1569,19 @@ async function simulateHandshake(client, server) {
1603
1569
  }
1604
1570
 
1605
1571
  // src/server/mocks/commands.ts
1606
- import { vi as vi9 } from "vitest";
1572
+ import { vi as vi8 } from "vitest";
1607
1573
  function createMockServerConsole(overrides) {
1608
1574
  const outputBuffer = [];
1609
1575
  const commandBuffer = [];
1610
1576
  return {
1611
- exec: vi9.fn((cmd) => {
1577
+ exec: vi8.fn((cmd) => {
1612
1578
  commandBuffer.push(cmd);
1613
1579
  return `Executed: ${cmd}`;
1614
1580
  }),
1615
- print: vi9.fn((text) => {
1581
+ print: vi8.fn((text) => {
1616
1582
  outputBuffer.push(text);
1617
1583
  }),
1618
- broadcast: vi9.fn((text) => {
1584
+ broadcast: vi8.fn((text) => {
1619
1585
  outputBuffer.push(`Broadcast: ${text}`);
1620
1586
  }),
1621
1587
  commandBuffer,
@@ -1628,13 +1594,13 @@ function createMockRConClient(password = "") {
1628
1594
  connected: false,
1629
1595
  lastCommand: "",
1630
1596
  lastResponse: "",
1631
- connect: vi9.fn(async (address, port, pwd) => {
1597
+ connect: vi8.fn(async (address, port, pwd) => {
1632
1598
  return pwd === password;
1633
1599
  }),
1634
- sendCommand: vi9.fn(async (cmd) => {
1600
+ sendCommand: vi8.fn(async (cmd) => {
1635
1601
  return `RCON Response for: ${cmd}`;
1636
1602
  }),
1637
- disconnect: vi9.fn()
1603
+ disconnect: vi8.fn()
1638
1604
  };
1639
1605
  }
1640
1606
  function simulateServerCommand(server, command) {
@@ -1703,19 +1669,19 @@ async function simulateServerRegistration(server, master) {
1703
1669
  }
1704
1670
 
1705
1671
  // src/server/mocks/physics.ts
1706
- import { vi as vi10 } from "vitest";
1672
+ import { vi as vi9 } from "vitest";
1707
1673
  function createMockCollisionEntityIndex(overrides) {
1708
1674
  return {
1709
- trace: vi10.fn().mockReturnValue({
1675
+ trace: vi9.fn().mockReturnValue({
1710
1676
  fraction: 1,
1711
1677
  allsolid: false,
1712
1678
  startsolid: false,
1713
1679
  endpos: { x: 0, y: 0, z: 0 },
1714
1680
  entityId: null
1715
1681
  }),
1716
- link: vi10.fn(),
1717
- unlink: vi10.fn(),
1718
- gatherTriggerTouches: vi10.fn().mockReturnValue([]),
1682
+ link: vi9.fn(),
1683
+ unlink: vi9.fn(),
1684
+ gatherTriggerTouches: vi9.fn().mockReturnValue([]),
1719
1685
  ...overrides
1720
1686
  };
1721
1687
  }
@@ -2211,7 +2177,7 @@ function createInputInjector(target) {
2211
2177
  }
2212
2178
 
2213
2179
  // src/engine/mocks/webgl.ts
2214
- import { vi as vi11 } from "vitest";
2180
+ import { vi as vi10 } from "vitest";
2215
2181
  var MockWebGL2RenderingContext = class {
2216
2182
  constructor(canvas) {
2217
2183
  this.ARRAY_BUFFER = 34962;
@@ -2270,139 +2236,139 @@ var MockWebGL2RenderingContext = class {
2270
2236
  this.calls = [];
2271
2237
  this.uniformLocations = /* @__PURE__ */ new Map();
2272
2238
  this.attributeLocations = /* @__PURE__ */ new Map();
2273
- this.enable = vi11.fn((cap) => this.calls.push(`enable:${cap}`));
2274
- this.disable = vi11.fn((cap) => this.calls.push(`disable:${cap}`));
2275
- this.depthFunc = vi11.fn((func) => this.calls.push(`depthFunc:${func}`));
2276
- this.cullFace = vi11.fn((mode) => this.calls.push(`cullFace:${mode}`));
2277
- this.depthMask = vi11.fn((flag) => this.calls.push(`depthMask:${flag}`));
2278
- this.blendFuncSeparate = vi11.fn(
2239
+ this.enable = vi10.fn((cap) => this.calls.push(`enable:${cap}`));
2240
+ this.disable = vi10.fn((cap) => this.calls.push(`disable:${cap}`));
2241
+ this.depthFunc = vi10.fn((func) => this.calls.push(`depthFunc:${func}`));
2242
+ this.cullFace = vi10.fn((mode) => this.calls.push(`cullFace:${mode}`));
2243
+ this.depthMask = vi10.fn((flag) => this.calls.push(`depthMask:${flag}`));
2244
+ this.blendFuncSeparate = vi10.fn(
2279
2245
  (srcRGB, dstRGB, srcAlpha, dstAlpha) => this.calls.push(`blendFuncSeparate:${srcRGB}:${dstRGB}:${srcAlpha}:${dstAlpha}`)
2280
2246
  );
2281
- this.blendFunc = vi11.fn((sfactor, dfactor) => this.calls.push(`blendFunc:${sfactor}:${dfactor}`));
2282
- this.getExtension = vi11.fn((name) => this.extensions.get(name) ?? null);
2283
- this.viewport = vi11.fn((x, y, w, h) => this.calls.push(`viewport:${x}:${y}:${w}:${h}`));
2284
- this.clear = vi11.fn((mask) => this.calls.push(`clear:${mask}`));
2285
- this.clearColor = vi11.fn((r, g, b, a) => this.calls.push(`clearColor:${r}:${g}:${b}:${a}`));
2286
- this.createShader = vi11.fn((type) => ({ id: ++this.shaderCounter, type }));
2287
- this.shaderSource = vi11.fn((shader, source) => this.calls.push(`shaderSource:${shader.id}:${source}`));
2288
- this.compileShader = vi11.fn((shader) => this.calls.push(`compileShader:${shader.id}`));
2289
- this.getShaderParameter = vi11.fn(
2247
+ this.blendFunc = vi10.fn((sfactor, dfactor) => this.calls.push(`blendFunc:${sfactor}:${dfactor}`));
2248
+ this.getExtension = vi10.fn((name) => this.extensions.get(name) ?? null);
2249
+ this.viewport = vi10.fn((x, y, w, h) => this.calls.push(`viewport:${x}:${y}:${w}:${h}`));
2250
+ this.clear = vi10.fn((mask) => this.calls.push(`clear:${mask}`));
2251
+ this.clearColor = vi10.fn((r, g, b, a) => this.calls.push(`clearColor:${r}:${g}:${b}:${a}`));
2252
+ this.createShader = vi10.fn((type) => ({ id: ++this.shaderCounter, type }));
2253
+ this.shaderSource = vi10.fn((shader, source) => this.calls.push(`shaderSource:${shader.id}:${source}`));
2254
+ this.compileShader = vi10.fn((shader) => this.calls.push(`compileShader:${shader.id}`));
2255
+ this.getShaderParameter = vi10.fn(
2290
2256
  (shader, pname) => pname === this.COMPILE_STATUS ? this.compileSucceeds : null
2291
2257
  );
2292
- this.getShaderInfoLog = vi11.fn(() => this.compileSucceeds ? "" : this.shaderInfoLog);
2293
- this.deleteShader = vi11.fn((shader) => this.calls.push(`deleteShader:${shader.id}`));
2294
- this.createProgram = vi11.fn(() => ({ id: ++this.programCounter }));
2295
- this.attachShader = vi11.fn(
2258
+ this.getShaderInfoLog = vi10.fn(() => this.compileSucceeds ? "" : this.shaderInfoLog);
2259
+ this.deleteShader = vi10.fn((shader) => this.calls.push(`deleteShader:${shader.id}`));
2260
+ this.createProgram = vi10.fn(() => ({ id: ++this.programCounter }));
2261
+ this.attachShader = vi10.fn(
2296
2262
  (program, shader) => this.calls.push(`attach:${program.id}:${shader.id}`)
2297
2263
  );
2298
- this.bindAttribLocation = vi11.fn(
2264
+ this.bindAttribLocation = vi10.fn(
2299
2265
  (program, index, name) => this.calls.push(`bindAttribLocation:${program.id}:${index}:${name}`)
2300
2266
  );
2301
- this.linkProgram = vi11.fn((program) => this.calls.push(`link:${program.id}`));
2302
- this.getProgramParameter = vi11.fn(
2267
+ this.linkProgram = vi10.fn((program) => this.calls.push(`link:${program.id}`));
2268
+ this.getProgramParameter = vi10.fn(
2303
2269
  (program, pname) => pname === this.LINK_STATUS ? this.linkSucceeds : null
2304
2270
  );
2305
- this.getProgramInfoLog = vi11.fn(() => this.linkSucceeds ? "" : this.programInfoLog);
2306
- this.deleteProgram = vi11.fn((program) => this.calls.push(`deleteProgram:${program.id}`));
2307
- this.useProgram = vi11.fn((program) => this.calls.push(`useProgram:${program?.id ?? "null"}`));
2308
- this.getUniformLocation = vi11.fn((program, name) => {
2271
+ this.getProgramInfoLog = vi10.fn(() => this.linkSucceeds ? "" : this.programInfoLog);
2272
+ this.deleteProgram = vi10.fn((program) => this.calls.push(`deleteProgram:${program.id}`));
2273
+ this.useProgram = vi10.fn((program) => this.calls.push(`useProgram:${program?.id ?? "null"}`));
2274
+ this.getUniformLocation = vi10.fn((program, name) => {
2309
2275
  this.calls.push(`getUniformLocation:${program.id}:${name}`);
2310
2276
  return this.uniformLocations.get(name) ?? null;
2311
2277
  });
2312
- this.getAttribLocation = vi11.fn((program, name) => {
2278
+ this.getAttribLocation = vi10.fn((program, name) => {
2313
2279
  this.calls.push(`getAttribLocation:${program.id}:${name}`);
2314
2280
  return this.attributeLocations.get(name) ?? -1;
2315
2281
  });
2316
- this.createBuffer = vi11.fn(() => ({ buffer: {} }));
2317
- this.bindBuffer = vi11.fn((target, buffer) => this.calls.push(`bindBuffer:${target}:${!!buffer}`));
2318
- this.bufferData = vi11.fn(
2282
+ this.createBuffer = vi10.fn(() => ({ buffer: {} }));
2283
+ this.bindBuffer = vi10.fn((target, buffer) => this.calls.push(`bindBuffer:${target}:${!!buffer}`));
2284
+ this.bufferData = vi10.fn(
2319
2285
  (target, data, usage) => this.calls.push(`bufferData:${target}:${usage}:${typeof data === "number" ? data : "data"}`)
2320
2286
  );
2321
- this.bufferSubData = vi11.fn(
2287
+ this.bufferSubData = vi10.fn(
2322
2288
  (target, offset, data) => this.calls.push(`bufferSubData:${target}:${offset}:${data.byteLength ?? "len"}`)
2323
2289
  );
2324
- this.deleteBuffer = vi11.fn((buffer) => this.calls.push(`deleteBuffer:${!!buffer}`));
2325
- this.createVertexArray = vi11.fn(() => ({ vao: {} }));
2326
- this.bindVertexArray = vi11.fn((vao) => this.calls.push(`bindVertexArray:${!!vao}`));
2327
- this.enableVertexAttribArray = vi11.fn((index) => this.calls.push(`enableAttrib:${index}`));
2328
- this.vertexAttribPointer = vi11.fn(
2290
+ this.deleteBuffer = vi10.fn((buffer) => this.calls.push(`deleteBuffer:${!!buffer}`));
2291
+ this.createVertexArray = vi10.fn(() => ({ vao: {} }));
2292
+ this.bindVertexArray = vi10.fn((vao) => this.calls.push(`bindVertexArray:${!!vao}`));
2293
+ this.enableVertexAttribArray = vi10.fn((index) => this.calls.push(`enableAttrib:${index}`));
2294
+ this.vertexAttribPointer = vi10.fn(
2329
2295
  (index, size, type, normalized, stride, offset) => this.calls.push(`vertexAttribPointer:${index}:${size}:${type}:${normalized}:${stride}:${offset}`)
2330
2296
  );
2331
- this.vertexAttribDivisor = vi11.fn((index, divisor) => this.calls.push(`divisor:${index}:${divisor}`));
2332
- this.deleteVertexArray = vi11.fn((vao) => this.calls.push(`deleteVertexArray:${!!vao}`));
2333
- this.createTexture = vi11.fn(() => ({ texture: {} }));
2334
- this.activeTexture = vi11.fn((unit) => this.calls.push(`activeTexture:${unit}`));
2335
- this.bindTexture = vi11.fn((target, texture) => this.calls.push(`bindTexture:${target}:${!!texture}`));
2336
- this.texParameteri = vi11.fn(
2297
+ this.vertexAttribDivisor = vi10.fn((index, divisor) => this.calls.push(`divisor:${index}:${divisor}`));
2298
+ this.deleteVertexArray = vi10.fn((vao) => this.calls.push(`deleteVertexArray:${!!vao}`));
2299
+ this.createTexture = vi10.fn(() => ({ texture: {} }));
2300
+ this.activeTexture = vi10.fn((unit) => this.calls.push(`activeTexture:${unit}`));
2301
+ this.bindTexture = vi10.fn((target, texture) => this.calls.push(`bindTexture:${target}:${!!texture}`));
2302
+ this.texParameteri = vi10.fn(
2337
2303
  (target, pname, param) => this.calls.push(`texParameteri:${target}:${pname}:${param}`)
2338
2304
  );
2339
- this.texImage2D = vi11.fn(
2305
+ this.texImage2D = vi10.fn(
2340
2306
  (target, level, internalFormat, width, height, border, format, type, pixels) => this.calls.push(
2341
2307
  `texImage2D:${target}:${level}:${internalFormat}:${width}:${height}:${border}:${format}:${type}:${pixels ? "data" : "null"}`
2342
2308
  )
2343
2309
  );
2344
- this.texImage3D = vi11.fn();
2310
+ this.texImage3D = vi10.fn();
2345
2311
  // Stub for compatibility
2346
- this.deleteTexture = vi11.fn((texture) => this.calls.push(`deleteTexture:${!!texture}`));
2347
- this.createFramebuffer = vi11.fn(() => ({ fb: {} }));
2348
- this.bindFramebuffer = vi11.fn(
2312
+ this.deleteTexture = vi10.fn((texture) => this.calls.push(`deleteTexture:${!!texture}`));
2313
+ this.createFramebuffer = vi10.fn(() => ({ fb: {} }));
2314
+ this.bindFramebuffer = vi10.fn(
2349
2315
  (target, framebuffer) => this.calls.push(`bindFramebuffer:${target}:${!!framebuffer}`)
2350
2316
  );
2351
- this.framebufferTexture2D = vi11.fn(
2317
+ this.framebufferTexture2D = vi10.fn(
2352
2318
  (target, attachment, textarget, texture, level) => this.calls.push(`framebufferTexture2D:${target}:${attachment}:${textarget}:${!!texture}:${level}`)
2353
2319
  );
2354
- this.deleteFramebuffer = vi11.fn((fb) => this.calls.push(`deleteFramebuffer:${!!fb}`));
2355
- this.checkFramebufferStatus = vi11.fn((target) => this.FRAMEBUFFER_COMPLETE);
2356
- this.createRenderbuffer = vi11.fn(() => ({ rb: {} }));
2357
- this.bindRenderbuffer = vi11.fn(
2320
+ this.deleteFramebuffer = vi10.fn((fb) => this.calls.push(`deleteFramebuffer:${!!fb}`));
2321
+ this.checkFramebufferStatus = vi10.fn((target) => this.FRAMEBUFFER_COMPLETE);
2322
+ this.createRenderbuffer = vi10.fn(() => ({ rb: {} }));
2323
+ this.bindRenderbuffer = vi10.fn(
2358
2324
  (target, renderbuffer) => this.calls.push(`bindRenderbuffer:${target}:${!!renderbuffer}`)
2359
2325
  );
2360
- this.renderbufferStorage = vi11.fn(
2326
+ this.renderbufferStorage = vi10.fn(
2361
2327
  (target, internalformat, width, height) => this.calls.push(`renderbufferStorage:${target}:${internalformat}:${width}:${height}`)
2362
2328
  );
2363
- this.framebufferRenderbuffer = vi11.fn(
2329
+ this.framebufferRenderbuffer = vi10.fn(
2364
2330
  (target, attachment, renderbuffertarget, renderbuffer) => this.calls.push(`framebufferRenderbuffer:${target}:${attachment}:${renderbuffertarget}:${!!renderbuffer}`)
2365
2331
  );
2366
- this.deleteRenderbuffer = vi11.fn((rb) => this.calls.push(`deleteRenderbuffer:${!!rb}`));
2367
- this.drawArrays = vi11.fn(
2332
+ this.deleteRenderbuffer = vi10.fn((rb) => this.calls.push(`deleteRenderbuffer:${!!rb}`));
2333
+ this.drawArrays = vi10.fn(
2368
2334
  (mode, first, count) => this.calls.push(`drawArrays:${mode}:${first}:${count}`)
2369
2335
  );
2370
- this.drawElements = vi11.fn(
2336
+ this.drawElements = vi10.fn(
2371
2337
  (mode, count, type, offset) => this.calls.push(`drawElements:${mode}:${count}:${type}:${offset}`)
2372
2338
  );
2373
2339
  // Queries
2374
- this.createQuery = vi11.fn(() => ({}));
2375
- this.beginQuery = vi11.fn();
2376
- this.endQuery = vi11.fn();
2377
- this.deleteQuery = vi11.fn();
2378
- this.getQueryParameter = vi11.fn();
2379
- this.getParameter = vi11.fn();
2380
- this.uniform1f = vi11.fn(
2340
+ this.createQuery = vi10.fn(() => ({}));
2341
+ this.beginQuery = vi10.fn();
2342
+ this.endQuery = vi10.fn();
2343
+ this.deleteQuery = vi10.fn();
2344
+ this.getQueryParameter = vi10.fn();
2345
+ this.getParameter = vi10.fn();
2346
+ this.uniform1f = vi10.fn(
2381
2347
  (location, x) => this.calls.push(`uniform1f:${location ? "set" : "null"}:${x}`)
2382
2348
  );
2383
- this.uniform1i = vi11.fn(
2349
+ this.uniform1i = vi10.fn(
2384
2350
  (location, x) => this.calls.push(`uniform1i:${location ? "set" : "null"}:${x}`)
2385
2351
  );
2386
- this.uniform4f = vi11.fn(
2352
+ this.uniform4f = vi10.fn(
2387
2353
  (location, x, y, z, w) => this.calls.push(`uniform4f:${location ? "set" : "null"}:${x}:${y}:${z}:${w}`)
2388
2354
  );
2389
- this.uniform3fv = vi11.fn(
2355
+ this.uniform3fv = vi10.fn(
2390
2356
  (location, data) => this.calls.push(`uniform3fv:${location ? "set" : "null"}:${Array.from(data).join(",")}`)
2391
2357
  );
2392
- this.uniform3f = vi11.fn(
2358
+ this.uniform3f = vi10.fn(
2393
2359
  (location, x, y, z) => this.calls.push(`uniform3f:${location ? "set" : "null"}:${x}:${y}:${z}`)
2394
2360
  );
2395
- this.uniform2f = vi11.fn(
2361
+ this.uniform2f = vi10.fn(
2396
2362
  (location, x, y) => this.calls.push(`uniform2f:${location ? "set" : "null"}:${x}:${y}`)
2397
2363
  );
2398
- this.uniform4fv = vi11.fn(
2364
+ this.uniform4fv = vi10.fn(
2399
2365
  (location, data) => this.calls.push(`uniform4fv:${location ? "set" : "null"}:${Array.from(data).join(",")}`)
2400
2366
  );
2401
- this.uniformMatrix4fv = vi11.fn(
2367
+ this.uniformMatrix4fv = vi10.fn(
2402
2368
  (location, transpose, data) => this.calls.push(`uniformMatrix4fv:${location ? "set" : "null"}:${transpose}:${Array.from(data).join(",")}`)
2403
2369
  );
2404
- this.uniformBlockBinding = vi11.fn();
2405
- this.isContextLost = vi11.fn(() => false);
2370
+ this.uniformBlockBinding = vi10.fn();
2371
+ this.isContextLost = vi10.fn(() => false);
2406
2372
  if (canvas) {
2407
2373
  this.canvas = canvas;
2408
2374
  this.drawingBufferWidth = canvas.width;
@@ -2762,13 +2728,13 @@ async function createHeadlessTestContext() {
2762
2728
  }
2763
2729
 
2764
2730
  // src/engine/mocks/webgpu.ts
2765
- import { vi as vi12 } from "vitest";
2731
+ import { vi as vi11 } from "vitest";
2766
2732
  import { globals } from "webgpu";
2767
2733
  function setupWebGPUMocks() {
2768
2734
  Object.assign(globalThis, globals);
2769
2735
  const mockGpu = {
2770
- requestAdapter: vi12.fn(),
2771
- getPreferredCanvasFormat: vi12.fn().mockReturnValue("bgra8unorm")
2736
+ requestAdapter: vi11.fn(),
2737
+ getPreferredCanvasFormat: vi11.fn().mockReturnValue("bgra8unorm")
2772
2738
  };
2773
2739
  const mockAdapter = createMockGPUAdapter();
2774
2740
  const mockDevice = createMockGPUDevice();
@@ -2797,8 +2763,8 @@ function createMockGPUAdapter(options = {}) {
2797
2763
  features: /* @__PURE__ */ new Set(),
2798
2764
  limits: {},
2799
2765
  isFallbackAdapter: false,
2800
- requestDevice: vi12.fn().mockResolvedValue(createMockGPUDevice()),
2801
- requestAdapterInfo: vi12.fn().mockResolvedValue({}),
2766
+ requestDevice: vi11.fn().mockResolvedValue(createMockGPUDevice()),
2767
+ requestAdapterInfo: vi11.fn().mockResolvedValue({}),
2802
2768
  ...options
2803
2769
  };
2804
2770
  }
@@ -2808,25 +2774,25 @@ function createMockGPUDevice(features = /* @__PURE__ */ new Set()) {
2808
2774
  features,
2809
2775
  limits: {},
2810
2776
  queue,
2811
- destroy: vi12.fn(),
2812
- createBuffer: vi12.fn((descriptor) => createMockGPUBuffer(descriptor)),
2813
- createTexture: vi12.fn((descriptor) => createMockGPUTexture(descriptor)),
2814
- createSampler: vi12.fn(() => createMockSampler()),
2815
- createBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2816
- createPipelineLayout: vi12.fn(() => ({ label: "mock-pipeline-layout" })),
2817
- createBindGroup: vi12.fn(() => ({ label: "mock-bind-group" })),
2818
- createShaderModule: vi12.fn((descriptor) => createMockShaderModule(descriptor)),
2819
- createComputePipeline: vi12.fn(() => createMockComputePipeline()),
2820
- createRenderPipeline: vi12.fn(() => createMockRenderPipeline()),
2821
- createComputePipelineAsync: vi12.fn().mockResolvedValue(createMockComputePipeline()),
2822
- createRenderPipelineAsync: vi12.fn().mockResolvedValue(createMockRenderPipeline()),
2823
- createCommandEncoder: vi12.fn(() => createMockCommandEncoder()),
2824
- createQuerySet: vi12.fn(() => ({ label: "mock-query-set" })),
2825
- pushErrorScope: vi12.fn(),
2826
- popErrorScope: vi12.fn().mockResolvedValue(null),
2827
- addEventListener: vi12.fn(),
2828
- removeEventListener: vi12.fn(),
2829
- dispatchEvent: vi12.fn(),
2777
+ destroy: vi11.fn(),
2778
+ createBuffer: vi11.fn((descriptor) => createMockGPUBuffer(descriptor)),
2779
+ createTexture: vi11.fn((descriptor) => createMockGPUTexture(descriptor)),
2780
+ createSampler: vi11.fn(() => createMockSampler()),
2781
+ createBindGroupLayout: vi11.fn(() => ({ label: "mock-bind-group-layout" })),
2782
+ createPipelineLayout: vi11.fn(() => ({ label: "mock-pipeline-layout" })),
2783
+ createBindGroup: vi11.fn(() => ({ label: "mock-bind-group" })),
2784
+ createShaderModule: vi11.fn((descriptor) => createMockShaderModule(descriptor)),
2785
+ createComputePipeline: vi11.fn(() => createMockComputePipeline()),
2786
+ createRenderPipeline: vi11.fn(() => createMockRenderPipeline()),
2787
+ createComputePipelineAsync: vi11.fn().mockResolvedValue(createMockComputePipeline()),
2788
+ createRenderPipelineAsync: vi11.fn().mockResolvedValue(createMockRenderPipeline()),
2789
+ createCommandEncoder: vi11.fn(() => createMockCommandEncoder()),
2790
+ createQuerySet: vi11.fn(() => ({ label: "mock-query-set" })),
2791
+ pushErrorScope: vi11.fn(),
2792
+ popErrorScope: vi11.fn().mockResolvedValue(null),
2793
+ addEventListener: vi11.fn(),
2794
+ removeEventListener: vi11.fn(),
2795
+ dispatchEvent: vi11.fn(),
2830
2796
  onuncapturederror: null,
2831
2797
  label: "",
2832
2798
  lost: Promise.resolve({ reason: "destroyed", message: "Device lost" })
@@ -2834,11 +2800,11 @@ function createMockGPUDevice(features = /* @__PURE__ */ new Set()) {
2834
2800
  }
2835
2801
  function createMockQueue() {
2836
2802
  return {
2837
- submit: vi12.fn(),
2838
- onSubmittedWorkDone: vi12.fn().mockResolvedValue(void 0),
2839
- writeBuffer: vi12.fn(),
2840
- writeTexture: vi12.fn(),
2841
- copyExternalImageToTexture: vi12.fn(),
2803
+ submit: vi11.fn(),
2804
+ onSubmittedWorkDone: vi11.fn().mockResolvedValue(void 0),
2805
+ writeBuffer: vi11.fn(),
2806
+ writeTexture: vi11.fn(),
2807
+ copyExternalImageToTexture: vi11.fn(),
2842
2808
  label: ""
2843
2809
  };
2844
2810
  }
@@ -2847,10 +2813,10 @@ function createMockGPUBuffer(descriptor) {
2847
2813
  size: descriptor.size,
2848
2814
  usage: descriptor.usage,
2849
2815
  mapState: "unmapped",
2850
- mapAsync: vi12.fn().mockResolvedValue(void 0),
2851
- getMappedRange: vi12.fn(() => new ArrayBuffer(descriptor.size)),
2852
- unmap: vi12.fn(),
2853
- destroy: vi12.fn(),
2816
+ mapAsync: vi11.fn().mockResolvedValue(void 0),
2817
+ getMappedRange: vi11.fn(() => new ArrayBuffer(descriptor.size)),
2818
+ unmap: vi11.fn(),
2819
+ destroy: vi11.fn(),
2854
2820
  label: descriptor.label || ""
2855
2821
  };
2856
2822
  }
@@ -2879,8 +2845,8 @@ function createMockGPUTexture(descriptor) {
2879
2845
  dimension: descriptor.dimension || "2d",
2880
2846
  format: descriptor.format,
2881
2847
  usage: descriptor.usage,
2882
- createView: vi12.fn(() => createMockTextureView()),
2883
- destroy: vi12.fn(),
2848
+ createView: vi11.fn(() => createMockTextureView()),
2849
+ destroy: vi11.fn(),
2884
2850
  label: descriptor.label || ""
2885
2851
  };
2886
2852
  }
@@ -2896,74 +2862,74 @@ function createMockSampler() {
2896
2862
  }
2897
2863
  function createMockShaderModule(descriptor) {
2898
2864
  return {
2899
- getCompilationInfo: vi12.fn().mockResolvedValue({ messages: [] }),
2865
+ getCompilationInfo: vi11.fn().mockResolvedValue({ messages: [] }),
2900
2866
  label: descriptor.label || ""
2901
2867
  };
2902
2868
  }
2903
2869
  function createMockComputePipeline() {
2904
2870
  return {
2905
- getBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2871
+ getBindGroupLayout: vi11.fn(() => ({ label: "mock-bind-group-layout" })),
2906
2872
  label: ""
2907
2873
  };
2908
2874
  }
2909
2875
  function createMockRenderPipeline() {
2910
2876
  return {
2911
- getBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2877
+ getBindGroupLayout: vi11.fn(() => ({ label: "mock-bind-group-layout" })),
2912
2878
  label: ""
2913
2879
  };
2914
2880
  }
2915
2881
  function createMockCommandEncoder() {
2916
2882
  return {
2917
- beginRenderPass: vi12.fn(() => createMockRenderPassEncoder()),
2918
- beginComputePass: vi12.fn(() => createMockComputePassEncoder()),
2919
- copyBufferToBuffer: vi12.fn(),
2920
- copyBufferToTexture: vi12.fn(),
2921
- copyTextureToBuffer: vi12.fn(),
2922
- copyTextureToTexture: vi12.fn(),
2923
- clearBuffer: vi12.fn(),
2924
- writeTimestamp: vi12.fn(),
2925
- resolveQuerySet: vi12.fn(),
2926
- finish: vi12.fn(() => ({ label: "mock-command-buffer" })),
2927
- pushDebugGroup: vi12.fn(),
2928
- popDebugGroup: vi12.fn(),
2929
- insertDebugMarker: vi12.fn(),
2883
+ beginRenderPass: vi11.fn(() => createMockRenderPassEncoder()),
2884
+ beginComputePass: vi11.fn(() => createMockComputePassEncoder()),
2885
+ copyBufferToBuffer: vi11.fn(),
2886
+ copyBufferToTexture: vi11.fn(),
2887
+ copyTextureToBuffer: vi11.fn(),
2888
+ copyTextureToTexture: vi11.fn(),
2889
+ clearBuffer: vi11.fn(),
2890
+ writeTimestamp: vi11.fn(),
2891
+ resolveQuerySet: vi11.fn(),
2892
+ finish: vi11.fn(() => ({ label: "mock-command-buffer" })),
2893
+ pushDebugGroup: vi11.fn(),
2894
+ popDebugGroup: vi11.fn(),
2895
+ insertDebugMarker: vi11.fn(),
2930
2896
  label: ""
2931
2897
  };
2932
2898
  }
2933
2899
  function createMockRenderPassEncoder() {
2934
2900
  return {
2935
- setPipeline: vi12.fn(),
2936
- setIndexBuffer: vi12.fn(),
2937
- setVertexBuffer: vi12.fn(),
2938
- setBindGroup: vi12.fn(),
2939
- setViewport: vi12.fn(),
2940
- setScissorRect: vi12.fn(),
2941
- setBlendConstant: vi12.fn(),
2942
- setStencilReference: vi12.fn(),
2943
- beginOcclusionQuery: vi12.fn(),
2944
- endOcclusionQuery: vi12.fn(),
2945
- executeBundles: vi12.fn(),
2946
- draw: vi12.fn(),
2947
- drawIndexed: vi12.fn(),
2948
- drawIndirect: vi12.fn(),
2949
- drawIndexedIndirect: vi12.fn(),
2950
- end: vi12.fn(),
2951
- pushDebugGroup: vi12.fn(),
2952
- popDebugGroup: vi12.fn(),
2953
- insertDebugMarker: vi12.fn(),
2901
+ setPipeline: vi11.fn(),
2902
+ setIndexBuffer: vi11.fn(),
2903
+ setVertexBuffer: vi11.fn(),
2904
+ setBindGroup: vi11.fn(),
2905
+ setViewport: vi11.fn(),
2906
+ setScissorRect: vi11.fn(),
2907
+ setBlendConstant: vi11.fn(),
2908
+ setStencilReference: vi11.fn(),
2909
+ beginOcclusionQuery: vi11.fn(),
2910
+ endOcclusionQuery: vi11.fn(),
2911
+ executeBundles: vi11.fn(),
2912
+ draw: vi11.fn(),
2913
+ drawIndexed: vi11.fn(),
2914
+ drawIndirect: vi11.fn(),
2915
+ drawIndexedIndirect: vi11.fn(),
2916
+ end: vi11.fn(),
2917
+ pushDebugGroup: vi11.fn(),
2918
+ popDebugGroup: vi11.fn(),
2919
+ insertDebugMarker: vi11.fn(),
2954
2920
  label: ""
2955
2921
  };
2956
2922
  }
2957
2923
  function createMockComputePassEncoder() {
2958
2924
  return {
2959
- setPipeline: vi12.fn(),
2960
- setBindGroup: vi12.fn(),
2961
- dispatchWorkgroups: vi12.fn(),
2962
- dispatchWorkgroupsIndirect: vi12.fn(),
2963
- end: vi12.fn(),
2964
- pushDebugGroup: vi12.fn(),
2965
- popDebugGroup: vi12.fn(),
2966
- insertDebugMarker: vi12.fn(),
2925
+ setPipeline: vi11.fn(),
2926
+ setBindGroup: vi11.fn(),
2927
+ dispatchWorkgroups: vi11.fn(),
2928
+ dispatchWorkgroupsIndirect: vi11.fn(),
2929
+ end: vi11.fn(),
2930
+ pushDebugGroup: vi11.fn(),
2931
+ popDebugGroup: vi11.fn(),
2932
+ insertDebugMarker: vi11.fn(),
2967
2933
  label: ""
2968
2934
  };
2969
2935
  }
@@ -3190,67 +3156,67 @@ var createMockBufferSource = (buffer) => {
3190
3156
  };
3191
3157
 
3192
3158
  // src/engine/mocks/renderer.ts
3193
- import { vi as vi13 } from "vitest";
3159
+ import { vi as vi12 } from "vitest";
3194
3160
  function createMockRenderer(overrides) {
3195
3161
  return {
3196
3162
  width: 800,
3197
3163
  height: 600,
3198
3164
  collisionVis: {
3199
- render: vi13.fn(),
3200
- clear: vi13.fn(),
3165
+ render: vi12.fn(),
3166
+ clear: vi12.fn(),
3201
3167
  shaderSize: 0,
3202
- dispose: vi13.fn()
3168
+ dispose: vi12.fn()
3203
3169
  },
3204
3170
  debug: {
3205
- render: vi13.fn(),
3206
- clear: vi13.fn(),
3207
- drawLine: vi13.fn(),
3208
- drawBoundingBox: vi13.fn(),
3209
- drawAxes: vi13.fn(),
3210
- getLabels: vi13.fn().mockReturnValue([]),
3171
+ render: vi12.fn(),
3172
+ clear: vi12.fn(),
3173
+ drawLine: vi12.fn(),
3174
+ drawBoundingBox: vi12.fn(),
3175
+ drawAxes: vi12.fn(),
3176
+ getLabels: vi12.fn().mockReturnValue([]),
3211
3177
  shaderSize: 0,
3212
- dispose: vi13.fn()
3178
+ dispose: vi12.fn()
3213
3179
  },
3214
3180
  particleSystem: {
3215
- update: vi13.fn(),
3216
- emit: vi13.fn(),
3217
- clear: vi13.fn(),
3181
+ update: vi12.fn(),
3182
+ emit: vi12.fn(),
3183
+ clear: vi12.fn(),
3218
3184
  count: 0
3219
3185
  },
3220
- getPerformanceReport: vi13.fn().mockReturnValue({}),
3221
- getMemoryUsage: vi13.fn().mockReturnValue({}),
3222
- renderFrame: vi13.fn(),
3223
- registerPic: vi13.fn().mockResolvedValue({}),
3224
- registerTexture: vi13.fn().mockReturnValue({}),
3225
- begin2D: vi13.fn(),
3226
- end2D: vi13.fn(),
3227
- drawPic: vi13.fn(),
3228
- drawString: vi13.fn(),
3229
- drawCenterString: vi13.fn(),
3230
- drawfillRect: vi13.fn(),
3231
- setEntityHighlight: vi13.fn(),
3232
- clearEntityHighlight: vi13.fn(),
3233
- highlightSurface: vi13.fn(),
3234
- removeSurfaceHighlight: vi13.fn(),
3235
- setDebugMode: vi13.fn(),
3236
- setBrightness: vi13.fn(),
3237
- setGamma: vi13.fn(),
3238
- setFullbright: vi13.fn(),
3239
- setAmbient: vi13.fn(),
3240
- setLightStyle: vi13.fn(),
3241
- setUnderwaterWarp: vi13.fn(),
3242
- setBloom: vi13.fn(),
3243
- setBloomIntensity: vi13.fn(),
3244
- setLodBias: vi13.fn(),
3245
- setAreaPortalState: vi13.fn(),
3246
- renderInstanced: vi13.fn(),
3247
- dispose: vi13.fn(),
3186
+ getPerformanceReport: vi12.fn().mockReturnValue({}),
3187
+ getMemoryUsage: vi12.fn().mockReturnValue({}),
3188
+ renderFrame: vi12.fn(),
3189
+ registerPic: vi12.fn().mockResolvedValue({}),
3190
+ registerTexture: vi12.fn().mockReturnValue({}),
3191
+ begin2D: vi12.fn(),
3192
+ end2D: vi12.fn(),
3193
+ drawPic: vi12.fn(),
3194
+ drawString: vi12.fn(),
3195
+ drawCenterString: vi12.fn(),
3196
+ drawfillRect: vi12.fn(),
3197
+ setEntityHighlight: vi12.fn(),
3198
+ clearEntityHighlight: vi12.fn(),
3199
+ highlightSurface: vi12.fn(),
3200
+ removeSurfaceHighlight: vi12.fn(),
3201
+ setDebugMode: vi12.fn(),
3202
+ setBrightness: vi12.fn(),
3203
+ setGamma: vi12.fn(),
3204
+ setFullbright: vi12.fn(),
3205
+ setAmbient: vi12.fn(),
3206
+ setLightStyle: vi12.fn(),
3207
+ setUnderwaterWarp: vi12.fn(),
3208
+ setBloom: vi12.fn(),
3209
+ setBloomIntensity: vi12.fn(),
3210
+ setLodBias: vi12.fn(),
3211
+ setAreaPortalState: vi12.fn(),
3212
+ renderInstanced: vi12.fn(),
3213
+ dispose: vi12.fn(),
3248
3214
  ...overrides
3249
3215
  };
3250
3216
  }
3251
3217
  function createMockFrameRenderer(overrides) {
3252
3218
  return {
3253
- renderFrame: vi13.fn().mockReturnValue({
3219
+ renderFrame: vi12.fn().mockReturnValue({
3254
3220
  batches: 0,
3255
3221
  facesDrawn: 0,
3256
3222
  drawCalls: 0,
@@ -3267,15 +3233,15 @@ function createMockBspPipeline(overrides) {
3267
3233
  return {
3268
3234
  gl,
3269
3235
  program: {
3270
- use: vi13.fn(),
3271
- dispose: vi13.fn(),
3236
+ use: vi12.fn(),
3237
+ dispose: vi12.fn(),
3272
3238
  sourceSize: 0,
3273
- getUniformLocation: vi13.fn().mockReturnValue(null)
3239
+ getUniformLocation: vi12.fn().mockReturnValue(null)
3274
3240
  },
3275
3241
  shaderSize: 0,
3276
- bind: vi13.fn().mockReturnValue({}),
3277
- draw: vi13.fn(),
3278
- dispose: vi13.fn(),
3242
+ bind: vi12.fn().mockReturnValue({}),
3243
+ draw: vi12.fn(),
3244
+ dispose: vi12.fn(),
3279
3245
  ...overrides
3280
3246
  };
3281
3247
  }
@@ -3284,15 +3250,15 @@ function createMockMd2Pipeline(overrides) {
3284
3250
  return {
3285
3251
  gl,
3286
3252
  program: {
3287
- use: vi13.fn(),
3288
- dispose: vi13.fn(),
3253
+ use: vi12.fn(),
3254
+ dispose: vi12.fn(),
3289
3255
  sourceSize: 0,
3290
- getUniformLocation: vi13.fn().mockReturnValue(null)
3256
+ getUniformLocation: vi12.fn().mockReturnValue(null)
3291
3257
  },
3292
3258
  shaderSize: 0,
3293
- bind: vi13.fn(),
3294
- draw: vi13.fn(),
3295
- dispose: vi13.fn(),
3259
+ bind: vi12.fn(),
3260
+ draw: vi12.fn(),
3261
+ dispose: vi12.fn(),
3296
3262
  ...overrides
3297
3263
  };
3298
3264
  }
@@ -3301,15 +3267,15 @@ function createMockMd3Pipeline(overrides) {
3301
3267
  return {
3302
3268
  gl,
3303
3269
  program: {
3304
- use: vi13.fn(),
3305
- dispose: vi13.fn(),
3270
+ use: vi12.fn(),
3271
+ dispose: vi12.fn(),
3306
3272
  sourceSize: 0,
3307
- getUniformLocation: vi13.fn().mockReturnValue(null)
3273
+ getUniformLocation: vi12.fn().mockReturnValue(null)
3308
3274
  },
3309
3275
  shaderSize: 0,
3310
- bind: vi13.fn(),
3311
- drawSurface: vi13.fn(),
3312
- dispose: vi13.fn(),
3276
+ bind: vi12.fn(),
3277
+ drawSurface: vi12.fn(),
3278
+ dispose: vi12.fn(),
3313
3279
  ...overrides
3314
3280
  };
3315
3281
  }
@@ -3318,29 +3284,29 @@ function createMockSpritePipeline(overrides) {
3318
3284
  return {
3319
3285
  gl,
3320
3286
  program: {
3321
- use: vi13.fn(),
3322
- dispose: vi13.fn(),
3287
+ use: vi12.fn(),
3288
+ dispose: vi12.fn(),
3323
3289
  sourceSize: 0,
3324
- getUniformLocation: vi13.fn().mockReturnValue(null)
3290
+ getUniformLocation: vi12.fn().mockReturnValue(null)
3325
3291
  },
3326
3292
  shaderSize: 0,
3327
3293
  vao: {
3328
- bind: vi13.fn(),
3329
- dispose: vi13.fn(),
3330
- configureAttributes: vi13.fn()
3294
+ bind: vi12.fn(),
3295
+ dispose: vi12.fn(),
3296
+ configureAttributes: vi12.fn()
3331
3297
  },
3332
3298
  vbo: {
3333
- bind: vi13.fn(),
3334
- dispose: vi13.fn(),
3335
- upload: vi13.fn()
3299
+ bind: vi12.fn(),
3300
+ dispose: vi12.fn(),
3301
+ upload: vi12.fn()
3336
3302
  },
3337
3303
  whiteTexture: {
3338
- bind: vi13.fn(),
3339
- upload: vi13.fn()
3304
+ bind: vi12.fn(),
3305
+ upload: vi12.fn()
3340
3306
  },
3341
- begin: vi13.fn(),
3342
- draw: vi13.fn(),
3343
- drawRect: vi13.fn(),
3307
+ begin: vi12.fn(),
3308
+ draw: vi12.fn(),
3309
+ drawRect: vi12.fn(),
3344
3310
  ...overrides
3345
3311
  };
3346
3312
  }
@@ -3349,69 +3315,69 @@ function createMockSkyboxPipeline(overrides) {
3349
3315
  return {
3350
3316
  gl,
3351
3317
  program: {
3352
- use: vi13.fn(),
3353
- dispose: vi13.fn(),
3318
+ use: vi12.fn(),
3319
+ dispose: vi12.fn(),
3354
3320
  sourceSize: 0,
3355
- getUniformLocation: vi13.fn().mockReturnValue(null)
3321
+ getUniformLocation: vi12.fn().mockReturnValue(null)
3356
3322
  },
3357
3323
  vao: {
3358
- bind: vi13.fn(),
3359
- dispose: vi13.fn(),
3360
- configureAttributes: vi13.fn()
3324
+ bind: vi12.fn(),
3325
+ dispose: vi12.fn(),
3326
+ configureAttributes: vi12.fn()
3361
3327
  },
3362
3328
  vbo: {
3363
- bind: vi13.fn(),
3364
- dispose: vi13.fn(),
3365
- upload: vi13.fn()
3329
+ bind: vi12.fn(),
3330
+ dispose: vi12.fn(),
3331
+ upload: vi12.fn()
3366
3332
  },
3367
3333
  cubemap: {
3368
- bind: vi13.fn(),
3369
- dispose: vi13.fn(),
3370
- setParameters: vi13.fn(),
3371
- upload: vi13.fn()
3334
+ bind: vi12.fn(),
3335
+ dispose: vi12.fn(),
3336
+ setParameters: vi12.fn(),
3337
+ upload: vi12.fn()
3372
3338
  },
3373
3339
  shaderSize: 0,
3374
- bind: vi13.fn(),
3375
- draw: vi13.fn(),
3376
- dispose: vi13.fn(),
3340
+ bind: vi12.fn(),
3341
+ draw: vi12.fn(),
3342
+ dispose: vi12.fn(),
3377
3343
  ...overrides
3378
3344
  };
3379
3345
  }
3380
3346
 
3381
3347
  // src/engine/mocks/assets.ts
3382
- import { vi as vi14 } from "vitest";
3348
+ import { vi as vi13 } from "vitest";
3383
3349
  function createMockAssetManager(overrides) {
3384
3350
  return {
3385
3351
  textures: {
3386
- get: vi14.fn(),
3387
- set: vi14.fn(),
3388
- has: vi14.fn(),
3389
- clear: vi14.fn(),
3352
+ get: vi13.fn(),
3353
+ set: vi13.fn(),
3354
+ has: vi13.fn(),
3355
+ clear: vi13.fn(),
3390
3356
  memoryUsage: 0
3391
3357
  },
3392
3358
  audio: {
3393
- load: vi14.fn(),
3394
- get: vi14.fn(),
3395
- clearAll: vi14.fn()
3359
+ load: vi13.fn(),
3360
+ get: vi13.fn(),
3361
+ clearAll: vi13.fn()
3396
3362
  },
3397
- loadTexture: vi14.fn().mockResolvedValue({}),
3398
- registerTexture: vi14.fn(),
3399
- loadSound: vi14.fn().mockResolvedValue({}),
3400
- loadMd2Model: vi14.fn().mockResolvedValue({}),
3401
- getMd2Model: vi14.fn(),
3402
- loadMd3Model: vi14.fn().mockResolvedValue({}),
3403
- getMd3Model: vi14.fn(),
3404
- loadSprite: vi14.fn().mockResolvedValue({}),
3405
- loadMap: vi14.fn().mockResolvedValue({}),
3406
- getMap: vi14.fn(),
3407
- loadPalette: vi14.fn().mockResolvedValue(void 0),
3408
- isAssetLoaded: vi14.fn().mockReturnValue(true),
3409
- listFiles: vi14.fn().mockReturnValue([]),
3410
- resetForLevelChange: vi14.fn(),
3411
- getMemoryUsage: vi14.fn().mockReturnValue({ textures: 0, audio: 0 }),
3412
- clearCache: vi14.fn(),
3413
- preloadAssets: vi14.fn().mockResolvedValue(void 0),
3414
- queueLoad: vi14.fn().mockImplementation((path4) => Promise.resolve({})),
3363
+ loadTexture: vi13.fn().mockResolvedValue({}),
3364
+ registerTexture: vi13.fn(),
3365
+ loadSound: vi13.fn().mockResolvedValue({}),
3366
+ loadMd2Model: vi13.fn().mockResolvedValue({}),
3367
+ getMd2Model: vi13.fn(),
3368
+ loadMd3Model: vi13.fn().mockResolvedValue({}),
3369
+ getMd3Model: vi13.fn(),
3370
+ loadSprite: vi13.fn().mockResolvedValue({}),
3371
+ loadMap: vi13.fn().mockResolvedValue({}),
3372
+ getMap: vi13.fn(),
3373
+ loadPalette: vi13.fn().mockResolvedValue(void 0),
3374
+ isAssetLoaded: vi13.fn().mockReturnValue(true),
3375
+ listFiles: vi13.fn().mockReturnValue([]),
3376
+ resetForLevelChange: vi13.fn(),
3377
+ getMemoryUsage: vi13.fn().mockReturnValue({ textures: 0, audio: 0 }),
3378
+ clearCache: vi13.fn(),
3379
+ preloadAssets: vi13.fn().mockResolvedValue(void 0),
3380
+ queueLoad: vi13.fn().mockImplementation((path4) => Promise.resolve({})),
3415
3381
  ...overrides
3416
3382
  };
3417
3383
  }
@@ -3499,16 +3465,16 @@ function createMockBspMap(overrides) {
3499
3465
  }
3500
3466
 
3501
3467
  // src/engine/mocks/buffers.ts
3502
- import { vi as vi15 } from "vitest";
3468
+ import { vi as vi14 } from "vitest";
3503
3469
  import { VertexBuffer, IndexBuffer } from "@quake2ts/engine";
3504
3470
  import { ShaderProgram } from "@quake2ts/engine";
3505
3471
  function createMockVertexBuffer(data, usage) {
3506
3472
  const gl = createMockWebGL2Context();
3507
3473
  const vb = new VertexBuffer(gl, usage ?? gl.STATIC_DRAW);
3508
- vi15.spyOn(vb, "bind");
3509
- vi15.spyOn(vb, "upload");
3510
- vi15.spyOn(vb, "update");
3511
- vi15.spyOn(vb, "dispose");
3474
+ vi14.spyOn(vb, "bind");
3475
+ vi14.spyOn(vb, "upload");
3476
+ vi14.spyOn(vb, "update");
3477
+ vi14.spyOn(vb, "dispose");
3512
3478
  if (data) {
3513
3479
  vb.upload(data, usage ?? gl.STATIC_DRAW);
3514
3480
  }
@@ -3517,10 +3483,10 @@ function createMockVertexBuffer(data, usage) {
3517
3483
  function createMockIndexBuffer(data, usage) {
3518
3484
  const gl = createMockWebGL2Context();
3519
3485
  const ib = new IndexBuffer(gl, usage ?? gl.STATIC_DRAW);
3520
- vi15.spyOn(ib, "bind");
3521
- vi15.spyOn(ib, "upload");
3522
- vi15.spyOn(ib, "update");
3523
- vi15.spyOn(ib, "dispose");
3486
+ vi14.spyOn(ib, "bind");
3487
+ vi14.spyOn(ib, "upload");
3488
+ vi14.spyOn(ib, "update");
3489
+ vi14.spyOn(ib, "dispose");
3524
3490
  if (data) {
3525
3491
  ib.upload(data, usage ?? gl.STATIC_DRAW);
3526
3492
  }
@@ -3533,10 +3499,10 @@ function createMockShaderProgram(overrides) {
3533
3499
  fragment: "#version 300 es\nvoid main() {}"
3534
3500
  };
3535
3501
  const program = ShaderProgram.create(gl, dummySources);
3536
- vi15.spyOn(program, "use");
3537
- vi15.spyOn(program, "getUniformLocation");
3538
- vi15.spyOn(program, "getAttributeLocation");
3539
- vi15.spyOn(program, "dispose");
3502
+ vi14.spyOn(program, "use");
3503
+ vi14.spyOn(program, "getUniformLocation");
3504
+ vi14.spyOn(program, "getAttributeLocation");
3505
+ vi14.spyOn(program, "dispose");
3540
3506
  if (overrides) {
3541
3507
  Object.assign(program, overrides);
3542
3508
  }
@@ -3552,7 +3518,7 @@ function createMockShader(vertSource, fragSource) {
3552
3518
  }
3553
3519
 
3554
3520
  // src/engine/mocks/lighting.ts
3555
- import { vi as vi16 } from "vitest";
3521
+ import { vi as vi15 } from "vitest";
3556
3522
  import { DLight, DynamicLightManager } from "@quake2ts/engine";
3557
3523
  function createMockDLight(position = { x: 0, y: 0, z: 0 }, color = { x: 1, y: 1, z: 1 }, intensity = 300) {
3558
3524
  return {
@@ -3564,10 +3530,10 @@ function createMockDLight(position = { x: 0, y: 0, z: 0 }, color = { x: 1, y: 1,
3564
3530
  }
3565
3531
  function createMockDLightManager(overrides) {
3566
3532
  const mockManager = {
3567
- addLight: vi16.fn(),
3568
- clear: vi16.fn(),
3569
- update: vi16.fn(),
3570
- getActiveLights: vi16.fn().mockReturnValue([]),
3533
+ addLight: vi15.fn(),
3534
+ clear: vi15.fn(),
3535
+ update: vi15.fn(),
3536
+ getActiveLights: vi15.fn().mockReturnValue([]),
3571
3537
  ...overrides
3572
3538
  };
3573
3539
  return mockManager;
@@ -3582,7 +3548,7 @@ function createMockLightmap(width = 128, height = 128) {
3582
3548
  }
3583
3549
 
3584
3550
  // src/engine/mocks/particles.ts
3585
- import { vi as vi17 } from "vitest";
3551
+ import { vi as vi16 } from "vitest";
3586
3552
  import { ParticleSystem } from "@quake2ts/engine";
3587
3553
  function createMockParticle(overrides) {
3588
3554
  return {
@@ -3601,8 +3567,8 @@ function createMockParticle(overrides) {
3601
3567
  }
3602
3568
  function createMockParticleEmitter(overrides) {
3603
3569
  return {
3604
- update: vi17.fn(),
3605
- emit: vi17.fn(),
3570
+ update: vi16.fn(),
3571
+ emit: vi16.fn(),
3606
3572
  ...overrides
3607
3573
  };
3608
3574
  }
@@ -3610,35 +3576,35 @@ function createMockParticleSystem(overrides) {
3610
3576
  return {
3611
3577
  maxParticles: 1e3,
3612
3578
  rng: {
3613
- frandom: vi17.fn().mockReturnValue(0.5),
3579
+ frandom: vi16.fn().mockReturnValue(0.5),
3614
3580
  // Deterministic default
3615
- random: vi17.fn().mockReturnValue(0.5),
3616
- seed: vi17.fn()
3581
+ random: vi16.fn().mockReturnValue(0.5),
3582
+ seed: vi16.fn()
3617
3583
  },
3618
- update: vi17.fn(),
3619
- spawn: vi17.fn(),
3620
- killAll: vi17.fn(),
3621
- aliveCount: vi17.fn().mockReturnValue(0),
3622
- getState: vi17.fn(),
3623
- buildMesh: vi17.fn(),
3584
+ update: vi16.fn(),
3585
+ spawn: vi16.fn(),
3586
+ killAll: vi16.fn(),
3587
+ aliveCount: vi16.fn().mockReturnValue(0),
3588
+ getState: vi16.fn(),
3589
+ buildMesh: vi16.fn(),
3624
3590
  ...overrides
3625
3591
  };
3626
3592
  }
3627
3593
 
3628
3594
  // src/engine/rendering.ts
3629
- import { vi as vi18 } from "vitest";
3595
+ import { vi as vi17 } from "vitest";
3630
3596
  function createMockRenderingContext() {
3631
3597
  const gl = createMockWebGL2Context();
3632
3598
  const camera = {
3633
- update: vi18.fn(),
3634
- getViewMatrix: vi18.fn().mockReturnValue(new Float32Array(16)),
3635
- getProjectionMatrix: vi18.fn().mockReturnValue(new Float32Array(16)),
3636
- getViewProjectionMatrix: vi18.fn().mockReturnValue(new Float32Array(16)),
3637
- getPosition: vi18.fn().mockReturnValue([0, 0, 0]),
3638
- getForward: vi18.fn().mockReturnValue([0, 0, -1]),
3639
- getRight: vi18.fn().mockReturnValue([1, 0, 0]),
3640
- getUp: vi18.fn().mockReturnValue([0, 1, 0]),
3641
- extractFrustumPlanes: vi18.fn(),
3599
+ update: vi17.fn(),
3600
+ getViewMatrix: vi17.fn().mockReturnValue(new Float32Array(16)),
3601
+ getProjectionMatrix: vi17.fn().mockReturnValue(new Float32Array(16)),
3602
+ getViewProjectionMatrix: vi17.fn().mockReturnValue(new Float32Array(16)),
3603
+ getPosition: vi17.fn().mockReturnValue([0, 0, 0]),
3604
+ getForward: vi17.fn().mockReturnValue([0, 0, -1]),
3605
+ getRight: vi17.fn().mockReturnValue([1, 0, 0]),
3606
+ getUp: vi17.fn().mockReturnValue([0, 1, 0]),
3607
+ extractFrustumPlanes: vi17.fn(),
3642
3608
  transform: {
3643
3609
  origin: [0, 0, 0],
3644
3610
  angles: [0, 0, 0],
@@ -3646,29 +3612,29 @@ function createMockRenderingContext() {
3646
3612
  }
3647
3613
  };
3648
3614
  const md2 = {
3649
- render: vi18.fn(),
3650
- init: vi18.fn(),
3651
- resize: vi18.fn()
3615
+ render: vi17.fn(),
3616
+ init: vi17.fn(),
3617
+ resize: vi17.fn()
3652
3618
  };
3653
3619
  const bsp = {
3654
- render: vi18.fn(),
3655
- init: vi18.fn(),
3656
- resize: vi18.fn()
3620
+ render: vi17.fn(),
3621
+ init: vi17.fn(),
3622
+ resize: vi17.fn()
3657
3623
  };
3658
3624
  const sprite = {
3659
- render: vi18.fn(),
3660
- init: vi18.fn(),
3661
- resize: vi18.fn()
3625
+ render: vi17.fn(),
3626
+ init: vi17.fn(),
3627
+ resize: vi17.fn()
3662
3628
  };
3663
3629
  const poly = {
3664
- render: vi18.fn(),
3665
- init: vi18.fn(),
3666
- resize: vi18.fn()
3630
+ render: vi17.fn(),
3631
+ init: vi17.fn(),
3632
+ resize: vi17.fn()
3667
3633
  };
3668
3634
  const particle = {
3669
- render: vi18.fn(),
3670
- init: vi18.fn(),
3671
- resize: vi18.fn()
3635
+ render: vi17.fn(),
3636
+ init: vi17.fn(),
3637
+ resize: vi17.fn()
3672
3638
  };
3673
3639
  return {
3674
3640
  gl,
@@ -4133,7 +4099,7 @@ function simulateCameraMovement(camera, input, deltaTime) {
4133
4099
  }
4134
4100
 
4135
4101
  // src/client/helpers/hud.ts
4136
- import { vi as vi19 } from "vitest";
4102
+ import { vi as vi18 } from "vitest";
4137
4103
  function createMockHudState(overrides) {
4138
4104
  const defaultPs = {
4139
4105
  damageAlpha: 0,
@@ -4163,11 +4129,11 @@ function createMockHudState(overrides) {
4163
4129
  defaultStats[2] = 25;
4164
4130
  defaultStats[4] = 50;
4165
4131
  const defaultMessages = {
4166
- drawCenterPrint: vi19.fn(),
4167
- drawNotifications: vi19.fn(),
4168
- addCenterPrint: vi19.fn(),
4169
- addNotification: vi19.fn(),
4170
- clear: vi19.fn()
4132
+ drawCenterPrint: vi18.fn(),
4133
+ drawNotifications: vi18.fn(),
4134
+ addCenterPrint: vi18.fn(),
4135
+ addNotification: vi18.fn(),
4136
+ clear: vi18.fn()
4171
4137
  };
4172
4138
  return {
4173
4139
  ps: overrides?.ps ?? defaultPs,
@@ -4186,7 +4152,7 @@ function createMockHudState(overrides) {
4186
4152
  function createMockScoreboard(players = []) {
4187
4153
  return {
4188
4154
  players,
4189
- draw: vi19.fn()
4155
+ draw: vi18.fn()
4190
4156
  };
4191
4157
  }
4192
4158
  function createMockChatMessage(text, sender, timestamp = Date.now()) {
@@ -4288,12 +4254,12 @@ function createMockFogData(overrides = {}) {
4288
4254
  }
4289
4255
 
4290
4256
  // src/client/mocks/download.ts
4291
- import { vi as vi20 } from "vitest";
4257
+ import { vi as vi19 } from "vitest";
4292
4258
  function createMockDownloadManager(overrides) {
4293
4259
  return {
4294
- download: vi20.fn().mockResolvedValue(new ArrayBuffer(0)),
4295
- cancel: vi20.fn(),
4296
- getProgress: vi20.fn().mockReturnValue(0),
4260
+ download: vi19.fn().mockResolvedValue(new ArrayBuffer(0)),
4261
+ cancel: vi19.fn(),
4262
+ getProgress: vi19.fn().mockReturnValue(0),
4297
4263
  ...overrides
4298
4264
  };
4299
4265
  }
@@ -4402,20 +4368,20 @@ var createMockConnectionState = (state = "connected") => ({
4402
4368
  });
4403
4369
 
4404
4370
  // src/client/mocks/console.ts
4405
- import { vi as vi21 } from "vitest";
4371
+ import { vi as vi20 } from "vitest";
4406
4372
  function createMockConsole(overrides) {
4407
4373
  const history = [];
4408
4374
  const errors = [];
4409
4375
  const commands = {};
4410
4376
  const cvars = {};
4411
4377
  return {
4412
- print: vi21.fn((text) => {
4378
+ print: vi20.fn((text) => {
4413
4379
  history.push(text);
4414
4380
  }),
4415
- error: vi21.fn((text) => {
4381
+ error: vi20.fn((text) => {
4416
4382
  errors.push(text);
4417
4383
  }),
4418
- execute: vi21.fn((text) => {
4384
+ execute: vi20.fn((text) => {
4419
4385
  const parts = text.trim().split(/\s+/);
4420
4386
  const cmd = parts[0];
4421
4387
  const args = parts.slice(1);
@@ -4425,11 +4391,11 @@ function createMockConsole(overrides) {
4425
4391
  history.push(`Unknown command "${cmd}"`);
4426
4392
  }
4427
4393
  }),
4428
- addCommand: vi21.fn((name, handler) => {
4394
+ addCommand: vi20.fn((name, handler) => {
4429
4395
  commands[name] = handler;
4430
4396
  }),
4431
- getCvar: vi21.fn((name) => cvars[name]),
4432
- setCvar: vi21.fn((name, value) => {
4397
+ getCvar: vi20.fn((name) => cvars[name]),
4398
+ setCvar: vi20.fn((name, value) => {
4433
4399
  cvars[name] = value;
4434
4400
  }),
4435
4401
  getHistory: () => history,
@@ -4808,10 +4774,15 @@ function throttleBandwidth(bytesPerSecond) {
4808
4774
  }
4809
4775
 
4810
4776
  // src/e2e/visual.ts
4811
- import { Canvas as Canvas3, Image as Image2 } from "@napi-rs/canvas";
4777
+ import { PNG as PNG2 } from "pngjs";
4778
+ import pixelmatch2 from "pixelmatch";
4812
4779
  import fs3 from "fs/promises";
4813
4780
  import path3 from "path";
4814
4781
  async function captureGameScreenshot(page, name) {
4782
+ const canvasElement = page.locator("canvas");
4783
+ if (await canvasElement.count() > 0) {
4784
+ return await canvasElement.screenshot({ path: `${name}.png` });
4785
+ }
4815
4786
  return await page.screenshot({ path: `${name}.png` });
4816
4787
  }
4817
4788
  async function takeScreenshot(canvas, filepath) {
@@ -4828,82 +4799,43 @@ async function takeScreenshot(canvas, filepath) {
4828
4799
  await fs3.mkdir(path3.dirname(filepath), { recursive: true });
4829
4800
  await fs3.writeFile(filepath, buffer);
4830
4801
  }
4831
- async function compareScreenshot(canvas, baselinePath) {
4832
- try {
4833
- await fs3.access(baselinePath);
4834
- } catch {
4835
- console.warn(`Baseline not found at ${baselinePath}, saving current as baseline.`);
4836
- await takeScreenshot(canvas, baselinePath);
4837
- return true;
4838
- }
4839
- const baselineBuffer = await fs3.readFile(baselinePath);
4840
- const baselineImage = new Image2();
4841
- baselineImage.src = baselineBuffer;
4842
- const width = baselineImage.width;
4843
- const height = baselineImage.height;
4844
- let currentBuffer;
4845
- if ("toBuffer" in canvas && typeof canvas.toBuffer === "function") {
4846
- currentBuffer = canvas.toBuffer("image/png");
4847
- } else if ("toDataURL" in canvas) {
4848
- const dataUrl = canvas.toDataURL("image/png");
4849
- currentBuffer = Buffer.from(dataUrl.replace(/^data:image\/png;base64,/, ""), "base64");
4850
- } else {
4851
- throw new Error("Unsupported canvas type");
4852
- }
4853
- if (baselineBuffer.equals(currentBuffer)) {
4854
- return true;
4855
- }
4856
- const baselineCanvas = new Canvas3(width, height);
4857
- const ctx = baselineCanvas.getContext("2d");
4858
- ctx.drawImage(baselineImage, 0, 0);
4859
- const baselineData = ctx.getImageData(0, 0, width, height).data;
4860
- const currentImage = new Image2();
4861
- currentImage.src = currentBuffer;
4862
- if (currentImage.width !== width || currentImage.height !== height) {
4863
- console.error(`Dimension mismatch: Baseline ${width}x${height} vs Current ${currentImage.width}x${currentImage.height}`);
4864
- return false;
4865
- }
4866
- const currentCanvas = new Canvas3(width, height);
4867
- const ctx2 = currentCanvas.getContext("2d");
4868
- ctx2.drawImage(currentImage, 0, 0);
4869
- const currentData = ctx2.getImageData(0, 0, width, height).data;
4870
- let diffPixels = 0;
4871
- const totalPixels = width * height;
4872
- for (let i = 0; i < baselineData.length; i += 4) {
4873
- if (baselineData[i] !== currentData[i] || // R
4874
- baselineData[i + 1] !== currentData[i + 1] || // G
4875
- baselineData[i + 2] !== currentData[i + 2] || // B
4876
- baselineData[i + 3] !== currentData[i + 3]) {
4877
- diffPixels++;
4878
- }
4879
- }
4880
- if (diffPixels > 0) {
4881
- console.error(`Visual regression: ${diffPixels} pixels differ (${(diffPixels / totalPixels * 100).toFixed(2)}%)`);
4882
- return false;
4883
- }
4884
- return true;
4885
- }
4886
4802
  function compareScreenshots(baseline, current, threshold = 0.01) {
4887
- if (baseline.length !== current.length) {
4888
- return { diffPercentage: 1 };
4889
- }
4890
- let diffPixels = 0;
4891
- const totalPixels = baseline.length;
4892
- for (let i = 0; i < baseline.length; i++) {
4893
- if (baseline[i] !== current[i]) {
4894
- diffPixels++;
4803
+ try {
4804
+ const img1 = PNG2.sync.read(baseline);
4805
+ const img2 = PNG2.sync.read(current);
4806
+ if (img1.width !== img2.width || img1.height !== img2.height) {
4807
+ throw new Error(`Image dimensions do not match: ${img1.width}x${img1.height} vs ${img2.width}x${img2.height}`);
4895
4808
  }
4809
+ const { width, height } = img1;
4810
+ const diff = new PNG2({ width, height });
4811
+ const diffPixels = pixelmatch2(
4812
+ img1.data,
4813
+ img2.data,
4814
+ diff.data,
4815
+ width,
4816
+ height,
4817
+ { threshold }
4818
+ );
4819
+ const diffPercentage = diffPixels / (width * height);
4820
+ const isMatch = diffPixels === 0;
4821
+ return {
4822
+ diffPixels,
4823
+ diffPercentage,
4824
+ isMatch,
4825
+ diffImage: PNG2.sync.write(diff)
4826
+ };
4827
+ } catch (error) {
4828
+ console.error("Error comparing screenshots:", error);
4829
+ return {
4830
+ diffPixels: -1,
4831
+ diffPercentage: 1,
4832
+ isMatch: false
4833
+ };
4896
4834
  }
4897
- const diffPercentage = diffPixels / totalPixels;
4898
- return {
4899
- diffPercentage
4900
- };
4901
4835
  }
4902
4836
  function createVisualTestScenario(sceneName) {
4903
4837
  return {
4904
- sceneName,
4905
- setup: async () => {
4906
- }
4838
+ sceneName
4907
4839
  };
4908
4840
  }
4909
4841
  export {
@@ -4939,7 +4871,6 @@ export {
4939
4871
  captureGameState,
4940
4872
  captureTexture,
4941
4873
  compareSaveGames,
4942
- compareScreenshot,
4943
4874
  compareScreenshots,
4944
4875
  compareSnapshots,
4945
4876
  createBandwidthTestScenario,