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.
@@ -463,6 +463,7 @@ function createTestContext(options) {
463
463
  const entities = {
464
464
  spawn: vi2.fn(() => {
465
465
  const ent = new Entity2(entityList.length + 1);
466
+ ent.inUse = true;
466
467
  entityList.push(ent);
467
468
  hooks.onEntitySpawn(ent);
468
469
  return ent;
@@ -472,6 +473,7 @@ function createTestContext(options) {
472
473
  if (idx !== -1) {
473
474
  entityList.splice(idx, 1);
474
475
  }
476
+ ent.inUse = false;
475
477
  hooks.onEntityRemove(ent);
476
478
  }),
477
479
  finalizeSpawn: vi2.fn(),
@@ -480,6 +482,7 @@ function createTestContext(options) {
480
482
  if (idx !== -1) {
481
483
  entityList.splice(idx, 1);
482
484
  }
485
+ ent.inUse = false;
483
486
  }),
484
487
  setSpawnRegistry: vi2.fn(),
485
488
  timeSeconds: 10,
@@ -2317,99 +2320,280 @@ function createMockImage(width = 100, height = 100, src = "") {
2317
2320
  return img;
2318
2321
  }
2319
2322
 
2320
- // src/engine/mocks/webgpu.ts
2321
- import { vi as vi12 } from "vitest";
2322
- function createMockGPUAdapter() {
2323
- return {
2324
- features: /* @__PURE__ */ new Set(),
2325
- limits: {
2326
- maxTextureDimension2D: 8192,
2327
- maxBindGroups: 4,
2328
- maxUniformBufferBindingSize: 65536,
2329
- maxStorageBufferBindingSize: 134217728
2330
- },
2331
- requestDevice: vi12.fn().mockResolvedValue(createMockGPUDevice())
2332
- };
2333
- }
2334
- function createMockGPUDevice() {
2323
+ // ../../node_modules/.pnpm/webgpu@0.3.8/node_modules/webgpu/index.js
2324
+ import { dirname, join } from "path";
2325
+ import { fileURLToPath } from "url";
2326
+ import { createRequire } from "module";
2327
+ var require2 = createRequire(import.meta.url);
2328
+ var isMac = process.platform === "darwin";
2329
+ var __dirname = dirname(fileURLToPath(import.meta.url));
2330
+ var arch = isMac ? "universal" : process.arch;
2331
+ var dawnNodePath = join(__dirname, "dist", `${process.platform}-${arch}.dawn.node`);
2332
+ var { create, globals } = require2(dawnNodePath);
2333
+
2334
+ // src/setup/webgpu.ts
2335
+ async function initHeadlessWebGPU(options) {
2336
+ if (typeof process === "undefined" || process.release?.name !== "node") {
2337
+ throw new Error("initHeadlessWebGPU should only be called in a Node.js environment");
2338
+ }
2339
+ if (!globalThis.navigator) {
2340
+ globalThis.navigator = {};
2341
+ }
2342
+ if (!globalThis.navigator.gpu) {
2343
+ const gpu = create([]);
2344
+ try {
2345
+ Object.defineProperty(globalThis.navigator, "gpu", {
2346
+ value: gpu,
2347
+ writable: true,
2348
+ configurable: true
2349
+ });
2350
+ } catch (e) {
2351
+ console.warn("Could not define navigator.gpu, trying direct assignment");
2352
+ globalThis.navigator.gpu = gpu;
2353
+ }
2354
+ Object.assign(globalThis, globals);
2355
+ }
2356
+ const adapter = await navigator.gpu.requestAdapter({
2357
+ powerPreference: options?.powerPreference || "high-performance"
2358
+ });
2359
+ if (!adapter) {
2360
+ throw new Error("Failed to create WebGPU adapter");
2361
+ }
2362
+ const device = await adapter.requestDevice({
2363
+ requiredFeatures: options?.requiredFeatures || []
2364
+ });
2365
+ if (!device) {
2366
+ throw new Error("Failed to create WebGPU device");
2367
+ }
2335
2368
  return {
2336
- features: /* @__PURE__ */ new Set(),
2337
- limits: {
2338
- maxTextureDimension2D: 8192
2339
- },
2340
- lost: new Promise(() => {
2341
- }),
2342
- // Pending promise
2343
- createShaderModule: vi12.fn(),
2344
- createBindGroupLayout: vi12.fn(),
2345
- createPipelineLayout: vi12.fn(),
2346
- createRenderPipeline: vi12.fn(),
2347
- createCommandEncoder: vi12.fn().mockReturnValue({
2348
- copyTextureToBuffer: vi12.fn(),
2349
- finish: vi12.fn()
2350
- }),
2351
- createBuffer: vi12.fn(),
2352
- createTexture: vi12.fn().mockReturnValue({
2353
- createView: vi12.fn()
2354
- }),
2355
- queue: {
2356
- submit: vi12.fn(),
2357
- writeBuffer: vi12.fn(),
2358
- writeTexture: vi12.fn()
2369
+ adapter,
2370
+ device,
2371
+ cleanup: async () => {
2372
+ device.destroy();
2359
2373
  }
2360
2374
  };
2361
2375
  }
2362
- function createMockGPUCanvasContext() {
2376
+ async function createHeadlessTestContext() {
2377
+ const { adapter, device } = await initHeadlessWebGPU();
2363
2378
  return {
2364
- configure: vi12.fn(),
2365
- getCurrentTexture: vi12.fn()
2379
+ adapter,
2380
+ device,
2381
+ queue: device.queue
2366
2382
  };
2367
2383
  }
2384
+
2385
+ // src/engine/mocks/webgpu.ts
2386
+ import { vi as vi12 } from "vitest";
2368
2387
  function setupWebGPUMocks() {
2369
- const mockAdapter = createMockGPUAdapter();
2388
+ Object.assign(globalThis, globals);
2370
2389
  const mockGpu = {
2371
- requestAdapter: vi12.fn().mockResolvedValue(mockAdapter),
2390
+ requestAdapter: vi12.fn(),
2372
2391
  getPreferredCanvasFormat: vi12.fn().mockReturnValue("bgra8unorm")
2373
2392
  };
2374
- Object.defineProperty(global, "navigator", {
2375
- value: {
2376
- ...global.navigator,
2377
- gpu: mockGpu
2378
- },
2379
- writable: true
2380
- });
2381
- if (typeof GPUTextureUsage === "undefined") {
2382
- global.GPUTextureUsage = {
2383
- COPY_SRC: 1,
2384
- COPY_DST: 2,
2385
- TEXTURE_BINDING: 4,
2386
- STORAGE_BINDING: 8,
2387
- RENDER_ATTACHMENT: 16
2388
- };
2389
- }
2390
- if (typeof GPUBufferUsage === "undefined") {
2391
- global.GPUBufferUsage = {
2392
- MAP_READ: 1,
2393
- MAP_WRITE: 2,
2394
- COPY_SRC: 4,
2395
- COPY_DST: 8,
2396
- INDEX: 16,
2397
- VERTEX: 32,
2398
- UNIFORM: 64,
2399
- STORAGE: 128,
2400
- INDIRECT: 256,
2401
- QUERY_RESOLVE: 512
2402
- };
2393
+ const mockAdapter = createMockGPUAdapter();
2394
+ const mockDevice = createMockGPUDevice();
2395
+ mockGpu.requestAdapter.mockResolvedValue(mockAdapter);
2396
+ mockAdapter.requestDevice.mockResolvedValue(mockDevice);
2397
+ if (!globalThis.navigator) {
2398
+ globalThis.navigator = {};
2403
2399
  }
2404
- if (typeof GPUMapMode === "undefined") {
2405
- global.GPUMapMode = {
2406
- READ: 1,
2407
- WRITE: 2
2408
- };
2400
+ try {
2401
+ Object.defineProperty(globalThis.navigator, "gpu", {
2402
+ value: mockGpu,
2403
+ writable: true,
2404
+ configurable: true
2405
+ });
2406
+ } catch (e) {
2407
+ globalThis.navigator.gpu = mockGpu;
2409
2408
  }
2410
2409
  return {
2411
2410
  mockGpu,
2412
- mockAdapter
2411
+ mockAdapter,
2412
+ mockDevice
2413
+ };
2414
+ }
2415
+ function createMockGPUAdapter(options = {}) {
2416
+ return {
2417
+ features: /* @__PURE__ */ new Set(),
2418
+ limits: {},
2419
+ isFallbackAdapter: false,
2420
+ requestDevice: vi12.fn().mockResolvedValue(createMockGPUDevice()),
2421
+ requestAdapterInfo: vi12.fn().mockResolvedValue({}),
2422
+ ...options
2423
+ };
2424
+ }
2425
+ function createMockGPUDevice(features = /* @__PURE__ */ new Set()) {
2426
+ const queue = createMockQueue();
2427
+ return {
2428
+ features,
2429
+ limits: {},
2430
+ queue,
2431
+ destroy: vi12.fn(),
2432
+ createBuffer: vi12.fn((descriptor) => createMockGPUBuffer(descriptor)),
2433
+ createTexture: vi12.fn((descriptor) => createMockGPUTexture(descriptor)),
2434
+ createSampler: vi12.fn(() => createMockSampler()),
2435
+ createBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2436
+ createPipelineLayout: vi12.fn(() => ({ label: "mock-pipeline-layout" })),
2437
+ createBindGroup: vi12.fn(() => ({ label: "mock-bind-group" })),
2438
+ createShaderModule: vi12.fn((descriptor) => createMockShaderModule(descriptor)),
2439
+ createComputePipeline: vi12.fn(() => createMockComputePipeline()),
2440
+ createRenderPipeline: vi12.fn(() => createMockRenderPipeline()),
2441
+ createComputePipelineAsync: vi12.fn().mockResolvedValue(createMockComputePipeline()),
2442
+ createRenderPipelineAsync: vi12.fn().mockResolvedValue(createMockRenderPipeline()),
2443
+ createCommandEncoder: vi12.fn(() => createMockCommandEncoder()),
2444
+ createQuerySet: vi12.fn(() => ({ label: "mock-query-set" })),
2445
+ pushErrorScope: vi12.fn(),
2446
+ popErrorScope: vi12.fn().mockResolvedValue(null),
2447
+ addEventListener: vi12.fn(),
2448
+ removeEventListener: vi12.fn(),
2449
+ dispatchEvent: vi12.fn(),
2450
+ onuncapturederror: null,
2451
+ label: "",
2452
+ lost: Promise.resolve({ reason: "destroyed", message: "Device lost" })
2453
+ };
2454
+ }
2455
+ function createMockQueue() {
2456
+ return {
2457
+ submit: vi12.fn(),
2458
+ onSubmittedWorkDone: vi12.fn().mockResolvedValue(void 0),
2459
+ writeBuffer: vi12.fn(),
2460
+ writeTexture: vi12.fn(),
2461
+ copyExternalImageToTexture: vi12.fn(),
2462
+ label: ""
2463
+ };
2464
+ }
2465
+ function createMockGPUBuffer(descriptor) {
2466
+ return {
2467
+ size: descriptor.size,
2468
+ usage: descriptor.usage,
2469
+ mapState: "unmapped",
2470
+ mapAsync: vi12.fn().mockResolvedValue(void 0),
2471
+ getMappedRange: vi12.fn(() => new ArrayBuffer(descriptor.size)),
2472
+ unmap: vi12.fn(),
2473
+ destroy: vi12.fn(),
2474
+ label: descriptor.label || ""
2475
+ };
2476
+ }
2477
+ function createMockGPUTexture(descriptor) {
2478
+ const size = descriptor.size;
2479
+ let width = 0;
2480
+ let height = 0;
2481
+ let depthOrArrayLayers = 1;
2482
+ if (Array.isArray(size) || size instanceof Float32Array || size instanceof Uint32Array) {
2483
+ const arr = Array.from(size);
2484
+ width = arr[0] || 0;
2485
+ height = arr[1] || 1;
2486
+ depthOrArrayLayers = arr[2] || 1;
2487
+ } else if (typeof size === "object") {
2488
+ const dict = size;
2489
+ width = dict.width;
2490
+ height = dict.height || 1;
2491
+ depthOrArrayLayers = dict.depthOrArrayLayers || 1;
2492
+ }
2493
+ return {
2494
+ width,
2495
+ height,
2496
+ depthOrArrayLayers,
2497
+ mipLevelCount: descriptor.mipLevelCount || 1,
2498
+ sampleCount: descriptor.sampleCount || 1,
2499
+ dimension: descriptor.dimension || "2d",
2500
+ format: descriptor.format,
2501
+ usage: descriptor.usage,
2502
+ createView: vi12.fn(() => createMockTextureView()),
2503
+ destroy: vi12.fn(),
2504
+ label: descriptor.label || ""
2505
+ };
2506
+ }
2507
+ function createMockTextureView() {
2508
+ return {
2509
+ label: ""
2510
+ };
2511
+ }
2512
+ function createMockSampler() {
2513
+ return {
2514
+ label: ""
2515
+ };
2516
+ }
2517
+ function createMockShaderModule(descriptor) {
2518
+ return {
2519
+ getCompilationInfo: vi12.fn().mockResolvedValue({ messages: [] }),
2520
+ label: descriptor.label || ""
2521
+ };
2522
+ }
2523
+ function createMockComputePipeline() {
2524
+ return {
2525
+ getBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2526
+ label: ""
2527
+ };
2528
+ }
2529
+ function createMockRenderPipeline() {
2530
+ return {
2531
+ getBindGroupLayout: vi12.fn(() => ({ label: "mock-bind-group-layout" })),
2532
+ label: ""
2533
+ };
2534
+ }
2535
+ function createMockCommandEncoder() {
2536
+ return {
2537
+ beginRenderPass: vi12.fn(() => createMockRenderPassEncoder()),
2538
+ beginComputePass: vi12.fn(() => createMockComputePassEncoder()),
2539
+ copyBufferToBuffer: vi12.fn(),
2540
+ copyBufferToTexture: vi12.fn(),
2541
+ copyTextureToBuffer: vi12.fn(),
2542
+ copyTextureToTexture: vi12.fn(),
2543
+ clearBuffer: vi12.fn(),
2544
+ writeTimestamp: vi12.fn(),
2545
+ resolveQuerySet: vi12.fn(),
2546
+ finish: vi12.fn(() => ({ label: "mock-command-buffer" })),
2547
+ pushDebugGroup: vi12.fn(),
2548
+ popDebugGroup: vi12.fn(),
2549
+ insertDebugMarker: vi12.fn(),
2550
+ label: ""
2551
+ };
2552
+ }
2553
+ function createMockRenderPassEncoder() {
2554
+ return {
2555
+ setPipeline: vi12.fn(),
2556
+ setIndexBuffer: vi12.fn(),
2557
+ setVertexBuffer: vi12.fn(),
2558
+ setBindGroup: vi12.fn(),
2559
+ setViewport: vi12.fn(),
2560
+ setScissorRect: vi12.fn(),
2561
+ setBlendConstant: vi12.fn(),
2562
+ setStencilReference: vi12.fn(),
2563
+ beginOcclusionQuery: vi12.fn(),
2564
+ endOcclusionQuery: vi12.fn(),
2565
+ executeBundles: vi12.fn(),
2566
+ draw: vi12.fn(),
2567
+ drawIndexed: vi12.fn(),
2568
+ drawIndirect: vi12.fn(),
2569
+ drawIndexedIndirect: vi12.fn(),
2570
+ end: vi12.fn(),
2571
+ pushDebugGroup: vi12.fn(),
2572
+ popDebugGroup: vi12.fn(),
2573
+ insertDebugMarker: vi12.fn(),
2574
+ label: ""
2575
+ };
2576
+ }
2577
+ function createMockComputePassEncoder() {
2578
+ return {
2579
+ setPipeline: vi12.fn(),
2580
+ setBindGroup: vi12.fn(),
2581
+ dispatchWorkgroups: vi12.fn(),
2582
+ dispatchWorkgroupsIndirect: vi12.fn(),
2583
+ end: vi12.fn(),
2584
+ pushDebugGroup: vi12.fn(),
2585
+ popDebugGroup: vi12.fn(),
2586
+ insertDebugMarker: vi12.fn(),
2587
+ label: ""
2588
+ };
2589
+ }
2590
+ function createMockWebGPUContext() {
2591
+ const adapter = createMockGPUAdapter();
2592
+ const device = createMockGPUDevice();
2593
+ return {
2594
+ adapter,
2595
+ device,
2596
+ queue: device.queue
2413
2597
  };
2414
2598
  }
2415
2599
 
@@ -2813,20 +2997,140 @@ function createMockSkyboxPipeline(overrides) {
2813
2997
  };
2814
2998
  }
2815
2999
 
2816
- // src/engine/rendering.ts
3000
+ // src/engine/mocks/assets.ts
2817
3001
  import { vi as vi14 } from "vitest";
3002
+ function createMockAssetManager(overrides) {
3003
+ return {
3004
+ textures: {
3005
+ get: vi14.fn(),
3006
+ set: vi14.fn(),
3007
+ has: vi14.fn(),
3008
+ clear: vi14.fn(),
3009
+ memoryUsage: 0
3010
+ },
3011
+ audio: {
3012
+ load: vi14.fn(),
3013
+ get: vi14.fn(),
3014
+ clearAll: vi14.fn()
3015
+ },
3016
+ loadTexture: vi14.fn().mockResolvedValue({}),
3017
+ registerTexture: vi14.fn(),
3018
+ loadSound: vi14.fn().mockResolvedValue({}),
3019
+ loadMd2Model: vi14.fn().mockResolvedValue({}),
3020
+ getMd2Model: vi14.fn(),
3021
+ loadMd3Model: vi14.fn().mockResolvedValue({}),
3022
+ getMd3Model: vi14.fn(),
3023
+ loadSprite: vi14.fn().mockResolvedValue({}),
3024
+ loadMap: vi14.fn().mockResolvedValue({}),
3025
+ getMap: vi14.fn(),
3026
+ loadPalette: vi14.fn().mockResolvedValue(void 0),
3027
+ isAssetLoaded: vi14.fn().mockReturnValue(true),
3028
+ listFiles: vi14.fn().mockReturnValue([]),
3029
+ resetForLevelChange: vi14.fn(),
3030
+ getMemoryUsage: vi14.fn().mockReturnValue({ textures: 0, audio: 0 }),
3031
+ clearCache: vi14.fn(),
3032
+ preloadAssets: vi14.fn().mockResolvedValue(void 0),
3033
+ queueLoad: vi14.fn().mockImplementation((path2) => Promise.resolve({})),
3034
+ ...overrides
3035
+ };
3036
+ }
3037
+ function createMockTexture(width = 1, height = 1, data) {
3038
+ return {
3039
+ width,
3040
+ height,
3041
+ data: data || new Uint8Array(width * height * 4).fill(255),
3042
+ format: 0,
3043
+ // RGBA
3044
+ name: "mock_texture",
3045
+ uploaded: false
3046
+ };
3047
+ }
3048
+ function createMockMd2Model(overrides) {
3049
+ return {
3050
+ header: {
3051
+ skinWidth: 0,
3052
+ skinHeight: 0,
3053
+ frameSize: 0,
3054
+ numSkins: 0,
3055
+ numVertices: 0,
3056
+ numSt: 0,
3057
+ numTriangles: 0,
3058
+ numGlCmds: 0,
3059
+ numFrames: 0,
3060
+ offsetSkins: 0,
3061
+ offsetSt: 0,
3062
+ offsetTriangles: 0,
3063
+ offsetFrames: 0,
3064
+ offsetGlCmds: 0,
3065
+ offsetEnd: 0
3066
+ },
3067
+ skins: [],
3068
+ texCoords: [],
3069
+ triangles: [],
3070
+ frames: [],
3071
+ glCommands: new Int32Array(0),
3072
+ ...overrides
3073
+ };
3074
+ }
3075
+ function createMockMd3Model(overrides) {
3076
+ return {
3077
+ header: {
3078
+ ident: 0,
3079
+ version: 0,
3080
+ name: "",
3081
+ flags: 0,
3082
+ numFrames: 0,
3083
+ numTags: 0,
3084
+ numSurfaces: 0,
3085
+ numSkins: 0,
3086
+ offsetFrames: 0,
3087
+ offsetTags: 0,
3088
+ offsetSurfaces: 0,
3089
+ offsetEnd: 0
3090
+ },
3091
+ frames: [],
3092
+ tags: [],
3093
+ surfaces: [],
3094
+ ...overrides
3095
+ };
3096
+ }
3097
+ function createMockBspMap(overrides) {
3098
+ return {
3099
+ version: 38,
3100
+ entities: [],
3101
+ planes: [],
3102
+ vertices: [],
3103
+ visibility: new Uint8Array(0),
3104
+ nodes: [],
3105
+ texInfo: [],
3106
+ faces: [],
3107
+ lightmaps: [],
3108
+ leafs: [],
3109
+ leafFaces: [],
3110
+ leafBrushes: [],
3111
+ edges: [],
3112
+ faceEdges: [],
3113
+ models: [],
3114
+ brushes: [],
3115
+ brushSides: [],
3116
+ ...overrides
3117
+ };
3118
+ }
3119
+
3120
+ // src/engine/rendering.ts
3121
+ import { vi as vi15 } from "vitest";
2818
3122
  function createMockRenderingContext() {
2819
3123
  const gl = createMockWebGL2Context();
2820
3124
  const camera = {
2821
- update: vi14.fn(),
2822
- getViewMatrix: vi14.fn().mockReturnValue(new Float32Array(16)),
2823
- getProjectionMatrix: vi14.fn().mockReturnValue(new Float32Array(16)),
2824
- getViewProjectionMatrix: vi14.fn().mockReturnValue(new Float32Array(16)),
2825
- getPosition: vi14.fn().mockReturnValue([0, 0, 0]),
2826
- getForward: vi14.fn().mockReturnValue([0, 0, -1]),
2827
- getRight: vi14.fn().mockReturnValue([1, 0, 0]),
2828
- getUp: vi14.fn().mockReturnValue([0, 1, 0]),
2829
- extractFrustumPlanes: vi14.fn(),
3125
+ update: vi15.fn(),
3126
+ getViewMatrix: vi15.fn().mockReturnValue(new Float32Array(16)),
3127
+ getProjectionMatrix: vi15.fn().mockReturnValue(new Float32Array(16)),
3128
+ getViewProjectionMatrix: vi15.fn().mockReturnValue(new Float32Array(16)),
3129
+ getPosition: vi15.fn().mockReturnValue([0, 0, 0]),
3130
+ getForward: vi15.fn().mockReturnValue([0, 0, -1]),
3131
+ getRight: vi15.fn().mockReturnValue([1, 0, 0]),
3132
+ getUp: vi15.fn().mockReturnValue([0, 1, 0]),
3133
+ extractFrustumPlanes: vi15.fn(),
2830
3134
  transform: {
2831
3135
  origin: [0, 0, 0],
2832
3136
  angles: [0, 0, 0],
@@ -2834,29 +3138,29 @@ function createMockRenderingContext() {
2834
3138
  }
2835
3139
  };
2836
3140
  const md2 = {
2837
- render: vi14.fn(),
2838
- init: vi14.fn(),
2839
- resize: vi14.fn()
3141
+ render: vi15.fn(),
3142
+ init: vi15.fn(),
3143
+ resize: vi15.fn()
2840
3144
  };
2841
3145
  const bsp = {
2842
- render: vi14.fn(),
2843
- init: vi14.fn(),
2844
- resize: vi14.fn()
3146
+ render: vi15.fn(),
3147
+ init: vi15.fn(),
3148
+ resize: vi15.fn()
2845
3149
  };
2846
3150
  const sprite = {
2847
- render: vi14.fn(),
2848
- init: vi14.fn(),
2849
- resize: vi14.fn()
3151
+ render: vi15.fn(),
3152
+ init: vi15.fn(),
3153
+ resize: vi15.fn()
2850
3154
  };
2851
3155
  const poly = {
2852
- render: vi14.fn(),
2853
- init: vi14.fn(),
2854
- resize: vi14.fn()
3156
+ render: vi15.fn(),
3157
+ init: vi15.fn(),
3158
+ resize: vi15.fn()
2855
3159
  };
2856
3160
  const particle = {
2857
- render: vi14.fn(),
2858
- init: vi14.fn(),
2859
- resize: vi14.fn()
3161
+ render: vi15.fn(),
3162
+ init: vi15.fn(),
3163
+ resize: vi15.fn()
2860
3164
  };
2861
3165
  return {
2862
3166
  gl,
@@ -3009,6 +3313,207 @@ function captureAudioEvents(context) {
3009
3313
  return [];
3010
3314
  }
3011
3315
 
3316
+ // src/engine/helpers/webgpu-rendering.ts
3317
+ async function createRenderTestSetup(width = 256, height = 256) {
3318
+ const setup = await initHeadlessWebGPU();
3319
+ const { device } = setup;
3320
+ const renderTarget = device.createTexture({
3321
+ size: { width, height, depthOrArrayLayers: 1 },
3322
+ format: "rgba8unorm",
3323
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
3324
+ });
3325
+ const renderTargetView = renderTarget.createView();
3326
+ const commandEncoder = device.createCommandEncoder();
3327
+ const context = {
3328
+ adapter: setup.adapter,
3329
+ device: setup.device,
3330
+ queue: setup.device.queue
3331
+ };
3332
+ return {
3333
+ context,
3334
+ renderTarget,
3335
+ renderTargetView,
3336
+ commandEncoder,
3337
+ width,
3338
+ height,
3339
+ cleanup: async () => {
3340
+ renderTarget.destroy();
3341
+ await setup.cleanup();
3342
+ }
3343
+ };
3344
+ }
3345
+ async function renderAndCapture(setup, renderFn) {
3346
+ const { device, queue } = setup.context;
3347
+ const { renderTargetView, commandEncoder, width, height } = setup;
3348
+ const passEncoder = commandEncoder.beginRenderPass({
3349
+ colorAttachments: [
3350
+ {
3351
+ view: renderTargetView,
3352
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
3353
+ loadOp: "clear",
3354
+ storeOp: "store"
3355
+ }
3356
+ ]
3357
+ });
3358
+ renderFn(passEncoder);
3359
+ passEncoder.end();
3360
+ const bytesPerPixel = 4;
3361
+ const unpaddedBytesPerRow = width * bytesPerPixel;
3362
+ const align = 256;
3363
+ const paddedBytesPerRow = Math.max(
3364
+ bytesPerPixel * width,
3365
+ Math.ceil(bytesPerPixel * width / align) * align
3366
+ );
3367
+ const bufferSize = paddedBytesPerRow * height;
3368
+ const readbackBuffer = device.createBuffer({
3369
+ size: bufferSize,
3370
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
3371
+ });
3372
+ commandEncoder.copyTextureToBuffer(
3373
+ {
3374
+ texture: setup.renderTarget
3375
+ },
3376
+ {
3377
+ buffer: readbackBuffer,
3378
+ bytesPerRow: paddedBytesPerRow
3379
+ },
3380
+ {
3381
+ width,
3382
+ height,
3383
+ depthOrArrayLayers: 1
3384
+ }
3385
+ );
3386
+ queue.submit([commandEncoder.finish()]);
3387
+ await readbackBuffer.mapAsync(GPUMapMode.READ);
3388
+ const arrayBuffer = readbackBuffer.getMappedRange();
3389
+ const output = new Uint8ClampedArray(width * height * 4);
3390
+ const srcBytes = new Uint8Array(arrayBuffer);
3391
+ for (let y = 0; y < height; y++) {
3392
+ const srcOffset = y * paddedBytesPerRow;
3393
+ const dstOffset = y * unpaddedBytesPerRow;
3394
+ output.set(srcBytes.subarray(srcOffset, srcOffset + unpaddedBytesPerRow), dstOffset);
3395
+ }
3396
+ readbackBuffer.unmap();
3397
+ readbackBuffer.destroy();
3398
+ return output;
3399
+ }
3400
+ async function createComputeTestSetup(outputSize) {
3401
+ const setup = await initHeadlessWebGPU();
3402
+ const { device } = setup;
3403
+ const outputBuffer = device.createBuffer({
3404
+ size: outputSize,
3405
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
3406
+ });
3407
+ const commandEncoder = device.createCommandEncoder();
3408
+ const context = {
3409
+ adapter: setup.adapter,
3410
+ device: setup.device,
3411
+ queue: setup.device.queue
3412
+ };
3413
+ return {
3414
+ context,
3415
+ outputBuffer,
3416
+ commandEncoder,
3417
+ outputSize,
3418
+ cleanup: async () => {
3419
+ outputBuffer.destroy();
3420
+ await setup.cleanup();
3421
+ }
3422
+ };
3423
+ }
3424
+ async function runComputeAndReadback(setup, computeFn) {
3425
+ const { device, queue } = setup.context;
3426
+ const { outputBuffer, commandEncoder, outputSize } = setup;
3427
+ const passEncoder = commandEncoder.beginComputePass();
3428
+ computeFn(passEncoder);
3429
+ passEncoder.end();
3430
+ const stagingBuffer = device.createBuffer({
3431
+ size: outputSize,
3432
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
3433
+ });
3434
+ commandEncoder.copyBufferToBuffer(
3435
+ outputBuffer,
3436
+ 0,
3437
+ stagingBuffer,
3438
+ 0,
3439
+ outputSize
3440
+ );
3441
+ queue.submit([commandEncoder.finish()]);
3442
+ await stagingBuffer.mapAsync(GPUMapMode.READ);
3443
+ const mappedRange = stagingBuffer.getMappedRange();
3444
+ const result = mappedRange.slice(0);
3445
+ stagingBuffer.unmap();
3446
+ stagingBuffer.destroy();
3447
+ return result;
3448
+ }
3449
+
3450
+ // src/engine/helpers/pipeline-test-template.ts
3451
+ import { expect } from "vitest";
3452
+ async function testPipelineRendering(name, createPipeline, setupGeometry, expectedOutput) {
3453
+ const setup = await createRenderTestSetup(256, 256);
3454
+ try {
3455
+ const pipeline = createPipeline(setup.context.device);
3456
+ const geometry = setupGeometry(setup.context.device);
3457
+ const pixels = await renderAndCapture(setup, (pass) => {
3458
+ pass.setPipeline(pipeline);
3459
+ pass.setVertexBuffer(0, geometry.vertexBuffer);
3460
+ if (geometry.indexBuffer) {
3461
+ pass.setIndexBuffer(geometry.indexBuffer, "uint16");
3462
+ pass.drawIndexed(geometry.indexCount || 0);
3463
+ } else {
3464
+ pass.draw(geometry.vertexCount);
3465
+ }
3466
+ });
3467
+ if (expectedOutput) {
3468
+ expect(pixels).toEqual(expectedOutput);
3469
+ } else {
3470
+ expect(pixels.length).toBe(256 * 256 * 4);
3471
+ }
3472
+ } finally {
3473
+ await setup.cleanup();
3474
+ }
3475
+ }
3476
+ async function testComputeShader(name, createComputePipeline, inputData, expectedOutput) {
3477
+ const setup = await createComputeTestSetup(inputData.byteLength);
3478
+ const { device } = setup.context;
3479
+ try {
3480
+ const pipeline = createComputePipeline(device);
3481
+ const stagingBuffer = device.createBuffer({
3482
+ size: inputData.byteLength,
3483
+ usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE,
3484
+ mappedAtCreation: true
3485
+ });
3486
+ new Float32Array(stagingBuffer.getMappedRange()).set(inputData);
3487
+ stagingBuffer.unmap();
3488
+ const encoder = device.createCommandEncoder();
3489
+ encoder.copyBufferToBuffer(stagingBuffer, 0, setup.outputBuffer, 0, inputData.byteLength);
3490
+ device.queue.submit([encoder.finish()]);
3491
+ const bindGroup = device.createBindGroup({
3492
+ layout: pipeline.getBindGroupLayout(0),
3493
+ entries: [
3494
+ {
3495
+ binding: 0,
3496
+ resource: {
3497
+ buffer: setup.outputBuffer
3498
+ }
3499
+ }
3500
+ ]
3501
+ });
3502
+ const resultBuffer = await runComputeAndReadback(setup, (pass) => {
3503
+ pass.setPipeline(pipeline);
3504
+ pass.setBindGroup(0, bindGroup);
3505
+ pass.dispatchWorkgroups(Math.ceil(inputData.length / 64));
3506
+ });
3507
+ if (expectedOutput) {
3508
+ const floatResult = new Float32Array(resultBuffer);
3509
+ expect(floatResult).toEqual(expectedOutput);
3510
+ }
3511
+ stagingBuffer.destroy();
3512
+ } finally {
3513
+ await setup.cleanup();
3514
+ }
3515
+ }
3516
+
3012
3517
  // ../../node_modules/.pnpm/gl-matrix@3.4.4/node_modules/gl-matrix/esm/common.js
3013
3518
  var EPSILON = 1e-6;
3014
3519
  var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array;
@@ -3029,7 +3534,7 @@ __export(vec3_exports, {
3029
3534
  ceil: () => ceil,
3030
3535
  clone: () => clone,
3031
3536
  copy: () => copy,
3032
- create: () => create,
3537
+ create: () => create2,
3033
3538
  cross: () => cross,
3034
3539
  dist: () => dist,
3035
3540
  distance: () => distance,
@@ -3073,7 +3578,7 @@ __export(vec3_exports, {
3073
3578
  transformQuat: () => transformQuat,
3074
3579
  zero: () => zero
3075
3580
  });
3076
- function create() {
3581
+ function create2() {
3077
3582
  var out = new ARRAY_TYPE(3);
3078
3583
  if (ARRAY_TYPE != Float32Array) {
3079
3584
  out[0] = 0;
@@ -3385,7 +3890,7 @@ var sqrDist = squaredDistance;
3385
3890
  var len = length;
3386
3891
  var sqrLen = squaredLength;
3387
3892
  var forEach = (function() {
3388
- var vec = create();
3893
+ var vec = create2();
3389
3894
  return function(a, stride, offset, count, fn, arg) {
3390
3895
  var i, l;
3391
3896
  if (!stride) {
@@ -3508,7 +4013,7 @@ function simulateCameraMovement(camera, input, deltaTime) {
3508
4013
  }
3509
4014
 
3510
4015
  // src/client/helpers/hud.ts
3511
- import { vi as vi15 } from "vitest";
4016
+ import { vi as vi16 } from "vitest";
3512
4017
  function createMockHudState(overrides) {
3513
4018
  const defaultPs = {
3514
4019
  damageAlpha: 0,
@@ -3543,11 +4048,11 @@ function createMockHudState(overrides) {
3543
4048
  batches: 10
3544
4049
  };
3545
4050
  const defaultMessages = {
3546
- drawCenterPrint: vi15.fn(),
3547
- drawNotifications: vi15.fn(),
3548
- addCenterPrint: vi15.fn(),
3549
- addNotification: vi15.fn(),
3550
- clear: vi15.fn()
4051
+ drawCenterPrint: vi16.fn(),
4052
+ drawNotifications: vi16.fn(),
4053
+ addCenterPrint: vi16.fn(),
4054
+ addNotification: vi16.fn(),
4055
+ clear: vi16.fn()
3551
4056
  };
3552
4057
  return {
3553
4058
  ps: overrides?.ps ?? defaultPs,
@@ -3563,7 +4068,7 @@ function createMockHudState(overrides) {
3563
4068
  function createMockScoreboard(players = []) {
3564
4069
  return {
3565
4070
  players,
3566
- draw: vi15.fn()
4071
+ draw: vi16.fn()
3567
4072
  };
3568
4073
  }
3569
4074
  function createMockChatMessage(text, sender, timestamp = Date.now()) {
@@ -3664,6 +4169,254 @@ function createMockFogData(overrides = {}) {
3664
4169
  };
3665
4170
  }
3666
4171
 
4172
+ // src/client/mocks/download.ts
4173
+ import { vi as vi17 } from "vitest";
4174
+ function createMockDownloadManager(overrides) {
4175
+ return {
4176
+ download: vi17.fn().mockResolvedValue(new ArrayBuffer(0)),
4177
+ cancel: vi17.fn(),
4178
+ getProgress: vi17.fn().mockReturnValue(0),
4179
+ ...overrides
4180
+ };
4181
+ }
4182
+ function createMockPrecacheList(models = [], sounds = [], images = []) {
4183
+ return {
4184
+ models,
4185
+ sounds,
4186
+ images
4187
+ };
4188
+ }
4189
+ async function simulateDownload(url, progressCallback) {
4190
+ const steps = 10;
4191
+ for (let i = 0; i <= steps; i++) {
4192
+ if (progressCallback) {
4193
+ progressCallback(i / steps);
4194
+ }
4195
+ await new Promise((resolve) => setTimeout(resolve, 10));
4196
+ }
4197
+ return new ArrayBuffer(1024);
4198
+ }
4199
+
4200
+ // src/client/mocks/state.ts
4201
+ var MAX_MODELS = 256;
4202
+ var MAX_SOUNDS = 256;
4203
+ var MAX_IMAGES = 256;
4204
+ var MockClientConfigStrings = class {
4205
+ constructor() {
4206
+ this.strings = /* @__PURE__ */ new Map();
4207
+ this.models = [];
4208
+ this.sounds = [];
4209
+ this.images = [];
4210
+ }
4211
+ set(index, value) {
4212
+ this.strings.set(index, value);
4213
+ if (index >= 32 /* Models */ && index < 32 /* Models */ + MAX_MODELS) {
4214
+ this.models[index - 32 /* Models */] = value;
4215
+ } else if (index >= 288 /* Sounds */ && index < 288 /* Sounds */ + MAX_SOUNDS) {
4216
+ this.sounds[index - 288 /* Sounds */] = value;
4217
+ } else if (index >= 544 /* Images */ && index < 544 /* Images */ + MAX_IMAGES) {
4218
+ this.images[index - 544 /* Images */] = value;
4219
+ }
4220
+ }
4221
+ get(index) {
4222
+ return this.strings.get(index);
4223
+ }
4224
+ getModelName(index) {
4225
+ return this.models[index];
4226
+ }
4227
+ getSoundName(index) {
4228
+ return this.sounds[index];
4229
+ }
4230
+ getImageName(index) {
4231
+ return this.images[index];
4232
+ }
4233
+ getPlayerName(playernum) {
4234
+ const info = this.strings.get(800 /* Players */ + playernum);
4235
+ if (!info) return void 0;
4236
+ const parts = info.split("\\");
4237
+ for (let i = 1; i < parts.length; i += 2) {
4238
+ if (parts[i] === "name") {
4239
+ return parts[i + 1];
4240
+ }
4241
+ }
4242
+ return void 0;
4243
+ }
4244
+ clear() {
4245
+ this.strings.clear();
4246
+ this.models.length = 0;
4247
+ this.sounds.length = 0;
4248
+ this.images.length = 0;
4249
+ }
4250
+ };
4251
+ var createMockClientState = (overrides) => {
4252
+ const configStrings = new MockClientConfigStrings();
4253
+ return {
4254
+ tickRate: 10,
4255
+ frameTimeMs: 100,
4256
+ serverFrame: 0,
4257
+ serverProtocol: 34,
4258
+ configStrings,
4259
+ playerNum: 0,
4260
+ serverTime: 0,
4261
+ parseEntities: 0,
4262
+ inAutoDemo: false,
4263
+ getClientName: (num) => `Player${num}`,
4264
+ getKeyBinding: (key) => "",
4265
+ ...overrides
4266
+ };
4267
+ };
4268
+ var createMockFrame = (overrides) => ({
4269
+ serverFrame: 0,
4270
+ deltaFrame: -1,
4271
+ valid: true,
4272
+ entities: [],
4273
+ ...overrides
4274
+ });
4275
+ var createMockClientInfo = (overrides) => ({
4276
+ name: "Player",
4277
+ skin: "male/grunt",
4278
+ model: "male",
4279
+ icon: "pics/icon.pcx",
4280
+ ...overrides
4281
+ });
4282
+ var createMockConnectionState = (state = "connected") => ({
4283
+ state
4284
+ });
4285
+
4286
+ // src/client/mocks/console.ts
4287
+ import { vi as vi18 } from "vitest";
4288
+ function createMockConsole(overrides) {
4289
+ const history = [];
4290
+ const errors = [];
4291
+ const commands = {};
4292
+ const cvars = {};
4293
+ return {
4294
+ print: vi18.fn((text) => {
4295
+ history.push(text);
4296
+ }),
4297
+ error: vi18.fn((text) => {
4298
+ errors.push(text);
4299
+ }),
4300
+ execute: vi18.fn((text) => {
4301
+ const parts = text.trim().split(/\s+/);
4302
+ const cmd = parts[0];
4303
+ const args = parts.slice(1);
4304
+ if (commands[cmd]) {
4305
+ commands[cmd](args);
4306
+ } else {
4307
+ history.push(`Unknown command "${cmd}"`);
4308
+ }
4309
+ }),
4310
+ addCommand: vi18.fn((name, handler) => {
4311
+ commands[name] = handler;
4312
+ }),
4313
+ getCvar: vi18.fn((name) => cvars[name]),
4314
+ setCvar: vi18.fn((name, value) => {
4315
+ cvars[name] = value;
4316
+ }),
4317
+ getHistory: () => history,
4318
+ clearHistory: () => {
4319
+ history.length = 0;
4320
+ errors.length = 0;
4321
+ },
4322
+ getErrors: () => errors,
4323
+ ...overrides
4324
+ };
4325
+ }
4326
+ function createMockCommand(name, handler) {
4327
+ return { name, handler };
4328
+ }
4329
+ function createMockCvarRegistry(initialCvars) {
4330
+ return { ...initialCvars };
4331
+ }
4332
+
4333
+ // src/client/helpers/prediction.ts
4334
+ var createPredictionTestScenario = (lagMs = 100) => {
4335
+ const clientState = createMockClientState({
4336
+ playerNum: 0,
4337
+ serverTime: 1e3,
4338
+ getClientName: (num) => "TestPlayer"
4339
+ });
4340
+ const snapshots = [];
4341
+ for (let i = 0; i < 5; i++) {
4342
+ const frameEntities = [
4343
+ {
4344
+ number: 1,
4345
+ origin: { x: i * 10, y: 0, z: 0 },
4346
+ angles: { x: 0, y: 0, z: 0 },
4347
+ oldOrigin: { x: (i - 1) * 10, y: 0, z: 0 },
4348
+ modelIndex: 0,
4349
+ modelIndex2: 0,
4350
+ modelIndex3: 0,
4351
+ modelIndex4: 0,
4352
+ frame: 0,
4353
+ skinNum: 0,
4354
+ effects: 0,
4355
+ renderfx: 0,
4356
+ solid: 0,
4357
+ sound: 0,
4358
+ event: 0
4359
+ }
4360
+ ];
4361
+ snapshots.push(frameEntities);
4362
+ }
4363
+ return {
4364
+ clientState,
4365
+ snapshots,
4366
+ lagMs
4367
+ };
4368
+ };
4369
+ var simulateClientPrediction = (state, input, deltaTime) => {
4370
+ return {
4371
+ ...state,
4372
+ serverTime: state.serverTime + deltaTime * 1e3
4373
+ };
4374
+ };
4375
+ var createInterpolationTestData = (startState, endState, steps = 10) => {
4376
+ const result = [];
4377
+ for (let i = 0; i <= steps; i++) {
4378
+ const t = i / steps;
4379
+ const lerp2 = (a, b) => a + (b - a) * t;
4380
+ result.push({
4381
+ ...startState,
4382
+ origin: {
4383
+ x: lerp2(startState.origin.x, endState.origin.x),
4384
+ y: lerp2(startState.origin.y, endState.origin.y),
4385
+ z: lerp2(startState.origin.z, endState.origin.z)
4386
+ },
4387
+ angles: {
4388
+ x: lerp2(startState.angles.x, endState.angles.x),
4389
+ y: lerp2(startState.angles.y, endState.angles.y),
4390
+ z: lerp2(startState.angles.z, endState.angles.z)
4391
+ }
4392
+ });
4393
+ }
4394
+ return result;
4395
+ };
4396
+ var verifySmoothing = (states) => {
4397
+ let maxError = 0;
4398
+ let totalError = 0;
4399
+ const jumps = [];
4400
+ for (let i = 1; i < states.length; i++) {
4401
+ const prev = states[i - 1].origin;
4402
+ const curr = states[i].origin;
4403
+ const dx = curr.x - prev.x;
4404
+ const dy = curr.y - prev.y;
4405
+ const dz = curr.z - prev.z;
4406
+ const dist2 = Math.sqrt(dx * dx + dy * dy + dz * dz);
4407
+ if (dist2 > 50) {
4408
+ jumps.push(i);
4409
+ }
4410
+ totalError += dist2;
4411
+ }
4412
+ return {
4413
+ smooth: jumps.length === 0,
4414
+ maxError,
4415
+ averageError: totalError / (states.length - 1 || 1),
4416
+ jumps
4417
+ };
4418
+ };
4419
+
3667
4420
  // src/e2e/playwright.ts
3668
4421
  async function createPlaywrightTestClient(options = {}) {
3669
4422
  let playwright;
@@ -3856,6 +4609,7 @@ export {
3856
4609
  HandshakeStage,
3857
4610
  InputInjector,
3858
4611
  FakeBufferSource as MockAudioBufferSourceNode,
4612
+ MockClientConfigStrings,
3859
4613
  MockNetDriver,
3860
4614
  MockNetworkTransport,
3861
4615
  MockPointerLock,
@@ -3872,6 +4626,7 @@ export {
3872
4626
  createBinaryWriterMock,
3873
4627
  createBounds,
3874
4628
  createCombatTestContext,
4629
+ createComputeTestSetup,
3875
4630
  createConfigStringArrayMock,
3876
4631
  createConfigStringMock,
3877
4632
  createControlledTimer,
@@ -3882,33 +4637,49 @@ export {
3882
4637
  createEntityFactory,
3883
4638
  createEntityStateFactory,
3884
4639
  createGameStateSnapshotFactory,
4640
+ createHeadlessTestContext,
3885
4641
  createInputInjector,
4642
+ createInterpolationTestData,
3886
4643
  createItemEntityFactory,
3887
4644
  createMessageReaderMock,
3888
4645
  createMessageWriterMock,
3889
4646
  createMockAI,
3890
4647
  createMockAmmoItem,
3891
4648
  createMockArmorItem,
4649
+ createMockAssetManager,
3892
4650
  createMockAudioBuffer,
3893
4651
  createMockAudioContext,
4652
+ createMockBspMap,
3894
4653
  createMockBspPipeline,
3895
4654
  createMockBufferSource,
3896
4655
  createMockCamera,
3897
4656
  createMockCanvas,
3898
4657
  createMockCanvasContext2D,
3899
4658
  createMockChatMessage,
4659
+ createMockClientInfo,
4660
+ createMockClientState,
3900
4661
  createMockCollisionEntityIndex,
4662
+ createMockCommand,
4663
+ createMockCommandEncoder,
4664
+ createMockComputePassEncoder,
4665
+ createMockComputePipeline,
3901
4666
  createMockConnection,
4667
+ createMockConnectionState,
4668
+ createMockConsole,
4669
+ createMockCvarRegistry,
3902
4670
  createMockDamageIndicator,
3903
4671
  createMockDamageInfo,
3904
4672
  createMockDeltaFrame,
4673
+ createMockDownloadManager,
3905
4674
  createMockEngine,
3906
4675
  createMockEntityState,
3907
4676
  createMockFogData,
4677
+ createMockFrame,
3908
4678
  createMockFrameRenderer,
3909
4679
  createMockGPUAdapter,
3910
- createMockGPUCanvasContext,
4680
+ createMockGPUBuffer,
3911
4681
  createMockGPUDevice,
4682
+ createMockGPUTexture,
3912
4683
  createMockGame,
3913
4684
  createMockGameExports,
3914
4685
  createMockGameState,
@@ -3923,7 +4694,9 @@ export {
3923
4694
  createMockKeyboardEvent,
3924
4695
  createMockLocalStorage,
3925
4696
  createMockMasterServer,
4697
+ createMockMd2Model,
3926
4698
  createMockMd2Pipeline,
4699
+ createMockMd3Model,
3927
4700
  createMockMd3Pipeline,
3928
4701
  createMockMonsterAI,
3929
4702
  createMockMonsterMove,
@@ -3935,12 +4708,17 @@ export {
3935
4708
  createMockPerformance,
3936
4709
  createMockPointerLock,
3937
4710
  createMockPowerupItem,
4711
+ createMockPrecacheList,
4712
+ createMockQueue,
3938
4713
  createMockRAF,
3939
4714
  createMockRConClient,
3940
4715
  createMockRateLimiter,
3941
4716
  createMockRefDef,
4717
+ createMockRenderPassEncoder,
4718
+ createMockRenderPipeline,
3942
4719
  createMockRenderer,
3943
4720
  createMockRenderingContext,
4721
+ createMockSampler,
3944
4722
  createMockScoreboard,
3945
4723
  createMockServer,
3946
4724
  createMockServerClient,
@@ -3950,9 +4728,12 @@ export {
3950
4728
  createMockServerState,
3951
4729
  createMockServerStatic,
3952
4730
  createMockSessionStorage,
4731
+ createMockShaderModule,
3953
4732
  createMockSkyboxPipeline,
3954
4733
  createMockSnapshot,
3955
4734
  createMockSpritePipeline,
4735
+ createMockTexture,
4736
+ createMockTextureView,
3956
4737
  createMockTransport,
3957
4738
  createMockUDPSocket,
3958
4739
  createMockUserInfo,
@@ -3960,6 +4741,7 @@ export {
3960
4741
  createMockWeapon,
3961
4742
  createMockWeaponItem,
3962
4743
  createMockWebGL2Context,
4744
+ createMockWebGPUContext,
3963
4745
  createMockWheelEvent,
3964
4746
  createMonsterEntityFactory,
3965
4747
  createMultiplayerTestScenario,
@@ -3970,7 +4752,9 @@ export {
3970
4752
  createPlayerEntityFactory,
3971
4753
  createPlayerStateFactory,
3972
4754
  createPlaywrightTestClient,
4755
+ createPredictionTestScenario,
3973
4756
  createProjectileEntityFactory,
4757
+ createRenderTestSetup,
3974
4758
  createServerSnapshot,
3975
4759
  createSpawnTestContext,
3976
4760
  createStorageTestScenario,
@@ -3982,6 +4766,7 @@ export {
3982
4766
  createVector3,
3983
4767
  createViewTestScenario,
3984
4768
  createVisualTestScenario,
4769
+ initHeadlessWebGPU,
3985
4770
  intersects,
3986
4771
  ladderTrace,
3987
4772
  makeAxisBrush,
@@ -3994,6 +4779,8 @@ export {
3994
4779
  measureSnapshotSize,
3995
4780
  mockMonsterAttacks,
3996
4781
  randomVector3,
4782
+ renderAndCapture,
4783
+ runComputeAndReadback,
3997
4784
  serializeUserInfo,
3998
4785
  setupBrowserEnvironment,
3999
4786
  setupMockAudioContext,
@@ -4001,6 +4788,8 @@ export {
4001
4788
  setupWebGPUMocks,
4002
4789
  simulateBandwidthLimit,
4003
4790
  simulateCameraMovement,
4791
+ simulateClientPrediction,
4792
+ simulateDownload,
4004
4793
  simulateFrames,
4005
4794
  simulateGravity,
4006
4795
  simulateHandshake,
@@ -4021,7 +4810,10 @@ export {
4021
4810
  teardownBrowserEnvironment,
4022
4811
  teardownMockAudioContext,
4023
4812
  teardownNodeEnvironment,
4813
+ testComputeShader,
4814
+ testPipelineRendering,
4024
4815
  throttleBandwidth,
4816
+ verifySmoothing,
4025
4817
  verifySnapshotConsistency,
4026
4818
  waitForGameReady
4027
4819
  };