murow 0.0.70 → 0.0.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -37
- package/dist/cjs/core/binary-codec/binary-codec.js +1 -0
- package/dist/cjs/core/binary-codec/index.js +1 -0
- package/dist/cjs/core/driver/driver.js +1 -0
- package/dist/cjs/core/driver/drivers/immediate.js +1 -0
- package/dist/cjs/core/driver/drivers/index.js +1 -0
- package/dist/cjs/core/driver/drivers/raf.js +1 -0
- package/dist/cjs/core/driver/drivers/timeout.js +1 -0
- package/dist/cjs/core/driver/index.js +1 -0
- package/dist/cjs/core/events/event-system.js +1 -0
- package/dist/cjs/core/events/index.js +1 -0
- package/dist/cjs/core/fixed-ticker/fixed-ticker.js +1 -0
- package/dist/cjs/core/fixed-ticker/index.js +1 -0
- package/dist/cjs/core/free-list/free-list.js +1 -0
- package/dist/cjs/core/free-list/index.js +1 -0
- package/dist/cjs/core/generate-id/generate-id.js +1 -0
- package/dist/cjs/core/generate-id/index.js +1 -0
- package/dist/cjs/core/index.js +1 -0
- package/dist/cjs/core/input/index.js +1 -0
- package/dist/cjs/core/input/manager.js +1 -0
- package/dist/cjs/core/input/sources/browser.js +1 -0
- package/dist/cjs/core/input/sources/index.js +1 -0
- package/dist/cjs/core/input/types.js +1 -0
- package/dist/cjs/core/lerp/index.js +1 -0
- package/dist/cjs/core/lerp/lerp.js +1 -0
- package/dist/cjs/core/navmesh/index.js +1 -0
- package/dist/cjs/core/navmesh/navmesh-worker-pool.js +1 -0
- package/dist/cjs/core/navmesh/navmesh.js +1 -0
- package/dist/cjs/core/navmesh/navmesh.worker.js +1 -0
- package/dist/cjs/core/pooled-codec/index.js +1 -0
- package/dist/cjs/core/pooled-codec/pooled-codec.js +1 -0
- package/dist/cjs/core/prediction/index.js +1 -0
- package/dist/cjs/core/prediction/prediction.js +1 -0
- package/dist/cjs/core/ray/index.js +1 -0
- package/dist/cjs/core/ray/ray-2d.js +1 -0
- package/dist/cjs/core/ray/ray-3d.js +1 -0
- package/dist/cjs/core/simple-rng/index.js +1 -0
- package/dist/cjs/core/simple-rng/simple-rng.js +1 -0
- package/dist/cjs/core/sparse-batcher/index.js +1 -0
- package/dist/cjs/core/sparse-batcher/sparse-batcher.js +1 -0
- package/dist/cjs/ecs/component-store.js +1 -0
- package/dist/cjs/ecs/component.js +1 -0
- package/dist/cjs/ecs/entity-handle.js +1 -0
- package/dist/cjs/ecs/index.js +1 -0
- package/dist/cjs/ecs/system-builder.js +1 -0
- package/dist/cjs/ecs/world-systems.js +1 -0
- package/dist/cjs/ecs/world.js +1 -0
- package/dist/cjs/game/index.js +1 -0
- package/dist/cjs/game/loop/index.js +1 -0
- package/dist/cjs/game/loop/loop.js +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/net/adapters/browser-websocket.js +1 -0
- package/dist/cjs/net/adapters/bun-websocket.js +1 -0
- package/dist/cjs/net/buffer-pool.js +1 -0
- package/dist/cjs/net/client.js +1 -0
- package/dist/cjs/net/index.js +1 -0
- package/dist/cjs/net/server.js +1 -0
- package/dist/cjs/net/types.js +1 -0
- package/dist/cjs/net/validators.js +1 -0
- package/dist/cjs/protocol/index.js +1 -0
- package/dist/cjs/protocol/intent/define-intent.js +1 -0
- package/dist/cjs/protocol/intent/index.js +1 -0
- package/dist/cjs/protocol/intent/intent-registry.js +1 -0
- package/dist/cjs/protocol/intent/intent.js +1 -0
- package/dist/cjs/protocol/rpc/define-rpc.js +1 -0
- package/dist/cjs/protocol/rpc/index.js +1 -0
- package/dist/cjs/protocol/rpc/rpc-registry.js +1 -0
- package/dist/cjs/protocol/rpc/rpc.js +1 -0
- package/dist/cjs/protocol/snapshot/index.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot-codec.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot-registry.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot.js +1 -0
- package/dist/cjs/renderer/base-2d-renderer.js +1 -0
- package/dist/cjs/renderer/base-3d-renderer.js +1 -0
- package/dist/cjs/renderer/base-renderer.js +1 -0
- package/dist/cjs/renderer/index.js +1 -0
- package/dist/cjs/renderer/types.js +1 -0
- package/dist/esm/core/binary-codec/binary-codec.js +1 -0
- package/dist/esm/core/binary-codec/index.js +1 -0
- package/dist/esm/core/driver/driver.js +1 -0
- package/dist/esm/core/driver/drivers/immediate.js +1 -0
- package/dist/esm/core/driver/drivers/index.js +1 -0
- package/dist/esm/core/driver/drivers/raf.js +1 -0
- package/dist/esm/core/driver/drivers/timeout.js +1 -0
- package/dist/esm/core/driver/index.js +1 -0
- package/dist/esm/core/events/event-system.js +1 -0
- package/dist/esm/core/events/index.js +1 -0
- package/dist/esm/core/fixed-ticker/fixed-ticker.js +1 -0
- package/dist/esm/core/fixed-ticker/index.js +1 -0
- package/dist/esm/core/free-list/free-list.js +1 -0
- package/dist/esm/core/free-list/index.js +1 -0
- package/dist/esm/core/generate-id/generate-id.js +1 -0
- package/dist/esm/core/generate-id/index.js +1 -0
- package/dist/esm/core/index.js +1 -0
- package/dist/esm/core/input/index.js +1 -0
- package/dist/esm/core/input/manager.js +1 -0
- package/dist/esm/core/input/sources/browser.js +1 -0
- package/dist/esm/core/input/sources/index.js +1 -0
- package/dist/esm/core/input/types.js +0 -0
- package/dist/esm/core/lerp/index.js +1 -0
- package/dist/esm/core/lerp/lerp.js +1 -0
- package/dist/esm/core/navmesh/index.js +1 -0
- package/dist/esm/core/navmesh/navmesh-worker-pool.js +1 -0
- package/dist/esm/core/navmesh/navmesh.js +1 -0
- package/dist/esm/core/navmesh/navmesh.worker.js +1 -0
- package/dist/esm/core/pooled-codec/index.js +1 -0
- package/dist/esm/core/pooled-codec/pooled-codec.js +1 -0
- package/dist/esm/core/prediction/index.js +1 -0
- package/dist/esm/core/prediction/prediction.js +1 -0
- package/dist/esm/core/ray/index.js +1 -0
- package/dist/esm/core/ray/ray-2d.js +1 -0
- package/dist/esm/core/ray/ray-3d.js +1 -0
- package/dist/esm/core/simple-rng/index.js +1 -0
- package/dist/esm/core/simple-rng/simple-rng.js +1 -0
- package/dist/esm/core/sparse-batcher/index.js +1 -0
- package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -0
- package/dist/esm/ecs/component-store.js +1 -0
- package/dist/esm/ecs/component.js +1 -0
- package/dist/esm/ecs/entity-handle.js +1 -0
- package/dist/esm/ecs/index.js +1 -0
- package/dist/esm/ecs/system-builder.js +1 -0
- package/dist/esm/ecs/world-systems.js +1 -0
- package/dist/esm/ecs/world.js +1 -0
- package/dist/esm/game/index.js +1 -0
- package/dist/esm/game/loop/index.js +1 -0
- package/dist/esm/game/loop/loop.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/net/adapters/browser-websocket.js +1 -0
- package/dist/esm/net/adapters/bun-websocket.js +1 -0
- package/dist/esm/net/buffer-pool.js +1 -0
- package/dist/esm/net/client.js +1 -0
- package/dist/esm/net/index.js +1 -0
- package/dist/esm/net/server.js +1 -0
- package/dist/esm/net/types.js +1 -0
- package/dist/esm/net/validators.js +1 -0
- package/dist/esm/protocol/index.js +1 -0
- package/dist/esm/protocol/intent/define-intent.js +1 -0
- package/dist/esm/protocol/intent/index.js +1 -0
- package/dist/esm/protocol/intent/intent-registry.js +1 -0
- package/dist/esm/protocol/intent/intent.js +0 -0
- package/dist/esm/protocol/rpc/define-rpc.js +1 -0
- package/dist/esm/protocol/rpc/index.js +1 -0
- package/dist/esm/protocol/rpc/rpc-registry.js +1 -0
- package/dist/esm/protocol/rpc/rpc.js +0 -0
- package/dist/esm/protocol/snapshot/index.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot-codec.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot-registry.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot.js +1 -0
- package/dist/esm/renderer/base-2d-renderer.js +1 -0
- package/dist/esm/renderer/base-3d-renderer.js +1 -0
- package/dist/esm/renderer/base-renderer.js +1 -0
- package/dist/esm/renderer/index.js +1 -0
- package/dist/esm/renderer/types.js +0 -0
- package/dist/{core → types/core}/binary-codec/binary-codec.d.ts +4 -0
- package/dist/{core → types/core}/events/event-system.d.ts +14 -33
- package/dist/types/core/free-list/free-list.d.ts +31 -0
- package/dist/types/core/free-list/index.d.ts +1 -0
- package/dist/{core → types/core}/index.d.ts +5 -0
- package/dist/{core → types/core}/input/index.d.ts +1 -0
- package/dist/{core → types/core}/input/manager.d.ts +2 -0
- package/dist/{core → types/core}/navmesh/navmesh.d.ts +1 -21
- package/dist/types/core/ray/index.d.ts +2 -0
- package/dist/types/core/ray/ray-2d.d.ts +37 -0
- package/dist/types/core/ray/ray-3d.d.ts +42 -0
- package/dist/types/core/simple-rng/index.d.ts +1 -0
- package/dist/types/core/simple-rng/simple-rng.d.ts +36 -0
- package/dist/types/core/sparse-batcher/index.d.ts +1 -0
- package/dist/types/core/sparse-batcher/sparse-batcher.d.ts +55 -0
- package/dist/{ecs → types/ecs}/world.d.ts +11 -0
- package/dist/{game → types/game}/loop/loop.d.ts +33 -29
- package/dist/{index.d.ts → types/index.d.ts} +1 -0
- package/dist/{net → types/net}/index.d.ts +2 -2
- package/dist/types/renderer/base-2d-renderer.d.ts +13 -0
- package/dist/types/renderer/base-3d-renderer.d.ts +10 -0
- package/dist/types/renderer/base-renderer.d.ts +21 -0
- package/dist/types/renderer/index.d.ts +4 -0
- package/dist/types/renderer/types.d.ts +79 -0
- package/dist/webgpu/cjs/index.js +6004 -0
- package/dist/webgpu/esm/index.js +5972 -0
- package/dist/webgpu/types/2d/animation.d.ts +97 -0
- package/dist/webgpu/types/2d/renderer.d.ts +55 -0
- package/dist/webgpu/types/2d/shader.d.ts +61 -0
- package/dist/webgpu/types/2d/sprite-accessor.d.ts +47 -0
- package/dist/webgpu/types/3d/gltf-skin-parser.d.ts +101 -0
- package/dist/webgpu/types/3d/morph-animation.d.ts +69 -0
- package/dist/webgpu/types/3d/morph-animation.test.d.ts +1 -0
- package/dist/webgpu/types/3d/renderer.d.ts +216 -0
- package/dist/webgpu/types/3d/shader.d.ts +136 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +2 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +8 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +32 -0
- package/dist/webgpu/types/3d/skeletal-animation.d.ts +90 -0
- package/dist/webgpu/types/camera/camera-2d.d.ts +53 -0
- package/dist/webgpu/types/camera/camera-2d.test.d.ts +1 -0
- package/dist/webgpu/types/camera/camera-3d.d.ts +81 -0
- package/dist/webgpu/types/camera/camera-3d.test.d.ts +1 -0
- package/dist/webgpu/types/camera/index.d.ts +2 -0
- package/dist/webgpu/types/compute/compute-builder.d.ts +123 -0
- package/dist/webgpu/types/compute/compute-builder.test.d.ts +1 -0
- package/dist/webgpu/types/core/constants.d.ts +59 -0
- package/dist/webgpu/types/core/constants.test.d.ts +1 -0
- package/dist/webgpu/types/core/index.d.ts +2 -0
- package/dist/webgpu/types/core/math.d.ts +37 -0
- package/dist/webgpu/types/core/types.d.ts +125 -0
- package/dist/webgpu/types/core/types.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/built-in.d.ts +58 -0
- package/dist/webgpu/types/geometry/built-in.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/geometry-builder.d.ts +281 -0
- package/dist/webgpu/types/geometry/geometry-builder.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/index.d.ts +2 -0
- package/dist/webgpu/types/index.d.ts +32 -0
- package/dist/webgpu/types/particle/emitter.d.ts +36 -0
- package/dist/webgpu/types/shaders/index.d.ts +2 -0
- package/dist/webgpu/types/shaders/runtime-transpile.d.ts +18 -0
- package/dist/webgpu/types/shaders/sprite-2d.wgsl.d.ts +10 -0
- package/dist/webgpu/types/shaders/typegpu.d.ts +9 -0
- package/dist/webgpu/types/shaders/utils.d.ts +28 -0
- package/dist/webgpu/types/shaders/utils.test.d.ts +1 -0
- package/dist/webgpu/types/spritesheet/index.d.ts +1 -0
- package/dist/webgpu/types/spritesheet/spritesheet.d.ts +57 -0
- package/dist/webgpu/types/spritesheet/spritesheet.test.d.ts +1 -0
- package/package.json +96 -26
- package/dist/core/binary-codec/binary-codec.js +0 -354
- package/dist/core/binary-codec/index.js +0 -1
- package/dist/core/driver/driver.js +0 -47
- package/dist/core/driver/drivers/immediate.js +0 -61
- package/dist/core/driver/drivers/index.js +0 -3
- package/dist/core/driver/drivers/raf.js +0 -62
- package/dist/core/driver/drivers/timeout.js +0 -71
- package/dist/core/driver/index.js +0 -2
- package/dist/core/events/event-system.js +0 -88
- package/dist/core/events/index.js +0 -1
- package/dist/core/fixed-ticker/fixed-ticker.js +0 -105
- package/dist/core/fixed-ticker/index.js +0 -1
- package/dist/core/generate-id/generate-id.js +0 -25
- package/dist/core/generate-id/index.js +0 -1
- package/dist/core/index.js +0 -10
- package/dist/core/input/index.js +0 -2
- package/dist/core/input/manager.js +0 -211
- package/dist/core/input/sources/browser.js +0 -29
- package/dist/core/input/sources/index.js +0 -1
- package/dist/core/lerp/index.js +0 -1
- package/dist/core/lerp/lerp.js +0 -42
- package/dist/core/navmesh/index.js +0 -1
- package/dist/core/navmesh/navmesh-worker-pool.js +0 -180
- package/dist/core/navmesh/navmesh.js +0 -799
- package/dist/core/navmesh/navmesh.worker.js +0 -79
- package/dist/core/pooled-codec/index.js +0 -1
- package/dist/core/pooled-codec/pooled-codec.js +0 -410
- package/dist/core/prediction/index.js +0 -1
- package/dist/core/prediction/prediction.js +0 -99
- package/dist/core.esm.js +0 -1
- package/dist/core.js +0 -1
- package/dist/ecs/component-store.js +0 -175
- package/dist/ecs/component.js +0 -43
- package/dist/ecs/entity-handle.js +0 -515
- package/dist/ecs/example.js +0 -125
- package/dist/ecs/index.js +0 -4
- package/dist/ecs/system-builder.js +0 -249
- package/dist/ecs/world-systems.js +0 -79
- package/dist/ecs/world.js +0 -767
- package/dist/game/index.js +0 -1
- package/dist/game/loop/index.js +0 -1
- package/dist/game/loop/loop.js +0 -108
- package/dist/index.js +0 -26
- package/dist/net/adapters/browser-websocket.js +0 -74
- package/dist/net/adapters/bun-websocket.js +0 -245
- package/dist/net/buffer-pool.js +0 -89
- package/dist/net/client.js +0 -586
- package/dist/net/index.js +0 -58
- package/dist/net/server.js +0 -974
- package/dist/net/types.js +0 -31
- package/dist/net/validators.js +0 -88
- package/dist/protocol/index.js +0 -92
- package/dist/protocol/intent/define-intent.js +0 -125
- package/dist/protocol/intent/index.js +0 -91
- package/dist/protocol/intent/intent-registry.js +0 -91
- package/dist/protocol/rpc/define-rpc.js +0 -84
- package/dist/protocol/rpc/index.js +0 -3
- package/dist/protocol/rpc/rpc-registry.js +0 -159
- package/dist/protocol/rpc/rpc.js +0 -12
- package/dist/protocol/snapshot/index.js +0 -43
- package/dist/protocol/snapshot/snapshot-codec.js +0 -67
- package/dist/protocol/snapshot/snapshot-registry.js +0 -168
- package/dist/protocol/snapshot/snapshot.js +0 -30
- package/src/core/binary-codec/README.md +0 -60
- package/src/core/binary-codec/binary-codec.test.ts +0 -300
- package/src/core/binary-codec/binary-codec.ts +0 -448
- package/src/core/binary-codec/index.ts +0 -1
- package/src/core/driver/README.md +0 -97
- package/src/core/driver/driver.test.ts +0 -414
- package/src/core/driver/driver.ts +0 -71
- package/src/core/driver/drivers/immediate.ts +0 -66
- package/src/core/driver/drivers/index.ts +0 -3
- package/src/core/driver/drivers/raf.ts +0 -67
- package/src/core/driver/drivers/timeout.ts +0 -77
- package/src/core/driver/index.ts +0 -2
- package/src/core/events/README.md +0 -47
- package/src/core/events/event-system.test.ts +0 -243
- package/src/core/events/event-system.ts +0 -140
- package/src/core/events/index.ts +0 -1
- package/src/core/fixed-ticker/README.md +0 -77
- package/src/core/fixed-ticker/fixed-ticker.test.ts +0 -151
- package/src/core/fixed-ticker/fixed-ticker.ts +0 -174
- package/src/core/fixed-ticker/index.ts +0 -1
- package/src/core/generate-id/README.md +0 -18
- package/src/core/generate-id/generate-id.test.ts +0 -79
- package/src/core/generate-id/generate-id.ts +0 -37
- package/src/core/generate-id/index.ts +0 -1
- package/src/core/index.ts +0 -10
- package/src/core/input/README.md +0 -24
- package/src/core/input/index.ts +0 -2
- package/src/core/input/manager.ts +0 -259
- package/src/core/input/sources/browser.ts +0 -39
- package/src/core/input/sources/index.ts +0 -1
- package/src/core/input/types.ts +0 -40
- package/src/core/lerp/README.md +0 -79
- package/src/core/lerp/index.ts +0 -1
- package/src/core/lerp/lerp.test.ts +0 -90
- package/src/core/lerp/lerp.ts +0 -42
- package/src/core/navmesh/README.md +0 -164
- package/src/core/navmesh/index.ts +0 -1
- package/src/core/navmesh/navmesh-worker-pool.ts +0 -236
- package/src/core/navmesh/navmesh-workers.test.ts +0 -356
- package/src/core/navmesh/navmesh.test.ts +0 -344
- package/src/core/navmesh/navmesh.ts +0 -1047
- package/src/core/navmesh/navmesh.worker.ts +0 -147
- package/src/core/pooled-codec/README.md +0 -70
- package/src/core/pooled-codec/index.ts +0 -1
- package/src/core/pooled-codec/pooled-codec.test.ts +0 -862
- package/src/core/pooled-codec/pooled-codec.ts +0 -504
- package/src/core/prediction/README.md +0 -64
- package/src/core/prediction/index.ts +0 -1
- package/src/core/prediction/prediction.test.ts +0 -423
- package/src/core/prediction/prediction.ts +0 -112
- package/src/ecs/README.md +0 -427
- package/src/ecs/benchmark.test.ts +0 -1645
- package/src/ecs/component-store.ts +0 -198
- package/src/ecs/component.ts +0 -90
- package/src/ecs/entity-handle.test.ts +0 -393
- package/src/ecs/entity-handle.ts +0 -563
- package/src/ecs/example.ts +0 -152
- package/src/ecs/index.ts +0 -4
- package/src/ecs/system-builder.ts +0 -404
- package/src/ecs/world-systems.ts +0 -83
- package/src/ecs/world.test.ts +0 -310
- package/src/ecs/world.ts +0 -904
- package/src/game/index.ts +0 -1
- package/src/game/loop/README.md +0 -32
- package/src/game/loop/index.ts +0 -1
- package/src/game/loop/loop.ts +0 -236
- package/src/index.ts +0 -32
- package/src/net/README.md +0 -474
- package/src/net/adapters/browser-websocket.ts +0 -86
- package/src/net/adapters/bun-websocket.ts +0 -292
- package/src/net/buffer-pool.ts +0 -106
- package/src/net/client.test.ts +0 -807
- package/src/net/client.ts +0 -695
- package/src/net/index.ts +0 -60
- package/src/net/server.test.ts +0 -799
- package/src/net/server.ts +0 -1152
- package/src/net/types.ts +0 -228
- package/src/net/validators.ts +0 -104
- package/src/protocol/README.md +0 -469
- package/src/protocol/index.ts +0 -93
- package/src/protocol/intent/define-intent.test.ts +0 -397
- package/src/protocol/intent/define-intent.ts +0 -201
- package/src/protocol/intent/index.ts +0 -94
- package/src/protocol/intent/intent-registry.test.ts +0 -198
- package/src/protocol/intent/intent-registry.ts +0 -112
- package/src/protocol/intent/intent.ts +0 -12
- package/src/protocol/rpc/define-rpc.test.ts +0 -141
- package/src/protocol/rpc/define-rpc.ts +0 -113
- package/src/protocol/rpc/index.ts +0 -3
- package/src/protocol/rpc/rpc-registry.test.ts +0 -168
- package/src/protocol/rpc/rpc-registry.ts +0 -176
- package/src/protocol/rpc/rpc.ts +0 -37
- package/src/protocol/snapshot/index.ts +0 -45
- package/src/protocol/snapshot/snapshot-codec.test.ts +0 -138
- package/src/protocol/snapshot/snapshot-codec.ts +0 -87
- package/src/protocol/snapshot/snapshot-registry.test.ts +0 -310
- package/src/protocol/snapshot/snapshot-registry.ts +0 -201
- package/src/protocol/snapshot/snapshot.test.ts +0 -76
- package/src/protocol/snapshot/snapshot.ts +0 -41
- /package/dist/{core → types/core}/binary-codec/index.d.ts +0 -0
- /package/dist/{core → types/core}/driver/driver.d.ts +0 -0
- /package/dist/{core → types/core}/driver/drivers/immediate.d.ts +0 -0
- /package/dist/{core → types/core}/driver/drivers/index.d.ts +0 -0
- /package/dist/{core → types/core}/driver/drivers/raf.d.ts +0 -0
- /package/dist/{core → types/core}/driver/drivers/timeout.d.ts +0 -0
- /package/dist/{core → types/core}/driver/index.d.ts +0 -0
- /package/dist/{core → types/core}/events/index.d.ts +0 -0
- /package/dist/{core → types/core}/fixed-ticker/fixed-ticker.d.ts +0 -0
- /package/dist/{core → types/core}/fixed-ticker/index.d.ts +0 -0
- /package/dist/{core → types/core}/generate-id/generate-id.d.ts +0 -0
- /package/dist/{core → types/core}/generate-id/index.d.ts +0 -0
- /package/dist/{core → types/core}/input/sources/browser.d.ts +0 -0
- /package/dist/{core → types/core}/input/sources/index.d.ts +0 -0
- /package/dist/{core → types/core}/input/types.d.ts +0 -0
- /package/dist/{core → types/core}/lerp/index.d.ts +0 -0
- /package/dist/{core → types/core}/lerp/lerp.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/index.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/navmesh-worker-pool.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/navmesh.worker.d.ts +0 -0
- /package/dist/{core → types/core}/pooled-codec/index.d.ts +0 -0
- /package/dist/{core → types/core}/pooled-codec/pooled-codec.d.ts +0 -0
- /package/dist/{core → types/core}/prediction/index.d.ts +0 -0
- /package/dist/{core → types/core}/prediction/prediction.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/component-store.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/component.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/entity-handle.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/example.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/index.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/system-builder.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/world-systems.d.ts +0 -0
- /package/dist/{game → types/game}/index.d.ts +0 -0
- /package/dist/{game → types/game}/loop/index.d.ts +0 -0
- /package/dist/{net → types/net}/adapters/browser-websocket.d.ts +0 -0
- /package/dist/{net → types/net}/adapters/bun-websocket.d.ts +0 -0
- /package/dist/{net → types/net}/buffer-pool.d.ts +0 -0
- /package/dist/{net → types/net}/client.d.ts +0 -0
- /package/dist/{net → types/net}/server.d.ts +0 -0
- /package/dist/{net → types/net}/types.d.ts +0 -0
- /package/dist/{net → types/net}/validators.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/define-intent.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/intent-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/intent.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/define-rpc.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/rpc-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/rpc.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot-codec.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot.d.ts +0 -0
- /package/dist/{core/input/types.js → webgpu/types/2d/animation.test.d.ts} +0 -0
- /package/dist/{protocol/intent/intent.js → webgpu/types/2d/sprite-accessor.test.d.ts} +0 -0
package/dist/net/client.js
DELETED
|
@@ -1,586 +0,0 @@
|
|
|
1
|
-
import { MessageType } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Generic game client for multiplayer networking
|
|
4
|
-
* Handles intent sending and snapshot receiving with full type safety
|
|
5
|
-
*
|
|
6
|
-
* @template TSnapshots Union type of all possible snapshot update types
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* type GameSnapshots = PlayerUpdate | ScoreUpdate | ProjectileUpdate;
|
|
11
|
-
*
|
|
12
|
-
* const client = new ClientNetwork<GameSnapshots>({
|
|
13
|
-
* transport: wsTransport,
|
|
14
|
-
* intentRegistry,
|
|
15
|
-
* snapshotRegistry,
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* // Type-safe snapshot handlers
|
|
19
|
-
* client.onSnapshot<PlayerUpdate>('players', (snapshot) => {
|
|
20
|
-
* snapshot.updates.players // ✅ Correctly typed
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export class ClientNetwork {
|
|
25
|
-
constructor(config) {
|
|
26
|
-
/** Snapshot type handlers: type -> handler[] (supports multiple handlers) */
|
|
27
|
-
this.snapshotHandlers = new Map();
|
|
28
|
-
/** RPC method handlers: method -> handler[] (supports multiple handlers) */
|
|
29
|
-
this.rpcHandlers = new Map();
|
|
30
|
-
/** Connection lifecycle handlers */
|
|
31
|
-
this.connectHandlers = [];
|
|
32
|
-
this.disconnectHandlers = [];
|
|
33
|
-
this.errorHandlers = [];
|
|
34
|
-
/** Connection state */
|
|
35
|
-
this.connected = false;
|
|
36
|
-
/** Last sent intent per kind (for change detection) */
|
|
37
|
-
this.lastSentIntents = new Map();
|
|
38
|
-
/** Rate limiting state */
|
|
39
|
-
this.messageCount = 0;
|
|
40
|
-
this.messageCountWindow = Date.now();
|
|
41
|
-
/** Heartbeat timer */
|
|
42
|
-
this.heartbeatTimer = null;
|
|
43
|
-
/** Last time we received a message from server */
|
|
44
|
-
this.lastMessageReceivedAt = Date.now();
|
|
45
|
-
this.transport = config.transport;
|
|
46
|
-
this.intentRegistry = config.intentRegistry;
|
|
47
|
-
this.snapshotRegistry = config.snapshotRegistry;
|
|
48
|
-
this.rpcRegistry = config.rpcRegistry;
|
|
49
|
-
this.config = {
|
|
50
|
-
maxMessageSize: config.config?.maxMessageSize ?? 65536,
|
|
51
|
-
debug: config.config?.debug ?? false,
|
|
52
|
-
enableBufferPooling: config.config?.enableBufferPooling ?? true,
|
|
53
|
-
maxMessagesPerSecond: config.config?.maxMessagesPerSecond ?? 60,
|
|
54
|
-
maxSendQueueSize: config.config?.maxSendQueueSize ?? 100,
|
|
55
|
-
heartbeatInterval: config.config?.heartbeatInterval ?? 30000,
|
|
56
|
-
heartbeatTimeout: config.config?.heartbeatTimeout ?? 60000,
|
|
57
|
-
lagSimulation: config.config?.lagSimulation,
|
|
58
|
-
};
|
|
59
|
-
this.lagSimulation = config.config?.lagSimulation;
|
|
60
|
-
this.setupTransportHandlers();
|
|
61
|
-
this.setupHeartbeat();
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Send an intent to the server (type-safe)
|
|
65
|
-
*/
|
|
66
|
-
/**
|
|
67
|
-
* Check if an intent has changed compared to the last sent intent of the same kind.
|
|
68
|
-
* Useful for bandwidth optimization - only send intents when they actually change.
|
|
69
|
-
*
|
|
70
|
-
* @param intent The intent to check
|
|
71
|
-
* @param compareFn Optional custom comparison function. If not provided, uses JSON.stringify.
|
|
72
|
-
* @returns true if the intent is different from the last sent intent of this kind
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts
|
|
76
|
-
* const moveIntent = { kind: IntentKind.Move, tick: 100, dx: 1, dy: 0 };
|
|
77
|
-
*
|
|
78
|
-
* // Only send if input changed
|
|
79
|
-
* if (client.hasIntentChanged(moveIntent)) {
|
|
80
|
-
* client.sendIntent(moveIntent);
|
|
81
|
-
* }
|
|
82
|
-
*
|
|
83
|
-
* // Custom comparison (more efficient than JSON.stringify)
|
|
84
|
-
* if (client.hasIntentChanged(moveIntent, (last, current) =>
|
|
85
|
-
* last.dx !== current.dx || last.dy !== current.dy
|
|
86
|
-
* )) {
|
|
87
|
-
* client.sendIntent(moveIntent);
|
|
88
|
-
* }
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
hasIntentChanged(intent, compareFn) {
|
|
92
|
-
const lastIntent = this.lastSentIntents.get(intent.kind);
|
|
93
|
-
if (!lastIntent) {
|
|
94
|
-
return true; // First time sending this intent kind
|
|
95
|
-
}
|
|
96
|
-
if (compareFn) {
|
|
97
|
-
return compareFn(lastIntent, intent);
|
|
98
|
-
}
|
|
99
|
-
// Default comparison: stringify everything except tick
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
101
|
-
const { tick: _lastTick, ...lastData } = lastIntent;
|
|
102
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
103
|
-
const { tick: _currentTick, ...currentData } = intent;
|
|
104
|
-
return JSON.stringify(lastData) !== JSON.stringify(currentData);
|
|
105
|
-
}
|
|
106
|
-
sendIntent(intent) {
|
|
107
|
-
if (!this.connected) {
|
|
108
|
-
this.log("Cannot send intent: not connected");
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
// Client-side rate limiting
|
|
112
|
-
if (!this.checkRateLimit()) {
|
|
113
|
-
this.log("Rate limit exceeded, dropping intent");
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
try {
|
|
117
|
-
// Encode intent
|
|
118
|
-
const intentData = this.intentRegistry.encode(intent);
|
|
119
|
-
// Wrap with message type header
|
|
120
|
-
const message = new Uint8Array(1 + intentData.byteLength);
|
|
121
|
-
message[0] = MessageType.INTENT;
|
|
122
|
-
message.set(intentData, 1);
|
|
123
|
-
// Send to server
|
|
124
|
-
this.transport.send(message);
|
|
125
|
-
// Track this intent for change detection (clone to avoid reference issues)
|
|
126
|
-
this.lastSentIntents.set(intent.kind, { ...intent });
|
|
127
|
-
this.log(`Sent intent (kind: ${intent.kind}, tick: ${intent.tick})`);
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
this.log(`Failed to send intent: ${error}`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Register a handler for a specific snapshot type (type-safe)
|
|
135
|
-
* Supports multiple handlers per snapshot type
|
|
136
|
-
* @template T The specific snapshot update type for this handler
|
|
137
|
-
* @returns Unsubscribe function to remove this handler
|
|
138
|
-
*/
|
|
139
|
-
onSnapshot(type, handler) {
|
|
140
|
-
let handlers = this.snapshotHandlers.get(type);
|
|
141
|
-
if (!handlers) {
|
|
142
|
-
handlers = [];
|
|
143
|
-
this.snapshotHandlers.set(type, handlers);
|
|
144
|
-
}
|
|
145
|
-
handlers.push(handler);
|
|
146
|
-
// Return unsubscribe function
|
|
147
|
-
return () => {
|
|
148
|
-
const handlers = this.snapshotHandlers.get(type);
|
|
149
|
-
if (handlers) {
|
|
150
|
-
const index = handlers.indexOf(handler);
|
|
151
|
-
if (index > -1) {
|
|
152
|
-
handlers.splice(index, 1);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Send an RPC to the server (type-safe)
|
|
159
|
-
*
|
|
160
|
-
* @template TSchema The RPC data type
|
|
161
|
-
* @param rpc The RPC definition created by defineRPC()
|
|
162
|
-
* @param data The RPC data to send
|
|
163
|
-
*
|
|
164
|
-
* @example
|
|
165
|
-
* ```ts
|
|
166
|
-
* const BuyItem = defineRPC({
|
|
167
|
-
* method: 'buyItem',
|
|
168
|
-
* schema: { itemId: BinaryCodec.string(32) }
|
|
169
|
-
* });
|
|
170
|
-
*
|
|
171
|
-
* client.sendRpc(BuyItem, { itemId: 'long_sword' });
|
|
172
|
-
* ```
|
|
173
|
-
*/
|
|
174
|
-
sendRPC(rpc, data) {
|
|
175
|
-
if (!this.rpcRegistry) {
|
|
176
|
-
throw new Error('RpcRegistry not configured. Pass rpcRegistry to ClientNetworkConfig.');
|
|
177
|
-
}
|
|
178
|
-
if (!this.connected) {
|
|
179
|
-
this.log("Cannot send RPC: not connected");
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
// Client-side rate limiting
|
|
183
|
-
if (!this.checkRateLimit()) {
|
|
184
|
-
this.log("Rate limit exceeded, dropping RPC");
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
try {
|
|
188
|
-
// Encode RPC
|
|
189
|
-
const rpcData = this.rpcRegistry.encode(rpc, data);
|
|
190
|
-
// Wrap with message type header
|
|
191
|
-
const message = new Uint8Array(1 + rpcData.byteLength);
|
|
192
|
-
message[0] = MessageType.CUSTOM;
|
|
193
|
-
message.set(rpcData, 1);
|
|
194
|
-
// Send to server
|
|
195
|
-
this.transport.send(message);
|
|
196
|
-
this.log(`Sent RPC (method: ${rpc.method})`);
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
this.log(`Failed to send RPC: ${error}`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Register a handler for incoming RPCs from the server (type-safe)
|
|
204
|
-
* Supports multiple handlers per RPC method
|
|
205
|
-
*
|
|
206
|
-
* @template TSchema The RPC data type
|
|
207
|
-
* @param rpc The RPC definition created by defineRPC()
|
|
208
|
-
* @param handler Callback function to handle the RPC
|
|
209
|
-
* @returns Unsubscribe function to remove this handler
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* ```ts
|
|
213
|
-
* const MatchCountdown = defineRPC({
|
|
214
|
-
* method: 'matchCountdown',
|
|
215
|
-
* schema: { secondsRemaining: BinaryCodec.u8 }
|
|
216
|
-
* });
|
|
217
|
-
*
|
|
218
|
-
* client.onRpc(MatchCountdown, (rpc) => {
|
|
219
|
-
* console.log(`Match starting in ${rpc.secondsRemaining}s`);
|
|
220
|
-
* });
|
|
221
|
-
* ```
|
|
222
|
-
*/
|
|
223
|
-
onRPC(rpc, handler) {
|
|
224
|
-
if (!this.rpcRegistry) {
|
|
225
|
-
throw new Error('RpcRegistry not configured. Pass rpcRegistry to ClientNetworkConfig.');
|
|
226
|
-
}
|
|
227
|
-
let handlers = this.rpcHandlers.get(rpc.method);
|
|
228
|
-
if (!handlers) {
|
|
229
|
-
handlers = [];
|
|
230
|
-
this.rpcHandlers.set(rpc.method, handlers);
|
|
231
|
-
}
|
|
232
|
-
handlers.push(handler);
|
|
233
|
-
// Return unsubscribe function
|
|
234
|
-
return () => {
|
|
235
|
-
const handlers = this.rpcHandlers.get(rpc.method);
|
|
236
|
-
if (handlers) {
|
|
237
|
-
const index = handlers.indexOf(handler);
|
|
238
|
-
if (index > -1) {
|
|
239
|
-
handlers.splice(index, 1);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Register a handler for connection events
|
|
246
|
-
*/
|
|
247
|
-
onConnect(handler) {
|
|
248
|
-
this.connectHandlers.push(handler);
|
|
249
|
-
return () => {
|
|
250
|
-
const index = this.connectHandlers.indexOf(handler);
|
|
251
|
-
if (index > -1)
|
|
252
|
-
this.connectHandlers.splice(index, 1);
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Register a handler for disconnection events
|
|
257
|
-
*/
|
|
258
|
-
onDisconnect(handler) {
|
|
259
|
-
this.disconnectHandlers.push(handler);
|
|
260
|
-
return () => {
|
|
261
|
-
const index = this.disconnectHandlers.indexOf(handler);
|
|
262
|
-
if (index > -1)
|
|
263
|
-
this.disconnectHandlers.splice(index, 1);
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Register a handler for transport errors
|
|
268
|
-
*/
|
|
269
|
-
onError(handler) {
|
|
270
|
-
this.errorHandlers.push(handler);
|
|
271
|
-
return () => {
|
|
272
|
-
const index = this.errorHandlers.indexOf(handler);
|
|
273
|
-
if (index > -1)
|
|
274
|
-
this.errorHandlers.splice(index, 1);
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Check if connected to server
|
|
279
|
-
*/
|
|
280
|
-
isConnected() {
|
|
281
|
-
return this.connected;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Disconnect from server
|
|
285
|
-
*/
|
|
286
|
-
disconnect() {
|
|
287
|
-
this.log("Disconnecting...");
|
|
288
|
-
// Stop heartbeat timer
|
|
289
|
-
if (this.heartbeatTimer) {
|
|
290
|
-
clearInterval(this.heartbeatTimer);
|
|
291
|
-
this.heartbeatTimer = null;
|
|
292
|
-
}
|
|
293
|
-
return this.transport.close();
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Setup transport event handlers
|
|
297
|
-
*/
|
|
298
|
-
setupTransportHandlers() {
|
|
299
|
-
// Setup open handler if transport supports it
|
|
300
|
-
if (this.transport.onOpen) {
|
|
301
|
-
this.transport.onOpen(() => {
|
|
302
|
-
this.log("Connected to server");
|
|
303
|
-
this.connected = true;
|
|
304
|
-
this.lastMessageReceivedAt = Date.now();
|
|
305
|
-
this.notifyConnectHandlers();
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
// If transport doesn't support onOpen, assume already connected
|
|
310
|
-
this.connected = true;
|
|
311
|
-
this.lastMessageReceivedAt = Date.now();
|
|
312
|
-
}
|
|
313
|
-
this.transport.onMessage((data) => {
|
|
314
|
-
const lagDelay = this.getLagDelay();
|
|
315
|
-
if (lagDelay > 0) {
|
|
316
|
-
// Simulate lag by delaying message handling
|
|
317
|
-
// IMPORTANT: Copy the data buffer as it may be reused by the transport
|
|
318
|
-
const dataCopy = new Uint8Array(data);
|
|
319
|
-
setTimeout(() => {
|
|
320
|
-
this.handleMessage(dataCopy);
|
|
321
|
-
}, lagDelay);
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
this.handleMessage(data);
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
this.transport.onClose(() => {
|
|
328
|
-
this.handleDisconnection();
|
|
329
|
-
});
|
|
330
|
-
// Setup error handler if transport supports it
|
|
331
|
-
if (this.transport.onError) {
|
|
332
|
-
this.transport.onError((error) => {
|
|
333
|
-
this.handleError(error);
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Setup heartbeat mechanism
|
|
339
|
-
*/
|
|
340
|
-
setupHeartbeat() {
|
|
341
|
-
if (this.config.heartbeatInterval === 0) {
|
|
342
|
-
return; // Heartbeats disabled
|
|
343
|
-
}
|
|
344
|
-
this.heartbeatTimer = setInterval(() => {
|
|
345
|
-
this.checkHeartbeat();
|
|
346
|
-
}, this.config.heartbeatInterval);
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Check server heartbeat timeout and send heartbeat
|
|
350
|
-
*/
|
|
351
|
-
checkHeartbeat() {
|
|
352
|
-
const now = Date.now();
|
|
353
|
-
const timeSinceLastMessage = now - this.lastMessageReceivedAt;
|
|
354
|
-
// Check if server has timed out
|
|
355
|
-
if (timeSinceLastMessage > this.config.heartbeatTimeout) {
|
|
356
|
-
this.log(`Server timed out (no message for ${timeSinceLastMessage}ms)`);
|
|
357
|
-
this.disconnect();
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
// Send heartbeat to server
|
|
361
|
-
try {
|
|
362
|
-
const heartbeatMessage = new Uint8Array([MessageType.HEARTBEAT]);
|
|
363
|
-
this.transport.send(heartbeatMessage);
|
|
364
|
-
}
|
|
365
|
-
catch (error) {
|
|
366
|
-
this.log(`Failed to send heartbeat: ${error}`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Handle incoming message from server
|
|
371
|
-
*/
|
|
372
|
-
handleMessage(data) {
|
|
373
|
-
// Update last message received timestamp
|
|
374
|
-
this.lastMessageReceivedAt = Date.now();
|
|
375
|
-
if (data.byteLength === 0) {
|
|
376
|
-
this.log("Received empty message from server");
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
if (data.byteLength > this.config.maxMessageSize) {
|
|
380
|
-
this.log(`Message exceeds max size: ${data.byteLength} > ${this.config.maxMessageSize}`);
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
const messageType = data[0];
|
|
384
|
-
const payload = data.subarray(1);
|
|
385
|
-
switch (messageType) {
|
|
386
|
-
case MessageType.SNAPSHOT:
|
|
387
|
-
this.handleSnapshot(payload);
|
|
388
|
-
break;
|
|
389
|
-
case MessageType.HEARTBEAT:
|
|
390
|
-
// Heartbeat received - already updated lastMessageReceivedAt above
|
|
391
|
-
this.log("Received heartbeat from server");
|
|
392
|
-
break;
|
|
393
|
-
case MessageType.CUSTOM:
|
|
394
|
-
this.handleRPC(payload);
|
|
395
|
-
break;
|
|
396
|
-
default:
|
|
397
|
-
this.log(`Unknown message type: ${messageType}`);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Decode and handle a snapshot from server
|
|
402
|
-
*
|
|
403
|
-
* IMPORTANT: Handlers receive the pooled object directly (zero-copy).
|
|
404
|
-
* Handlers MUST extract any data they need immediately - do NOT store references to the snapshot.updates object.
|
|
405
|
-
* The object will be released back to the pool after all handlers complete.
|
|
406
|
-
*/
|
|
407
|
-
handleSnapshot(data) {
|
|
408
|
-
try {
|
|
409
|
-
// Decode using snapshot registry (returns { type, snapshot })
|
|
410
|
-
const decoded = this.snapshotRegistry.decode(data);
|
|
411
|
-
this.log(`Received snapshot (type: ${decoded.type}, tick: ${decoded.snapshot.tick})`);
|
|
412
|
-
// Call all type-specific handlers if registered
|
|
413
|
-
// HANDLERS MUST NOT STORE REFERENCES - extract data immediately!
|
|
414
|
-
const handlers = this.snapshotHandlers.get(decoded.type);
|
|
415
|
-
if (handlers && handlers.length > 0) {
|
|
416
|
-
for (const handler of handlers) {
|
|
417
|
-
try {
|
|
418
|
-
handler(decoded.snapshot);
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
this.log(`Error in snapshot handler: ${error}`);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
this.log(`No handler registered for snapshot type: ${decoded.type}`);
|
|
427
|
-
}
|
|
428
|
-
// Release the pooled object back to the pool
|
|
429
|
-
// This enables efficient memory reuse across snapshot updates (zero GC pressure)
|
|
430
|
-
this.snapshotRegistry.release(decoded.type, decoded.snapshot.updates);
|
|
431
|
-
}
|
|
432
|
-
catch (error) {
|
|
433
|
-
this.log(`Failed to decode snapshot: ${error}`);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Handle incoming RPC message from server
|
|
438
|
-
*
|
|
439
|
-
* IMPORTANT: Handlers receive the pooled object directly (zero-copy).
|
|
440
|
-
* Handlers MUST extract any data they need immediately - do NOT store references to the RPC data object.
|
|
441
|
-
* The object will be released back to the pool after all handlers complete.
|
|
442
|
-
*/
|
|
443
|
-
handleRPC(data) {
|
|
444
|
-
if (!this.rpcRegistry) {
|
|
445
|
-
this.log("Received RPC but RpcRegistry not configured");
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
try {
|
|
449
|
-
// Decode using RPC registry (returns { method, data })
|
|
450
|
-
const decoded = this.rpcRegistry.decode(data);
|
|
451
|
-
this.log(`Received RPC (method: ${decoded.method})`);
|
|
452
|
-
// Call all method-specific handlers if registered
|
|
453
|
-
// HANDLERS MUST NOT STORE REFERENCES - extract data immediately!
|
|
454
|
-
const handlers = this.rpcHandlers.get(decoded.method);
|
|
455
|
-
if (handlers && handlers.length > 0) {
|
|
456
|
-
for (const handler of handlers) {
|
|
457
|
-
try {
|
|
458
|
-
handler(decoded.data);
|
|
459
|
-
}
|
|
460
|
-
catch (error) {
|
|
461
|
-
this.log(`Error in RPC handler: ${error}`);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
this.log(`No handler registered for RPC method: ${decoded.method}`);
|
|
467
|
-
}
|
|
468
|
-
// Release the pooled object back to the pool
|
|
469
|
-
// This enables efficient memory reuse across RPC calls (zero GC pressure)
|
|
470
|
-
this.rpcRegistry.release(decoded.method, decoded.data);
|
|
471
|
-
}
|
|
472
|
-
catch (error) {
|
|
473
|
-
this.log(`Failed to decode RPC: ${error}`);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* Handle disconnection from server
|
|
478
|
-
*/
|
|
479
|
-
handleDisconnection() {
|
|
480
|
-
this.log("Disconnected from server");
|
|
481
|
-
this.connected = false;
|
|
482
|
-
// Stop heartbeat timer
|
|
483
|
-
if (this.heartbeatTimer) {
|
|
484
|
-
clearInterval(this.heartbeatTimer);
|
|
485
|
-
this.heartbeatTimer = null;
|
|
486
|
-
}
|
|
487
|
-
this.notifyDisconnectHandlers();
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Notify connect handlers
|
|
491
|
-
*/
|
|
492
|
-
notifyConnectHandlers() {
|
|
493
|
-
for (const handler of this.connectHandlers) {
|
|
494
|
-
try {
|
|
495
|
-
handler();
|
|
496
|
-
}
|
|
497
|
-
catch (error) {
|
|
498
|
-
// Don't call log here as it might throw, use console.error directly
|
|
499
|
-
if (this.config.debug) {
|
|
500
|
-
console.error(`[ClientNetwork] Error in connect handler: ${error}`);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Notify disconnect handlers
|
|
507
|
-
*/
|
|
508
|
-
notifyDisconnectHandlers() {
|
|
509
|
-
for (const handler of this.disconnectHandlers) {
|
|
510
|
-
try {
|
|
511
|
-
handler();
|
|
512
|
-
}
|
|
513
|
-
catch (error) {
|
|
514
|
-
// Don't call log here as it might throw, use console.error directly
|
|
515
|
-
if (this.config.debug) {
|
|
516
|
-
console.error(`[ClientNetwork] Error in disconnect handler: ${error}`);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Handle transport errors
|
|
523
|
-
*/
|
|
524
|
-
handleError(error) {
|
|
525
|
-
this.log(`Transport error: ${error.message}`);
|
|
526
|
-
this.notifyErrorHandlers(error);
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* Notify error handlers
|
|
530
|
-
*/
|
|
531
|
-
notifyErrorHandlers(error) {
|
|
532
|
-
for (const handler of this.errorHandlers) {
|
|
533
|
-
try {
|
|
534
|
-
handler(error);
|
|
535
|
-
}
|
|
536
|
-
catch (err) {
|
|
537
|
-
this.log(`Error in error handler: ${err}`);
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Check client-side rate limit
|
|
543
|
-
* Returns true if message should be sent, false if rate limit exceeded
|
|
544
|
-
*/
|
|
545
|
-
checkRateLimit() {
|
|
546
|
-
if (this.config.maxMessagesPerSecond === 0) {
|
|
547
|
-
return true; // Rate limiting disabled
|
|
548
|
-
}
|
|
549
|
-
const now = Date.now();
|
|
550
|
-
const windowStart = Math.floor(now / 1000) * 1000; // Start of current second
|
|
551
|
-
// Reset counter if we're in a new time window
|
|
552
|
-
if (this.messageCountWindow !== windowStart) {
|
|
553
|
-
this.messageCountWindow = windowStart;
|
|
554
|
-
this.messageCount = 0;
|
|
555
|
-
}
|
|
556
|
-
// Check if limit would be exceeded BEFORE incrementing
|
|
557
|
-
if (this.messageCount >= this.config.maxMessagesPerSecond) {
|
|
558
|
-
return false;
|
|
559
|
-
}
|
|
560
|
-
// Only increment if we're allowing this message
|
|
561
|
-
this.messageCount++;
|
|
562
|
-
return true;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Calculate lag delay based on lag simulation configuration
|
|
566
|
-
*/
|
|
567
|
-
getLagDelay() {
|
|
568
|
-
if (!this.lagSimulation) {
|
|
569
|
-
return 0;
|
|
570
|
-
}
|
|
571
|
-
if (typeof this.lagSimulation === 'number') {
|
|
572
|
-
return this.lagSimulation;
|
|
573
|
-
}
|
|
574
|
-
// Random delay between min and max
|
|
575
|
-
const { min, max } = this.lagSimulation;
|
|
576
|
-
return min + Math.random() * (max - min);
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Debug logging
|
|
580
|
-
*/
|
|
581
|
-
log(message) {
|
|
582
|
-
if (this.config.debug) {
|
|
583
|
-
console.log(`[ClientNetwork] ${message}`);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
package/dist/net/index.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module net
|
|
3
|
-
*
|
|
4
|
-
* Transport-agnostic networking layer for multiplayer games
|
|
5
|
-
*
|
|
6
|
-
* This module provides generic client/server abstractions that work with any transport layer
|
|
7
|
-
* (WebSocket, WebRTC, UDP, Socket.io, etc.)
|
|
8
|
-
*
|
|
9
|
-
* Key features:
|
|
10
|
-
* - Per-peer snapshot registry tracking (fog of war, interest management)
|
|
11
|
-
* - Type-safe intent/snapshot encoding
|
|
12
|
-
* - Pluggable transport adapters
|
|
13
|
-
* - Connection lifecycle management
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* import { ServerNetwork, ClientNetwork } from '@mococa/net';
|
|
18
|
-
* import { BunWebSocketServerTransport } from '@mococa/net/transports/bun-websocket';
|
|
19
|
-
* import { IntentRegistry, SnapshotRegistry } from '@mococa/protocol';
|
|
20
|
-
*
|
|
21
|
-
* // Server setup
|
|
22
|
-
* const transport = BunWebSocketServerTransport.create(3000);
|
|
23
|
-
* const server = new ServerNetwork({
|
|
24
|
-
* transport,
|
|
25
|
-
* intentRegistry: new IntentRegistry(),
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* // Per-peer snapshot registry factory
|
|
29
|
-
* const server = new ServerNetwork({
|
|
30
|
-
* transport,
|
|
31
|
-
* intentRegistry: new IntentRegistry(),
|
|
32
|
-
* createPeerSnapshotRegistry: () => {
|
|
33
|
-
* const registry = new SnapshotRegistry();
|
|
34
|
-
* registry.register('GameState', gameStateCodec);
|
|
35
|
-
* return registry;
|
|
36
|
-
* }
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* // Handle intents
|
|
40
|
-
* server.onIntent(IntentKind.Move, (peerId, intent) => {
|
|
41
|
-
* console.log(`Player ${peerId} moved:`, intent);
|
|
42
|
-
* });
|
|
43
|
-
*
|
|
44
|
-
* // Broadcast snapshots (each peer uses their own registry)
|
|
45
|
-
* server.broadcastSnapshot('GameState', {
|
|
46
|
-
* tick: 100,
|
|
47
|
-
* updates: { players: [...] }
|
|
48
|
-
* });
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export * from "./types";
|
|
52
|
-
export * from "./server";
|
|
53
|
-
export * from "./client";
|
|
54
|
-
export * from "./adapters/bun-websocket";
|
|
55
|
-
export * from "./buffer-pool";
|
|
56
|
-
export * from "./validators";
|
|
57
|
-
// Re-export commonly used enums for convenience
|
|
58
|
-
export { MessageType, MessagePriority } from "./types";
|