quake2ts 0.0.568 → 0.0.570

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.
@@ -150,6 +150,13 @@ function makeBrushFromMinsMaxs(mins, maxs, contents = CONTENTS_SOLID) {
150
150
  }
151
151
 
152
152
  // src/game/factories.ts
153
+ import {
154
+ Entity,
155
+ MoveType,
156
+ Solid,
157
+ ServerFlags,
158
+ DeadFlag
159
+ } from "@quake2ts/game";
153
160
  var createPlayerStateFactory = (overrides) => ({
154
161
  pm_type: 0,
155
162
  pm_time: 0,
@@ -232,10 +239,77 @@ var createGameStateSnapshotFactory = (overrides) => ({
232
239
  pm_type: 0,
233
240
  ...overrides
234
241
  });
242
+ function createEntityFactory(overrides = {}) {
243
+ const ent = new Entity(1);
244
+ Object.assign(ent, {
245
+ classname: "info_null",
246
+ health: 0,
247
+ max_health: 0,
248
+ takedamage: false,
249
+ deadflag: DeadFlag.Alive,
250
+ solid: Solid.Not,
251
+ movetype: MoveType.None,
252
+ flags: 0,
253
+ svflags: 0,
254
+ ...overrides
255
+ });
256
+ return ent;
257
+ }
258
+ function createPlayerEntityFactory(overrides = {}) {
259
+ return createEntityFactory({
260
+ classname: "player",
261
+ health: 100,
262
+ max_health: 100,
263
+ takedamage: true,
264
+ solid: Solid.BoundingBox,
265
+ movetype: MoveType.Walk,
266
+ svflags: ServerFlags.Player,
267
+ viewheight: 22,
268
+ ...overrides
269
+ });
270
+ }
271
+ function createMonsterEntityFactory(classname, overrides = {}) {
272
+ return createEntityFactory({
273
+ classname,
274
+ health: 100,
275
+ max_health: 100,
276
+ takedamage: true,
277
+ solid: Solid.BoundingBox,
278
+ movetype: MoveType.Step,
279
+ svflags: ServerFlags.Monster,
280
+ deadflag: DeadFlag.Alive,
281
+ ...overrides
282
+ });
283
+ }
284
+ function createItemEntityFactory(classname, overrides = {}) {
285
+ return createEntityFactory({
286
+ classname,
287
+ solid: Solid.Trigger,
288
+ movetype: MoveType.Toss,
289
+ ...overrides
290
+ });
291
+ }
292
+ function createProjectileEntityFactory(classname, overrides = {}) {
293
+ return createEntityFactory({
294
+ classname,
295
+ solid: Solid.Bsp,
296
+ movetype: MoveType.FlyMissile,
297
+ svflags: ServerFlags.Projectile,
298
+ ...overrides
299
+ });
300
+ }
301
+ function createTriggerEntityFactory(classname, overrides = {}) {
302
+ return createEntityFactory({
303
+ classname,
304
+ solid: Solid.Trigger,
305
+ movetype: MoveType.None,
306
+ ...overrides
307
+ });
308
+ }
235
309
 
236
310
  // src/game/helpers.ts
237
311
  import { vi as vi2 } from "vitest";
238
- import { Entity, SpawnRegistry, ScriptHookRegistry } from "@quake2ts/game";
312
+ import { Entity as Entity2, SpawnRegistry, ScriptHookRegistry } from "@quake2ts/game";
239
313
  import { createRandomGenerator } from "@quake2ts/shared";
240
314
  import { intersects, stairTrace, ladderTrace } from "@quake2ts/shared";
241
315
  var createMockEngine = () => ({
@@ -288,7 +362,7 @@ function createTestContext(options) {
288
362
  const hooks = game.hooks;
289
363
  const entities = {
290
364
  spawn: vi2.fn(() => {
291
- const ent = new Entity(entityList.length + 1);
365
+ const ent = new Entity2(entityList.length + 1);
292
366
  entityList.push(ent);
293
367
  hooks.onEntitySpawn(ent);
294
368
  return ent;
@@ -367,7 +441,7 @@ function createTestContext(options) {
367
441
  deathmatch: false,
368
442
  coop: false,
369
443
  activeCount: entityList.length,
370
- world: entityList.find((e) => e.classname === "worldspawn") || new Entity(0)
444
+ world: entityList.find((e) => e.classname === "worldspawn") || new Entity2(0)
371
445
  // ... other EntitySystem properties would go here
372
446
  };
373
447
  return {
@@ -384,14 +458,115 @@ function createTestContext(options) {
384
458
  precacheImage: vi2.fn()
385
459
  };
386
460
  }
387
- function createSpawnContext() {
461
+ function createSpawnTestContext(mapName) {
462
+ const ctx = createTestContext();
463
+ if (mapName) {
464
+ ctx.game.spawnWorld();
465
+ }
466
+ return ctx;
467
+ }
468
+ function createCombatTestContext() {
469
+ return createTestContext();
470
+ }
471
+ function createPhysicsTestContext() {
388
472
  return createTestContext();
389
473
  }
390
474
  function createEntity() {
391
- return new Entity(1);
475
+ return new Entity2(1);
476
+ }
477
+
478
+ // src/game/mocks/ai.ts
479
+ import { vi as vi3 } from "vitest";
480
+ function createMockAI(overrides = {}) {
481
+ return {
482
+ checkAttack: vi3.fn(() => false),
483
+ findTarget: vi3.fn(() => null),
484
+ visible: vi3.fn(() => true),
485
+ infront: vi3.fn(() => true),
486
+ ...overrides
487
+ };
488
+ }
489
+ function createMockMonsterAI(overrides = {}) {
490
+ return {
491
+ stand: vi3.fn(),
492
+ walk: vi3.fn(),
493
+ run: vi3.fn(),
494
+ dodge: vi3.fn(),
495
+ attack: vi3.fn(),
496
+ melee: vi3.fn(),
497
+ sight: vi3.fn(),
498
+ idle: vi3.fn(),
499
+ ...overrides
500
+ };
501
+ }
502
+ function createMockMonsterMove(first, last, think, action) {
503
+ const frames = [];
504
+ for (let i = first; i <= last; i++) {
505
+ frames.push({
506
+ ai: action,
507
+ dist: 0,
508
+ think
509
+ });
510
+ }
511
+ return {
512
+ firstframe: first,
513
+ lastframe: last,
514
+ frames,
515
+ endfunc: null
516
+ };
517
+ }
518
+
519
+ // src/game/mocks/combat.ts
520
+ import { vi as vi4 } from "vitest";
521
+ import { DamageMod } from "@quake2ts/game";
522
+ function createMockDamageInfo(overrides = {}) {
523
+ return {
524
+ damage: 10,
525
+ mod: DamageMod.UNKNOWN,
526
+ knockback: 0,
527
+ attacker: null,
528
+ inflictor: null,
529
+ dir: null,
530
+ point: null,
531
+ ...overrides
532
+ };
533
+ }
534
+ var WEAPON_NAMES = {
535
+ "weapon_blaster": "Blaster",
536
+ "weapon_shotgun": "Shotgun",
537
+ "weapon_supershotgun": "Super Shotgun",
538
+ "weapon_machinegun": "Machinegun",
539
+ "weapon_chaingun": "Chaingun",
540
+ "weapon_grenadelauncher": "Grenade Launcher",
541
+ "weapon_rocketlauncher": "Rocket Launcher",
542
+ "weapon_hyperblaster": "HyperBlaster",
543
+ "weapon_railgun": "Railgun",
544
+ "weapon_bfg": "BFG10K"
545
+ };
546
+ function createMockWeapon(name = "Mock Weapon") {
547
+ const displayName = WEAPON_NAMES[name] || name;
548
+ return {
549
+ name: displayName,
550
+ ammoType: "bullets",
551
+ ammoUse: 1,
552
+ selection: vi4.fn(),
553
+ think: vi4.fn(),
554
+ command: vi4.fn()
555
+ };
392
556
  }
557
+ var mockMonsterAttacks = {
558
+ fireBlaster: vi4.fn(),
559
+ fireRocket: vi4.fn(),
560
+ fireGrenade: vi4.fn(),
561
+ fireHeat: vi4.fn(),
562
+ fireBullet: vi4.fn(),
563
+ fireShotgun: vi4.fn(),
564
+ fireRailgun: vi4.fn(),
565
+ fireBFG: vi4.fn()
566
+ };
393
567
 
394
568
  // src/game/mocks.ts
569
+ import { vi as vi5 } from "vitest";
395
570
  function createMockGameState(overrides) {
396
571
  return {
397
572
  levelName: "test_level",
@@ -401,9 +576,97 @@ function createMockGameState(overrides) {
401
576
  ...overrides
402
577
  };
403
578
  }
579
+ function createMockGameExports(overrides) {
580
+ return {
581
+ init: vi5.fn(),
582
+ shutdown: vi5.fn(),
583
+ spawnWorld: vi5.fn(),
584
+ frame: vi5.fn().mockReturnValue({ state: {} }),
585
+ clientConnect: vi5.fn().mockReturnValue(true),
586
+ clientBegin: vi5.fn().mockReturnValue({ index: 1, origin: { x: 0, y: 0, z: 0 } }),
587
+ clientDisconnect: vi5.fn(),
588
+ clientThink: vi5.fn(),
589
+ // clientUserInfoChanged is not in GameExports
590
+ // clientCommand is not in GameExports (it's serverCommand?) No, clientCommand might be missing from interface but present in impl or legacy.
591
+ // Checking GameExports interface in src/index.ts:
592
+ /*
593
+ clientConnect(ent: Entity | null, userInfo: string): string | true;
594
+ clientBegin(client: PlayerClient): Entity;
595
+ clientDisconnect(ent: Entity): void;
596
+ clientThink(ent: Entity, cmd: UserCommand): void;
597
+ respawn(ent: Entity): void;
598
+ ...
599
+ configstring(index: number, value: string): void;
600
+ serverCommand(cmd: string): void;
601
+ */
602
+ respawn: vi5.fn(),
603
+ entities: {
604
+ getByIndex: vi5.fn(),
605
+ forEachEntity: vi5.fn(),
606
+ findByRadius: vi5.fn(),
607
+ find: vi5.fn(),
608
+ checkAnyCollision: vi5.fn(),
609
+ trace: vi5.fn(),
610
+ pointcontents: vi5.fn(),
611
+ link: vi5.fn(),
612
+ // linkentity mapped to link in EntitySystem? No, linkentity in imports, link/unlink in System.
613
+ unlink: vi5.fn(),
614
+ spawn: vi5.fn(),
615
+ free: vi5.fn(),
616
+ activeCount: 0,
617
+ world: { classname: "worldspawn" }
618
+ },
619
+ multicast: vi5.fn(),
620
+ unicast: vi5.fn(),
621
+ configstring: vi5.fn(),
622
+ serverCommand: vi5.fn(),
623
+ sound: vi5.fn(),
624
+ soundIndex: vi5.fn(),
625
+ centerprintf: vi5.fn(),
626
+ trace: vi5.fn(),
627
+ time: 0,
628
+ deathmatch: false,
629
+ skill: 1,
630
+ rogue: false,
631
+ xatrix: false,
632
+ coop: false,
633
+ friendlyFire: false,
634
+ random: {
635
+ next: vi5.fn(),
636
+ nextFloat: vi5.fn(),
637
+ range: vi5.fn(),
638
+ crandom: vi5.fn(),
639
+ getState: vi5.fn(),
640
+ setState: vi5.fn()
641
+ },
642
+ createSave: vi5.fn(),
643
+ loadSave: vi5.fn(),
644
+ serialize: vi5.fn(),
645
+ loadState: vi5.fn(),
646
+ setGodMode: vi5.fn(),
647
+ setNoclip: vi5.fn(),
648
+ setNotarget: vi5.fn(),
649
+ giveItem: vi5.fn(),
650
+ damage: vi5.fn(),
651
+ teleport: vi5.fn(),
652
+ registerHooks: vi5.fn(),
653
+ hooks: {
654
+ onMapLoad: vi5.fn(),
655
+ onMapUnload: vi5.fn(),
656
+ onPlayerSpawn: vi5.fn(),
657
+ onPlayerDeath: vi5.fn(),
658
+ register: vi5.fn()
659
+ },
660
+ setSpectator: vi5.fn(),
661
+ registerEntitySpawn: vi5.fn(),
662
+ unregisterEntitySpawn: vi5.fn(),
663
+ getCustomEntities: vi5.fn(),
664
+ ...overrides
665
+ };
666
+ }
404
667
 
405
668
  // src/server/mocks/transport.ts
406
- import { vi as vi3 } from "vitest";
669
+ import { vi as vi6 } from "vitest";
407
670
  var MockTransport = class {
408
671
  constructor() {
409
672
  this.address = "127.0.0.1";
@@ -411,11 +674,11 @@ var MockTransport = class {
411
674
  this.sentMessages = [];
412
675
  this.receivedMessages = [];
413
676
  this.listening = false;
414
- this.listenSpy = vi3.fn().mockImplementation(async (port) => {
677
+ this.listenSpy = vi6.fn().mockImplementation(async (port) => {
415
678
  this.port = port;
416
679
  this.listening = true;
417
680
  });
418
- this.closeSpy = vi3.fn().mockImplementation(() => {
681
+ this.closeSpy = vi6.fn().mockImplementation(() => {
419
682
  this.listening = false;
420
683
  });
421
684
  }
@@ -471,11 +734,11 @@ var MockTransport = class {
471
734
  };
472
735
  function createMockUDPSocket(overrides) {
473
736
  const socket = {
474
- send: vi3.fn(),
475
- on: vi3.fn(),
476
- close: vi3.fn(),
477
- bind: vi3.fn(),
478
- address: vi3.fn().mockReturnValue({ address: "127.0.0.1", family: "IPv4", port: 0 }),
737
+ send: vi6.fn(),
738
+ on: vi6.fn(),
739
+ close: vi6.fn(),
740
+ bind: vi6.fn(),
741
+ address: vi6.fn().mockReturnValue({ address: "127.0.0.1", family: "IPv4", port: 0 }),
479
742
  ...overrides
480
743
  };
481
744
  return socket;
@@ -492,13 +755,13 @@ function createMockTransport(address = "127.0.0.1", port = 27910, overrides) {
492
755
  }
493
756
  function createMockNetDriver(overrides) {
494
757
  return {
495
- connect: vi3.fn().mockResolvedValue(void 0),
496
- disconnect: vi3.fn(),
497
- send: vi3.fn(),
498
- onMessage: vi3.fn(),
499
- onClose: vi3.fn(),
500
- onError: vi3.fn(),
501
- isConnected: vi3.fn().mockReturnValue(true),
758
+ connect: vi6.fn().mockResolvedValue(void 0),
759
+ disconnect: vi6.fn(),
760
+ send: vi6.fn(),
761
+ onMessage: vi6.fn(),
762
+ onClose: vi6.fn(),
763
+ onError: vi6.fn(),
764
+ isConnected: vi6.fn().mockReturnValue(true),
502
765
  ...overrides
503
766
  };
504
767
  }
@@ -506,7 +769,7 @@ function createMockNetDriver(overrides) {
506
769
  // src/server/mocks/state.ts
507
770
  import { ServerState, ClientState } from "@quake2ts/server";
508
771
  import { MAX_CONFIGSTRINGS, MAX_EDICTS } from "@quake2ts/shared";
509
- import { vi as vi4 } from "vitest";
772
+ import { vi as vi7 } from "vitest";
510
773
  function createMockServerState(overrides) {
511
774
  return {
512
775
  state: ServerState.Game,
@@ -548,13 +811,13 @@ function createMockServerClient(clientNum, overrides) {
548
811
  incomingSequence: 0,
549
812
  outgoingSequence: 0,
550
813
  lastReceived: 0,
551
- process: vi4.fn(),
552
- transmit: vi4.fn(),
553
- writeReliableByte: vi4.fn(),
554
- writeReliableShort: vi4.fn(),
555
- writeReliableLong: vi4.fn(),
556
- writeReliableString: vi4.fn(),
557
- writeReliableData: vi4.fn()
814
+ process: vi7.fn(),
815
+ transmit: vi7.fn(),
816
+ writeReliableByte: vi7.fn(),
817
+ writeReliableShort: vi7.fn(),
818
+ writeReliableLong: vi7.fn(),
819
+ writeReliableString: vi7.fn(),
820
+ writeReliableData: vi7.fn()
558
821
  },
559
822
  // Cast as any because NetChan might be complex to fully mock here
560
823
  userInfo: "",
@@ -596,13 +859,13 @@ function createMockServerClient(clientNum, overrides) {
596
859
  }
597
860
  function createMockServer(overrides) {
598
861
  return {
599
- start: vi4.fn().mockResolvedValue(void 0),
600
- stop: vi4.fn(),
601
- multicast: vi4.fn(),
602
- unicast: vi4.fn(),
603
- configstring: vi4.fn(),
604
- kickPlayer: vi4.fn(),
605
- changeMap: vi4.fn().mockResolvedValue(void 0),
862
+ start: vi7.fn().mockResolvedValue(void 0),
863
+ stop: vi7.fn(),
864
+ multicast: vi7.fn(),
865
+ unicast: vi7.fn(),
866
+ configstring: vi7.fn(),
867
+ kickPlayer: vi7.fn(),
868
+ changeMap: vi7.fn().mockResolvedValue(void 0),
606
869
  ...overrides
607
870
  };
608
871
  }
@@ -664,19 +927,19 @@ async function simulateHandshake(client, server) {
664
927
  }
665
928
 
666
929
  // src/server/mocks/commands.ts
667
- import { vi as vi5 } from "vitest";
930
+ import { vi as vi8 } from "vitest";
668
931
  function createMockServerConsole(overrides) {
669
932
  const outputBuffer = [];
670
933
  const commandBuffer = [];
671
934
  return {
672
- exec: vi5.fn((cmd) => {
935
+ exec: vi8.fn((cmd) => {
673
936
  commandBuffer.push(cmd);
674
937
  return `Executed: ${cmd}`;
675
938
  }),
676
- print: vi5.fn((text) => {
939
+ print: vi8.fn((text) => {
677
940
  outputBuffer.push(text);
678
941
  }),
679
- broadcast: vi5.fn((text) => {
942
+ broadcast: vi8.fn((text) => {
680
943
  outputBuffer.push(`Broadcast: ${text}`);
681
944
  }),
682
945
  commandBuffer,
@@ -689,13 +952,13 @@ function createMockRConClient(password = "") {
689
952
  connected: false,
690
953
  lastCommand: "",
691
954
  lastResponse: "",
692
- connect: vi5.fn(async (address, port, pwd) => {
955
+ connect: vi8.fn(async (address, port, pwd) => {
693
956
  return pwd === password;
694
957
  }),
695
- sendCommand: vi5.fn(async (cmd) => {
958
+ sendCommand: vi8.fn(async (cmd) => {
696
959
  return `RCON Response for: ${cmd}`;
697
960
  }),
698
- disconnect: vi5.fn()
961
+ disconnect: vi8.fn()
699
962
  };
700
963
  }
701
964
  function simulateServerCommand(server, command) {
@@ -1338,10 +1601,10 @@ function createMockImage(width, height, src) {
1338
1601
  }
1339
1602
 
1340
1603
  // src/engine/mocks/webgpu.ts
1341
- import { vi as vi6 } from "vitest";
1604
+ import { vi as vi9 } from "vitest";
1342
1605
  function createMockGPUAdapter() {
1343
1606
  return {
1344
- requestDevice: vi6.fn().mockResolvedValue(createMockGPUDevice()),
1607
+ requestDevice: vi9.fn().mockResolvedValue(createMockGPUDevice()),
1345
1608
  features: /* @__PURE__ */ new Set(),
1346
1609
  limits: {}
1347
1610
  };
@@ -1351,40 +1614,40 @@ function createMockGPUDevice() {
1351
1614
  features: /* @__PURE__ */ new Set(),
1352
1615
  limits: {},
1353
1616
  queue: {
1354
- submit: vi6.fn(),
1355
- writeBuffer: vi6.fn(),
1356
- writeTexture: vi6.fn(),
1357
- copyExternalImageToTexture: vi6.fn()
1358
- },
1359
- createCommandEncoder: vi6.fn().mockReturnValue({
1360
- beginRenderPass: vi6.fn().mockReturnValue({
1361
- setPipeline: vi6.fn(),
1362
- draw: vi6.fn(),
1363
- end: vi6.fn()
1617
+ submit: vi9.fn(),
1618
+ writeBuffer: vi9.fn(),
1619
+ writeTexture: vi9.fn(),
1620
+ copyExternalImageToTexture: vi9.fn()
1621
+ },
1622
+ createCommandEncoder: vi9.fn().mockReturnValue({
1623
+ beginRenderPass: vi9.fn().mockReturnValue({
1624
+ setPipeline: vi9.fn(),
1625
+ draw: vi9.fn(),
1626
+ end: vi9.fn()
1364
1627
  }),
1365
- finish: vi6.fn()
1628
+ finish: vi9.fn()
1366
1629
  }),
1367
- createRenderPipeline: vi6.fn(),
1368
- createShaderModule: vi6.fn(),
1369
- createBindGroup: vi6.fn(),
1370
- createBindGroupLayout: vi6.fn(),
1371
- createBuffer: vi6.fn(),
1372
- createTexture: vi6.fn(),
1373
- createSampler: vi6.fn()
1630
+ createRenderPipeline: vi9.fn(),
1631
+ createShaderModule: vi9.fn(),
1632
+ createBindGroup: vi9.fn(),
1633
+ createBindGroupLayout: vi9.fn(),
1634
+ createBuffer: vi9.fn(),
1635
+ createTexture: vi9.fn(),
1636
+ createSampler: vi9.fn()
1374
1637
  };
1375
1638
  }
1376
1639
  function createMockGPUCanvasContext() {
1377
1640
  return {
1378
- configure: vi6.fn(),
1379
- unconfigure: vi6.fn(),
1380
- getCurrentTexture: vi6.fn()
1641
+ configure: vi9.fn(),
1642
+ unconfigure: vi9.fn(),
1643
+ getCurrentTexture: vi9.fn()
1381
1644
  };
1382
1645
  }
1383
1646
  function setupWebGPUMocks() {
1384
1647
  const mockAdapter = createMockGPUAdapter();
1385
1648
  const mockGpu = {
1386
- requestAdapter: vi6.fn().mockResolvedValue(mockAdapter),
1387
- getPreferredCanvasFormat: vi6.fn().mockReturnValue("bgra8unorm")
1649
+ requestAdapter: vi9.fn().mockResolvedValue(mockAdapter),
1650
+ getPreferredCanvasFormat: vi9.fn().mockReturnValue("bgra8unorm")
1388
1651
  };
1389
1652
  Object.defineProperty(global.navigator, "gpu", {
1390
1653
  value: mockGpu,
@@ -2000,27 +2263,35 @@ export {
2000
2263
  compareScreenshots,
2001
2264
  createBinaryStreamMock,
2002
2265
  createBinaryWriterMock,
2266
+ createCombatTestContext,
2003
2267
  createControlledTimer,
2004
2268
  createCustomNetworkCondition,
2005
2269
  createDeltaSnapshot,
2006
2270
  createEntity,
2271
+ createEntityFactory,
2007
2272
  createEntityStateFactory,
2008
2273
  createGameStateSnapshotFactory,
2274
+ createItemEntityFactory,
2275
+ createMockAI,
2009
2276
  createMockAudioContext,
2010
2277
  createMockCanvas,
2011
2278
  createMockCanvasContext2D,
2012
2279
  createMockConnection,
2280
+ createMockDamageInfo,
2013
2281
  createMockEngine,
2014
2282
  createMockGPUAdapter,
2015
2283
  createMockGPUCanvasContext,
2016
2284
  createMockGPUDevice,
2017
2285
  createMockGame,
2286
+ createMockGameExports,
2018
2287
  createMockGameState,
2019
2288
  createMockHandshake,
2020
2289
  createMockImage,
2021
2290
  createMockImageData,
2022
2291
  createMockIndexedDB,
2023
2292
  createMockLocalStorage,
2293
+ createMockMonsterAI,
2294
+ createMockMonsterMove,
2024
2295
  createMockNetDriver,
2025
2296
  createMockNetworkAddress,
2026
2297
  createMockPerformance,
@@ -2035,15 +2306,21 @@ export {
2035
2306
  createMockTransport,
2036
2307
  createMockUDPSocket,
2037
2308
  createMockUserInfo,
2309
+ createMockWeapon,
2038
2310
  createMockWebGL2Context,
2311
+ createMonsterEntityFactory,
2039
2312
  createMultiplayerTestScenario,
2040
2313
  createNetChanMock,
2314
+ createPhysicsTestContext,
2315
+ createPlayerEntityFactory,
2041
2316
  createPlayerStateFactory,
2042
2317
  createPlaywrightTestClient,
2318
+ createProjectileEntityFactory,
2043
2319
  createServerSnapshot,
2044
- createSpawnContext,
2320
+ createSpawnTestContext,
2045
2321
  createStorageTestScenario,
2046
2322
  createTestContext,
2323
+ createTriggerEntityFactory,
2047
2324
  createVisualTestScenario,
2048
2325
  intersects,
2049
2326
  ladderTrace,
@@ -2054,6 +2331,7 @@ export {
2054
2331
  makeLeafModel,
2055
2332
  makeNode,
2056
2333
  makePlane,
2334
+ mockMonsterAttacks,
2057
2335
  serializeUserInfo,
2058
2336
  setupBrowserEnvironment,
2059
2337
  setupMockAudioContext,