quake2ts 0.0.621 → 0.0.630

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.
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  HandshakeStage: () => HandshakeStage,
43
43
  InputInjector: () => InputInjector,
44
44
  MockAudioBufferSourceNode: () => FakeBufferSource,
45
+ MockClientConfigStrings: () => MockClientConfigStrings,
45
46
  MockNetDriver: () => MockNetDriver,
46
47
  MockNetworkTransport: () => MockNetworkTransport,
47
48
  MockPointerLock: () => MockPointerLock,
@@ -58,6 +59,7 @@ __export(index_exports, {
58
59
  createBinaryWriterMock: () => createBinaryWriterMock,
59
60
  createBounds: () => createBounds,
60
61
  createCombatTestContext: () => createCombatTestContext,
62
+ createComputeTestSetup: () => createComputeTestSetup,
61
63
  createConfigStringArrayMock: () => createConfigStringArrayMock,
62
64
  createConfigStringMock: () => createConfigStringMock,
63
65
  createControlledTimer: () => createControlledTimer,
@@ -68,33 +70,49 @@ __export(index_exports, {
68
70
  createEntityFactory: () => createEntityFactory,
69
71
  createEntityStateFactory: () => createEntityStateFactory,
70
72
  createGameStateSnapshotFactory: () => createGameStateSnapshotFactory,
73
+ createHeadlessTestContext: () => createHeadlessTestContext,
71
74
  createInputInjector: () => createInputInjector,
75
+ createInterpolationTestData: () => createInterpolationTestData,
72
76
  createItemEntityFactory: () => createItemEntityFactory,
73
77
  createMessageReaderMock: () => createMessageReaderMock,
74
78
  createMessageWriterMock: () => createMessageWriterMock,
75
79
  createMockAI: () => createMockAI,
76
80
  createMockAmmoItem: () => createMockAmmoItem,
77
81
  createMockArmorItem: () => createMockArmorItem,
82
+ createMockAssetManager: () => createMockAssetManager,
78
83
  createMockAudioBuffer: () => createMockAudioBuffer,
79
84
  createMockAudioContext: () => createMockAudioContext,
85
+ createMockBspMap: () => createMockBspMap,
80
86
  createMockBspPipeline: () => createMockBspPipeline,
81
87
  createMockBufferSource: () => createMockBufferSource,
82
88
  createMockCamera: () => createMockCamera,
83
89
  createMockCanvas: () => createMockCanvas,
84
90
  createMockCanvasContext2D: () => createMockCanvasContext2D,
85
91
  createMockChatMessage: () => createMockChatMessage,
92
+ createMockClientInfo: () => createMockClientInfo,
93
+ createMockClientState: () => createMockClientState,
86
94
  createMockCollisionEntityIndex: () => createMockCollisionEntityIndex,
95
+ createMockCommand: () => createMockCommand,
96
+ createMockCommandEncoder: () => createMockCommandEncoder,
97
+ createMockComputePassEncoder: () => createMockComputePassEncoder,
98
+ createMockComputePipeline: () => createMockComputePipeline,
87
99
  createMockConnection: () => createMockConnection,
100
+ createMockConnectionState: () => createMockConnectionState,
101
+ createMockConsole: () => createMockConsole,
102
+ createMockCvarRegistry: () => createMockCvarRegistry,
88
103
  createMockDamageIndicator: () => createMockDamageIndicator,
89
104
  createMockDamageInfo: () => createMockDamageInfo,
90
105
  createMockDeltaFrame: () => createMockDeltaFrame,
106
+ createMockDownloadManager: () => createMockDownloadManager,
91
107
  createMockEngine: () => createMockEngine,
92
108
  createMockEntityState: () => createMockEntityState,
93
109
  createMockFogData: () => createMockFogData,
110
+ createMockFrame: () => createMockFrame,
94
111
  createMockFrameRenderer: () => createMockFrameRenderer,
95
112
  createMockGPUAdapter: () => createMockGPUAdapter,
96
- createMockGPUCanvasContext: () => createMockGPUCanvasContext,
113
+ createMockGPUBuffer: () => createMockGPUBuffer,
97
114
  createMockGPUDevice: () => createMockGPUDevice,
115
+ createMockGPUTexture: () => createMockGPUTexture,
98
116
  createMockGame: () => createMockGame,
99
117
  createMockGameExports: () => createMockGameExports,
100
118
  createMockGameState: () => createMockGameState,
@@ -109,7 +127,9 @@ __export(index_exports, {
109
127
  createMockKeyboardEvent: () => createMockKeyboardEvent,
110
128
  createMockLocalStorage: () => createMockLocalStorage,
111
129
  createMockMasterServer: () => createMockMasterServer,
130
+ createMockMd2Model: () => createMockMd2Model,
112
131
  createMockMd2Pipeline: () => createMockMd2Pipeline,
132
+ createMockMd3Model: () => createMockMd3Model,
113
133
  createMockMd3Pipeline: () => createMockMd3Pipeline,
114
134
  createMockMonsterAI: () => createMockMonsterAI,
115
135
  createMockMonsterMove: () => createMockMonsterMove,
@@ -121,12 +141,17 @@ __export(index_exports, {
121
141
  createMockPerformance: () => createMockPerformance,
122
142
  createMockPointerLock: () => createMockPointerLock,
123
143
  createMockPowerupItem: () => createMockPowerupItem,
144
+ createMockPrecacheList: () => createMockPrecacheList,
145
+ createMockQueue: () => createMockQueue,
124
146
  createMockRAF: () => createMockRAF,
125
147
  createMockRConClient: () => createMockRConClient,
126
148
  createMockRateLimiter: () => createMockRateLimiter,
127
149
  createMockRefDef: () => createMockRefDef,
150
+ createMockRenderPassEncoder: () => createMockRenderPassEncoder,
151
+ createMockRenderPipeline: () => createMockRenderPipeline,
128
152
  createMockRenderer: () => createMockRenderer,
129
153
  createMockRenderingContext: () => createMockRenderingContext,
154
+ createMockSampler: () => createMockSampler,
130
155
  createMockScoreboard: () => createMockScoreboard,
131
156
  createMockServer: () => createMockServer,
132
157
  createMockServerClient: () => createMockServerClient,
@@ -136,9 +161,12 @@ __export(index_exports, {
136
161
  createMockServerState: () => createMockServerState,
137
162
  createMockServerStatic: () => createMockServerStatic,
138
163
  createMockSessionStorage: () => createMockSessionStorage,
164
+ createMockShaderModule: () => createMockShaderModule,
139
165
  createMockSkyboxPipeline: () => createMockSkyboxPipeline,
140
166
  createMockSnapshot: () => createMockSnapshot,
141
167
  createMockSpritePipeline: () => createMockSpritePipeline,
168
+ createMockTexture: () => createMockTexture,
169
+ createMockTextureView: () => createMockTextureView,
142
170
  createMockTransport: () => createMockTransport,
143
171
  createMockUDPSocket: () => createMockUDPSocket,
144
172
  createMockUserInfo: () => createMockUserInfo,
@@ -146,6 +174,7 @@ __export(index_exports, {
146
174
  createMockWeapon: () => createMockWeapon,
147
175
  createMockWeaponItem: () => createMockWeaponItem,
148
176
  createMockWebGL2Context: () => createMockWebGL2Context,
177
+ createMockWebGPUContext: () => createMockWebGPUContext,
149
178
  createMockWheelEvent: () => createMockWheelEvent,
150
179
  createMonsterEntityFactory: () => createMonsterEntityFactory,
151
180
  createMultiplayerTestScenario: () => createMultiplayerTestScenario,
@@ -156,7 +185,9 @@ __export(index_exports, {
156
185
  createPlayerEntityFactory: () => createPlayerEntityFactory,
157
186
  createPlayerStateFactory: () => createPlayerStateFactory,
158
187
  createPlaywrightTestClient: () => createPlaywrightTestClient,
188
+ createPredictionTestScenario: () => createPredictionTestScenario,
159
189
  createProjectileEntityFactory: () => createProjectileEntityFactory,
190
+ createRenderTestSetup: () => createRenderTestSetup,
160
191
  createServerSnapshot: () => createServerSnapshot,
161
192
  createSpawnTestContext: () => createSpawnTestContext,
162
193
  createStorageTestScenario: () => createStorageTestScenario,
@@ -168,6 +199,7 @@ __export(index_exports, {
168
199
  createVector3: () => createVector3,
169
200
  createViewTestScenario: () => createViewTestScenario,
170
201
  createVisualTestScenario: () => createVisualTestScenario,
202
+ initHeadlessWebGPU: () => initHeadlessWebGPU,
171
203
  intersects: () => import_shared2.intersects,
172
204
  ladderTrace: () => import_shared2.ladderTrace,
173
205
  makeAxisBrush: () => makeAxisBrush,
@@ -180,6 +212,8 @@ __export(index_exports, {
180
212
  measureSnapshotSize: () => measureSnapshotSize,
181
213
  mockMonsterAttacks: () => mockMonsterAttacks,
182
214
  randomVector3: () => randomVector3,
215
+ renderAndCapture: () => renderAndCapture,
216
+ runComputeAndReadback: () => runComputeAndReadback,
183
217
  serializeUserInfo: () => serializeUserInfo,
184
218
  setupBrowserEnvironment: () => setupBrowserEnvironment,
185
219
  setupMockAudioContext: () => setupMockAudioContext,
@@ -187,6 +221,8 @@ __export(index_exports, {
187
221
  setupWebGPUMocks: () => setupWebGPUMocks,
188
222
  simulateBandwidthLimit: () => simulateBandwidthLimit,
189
223
  simulateCameraMovement: () => simulateCameraMovement,
224
+ simulateClientPrediction: () => simulateClientPrediction,
225
+ simulateDownload: () => simulateDownload,
190
226
  simulateFrames: () => simulateFrames,
191
227
  simulateGravity: () => simulateGravity,
192
228
  simulateHandshake: () => simulateHandshake,
@@ -207,7 +243,10 @@ __export(index_exports, {
207
243
  teardownBrowserEnvironment: () => teardownBrowserEnvironment,
208
244
  teardownMockAudioContext: () => teardownMockAudioContext,
209
245
  teardownNodeEnvironment: () => teardownNodeEnvironment,
246
+ testComputeShader: () => testComputeShader,
247
+ testPipelineRendering: () => testPipelineRendering,
210
248
  throttleBandwidth: () => throttleBandwidth,
249
+ verifySmoothing: () => verifySmoothing,
211
250
  verifySnapshotConsistency: () => verifySnapshotConsistency,
212
251
  waitForGameReady: () => waitForGameReady
213
252
  });
@@ -663,6 +702,7 @@ function createTestContext(options) {
663
702
  const entities = {
664
703
  spawn: import_vitest2.vi.fn(() => {
665
704
  const ent = new import_game2.Entity(entityList.length + 1);
705
+ ent.inUse = true;
666
706
  entityList.push(ent);
667
707
  hooks.onEntitySpawn(ent);
668
708
  return ent;
@@ -672,6 +712,7 @@ function createTestContext(options) {
672
712
  if (idx !== -1) {
673
713
  entityList.splice(idx, 1);
674
714
  }
715
+ ent.inUse = false;
675
716
  hooks.onEntityRemove(ent);
676
717
  }),
677
718
  finalizeSpawn: import_vitest2.vi.fn(),
@@ -680,6 +721,7 @@ function createTestContext(options) {
680
721
  if (idx !== -1) {
681
722
  entityList.splice(idx, 1);
682
723
  }
724
+ ent.inUse = false;
683
725
  }),
684
726
  setSpawnRegistry: import_vitest2.vi.fn(),
685
727
  timeSeconds: 10,
@@ -2506,99 +2548,281 @@ function createMockImage(width = 100, height = 100, src = "") {
2506
2548
  return img;
2507
2549
  }
2508
2550
 
2509
- // src/engine/mocks/webgpu.ts
2510
- var import_vitest12 = require("vitest");
2511
- function createMockGPUAdapter() {
2512
- return {
2513
- features: /* @__PURE__ */ new Set(),
2514
- limits: {
2515
- maxTextureDimension2D: 8192,
2516
- maxBindGroups: 4,
2517
- maxUniformBufferBindingSize: 65536,
2518
- maxStorageBufferBindingSize: 134217728
2519
- },
2520
- requestDevice: import_vitest12.vi.fn().mockResolvedValue(createMockGPUDevice())
2521
- };
2522
- }
2523
- function createMockGPUDevice() {
2551
+ // ../../node_modules/.pnpm/webgpu@0.3.8/node_modules/webgpu/index.js
2552
+ var import_node_path = require("path");
2553
+ var import_node_url = require("url");
2554
+ var import_module = require("module");
2555
+ var import_meta = {};
2556
+ var require2 = (0, import_module.createRequire)(import_meta.url);
2557
+ var isMac = process.platform === "darwin";
2558
+ var __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
2559
+ var arch = isMac ? "universal" : process.arch;
2560
+ var dawnNodePath = (0, import_node_path.join)(__dirname, "dist", `${process.platform}-${arch}.dawn.node`);
2561
+ var { create, globals } = require2(dawnNodePath);
2562
+
2563
+ // src/setup/webgpu.ts
2564
+ async function initHeadlessWebGPU(options) {
2565
+ if (typeof process === "undefined" || process.release?.name !== "node") {
2566
+ throw new Error("initHeadlessWebGPU should only be called in a Node.js environment");
2567
+ }
2568
+ if (!globalThis.navigator) {
2569
+ globalThis.navigator = {};
2570
+ }
2571
+ if (!globalThis.navigator.gpu) {
2572
+ const gpu = create([]);
2573
+ try {
2574
+ Object.defineProperty(globalThis.navigator, "gpu", {
2575
+ value: gpu,
2576
+ writable: true,
2577
+ configurable: true
2578
+ });
2579
+ } catch (e) {
2580
+ console.warn("Could not define navigator.gpu, trying direct assignment");
2581
+ globalThis.navigator.gpu = gpu;
2582
+ }
2583
+ Object.assign(globalThis, globals);
2584
+ }
2585
+ const adapter = await navigator.gpu.requestAdapter({
2586
+ powerPreference: options?.powerPreference || "high-performance"
2587
+ });
2588
+ if (!adapter) {
2589
+ throw new Error("Failed to create WebGPU adapter");
2590
+ }
2591
+ const device = await adapter.requestDevice({
2592
+ requiredFeatures: options?.requiredFeatures || []
2593
+ });
2594
+ if (!device) {
2595
+ throw new Error("Failed to create WebGPU device");
2596
+ }
2524
2597
  return {
2525
- features: /* @__PURE__ */ new Set(),
2526
- limits: {
2527
- maxTextureDimension2D: 8192
2528
- },
2529
- lost: new Promise(() => {
2530
- }),
2531
- // Pending promise
2532
- createShaderModule: import_vitest12.vi.fn(),
2533
- createBindGroupLayout: import_vitest12.vi.fn(),
2534
- createPipelineLayout: import_vitest12.vi.fn(),
2535
- createRenderPipeline: import_vitest12.vi.fn(),
2536
- createCommandEncoder: import_vitest12.vi.fn().mockReturnValue({
2537
- copyTextureToBuffer: import_vitest12.vi.fn(),
2538
- finish: import_vitest12.vi.fn()
2539
- }),
2540
- createBuffer: import_vitest12.vi.fn(),
2541
- createTexture: import_vitest12.vi.fn().mockReturnValue({
2542
- createView: import_vitest12.vi.fn()
2543
- }),
2544
- queue: {
2545
- submit: import_vitest12.vi.fn(),
2546
- writeBuffer: import_vitest12.vi.fn(),
2547
- writeTexture: import_vitest12.vi.fn()
2598
+ adapter,
2599
+ device,
2600
+ cleanup: async () => {
2601
+ device.destroy();
2548
2602
  }
2549
2603
  };
2550
2604
  }
2551
- function createMockGPUCanvasContext() {
2605
+ async function createHeadlessTestContext() {
2606
+ const { adapter, device } = await initHeadlessWebGPU();
2552
2607
  return {
2553
- configure: import_vitest12.vi.fn(),
2554
- getCurrentTexture: import_vitest12.vi.fn()
2608
+ adapter,
2609
+ device,
2610
+ queue: device.queue
2555
2611
  };
2556
2612
  }
2613
+
2614
+ // src/engine/mocks/webgpu.ts
2615
+ var import_vitest12 = require("vitest");
2557
2616
  function setupWebGPUMocks() {
2558
- const mockAdapter = createMockGPUAdapter();
2617
+ Object.assign(globalThis, globals);
2559
2618
  const mockGpu = {
2560
- requestAdapter: import_vitest12.vi.fn().mockResolvedValue(mockAdapter),
2619
+ requestAdapter: import_vitest12.vi.fn(),
2561
2620
  getPreferredCanvasFormat: import_vitest12.vi.fn().mockReturnValue("bgra8unorm")
2562
2621
  };
2563
- Object.defineProperty(global, "navigator", {
2564
- value: {
2565
- ...global.navigator,
2566
- gpu: mockGpu
2567
- },
2568
- writable: true
2569
- });
2570
- if (typeof GPUTextureUsage === "undefined") {
2571
- global.GPUTextureUsage = {
2572
- COPY_SRC: 1,
2573
- COPY_DST: 2,
2574
- TEXTURE_BINDING: 4,
2575
- STORAGE_BINDING: 8,
2576
- RENDER_ATTACHMENT: 16
2577
- };
2578
- }
2579
- if (typeof GPUBufferUsage === "undefined") {
2580
- global.GPUBufferUsage = {
2581
- MAP_READ: 1,
2582
- MAP_WRITE: 2,
2583
- COPY_SRC: 4,
2584
- COPY_DST: 8,
2585
- INDEX: 16,
2586
- VERTEX: 32,
2587
- UNIFORM: 64,
2588
- STORAGE: 128,
2589
- INDIRECT: 256,
2590
- QUERY_RESOLVE: 512
2591
- };
2622
+ const mockAdapter = createMockGPUAdapter();
2623
+ const mockDevice = createMockGPUDevice();
2624
+ mockGpu.requestAdapter.mockResolvedValue(mockAdapter);
2625
+ mockAdapter.requestDevice.mockResolvedValue(mockDevice);
2626
+ if (!globalThis.navigator) {
2627
+ globalThis.navigator = {};
2592
2628
  }
2593
- if (typeof GPUMapMode === "undefined") {
2594
- global.GPUMapMode = {
2595
- READ: 1,
2596
- WRITE: 2
2597
- };
2629
+ try {
2630
+ Object.defineProperty(globalThis.navigator, "gpu", {
2631
+ value: mockGpu,
2632
+ writable: true,
2633
+ configurable: true
2634
+ });
2635
+ } catch (e) {
2636
+ globalThis.navigator.gpu = mockGpu;
2598
2637
  }
2599
2638
  return {
2600
2639
  mockGpu,
2601
- mockAdapter
2640
+ mockAdapter,
2641
+ mockDevice
2642
+ };
2643
+ }
2644
+ function createMockGPUAdapter(options = {}) {
2645
+ return {
2646
+ features: /* @__PURE__ */ new Set(),
2647
+ limits: {},
2648
+ isFallbackAdapter: false,
2649
+ requestDevice: import_vitest12.vi.fn().mockResolvedValue(createMockGPUDevice()),
2650
+ requestAdapterInfo: import_vitest12.vi.fn().mockResolvedValue({}),
2651
+ ...options
2652
+ };
2653
+ }
2654
+ function createMockGPUDevice(features = /* @__PURE__ */ new Set()) {
2655
+ const queue = createMockQueue();
2656
+ return {
2657
+ features,
2658
+ limits: {},
2659
+ queue,
2660
+ destroy: import_vitest12.vi.fn(),
2661
+ createBuffer: import_vitest12.vi.fn((descriptor) => createMockGPUBuffer(descriptor)),
2662
+ createTexture: import_vitest12.vi.fn((descriptor) => createMockGPUTexture(descriptor)),
2663
+ createSampler: import_vitest12.vi.fn(() => createMockSampler()),
2664
+ createBindGroupLayout: import_vitest12.vi.fn(() => ({ label: "mock-bind-group-layout" })),
2665
+ createPipelineLayout: import_vitest12.vi.fn(() => ({ label: "mock-pipeline-layout" })),
2666
+ createBindGroup: import_vitest12.vi.fn(() => ({ label: "mock-bind-group" })),
2667
+ createShaderModule: import_vitest12.vi.fn((descriptor) => createMockShaderModule(descriptor)),
2668
+ createComputePipeline: import_vitest12.vi.fn(() => createMockComputePipeline()),
2669
+ createRenderPipeline: import_vitest12.vi.fn(() => createMockRenderPipeline()),
2670
+ createComputePipelineAsync: import_vitest12.vi.fn().mockResolvedValue(createMockComputePipeline()),
2671
+ createRenderPipelineAsync: import_vitest12.vi.fn().mockResolvedValue(createMockRenderPipeline()),
2672
+ createCommandEncoder: import_vitest12.vi.fn(() => createMockCommandEncoder()),
2673
+ createQuerySet: import_vitest12.vi.fn(() => ({ label: "mock-query-set" })),
2674
+ pushErrorScope: import_vitest12.vi.fn(),
2675
+ popErrorScope: import_vitest12.vi.fn().mockResolvedValue(null),
2676
+ addEventListener: import_vitest12.vi.fn(),
2677
+ removeEventListener: import_vitest12.vi.fn(),
2678
+ dispatchEvent: import_vitest12.vi.fn(),
2679
+ onuncapturederror: null,
2680
+ label: "",
2681
+ lost: Promise.resolve({ reason: "destroyed", message: "Device lost" })
2682
+ };
2683
+ }
2684
+ function createMockQueue() {
2685
+ return {
2686
+ submit: import_vitest12.vi.fn(),
2687
+ onSubmittedWorkDone: import_vitest12.vi.fn().mockResolvedValue(void 0),
2688
+ writeBuffer: import_vitest12.vi.fn(),
2689
+ writeTexture: import_vitest12.vi.fn(),
2690
+ copyExternalImageToTexture: import_vitest12.vi.fn(),
2691
+ label: ""
2692
+ };
2693
+ }
2694
+ function createMockGPUBuffer(descriptor) {
2695
+ return {
2696
+ size: descriptor.size,
2697
+ usage: descriptor.usage,
2698
+ mapState: "unmapped",
2699
+ mapAsync: import_vitest12.vi.fn().mockResolvedValue(void 0),
2700
+ getMappedRange: import_vitest12.vi.fn(() => new ArrayBuffer(descriptor.size)),
2701
+ unmap: import_vitest12.vi.fn(),
2702
+ destroy: import_vitest12.vi.fn(),
2703
+ label: descriptor.label || ""
2704
+ };
2705
+ }
2706
+ function createMockGPUTexture(descriptor) {
2707
+ const size = descriptor.size;
2708
+ let width = 0;
2709
+ let height = 0;
2710
+ let depthOrArrayLayers = 1;
2711
+ if (Array.isArray(size) || size instanceof Float32Array || size instanceof Uint32Array) {
2712
+ const arr = Array.from(size);
2713
+ width = arr[0] || 0;
2714
+ height = arr[1] || 1;
2715
+ depthOrArrayLayers = arr[2] || 1;
2716
+ } else if (typeof size === "object") {
2717
+ const dict = size;
2718
+ width = dict.width;
2719
+ height = dict.height || 1;
2720
+ depthOrArrayLayers = dict.depthOrArrayLayers || 1;
2721
+ }
2722
+ return {
2723
+ width,
2724
+ height,
2725
+ depthOrArrayLayers,
2726
+ mipLevelCount: descriptor.mipLevelCount || 1,
2727
+ sampleCount: descriptor.sampleCount || 1,
2728
+ dimension: descriptor.dimension || "2d",
2729
+ format: descriptor.format,
2730
+ usage: descriptor.usage,
2731
+ createView: import_vitest12.vi.fn(() => createMockTextureView()),
2732
+ destroy: import_vitest12.vi.fn(),
2733
+ label: descriptor.label || ""
2734
+ };
2735
+ }
2736
+ function createMockTextureView() {
2737
+ return {
2738
+ label: ""
2739
+ };
2740
+ }
2741
+ function createMockSampler() {
2742
+ return {
2743
+ label: ""
2744
+ };
2745
+ }
2746
+ function createMockShaderModule(descriptor) {
2747
+ return {
2748
+ getCompilationInfo: import_vitest12.vi.fn().mockResolvedValue({ messages: [] }),
2749
+ label: descriptor.label || ""
2750
+ };
2751
+ }
2752
+ function createMockComputePipeline() {
2753
+ return {
2754
+ getBindGroupLayout: import_vitest12.vi.fn(() => ({ label: "mock-bind-group-layout" })),
2755
+ label: ""
2756
+ };
2757
+ }
2758
+ function createMockRenderPipeline() {
2759
+ return {
2760
+ getBindGroupLayout: import_vitest12.vi.fn(() => ({ label: "mock-bind-group-layout" })),
2761
+ label: ""
2762
+ };
2763
+ }
2764
+ function createMockCommandEncoder() {
2765
+ return {
2766
+ beginRenderPass: import_vitest12.vi.fn(() => createMockRenderPassEncoder()),
2767
+ beginComputePass: import_vitest12.vi.fn(() => createMockComputePassEncoder()),
2768
+ copyBufferToBuffer: import_vitest12.vi.fn(),
2769
+ copyBufferToTexture: import_vitest12.vi.fn(),
2770
+ copyTextureToBuffer: import_vitest12.vi.fn(),
2771
+ copyTextureToTexture: import_vitest12.vi.fn(),
2772
+ clearBuffer: import_vitest12.vi.fn(),
2773
+ writeTimestamp: import_vitest12.vi.fn(),
2774
+ resolveQuerySet: import_vitest12.vi.fn(),
2775
+ finish: import_vitest12.vi.fn(() => ({ label: "mock-command-buffer" })),
2776
+ pushDebugGroup: import_vitest12.vi.fn(),
2777
+ popDebugGroup: import_vitest12.vi.fn(),
2778
+ insertDebugMarker: import_vitest12.vi.fn(),
2779
+ label: ""
2780
+ };
2781
+ }
2782
+ function createMockRenderPassEncoder() {
2783
+ return {
2784
+ setPipeline: import_vitest12.vi.fn(),
2785
+ setIndexBuffer: import_vitest12.vi.fn(),
2786
+ setVertexBuffer: import_vitest12.vi.fn(),
2787
+ setBindGroup: import_vitest12.vi.fn(),
2788
+ setViewport: import_vitest12.vi.fn(),
2789
+ setScissorRect: import_vitest12.vi.fn(),
2790
+ setBlendConstant: import_vitest12.vi.fn(),
2791
+ setStencilReference: import_vitest12.vi.fn(),
2792
+ beginOcclusionQuery: import_vitest12.vi.fn(),
2793
+ endOcclusionQuery: import_vitest12.vi.fn(),
2794
+ executeBundles: import_vitest12.vi.fn(),
2795
+ draw: import_vitest12.vi.fn(),
2796
+ drawIndexed: import_vitest12.vi.fn(),
2797
+ drawIndirect: import_vitest12.vi.fn(),
2798
+ drawIndexedIndirect: import_vitest12.vi.fn(),
2799
+ end: import_vitest12.vi.fn(),
2800
+ pushDebugGroup: import_vitest12.vi.fn(),
2801
+ popDebugGroup: import_vitest12.vi.fn(),
2802
+ insertDebugMarker: import_vitest12.vi.fn(),
2803
+ label: ""
2804
+ };
2805
+ }
2806
+ function createMockComputePassEncoder() {
2807
+ return {
2808
+ setPipeline: import_vitest12.vi.fn(),
2809
+ setBindGroup: import_vitest12.vi.fn(),
2810
+ dispatchWorkgroups: import_vitest12.vi.fn(),
2811
+ dispatchWorkgroupsIndirect: import_vitest12.vi.fn(),
2812
+ end: import_vitest12.vi.fn(),
2813
+ pushDebugGroup: import_vitest12.vi.fn(),
2814
+ popDebugGroup: import_vitest12.vi.fn(),
2815
+ insertDebugMarker: import_vitest12.vi.fn(),
2816
+ label: ""
2817
+ };
2818
+ }
2819
+ function createMockWebGPUContext() {
2820
+ const adapter = createMockGPUAdapter();
2821
+ const device = createMockGPUDevice();
2822
+ return {
2823
+ adapter,
2824
+ device,
2825
+ queue: device.queue
2602
2826
  };
2603
2827
  }
2604
2828
 
@@ -3002,20 +3226,140 @@ function createMockSkyboxPipeline(overrides) {
3002
3226
  };
3003
3227
  }
3004
3228
 
3005
- // src/engine/rendering.ts
3229
+ // src/engine/mocks/assets.ts
3006
3230
  var import_vitest14 = require("vitest");
3231
+ function createMockAssetManager(overrides) {
3232
+ return {
3233
+ textures: {
3234
+ get: import_vitest14.vi.fn(),
3235
+ set: import_vitest14.vi.fn(),
3236
+ has: import_vitest14.vi.fn(),
3237
+ clear: import_vitest14.vi.fn(),
3238
+ memoryUsage: 0
3239
+ },
3240
+ audio: {
3241
+ load: import_vitest14.vi.fn(),
3242
+ get: import_vitest14.vi.fn(),
3243
+ clearAll: import_vitest14.vi.fn()
3244
+ },
3245
+ loadTexture: import_vitest14.vi.fn().mockResolvedValue({}),
3246
+ registerTexture: import_vitest14.vi.fn(),
3247
+ loadSound: import_vitest14.vi.fn().mockResolvedValue({}),
3248
+ loadMd2Model: import_vitest14.vi.fn().mockResolvedValue({}),
3249
+ getMd2Model: import_vitest14.vi.fn(),
3250
+ loadMd3Model: import_vitest14.vi.fn().mockResolvedValue({}),
3251
+ getMd3Model: import_vitest14.vi.fn(),
3252
+ loadSprite: import_vitest14.vi.fn().mockResolvedValue({}),
3253
+ loadMap: import_vitest14.vi.fn().mockResolvedValue({}),
3254
+ getMap: import_vitest14.vi.fn(),
3255
+ loadPalette: import_vitest14.vi.fn().mockResolvedValue(void 0),
3256
+ isAssetLoaded: import_vitest14.vi.fn().mockReturnValue(true),
3257
+ listFiles: import_vitest14.vi.fn().mockReturnValue([]),
3258
+ resetForLevelChange: import_vitest14.vi.fn(),
3259
+ getMemoryUsage: import_vitest14.vi.fn().mockReturnValue({ textures: 0, audio: 0 }),
3260
+ clearCache: import_vitest14.vi.fn(),
3261
+ preloadAssets: import_vitest14.vi.fn().mockResolvedValue(void 0),
3262
+ queueLoad: import_vitest14.vi.fn().mockImplementation((path2) => Promise.resolve({})),
3263
+ ...overrides
3264
+ };
3265
+ }
3266
+ function createMockTexture(width = 1, height = 1, data) {
3267
+ return {
3268
+ width,
3269
+ height,
3270
+ data: data || new Uint8Array(width * height * 4).fill(255),
3271
+ format: 0,
3272
+ // RGBA
3273
+ name: "mock_texture",
3274
+ uploaded: false
3275
+ };
3276
+ }
3277
+ function createMockMd2Model(overrides) {
3278
+ return {
3279
+ header: {
3280
+ skinWidth: 0,
3281
+ skinHeight: 0,
3282
+ frameSize: 0,
3283
+ numSkins: 0,
3284
+ numVertices: 0,
3285
+ numSt: 0,
3286
+ numTriangles: 0,
3287
+ numGlCmds: 0,
3288
+ numFrames: 0,
3289
+ offsetSkins: 0,
3290
+ offsetSt: 0,
3291
+ offsetTriangles: 0,
3292
+ offsetFrames: 0,
3293
+ offsetGlCmds: 0,
3294
+ offsetEnd: 0
3295
+ },
3296
+ skins: [],
3297
+ texCoords: [],
3298
+ triangles: [],
3299
+ frames: [],
3300
+ glCommands: new Int32Array(0),
3301
+ ...overrides
3302
+ };
3303
+ }
3304
+ function createMockMd3Model(overrides) {
3305
+ return {
3306
+ header: {
3307
+ ident: 0,
3308
+ version: 0,
3309
+ name: "",
3310
+ flags: 0,
3311
+ numFrames: 0,
3312
+ numTags: 0,
3313
+ numSurfaces: 0,
3314
+ numSkins: 0,
3315
+ offsetFrames: 0,
3316
+ offsetTags: 0,
3317
+ offsetSurfaces: 0,
3318
+ offsetEnd: 0
3319
+ },
3320
+ frames: [],
3321
+ tags: [],
3322
+ surfaces: [],
3323
+ ...overrides
3324
+ };
3325
+ }
3326
+ function createMockBspMap(overrides) {
3327
+ return {
3328
+ version: 38,
3329
+ entities: [],
3330
+ planes: [],
3331
+ vertices: [],
3332
+ visibility: new Uint8Array(0),
3333
+ nodes: [],
3334
+ texInfo: [],
3335
+ faces: [],
3336
+ lightmaps: [],
3337
+ leafs: [],
3338
+ leafFaces: [],
3339
+ leafBrushes: [],
3340
+ edges: [],
3341
+ faceEdges: [],
3342
+ models: [],
3343
+ brushes: [],
3344
+ brushSides: [],
3345
+ ...overrides
3346
+ };
3347
+ }
3348
+
3349
+ // src/engine/rendering.ts
3350
+ var import_vitest15 = require("vitest");
3007
3351
  function createMockRenderingContext() {
3008
3352
  const gl = createMockWebGL2Context();
3009
3353
  const camera = {
3010
- update: import_vitest14.vi.fn(),
3011
- getViewMatrix: import_vitest14.vi.fn().mockReturnValue(new Float32Array(16)),
3012
- getProjectionMatrix: import_vitest14.vi.fn().mockReturnValue(new Float32Array(16)),
3013
- getViewProjectionMatrix: import_vitest14.vi.fn().mockReturnValue(new Float32Array(16)),
3014
- getPosition: import_vitest14.vi.fn().mockReturnValue([0, 0, 0]),
3015
- getForward: import_vitest14.vi.fn().mockReturnValue([0, 0, -1]),
3016
- getRight: import_vitest14.vi.fn().mockReturnValue([1, 0, 0]),
3017
- getUp: import_vitest14.vi.fn().mockReturnValue([0, 1, 0]),
3018
- extractFrustumPlanes: import_vitest14.vi.fn(),
3354
+ update: import_vitest15.vi.fn(),
3355
+ getViewMatrix: import_vitest15.vi.fn().mockReturnValue(new Float32Array(16)),
3356
+ getProjectionMatrix: import_vitest15.vi.fn().mockReturnValue(new Float32Array(16)),
3357
+ getViewProjectionMatrix: import_vitest15.vi.fn().mockReturnValue(new Float32Array(16)),
3358
+ getPosition: import_vitest15.vi.fn().mockReturnValue([0, 0, 0]),
3359
+ getForward: import_vitest15.vi.fn().mockReturnValue([0, 0, -1]),
3360
+ getRight: import_vitest15.vi.fn().mockReturnValue([1, 0, 0]),
3361
+ getUp: import_vitest15.vi.fn().mockReturnValue([0, 1, 0]),
3362
+ extractFrustumPlanes: import_vitest15.vi.fn(),
3019
3363
  transform: {
3020
3364
  origin: [0, 0, 0],
3021
3365
  angles: [0, 0, 0],
@@ -3023,29 +3367,29 @@ function createMockRenderingContext() {
3023
3367
  }
3024
3368
  };
3025
3369
  const md2 = {
3026
- render: import_vitest14.vi.fn(),
3027
- init: import_vitest14.vi.fn(),
3028
- resize: import_vitest14.vi.fn()
3370
+ render: import_vitest15.vi.fn(),
3371
+ init: import_vitest15.vi.fn(),
3372
+ resize: import_vitest15.vi.fn()
3029
3373
  };
3030
3374
  const bsp = {
3031
- render: import_vitest14.vi.fn(),
3032
- init: import_vitest14.vi.fn(),
3033
- resize: import_vitest14.vi.fn()
3375
+ render: import_vitest15.vi.fn(),
3376
+ init: import_vitest15.vi.fn(),
3377
+ resize: import_vitest15.vi.fn()
3034
3378
  };
3035
3379
  const sprite = {
3036
- render: import_vitest14.vi.fn(),
3037
- init: import_vitest14.vi.fn(),
3038
- resize: import_vitest14.vi.fn()
3380
+ render: import_vitest15.vi.fn(),
3381
+ init: import_vitest15.vi.fn(),
3382
+ resize: import_vitest15.vi.fn()
3039
3383
  };
3040
3384
  const poly = {
3041
- render: import_vitest14.vi.fn(),
3042
- init: import_vitest14.vi.fn(),
3043
- resize: import_vitest14.vi.fn()
3385
+ render: import_vitest15.vi.fn(),
3386
+ init: import_vitest15.vi.fn(),
3387
+ resize: import_vitest15.vi.fn()
3044
3388
  };
3045
3389
  const particle = {
3046
- render: import_vitest14.vi.fn(),
3047
- init: import_vitest14.vi.fn(),
3048
- resize: import_vitest14.vi.fn()
3390
+ render: import_vitest15.vi.fn(),
3391
+ init: import_vitest15.vi.fn(),
3392
+ resize: import_vitest15.vi.fn()
3049
3393
  };
3050
3394
  return {
3051
3395
  gl,
@@ -3198,6 +3542,207 @@ function captureAudioEvents(context) {
3198
3542
  return [];
3199
3543
  }
3200
3544
 
3545
+ // src/engine/helpers/webgpu-rendering.ts
3546
+ async function createRenderTestSetup(width = 256, height = 256) {
3547
+ const setup = await initHeadlessWebGPU();
3548
+ const { device } = setup;
3549
+ const renderTarget = device.createTexture({
3550
+ size: { width, height, depthOrArrayLayers: 1 },
3551
+ format: "rgba8unorm",
3552
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
3553
+ });
3554
+ const renderTargetView = renderTarget.createView();
3555
+ const commandEncoder = device.createCommandEncoder();
3556
+ const context = {
3557
+ adapter: setup.adapter,
3558
+ device: setup.device,
3559
+ queue: setup.device.queue
3560
+ };
3561
+ return {
3562
+ context,
3563
+ renderTarget,
3564
+ renderTargetView,
3565
+ commandEncoder,
3566
+ width,
3567
+ height,
3568
+ cleanup: async () => {
3569
+ renderTarget.destroy();
3570
+ await setup.cleanup();
3571
+ }
3572
+ };
3573
+ }
3574
+ async function renderAndCapture(setup, renderFn) {
3575
+ const { device, queue } = setup.context;
3576
+ const { renderTargetView, commandEncoder, width, height } = setup;
3577
+ const passEncoder = commandEncoder.beginRenderPass({
3578
+ colorAttachments: [
3579
+ {
3580
+ view: renderTargetView,
3581
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
3582
+ loadOp: "clear",
3583
+ storeOp: "store"
3584
+ }
3585
+ ]
3586
+ });
3587
+ renderFn(passEncoder);
3588
+ passEncoder.end();
3589
+ const bytesPerPixel = 4;
3590
+ const unpaddedBytesPerRow = width * bytesPerPixel;
3591
+ const align = 256;
3592
+ const paddedBytesPerRow = Math.max(
3593
+ bytesPerPixel * width,
3594
+ Math.ceil(bytesPerPixel * width / align) * align
3595
+ );
3596
+ const bufferSize = paddedBytesPerRow * height;
3597
+ const readbackBuffer = device.createBuffer({
3598
+ size: bufferSize,
3599
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
3600
+ });
3601
+ commandEncoder.copyTextureToBuffer(
3602
+ {
3603
+ texture: setup.renderTarget
3604
+ },
3605
+ {
3606
+ buffer: readbackBuffer,
3607
+ bytesPerRow: paddedBytesPerRow
3608
+ },
3609
+ {
3610
+ width,
3611
+ height,
3612
+ depthOrArrayLayers: 1
3613
+ }
3614
+ );
3615
+ queue.submit([commandEncoder.finish()]);
3616
+ await readbackBuffer.mapAsync(GPUMapMode.READ);
3617
+ const arrayBuffer = readbackBuffer.getMappedRange();
3618
+ const output = new Uint8ClampedArray(width * height * 4);
3619
+ const srcBytes = new Uint8Array(arrayBuffer);
3620
+ for (let y = 0; y < height; y++) {
3621
+ const srcOffset = y * paddedBytesPerRow;
3622
+ const dstOffset = y * unpaddedBytesPerRow;
3623
+ output.set(srcBytes.subarray(srcOffset, srcOffset + unpaddedBytesPerRow), dstOffset);
3624
+ }
3625
+ readbackBuffer.unmap();
3626
+ readbackBuffer.destroy();
3627
+ return output;
3628
+ }
3629
+ async function createComputeTestSetup(outputSize) {
3630
+ const setup = await initHeadlessWebGPU();
3631
+ const { device } = setup;
3632
+ const outputBuffer = device.createBuffer({
3633
+ size: outputSize,
3634
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
3635
+ });
3636
+ const commandEncoder = device.createCommandEncoder();
3637
+ const context = {
3638
+ adapter: setup.adapter,
3639
+ device: setup.device,
3640
+ queue: setup.device.queue
3641
+ };
3642
+ return {
3643
+ context,
3644
+ outputBuffer,
3645
+ commandEncoder,
3646
+ outputSize,
3647
+ cleanup: async () => {
3648
+ outputBuffer.destroy();
3649
+ await setup.cleanup();
3650
+ }
3651
+ };
3652
+ }
3653
+ async function runComputeAndReadback(setup, computeFn) {
3654
+ const { device, queue } = setup.context;
3655
+ const { outputBuffer, commandEncoder, outputSize } = setup;
3656
+ const passEncoder = commandEncoder.beginComputePass();
3657
+ computeFn(passEncoder);
3658
+ passEncoder.end();
3659
+ const stagingBuffer = device.createBuffer({
3660
+ size: outputSize,
3661
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
3662
+ });
3663
+ commandEncoder.copyBufferToBuffer(
3664
+ outputBuffer,
3665
+ 0,
3666
+ stagingBuffer,
3667
+ 0,
3668
+ outputSize
3669
+ );
3670
+ queue.submit([commandEncoder.finish()]);
3671
+ await stagingBuffer.mapAsync(GPUMapMode.READ);
3672
+ const mappedRange = stagingBuffer.getMappedRange();
3673
+ const result = mappedRange.slice(0);
3674
+ stagingBuffer.unmap();
3675
+ stagingBuffer.destroy();
3676
+ return result;
3677
+ }
3678
+
3679
+ // src/engine/helpers/pipeline-test-template.ts
3680
+ var import_vitest16 = require("vitest");
3681
+ async function testPipelineRendering(name, createPipeline, setupGeometry, expectedOutput) {
3682
+ const setup = await createRenderTestSetup(256, 256);
3683
+ try {
3684
+ const pipeline = createPipeline(setup.context.device);
3685
+ const geometry = setupGeometry(setup.context.device);
3686
+ const pixels = await renderAndCapture(setup, (pass) => {
3687
+ pass.setPipeline(pipeline);
3688
+ pass.setVertexBuffer(0, geometry.vertexBuffer);
3689
+ if (geometry.indexBuffer) {
3690
+ pass.setIndexBuffer(geometry.indexBuffer, "uint16");
3691
+ pass.drawIndexed(geometry.indexCount || 0);
3692
+ } else {
3693
+ pass.draw(geometry.vertexCount);
3694
+ }
3695
+ });
3696
+ if (expectedOutput) {
3697
+ (0, import_vitest16.expect)(pixels).toEqual(expectedOutput);
3698
+ } else {
3699
+ (0, import_vitest16.expect)(pixels.length).toBe(256 * 256 * 4);
3700
+ }
3701
+ } finally {
3702
+ await setup.cleanup();
3703
+ }
3704
+ }
3705
+ async function testComputeShader(name, createComputePipeline, inputData, expectedOutput) {
3706
+ const setup = await createComputeTestSetup(inputData.byteLength);
3707
+ const { device } = setup.context;
3708
+ try {
3709
+ const pipeline = createComputePipeline(device);
3710
+ const stagingBuffer = device.createBuffer({
3711
+ size: inputData.byteLength,
3712
+ usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE,
3713
+ mappedAtCreation: true
3714
+ });
3715
+ new Float32Array(stagingBuffer.getMappedRange()).set(inputData);
3716
+ stagingBuffer.unmap();
3717
+ const encoder = device.createCommandEncoder();
3718
+ encoder.copyBufferToBuffer(stagingBuffer, 0, setup.outputBuffer, 0, inputData.byteLength);
3719
+ device.queue.submit([encoder.finish()]);
3720
+ const bindGroup = device.createBindGroup({
3721
+ layout: pipeline.getBindGroupLayout(0),
3722
+ entries: [
3723
+ {
3724
+ binding: 0,
3725
+ resource: {
3726
+ buffer: setup.outputBuffer
3727
+ }
3728
+ }
3729
+ ]
3730
+ });
3731
+ const resultBuffer = await runComputeAndReadback(setup, (pass) => {
3732
+ pass.setPipeline(pipeline);
3733
+ pass.setBindGroup(0, bindGroup);
3734
+ pass.dispatchWorkgroups(Math.ceil(inputData.length / 64));
3735
+ });
3736
+ if (expectedOutput) {
3737
+ const floatResult = new Float32Array(resultBuffer);
3738
+ (0, import_vitest16.expect)(floatResult).toEqual(expectedOutput);
3739
+ }
3740
+ stagingBuffer.destroy();
3741
+ } finally {
3742
+ await setup.cleanup();
3743
+ }
3744
+ }
3745
+
3201
3746
  // ../../node_modules/.pnpm/gl-matrix@3.4.4/node_modules/gl-matrix/esm/common.js
3202
3747
  var EPSILON = 1e-6;
3203
3748
  var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
@@ -3218,7 +3763,7 @@ __export(vec3_exports, {
3218
3763
  ceil: () => ceil,
3219
3764
  clone: () => clone,
3220
3765
  copy: () => copy,
3221
- create: () => create,
3766
+ create: () => create2,
3222
3767
  cross: () => cross,
3223
3768
  dist: () => dist,
3224
3769
  distance: () => distance,
@@ -3262,7 +3807,7 @@ __export(vec3_exports, {
3262
3807
  transformQuat: () => transformQuat,
3263
3808
  zero: () => zero
3264
3809
  });
3265
- function create() {
3810
+ function create2() {
3266
3811
  var out = new ARRAY_TYPE(3);
3267
3812
  if (ARRAY_TYPE != Float32Array) {
3268
3813
  out[0] = 0;
@@ -3574,7 +4119,7 @@ var sqrDist = squaredDistance;
3574
4119
  var len = length;
3575
4120
  var sqrLen = squaredLength;
3576
4121
  var forEach = (function() {
3577
- var vec = create();
4122
+ var vec = create2();
3578
4123
  return function(a, stride, offset, count, fn, arg) {
3579
4124
  var i, l;
3580
4125
  if (!stride) {
@@ -3697,7 +4242,7 @@ function simulateCameraMovement(camera, input, deltaTime) {
3697
4242
  }
3698
4243
 
3699
4244
  // src/client/helpers/hud.ts
3700
- var import_vitest15 = require("vitest");
4245
+ var import_vitest17 = require("vitest");
3701
4246
  function createMockHudState(overrides) {
3702
4247
  const defaultPs = {
3703
4248
  damageAlpha: 0,
@@ -3732,11 +4277,11 @@ function createMockHudState(overrides) {
3732
4277
  batches: 10
3733
4278
  };
3734
4279
  const defaultMessages = {
3735
- drawCenterPrint: import_vitest15.vi.fn(),
3736
- drawNotifications: import_vitest15.vi.fn(),
3737
- addCenterPrint: import_vitest15.vi.fn(),
3738
- addNotification: import_vitest15.vi.fn(),
3739
- clear: import_vitest15.vi.fn()
4280
+ drawCenterPrint: import_vitest17.vi.fn(),
4281
+ drawNotifications: import_vitest17.vi.fn(),
4282
+ addCenterPrint: import_vitest17.vi.fn(),
4283
+ addNotification: import_vitest17.vi.fn(),
4284
+ clear: import_vitest17.vi.fn()
3740
4285
  };
3741
4286
  return {
3742
4287
  ps: overrides?.ps ?? defaultPs,
@@ -3752,7 +4297,7 @@ function createMockHudState(overrides) {
3752
4297
  function createMockScoreboard(players = []) {
3753
4298
  return {
3754
4299
  players,
3755
- draw: import_vitest15.vi.fn()
4300
+ draw: import_vitest17.vi.fn()
3756
4301
  };
3757
4302
  }
3758
4303
  function createMockChatMessage(text, sender, timestamp = Date.now()) {
@@ -3850,6 +4395,254 @@ function createMockFogData(overrides = {}) {
3850
4395
  };
3851
4396
  }
3852
4397
 
4398
+ // src/client/mocks/download.ts
4399
+ var import_vitest18 = require("vitest");
4400
+ function createMockDownloadManager(overrides) {
4401
+ return {
4402
+ download: import_vitest18.vi.fn().mockResolvedValue(new ArrayBuffer(0)),
4403
+ cancel: import_vitest18.vi.fn(),
4404
+ getProgress: import_vitest18.vi.fn().mockReturnValue(0),
4405
+ ...overrides
4406
+ };
4407
+ }
4408
+ function createMockPrecacheList(models = [], sounds = [], images = []) {
4409
+ return {
4410
+ models,
4411
+ sounds,
4412
+ images
4413
+ };
4414
+ }
4415
+ async function simulateDownload(url, progressCallback) {
4416
+ const steps = 10;
4417
+ for (let i = 0; i <= steps; i++) {
4418
+ if (progressCallback) {
4419
+ progressCallback(i / steps);
4420
+ }
4421
+ await new Promise((resolve) => setTimeout(resolve, 10));
4422
+ }
4423
+ return new ArrayBuffer(1024);
4424
+ }
4425
+
4426
+ // src/client/mocks/state.ts
4427
+ var MAX_MODELS = 256;
4428
+ var MAX_SOUNDS = 256;
4429
+ var MAX_IMAGES = 256;
4430
+ var MockClientConfigStrings = class {
4431
+ constructor() {
4432
+ this.strings = /* @__PURE__ */ new Map();
4433
+ this.models = [];
4434
+ this.sounds = [];
4435
+ this.images = [];
4436
+ }
4437
+ set(index, value) {
4438
+ this.strings.set(index, value);
4439
+ if (index >= 32 /* Models */ && index < 32 /* Models */ + MAX_MODELS) {
4440
+ this.models[index - 32 /* Models */] = value;
4441
+ } else if (index >= 288 /* Sounds */ && index < 288 /* Sounds */ + MAX_SOUNDS) {
4442
+ this.sounds[index - 288 /* Sounds */] = value;
4443
+ } else if (index >= 544 /* Images */ && index < 544 /* Images */ + MAX_IMAGES) {
4444
+ this.images[index - 544 /* Images */] = value;
4445
+ }
4446
+ }
4447
+ get(index) {
4448
+ return this.strings.get(index);
4449
+ }
4450
+ getModelName(index) {
4451
+ return this.models[index];
4452
+ }
4453
+ getSoundName(index) {
4454
+ return this.sounds[index];
4455
+ }
4456
+ getImageName(index) {
4457
+ return this.images[index];
4458
+ }
4459
+ getPlayerName(playernum) {
4460
+ const info = this.strings.get(800 /* Players */ + playernum);
4461
+ if (!info) return void 0;
4462
+ const parts = info.split("\\");
4463
+ for (let i = 1; i < parts.length; i += 2) {
4464
+ if (parts[i] === "name") {
4465
+ return parts[i + 1];
4466
+ }
4467
+ }
4468
+ return void 0;
4469
+ }
4470
+ clear() {
4471
+ this.strings.clear();
4472
+ this.models.length = 0;
4473
+ this.sounds.length = 0;
4474
+ this.images.length = 0;
4475
+ }
4476
+ };
4477
+ var createMockClientState = (overrides) => {
4478
+ const configStrings = new MockClientConfigStrings();
4479
+ return {
4480
+ tickRate: 10,
4481
+ frameTimeMs: 100,
4482
+ serverFrame: 0,
4483
+ serverProtocol: 34,
4484
+ configStrings,
4485
+ playerNum: 0,
4486
+ serverTime: 0,
4487
+ parseEntities: 0,
4488
+ inAutoDemo: false,
4489
+ getClientName: (num) => `Player${num}`,
4490
+ getKeyBinding: (key) => "",
4491
+ ...overrides
4492
+ };
4493
+ };
4494
+ var createMockFrame = (overrides) => ({
4495
+ serverFrame: 0,
4496
+ deltaFrame: -1,
4497
+ valid: true,
4498
+ entities: [],
4499
+ ...overrides
4500
+ });
4501
+ var createMockClientInfo = (overrides) => ({
4502
+ name: "Player",
4503
+ skin: "male/grunt",
4504
+ model: "male",
4505
+ icon: "pics/icon.pcx",
4506
+ ...overrides
4507
+ });
4508
+ var createMockConnectionState = (state = "connected") => ({
4509
+ state
4510
+ });
4511
+
4512
+ // src/client/mocks/console.ts
4513
+ var import_vitest19 = require("vitest");
4514
+ function createMockConsole(overrides) {
4515
+ const history = [];
4516
+ const errors = [];
4517
+ const commands = {};
4518
+ const cvars = {};
4519
+ return {
4520
+ print: import_vitest19.vi.fn((text) => {
4521
+ history.push(text);
4522
+ }),
4523
+ error: import_vitest19.vi.fn((text) => {
4524
+ errors.push(text);
4525
+ }),
4526
+ execute: import_vitest19.vi.fn((text) => {
4527
+ const parts = text.trim().split(/\s+/);
4528
+ const cmd = parts[0];
4529
+ const args = parts.slice(1);
4530
+ if (commands[cmd]) {
4531
+ commands[cmd](args);
4532
+ } else {
4533
+ history.push(`Unknown command "${cmd}"`);
4534
+ }
4535
+ }),
4536
+ addCommand: import_vitest19.vi.fn((name, handler) => {
4537
+ commands[name] = handler;
4538
+ }),
4539
+ getCvar: import_vitest19.vi.fn((name) => cvars[name]),
4540
+ setCvar: import_vitest19.vi.fn((name, value) => {
4541
+ cvars[name] = value;
4542
+ }),
4543
+ getHistory: () => history,
4544
+ clearHistory: () => {
4545
+ history.length = 0;
4546
+ errors.length = 0;
4547
+ },
4548
+ getErrors: () => errors,
4549
+ ...overrides
4550
+ };
4551
+ }
4552
+ function createMockCommand(name, handler) {
4553
+ return { name, handler };
4554
+ }
4555
+ function createMockCvarRegistry(initialCvars) {
4556
+ return { ...initialCvars };
4557
+ }
4558
+
4559
+ // src/client/helpers/prediction.ts
4560
+ var createPredictionTestScenario = (lagMs = 100) => {
4561
+ const clientState = createMockClientState({
4562
+ playerNum: 0,
4563
+ serverTime: 1e3,
4564
+ getClientName: (num) => "TestPlayer"
4565
+ });
4566
+ const snapshots = [];
4567
+ for (let i = 0; i < 5; i++) {
4568
+ const frameEntities = [
4569
+ {
4570
+ number: 1,
4571
+ origin: { x: i * 10, y: 0, z: 0 },
4572
+ angles: { x: 0, y: 0, z: 0 },
4573
+ oldOrigin: { x: (i - 1) * 10, y: 0, z: 0 },
4574
+ modelIndex: 0,
4575
+ modelIndex2: 0,
4576
+ modelIndex3: 0,
4577
+ modelIndex4: 0,
4578
+ frame: 0,
4579
+ skinNum: 0,
4580
+ effects: 0,
4581
+ renderfx: 0,
4582
+ solid: 0,
4583
+ sound: 0,
4584
+ event: 0
4585
+ }
4586
+ ];
4587
+ snapshots.push(frameEntities);
4588
+ }
4589
+ return {
4590
+ clientState,
4591
+ snapshots,
4592
+ lagMs
4593
+ };
4594
+ };
4595
+ var simulateClientPrediction = (state, input, deltaTime) => {
4596
+ return {
4597
+ ...state,
4598
+ serverTime: state.serverTime + deltaTime * 1e3
4599
+ };
4600
+ };
4601
+ var createInterpolationTestData = (startState, endState, steps = 10) => {
4602
+ const result = [];
4603
+ for (let i = 0; i <= steps; i++) {
4604
+ const t = i / steps;
4605
+ const lerp2 = (a, b) => a + (b - a) * t;
4606
+ result.push({
4607
+ ...startState,
4608
+ origin: {
4609
+ x: lerp2(startState.origin.x, endState.origin.x),
4610
+ y: lerp2(startState.origin.y, endState.origin.y),
4611
+ z: lerp2(startState.origin.z, endState.origin.z)
4612
+ },
4613
+ angles: {
4614
+ x: lerp2(startState.angles.x, endState.angles.x),
4615
+ y: lerp2(startState.angles.y, endState.angles.y),
4616
+ z: lerp2(startState.angles.z, endState.angles.z)
4617
+ }
4618
+ });
4619
+ }
4620
+ return result;
4621
+ };
4622
+ var verifySmoothing = (states) => {
4623
+ let maxError = 0;
4624
+ let totalError = 0;
4625
+ const jumps = [];
4626
+ for (let i = 1; i < states.length; i++) {
4627
+ const prev = states[i - 1].origin;
4628
+ const curr = states[i].origin;
4629
+ const dx = curr.x - prev.x;
4630
+ const dy = curr.y - prev.y;
4631
+ const dz = curr.z - prev.z;
4632
+ const dist2 = Math.sqrt(dx * dx + dy * dy + dz * dz);
4633
+ if (dist2 > 50) {
4634
+ jumps.push(i);
4635
+ }
4636
+ totalError += dist2;
4637
+ }
4638
+ return {
4639
+ smooth: jumps.length === 0,
4640
+ maxError,
4641
+ averageError: totalError / (states.length - 1 || 1),
4642
+ jumps
4643
+ };
4644
+ };
4645
+
3853
4646
  // src/e2e/playwright.ts
3854
4647
  async function createPlaywrightTestClient(options = {}) {
3855
4648
  let playwright;
@@ -4043,6 +4836,7 @@ function createVisualTestScenario(sceneName) {
4043
4836
  HandshakeStage,
4044
4837
  InputInjector,
4045
4838
  MockAudioBufferSourceNode,
4839
+ MockClientConfigStrings,
4046
4840
  MockNetDriver,
4047
4841
  MockNetworkTransport,
4048
4842
  MockPointerLock,
@@ -4059,6 +4853,7 @@ function createVisualTestScenario(sceneName) {
4059
4853
  createBinaryWriterMock,
4060
4854
  createBounds,
4061
4855
  createCombatTestContext,
4856
+ createComputeTestSetup,
4062
4857
  createConfigStringArrayMock,
4063
4858
  createConfigStringMock,
4064
4859
  createControlledTimer,
@@ -4069,33 +4864,49 @@ function createVisualTestScenario(sceneName) {
4069
4864
  createEntityFactory,
4070
4865
  createEntityStateFactory,
4071
4866
  createGameStateSnapshotFactory,
4867
+ createHeadlessTestContext,
4072
4868
  createInputInjector,
4869
+ createInterpolationTestData,
4073
4870
  createItemEntityFactory,
4074
4871
  createMessageReaderMock,
4075
4872
  createMessageWriterMock,
4076
4873
  createMockAI,
4077
4874
  createMockAmmoItem,
4078
4875
  createMockArmorItem,
4876
+ createMockAssetManager,
4079
4877
  createMockAudioBuffer,
4080
4878
  createMockAudioContext,
4879
+ createMockBspMap,
4081
4880
  createMockBspPipeline,
4082
4881
  createMockBufferSource,
4083
4882
  createMockCamera,
4084
4883
  createMockCanvas,
4085
4884
  createMockCanvasContext2D,
4086
4885
  createMockChatMessage,
4886
+ createMockClientInfo,
4887
+ createMockClientState,
4087
4888
  createMockCollisionEntityIndex,
4889
+ createMockCommand,
4890
+ createMockCommandEncoder,
4891
+ createMockComputePassEncoder,
4892
+ createMockComputePipeline,
4088
4893
  createMockConnection,
4894
+ createMockConnectionState,
4895
+ createMockConsole,
4896
+ createMockCvarRegistry,
4089
4897
  createMockDamageIndicator,
4090
4898
  createMockDamageInfo,
4091
4899
  createMockDeltaFrame,
4900
+ createMockDownloadManager,
4092
4901
  createMockEngine,
4093
4902
  createMockEntityState,
4094
4903
  createMockFogData,
4904
+ createMockFrame,
4095
4905
  createMockFrameRenderer,
4096
4906
  createMockGPUAdapter,
4097
- createMockGPUCanvasContext,
4907
+ createMockGPUBuffer,
4098
4908
  createMockGPUDevice,
4909
+ createMockGPUTexture,
4099
4910
  createMockGame,
4100
4911
  createMockGameExports,
4101
4912
  createMockGameState,
@@ -4110,7 +4921,9 @@ function createVisualTestScenario(sceneName) {
4110
4921
  createMockKeyboardEvent,
4111
4922
  createMockLocalStorage,
4112
4923
  createMockMasterServer,
4924
+ createMockMd2Model,
4113
4925
  createMockMd2Pipeline,
4926
+ createMockMd3Model,
4114
4927
  createMockMd3Pipeline,
4115
4928
  createMockMonsterAI,
4116
4929
  createMockMonsterMove,
@@ -4122,12 +4935,17 @@ function createVisualTestScenario(sceneName) {
4122
4935
  createMockPerformance,
4123
4936
  createMockPointerLock,
4124
4937
  createMockPowerupItem,
4938
+ createMockPrecacheList,
4939
+ createMockQueue,
4125
4940
  createMockRAF,
4126
4941
  createMockRConClient,
4127
4942
  createMockRateLimiter,
4128
4943
  createMockRefDef,
4944
+ createMockRenderPassEncoder,
4945
+ createMockRenderPipeline,
4129
4946
  createMockRenderer,
4130
4947
  createMockRenderingContext,
4948
+ createMockSampler,
4131
4949
  createMockScoreboard,
4132
4950
  createMockServer,
4133
4951
  createMockServerClient,
@@ -4137,9 +4955,12 @@ function createVisualTestScenario(sceneName) {
4137
4955
  createMockServerState,
4138
4956
  createMockServerStatic,
4139
4957
  createMockSessionStorage,
4958
+ createMockShaderModule,
4140
4959
  createMockSkyboxPipeline,
4141
4960
  createMockSnapshot,
4142
4961
  createMockSpritePipeline,
4962
+ createMockTexture,
4963
+ createMockTextureView,
4143
4964
  createMockTransport,
4144
4965
  createMockUDPSocket,
4145
4966
  createMockUserInfo,
@@ -4147,6 +4968,7 @@ function createVisualTestScenario(sceneName) {
4147
4968
  createMockWeapon,
4148
4969
  createMockWeaponItem,
4149
4970
  createMockWebGL2Context,
4971
+ createMockWebGPUContext,
4150
4972
  createMockWheelEvent,
4151
4973
  createMonsterEntityFactory,
4152
4974
  createMultiplayerTestScenario,
@@ -4157,7 +4979,9 @@ function createVisualTestScenario(sceneName) {
4157
4979
  createPlayerEntityFactory,
4158
4980
  createPlayerStateFactory,
4159
4981
  createPlaywrightTestClient,
4982
+ createPredictionTestScenario,
4160
4983
  createProjectileEntityFactory,
4984
+ createRenderTestSetup,
4161
4985
  createServerSnapshot,
4162
4986
  createSpawnTestContext,
4163
4987
  createStorageTestScenario,
@@ -4169,6 +4993,7 @@ function createVisualTestScenario(sceneName) {
4169
4993
  createVector3,
4170
4994
  createViewTestScenario,
4171
4995
  createVisualTestScenario,
4996
+ initHeadlessWebGPU,
4172
4997
  intersects,
4173
4998
  ladderTrace,
4174
4999
  makeAxisBrush,
@@ -4181,6 +5006,8 @@ function createVisualTestScenario(sceneName) {
4181
5006
  measureSnapshotSize,
4182
5007
  mockMonsterAttacks,
4183
5008
  randomVector3,
5009
+ renderAndCapture,
5010
+ runComputeAndReadback,
4184
5011
  serializeUserInfo,
4185
5012
  setupBrowserEnvironment,
4186
5013
  setupMockAudioContext,
@@ -4188,6 +5015,8 @@ function createVisualTestScenario(sceneName) {
4188
5015
  setupWebGPUMocks,
4189
5016
  simulateBandwidthLimit,
4190
5017
  simulateCameraMovement,
5018
+ simulateClientPrediction,
5019
+ simulateDownload,
4191
5020
  simulateFrames,
4192
5021
  simulateGravity,
4193
5022
  simulateHandshake,
@@ -4208,7 +5037,10 @@ function createVisualTestScenario(sceneName) {
4208
5037
  teardownBrowserEnvironment,
4209
5038
  teardownMockAudioContext,
4210
5039
  teardownNodeEnvironment,
5040
+ testComputeShader,
5041
+ testPipelineRendering,
4211
5042
  throttleBandwidth,
5043
+ verifySmoothing,
4212
5044
  verifySnapshotConsistency,
4213
5045
  waitForGameReady
4214
5046
  });