murow 0.0.53 → 0.0.60

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.
Files changed (56) hide show
  1. package/dist/core/index.d.ts +1 -0
  2. package/dist/core/index.js +1 -0
  3. package/dist/core/loop/drivers/immediate.d.ts +47 -0
  4. package/dist/core/loop/drivers/immediate.js +61 -0
  5. package/dist/core/loop/drivers/index.d.ts +3 -0
  6. package/dist/core/loop/drivers/index.js +3 -0
  7. package/dist/core/loop/drivers/raf.d.ts +44 -0
  8. package/dist/core/loop/drivers/raf.js +62 -0
  9. package/dist/core/loop/drivers/timeout.d.ts +52 -0
  10. package/dist/core/loop/drivers/timeout.js +71 -0
  11. package/dist/core/loop/index.d.ts +2 -0
  12. package/dist/core/loop/index.js +2 -0
  13. package/dist/core/loop/loop.d.ts +58 -0
  14. package/dist/core/loop/loop.js +47 -0
  15. package/dist/core.esm.js +1 -1
  16. package/dist/core.js +1 -1
  17. package/dist/ecs/component-store.d.ts +1 -0
  18. package/dist/ecs/component-store.js +3 -22
  19. package/dist/ecs/component.d.ts +2 -0
  20. package/dist/ecs/entity-handle.d.ts +184 -12
  21. package/dist/ecs/entity-handle.js +298 -15
  22. package/dist/ecs/system-builder.d.ts +130 -0
  23. package/dist/ecs/system-builder.js +180 -0
  24. package/dist/ecs/system.d.ts +63 -0
  25. package/dist/ecs/system.js +92 -0
  26. package/dist/ecs/world-systems.d.ts +69 -0
  27. package/dist/ecs/world-systems.js +79 -0
  28. package/dist/ecs/world.d.ts +42 -9
  29. package/dist/ecs/world.js +102 -11
  30. package/dist/net/client.d.ts +8 -0
  31. package/dist/net/client.js +16 -0
  32. package/dist/protocol/rpc/rpc-registry.d.ts +8 -0
  33. package/dist/protocol/rpc/rpc-registry.js +17 -0
  34. package/dist/protocol/snapshot/snapshot-registry.d.ts +8 -0
  35. package/dist/protocol/snapshot/snapshot-registry.js +17 -0
  36. package/package.json +1 -1
  37. package/src/core/index.ts +1 -0
  38. package/src/core/loop/README.md +97 -0
  39. package/src/core/loop/drivers/immediate.ts +66 -0
  40. package/src/core/loop/drivers/index.ts +3 -0
  41. package/src/core/loop/drivers/raf.ts +67 -0
  42. package/src/core/loop/drivers/timeout.ts +77 -0
  43. package/src/core/loop/index.ts +2 -0
  44. package/src/core/loop/loop.test.ts +414 -0
  45. package/src/core/loop/loop.ts +71 -0
  46. package/src/ecs/component-store.ts +5 -27
  47. package/src/ecs/component.ts +3 -0
  48. package/src/ecs/entity-handle.ts +334 -16
  49. package/src/ecs/system-builder.ts +309 -0
  50. package/src/ecs/system.ts +111 -0
  51. package/src/ecs/world-systems.ts +83 -0
  52. package/src/ecs/world.ts +828 -732
  53. package/src/net/client.test.ts +283 -2
  54. package/src/net/client.ts +18 -0
  55. package/src/protocol/rpc/rpc-registry.ts +20 -0
  56. package/src/protocol/snapshot/snapshot-registry.ts +20 -0
@@ -3,6 +3,7 @@ export * from './events';
3
3
  export * from './fixed-ticker';
4
4
  export * from './generate-id';
5
5
  export * from './lerp';
6
+ export * from './loop';
6
7
  export * from './navmesh';
7
8
  export * from './pooled-codec';
8
9
  export * from './prediction';
@@ -3,6 +3,7 @@ export * from './events';
3
3
  export * from './fixed-ticker';
4
4
  export * from './generate-id';
5
5
  export * from './lerp';
6
+ export * from './loop';
6
7
  export * from './navmesh';
7
8
  export * from './pooled-codec';
8
9
  export * from './prediction';
