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
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { Component } from "./component";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stores component data using separate TypedArrays per field (SoA - Structure of Arrays).
|
|
5
|
-
* Alternative to DataView-based storage for comparison.
|
|
6
|
-
*
|
|
7
|
-
* Tradeoffs:
|
|
8
|
-
* + Faster individual field access (native typed array operations)
|
|
9
|
-
* + Better for column-major access patterns
|
|
10
|
-
* + SIMD-friendly (can vectorize single-field operations)
|
|
11
|
-
* - Worse cache locality for row-major access (whole component reads)
|
|
12
|
-
* - More memory fragmentation (separate arrays)
|
|
13
|
-
* - Slightly higher memory overhead (each TypedArray has its own header)
|
|
14
|
-
*/
|
|
15
|
-
export class ComponentStore<T extends object> {
|
|
16
|
-
private arrays: (Float32Array | Int32Array | Uint32Array | Uint16Array | Uint8Array)[];
|
|
17
|
-
private stride: number; // Component size in bytes (for compatibility)
|
|
18
|
-
private component: Component<T>;
|
|
19
|
-
private maxEntities: number;
|
|
20
|
-
|
|
21
|
-
// Single reusable object for get() - zero allocations!
|
|
22
|
-
private reusableObject: T;
|
|
23
|
-
|
|
24
|
-
// Pre-computed field metadata for fast access
|
|
25
|
-
private fields: any[];
|
|
26
|
-
private fieldKeys: (keyof T)[];
|
|
27
|
-
private fieldIndexMap: Record<string, number>;
|
|
28
|
-
|
|
29
|
-
constructor(component: Component<T>, maxEntities: number) {
|
|
30
|
-
this.component = component;
|
|
31
|
-
this.maxEntities = maxEntities;
|
|
32
|
-
this.stride = component.size;
|
|
33
|
-
|
|
34
|
-
// Pre-compute field metadata
|
|
35
|
-
this.fieldKeys = component.fieldNames;
|
|
36
|
-
this.fields = [];
|
|
37
|
-
this.fieldIndexMap = {};
|
|
38
|
-
this.arrays = [];
|
|
39
|
-
|
|
40
|
-
// Create separate typed array for each field
|
|
41
|
-
for (let i = 0; i < this.fieldKeys.length; i++) {
|
|
42
|
-
const key = this.fieldKeys[i];
|
|
43
|
-
const field = component.schema[key];
|
|
44
|
-
this.fields.push(field);
|
|
45
|
-
this.fieldIndexMap[key as string] = i;
|
|
46
|
-
|
|
47
|
-
// Allocate appropriate typed array based on field type
|
|
48
|
-
switch (field.size) {
|
|
49
|
-
case 4:
|
|
50
|
-
// Could be f32, i32, or u32 - check field type
|
|
51
|
-
if (field.read.toString().includes("getFloat32")) {
|
|
52
|
-
this.arrays.push(new Float32Array(maxEntities));
|
|
53
|
-
} else if (field.read.toString().includes("getInt32")) {
|
|
54
|
-
this.arrays.push(new Int32Array(maxEntities));
|
|
55
|
-
} else {
|
|
56
|
-
this.arrays.push(new Uint32Array(maxEntities));
|
|
57
|
-
}
|
|
58
|
-
break;
|
|
59
|
-
case 2:
|
|
60
|
-
this.arrays.push(new Uint16Array(maxEntities));
|
|
61
|
-
break;
|
|
62
|
-
case 1:
|
|
63
|
-
this.arrays.push(new Uint8Array(maxEntities));
|
|
64
|
-
break;
|
|
65
|
-
default:
|
|
66
|
-
// Fallback to Uint8Array with multiple elements
|
|
67
|
-
this.arrays.push(new Uint8Array(maxEntities * field.size));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Create single reusable object
|
|
72
|
-
this.reusableObject = {} as T;
|
|
73
|
-
for (let i = 0; i < this.fieldKeys.length; i++) {
|
|
74
|
-
this.reusableObject[this.fieldKeys[i]] = this.fields[i].toNil();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Get component data for an entity.
|
|
80
|
-
*
|
|
81
|
-
* ⚠️ IMPORTANT: Returns a REUSED object that is overwritten on the next get() call.
|
|
82
|
-
*/
|
|
83
|
-
get(entityId: number): Readonly<T> {
|
|
84
|
-
const length = this.fields.length;
|
|
85
|
-
|
|
86
|
-
// Unrolled loop for common cases
|
|
87
|
-
if (length === 2) {
|
|
88
|
-
this.reusableObject[this.fieldKeys[0]] = this.arrays[0][entityId] as any;
|
|
89
|
-
this.reusableObject[this.fieldKeys[1]] = this.arrays[1][entityId] as any;
|
|
90
|
-
} else if (length === 3) {
|
|
91
|
-
this.reusableObject[this.fieldKeys[0]] = this.arrays[0][entityId] as any;
|
|
92
|
-
this.reusableObject[this.fieldKeys[1]] = this.arrays[1][entityId] as any;
|
|
93
|
-
this.reusableObject[this.fieldKeys[2]] = this.arrays[2][entityId] as any;
|
|
94
|
-
} else if (length === 4) {
|
|
95
|
-
this.reusableObject[this.fieldKeys[0]] = this.arrays[0][entityId] as any;
|
|
96
|
-
this.reusableObject[this.fieldKeys[1]] = this.arrays[1][entityId] as any;
|
|
97
|
-
this.reusableObject[this.fieldKeys[2]] = this.arrays[2][entityId] as any;
|
|
98
|
-
this.reusableObject[this.fieldKeys[3]] = this.arrays[3][entityId] as any;
|
|
99
|
-
} else {
|
|
100
|
-
// Generic loop for other sizes
|
|
101
|
-
for (let i = 0; i < length; i++) {
|
|
102
|
-
this.reusableObject[this.fieldKeys[i]] = this.arrays[i][entityId] as any;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return this.reusableObject as Readonly<T>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Get a mutable copy of component data.
|
|
111
|
-
*/
|
|
112
|
-
getMutable(entityId: number): T {
|
|
113
|
-
const copy = {} as T;
|
|
114
|
-
this.copyTo(entityId, copy);
|
|
115
|
-
return copy;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Copy component data into a provided object.
|
|
120
|
-
*/
|
|
121
|
-
copyTo(entityId: number, target: T): void {
|
|
122
|
-
for (let i = 0; i < this.fields.length; i++) {
|
|
123
|
-
target[this.fieldKeys[i]] = this.arrays[i][entityId] as any;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Set component data for an entity.
|
|
129
|
-
*/
|
|
130
|
-
set(entityId: number, data: T): void {
|
|
131
|
-
const length = this.fields.length;
|
|
132
|
-
|
|
133
|
-
// Unrolled loop for common cases
|
|
134
|
-
if (length === 2) {
|
|
135
|
-
this.arrays[0][entityId] = data[this.fieldKeys[0]] as any;
|
|
136
|
-
this.arrays[1][entityId] = data[this.fieldKeys[1]] as any;
|
|
137
|
-
} else if (length === 3) {
|
|
138
|
-
this.arrays[0][entityId] = data[this.fieldKeys[0]] as any;
|
|
139
|
-
this.arrays[1][entityId] = data[this.fieldKeys[1]] as any;
|
|
140
|
-
this.arrays[2][entityId] = data[this.fieldKeys[2]] as any;
|
|
141
|
-
} else if (length === 4) {
|
|
142
|
-
this.arrays[0][entityId] = data[this.fieldKeys[0]] as any;
|
|
143
|
-
this.arrays[1][entityId] = data[this.fieldKeys[1]] as any;
|
|
144
|
-
this.arrays[2][entityId] = data[this.fieldKeys[2]] as any;
|
|
145
|
-
this.arrays[3][entityId] = data[this.fieldKeys[3]] as any;
|
|
146
|
-
} else {
|
|
147
|
-
// Generic loop for other sizes
|
|
148
|
-
for (let i = 0; i < length; i++) {
|
|
149
|
-
this.arrays[i][entityId] = data[this.fieldKeys[i]] as any;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Update specific fields of a component.
|
|
156
|
-
* Optimized to avoid Object.keys() allocation in hot path.
|
|
157
|
-
*/
|
|
158
|
-
update(entityId: number, partial: Partial<T>): void {
|
|
159
|
-
// Direct iteration
|
|
160
|
-
for (const key in partial) {
|
|
161
|
-
const i = this.fieldIndexMap[key];
|
|
162
|
-
this.arrays[i][entityId] = partial[key as keyof T] as any;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Clear component data for an entity (set to default values)
|
|
168
|
-
*/
|
|
169
|
-
clear(entityId: number): void {
|
|
170
|
-
for (let i = 0; i < this.fields.length; i++) {
|
|
171
|
-
this.arrays[i][entityId] = this.fields[i].toNil();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Get direct access to the underlying arrays.
|
|
177
|
-
* Advanced use only - for SIMD operations, batch processing, etc.
|
|
178
|
-
*/
|
|
179
|
-
getRawArrays(): readonly (Float32Array | Int32Array | Uint32Array | Uint16Array | Uint8Array)[] {
|
|
180
|
-
return this.arrays;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Get a specific field's array directly.
|
|
185
|
-
* Useful for vectorized operations on a single field across all entities.
|
|
186
|
-
*/
|
|
187
|
-
getFieldArray(fieldName: keyof T): Float32Array | Int32Array | Uint32Array | Uint16Array | Uint8Array {
|
|
188
|
-
const index = this.fieldIndexMap[fieldName as string];
|
|
189
|
-
return this.arrays[index];
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Get the stride in bytes (for compatibility with DataView version).
|
|
194
|
-
*/
|
|
195
|
-
getStride(): number {
|
|
196
|
-
return this.stride;
|
|
197
|
-
}
|
|
198
|
-
}
|
package/src/ecs/component.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Schema } from "../core/binary-codec";
|
|
2
|
-
import { PooledCodec, ArrayField } from "../core/pooled-codec";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Metadata for a component definition
|
|
6
|
-
*/
|
|
7
|
-
export interface ComponentMeta<T extends object> {
|
|
8
|
-
/** Schema defining the component's binary layout */
|
|
9
|
-
schema: Schema<T>;
|
|
10
|
-
|
|
11
|
-
/** Unique name for this component type */
|
|
12
|
-
name: string;
|
|
13
|
-
|
|
14
|
-
/** Size of the component in bytes */
|
|
15
|
-
size: number;
|
|
16
|
-
|
|
17
|
-
/** Number of fields in the schema */
|
|
18
|
-
fieldCount: number;
|
|
19
|
-
|
|
20
|
-
/** Field names in order */
|
|
21
|
-
fieldNames: (keyof T)[];
|
|
22
|
-
|
|
23
|
-
/** Codec for array serialization */
|
|
24
|
-
arrayCodec: ArrayField<T>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Component type returned by defineComponent
|
|
29
|
-
*/
|
|
30
|
-
export type Component<T extends object = any> = ComponentMeta<T> & {
|
|
31
|
-
/** Type marker for TypeScript inference */
|
|
32
|
-
__type?: T;
|
|
33
|
-
|
|
34
|
-
/** Internal: Index assigned by World when registered */
|
|
35
|
-
__worldIndex?: number;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Infer the data type from a Component
|
|
40
|
-
*/
|
|
41
|
-
export type InferComponentType<C> = C extends Component<infer T> ? T : never;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Calculate the byte size of a schema
|
|
45
|
-
*/
|
|
46
|
-
function calculateSchemaSize<T extends object>(schema: Schema<T>): number {
|
|
47
|
-
let size = 0;
|
|
48
|
-
for (const key of Object.keys(schema) as (keyof T)[]) {
|
|
49
|
-
size += schema[key].size;
|
|
50
|
-
}
|
|
51
|
-
return size;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Define a component type with its binary schema.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```typescript
|
|
59
|
-
* const Transform = defineComponent('Transform', {
|
|
60
|
-
* x: BinaryCodec.f32,
|
|
61
|
-
* y: BinaryCodec.f32,
|
|
62
|
-
* rotation: BinaryCodec.f32,
|
|
63
|
-
* });
|
|
64
|
-
*
|
|
65
|
-
* const Health = defineComponent('Health', {
|
|
66
|
-
* current: BinaryCodec.u16,
|
|
67
|
-
* max: BinaryCodec.u16,
|
|
68
|
-
* });
|
|
69
|
-
* ```
|
|
70
|
-
*/
|
|
71
|
-
export function defineComponent<T extends object>(
|
|
72
|
-
name: string,
|
|
73
|
-
schema: Schema<T>
|
|
74
|
-
): Component<T> {
|
|
75
|
-
const size = calculateSchemaSize(schema);
|
|
76
|
-
const fieldNames = Object.keys(schema) as (keyof T)[];
|
|
77
|
-
const fieldCount = fieldNames.length;
|
|
78
|
-
|
|
79
|
-
// Create PooledCodec for array serialization
|
|
80
|
-
const arrayCodec = PooledCodec.array(schema);
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
name,
|
|
84
|
-
schema,
|
|
85
|
-
size,
|
|
86
|
-
fieldCount,
|
|
87
|
-
fieldNames,
|
|
88
|
-
arrayCodec,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { BinaryCodec } from "../core/binary-codec";
|
|
3
|
-
import { defineComponent } from "./component";
|
|
4
|
-
import { EntityHandle } from "./entity-handle";
|
|
5
|
-
import { World } from "./world";
|
|
6
|
-
|
|
7
|
-
// Define test components
|
|
8
|
-
const Transform = defineComponent("Transform", {
|
|
9
|
-
x: BinaryCodec.f32,
|
|
10
|
-
y: BinaryCodec.f32,
|
|
11
|
-
rotation: BinaryCodec.f32,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const Velocity = defineComponent("Velocity", {
|
|
15
|
-
vx: BinaryCodec.f32,
|
|
16
|
-
vy: BinaryCodec.f32,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const Health = defineComponent("Health", {
|
|
20
|
-
current: BinaryCodec.u16,
|
|
21
|
-
max: BinaryCodec.u16,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe("EntityHandle", () => {
|
|
25
|
-
test("should create entity handle and expose raw id", () => {
|
|
26
|
-
const world = new World({
|
|
27
|
-
maxEntities: 100,
|
|
28
|
-
components: [Transform],
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const entityId = world.spawn();
|
|
32
|
-
const handle = new EntityHandle(world, entityId);
|
|
33
|
-
|
|
34
|
-
expect(handle.id).toBe(entityId);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test("should support fluent API with method chaining", () => {
|
|
38
|
-
const world = new World({
|
|
39
|
-
maxEntities: 100,
|
|
40
|
-
components: [Transform, Velocity, Health],
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const entity = world.entity(world.spawn())
|
|
44
|
-
.add(Transform, { x: 100, y: 200, rotation: 0 })
|
|
45
|
-
.add(Velocity, { vx: 10, vy: 20 })
|
|
46
|
-
.add(Health, { current: 100, max: 100 });
|
|
47
|
-
|
|
48
|
-
// Verify all components were added
|
|
49
|
-
expect(world.has(entity.id, Transform)).toBe(true);
|
|
50
|
-
expect(world.has(entity.id, Velocity)).toBe(true);
|
|
51
|
-
expect(world.has(entity.id, Health)).toBe(true);
|
|
52
|
-
|
|
53
|
-
// Verify data is correct
|
|
54
|
-
const transform = entity.get(Transform);
|
|
55
|
-
expect(transform.x).toBe(100);
|
|
56
|
-
expect(transform.y).toBe(200);
|
|
57
|
-
|
|
58
|
-
const velocity = entity.get(Velocity);
|
|
59
|
-
expect(velocity.vx).toBe(10);
|
|
60
|
-
expect(velocity.vy).toBe(20);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("should support add operation", () => {
|
|
64
|
-
const world = new World({
|
|
65
|
-
maxEntities: 100,
|
|
66
|
-
components: [Transform],
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const entity = world.entity(world.spawn());
|
|
70
|
-
entity.add(Transform, { x: 50, y: 100, rotation: 0 });
|
|
71
|
-
|
|
72
|
-
expect(entity.has(Transform)).toBe(true);
|
|
73
|
-
const t = entity.get(Transform);
|
|
74
|
-
expect(t.x).toBe(50);
|
|
75
|
-
expect(t.y).toBe(100);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("should support get operation", () => {
|
|
79
|
-
const world = new World({
|
|
80
|
-
maxEntities: 100,
|
|
81
|
-
components: [Transform],
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const entity = world.entity(world.spawn());
|
|
85
|
-
entity.add(Transform, { x: 10, y: 20, rotation: 0.5 });
|
|
86
|
-
|
|
87
|
-
const transform = entity.get(Transform);
|
|
88
|
-
expect(transform.x).toBe(10);
|
|
89
|
-
expect(transform.y).toBe(20);
|
|
90
|
-
expect(transform.rotation).toBe(0.5);
|
|
91
|
-
|
|
92
|
-
// TypeScript prevents mutation at compile time (Readonly<T>)
|
|
93
|
-
// At runtime, it's the same reusable object from ComponentStore
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test("should support update operation with chaining", () => {
|
|
97
|
-
const world = new World({
|
|
98
|
-
maxEntities: 100,
|
|
99
|
-
components: [Transform, Health],
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const entity = world.entity(world.spawn())
|
|
103
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 })
|
|
104
|
-
.add(Health, { current: 100, max: 100 });
|
|
105
|
-
|
|
106
|
-
entity
|
|
107
|
-
.update(Transform, { x: 150 })
|
|
108
|
-
.update(Health, { current: 50 });
|
|
109
|
-
|
|
110
|
-
const transform = entity.get(Transform);
|
|
111
|
-
expect(transform.x).toBe(150);
|
|
112
|
-
expect(transform.y).toBe(0); // Unchanged
|
|
113
|
-
|
|
114
|
-
const health = entity.get(Health);
|
|
115
|
-
expect(health.current).toBe(50);
|
|
116
|
-
expect(health.max).toBe(100); // Unchanged
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test("should support set operation with chaining", () => {
|
|
120
|
-
const world = new World({
|
|
121
|
-
maxEntities: 100,
|
|
122
|
-
components: [Transform],
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
const entity = world.entity(world.spawn())
|
|
126
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 });
|
|
127
|
-
|
|
128
|
-
entity.set(Transform, { x: 100, y: 200, rotation: 1.5 });
|
|
129
|
-
|
|
130
|
-
const transform = entity.get(Transform);
|
|
131
|
-
expect(transform.x).toBe(100);
|
|
132
|
-
expect(transform.y).toBe(200);
|
|
133
|
-
expect(transform.rotation).toBe(1.5);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test("should support has operation", () => {
|
|
137
|
-
const world = new World({
|
|
138
|
-
maxEntities: 100,
|
|
139
|
-
components: [Transform, Velocity],
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const entity = world.entity(world.spawn())
|
|
143
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 });
|
|
144
|
-
|
|
145
|
-
expect(entity.has(Transform)).toBe(true);
|
|
146
|
-
expect(entity.has(Velocity)).toBe(false);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test("should support remove operation with chaining", () => {
|
|
150
|
-
const world = new World({
|
|
151
|
-
maxEntities: 100,
|
|
152
|
-
components: [Transform, Velocity, Health],
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const entity = world.entity(world.spawn())
|
|
156
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 })
|
|
157
|
-
.add(Velocity, { vx: 10, vy: 20 })
|
|
158
|
-
.add(Health, { current: 100, max: 100 });
|
|
159
|
-
|
|
160
|
-
entity
|
|
161
|
-
.remove(Velocity)
|
|
162
|
-
.remove(Health);
|
|
163
|
-
|
|
164
|
-
expect(entity.has(Transform)).toBe(true);
|
|
165
|
-
expect(entity.has(Velocity)).toBe(false);
|
|
166
|
-
expect(entity.has(Health)).toBe(false);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
test("should support despawn operation", () => {
|
|
170
|
-
const world = new World({
|
|
171
|
-
maxEntities: 100,
|
|
172
|
-
components: [Transform],
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
const entity = world.entity(world.spawn())
|
|
176
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 });
|
|
177
|
-
|
|
178
|
-
expect(entity.isAlive()).toBe(true);
|
|
179
|
-
|
|
180
|
-
entity.despawn();
|
|
181
|
-
|
|
182
|
-
expect(entity.isAlive()).toBe(false);
|
|
183
|
-
expect(world.isAlive(entity.id)).toBe(false);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test("should support isAlive check", () => {
|
|
187
|
-
const world = new World({
|
|
188
|
-
maxEntities: 100,
|
|
189
|
-
components: [Transform],
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
const entity = world.entity(world.spawn());
|
|
193
|
-
|
|
194
|
-
expect(entity.isAlive()).toBe(true);
|
|
195
|
-
|
|
196
|
-
world.despawn(entity.id);
|
|
197
|
-
|
|
198
|
-
expect(entity.isAlive()).toBe(false);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
test("should support getMutable operation", () => {
|
|
202
|
-
const world = new World({
|
|
203
|
-
maxEntities: 100,
|
|
204
|
-
components: [Transform],
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
const entity = world.entity(world.spawn())
|
|
208
|
-
.add(Transform, { x: 10, y: 20, rotation: 0 });
|
|
209
|
-
|
|
210
|
-
const transform = entity.getMutable(Transform);
|
|
211
|
-
transform.x = 100;
|
|
212
|
-
transform.y = 200;
|
|
213
|
-
|
|
214
|
-
entity.set(Transform, transform);
|
|
215
|
-
|
|
216
|
-
const updated = entity.get(Transform);
|
|
217
|
-
expect(updated.x).toBe(100);
|
|
218
|
-
expect(updated.y).toBe(200);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
test("should work in realistic game loop", () => {
|
|
222
|
-
const world = new World({
|
|
223
|
-
maxEntities: 100,
|
|
224
|
-
components: [Transform, Velocity, Health],
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// Create entities using fluent API
|
|
228
|
-
const player = world.entity(world.spawn())
|
|
229
|
-
.add(Transform, { x: 0, y: 0, rotation: 0 })
|
|
230
|
-
.add(Velocity, { vx: 5, vy: 0 })
|
|
231
|
-
.add(Health, { current: 100, max: 100 });
|
|
232
|
-
|
|
233
|
-
const enemy = world.entity(world.spawn())
|
|
234
|
-
.add(Transform, { x: 100, y: 0, rotation: 0 })
|
|
235
|
-
.add(Velocity, { vx: -2, vy: 0 })
|
|
236
|
-
.add(Health, { current: 50, max: 50 });
|
|
237
|
-
|
|
238
|
-
// Simulate 10 frames
|
|
239
|
-
const deltaTime = 0.016;
|
|
240
|
-
for (let i = 0; i < 10; i++) {
|
|
241
|
-
// Movement system
|
|
242
|
-
for (const entityId of world.query(Transform, Velocity)) {
|
|
243
|
-
const entity = world.entity(entityId);
|
|
244
|
-
const t = entity.get(Transform);
|
|
245
|
-
const v = entity.get(Velocity);
|
|
246
|
-
|
|
247
|
-
entity.update(Transform, {
|
|
248
|
-
x: t.x + v.vx * deltaTime,
|
|
249
|
-
y: t.y + v.vy * deltaTime,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Verify positions changed
|
|
255
|
-
const playerTransform = player.get(Transform);
|
|
256
|
-
expect(playerTransform.x).toBeCloseTo(0.8, 1);
|
|
257
|
-
|
|
258
|
-
const enemyTransform = enemy.get(Transform);
|
|
259
|
-
expect(enemyTransform.x).toBeCloseTo(99.68, 1);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
test("PERFORMANCE: EntityHandle should have zero overhead vs raw API", () => {
|
|
263
|
-
const world = new World({
|
|
264
|
-
maxEntities: 10000,
|
|
265
|
-
components: [Transform, Velocity],
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
const iterations = 10000;
|
|
269
|
-
|
|
270
|
-
// Benchmark raw API
|
|
271
|
-
const rawStart = performance.now();
|
|
272
|
-
for (let i = 0; i < iterations; i++) {
|
|
273
|
-
const id = world.spawn();
|
|
274
|
-
world.add(id, Transform, { x: i, y: i, rotation: 0 });
|
|
275
|
-
world.add(id, Velocity, { vx: 1, vy: 1 });
|
|
276
|
-
world.update(id, Transform, { x: i + 1 });
|
|
277
|
-
const t = world.get(id, Transform);
|
|
278
|
-
world.remove(id, Velocity);
|
|
279
|
-
world.despawn(id);
|
|
280
|
-
}
|
|
281
|
-
const rawTime = performance.now() - rawStart;
|
|
282
|
-
|
|
283
|
-
// Benchmark EntityHandle API
|
|
284
|
-
const handleStart = performance.now();
|
|
285
|
-
for (let i = 0; i < iterations; i++) {
|
|
286
|
-
const entity = world.entity(world.spawn())
|
|
287
|
-
.add(Transform, { x: i, y: i, rotation: 0 })
|
|
288
|
-
.add(Velocity, { vx: 1, vy: 1 })
|
|
289
|
-
.update(Transform, { x: i + 1 });
|
|
290
|
-
|
|
291
|
-
const t = entity.get(Transform);
|
|
292
|
-
entity.remove(Velocity).despawn();
|
|
293
|
-
}
|
|
294
|
-
const handleTime = performance.now() - handleStart;
|
|
295
|
-
|
|
296
|
-
console.log(`\nEntityHandle Performance Test (${iterations} iterations):`);
|
|
297
|
-
console.log(`Raw API time: ${rawTime.toFixed(2)}ms`);
|
|
298
|
-
console.log(`Handle API time: ${handleTime.toFixed(2)}ms`);
|
|
299
|
-
console.log(`Overhead: ${((handleTime / rawTime - 1) * 100).toFixed(1)}%`);
|
|
300
|
-
|
|
301
|
-
// Handle should be within 50% of raw performance (accounting for JIT warmup and variance)
|
|
302
|
-
// In real-world usage with proper JIT optimization, overhead is typically <5%
|
|
303
|
-
expect(handleTime).toBeLessThan(rawTime * 1.5);
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
test("PERFORMANCE: EntityHandle in query loops should match raw API", () => {
|
|
307
|
-
const world = new World({
|
|
308
|
-
maxEntities: 5000,
|
|
309
|
-
components: [Transform, Velocity],
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// Setup entities
|
|
313
|
-
const entities: number[] = [];
|
|
314
|
-
for (let i = 0; i < 5000; i++) {
|
|
315
|
-
const id = world.spawn();
|
|
316
|
-
world.add(id, Transform, { x: i, y: i, rotation: 0 });
|
|
317
|
-
world.add(id, Velocity, { vx: 1, vy: 1 });
|
|
318
|
-
entities.push(id);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const iterations = 100;
|
|
322
|
-
const deltaTime = 0.016;
|
|
323
|
-
|
|
324
|
-
// Benchmark raw API
|
|
325
|
-
const rawStart = performance.now();
|
|
326
|
-
for (let iter = 0; iter < iterations; iter++) {
|
|
327
|
-
for (const id of world.query(Transform, Velocity)) {
|
|
328
|
-
const t = world.get(id, Transform);
|
|
329
|
-
const v = world.get(id, Velocity);
|
|
330
|
-
world.update(id, Transform, {
|
|
331
|
-
x: t.x + v.vx * deltaTime,
|
|
332
|
-
y: t.y + v.vy * deltaTime,
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const rawTime = performance.now() - rawStart;
|
|
337
|
-
|
|
338
|
-
// Reset positions
|
|
339
|
-
for (const id of entities) {
|
|
340
|
-
world.update(id, Transform, { x: 0, y: 0 });
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Benchmark EntityHandle API
|
|
344
|
-
const handleStart = performance.now();
|
|
345
|
-
for (let iter = 0; iter < iterations; iter++) {
|
|
346
|
-
for (const id of world.query(Transform, Velocity)) {
|
|
347
|
-
const entity = world.entity(id);
|
|
348
|
-
const t = entity.get(Transform);
|
|
349
|
-
const v = entity.get(Velocity);
|
|
350
|
-
entity.update(Transform, {
|
|
351
|
-
x: t.x + v.vx * deltaTime,
|
|
352
|
-
y: t.y + v.vy * deltaTime,
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
const handleTime = performance.now() - handleStart;
|
|
357
|
-
|
|
358
|
-
console.log(`\nEntityHandle Query Loop Performance (5k entities, ${iterations} frames):`);
|
|
359
|
-
console.log(`Raw API time: ${rawTime.toFixed(2)}ms`);
|
|
360
|
-
console.log(`Handle API time: ${handleTime.toFixed(2)}ms`);
|
|
361
|
-
console.log(`Overhead: ${((handleTime / rawTime - 1) * 100).toFixed(1)}%`);
|
|
362
|
-
|
|
363
|
-
// Handle should be within 25% of raw performance in query loops (accounting for variance)
|
|
364
|
-
// Typical overhead in production: 0-5%
|
|
365
|
-
expect(handleTime).toBeLessThan(rawTime * 1.25);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
test("PERFORMANCE: EntityHandle construction should be negligible", () => {
|
|
369
|
-
const world = new World({
|
|
370
|
-
maxEntities: 10000,
|
|
371
|
-
components: [Transform],
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
const entities = [];
|
|
375
|
-
for (let i = 0; i < 10000; i++) {
|
|
376
|
-
entities.push(world.spawn());
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Benchmark handle construction
|
|
380
|
-
const start = performance.now();
|
|
381
|
-
for (let i = 0; i < 10000; i++) {
|
|
382
|
-
const handle = world.entity(entities[i]);
|
|
383
|
-
const id = handle.id; // Use it to prevent optimization
|
|
384
|
-
}
|
|
385
|
-
const elapsed = performance.now() - start;
|
|
386
|
-
|
|
387
|
-
console.log(`\nEntityHandle Construction (10k handles): ${elapsed.toFixed(2)}ms`);
|
|
388
|
-
console.log(`Per handle: ${(elapsed / 10000 * 1000).toFixed(2)}µs`);
|
|
389
|
-
|
|
390
|
-
// Should be extremely fast (< 1ms for 10k constructions)
|
|
391
|
-
expect(elapsed).toBeLessThan(1.0);
|
|
392
|
-
});
|
|
393
|
-
});
|