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/src/net/README.md
DELETED
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
# Network Layer (`@mococa/net`)
|
|
2
|
-
|
|
3
|
-
Transport-agnostic networking layer for multiplayer games. Provides generic client/server abstractions that work with any transport (WebSocket, WebRTC, UDP, Socket.io, etc.)
|
|
4
|
-
|
|
5
|
-
## Key Features
|
|
6
|
-
|
|
7
|
-
- **Per-Peer Snapshot Registries** - Each player gets their own snapshot codec, enabling:
|
|
8
|
-
- Fog of war (only send visible entities)
|
|
9
|
-
- Interest management (only send relevant data)
|
|
10
|
-
- Player-specific compression/optimization
|
|
11
|
-
|
|
12
|
-
- **Transport Agnostic** - Pluggable transport adapters for:
|
|
13
|
-
- Bun WebSocket (included)
|
|
14
|
-
- Browser WebSocket
|
|
15
|
-
- WebRTC
|
|
16
|
-
- UDP
|
|
17
|
-
- Socket.io
|
|
18
|
-
- Custom transports
|
|
19
|
-
|
|
20
|
-
- **Type-Safe Protocol** - Integrates with `@mococa/protocol`:
|
|
21
|
-
- Intent encoding/decoding (client inputs)
|
|
22
|
-
- Snapshot encoding/decoding (state sync)
|
|
23
|
-
- RPC encoding/decoding (one-off events)
|
|
24
|
-
- Binary serialization
|
|
25
|
-
|
|
26
|
-
- **Connection Lifecycle** - Built-in handling for:
|
|
27
|
-
- Connection/disconnection events
|
|
28
|
-
- Per-peer state tracking
|
|
29
|
-
- Message routing
|
|
30
|
-
|
|
31
|
-
## Architecture
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
┌─────────────┐ ┌─────────────┐
|
|
35
|
-
│ Game Client │ │ Game Server │
|
|
36
|
-
└──────┬──────┘ └──────┬──────┘
|
|
37
|
-
│ │
|
|
38
|
-
│ Intents (MoveIntent) │
|
|
39
|
-
├─────────────────────────────────>│
|
|
40
|
-
│ │
|
|
41
|
-
│ Snapshots (GameState) │
|
|
42
|
-
│<─────────────────────────────────┤
|
|
43
|
-
│ │
|
|
44
|
-
│ RPCs (BuyItem) │
|
|
45
|
-
├─────────────────────────────────>│
|
|
46
|
-
│ │
|
|
47
|
-
│ RPCs (MatchCountdown) │
|
|
48
|
-
│<─────────────────────────────────┤
|
|
49
|
-
│ │
|
|
50
|
-
▼ ▼
|
|
51
|
-
┌─────────────┐ ┌─────────────┐
|
|
52
|
-
│ ClientNetwork│ │ServerNetwork│
|
|
53
|
-
│ Class │ │ Class │
|
|
54
|
-
└──────┬──────┘ └──────┬──────┘
|
|
55
|
-
│ │
|
|
56
|
-
│ Binary Messages (Uint8Array) │
|
|
57
|
-
├─────────────────────────────────>│
|
|
58
|
-
│<─────────────────────────────────┤
|
|
59
|
-
│ │
|
|
60
|
-
▼ ▼
|
|
61
|
-
┌─────────────┐ ┌─────────────┐
|
|
62
|
-
│ Transport │ │ Transport │
|
|
63
|
-
│ Adapter │◄──────WebSocket───►│ Adapter │
|
|
64
|
-
└─────────────┘ └─────────────┘
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Quick Start
|
|
68
|
-
|
|
69
|
-
### 1. Define Your Game Protocol
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
import { BinaryCodec, defineIntent, IntentRegistry, SnapshotRegistry } from '@mococa/gamedev-utils';
|
|
73
|
-
|
|
74
|
-
// Define intents (client -> server)
|
|
75
|
-
enum IntentKind {
|
|
76
|
-
Move = 1,
|
|
77
|
-
Attack = 2,
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const MoveIntent = defineIntent({
|
|
81
|
-
kind: IntentKind.Move,
|
|
82
|
-
schema: {
|
|
83
|
-
dx: BinaryCodec.f32,
|
|
84
|
-
dy: BinaryCodec.f32,
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Define game state (server -> client)
|
|
89
|
-
const GameStateCodec = BinaryCodec.object({
|
|
90
|
-
players: BinaryCodec.record(BinaryCodec.string, BinaryCodec.object({
|
|
91
|
-
x: BinaryCodec.f32,
|
|
92
|
-
y: BinaryCodec.f32,
|
|
93
|
-
health: BinaryCodec.u8,
|
|
94
|
-
})),
|
|
95
|
-
tick: BinaryCodec.u32,
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### 2. Create Server
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
import { ServerNetwork, BunWebSocketServerTransport } from '@mococa/gamedev-utils';
|
|
103
|
-
|
|
104
|
-
// Create transport
|
|
105
|
-
const transport = BunWebSocketServerTransport.create(3000);
|
|
106
|
-
|
|
107
|
-
// Create intent registry
|
|
108
|
-
const intentRegistry = new IntentRegistry();
|
|
109
|
-
intentRegistry.register(IntentKind.Move, MoveIntent.codec);
|
|
110
|
-
|
|
111
|
-
// Create server with per-peer snapshot registry factory
|
|
112
|
-
const server = new ServerNetwork({
|
|
113
|
-
transport,
|
|
114
|
-
intentRegistry,
|
|
115
|
-
createPeerSnapshotRegistry: () => {
|
|
116
|
-
// Factory called for each new peer connection
|
|
117
|
-
const registry = new SnapshotRegistry();
|
|
118
|
-
registry.register('GameState', GameStateCodec);
|
|
119
|
-
return registry;
|
|
120
|
-
},
|
|
121
|
-
config: { debug: true }
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Handle intents
|
|
125
|
-
server.onIntent(IntentKind.Move, (peerId, intent) => {
|
|
126
|
-
const { dx, dy } = intent as MoveIntent;
|
|
127
|
-
// Update game state...
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Broadcast snapshots
|
|
131
|
-
setInterval(() => {
|
|
132
|
-
server.broadcastSnapshot('GameState', {
|
|
133
|
-
tick: currentTick++,
|
|
134
|
-
updates: gameState
|
|
135
|
-
});
|
|
136
|
-
}, 50); // 20 Hz
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 3. Create Client
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
import { ClientNetwork, BunWebSocketClientTransport } from '@mococa/gamedev-utils';
|
|
143
|
-
|
|
144
|
-
// Connect to server
|
|
145
|
-
const transport = await BunWebSocketClientTransport.connect('ws://localhost:3000');
|
|
146
|
-
|
|
147
|
-
// Create registries
|
|
148
|
-
const intentRegistry = new IntentRegistry();
|
|
149
|
-
intentRegistry.register(IntentKind.Move, MoveIntent.codec);
|
|
150
|
-
|
|
151
|
-
const snapshotRegistry = new SnapshotRegistry();
|
|
152
|
-
snapshotRegistry.register('GameState', GameStateCodec);
|
|
153
|
-
|
|
154
|
-
// Create client
|
|
155
|
-
const client = new ClientNetwork({
|
|
156
|
-
transport,
|
|
157
|
-
intentRegistry,
|
|
158
|
-
snapshotRegistry,
|
|
159
|
-
config: { debug: true }
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Handle snapshots
|
|
163
|
-
client.onSnapshot('GameState', (snapshot) => {
|
|
164
|
-
// Apply to local game state
|
|
165
|
-
gameState = applySnapshot(gameState, snapshot);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// Send intents
|
|
169
|
-
client.sendIntent({
|
|
170
|
-
kind: IntentKind.Move,
|
|
171
|
-
tick: currentTick,
|
|
172
|
-
dx: 1.0,
|
|
173
|
-
dy: 0.5
|
|
174
|
-
});
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## RPCs (Remote Procedure Calls)
|
|
178
|
-
|
|
179
|
-
For one-off events that don't fit intents (inputs) or snapshots (state sync), use RPCs. See [Protocol README](../protocol/README.md#rpcs-remote-procedure-calls) for full documentation.
|
|
180
|
-
|
|
181
|
-
### Quick Example
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
import { defineRPC, RpcRegistry } from '@mococa/gamedev-utils';
|
|
185
|
-
|
|
186
|
-
// Define RPCs
|
|
187
|
-
const MatchCountdown = defineRPC({
|
|
188
|
-
method: 'matchCountdown',
|
|
189
|
-
schema: {
|
|
190
|
-
secondsRemaining: BinaryCodec.u8,
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
const BuyItem = defineRPC({
|
|
195
|
-
method: 'buyItem',
|
|
196
|
-
schema: {
|
|
197
|
-
itemId: BinaryCodec.string(32),
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// Register RPCs
|
|
202
|
-
const rpcRegistry = new RpcRegistry();
|
|
203
|
-
rpcRegistry.register(MatchCountdown);
|
|
204
|
-
rpcRegistry.register(BuyItem);
|
|
205
|
-
|
|
206
|
-
// Add to client/server config
|
|
207
|
-
const client = new ClientNetwork({
|
|
208
|
-
transport,
|
|
209
|
-
intentRegistry,
|
|
210
|
-
snapshotRegistry,
|
|
211
|
-
rpcRegistry, // ← Optional
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// Client: Send RPC to server
|
|
215
|
-
client.sendRpc(BuyItem, { itemId: 'long_sword' });
|
|
216
|
-
|
|
217
|
-
// Client: Receive RPC from server
|
|
218
|
-
client.onRpc(MatchCountdown, (rpc) => {
|
|
219
|
-
showCountdownUI(rpc.secondsRemaining);
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Server: Receive RPC from client
|
|
223
|
-
server.onRpc(BuyItem, (peerId, rpc) => {
|
|
224
|
-
handlePurchase(peerId, rpc.itemId);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// Server: Send RPC to specific client
|
|
228
|
-
server.sendRpc(peerId, MatchCountdown, { secondsRemaining: 10 });
|
|
229
|
-
|
|
230
|
-
// Server: Broadcast RPC to all clients
|
|
231
|
-
server.sendRpcBroadcast(MatchCountdown, { secondsRemaining: 3 });
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
**When to use:**
|
|
235
|
-
- ✅ Match lifecycle events (countdown, pause, end)
|
|
236
|
-
- ✅ Meta-game events (achievements, notifications)
|
|
237
|
-
- ✅ Chat messages
|
|
238
|
-
- ✅ UI feedback (purchase confirmations, errors)
|
|
239
|
-
|
|
240
|
-
**When NOT to use:**
|
|
241
|
-
- ❌ Game state (use Snapshots)
|
|
242
|
-
- ❌ Player inputs (use Intents)
|
|
243
|
-
- ❌ Anything late joiners need to know
|
|
244
|
-
|
|
245
|
-
## Per-Peer Snapshot Registries
|
|
246
|
-
|
|
247
|
-
The killer feature! Each peer automatically gets their own snapshot registry via the factory function, enabling powerful optimizations:
|
|
248
|
-
|
|
249
|
-
### Fog of War (Runtime Filtering)
|
|
250
|
-
|
|
251
|
-
Use `broadcastSnapshotWithCustomization` to filter data per-peer at runtime:
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
server.broadcastSnapshotWithCustomization('GameState', baseSnapshot, (peerId, snapshot) => {
|
|
255
|
-
const player = gameState.players[peerId];
|
|
256
|
-
|
|
257
|
-
// Only send visible entities to this player
|
|
258
|
-
const visibleEntities = entities.filter(entity =>
|
|
259
|
-
distance(player, entity) < VISIBILITY_RADIUS
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
tick: snapshot.tick,
|
|
264
|
-
updates: {
|
|
265
|
-
...snapshot.updates,
|
|
266
|
-
entities: visibleEntities
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
});
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Platform-Specific Encoding (Factory Pattern)
|
|
273
|
-
|
|
274
|
-
Different clients can use different codecs by customizing the factory:
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
const server = new ServerNetwork({
|
|
278
|
-
transport,
|
|
279
|
-
intentRegistry,
|
|
280
|
-
createPeerSnapshotRegistry: () => {
|
|
281
|
-
// You could inspect peer metadata here to decide which codec to use
|
|
282
|
-
const registry = new SnapshotRegistry();
|
|
283
|
-
|
|
284
|
-
// All peers use same codec by default
|
|
285
|
-
// For different codecs per peer, use peer metadata and create
|
|
286
|
-
// registries conditionally in the factory
|
|
287
|
-
registry.register('GameState', GameStateCodec);
|
|
288
|
-
return registry;
|
|
289
|
-
},
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
// To customize per-peer, set metadata on connection:
|
|
293
|
-
server.onConnection((peerId) => {
|
|
294
|
-
const userAgent = /* get from transport metadata */;
|
|
295
|
-
server.setPeerMetadata(peerId, 'platform', userAgent.includes('Mobile') ? 'mobile' : 'desktop');
|
|
296
|
-
|
|
297
|
-
// Then in factory, check metadata (note: factory runs before onConnection)
|
|
298
|
-
// So you'd need to create registries lazily or use customization method
|
|
299
|
-
});
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
**Note**: The factory runs once per peer automatically. For truly dynamic per-peer codecs, use `broadcastSnapshotWithCustomization` to filter/transform data at send time.
|
|
303
|
-
|
|
304
|
-
## Creating Custom Transports
|
|
305
|
-
|
|
306
|
-
Implement the `TransportAdapter` interface:
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
import { TransportAdapter, ServerTransportAdapter } from '@mococa/net';
|
|
310
|
-
|
|
311
|
-
// Client-side transport
|
|
312
|
-
class MyTransport implements TransportAdapter {
|
|
313
|
-
send(data: Uint8Array): void {
|
|
314
|
-
// Send binary data through your transport
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
onOpen?(handler: () => void): void {
|
|
318
|
-
// Register open handler (optional - if omitted, assumes already connected)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
onMessage(handler: (data: Uint8Array) => void): void {
|
|
322
|
-
// Register message handler
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
onClose(handler: () => void): void {
|
|
326
|
-
// Register close handler
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
close(): void {
|
|
330
|
-
// Close connection
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Server-side transport
|
|
335
|
-
class MyServerTransport implements ServerTransportAdapter<MyTransport> {
|
|
336
|
-
onConnection(handler: (peer: MyTransport, peerId: string) => void): void {
|
|
337
|
-
// Register connection handler
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
onDisconnection(handler: (peerId: string) => void): void {
|
|
341
|
-
// Register disconnection handler
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
getPeer(peerId: string): MyTransport | undefined {
|
|
345
|
-
// Get peer by ID
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
getPeerIds(): string[] {
|
|
349
|
-
// Get all peer IDs
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
close(): void {
|
|
353
|
-
// Close server
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
## Message Protocol
|
|
359
|
-
|
|
360
|
-
Messages are prefixed with a single byte indicating type:
|
|
361
|
-
|
|
362
|
-
```
|
|
363
|
-
┌────────────┬──────────────────────┐
|
|
364
|
-
│ Type (u8) │ Payload (variable) │
|
|
365
|
-
├────────────┼──────────────────────┤
|
|
366
|
-
│ 0x01 │ Intent data │ (Client -> Server)
|
|
367
|
-
│ 0x02 │ Snapshot data │ (Server -> Client)
|
|
368
|
-
│ 0xFF │ Custom data │ (Bidirectional)
|
|
369
|
-
└────────────┴──────────────────────┘
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
This allows the layer to automatically route messages without requiring separate channels.
|
|
373
|
-
|
|
374
|
-
## API Reference
|
|
375
|
-
|
|
376
|
-
### `ServerNetwork<TPeer>`
|
|
377
|
-
|
|
378
|
-
#### Constructor
|
|
379
|
-
```typescript
|
|
380
|
-
constructor(config: {
|
|
381
|
-
transport: ServerTransportAdapter<TPeer>;
|
|
382
|
-
intentRegistry: IntentRegistry;
|
|
383
|
-
createPeerSnapshotRegistry: () => SnapshotRegistry<TSnapshots>;
|
|
384
|
-
config?: NetworkConfig;
|
|
385
|
-
})
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
**Parameters**:
|
|
389
|
-
- `transport`: Server transport adapter for connection management
|
|
390
|
-
- `intentRegistry`: Registry for decoding client intents
|
|
391
|
-
- `createPeerSnapshotRegistry`: Factory function called once per new peer to create their snapshot registry
|
|
392
|
-
- `config`: Optional network configuration (debug, rate limits, buffer pooling, etc.)
|
|
393
|
-
|
|
394
|
-
#### Methods
|
|
395
|
-
- `onIntent(kind: number, handler: (peerId: string, intent: unknown) => void)` - Handle specific intent type
|
|
396
|
-
- `onConnection(handler: (peerId: string) => void)` - Handle new connections
|
|
397
|
-
- `onDisconnection(handler: (peerId: string) => void)` - Handle disconnections
|
|
398
|
-
- `sendSnapshotToPeer<T>(peerId: string, type: string, snapshot: Snapshot<T>)` - Send to specific peer
|
|
399
|
-
- `broadcastSnapshot<T>(type: string, snapshot: Snapshot<T>, filter?: (peerId: string) => boolean)` - Broadcast to all
|
|
400
|
-
- `broadcastSnapshotWithCustomization<T>(type: string, baseSnapshot: Snapshot<T>, customize: (peerId: string, snapshot: Snapshot<T>) => Snapshot<T>)` - Broadcast with per-peer customization
|
|
401
|
-
- `getPeerIds()` - Get all connected peer IDs
|
|
402
|
-
- `getPeerState(peerId: string)` - Get peer state
|
|
403
|
-
- `setPeerMetadata(peerId: string, key: string, value: unknown)` - Update peer metadata
|
|
404
|
-
- `close()` - Close server
|
|
405
|
-
|
|
406
|
-
### `ClientNetwork`
|
|
407
|
-
|
|
408
|
-
#### Constructor
|
|
409
|
-
```typescript
|
|
410
|
-
constructor(config: {
|
|
411
|
-
transport: TransportAdapter;
|
|
412
|
-
intentRegistry: IntentRegistry;
|
|
413
|
-
snapshotRegistry: SnapshotRegistry;
|
|
414
|
-
config?: NetworkConfig;
|
|
415
|
-
})
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
#### Methods
|
|
419
|
-
- `sendIntent(intent: unknown)` - Send intent to server
|
|
420
|
-
- `onSnapshot<T>(type: string, handler: (snapshot: Snapshot<T>) => void)` - Handle specific snapshot type
|
|
421
|
-
- `onAnySnapshot(handler: (type: string, snapshot: Snapshot<unknown>) => void)` - Handle all snapshots
|
|
422
|
-
- `onClose(handler: () => void)` - Handle connection close
|
|
423
|
-
- `getLastReceivedTick()` - Get last received tick number
|
|
424
|
-
- `isConnected()` - Check connection status
|
|
425
|
-
- `close()` - Close connection
|
|
426
|
-
|
|
427
|
-
## Examples
|
|
428
|
-
|
|
429
|
-
See [examples/multiplayer-game.ts](../../examples/multiplayer-game.ts) for a complete working example with:
|
|
430
|
-
- Server setup with per-peer registries
|
|
431
|
-
- Client prediction
|
|
432
|
-
- Multiple intent types
|
|
433
|
-
- Fog of war implementation
|
|
434
|
-
- Movement, combat, and chat
|
|
435
|
-
|
|
436
|
-
## Best Practices
|
|
437
|
-
|
|
438
|
-
1. **Provide a snapshot registry factory** - Required parameter in ServerNetwork constructor
|
|
439
|
-
2. **Keep snapshots small** - Only send delta updates (use `Partial<T>` for snapshot.updates)
|
|
440
|
-
3. **Use fog of war** - Filter data with `broadcastSnapshotWithCustomization`
|
|
441
|
-
4. **Handle disconnections** - Clean up game state in `onDisconnection` handlers (registries auto-cleaned)
|
|
442
|
-
5. **Rate limit snapshots** - Typical game tick rates: 10-25 Hz (don't exceed 60Hz)
|
|
443
|
-
6. **Validate intents** - Always sanitize/validate data from clients (see validators)
|
|
444
|
-
7. **Use tick numbers** - Include tick in intents for prediction/rollback
|
|
445
|
-
8. **Transport buffer copying** - Custom transports MUST copy buffers in `send()` if queuing internally
|
|
446
|
-
|
|
447
|
-
## Performance Tips
|
|
448
|
-
|
|
449
|
-
- Use pooled codecs for zero-allocation encoding
|
|
450
|
-
- Batch snapshot updates when possible
|
|
451
|
-
- Implement delta compression for large states
|
|
452
|
-
- Use binary encoding (not JSON!)
|
|
453
|
-
- Consider different update rates for different data (e.g., position vs. health)
|
|
454
|
-
- Profile your snapshot sizes - aim for < 1KB per snapshot
|
|
455
|
-
|
|
456
|
-
## Current Features
|
|
457
|
-
|
|
458
|
-
Already implemented:
|
|
459
|
-
- ✅ Message priority/ordering (priority queue with backpressure)
|
|
460
|
-
- ✅ Bandwidth tracking (per-peer bandwidth monitoring)
|
|
461
|
-
- ✅ Rate limiting (configurable maxMessagesPerSecond)
|
|
462
|
-
- ✅ Buffer pooling (zero-copy message wrapping)
|
|
463
|
-
- ✅ Heartbeat/timeout detection (automatic disconnection)
|
|
464
|
-
- ✅ Intent validators (composable validation)
|
|
465
|
-
|
|
466
|
-
## Future Enhancements
|
|
467
|
-
|
|
468
|
-
Potential additions:
|
|
469
|
-
- Reliable message channels (with acks/retries)
|
|
470
|
-
- Automatic compression (LZ4/Zstd)
|
|
471
|
-
- Latency measurement (RTT tracking)
|
|
472
|
-
- Built-in lag compensation helpers
|
|
473
|
-
- Delta compression for snapshots
|
|
474
|
-
- Connection migration/reconnection
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { TransportAdapter } from "../types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Browser WebSocket transport adapter for ClientNetwork
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const transport = new BrowserWebSocketClientTransport("ws://localhost:3007");
|
|
9
|
-
* const client = new ClientNetwork({ transport, ... });
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
export class BrowserWebSocketClientTransport implements TransportAdapter {
|
|
13
|
-
private ws: WebSocket;
|
|
14
|
-
private openHandler: (() => void) | null = null;
|
|
15
|
-
private messageHandler: ((data: Uint8Array) => void) | null = null;
|
|
16
|
-
private closeHandler: (() => void) | null = null;
|
|
17
|
-
private errorHandler: ((error: Error) => void) | null = null;
|
|
18
|
-
private isOpen = false;
|
|
19
|
-
private pendingMessages: Uint8Array[] = [];
|
|
20
|
-
|
|
21
|
-
constructor(url: string) {
|
|
22
|
-
this.ws = new WebSocket(url);
|
|
23
|
-
this.ws.binaryType = 'arraybuffer';
|
|
24
|
-
|
|
25
|
-
this.ws.onopen = () => {
|
|
26
|
-
this.isOpen = true;
|
|
27
|
-
// Flush any pending messages
|
|
28
|
-
for (const msg of this.pendingMessages) {
|
|
29
|
-
this.ws.send(msg);
|
|
30
|
-
}
|
|
31
|
-
this.pendingMessages = [];
|
|
32
|
-
if (this.openHandler) {
|
|
33
|
-
this.openHandler();
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.ws.onmessage = (event) => {
|
|
38
|
-
if (this.messageHandler && event.data instanceof ArrayBuffer) {
|
|
39
|
-
this.messageHandler(new Uint8Array(event.data));
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
this.ws.onclose = () => {
|
|
44
|
-
this.isOpen = false;
|
|
45
|
-
if (this.closeHandler) {
|
|
46
|
-
this.closeHandler();
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
this.ws.onerror = () => {
|
|
51
|
-
if (this.errorHandler) {
|
|
52
|
-
this.errorHandler(new Error('WebSocket error'));
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
send(data: Uint8Array): void {
|
|
58
|
-
if (this.isOpen && this.ws.readyState === WebSocket.OPEN) {
|
|
59
|
-
// WebSocket.send() copies the buffer, so this is safe
|
|
60
|
-
this.ws.send(data);
|
|
61
|
-
} else if (this.ws.readyState === WebSocket.CONNECTING) {
|
|
62
|
-
// Queue messages sent before connection is established
|
|
63
|
-
this.pendingMessages.push(data);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
onMessage(handler: (data: Uint8Array) => void): void {
|
|
68
|
-
this.messageHandler = handler;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
onOpen(handler: () => void): void {
|
|
72
|
-
this.openHandler = handler;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
onClose(handler: () => void): void {
|
|
76
|
-
this.closeHandler = handler;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
onError(handler: (error: Error) => void): void {
|
|
80
|
-
this.errorHandler = handler;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
close(): void {
|
|
84
|
-
this.ws.close();
|
|
85
|
-
}
|
|
86
|
-
}
|