@@ -0,0 +1,47 @@
1
+ import { LoopDriver } from "../loop";
2
+ /**
3
+ * Server-side game loop driver using setImmediate.
4
+ *
5
+ * This driver runs the game loop as fast as possible without blocking the event loop,
6
+ * making it suitable for Node.js server environments where high tick rates are desired.
7
+ *
8
+ * Delta time is automatically calculated between iterations and passed to the update callback in seconds.
9
+ *
10
+ * **Note:** This driver requires Node.js as it uses `setImmediate` which is not available in browsers.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const driver = new ImmediateDriver((dt) => {
15
+ * world.tick(dt);
16
+ * broadcastState();
17
+ * });
18
+ * driver.start();
19
+ * ```
20
+ */
21
+ export declare class ImmediateDriver implements LoopDriver {
22
+ update: (dt: number) => void;
23
+ /**
24
+ * @param update - Callback invoked each tick with delta time in seconds
25
+ */
26
+ constructor(update: (dt: number) => void);
27
+ private last;
28
+ private running;
29
+ /**
30
+ * Starts the game loop using setImmediate.
31
+ *
32
+ * Resets timing to prevent large initial delta.
33
+ */
34
+ start(): void;
35
+ /**
36
+ * Stops the game loop.
37
+ *
38
+ * Note: Does not cancel already queued setImmediate callbacks.
39
+ */
40
+ stop(): void;
41
+ /**
42
+ * Internal loop method that calculates delta time and schedules the next iteration.
43
+ *
44
+ * Delta time is provided in seconds.
45
+ */
46
+ loop: () => void;
47
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Server-side game loop driver using setImmediate.
3
+ *
4
+ * This driver runs the game loop as fast as possible without blocking the event loop,
5
+ * making it suitable for Node.js server environments where high tick rates are desired.
6
+ *
7
+ * Delta time is automatically calculated between iterations and passed to the update callback in seconds.
8
+ *
9
+ * **Note:** This driver requires Node.js as it uses `setImmediate` which is not available in browsers.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const driver = new ImmediateDriver((dt) => {
14
+ * world.tick(dt);
15
+ * broadcastState();
16
+ * });
17
+ * driver.start();
18
+ * ```
19
+ */
20
+ export class ImmediateDriver {
21
+ /**
22
+ * @param update - Callback invoked each tick with delta time in seconds
23
+ */
24
+ constructor(update) {
25
+ this.update = update;
26
+ this.last = performance.now();
27
+ this.running = false;
28
+ /**
29
+ * Internal loop method that calculates delta time and schedules the next iteration.
30
+ *
31
+ * Delta time is provided in seconds.
32
+ */
33
+ this.loop = () => {
34
+ if (!this.running)
35
+ return;
36
+ const now = performance.now();
37
+ const dt = (now - this.last) / 1000;
38
+ this.last = now;
39
+ this.update(dt);
40
+ setImmediate(this.loop);
41
+ };
42
+ }
43
+ /**
44
+ * Starts the game loop using setImmediate.
45
+ *
46
+ * Resets timing to prevent large initial delta.
47
+ */
48
+ start() {
49
+ this.running = true;
50
+ this.last = performance.now();
51
+ this.loop();
52
+ }
53
+ /**
54
+ * Stops the game loop.
55
+ *
56
+ * Note: Does not cancel already queued setImmediate callbacks.
57
+ */
58
+ stop() {
59
+ this.running = false;
60
+ }
61
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./immediate";
2
+ export * from "./raf";
3
+ export * from "./timeout";
@@ -0,0 +1,3 @@
1
+ export * from "./immediate";
2
+ export * from "./raf";
3
+ export * from "./timeout";
@@ -0,0 +1,44 @@
1
+ import { LoopDriver } from "../loop";
2
+ /**
3
+ * Client-side game loop driver using requestAnimationFrame.
4
+ *
5
+ * This driver synchronizes updates with the browser's display refresh rate (typically 60 FPS),
6
+ * providing smooth rendering and automatic throttling when the tab is not visible.
7
+ *
8
+ * Delta time is automatically calculated between frames and passed to the update callback in seconds.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const driver = new RafDriver((dt) => {
13
+ * player.update(dt);
14
+ * renderer.render();
15
+ * });
16
+ * driver.start();
17
+ * ```
18
+ */
19
+ export declare class RafDriver implements LoopDriver {
20
+ update: (dt: number) => void;
21
+ /**
22
+ * @param update - Callback invoked each frame with delta time in seconds
23
+ */
24
+ constructor(update: (dt: number) => void);
25
+ private last;
26
+ private running;
27
+ private rafId;
28
+ /**
29
+ * Starts the game loop using requestAnimationFrame.
30
+ *
31
+ * Resets timing to prevent large initial delta.
32
+ */
33
+ start(): void;
34
+ /**
35
+ * Stops the game loop and cancels any pending animation frame.
36
+ */
37
+ stop(): void;
38
+ /**
39
+ * Internal loop method that calculates delta time and schedules the next frame.
40
+ *
41
+ * Delta time is provided in seconds.
42
+ */
43
+ loop: () => void;
44
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Client-side game loop driver using requestAnimationFrame.
3
+ *
4
+ * This driver synchronizes updates with the browser's display refresh rate (typically 60 FPS),
5
+ * providing smooth rendering and automatic throttling when the tab is not visible.
6
+ *
7
+ * Delta time is automatically calculated between frames and passed to the update callback in seconds.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const driver = new RafDriver((dt) => {
12
+ * player.update(dt);
13
+ * renderer.render();
14
+ * });
15
+ * driver.start();
16
+ * ```
17
+ */
18
+ export class RafDriver {
19
+ /**
20
+ * @param update - Callback invoked each frame with delta time in seconds
21
+ */
22
+ constructor(update) {
23
+ this.update = update;
24
+ this.last = performance.now();
25
+ this.running = false;
26
+ this.rafId = null;
27
+ /**
28
+ * Internal loop method that calculates delta time and schedules the next frame.
29
+ *
30
+ * Delta time is provided in seconds.
31
+ */
32
+ this.loop = () => {
33
+ if (!this.running)
34
+ return;
35
+ const now = performance.now();
36
+ const dt = (now - this.last) / 1000;
37
+ this.last = now;
38
+ this.update(dt);
39
+ requestAnimationFrame(this.loop);
40
+ };
41
+ }
42
+ /**
43
+ * Starts the game loop using requestAnimationFrame.
44
+ *
45
+ * Resets timing to prevent large initial delta.
46
+ */
47
+ start() {
48
+ this.running = true;
49
+ this.last = performance.now();
50
+ this.rafId = requestAnimationFrame(this.loop);
51
+ }
52
+ /**
53
+ * Stops the game loop and cancels any pending animation frame.
54
+ */
55
+ stop() {
56
+ this.running = false;
57
+ if (this.rafId !== null) {
58
+ cancelAnimationFrame(this.rafId);
59
+ this.rafId = null;
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,52 @@
1
+ import { LoopDriver } from "../loop";
2
+ /**
3
+ * Server-side game loop driver using setTimeout.
4
+ *
5
+ * This driver provides a more controlled alternative to setImmediate, running the game loop
6
+ * with a minimal delay (1ms) between iterations. This ensures the event loop can process
7
+ * I/O operations while maintaining high tick rates.
8
+ *
9
+ * Unlike setImmediate which runs as fast as possible, setTimeout provides better I/O responsiveness
10
+ * by yielding to the event loop between ticks with a minimal delay.
11
+ *
12
+ * Delta time is automatically calculated between iterations and passed to the update callback in seconds.
13
+ *
14
+ * **Note:** This driver is designed for Node.js/Bun server environments. For maximum performance
15
+ * without I/O concerns, use ImmediateDriver instead.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const driver = new TimeoutDriver((dt) => {
20
+ * world.tick(dt);
21
+ * broadcastState();
22
+ * });
23
+ * driver.start();
24
+ * ```
25
+ */
26
+ export declare class TimeoutDriver implements LoopDriver {
27
+ update: (dt: number) => void;
28
+ /**
29
+ * @param update - Callback invoked each tick with delta time in seconds
30
+ */
31
+ constructor(update: (dt: number) => void);
32
+ private last;
33
+ private running;
34
+ /**
35
+ * Starts the game loop using setTimeout with minimal delay.
36
+ *
37
+ * Resets timing to prevent large initial delta.
38
+ */
39
+ start(): void;
40
+ /**
41
+ * Stops the game loop.
42
+ *
43
+ * Note: Does not cancel already queued setTimeout callbacks.
44
+ */
45
+ stop(): void;
46
+ /**
47
+ * Internal loop method that calculates delta time and schedules the next iteration.
48
+ *
49
+ * Delta time is provided in seconds. Uses 1ms delay to allow I/O processing.
50
+ */
51
+ loop: () => void;
52
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Minimal delay for setTimeout-based loop scheduling.
3
+ * Using 1ms allows the event loop to process I/O while still maintaining high tick rates.
4
+ */
5
+ const TIMEOUT_DELAY = 1;
6
+ /**
7
+ * Server-side game loop driver using setTimeout.
8
+ *
9
+ * This driver provides a more controlled alternative to setImmediate, running the game loop
10
+ * with a minimal delay (1ms) between iterations. This ensures the event loop can process
11
+ * I/O operations while maintaining high tick rates.
12
+ *
13
+ * Unlike setImmediate which runs as fast as possible, setTimeout provides better I/O responsiveness
14
+ * by yielding to the event loop between ticks with a minimal delay.
15
+ *
16
+ * Delta time is automatically calculated between iterations and passed to the update callback in seconds.
17
+ *
18
+ * **Note:** This driver is designed for Node.js/Bun server environments. For maximum performance
19
+ * without I/O concerns, use ImmediateDriver instead.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const driver = new TimeoutDriver((dt) => {
24
+ * world.tick(dt);
25
+ * broadcastState();
26
+ * });
27
+ * driver.start();
28
+ * ```
29
+ */
30
+ export class TimeoutDriver {
31
+ /**
32
+ * @param update - Callback invoked each tick with delta time in seconds
33
+ */
34
+ constructor(update) {
35
+ this.update = update;
36
+ this.last = performance.now();
37
+ this.running = false;
38
+ /**
39
+ * Internal loop method that calculates delta time and schedules the next iteration.
40
+ *
41
+ * Delta time is provided in seconds. Uses 1ms delay to allow I/O processing.
42
+ */
43
+ this.loop = () => {
44
+ if (!this.running)
45
+ return;
46
+ const now = performance.now();
47
+ const dt = (now - this.last) / 1000;
48
+ this.last = now;
49
+ this.update(dt);
50
+ setTimeout(this.loop, TIMEOUT_DELAY);
51
+ };
52
+ }
53
+ /**
54
+ * Starts the game loop using setTimeout with minimal delay.
55
+ *
56
+ * Resets timing to prevent large initial delta.
57
+ */
58
+ start() {
59
+ this.running = true;
60
+ this.last = performance.now();
61
+ this.loop();
62
+ }
63
+ /**
64
+ * Stops the game loop.
65
+ *
66
+ * Note: Does not cancel already queued setTimeout callbacks.
67
+ */
68
+ stop() {
69
+ this.running = false;
70
+ }
71
+ }
@@ -0,0 +1,2 @@
1
+ export * from './loop';
2
+ export * from './drivers';
@@ -0,0 +1,2 @@
1
+ export * from './loop';
2
+ export * from './drivers';
@@ -0,0 +1,58 @@
1
+ import { ImmediateDriver, RafDriver, TimeoutDriver } from "./drivers";
2
+ export { ImmediateDriver, RafDriver, TimeoutDriver };
3
+ /**
4
+ * Interface for game loop drivers that handle frame updates.
5
+ * Drivers are responsible for scheduling and executing the game loop
6
+ * at the appropriate rate for their environment (client or server).
7
+ */
8
+ export interface LoopDriver {
9
+ /** Starts the game loop */
10
+ start(): void;
11
+ /** Stops the game loop */
12
+ stop(): void;
13
+ /** Internal loop iteration method */
14
+ loop(): void;
15
+ /** Update callback invoked each frame with delta time in seconds */
16
+ update(dt: number): void;
17
+ }
18
+ /**
19
+ * Type of driver to use for the game loop.
20
+ * - `'client'`: Uses requestAnimationFrame for browser environments (syncs with display refresh rate)
21
+ * - `'server-immediate'`: Uses setImmediate for Node.js environments (runs as fast as possible, maximum performance)
22
+ * - `'server-timeout'`: Uses setTimeout with 1ms delay for Node.js environments (balanced performance with better I/O responsiveness)
23
+ */
24
+ export type DriverType = 'server-immediate' | 'client' | 'server-timeout';
25
+ /**
26
+ * Factory function to create a loop driver for the specified environment.
27
+ *
28
+ * @param type - The environment type
29
+ * - `'client'`: Browser RAF driver (60 FPS, syncs with display)
30
+ * - `'server'`: Node.js setImmediate driver (maximum performance)
31
+ * - `'server-timeout'`: Node.js setTimeout driver (balanced with I/O)
32
+ * @param update - Callback function invoked each frame with delta time in seconds
33
+ * @returns A configured LoopDriver instance ready to start
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Client
38
+ * const clientDriver = createDriver('client', (dt) => {
39
+ * game.update(dt);
40
+ * renderer.render();
41
+ * });
42
+ * clientDriver.start();
43
+ *
44
+ * // Server (maximum performance)
45
+ * const serverDriver = createDriver('server', (dt) => {
46
+ * simulation.tick(dt);
47
+ * });
48
+ * serverDriver.start();
49
+ *
50
+ * // Server (balanced with I/O)
51
+ * const balancedDriver = createDriver('server-timeout', (dt) => {
52
+ * simulation.tick(dt);
53
+ * handleNetworkIO();
54
+ * });
55
+ * balancedDriver.start();
56
+ * ```
57
+ */
58
+ export declare function createDriver(type: DriverType, update: (dt: number) => void): ImmediateDriver | RafDriver | TimeoutDriver;
@@ -0,0 +1,47 @@
1
+ import { ImmediateDriver, RafDriver, TimeoutDriver } from "./drivers";
2
+ // Re-export driver classes for testing and direct usage
3
+ export { ImmediateDriver, RafDriver, TimeoutDriver };
4
+ /**
5
+ * Factory function to create a loop driver for the specified environment.
6
+ *
7
+ * @param type - The environment type
8
+ * - `'client'`: Browser RAF driver (60 FPS, syncs with display)
9
+ * - `'server'`: Node.js setImmediate driver (maximum performance)
10
+ * - `'server-timeout'`: Node.js setTimeout driver (balanced with I/O)
11
+ * @param update - Callback function invoked each frame with delta time in seconds
12
+ * @returns A configured LoopDriver instance ready to start
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // Client
17
+ * const clientDriver = createDriver('client', (dt) => {
18
+ * game.update(dt);
19
+ * renderer.render();
20
+ * });
21
+ * clientDriver.start();
22
+ *
23
+ * // Server (maximum performance)
24
+ * const serverDriver = createDriver('server', (dt) => {
25
+ * simulation.tick(dt);
26
+ * });
27
+ * serverDriver.start();
28
+ *
29
+ * // Server (balanced with I/O)
30
+ * const balancedDriver = createDriver('server-timeout', (dt) => {
31
+ * simulation.tick(dt);
32
+ * handleNetworkIO();
33
+ * });
34
+ * balancedDriver.start();
35
+ * ```
36
+ */
37
+ export function createDriver(type, update) {
38
+ if (type === 'server-immediate') {
39
+ return new ImmediateDriver(update);
40
+ }
41
+ else if (type === 'server-timeout') {
42
+ return new TimeoutDriver(update);
43
+ }
44
+ else {
45
+ return new RafDriver(update);
46
+ }
47
+ }
package/dist/core.esm.js CHANGED
@@ -1 +1 @@
1
- var H=Object.defineProperty;var G=(l,e)=>()=>(l&&(e=l(l=0)),e);var Z=(l,e)=>{for(var t in e)H(l,t,{get:e[t],enumerable:!0})};var C={};Z(C,{NavMeshWorkerPool:()=>z});var z,_=G(()=>{z=class{constructor(e,t,s="grid",r=[]){this.poolSize=e;this.workerPath=t;this.navType=s;this.obstacles=r;this.workers=[];this.nextWorkerIndex=0;this.requestId=0;this.pendingRequests=new Map;this.initialized=!1}async init(){if(this.initialized)return;let e=[];for(let t=0;t<this.poolSize;t++){let s=new Worker(this.workerPath,{type:"module"});s.onmessage=o=>{let n=o.data;if(n.type==="PATH_RESULT"){let i=this.pendingRequests.get(n.id);i&&(i.resolve(n.path),this.pendingRequests.delete(n.id))}else if(n.type==="ERROR")for(let[i,a]of this.pendingRequests.entries())a.reject(new Error(n.error)),this.pendingRequests.delete(i)},s.onerror=o=>{console.error("Worker error:",o);for(let[n,i]of this.pendingRequests.entries())i.reject(new Error("Worker error")),this.pendingRequests.delete(n)},this.workers.push(s);let r=new Promise(o=>{let n=i=>{i.data.type==="READY"&&(s.removeEventListener("message",n),o())};s.addEventListener("message",n)});s.postMessage({type:"INIT",navType:this.navType,obstacles:this.obstacles}),e.push(r)}await Promise.all(e),this.initialized=!0}async findPath(e,t){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let s=this.requestId++,r=this.workers[this.nextWorkerIndex];return this.nextWorkerIndex=(this.nextWorkerIndex+1)%this.workers.length,new Promise((o,n)=>{this.pendingRequests.set(s,{id:s,from:e,to:t,resolve:o,reject:n}),r.postMessage({type:"FIND_PATH",id:s,from:e,to:t})})}async addObstacle(e){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let t=this.workers.map(r=>new Promise(o=>{let n=i=>{i.data.type==="OBSTACLE_ADDED"&&(r.removeEventListener("message",n),o(i.data.obstacleId))};r.addEventListener("message",n),r.postMessage({type:"ADD_OBSTACLE",obstacle:e})}));return(await Promise.all(t))[0]}async removeObstacle(e){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let t=this.workers.map(s=>new Promise(r=>{let o=n=>{n.data.type==="OBSTACLE_REMOVED"&&(s.removeEventListener("message",o),r())};s.addEventListener("message",o),s.postMessage({type:"REMOVE_OBSTACLE",obstacleId:e})}));await Promise.all(t)}async moveObstacle(e,t){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let s=this.workers.map(r=>new Promise(o=>{let n=i=>{i.data.type==="OBSTACLE_MOVED"&&(r.removeEventListener("message",n),o())};r.addEventListener("message",n),r.postMessage({type:"MOVE_OBSTACLE",obstacleId:e,pos:t})}));await Promise.all(s)}terminate(){for(let e of this.workers)e.terminate();this.workers=[],this.pendingRequests.clear(),this.initialized=!1}get pendingCount(){return this.pendingRequests.size}get size(){return this.workers.length}}});var V=Symbol("schemaSize");function R(l){let e=l[V];if(e!==void 0)return e;let t=0;for(let s of Object.keys(l))t+=l[s].size;return l[V]=t,t}var v=class{static encodeInto(e,t){let s=R(e),r=new ArrayBuffer(s),o=new DataView(r),n=0;for(let i of Object.keys(e)){let a=e[i];a.write(o,n,t[i]),n+=a.size}return new Uint8Array(r)}static decodeInto(e,t,s){let r=R(e);if(t.byteLength<r)throw new RangeError(`Buffer too small: expected ${r} bytes, got ${t.byteLength}`);let o=new DataView(t.buffer,t.byteOffset,t.byteLength),n=0;for(let i of Object.keys(e)){let a=e[i];s[i]=a.read(o,n),n+=a.size}return s}},m=class{static{this.u8={size:1,write:(e,t,s)=>e.setUint8(t,s),read:(e,t)=>e.getUint8(t),toNil:()=>0}}static{this.u16={size:2,write:(e,t,s)=>e.setUint16(t,s,!1),read:(e,t)=>e.getUint16(t,!1),toNil:()=>0}}static{this.u32={size:4,write:(e,t,s)=>e.setUint32(t,s,!1),read:(e,t)=>e.getUint32(t,!1),toNil:()=>0}}static{this.i8={size:1,write:(e,t,s)=>e.setInt8(t,s),read:(e,t)=>e.getInt8(t),toNil:()=>0}}static{this.i16={size:2,write:(e,t,s)=>e.setInt16(t,s,!1),read:(e,t)=>e.getInt16(t,!1),toNil:()=>0}}static{this.i32={size:4,write:(e,t,s)=>e.setInt32(t,s,!1),read:(e,t)=>e.getInt32(t,!1),toNil:()=>0}}static{this.f32={size:4,write:(e,t,s)=>e.setFloat32(t,s,!1),read:(e,t)=>e.getFloat32(t,!1),toNil:()=>0}}static{this.f64={size:8,write:(e,t,s)=>e.setFloat64(t,s,!1),read:(e,t)=>e.getFloat64(t,!1),toNil:()=>0}}static{this.bool={size:1,write:(e,t,s)=>e.setUint8(t,s?1:0),read:(e,t)=>e.getUint8(t)!==0,toNil:()=>!1}}static string(e){return{size:e+2,write(t,s,r){let n=new TextEncoder().encode(r);if(n.length>e)throw new RangeError(`String too long, max ${e} bytes`);t.setUint16(s,n.length,!1);for(let i=0;i<n.length;i++)t.setUint8(s+2+i,n[i]);for(let i=n.length;i<e;i++)t.setUint8(s+2+i,0)},read(t,s){let r=t.getUint16(s,!1),o=new Uint8Array(r);for(let n=0;n<r;n++)o[n]=t.getUint8(s+2+n);return new TextDecoder().decode(o)},toNil:()=>""}}static{this.vec2={size:8,write(e,t,s){e.setFloat32(t,s.x,!1),e.setFloat32(t+4,s.y,!1)},read(e,t){return{x:e.getFloat32(t,!1),y:e.getFloat32(t+4,!1)}},toNil:()=>({x:0,y:0})}}static{this.vec3={size:12,write(e,t,s){e.setFloat32(t,s.x,!1),e.setFloat32(t+4,s.y,!1),e.setFloat32(t+8,s.z,!1)},read(e,t){return{x:e.getFloat32(t,!1),y:e.getFloat32(t+4,!1),z:e.getFloat32(t+8,!1)}},toNil:()=>({x:0,y:0,z:0})}}static{this.color={size:4,write(e,t,s){e.setUint8(t,s.r),e.setUint8(t+1,s.g),e.setUint8(t+2,s.b),e.setUint8(t+3,s.a)},read(e,t){return{r:e.getUint8(t),g:e.getUint8(t+1),b:e.getUint8(t+2),a:e.getUint8(t+3)}},toNil:()=>({r:0,g:0,b:0,a:0})}}static{this.f32_le={size:4,write:(e,t,s)=>e.setFloat32(t,s,!0),read:(e,t)=>e.getFloat32(t,!0),toNil:()=>0}}static{this.f64_le={size:8,write:(e,t,s)=>e.setFloat64(t,s,!0),read:(e,t)=>e.getFloat64(t,!0),toNil:()=>0}}static{this.u16_le={size:2,write:(e,t,s)=>e.setUint16(t,s,!0),read:(e,t)=>e.getUint16(t,!0),toNil:()=>0}}static{this.u32_le={size:4,write:(e,t,s)=>e.setUint32(t,s,!0),read:(e,t)=>e.getUint32(t,!0),toNil:()=>0}}static{this.i16_le={size:2,write:(e,t,s)=>e.setInt16(t,s,!0),read:(e,t)=>e.getInt16(t,!0),toNil:()=>0}}static{this.i32_le={size:4,write:(e,t,s)=>e.setInt32(t,s,!0),read:(e,t)=>e.getInt32(t,!0),toNil:()=>0}}static{this.vec2_le={size:8,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0)],toNil:()=>[0,0]}}static{this.vec3_le={size:12,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0),e.setFloat32(t+8,s[2],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0),e.getFloat32(t+8,!0)],toNil:()=>[0,0,0]}}static{this.vec4_le={size:16,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0),e.setFloat32(t+8,s[2],!0),e.setFloat32(t+12,s[3],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0),e.getFloat32(t+8,!0),e.getFloat32(t+12,!0)],toNil:()=>[0,0,0,0]}}},k=class extends v{static{this.u8=m.u8}static{this.u16=m.u16}static{this.u32=m.u32}static{this.i8=m.i8}static{this.i16=m.i16}static{this.i32=m.i32}static{this.f32=m.f32}static{this.bool=m.bool}static{this.string=m.string}static{this.vec2=m.vec2}static{this.vec3=m.vec3}static{this.color=m.color}static encode(e,t){return this.encodeInto(e,t)}static decode(e,t,s){return this.decodeInto(e,t,s)}};var A=class{constructor({events:e}){this.callbacks=new Map,this.events=e;for(let t of this.events)this.callbacks.set(t,new Set)}on(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);s.add(t)}once(e,t){let s=r=>{t(r),this.off(e,s)};this.on(e,s)}emit(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);for(let r of s)r(t)}off(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);s.delete(t)}clear(e){if(!e){this.callbacks.clear();for(let s of this.events)this.callbacks.set(s,new Set);return}let t=this.callbacks.get(e);if(!t)return console.warn(`Event "${e}" does not exist.`);t.clear()}};var N=class{constructor({rate:e,onTick:t}){this.accumulator=0;this._tickCount=0;this.rate=e,this.intervalMs=1e3/this.rate,this.onTick=t,this.maxTicksPerFrame=Math.max(1,Math.floor(e/2))}getTicks(e){this.accumulator+=e*1e3;let t=0;for(;this.accumulator>=this.intervalMs&&t<this.maxTicksPerFrame;)this.accumulator-=this.intervalMs,t++;let s=Math.floor(this.accumulator/this.intervalMs);return s>0&&this.onTickSkipped&&this.onTickSkipped(s),t}tick(e){let t=this.getTicks(e);for(let s=0;s<t;s++)this.onTick(1/this.rate,this._tickCount++)}get tickCount(){return this._tickCount}resetTickCount(){this._tickCount=0}get accumulatedTime(){return this.accumulator/1e3}get alpha(){return Math.min(this.accumulatedTime/(1/this.rate),1)}};function ue(l={}){let{prefix:e="",size:t=16}=l,s=Math.max(t-e.length,8),r=Math.ceil(s/8),n=crypto.getRandomValues(new Uint32Array(r)).reduce((i,a)=>i+a.toString(16).padStart(8,"0"),"");return n=n.slice(0,s).padStart(s,"0"),`${e}${n}`}function ye(l,e,t){return l+(e-l)*t}var J=[{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}],w=l=>({x:Math.floor(l.x),y:Math.floor(l.y)}),j=l=>({x:l.x+.5,y:l.y+.5}),Q=(()=>{let l=1;return()=>l++})(),b=(l,e)=>l&65535|(e&65535)<<16,O=l=>({x:l<<16>>16,y:l>>16}),S=class{constructor(e){this.scoreFn=e;this.heap=[]}push(e){this.heap.push(e),this.bubbleUp(this.heap.length-1)}pop(){let e=this.heap[0],t=this.heap.pop();return this.heap.length>0&&t!==void 0&&(this.heap[0]=t,this.sinkDown(0)),e}get size(){return this.heap.length}bubbleUp(e){let t=this.heap[e],s=this.scoreFn(t);for(;e>0;){let r=(e+1>>1)-1,o=this.heap[r];if(s>=this.scoreFn(o))break;this.heap[r]=t,this.heap[e]=o,e=r}}sinkDown(e){let t=this.heap.length,s=this.heap[e],r=this.scoreFn(s);for(;;){let o=e+1<<1,n=o-1,i=null,a;if(n<t){let c=this.heap[n];a=this.scoreFn(c),a<r&&(i=n)}if(o<t){let c=this.heap[o];this.scoreFn(c)<(i===null?r:a)&&(i=o)}if(i===null)break;this.heap[e]=this.heap[i],this.heap[i]=s,e=i}}},E=class{constructor(e=1){this.grid=new Map;this.obstacleCells=new Map;this.cellSize=e}hash(e,t){let s=Math.floor(e/this.cellSize),r=Math.floor(t/this.cellSize);return b(s,r)}add(e,t){let s=this.getCellsForObstacle(t);for(let r of s)this.grid.has(r)||this.grid.set(r,new Set),this.grid.get(r).add(e);this.obstacleCells.set(e,s)}remove(e){let t=this.obstacleCells.get(e);if(t){for(let s of t){let r=this.grid.get(s);r&&(r.delete(e),r.size===0&&this.grid.delete(s))}this.obstacleCells.delete(e)}}query(e){let t=this.hash(e.x,e.y);return this.grid.get(t)||new Set}clear(){this.grid.clear(),this.obstacleCells.clear()}getCellsForObstacle(e){let t=new Set;if(e.type==="circle"){let s=e.radius,r=Math.floor((e.pos.x-s)/this.cellSize),o=Math.floor((e.pos.x+s)/this.cellSize),n=Math.floor((e.pos.y-s)/this.cellSize),i=Math.floor((e.pos.y+s)/this.cellSize);for(let a=r;a<=o;a++)for(let c=n;c<=i;c++)t.add(b(a,c))}else if(e.type==="rect"){let s=e.pos.x+e.size.x/2,r=e.pos.y+e.size.y/2,o=e.size.x/2,n=e.size.y/2,i=Math.sqrt(o*o+n*n),a=Math.floor((s-i)/this.cellSize),c=Math.floor((s+i)/this.cellSize),u=Math.floor((r-i)/this.cellSize),d=Math.floor((r+i)/this.cellSize);for(let h=a;h<=c;h++)for(let f=u;f<=d;f++)t.add(b(h,f))}else if(e.type==="polygon"){let s=X(e),r=Math.floor(s.minX/this.cellSize),o=Math.floor(s.maxX/this.cellSize),n=Math.floor(s.minY/this.cellSize),i=Math.floor(s.maxY/this.cellSize);for(let a=r;a<=o;a++)for(let c=n;c<=i;c++)t.add(b(a,c))}return t}};function q(l,e){let t=l.x-e.pos.x,s=l.y-e.pos.y;return t*t+s*s<=e.radius*e.radius}function D(l,e){let t=e.pos.x+e.size.x/2,s=e.pos.y+e.size.y/2;if(e.rotation){let r=Math.cos(-e.rotation),o=Math.sin(-e.rotation),n=l.x-t,i=l.y-s,a=n*r-i*o,c=n*o+i*r;return Math.abs(a)<=e.size.x/2&&Math.abs(c)<=e.size.y/2}return l.x>=e.pos.x&&l.y>=e.pos.y&&l.x<=e.pos.x+e.size.x&&l.y<=e.pos.y+e.size.y}function Y(l,e){let t=!1,s=e.points,r=e.rotation?Math.cos(e.rotation):1,o=e.rotation?Math.sin(e.rotation):0;for(let n=0,i=s.length-1;n<s.length;i=n++){let a=s[n].x,c=s[n].y,u=s[i].x,d=s[i].y;if(e.rotation){let f=a*r-c*o,y=a*o+c*r,p=u*r-d*o,x=u*o+d*r;a=f,c=y,u=p,d=x}a+=e.pos.x,c+=e.pos.y,u+=e.pos.x,d+=e.pos.y,c>l.y!=d>l.y&&l.x<(u-a)*(l.y-c)/(d-c)+a&&(t=!t)}return t}function X(l){let e=1/0,t=1/0,s=-1/0,r=-1/0,o=l.rotation?Math.cos(l.rotation):1,n=l.rotation?Math.sin(l.rotation):0;for(let i of l.points){let a=i.x,c=i.y;if(l.rotation){let u=a*o-c*n,d=a*n+c*o;a=u,c=d}a+=l.pos.x,c+=l.pos.y,e=Math.min(e,a),t=Math.min(t,c),s=Math.max(s,a),r=Math.max(r,c)}return{minX:e,minY:t,maxX:s,maxY:r}}var M=class{constructor(){this.items=new Map;this.spatial=new E(1);this._cachedItems=[];this.dirty=!0;this.version=0}add(e){let t=Q(),s={...e,id:t};return this.items.set(t,s),this.spatial.add(t,s),this.dirty=!0,this.version++,t}move(e,t){let s=this.items.get(e);if(!s)return;this.spatial.remove(e);let r={...s,pos:{...t}};this.items.set(e,r),this.spatial.add(e,r),this.dirty=!0,this.version++}remove(e){this.spatial.remove(e),this.items.delete(e),this.dirty=!0,this.version++}at(e){let t=this.spatial.query(e);for(let s of t){let r=this.items.get(s);if(!(!r||r.solid===!1)&&(r.type==="circle"&&q(e,r)||r.type==="rect"&&D(e,r)||r.type==="polygon"&&Y(e,r)))return r}}get values(){return this.dirty?(this._cachedItems=[...this.items.values()],this.dirty=!1,this._cachedItems):this._cachedItems}},F=class{constructor(e){this.obstacles=e;this.blocked=new Set}rebuild(){this.blocked.clear();for(let e of this.obstacles.values)if(e.solid!==!1){if(e.type==="circle"){let t=Math.ceil(e.radius),s=Math.floor(e.pos.x),r=Math.floor(e.pos.y);for(let o=-t;o<=t;o++)for(let n=-t;n<=t;n++){let i=s+o,a=r+n,c={x:i+.5,y:a+.5};q(c,e)&&this.blocked.add(b(i,a))}}else if(e.type==="rect"){let t=e.pos.x+e.size.x/2,s=e.pos.y+e.size.y/2,r=e.size.x/2,o=e.size.y/2,n=Math.sqrt(r*r+o*o),i=Math.floor(t-n),a=Math.ceil(t+n),c=Math.floor(s-n),u=Math.ceil(s+n);for(let d=i;d<=a;d++)for(let h=c;h<=u;h++){let f={x:d+.5,y:h+.5};D(f,e)&&this.blocked.add(b(d,h))}}else if(e.type==="polygon"){let t=X(e),s=Math.floor(t.minX),r=Math.ceil(t.maxX),o=Math.floor(t.minY),n=Math.ceil(t.maxY);for(let i=s;i<=r;i++)for(let a=o;a<=n;a++){let c={x:i+.5,y:a+.5};Y(c,e)&&this.blocked.add(b(i,a))}}}}findPath(e,t){return L(w(e),w(t),(s,r)=>!this.blocked.has(b(s,r))).map(j)}},P=class{constructor(e){this.obstacles=e}rebuild(){}findPath(e,t){let s=Math.ceil(Math.hypot(t.x-e.x,t.y-e.y)*2),r=!1;for(let n=1;n<=s;n++){let i=n/s,a={x:e.x+(t.x-e.x)*i,y:e.y+(t.y-e.y)*i};if(this.obstacles.at(a)){r=!0;break}}return r?L(w(e),w(t),(n,i)=>{let a={x:n+.5,y:i+.5};return!this.obstacles.at(a)}).map(j):[e,t]}},W=class{constructor(e,t){this.type=e;this.lastVersion=-1;this.pendingPaths=0;this.AUTO_WORKER_THRESHOLD=20;this.obstacles=new M,this.options={workers:t?.workers??!1,workerPoolSize:t?.workerPoolSize??4,workerPath:t?.workerPath??"./navmesh.worker.js"},e==="grid"&&(this.grid=new F(this.obstacles)),e==="graph"&&(this.graph=new P(this.obstacles)),this.options.workers===!0&&this.initWorkerPool()}async initWorkerPool(){if(!this.workerPool)try{let{NavMeshWorkerPool:e}=await Promise.resolve().then(()=>(_(),C));this.workerPool=new e(this.options.workerPoolSize,this.options.workerPath,this.type,this.obstacles.values),await this.workerPool.init()}catch(e){console.warn("Failed to initialize worker pool, falling back to sync:",e),this.options.workers=!1}}shouldUseWorkers(){return this.options.workers===!1?!1:this.options.workers===!0?!0:this.pendingPaths>=this.AUTO_WORKER_THRESHOLD}addObstacle(e){return this.obstacles.add(e)}moveObstacle(e,t){this.obstacles.move(e,t)}removeObstacle(e){this.obstacles.remove(e)}getObstacles(){return this.obstacles.values}findPath({from:e,to:t}){return this.shouldUseWorkers()&&this.workerPool?(this.pendingPaths++,this.findPathAsync(e,t).finally(()=>{this.pendingPaths--})):(this.rebuild(),this.type==="grid"?this.grid.findPath(e,t):this.graph.findPath(e,t))}async findPathAsync(e,t){return this.options.workers==="auto"&&!this.workerPool&&await this.initWorkerPool(),this.workerPool?this.workerPool.findPath(e,t):(this.rebuild(),this.type==="grid"?this.grid.findPath(e,t):this.graph.findPath(e,t))}rebuild(){this.lastVersion!==this.obstacles.version&&(this.grid?.rebuild(),this.graph?.rebuild(),this.lastVersion=this.obstacles.version)}dispose(){this.workerPool&&(this.workerPool.terminate(),this.workerPool=void 0)}getWorkerStatus(){return{workersEnabled:this.options.workers,workerPoolActive:!!this.workerPool,pendingPaths:this.pendingPaths,usingWorkersNow:this.shouldUseWorkers()}}};function L(l,e,t){let s=new Map,r=new Map,o=new Set,n=new Set,i=d=>b(d.x,d.y),a=(d,h)=>Math.abs(d.x-h.x)+Math.abs(d.y-h.y),c=new S(d=>{let h=O(d);return r.get(d)+a(h,e)}),u=i(l);for(r.set(u,0),c.push(u),n.add(u);c.size>0;){let d=c.pop();n.delete(d);let h=O(d);if(h.x===e.x&&h.y===e.y)return ee(s,h);o.add(d);for(let f of J){let y={x:h.x+f.x,y:h.y+f.y};if(!t(y.x,y.y))continue;let p=i(y);if(o.has(p))continue;let x=r.get(d)+1;x<(r.get(p)??1/0)&&(r.set(p,x),s.set(p,d),n.has(p)||(c.push(p),n.add(p)))}}return[]}function ee(l,e){let t=[e],s=b(e.x,e.y);for(;l.has(s);)s=l.get(s),t.push(O(s));return t.reverse()}var g=class{constructor(e){this.factory=e;this.pool=[]}acquire(){return this.pool.pop()??this.factory()}release(e){this.pool.push(e)}releaseAll(e){this.pool.push(...e)}},T=class{constructor(e){this.schema=e;this.pool=new g(()=>this.createNil())}createNil(){let e={};for(let t of Object.keys(this.schema)){let s=this.schema[t];e[t]="toNil"in s?s.toNil():void 0}return e}decode(e){let t=this.pool.acquire();return this.decodeInto(e,t),t}decodeInto(e,t){let s=0;for(let r of Object.keys(this.schema)){let o=this.schema[r];if("decodeAll"in o){let n=o.decodeAll(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else if("decodeField"in o){let n=o.decodeField(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else if("decode"in o){let n=o.decode(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else{let n=o.size||0,i=e.subarray(s,s+n);k.decodeInto({[r]:o},i,t),s+=n}}}release(e){this.pool.release(e)}},K=class{constructor(e){this.pooledDecoder=new T(e)}decodeAll(e){return e.map(t=>this.pooledDecoder.decode(t))}releaseAll(e){e.forEach(t=>this.pooledDecoder.release(t))}},U=class{constructor(e,t=1024){this.schema=e;this.bufferSize=t;this.pool=new g(()=>new Uint8Array(t))}encode(e){let t=this.pool.acquire(),s=0;for(let r of Object.keys(this.schema)){let o=this.schema[r];if("encode"in o){let n=o.encode(e[r]);t.set(n,s),s+=n.length}else if("encodeAll"in o){let n=o.encodeAll(e[r]),i=0;for(let a of n)t.set(a,s+i),i+=a.length;s+=i}else{let n=k.encode({[r]:o},{[r]:e[r]});t.set(n,s),s+=n.length}}return t.subarray(0,s)}release(e){this.pool.release(e)}},B=class{constructor(e){this.schema=e;this.encoder=new U(e),this.decoder=new T(e)}calculateSize(e){let t=0;for(let s of Object.keys(this.schema)){let r=this.schema[s];"size"in r?t+=r.size:"calculateSize"in r&&(t+=r.calculateSize(e[s]))}return t}encodeInto(e,t,s){let r=new DataView(t.buffer,t.byteOffset),o=s;for(let n of Object.keys(this.schema)){let i=this.schema[n];if("write"in i)i.write(r,o,e[n]),o+=i.size;else if("encodeInto"in i){let a=i.encodeInto(e[n],t,o);o+=a}else if("encode"in i){let a=i.encode(e[n]);t.set(a,o),o+=a.length}}return o-s}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}release(e){this.decoder.release(e)}static array(e){let t=0;for(let a of Object.keys(e)){let c=e[a];t+=c.size||0}let s=new g(()=>new Uint8Array(16384)),r=new g(()=>{let a={};for(let c of Object.keys(e)){let u=e[c];a[c]="toNil"in u?u.toNil():void 0}return a}),o=new g(()=>[]),n=null,i=null;return{__arrayType:void 0,calculateSize(a){return 2+a.length*t},encodeInto(a,c,u){let d=new DataView(c.buffer,c.byteOffset);d.setUint16(u,a.length,!1);let h=u+2;for(let f of a)for(let y of Object.keys(e)){let p=e[y];p.write(d,h,f[y]),h+=p.size}return h-u},encode(a){let c=2+a.length*t,u=s.acquire();u.length<c&&(s.release(u),u=new Uint8Array(Math.max(c,u.length*2))),(!n||n.buffer!==u.buffer)&&(n=new DataView(u.buffer,u.byteOffset)),n.setUint16(0,a.length,!1);let d=2;for(let f of a)for(let y of Object.keys(e)){let p=e[y];p.write(n,d,f[y]),d+=p.size}let h=new Uint8Array(d);return h.set(u.subarray(0,d)),s.release(u),h},decodeField(a){let c=a[0]<<8|a[1],u=o.acquire();u.length=c,(!i||i.buffer!==a.buffer||i.byteOffset!==a.byteOffset)&&(i=new DataView(a.buffer,a.byteOffset));let d=2;for(let h=0;h<c;h++){let f=r.acquire();for(let y of Object.keys(e)){let p=e[y];f[y]=p.read(i,d),d+=p.size}u[h]=f}return{value:u,bytesRead:d}},decode(a){return this.decodeField(a).value},toNil(){return[]}}}};var I=class{constructor(){this.tracker=new Map}get size(){return this.tracker.size}track(e,t){return this.tracker.has(e)||this.tracker.set(e,[]),this.tracker.get(e).push(t),t}dropUpTo(e){let t=[];for(let[s,r]of this.tracker)s<=e?this.tracker.delete(s):t.push([s,r]);return t.sort(([s],[r])=>s-r),t.map(([s,r])=>r).flat()}values(){return Array.from(this.tracker.entries()).sort(([e],[t])=>e-t).map(([e,t])=>t).flat()}},$=class{constructor(e){this.options=e;this.tracker=new I}trackIntent(e,t){this.tracker.track(e,t)}onSnapshot(e){this.options.onLoadState(e.state);let t=this.tracker.dropUpTo(e.tick);t.length>0&&this.options.onReplay(t)}replay(e){this.options.onReplay(e)}};export{v as BaseBinaryCodec,k as BinaryCodec,m as BinaryPrimitives,A as EventSystem,N as FixedTicker,I as IntentTracker,W as NavMesh,g as ObjectPool,K as PooledArrayDecoder,B as PooledCodec,T as PooledDecoder,U as PooledEncoder,$ as Reconciliator,ue as generateId,ye as lerp};
1
+ var J=Object.defineProperty;var Q=(l,e)=>()=>(l&&(e=l(l=0)),e);var ee=(l,e)=>{for(var t in e)J(l,t,{get:e[t],enumerable:!0})};var W={};ee(W,{NavMeshWorkerPool:()=>E});var E,j=Q(()=>{E=class{constructor(e,t,s="grid",r=[]){this.poolSize=e;this.workerPath=t;this.navType=s;this.obstacles=r;this.workers=[];this.nextWorkerIndex=0;this.requestId=0;this.pendingRequests=new Map;this.initialized=!1}async init(){if(this.initialized)return;let e=[];for(let t=0;t<this.poolSize;t++){let s=new Worker(this.workerPath,{type:"module"});s.onmessage=o=>{let n=o.data;if(n.type==="PATH_RESULT"){let i=this.pendingRequests.get(n.id);i&&(i.resolve(n.path),this.pendingRequests.delete(n.id))}else if(n.type==="ERROR")for(let[i,a]of this.pendingRequests.entries())a.reject(new Error(n.error)),this.pendingRequests.delete(i)},s.onerror=o=>{console.error("Worker error:",o);for(let[n,i]of this.pendingRequests.entries())i.reject(new Error("Worker error")),this.pendingRequests.delete(n)},this.workers.push(s);let r=new Promise(o=>{let n=i=>{i.data.type==="READY"&&(s.removeEventListener("message",n),o())};s.addEventListener("message",n)});s.postMessage({type:"INIT",navType:this.navType,obstacles:this.obstacles}),e.push(r)}await Promise.all(e),this.initialized=!0}async findPath(e,t){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let s=this.requestId++,r=this.workers[this.nextWorkerIndex];return this.nextWorkerIndex=(this.nextWorkerIndex+1)%this.workers.length,new Promise((o,n)=>{this.pendingRequests.set(s,{id:s,from:e,to:t,resolve:o,reject:n}),r.postMessage({type:"FIND_PATH",id:s,from:e,to:t})})}async addObstacle(e){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let t=this.workers.map(r=>new Promise(o=>{let n=i=>{i.data.type==="OBSTACLE_ADDED"&&(r.removeEventListener("message",n),o(i.data.obstacleId))};r.addEventListener("message",n),r.postMessage({type:"ADD_OBSTACLE",obstacle:e})}));return(await Promise.all(t))[0]}async removeObstacle(e){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let t=this.workers.map(s=>new Promise(r=>{let o=n=>{n.data.type==="OBSTACLE_REMOVED"&&(s.removeEventListener("message",o),r())};s.addEventListener("message",o),s.postMessage({type:"REMOVE_OBSTACLE",obstacleId:e})}));await Promise.all(t)}async moveObstacle(e,t){if(!this.initialized)throw new Error("Worker pool not initialized. Call init() first.");let s=this.workers.map(r=>new Promise(o=>{let n=i=>{i.data.type==="OBSTACLE_MOVED"&&(r.removeEventListener("message",n),o())};r.addEventListener("message",n),r.postMessage({type:"MOVE_OBSTACLE",obstacleId:e,pos:t})}));await Promise.all(s)}terminate(){for(let e of this.workers)e.terminate();this.workers=[],this.pendingRequests.clear(),this.initialized=!1}get pendingCount(){return this.pendingRequests.size}get size(){return this.workers.length}}});var N=Symbol("schemaSize");function C(l){let e=l[N];if(e!==void 0)return e;let t=0;for(let s of Object.keys(l))t+=l[s].size;return l[N]=t,t}var S=class{static encodeInto(e,t){let s=C(e),r=new ArrayBuffer(s),o=new DataView(r),n=0;for(let i of Object.keys(e)){let a=e[i];a.write(o,n,t[i]),n+=a.size}return new Uint8Array(r)}static decodeInto(e,t,s){let r=C(e);if(t.byteLength<r)throw new RangeError(`Buffer too small: expected ${r} bytes, got ${t.byteLength}`);let o=new DataView(t.buffer,t.byteOffset,t.byteLength),n=0;for(let i of Object.keys(e)){let a=e[i];s[i]=a.read(o,n),n+=a.size}return s}},y=class{static{this.u8={size:1,write:(e,t,s)=>e.setUint8(t,s),read:(e,t)=>e.getUint8(t),toNil:()=>0}}static{this.u16={size:2,write:(e,t,s)=>e.setUint16(t,s,!1),read:(e,t)=>e.getUint16(t,!1),toNil:()=>0}}static{this.u32={size:4,write:(e,t,s)=>e.setUint32(t,s,!1),read:(e,t)=>e.getUint32(t,!1),toNil:()=>0}}static{this.i8={size:1,write:(e,t,s)=>e.setInt8(t,s),read:(e,t)=>e.getInt8(t),toNil:()=>0}}static{this.i16={size:2,write:(e,t,s)=>e.setInt16(t,s,!1),read:(e,t)=>e.getInt16(t,!1),toNil:()=>0}}static{this.i32={size:4,write:(e,t,s)=>e.setInt32(t,s,!1),read:(e,t)=>e.getInt32(t,!1),toNil:()=>0}}static{this.f32={size:4,write:(e,t,s)=>e.setFloat32(t,s,!1),read:(e,t)=>e.getFloat32(t,!1),toNil:()=>0}}static{this.f64={size:8,write:(e,t,s)=>e.setFloat64(t,s,!1),read:(e,t)=>e.getFloat64(t,!1),toNil:()=>0}}static{this.bool={size:1,write:(e,t,s)=>e.setUint8(t,s?1:0),read:(e,t)=>e.getUint8(t)!==0,toNil:()=>!1}}static string(e){return{size:e+2,write(t,s,r){let n=new TextEncoder().encode(r);if(n.length>e)throw new RangeError(`String too long, max ${e} bytes`);t.setUint16(s,n.length,!1);for(let i=0;i<n.length;i++)t.setUint8(s+2+i,n[i]);for(let i=n.length;i<e;i++)t.setUint8(s+2+i,0)},read(t,s){let r=t.getUint16(s,!1),o=new Uint8Array(r);for(let n=0;n<r;n++)o[n]=t.getUint8(s+2+n);return new TextDecoder().decode(o)},toNil:()=>""}}static{this.vec2={size:8,write(e,t,s){e.setFloat32(t,s.x,!1),e.setFloat32(t+4,s.y,!1)},read(e,t){return{x:e.getFloat32(t,!1),y:e.getFloat32(t+4,!1)}},toNil:()=>({x:0,y:0})}}static{this.vec3={size:12,write(e,t,s){e.setFloat32(t,s.x,!1),e.setFloat32(t+4,s.y,!1),e.setFloat32(t+8,s.z,!1)},read(e,t){return{x:e.getFloat32(t,!1),y:e.getFloat32(t+4,!1),z:e.getFloat32(t+8,!1)}},toNil:()=>({x:0,y:0,z:0})}}static{this.color={size:4,write(e,t,s){e.setUint8(t,s.r),e.setUint8(t+1,s.g),e.setUint8(t+2,s.b),e.setUint8(t+3,s.a)},read(e,t){return{r:e.getUint8(t),g:e.getUint8(t+1),b:e.getUint8(t+2),a:e.getUint8(t+3)}},toNil:()=>({r:0,g:0,b:0,a:0})}}static{this.f32_le={size:4,write:(e,t,s)=>e.setFloat32(t,s,!0),read:(e,t)=>e.getFloat32(t,!0),toNil:()=>0}}static{this.f64_le={size:8,write:(e,t,s)=>e.setFloat64(t,s,!0),read:(e,t)=>e.getFloat64(t,!0),toNil:()=>0}}static{this.u16_le={size:2,write:(e,t,s)=>e.setUint16(t,s,!0),read:(e,t)=>e.getUint16(t,!0),toNil:()=>0}}static{this.u32_le={size:4,write:(e,t,s)=>e.setUint32(t,s,!0),read:(e,t)=>e.getUint32(t,!0),toNil:()=>0}}static{this.i16_le={size:2,write:(e,t,s)=>e.setInt16(t,s,!0),read:(e,t)=>e.getInt16(t,!0),toNil:()=>0}}static{this.i32_le={size:4,write:(e,t,s)=>e.setInt32(t,s,!0),read:(e,t)=>e.getInt32(t,!0),toNil:()=>0}}static{this.vec2_le={size:8,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0)],toNil:()=>[0,0]}}static{this.vec3_le={size:12,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0),e.setFloat32(t+8,s[2],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0),e.getFloat32(t+8,!0)],toNil:()=>[0,0,0]}}static{this.vec4_le={size:16,write:(e,t,s)=>{e.setFloat32(t,s[0],!0),e.setFloat32(t+4,s[1],!0),e.setFloat32(t+8,s[2],!0),e.setFloat32(t+12,s[3],!0)},read:(e,t)=>[e.getFloat32(t,!0),e.getFloat32(t+4,!0),e.getFloat32(t+8,!0),e.getFloat32(t+12,!0)],toNil:()=>[0,0,0,0]}}},x=class extends S{static{this.u8=y.u8}static{this.u16=y.u16}static{this.u32=y.u32}static{this.i8=y.i8}static{this.i16=y.i16}static{this.i32=y.i32}static{this.f32=y.f32}static{this.bool=y.bool}static{this.string=y.string}static{this.vec2=y.vec2}static{this.vec3=y.vec3}static{this.color=y.color}static encode(e,t){return this.encodeInto(e,t)}static decode(e,t,s){return this.decodeInto(e,t,s)}};var D=class{constructor({events:e}){this.callbacks=new Map,this.events=e;for(let t of this.events)this.callbacks.set(t,new Set)}on(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);s.add(t)}once(e,t){let s=r=>{t(r),this.off(e,s)};this.on(e,s)}emit(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);for(let r of s)r(t)}off(e,t){let s=this.callbacks.get(e);if(!s)return console.warn(`Event "${e}" does not exist.`);s.delete(t)}clear(e){if(!e){this.callbacks.clear();for(let s of this.events)this.callbacks.set(s,new Set);return}let t=this.callbacks.get(e);if(!t)return console.warn(`Event "${e}" does not exist.`);t.clear()}};var _=class{constructor({rate:e,onTick:t}){this.accumulator=0;this._tickCount=0;this.rate=e,this.intervalMs=1e3/this.rate,this.onTick=t,this.maxTicksPerFrame=Math.max(1,Math.floor(e/2))}getTicks(e){this.accumulator+=e*1e3;let t=0;for(;this.accumulator>=this.intervalMs&&t<this.maxTicksPerFrame;)this.accumulator-=this.intervalMs,t++;let s=Math.floor(this.accumulator/this.intervalMs);return s>0&&this.onTickSkipped&&this.onTickSkipped(s),t}tick(e){let t=this.getTicks(e);for(let s=0;s<t;s++)this.onTick(1/this.rate,this._tickCount++)}get tickCount(){return this._tickCount}resetTickCount(){this._tickCount=0}get accumulatedTime(){return this.accumulator/1e3}get alpha(){return Math.min(this.accumulatedTime/(1/this.rate),1)}};function me(l={}){let{prefix:e="",size:t=16}=l,s=Math.max(t-e.length,8),r=Math.ceil(s/8),n=crypto.getRandomValues(new Uint32Array(r)).reduce((i,a)=>i+a.toString(16).padStart(8,"0"),"");return n=n.slice(0,s).padStart(s,"0"),`${e}${n}`}function xe(l,e,t){return l+(e-l)*t}var v=class{constructor(e){this.update=e;this.last=performance.now();this.running=!1;this.loop=()=>{if(!this.running)return;let e=performance.now(),t=(e-this.last)/1e3;this.last=e,this.update(t),setImmediate(this.loop)}}start(){this.running=!0,this.last=performance.now(),this.loop()}stop(){this.running=!1}};var w=class{constructor(e){this.update=e;this.last=performance.now();this.running=!1;this.rafId=null;this.loop=()=>{if(!this.running)return;let e=performance.now(),t=(e-this.last)/1e3;this.last=e,this.update(t),requestAnimationFrame(this.loop)}}start(){this.running=!0,this.last=performance.now(),this.rafId=requestAnimationFrame(this.loop)}stop(){this.running=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}};var te=1,T=class{constructor(e){this.update=e;this.last=performance.now();this.running=!1;this.loop=()=>{if(!this.running)return;let e=performance.now(),t=(e-this.last)/1e3;this.last=e,this.update(t),setTimeout(this.loop,te)}}start(){this.running=!0,this.last=performance.now(),this.loop()}stop(){this.running=!1}};function Ue(l,e){return l==="server-immediate"?new v(e):l==="server-timeout"?new T(e):new w(e)}var se=[{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}],z=l=>({x:Math.floor(l.x),y:Math.floor(l.y)}),L=l=>({x:l.x+.5,y:l.y+.5}),re=(()=>{let l=1;return()=>l++})(),b=(l,e)=>l&65535|(e&65535)<<16,M=l=>({x:l<<16>>16,y:l>>16}),F=class{constructor(e){this.scoreFn=e;this.heap=[]}push(e){this.heap.push(e),this.bubbleUp(this.heap.length-1)}pop(){let e=this.heap[0],t=this.heap.pop();return this.heap.length>0&&t!==void 0&&(this.heap[0]=t,this.sinkDown(0)),e}get size(){return this.heap.length}bubbleUp(e){let t=this.heap[e],s=this.scoreFn(t);for(;e>0;){let r=(e+1>>1)-1,o=this.heap[r];if(s>=this.scoreFn(o))break;this.heap[r]=t,this.heap[e]=o,e=r}}sinkDown(e){let t=this.heap.length,s=this.heap[e],r=this.scoreFn(s);for(;;){let o=e+1<<1,n=o-1,i=null,a;if(n<t){let c=this.heap[n];a=this.scoreFn(c),a<r&&(i=n)}if(o<t){let c=this.heap[o];this.scoreFn(c)<(i===null?r:a)&&(i=o)}if(i===null)break;this.heap[e]=this.heap[i],this.heap[i]=s,e=i}}},P=class{constructor(e=1){this.grid=new Map;this.obstacleCells=new Map;this.cellSize=e}hash(e,t){let s=Math.floor(e/this.cellSize),r=Math.floor(t/this.cellSize);return b(s,r)}add(e,t){let s=this.getCellsForObstacle(t);for(let r of s)this.grid.has(r)||this.grid.set(r,new Set),this.grid.get(r).add(e);this.obstacleCells.set(e,s)}remove(e){let t=this.obstacleCells.get(e);if(t){for(let s of t){let r=this.grid.get(s);r&&(r.delete(e),r.size===0&&this.grid.delete(s))}this.obstacleCells.delete(e)}}query(e){let t=this.hash(e.x,e.y);return this.grid.get(t)||new Set}clear(){this.grid.clear(),this.obstacleCells.clear()}getCellsForObstacle(e){let t=new Set;if(e.type==="circle"){let s=e.radius,r=Math.floor((e.pos.x-s)/this.cellSize),o=Math.floor((e.pos.x+s)/this.cellSize),n=Math.floor((e.pos.y-s)/this.cellSize),i=Math.floor((e.pos.y+s)/this.cellSize);for(let a=r;a<=o;a++)for(let c=n;c<=i;c++)t.add(b(a,c))}else if(e.type==="rect"){let s=e.pos.x+e.size.x/2,r=e.pos.y+e.size.y/2,o=e.size.x/2,n=e.size.y/2,i=Math.sqrt(o*o+n*n),a=Math.floor((s-i)/this.cellSize),c=Math.floor((s+i)/this.cellSize),u=Math.floor((r-i)/this.cellSize),d=Math.floor((r+i)/this.cellSize);for(let h=a;h<=c;h++)for(let f=u;f<=d;f++)t.add(b(h,f))}else if(e.type==="polygon"){let s=B(e),r=Math.floor(s.minX/this.cellSize),o=Math.floor(s.maxX/this.cellSize),n=Math.floor(s.minY/this.cellSize),i=Math.floor(s.maxY/this.cellSize);for(let a=r;a<=o;a++)for(let c=n;c<=i;c++)t.add(b(a,c))}return t}};function Y(l,e){let t=l.x-e.pos.x,s=l.y-e.pos.y;return t*t+s*s<=e.radius*e.radius}function X(l,e){let t=e.pos.x+e.size.x/2,s=e.pos.y+e.size.y/2;if(e.rotation){let r=Math.cos(-e.rotation),o=Math.sin(-e.rotation),n=l.x-t,i=l.y-s,a=n*r-i*o,c=n*o+i*r;return Math.abs(a)<=e.size.x/2&&Math.abs(c)<=e.size.y/2}return l.x>=e.pos.x&&l.y>=e.pos.y&&l.x<=e.pos.x+e.size.x&&l.y<=e.pos.y+e.size.y}function K(l,e){let t=!1,s=e.points,r=e.rotation?Math.cos(e.rotation):1,o=e.rotation?Math.sin(e.rotation):0;for(let n=0,i=s.length-1;n<s.length;i=n++){let a=s[n].x,c=s[n].y,u=s[i].x,d=s[i].y;if(e.rotation){let f=a*r-c*o,m=a*o+c*r,p=u*r-d*o,k=u*o+d*r;a=f,c=m,u=p,d=k}a+=e.pos.x,c+=e.pos.y,u+=e.pos.x,d+=e.pos.y,c>l.y!=d>l.y&&l.x<(u-a)*(l.y-c)/(d-c)+a&&(t=!t)}return t}function B(l){let e=1/0,t=1/0,s=-1/0,r=-1/0,o=l.rotation?Math.cos(l.rotation):1,n=l.rotation?Math.sin(l.rotation):0;for(let i of l.points){let a=i.x,c=i.y;if(l.rotation){let u=a*o-c*n,d=a*n+c*o;a=u,c=d}a+=l.pos.x,c+=l.pos.y,e=Math.min(e,a),t=Math.min(t,c),s=Math.max(s,a),r=Math.max(r,c)}return{minX:e,minY:t,maxX:s,maxY:r}}var U=class{constructor(){this.items=new Map;this.spatial=new P(1);this._cachedItems=[];this.dirty=!0;this.version=0}add(e){let t=re(),s={...e,id:t};return this.items.set(t,s),this.spatial.add(t,s),this.dirty=!0,this.version++,t}move(e,t){let s=this.items.get(e);if(!s)return;this.spatial.remove(e);let r={...s,pos:{...t}};this.items.set(e,r),this.spatial.add(e,r),this.dirty=!0,this.version++}remove(e){this.spatial.remove(e),this.items.delete(e),this.dirty=!0,this.version++}at(e){let t=this.spatial.query(e);for(let s of t){let r=this.items.get(s);if(!(!r||r.solid===!1)&&(r.type==="circle"&&Y(e,r)||r.type==="rect"&&X(e,r)||r.type==="polygon"&&K(e,r)))return r}}get values(){return this.dirty?(this._cachedItems=[...this.items.values()],this.dirty=!1,this._cachedItems):this._cachedItems}},I=class{constructor(e){this.obstacles=e;this.blocked=new Set}rebuild(){this.blocked.clear();for(let e of this.obstacles.values)if(e.solid!==!1){if(e.type==="circle"){let t=Math.ceil(e.radius),s=Math.floor(e.pos.x),r=Math.floor(e.pos.y);for(let o=-t;o<=t;o++)for(let n=-t;n<=t;n++){let i=s+o,a=r+n,c={x:i+.5,y:a+.5};Y(c,e)&&this.blocked.add(b(i,a))}}else if(e.type==="rect"){let t=e.pos.x+e.size.x/2,s=e.pos.y+e.size.y/2,r=e.size.x/2,o=e.size.y/2,n=Math.sqrt(r*r+o*o),i=Math.floor(t-n),a=Math.ceil(t+n),c=Math.floor(s-n),u=Math.ceil(s+n);for(let d=i;d<=a;d++)for(let h=c;h<=u;h++){let f={x:d+.5,y:h+.5};X(f,e)&&this.blocked.add(b(d,h))}}else if(e.type==="polygon"){let t=B(e),s=Math.floor(t.minX),r=Math.ceil(t.maxX),o=Math.floor(t.minY),n=Math.ceil(t.maxY);for(let i=s;i<=r;i++)for(let a=o;a<=n;a++){let c={x:i+.5,y:a+.5};K(c,e)&&this.blocked.add(b(i,a))}}}}findPath(e,t){return $(z(e),z(t),(s,r)=>!this.blocked.has(b(s,r))).map(L)}},V=class{constructor(e){this.obstacles=e}rebuild(){}findPath(e,t){let s=Math.ceil(Math.hypot(t.x-e.x,t.y-e.y)*2),r=!1;for(let n=1;n<=s;n++){let i=n/s,a={x:e.x+(t.x-e.x)*i,y:e.y+(t.y-e.y)*i};if(this.obstacles.at(a)){r=!0;break}}return r?$(z(e),z(t),(n,i)=>{let a={x:n+.5,y:i+.5};return!this.obstacles.at(a)}).map(L):[e,t]}},q=class{constructor(e,t){this.type=e;this.lastVersion=-1;this.pendingPaths=0;this.AUTO_WORKER_THRESHOLD=20;this.obstacles=new U,this.options={workers:t?.workers??!1,workerPoolSize:t?.workerPoolSize??4,workerPath:t?.workerPath??"./navmesh.worker.js"},e==="grid"&&(this.grid=new I(this.obstacles)),e==="graph"&&(this.graph=new V(this.obstacles)),this.options.workers===!0&&this.initWorkerPool()}async initWorkerPool(){if(!this.workerPool)try{let{NavMeshWorkerPool:e}=await Promise.resolve().then(()=>(j(),W));this.workerPool=new e(this.options.workerPoolSize,this.options.workerPath,this.type,this.obstacles.values),await this.workerPool.init()}catch(e){console.warn("Failed to initialize worker pool, falling back to sync:",e),this.options.workers=!1}}shouldUseWorkers(){return this.options.workers===!1?!1:this.options.workers===!0?!0:this.pendingPaths>=this.AUTO_WORKER_THRESHOLD}addObstacle(e){return this.obstacles.add(e)}moveObstacle(e,t){this.obstacles.move(e,t)}removeObstacle(e){this.obstacles.remove(e)}getObstacles(){return this.obstacles.values}findPath({from:e,to:t}){return this.shouldUseWorkers()&&this.workerPool?(this.pendingPaths++,this.findPathAsync(e,t).finally(()=>{this.pendingPaths--})):(this.rebuild(),this.type==="grid"?this.grid.findPath(e,t):this.graph.findPath(e,t))}async findPathAsync(e,t){return this.options.workers==="auto"&&!this.workerPool&&await this.initWorkerPool(),this.workerPool?this.workerPool.findPath(e,t):(this.rebuild(),this.type==="grid"?this.grid.findPath(e,t):this.graph.findPath(e,t))}rebuild(){this.lastVersion!==this.obstacles.version&&(this.grid?.rebuild(),this.graph?.rebuild(),this.lastVersion=this.obstacles.version)}dispose(){this.workerPool&&(this.workerPool.terminate(),this.workerPool=void 0)}getWorkerStatus(){return{workersEnabled:this.options.workers,workerPoolActive:!!this.workerPool,pendingPaths:this.pendingPaths,usingWorkersNow:this.shouldUseWorkers()}}};function $(l,e,t){let s=new Map,r=new Map,o=new Set,n=new Set,i=d=>b(d.x,d.y),a=(d,h)=>Math.abs(d.x-h.x)+Math.abs(d.y-h.y),c=new F(d=>{let h=M(d);return r.get(d)+a(h,e)}),u=i(l);for(r.set(u,0),c.push(u),n.add(u);c.size>0;){let d=c.pop();n.delete(d);let h=M(d);if(h.x===e.x&&h.y===e.y)return ne(s,h);o.add(d);for(let f of se){let m={x:h.x+f.x,y:h.y+f.y};if(!t(m.x,m.y))continue;let p=i(m);if(o.has(p))continue;let k=r.get(d)+1;k<(r.get(p)??1/0)&&(r.set(p,k),s.set(p,d),n.has(p)||(c.push(p),n.add(p)))}}return[]}function ne(l,e){let t=[e],s=b(e.x,e.y);for(;l.has(s);)s=l.get(s),t.push(M(s));return t.reverse()}var g=class{constructor(e){this.factory=e;this.pool=[]}acquire(){return this.pool.pop()??this.factory()}release(e){this.pool.push(e)}releaseAll(e){this.pool.push(...e)}},O=class{constructor(e){this.schema=e;this.pool=new g(()=>this.createNil())}createNil(){let e={};for(let t of Object.keys(this.schema)){let s=this.schema[t];e[t]="toNil"in s?s.toNil():void 0}return e}decode(e){let t=this.pool.acquire();return this.decodeInto(e,t),t}decodeInto(e,t){let s=0;for(let r of Object.keys(this.schema)){let o=this.schema[r];if("decodeAll"in o){let n=o.decodeAll(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else if("decodeField"in o){let n=o.decodeField(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else if("decode"in o){let n=o.decode(e.subarray(s));t[r]=n.value,s+=n.bytesRead}else{let n=o.size||0,i=e.subarray(s,s+n);x.decodeInto({[r]:o},i,t),s+=n}}}release(e){this.pool.release(e)}},H=class{constructor(e){this.pooledDecoder=new O(e)}decodeAll(e){return e.map(t=>this.pooledDecoder.decode(t))}releaseAll(e){e.forEach(t=>this.pooledDecoder.release(t))}},A=class{constructor(e,t=1024){this.schema=e;this.bufferSize=t;this.pool=new g(()=>new Uint8Array(t))}encode(e){let t=this.pool.acquire(),s=0;for(let r of Object.keys(this.schema)){let o=this.schema[r];if("encode"in o){let n=o.encode(e[r]);t.set(n,s),s+=n.length}else if("encodeAll"in o){let n=o.encodeAll(e[r]),i=0;for(let a of n)t.set(a,s+i),i+=a.length;s+=i}else{let n=x.encode({[r]:o},{[r]:e[r]});t.set(n,s),s+=n.length}}return t.subarray(0,s)}release(e){this.pool.release(e)}},G=class{constructor(e){this.schema=e;this.encoder=new A(e),this.decoder=new O(e)}calculateSize(e){let t=0;for(let s of Object.keys(this.schema)){let r=this.schema[s];"size"in r?t+=r.size:"calculateSize"in r&&(t+=r.calculateSize(e[s]))}return t}encodeInto(e,t,s){let r=new DataView(t.buffer,t.byteOffset),o=s;for(let n of Object.keys(this.schema)){let i=this.schema[n];if("write"in i)i.write(r,o,e[n]),o+=i.size;else if("encodeInto"in i){let a=i.encodeInto(e[n],t,o);o+=a}else if("encode"in i){let a=i.encode(e[n]);t.set(a,o),o+=a.length}}return o-s}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}release(e){this.decoder.release(e)}static array(e){let t=0;for(let a of Object.keys(e)){let c=e[a];t+=c.size||0}let s=new g(()=>new Uint8Array(16384)),r=new g(()=>{let a={};for(let c of Object.keys(e)){let u=e[c];a[c]="toNil"in u?u.toNil():void 0}return a}),o=new g(()=>[]),n=null,i=null;return{__arrayType:void 0,calculateSize(a){return 2+a.length*t},encodeInto(a,c,u){let d=new DataView(c.buffer,c.byteOffset);d.setUint16(u,a.length,!1);let h=u+2;for(let f of a)for(let m of Object.keys(e)){let p=e[m];p.write(d,h,f[m]),h+=p.size}return h-u},encode(a){let c=2+a.length*t,u=s.acquire();u.length<c&&(s.release(u),u=new Uint8Array(Math.max(c,u.length*2))),(!n||n.buffer!==u.buffer)&&(n=new DataView(u.buffer,u.byteOffset)),n.setUint16(0,a.length,!1);let d=2;for(let f of a)for(let m of Object.keys(e)){let p=e[m];p.write(n,d,f[m]),d+=p.size}let h=new Uint8Array(d);return h.set(u.subarray(0,d)),s.release(u),h},decodeField(a){let c=a[0]<<8|a[1],u=o.acquire();u.length=c,(!i||i.buffer!==a.buffer||i.byteOffset!==a.byteOffset)&&(i=new DataView(a.buffer,a.byteOffset));let d=2;for(let h=0;h<c;h++){let f=r.acquire();for(let m of Object.keys(e)){let p=e[m];f[m]=p.read(i,d),d+=p.size}u[h]=f}return{value:u,bytesRead:d}},decode(a){return this.decodeField(a).value},toNil(){return[]}}}};var R=class{constructor(){this.tracker=new Map}get size(){return this.tracker.size}track(e,t){return this.tracker.has(e)||this.tracker.set(e,[]),this.tracker.get(e).push(t),t}dropUpTo(e){let t=[];for(let[s,r]of this.tracker)s<=e?this.tracker.delete(s):t.push([s,r]);return t.sort(([s],[r])=>s-r),t.map(([s,r])=>r).flat()}values(){return Array.from(this.tracker.entries()).sort(([e],[t])=>e-t).map(([e,t])=>t).flat()}},Z=class{constructor(e){this.options=e;this.tracker=new R}trackIntent(e,t){this.tracker.track(e,t)}onSnapshot(e){this.options.onLoadState(e.state);let t=this.tracker.dropUpTo(e.tick);t.length>0&&this.options.onReplay(t)}replay(e){this.options.onReplay(e)}};export{S as BaseBinaryCodec,x as BinaryCodec,y as BinaryPrimitives,D as EventSystem,_ as FixedTicker,v as ImmediateDriver,R as IntentTracker,q as NavMesh,g as ObjectPool,H as PooledArrayDecoder,G as PooledCodec,O as PooledDecoder,A as PooledEncoder,w as RafDriver,Z as Reconciliator,T as TimeoutDriver,Ue as createDriver,me as generateId,xe as lerp};