@zylem/behaviors 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{chunk-K4UBXSZL.js → chunk-2C3Z5GE7.js} +2 -1
  3. package/dist/chunk-2C3Z5GE7.js.map +1 -0
  4. package/dist/{chunk-BC3IJYS7.js → chunk-2CLT36VB.js} +5 -4
  5. package/dist/chunk-2CLT36VB.js.map +1 -0
  6. package/dist/{chunk-23HQH3GJ.js → chunk-3PYGRHAL.js} +2 -1
  7. package/dist/chunk-3PYGRHAL.js.map +1 -0
  8. package/dist/{chunk-6UMC6BB5.js → chunk-4I6E6DGV.js} +5 -4
  9. package/dist/chunk-4I6E6DGV.js.map +1 -0
  10. package/dist/{chunk-RER2IDPW.js → chunk-4URF65BR.js} +1 -0
  11. package/dist/chunk-4URF65BR.js.map +1 -0
  12. package/dist/{chunk-IEA7F73P.js → chunk-6C6NXNEW.js} +2 -1
  13. package/dist/chunk-6C6NXNEW.js.map +1 -0
  14. package/dist/{chunk-WSKD7GY3.js → chunk-7JJEIADR.js} +1 -0
  15. package/dist/chunk-7JJEIADR.js.map +1 -0
  16. package/dist/{chunk-6Y3GB76J.js → chunk-ARJWUNRE.js} +4 -3
  17. package/dist/chunk-ARJWUNRE.js.map +1 -0
  18. package/dist/{chunk-F6LFX4V3.js → chunk-BXP4K7RF.js} +3 -2
  19. package/dist/chunk-BXP4K7RF.js.map +1 -0
  20. package/dist/{chunk-F7E23E26.js → chunk-DYLH6K7B.js} +1 -0
  21. package/dist/chunk-DYLH6K7B.js.map +1 -0
  22. package/dist/{chunk-2HKY6WF7.js → chunk-EIWQM6U3.js} +1 -0
  23. package/dist/chunk-EIWQM6U3.js.map +1 -0
  24. package/dist/{chunk-YDLO5M7S.js → chunk-EZNCCO4L.js} +1 -0
  25. package/dist/chunk-EZNCCO4L.js.map +1 -0
  26. package/dist/{chunk-FOOM42MK.js → chunk-F3KRX2V4.js} +6 -5
  27. package/dist/chunk-F3KRX2V4.js.map +1 -0
  28. package/dist/{chunk-7IZ36Y5G.js → chunk-FPTWVCPN.js} +3 -2
  29. package/dist/chunk-FPTWVCPN.js.map +1 -0
  30. package/dist/{chunk-7Y6JVZ5H.js → chunk-GCNRXAKH.js} +2 -1
  31. package/dist/chunk-GCNRXAKH.js.map +1 -0
  32. package/dist/{chunk-4DVDFCVY.js → chunk-HZMY3TT4.js} +1 -0
  33. package/dist/chunk-HZMY3TT4.js.map +1 -0
  34. package/dist/{chunk-7U4WFBWM.js → chunk-ID5QJYF5.js} +1 -0
  35. package/dist/chunk-ID5QJYF5.js.map +1 -0
  36. package/dist/{chunk-T2P4JTQN.js → chunk-JAN34G6S.js} +3 -2
  37. package/dist/chunk-JAN34G6S.js.map +1 -0
  38. package/dist/{chunk-J5XLB24H.js → chunk-K3UNLQ7W.js} +2 -1
  39. package/dist/chunk-K3UNLQ7W.js.map +1 -0
  40. package/dist/{chunk-ZHBD65AZ.js → chunk-KDY5N6J4.js} +1 -0
  41. package/dist/chunk-KDY5N6J4.js.map +1 -0
  42. package/dist/{chunk-RD2YTTXY.js → chunk-KOZUNIIE.js} +4 -3
  43. package/dist/chunk-KOZUNIIE.js.map +1 -0
  44. package/dist/{chunk-2HLZBWGD.js → chunk-KS72RZHX.js} +1 -0
  45. package/dist/chunk-KS72RZHX.js.map +1 -0
  46. package/dist/{chunk-4EWASZHB.js → chunk-LD5SMIB3.js} +1 -0
  47. package/dist/chunk-LD5SMIB3.js.map +1 -0
  48. package/dist/{chunk-WHKPWIQO.js → chunk-OHCPV2NT.js} +1 -0
  49. package/dist/chunk-OHCPV2NT.js.map +1 -0
  50. package/dist/{chunk-HIBJDA5Z.js → chunk-OYWFPIHF.js} +5 -4
  51. package/dist/chunk-OYWFPIHF.js.map +1 -0
  52. package/dist/{chunk-FHDYJ5WP.js → chunk-RTRVBEIB.js} +3 -2
  53. package/dist/chunk-RTRVBEIB.js.map +1 -0
  54. package/dist/{chunk-RQWWUML4.js → chunk-RTVRUNYR.js} +1 -0
  55. package/dist/chunk-RTVRUNYR.js.map +1 -0
  56. package/dist/{chunk-IQRG5BAZ.js → chunk-SS7ELMJ7.js} +5 -4
  57. package/dist/chunk-SS7ELMJ7.js.map +1 -0
  58. package/dist/{chunk-L76JG73P.js → chunk-STCCNLPC.js} +4 -3
  59. package/dist/chunk-STCCNLPC.js.map +1 -0
  60. package/dist/{chunk-UFHYR2LV.js → chunk-SVLNF434.js} +1 -0
  61. package/dist/chunk-SVLNF434.js.map +1 -0
  62. package/dist/{chunk-K6CWKFHL.js → chunk-UYFOLI2X.js} +1 -0
  63. package/dist/chunk-UYFOLI2X.js.map +1 -0
  64. package/dist/{chunk-VO5J64DG.js → chunk-VAN4WW3F.js} +3 -2
  65. package/dist/chunk-VAN4WW3F.js.map +1 -0
  66. package/dist/{chunk-ERS6SNA5.js → chunk-WOMHL23C.js} +2 -1
  67. package/dist/chunk-WOMHL23C.js.map +1 -0
  68. package/dist/{chunk-RHW3IDQX.js → chunk-WWVD5DR5.js} +1 -0
  69. package/dist/chunk-WWVD5DR5.js.map +1 -0
  70. package/dist/{chunk-E4HTCQPK.js → chunk-XG2YMCJW.js} +5 -4
  71. package/dist/chunk-XG2YMCJW.js.map +1 -0
  72. package/dist/{chunk-D53GNZXP.js → chunk-XIJNE67Y.js} +4 -3
  73. package/dist/chunk-XIJNE67Y.js.map +1 -0
  74. package/dist/{chunk-YYJP62QD.js → chunk-Y6UJOUE5.js} +1 -0
  75. package/dist/chunk-Y6UJOUE5.js.map +1 -0
  76. package/dist/{chunk-SBACY5SU.js → chunk-YUO6SKJD.js} +6 -5
  77. package/dist/chunk-YUO6SKJD.js.map +1 -0
  78. package/dist/{chunk-VPZ32CCD.js → chunk-ZPSAXX73.js} +4 -3
  79. package/dist/chunk-ZPSAXX73.js.map +1 -0
  80. package/dist/cooldown.js +3 -2
  81. package/dist/cooldown.js.map +1 -0
  82. package/dist/coordinators/boundary-ricochet-3d.js +3 -2
  83. package/dist/coordinators/boundary-ricochet-3d.js.map +1 -0
  84. package/dist/coordinators/boundary-ricochet.js +3 -2
  85. package/dist/coordinators/boundary-ricochet.js.map +1 -0
  86. package/dist/coordinators/first-person-shooter.js +4 -3
  87. package/dist/coordinators/first-person-shooter.js.map +1 -0
  88. package/dist/coordinators/multidirectional-space-shooter.js +5 -4
  89. package/dist/coordinators/multidirectional-space-shooter.js.map +1 -0
  90. package/dist/coordinators/top-down-shooter.js +5 -4
  91. package/dist/coordinators/top-down-shooter.js.map +1 -0
  92. package/dist/core.js +7 -6
  93. package/dist/core.js.map +1 -0
  94. package/dist/destructible-3d.js +4 -3
  95. package/dist/destructible-3d.js.map +1 -0
  96. package/dist/destructible-prebake.js +2 -1
  97. package/dist/destructible-prebake.js.map +1 -0
  98. package/dist/first-person.js +7 -6
  99. package/dist/first-person.js.map +1 -0
  100. package/dist/index.js +39 -38
  101. package/dist/index.js.map +1 -0
  102. package/dist/jumper-2d.js +6 -5
  103. package/dist/jumper-2d.js.map +1 -0
  104. package/dist/jumper-3d.js +7 -6
  105. package/dist/jumper-3d.js.map +1 -0
  106. package/dist/particle-emitter/presets.js +2 -1
  107. package/dist/particle-emitter/presets.js.map +1 -0
  108. package/dist/particle-emitter.js +5 -4
  109. package/dist/particle-emitter.js.map +1 -0
  110. package/dist/platformer-3d.js +4 -3
  111. package/dist/platformer-3d.js.map +1 -0
  112. package/dist/ricochet-2d.js +5 -4
  113. package/dist/ricochet-2d.js.map +1 -0
  114. package/dist/ricochet-3d.js +5 -4
  115. package/dist/ricochet-3d.js.map +1 -0
  116. package/dist/runtime-2d.js +3 -2
  117. package/dist/runtime-2d.js.map +1 -0
  118. package/dist/runtime-pong.js +3 -2
  119. package/dist/runtime-pong.js.map +1 -0
  120. package/dist/screen-visibility.js +3 -2
  121. package/dist/screen-visibility.js.map +1 -0
  122. package/dist/screen-wrap.js +5 -4
  123. package/dist/screen-wrap.js.map +1 -0
  124. package/dist/shooter-2d.js +5 -4
  125. package/dist/shooter-2d.js.map +1 -0
  126. package/dist/thruster.js +6 -5
  127. package/dist/thruster.js.map +1 -0
  128. package/dist/top-down-movement.js +6 -5
  129. package/dist/top-down-movement.js.map +1 -0
  130. package/dist/world-boundary-2d.js +6 -5
  131. package/dist/world-boundary-2d.js.map +1 -0
  132. package/dist/world-boundary-3d.js +6 -5
  133. package/dist/world-boundary-3d.js.map +1 -0
  134. package/package.json +4 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zylem Game Toolkit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineBehavior
3
- } from "./chunk-YDLO5M7S.js";
3
+ } from "./chunk-EZNCCO4L.js";
4
4
 
5
5
  // src/lib/behaviors/runtime-pong/runtime-pong.descriptors.ts
6
6
  var runtimeNoopSystemFactory = () => ({
@@ -173,3 +173,4 @@ export {
173
173
  emitRuntimeGoal,
174
174
  bindRuntimePongBallHandle
175
175
  };
176
+ //# sourceMappingURL=chunk-2C3Z5GE7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/behaviors/runtime-pong/runtime-pong.descriptors.ts"],"sourcesContent":["import {\n\tdefineBehavior,\n\ttype BehaviorRef,\n} from '../behavior-descriptor';\nimport type { BehaviorSystem } from '../behavior-system';\n\nexport interface RuntimePongBallOptions {\n\tinitialVelocity: readonly [number, number];\n}\n\nexport interface RuntimePongBallHandle {\n\tsetRuntimePosition(x: number, y: number, z?: number): void;\n\tsetRuntimeVelocity(x: number, y: number): void;\n\tgetRuntimePosition(): { x: number; y: number; z: number } | null;\n}\n\nexport interface RuntimePaddleInput2DOptions {\n\tplayer: 'p1' | 'p2';\n\tspeed: number;\n}\n\nexport interface RuntimeWorldBoundary2DOptions {\n\tboundaries: {\n\t\tleft: number;\n\t\tright: number;\n\t\tbottom: number;\n\t\ttop: number;\n\t};\n}\n\nexport interface RuntimeRicochet2DOptions {\n\tminSpeed: number;\n\tmaxSpeed: number;\n\tspeedMultiplier: number;\n\treflectionMode: 'simple' | 'angled';\n\tmaxAngleDeg: number;\n}\n\nexport interface RuntimeRicochet2DEvent {\n\tkind: 'wall' | 'paddle';\n}\n\nexport interface RuntimeRicochet2DHandle {\n\tonRicochet(callback: (event: RuntimeRicochet2DEvent) => void): () => void;\n}\n\n/** Registers a gameplay2d trigger AABB (sensor); wasm reports overlap via {@link emitRuntimeTriggerRegionEnter}. */\nexport interface RuntimeTriggerRegion2DOptions {\n\ttriggerId: number;\n\thalfExtents: readonly [number, number];\n}\n\nexport interface RuntimeTriggerRegion2DEvent {\n\ttriggerId: number;\n}\n\nexport interface RuntimeTriggerRegion2DHandle {\n\tonRegionEnter(callback: (event: RuntimeTriggerRegion2DEvent) => void): () => void;\n}\n\nexport interface RuntimeGoalZone2DOptions {\n\tscorer: 'p1' | 'p2';\n}\n\nexport interface RuntimeGoalZone2DEvent {\n\tscorer: 'p1' | 'p2';\n}\n\nexport interface RuntimeGoalZone2DHandle {\n\tonGoal(callback: (event: RuntimeGoalZone2DEvent) => void): () => void;\n}\n\nconst runtimeNoopSystemFactory = (): BehaviorSystem => ({\n\tupdate(_ecs: unknown, _delta: number) {},\n});\n\nexport const RUNTIME_PONG_BALL_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-pong-ball');\nexport const RUNTIME_PADDLE_INPUT_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-paddle-input-2d');\nexport const RUNTIME_WORLD_BOUNDARY_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-world-boundary-2d');\nexport const RUNTIME_RICOCHET_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-ricochet-2d');\nexport const RUNTIME_TRIGGER_REGION_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-trigger-region-2d');\nexport const RUNTIME_GOAL_ZONE_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:runtime-goal-zone-2d');\n\nconst RICOCHET_LISTENERS = Symbol('runtime-ricochet-listeners');\nconst TRIGGER_REGION_LISTENERS = Symbol('runtime-trigger-region-listeners');\nconst GOAL_LISTENERS = Symbol('runtime-goal-listeners');\nconst RUNTIME_BALL_SET_POSITION = Symbol('runtime-ball-set-position');\nconst RUNTIME_BALL_SET_VELOCITY = Symbol('runtime-ball-set-velocity');\nconst RUNTIME_BALL_GET_POSITION = Symbol('runtime-ball-get-position');\n\nexport const RuntimePongBallBehavior = defineBehavior<\n\tRuntimePongBallOptions,\n\tRuntimePongBallHandle\n>({\n\tname: 'runtime-pong-ball',\n\tdefaultOptions: {\n\t\tinitialVelocity: [0, 0] as [number, number],\n\t},\n\tsystemFactory: runtimeNoopSystemFactory,\n\tcreateHandle: (ref: BehaviorRef<RuntimePongBallOptions>) => ({\n\t\tsetRuntimePosition(x: number, y: number, z: number = 0): void {\n\t\t\tconst callback = (ref as any)[RUNTIME_BALL_SET_POSITION] as\n\t\t\t\t| ((x: number, y: number, z: number) => void)\n\t\t\t\t| undefined;\n\t\t\tcallback?.(x, y, z);\n\t\t},\n\t\tsetRuntimeVelocity(x: number, y: number): void {\n\t\t\tconst callback = (ref as any)[RUNTIME_BALL_SET_VELOCITY] as\n\t\t\t\t| ((x: number, y: number) => void)\n\t\t\t\t| undefined;\n\t\t\tcallback?.(x, y);\n\t\t},\n\t\tgetRuntimePosition(): { x: number; y: number; z: number } | null {\n\t\t\tconst callback = (ref as any)[RUNTIME_BALL_GET_POSITION] as\n\t\t\t\t| (() => { x: number; y: number; z: number } | null)\n\t\t\t\t| undefined;\n\t\t\treturn callback?.() ?? null;\n\t\t},\n\t}),\n});\n\nexport const RuntimePaddleInput2DBehavior = defineBehavior<RuntimePaddleInput2DOptions>({\n\tname: 'runtime-paddle-input-2d',\n\tdefaultOptions: {\n\t\tplayer: 'p1',\n\t\tspeed: 5,\n\t} as RuntimePaddleInput2DOptions,\n\tsystemFactory: runtimeNoopSystemFactory,\n});\n\nexport const RuntimeWorldBoundary2DBehavior = defineBehavior({\n\tname: 'runtime-world-boundary-2d',\n\tdefaultOptions: {\n\t\tboundaries: {\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\tbottom: 0,\n\t\t\ttop: 0,\n\t\t},\n\t},\n\tsystemFactory: runtimeNoopSystemFactory,\n});\n\nexport const RuntimeRicochet2DBehavior = defineBehavior<\n\tRuntimeRicochet2DOptions,\n\tRuntimeRicochet2DHandle\n>({\n\tname: 'runtime-ricochet-2d',\n\tdefaultOptions: {\n\t\tminSpeed: 2,\n\t\tmaxSpeed: 20,\n\t\tspeedMultiplier: 1.05,\n\t\treflectionMode: 'angled' as const,\n\t\tmaxAngleDeg: 60,\n\t},\n\tsystemFactory: runtimeNoopSystemFactory,\n\tcreateHandle: (ref: BehaviorRef<RuntimeRicochet2DOptions>) => ({\n\t\tonRicochet(callback: (event: RuntimeRicochet2DEvent) => void): () => void {\n\t\t\tconst listeners =\n\t\t\t\t((ref as any)[RICOCHET_LISTENERS] as Array<(event: RuntimeRicochet2DEvent) => void> | undefined)\n\t\t\t\t?? [];\n\t\t\tif (!(ref as any)[RICOCHET_LISTENERS]) {\n\t\t\t\t(ref as any)[RICOCHET_LISTENERS] = listeners;\n\t\t\t}\n\t\t\tlisteners.push(callback);\n\t\t\treturn () => {\n\t\t\t\tconst index = listeners.indexOf(callback);\n\t\t\t\tif (index >= 0) {\n\t\t\t\t\tlisteners.splice(index, 1);\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t}),\n});\n\nexport const RuntimeTriggerRegion2DBehavior = defineBehavior<\n\tRuntimeTriggerRegion2DOptions,\n\tRuntimeTriggerRegion2DHandle\n>({\n\tname: 'runtime-trigger-region-2d',\n\tdefaultOptions: {\n\t\ttriggerId: 0,\n\t\thalfExtents: [0.5, 2.5] as [number, number],\n\t},\n\tsystemFactory: runtimeNoopSystemFactory,\n\tcreateHandle: (ref: BehaviorRef<RuntimeTriggerRegion2DOptions>) => ({\n\t\tonRegionEnter(callback: (event: RuntimeTriggerRegion2DEvent) => void): () => void {\n\t\t\tconst listeners =\n\t\t\t\t((ref as any)[TRIGGER_REGION_LISTENERS] as\n\t\t\t\t\t| Array<(event: RuntimeTriggerRegion2DEvent) => void>\n\t\t\t\t\t| undefined) ?? [];\n\t\t\tif (!(ref as any)[TRIGGER_REGION_LISTENERS]) {\n\t\t\t\t(ref as any)[TRIGGER_REGION_LISTENERS] = listeners;\n\t\t\t}\n\t\t\tlisteners.push(callback);\n\t\t\treturn () => {\n\t\t\t\tconst index = listeners.indexOf(callback);\n\t\t\t\tif (index >= 0) {\n\t\t\t\t\tlisteners.splice(index, 1);\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t}),\n});\n\nexport const RuntimeGoalZone2DBehavior = defineBehavior<\n\tRuntimeGoalZone2DOptions,\n\tRuntimeGoalZone2DHandle\n>({\n\tname: 'runtime-goal-zone-2d',\n\tdefaultOptions: {\n\t\tscorer: 'p1',\n\t} as RuntimeGoalZone2DOptions,\n\tsystemFactory: runtimeNoopSystemFactory,\n\tcreateHandle: (ref: BehaviorRef<RuntimeGoalZone2DOptions>) => ({\n\t\tonGoal(callback: (event: RuntimeGoalZone2DEvent) => void): () => void {\n\t\t\tconst listeners =\n\t\t\t\t((ref as any)[GOAL_LISTENERS] as Array<(event: RuntimeGoalZone2DEvent) => void> | undefined)\n\t\t\t\t?? [];\n\t\t\tif (!(ref as any)[GOAL_LISTENERS]) {\n\t\t\t\t(ref as any)[GOAL_LISTENERS] = listeners;\n\t\t\t}\n\t\t\tlisteners.push(callback);\n\t\t\treturn () => {\n\t\t\t\tconst index = listeners.indexOf(callback);\n\t\t\t\tif (index >= 0) {\n\t\t\t\t\tlisteners.splice(index, 1);\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t}),\n});\n\nexport function emitRuntimeRicochet(\n\tref: BehaviorRef<RuntimeRicochet2DOptions>,\n\tevent: RuntimeRicochet2DEvent,\n): void {\n\tconst listeners = (ref as any)[RICOCHET_LISTENERS] as\n\t\t| Array<(event: RuntimeRicochet2DEvent) => void>\n\t\t| undefined;\n\tfor (const listener of listeners ?? []) {\n\t\tlistener(event);\n\t}\n}\n\nexport function emitRuntimeTriggerRegionEnter(\n\tref: BehaviorRef<RuntimeTriggerRegion2DOptions>,\n\tevent: RuntimeTriggerRegion2DEvent,\n): void {\n\tconst listeners = (ref as any)[TRIGGER_REGION_LISTENERS] as\n\t\t| Array<(event: RuntimeTriggerRegion2DEvent) => void>\n\t\t| undefined;\n\tfor (const listener of listeners ?? []) {\n\t\tlistener(event);\n\t}\n}\n\nexport function emitRuntimeGoal(\n\tref: BehaviorRef<RuntimeGoalZone2DOptions>,\n\tevent: RuntimeGoalZone2DEvent,\n): void {\n\tconst listeners = (ref as any)[GOAL_LISTENERS] as\n\t\t| Array<(event: RuntimeGoalZone2DEvent) => void>\n\t\t| undefined;\n\tfor (const listener of listeners ?? []) {\n\t\tlistener(event);\n\t}\n}\n\nexport function bindRuntimePongBallHandle(\n\tref: BehaviorRef<RuntimePongBallOptions>,\n\tcontrols: {\n\t\tsetPosition: (x: number, y: number, z: number) => void;\n\t\tsetVelocity: (x: number, y: number) => void;\n\t\tgetPosition: () => { x: number; y: number; z: number } | null;\n\t},\n): void {\n\t(ref as any)[RUNTIME_BALL_SET_POSITION] = controls.setPosition;\n\t(ref as any)[RUNTIME_BALL_SET_VELOCITY] = controls.setVelocity;\n\t(ref as any)[RUNTIME_BALL_GET_POSITION] = controls.getPosition;\n}\n"],"mappings":"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","names":[]}
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  createThrusterInputComponent,
3
3
  createThrusterMovementComponent
4
- } from "./chunk-2HLZBWGD.js";
4
+ } from "./chunk-KS72RZHX.js";
5
5
  import {
6
6
  getRotationAngle2D,
7
7
  normalizeDirection2D
8
- } from "./chunk-7U4WFBWM.js";
8
+ } from "./chunk-ID5QJYF5.js";
9
9
  import {
10
10
  SyncStateMachine,
11
11
  t
12
- } from "./chunk-RER2IDPW.js";
12
+ } from "./chunk-4URF65BR.js";
13
13
  import {
14
14
  defineBehavior
15
- } from "./chunk-YDLO5M7S.js";
15
+ } from "./chunk-EZNCCO4L.js";
16
16
 
17
17
  // src/lib/behaviors/thruster/thruster-fsm.ts
18
18
  var ThrusterState = /* @__PURE__ */ ((ThrusterState2) => {
@@ -238,3 +238,4 @@ export {
238
238
  ThrusterMovementBehavior,
239
239
  ThrusterBehavior
240
240
  };
241
+ //# sourceMappingURL=chunk-2CLT36VB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/behaviors/thruster/thruster-fsm.ts","../src/lib/behaviors/thruster/thruster-movement.behavior.ts","../src/lib/behaviors/thruster/thruster.descriptor.ts"],"sourcesContent":["/**\n * ThrusterFSM\n * \n * State machine controller for thruster behavior.\n * FSM does NOT touch physics or ThrusterMovementBehavior - it only writes ThrusterInputComponent.\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { ThrusterInputComponent } from './components';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM State Model\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterState {\n\tIdle = 'idle',\n\tActive = 'active',\n\tBoosting = 'boosting',\n\tDisabled = 'disabled',\n\tDocked = 'docked',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterEvent {\n\tActivate = 'activate',\n\tDeactivate = 'deactivate',\n\tBoost = 'boost',\n\tEndBoost = 'endBoost',\n\tDisable = 'disable',\n\tEnable = 'enable',\n\tDock = 'dock',\n\tUndock = 'undock',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Context Object\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterFSMContext {\n\tinput: ThrusterInputComponent;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Player Input (raw input from controller/keyboard)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlayerInput {\n\tthrust: number;\n\trotate: number;\n\tthrustX?: number;\n\tthrustY?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterFSM Controller\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThrusterFSM {\n\tmachine: SyncStateMachine<ThrusterState, ThrusterEvent, never>;\n\n\tconstructor(private ctx: ThrusterFSMContext) {\n\t\tthis.machine = new SyncStateMachine<ThrusterState, ThrusterEvent, never>(\n\t\t\tThrusterState.Idle,\n\t\t\t[\n\t\t\t\t// Core transitions\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Boost, ThrusterState.Boosting),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Dock, ThrusterState.Docked),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.EndBoost, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Disabled, ThrusterEvent.Enable, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Docked, ThrusterEvent.Undock, ThrusterState.Idle),\n\t\t\t\t// Self-transitions (no-ops for redundant events)\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState(): ThrusterState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Dispatch an event to transition state\n\t */\n\tdispatch(event: ThrusterEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/**\n\t * Update FSM state based on player input.\n\t * Auto-transitions between Idle/Active to report current state.\n\t * Does NOT modify input - just observes and reports.\n\t */\n\tupdate(playerInput: PlayerInput): void {\n\t\tconst state = this.machine.getState();\n\t\tconst hasInput =\n\t\t\tMath.abs(playerInput.thrust) > 0.01\n\t\t\t|| Math.abs(playerInput.rotate) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustX ?? 0) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustY ?? 0) > 0.01;\n\n\t\t// Auto-transition to report state based on input\n\t\tif (hasInput && state === ThrusterState.Idle) {\n\t\t\tthis.dispatch(ThrusterEvent.Activate);\n\t\t} else if (!hasInput && state === ThrusterState.Active) {\n\t\t\tthis.dispatch(ThrusterEvent.Deactivate);\n\t\t}\n\t}\n}\n","/**\n * ThrusterMovementBehavior\n * \n * This is the heart of the thruster movement system - a pure, stateless force generator.\n * Works identically for player, AI, and replay.\n */\n\nimport type { ZylemWorld } from '../../collision/world';\nimport type { PhysicsBodyComponent } from '../components';\nimport type { ThrusterMovementComponent, ThrusterInputComponent } from './components';\nimport {\n\tgetRotationAngle2D,\n\tnormalizeDirection2D,\n} from '../shared/direction-2d';\n\n/**\n * Zylem-style Behavior interface\n */\nexport interface Behavior {\n\tupdate(dt: number): void;\n}\n\n/**\n * Entity with thruster components\n */\nexport interface ThrusterEntity {\n\tphysics: PhysicsBodyComponent;\n\tthruster: ThrusterMovementComponent;\n\t$thruster: ThrusterInputComponent;\n}\n\n/**\n * ThrusterMovementBehavior - Force generator for thruster-equipped entities\n * \n * Responsibilities:\n * - Query entities with PhysicsBody, ThrusterMovement, and ThrusterInput components\n * - Apply velocities based on thrust input (2D mode)\n * - Apply angular velocity based on rotation input\n */\nexport class ThrusterMovementBehavior implements Behavior {\n\tconstructor(private world: ZylemWorld) {}\n\n\t/**\n\t * Update a single thruster-enabled entity.\n\t */\n\tupdateEntity(gameEntity: any, _dt: number): void {\n\t\tif (!gameEntity.physics?.body || !gameEntity.thruster || !gameEntity.$thruster) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst e: ThrusterEntity = {\n\t\t\tphysics: gameEntity.physics,\n\t\t\tthruster: gameEntity.thruster,\n\t\t\t$thruster: gameEntity.$thruster,\n\t\t};\n\n\t\tconst body = e.physics.body;\n\t\tconst thruster = e.thruster;\n\t\tconst input = e.$thruster;\n\n\t\tif (thruster.linearDamping != null && typeof body.setLinearDamping === 'function') {\n\t\t\tbody.setLinearDamping(thruster.linearDamping);\n\t\t}\n\n\t\t// Get Z rotation from quaternion (for 2D sprites)\n\t\tconst rotationZ = getRotationAngle2D(body.rotation());\n\t\tconst currentVel = body.linvel();\n\t\tconst vectorThrust = normalizeDirection2D(input.thrustX, input.thrustY);\n\n\t\t// --- Linear thrust ---\n\t\tif (vectorThrust) {\n\t\t\tconst thrustScale = Math.min(1, Math.hypot(input.thrustX, input.thrustY));\n\t\t\tconst thrustAmount = thruster.linearThrust * thrustScale * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + vectorThrust.x * thrustAmount,\n\t\t\t\ty: currentVel.y + vectorThrust.y * thrustAmount,\n\t\t\t\tz: currentVel.z,\n\t\t\t}, true);\n\t\t} else if (input.thrust !== 0) {\n\t\t\tconst forwardX = Math.sin(-rotationZ);\n\t\t\tconst forwardY = Math.cos(-rotationZ);\n\t\t\tconst thrustAmount = thruster.linearThrust * input.thrust * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + forwardX * thrustAmount,\n\t\t\t\ty: currentVel.y + forwardY * thrustAmount,\n\t\t\t\tz: currentVel.z\n\t\t\t}, true);\n\t\t}\n\n\t\t// --- Angular thrust (Z-axis for 2D) ---\n\t\tif (input.rotate !== 0) {\n\t\t\tbody.setAngvel({ x: 0, y: 0, z: -thruster.angularThrust * input.rotate }, true);\n\t\t} else {\n\t\t\t// Stop rotation when no input\n\t\t\tconst angVel = body.angvel();\n\t\t\tbody.setAngvel({ x: angVel.x, y: angVel.y, z: 0 }, true);\n\t\t}\n\t}\n\n\tupdate(dt: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tthis.updateEntity(entity, dt);\n\t\t}\n\t}\n}\n","/**\n * Thruster Behavior Descriptor\n * \n * Type-safe descriptor for the thruster behavior system using the new entity.use() API.\n * This wraps the existing ThrusterMovementBehavior and components.\n */\n\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ThrusterMovementBehavior, ThrusterEntity } from './thruster-movement.behavior';\nimport { ThrusterFSM } from './thruster-fsm';\nimport {\n\tcreateThrusterInputComponent,\n\tcreateThrusterMovementComponent,\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n} from './components';\nimport type { WasmStageRuntime } from '../../runtime/wasm-stage-runtime';\n\n/**\n * Thruster behavior options (typed for entity.use() autocomplete)\n */\nexport interface ThrusterBehaviorOptions {\n\t/** Forward thrust force (default: 10) */\n\tlinearThrust: number;\n\t/** Rotation torque (default: 5) */\n\tangularThrust: number;\n\t/** Optional linear damping override */\n\tlinearDamping?: number;\n}\n\nconst defaultOptions: ThrusterBehaviorOptions = {\n\tlinearThrust: 10,\n\tangularThrust: 5,\n\tlinearDamping: undefined,\n};\n\nconst THRUSTER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:thruster');\n\n/**\n * Adapter that wraps ThrusterMovementBehavior as a BehaviorSystem.\n * \n * This bridges the entity.use() pattern with the ECS component-based approach:\n * - Reads options from entity behaviorRefs\n * - Initializes ThrusterMovementComponent and ThrusterInputComponent on entities\n * - Creates FSM lazily and attaches to BehaviorRef for access via handle.getFSM()\n * - Delegates physics to ThrusterMovementBehavior\n * \n * NOTE: Input is controlled by the user via entity.onUpdate() - set entity.input.thrust/rotate\n */\nclass ThrusterBehaviorSystem implements BehaviorSystem {\n\tprivate movementBehavior: ThrusterMovementBehavior;\n\tprivate attachedRuntimeSlots = new Set<number>();\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate wasmStage: WasmStageRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.movementBehavior = new ThrusterMovementBehavior(world);\n\t}\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(THRUSTER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst thrusterRef = link.ref as any;\n\n\t\t\tconst options = thrusterRef.options as ThrusterBehaviorOptions;\n\n\t\t\tif (!gameEntity.thruster) {\n\t\t\t\tgameEntity.thruster = createThrusterMovementComponent(\n\t\t\t\t\toptions.linearThrust,\n\t\t\t\t\toptions.angularThrust,\n\t\t\t\t\t{ linearDamping: options.linearDamping },\n\t\t\t\t) as ThrusterMovementComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.$thruster) {\n\t\t\t\tgameEntity.$thruster = createThrusterInputComponent() as ThrusterInputComponent;\n\t\t\t}\n\n\t\t\tif (!thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm = new ThrusterFSM({ input: gameEntity.$thruster });\n\t\t\t}\n\n\t\t\tif (thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm.update({\n\t\t\t\t\tthrust: gameEntity.$thruster.thrust,\n\t\t\t\t\trotate: gameEntity.$thruster.rotate,\n\t\t\t\t\tthrustX: gameEntity.$thruster.thrustX,\n\t\t\t\t\tthrustY: gameEntity.$thruster.thrustY,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst handle = (gameEntity.runtimeHandle ?? -1) as number;\n\t\t\tif (this.wasmStage && handle >= 0) {\n\t\t\t\tthis.ensureWasmAttached(handle, options);\n\t\t\t\tconst input = gameEntity.$thruster as ThrusterInputComponent | undefined;\n\t\t\t\tif (input) {\n\t\t\t\t\tthis.wasmStage.setThrusterInput(handle, input.thrust, input.rotate);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!gameEntity.body) continue;\n\t\t\tif (!gameEntity.physics) {\n\t\t\t\tgameEntity.physics = { body: gameEntity.body };\n\t\t\t}\n\t\t\tthis.movementBehavior.updateEntity(gameEntity, delta);\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: ThrusterBehaviorOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tthis.wasmStage.attachThruster(handle, {\n\t\t\tmaxSpeed: 50,\n\t\t\tacceleration: options.linearThrust,\n\t\t\tturnRateRadPerSec: options.angularThrust,\n\t\t\tlinearDamping: options.linearDamping ?? 0,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\n/**\n * ThrusterBehavior - typed descriptor for thruster movement.\n * \n * Uses the existing ThrusterMovementBehavior under the hood.\n * \n * @example\n * ```typescript\n * import { ThrusterBehavior } from \"@zylem/game-lib/behavior\";\n * \n * const ship = createSprite({ ... });\n * ship.use(ThrusterBehavior, { linearThrust: 15, angularThrust: 8 });\n * ```\n */\nexport const ThrusterBehavior = defineBehavior<ThrusterBehaviorOptions, Record<string, never>, ThrusterEntity>({\n\tname: 'thruster',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ThrusterBehaviorSystem(ctx.world, ctx.wasmStage ?? null, ctx.getBehaviorLinks),\n});\n"],"mappings":"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","names":["ThrusterState","ThrusterEvent"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getBounds3DNormalFromHits
3
- } from "./chunk-WHKPWIQO.js";
3
+ } from "./chunk-OHCPV2NT.js";
4
4
 
5
5
  // src/lib/coordinators/boundary-ricochet-3d.coordinator.ts
6
6
  var BoundaryRicochet3DCoordinator = class {
@@ -32,3 +32,4 @@ var BoundaryRicochet3DCoordinator = class {
32
32
  export {
33
33
  BoundaryRicochet3DCoordinator
34
34
  };
35
+ //# sourceMappingURL=chunk-3PYGRHAL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/coordinators/boundary-ricochet-3d.coordinator.ts"],"sourcesContent":["import { GameEntity } from '../entities/entity';\nimport type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { Ricochet3DHandle } from '../behaviors/ricochet-3d/ricochet-3d.descriptor';\nimport type { WorldBoundary3DHandle } from '../behaviors/world-boundary-3d/world-boundary-3d.descriptor';\nimport { getBounds3DNormalFromHits } from '../behaviors/shared/bounds-3d';\n\nexport class BoundaryRicochet3DCoordinator {\n\tconstructor(\n\t\tprivate entity: GameEntity<any> & MoveableEntity,\n\t\tprivate boundary: WorldBoundary3DHandle,\n\t\tprivate ricochet: Ricochet3DHandle,\n\t) {}\n\n\tpublic update(): boolean {\n\t\tconst hits = this.boundary.getLastHits();\n\t\tif (!hits) return false;\n\n\t\tconst anyHit =\n\t\t\thits.left || hits.right || hits.top || hits.bottom || hits.back || hits.front;\n\t\tif (!anyHit) return false;\n\n\t\tconst clamped = this.boundary.getLastClampedPosition();\n\t\tif (clamped && this.entity.body) {\n\t\t\tthis.entity.body.setTranslation(clamped, true);\n\t\t}\n\n\t\tconst normal = getBounds3DNormalFromHits(hits);\n\t\treturn this.ricochet.applyRicochet({\n\t\t\tentity: this.entity,\n\t\t\tcontact: { normal },\n\t\t});\n\t}\n}\n"],"mappings":";;;;;AAMO,IAAM,gCAAN,MAAoC;AAAA,EAC1C,YACS,QACA,UACA,UACP;AAHO;AACA;AACA;AAAA,EACN;AAAA,EAHM;AAAA,EACA;AAAA,EACA;AAAA,EAGF,SAAkB;AACxB,UAAM,OAAO,KAAK,SAAS,YAAY;AACvC,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,SACL,KAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,KAAK,UAAU,KAAK,QAAQ,KAAK;AACzE,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,KAAK,SAAS,uBAAuB;AACrD,QAAI,WAAW,KAAK,OAAO,MAAM;AAChC,WAAK,OAAO,KAAK,eAAe,SAAS,IAAI;AAAA,IAC9C;AAEA,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,KAAK,SAAS,cAAc;AAAA,MAClC,QAAQ,KAAK;AAAA,MACb,SAAS,EAAE,OAAO;AAAA,IACnB,CAAC;AAAA,EACF;AACD;","names":[]}
@@ -4,17 +4,17 @@ import {
4
4
  constrainMovementToBounds3D,
5
5
  hasAnyBounds3DHit,
6
6
  insetBounds3D
7
- } from "./chunk-WHKPWIQO.js";
7
+ } from "./chunk-OHCPV2NT.js";
8
8
  import {
9
9
  StageBoundaryDim
10
- } from "./chunk-YYJP62QD.js";
10
+ } from "./chunk-Y6UJOUE5.js";
11
11
  import {
12
12
  SyncStateMachine,
13
13
  t
14
- } from "./chunk-RER2IDPW.js";
14
+ } from "./chunk-4URF65BR.js";
15
15
  import {
16
16
  defineBehavior
17
- } from "./chunk-YDLO5M7S.js";
17
+ } from "./chunk-EZNCCO4L.js";
18
18
 
19
19
  // src/lib/behaviors/world-boundary-3d/world-boundary-3d-fsm.ts
20
20
  var WorldBoundary3DState = /* @__PURE__ */ ((WorldBoundary3DState2) => {
@@ -209,3 +209,4 @@ export {
209
209
  WorldBoundary3DFSM,
210
210
  WorldBoundary3DBehavior
211
211
  };
212
+ //# sourceMappingURL=chunk-4I6E6DGV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/behaviors/world-boundary-3d/world-boundary-3d-fsm.ts","../src/lib/behaviors/world-boundary-3d/world-boundary-3d.descriptor.ts"],"sourcesContent":["import { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport {\n\tclampPointToBounds3D,\n\tcomputeBounds3DHits,\n\tconstrainMovementToBounds3D,\n\thasAnyBounds3DHit,\n\tinsetBounds3D,\n\ttype Bounds3DPaddingInput,\n\ttype Bounds3DPoint,\n} from '../shared/bounds-3d';\n\nexport type WorldBoundary3DHit =\n\t| 'top'\n\t| 'bottom'\n\t| 'left'\n\t| 'right'\n\t| 'back'\n\t| 'front';\n\nexport type WorldBoundary3DHits = Record<WorldBoundary3DHit, boolean>;\n\nexport interface WorldBoundary3DPosition extends Bounds3DPoint {}\n\nexport interface WorldBoundary3DBounds {\n\ttop: number;\n\tbottom: number;\n\tleft: number;\n\tright: number;\n\tback: number;\n\tfront: number;\n}\n\nexport enum WorldBoundary3DState {\n\tInside = 'inside',\n\tTouching = 'touching',\n}\n\nexport enum WorldBoundary3DEvent {\n\tEnterInside = 'enter-inside',\n\tTouchBoundary = 'touch-boundary',\n}\n\nexport function computeWorldBoundary3DHits(\n\tposition: WorldBoundary3DPosition,\n\tbounds: WorldBoundary3DBounds,\n\tpadding?: Bounds3DPaddingInput,\n): WorldBoundary3DHits {\n\treturn computeBounds3DHits(position, insetBounds3D({\n\t\tminX: bounds.left,\n\t\tmaxX: bounds.right,\n\t\tminY: bounds.bottom,\n\t\tmaxY: bounds.top,\n\t\tminZ: bounds.back,\n\t\tmaxZ: bounds.front,\n\t}, padding));\n}\n\nexport function hasAnyWorldBoundary3DHit(hits: WorldBoundary3DHits): boolean {\n\treturn hasAnyBounds3DHit(hits);\n}\n\nexport class WorldBoundary3DFSM {\n\tpublic readonly machine: SyncStateMachine<WorldBoundary3DState, WorldBoundary3DEvent, never>;\n\n\tprivate lastHits: WorldBoundary3DHits = {\n\t\ttop: false,\n\t\tbottom: false,\n\t\tleft: false,\n\t\tright: false,\n\t\tback: false,\n\t\tfront: false,\n\t};\n\tprivate lastPosition: WorldBoundary3DPosition | null = null;\n\tprivate lastClampedPosition: WorldBoundary3DPosition | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<WorldBoundary3DState, WorldBoundary3DEvent, never>(\n\t\t\tWorldBoundary3DState.Inside,\n\t\t\t[\n\t\t\t\tt(WorldBoundary3DState.Inside, WorldBoundary3DEvent.TouchBoundary, WorldBoundary3DState.Touching),\n\t\t\t\tt(WorldBoundary3DState.Touching, WorldBoundary3DEvent.EnterInside, WorldBoundary3DState.Inside),\n\t\t\t\tt(WorldBoundary3DState.Inside, WorldBoundary3DEvent.EnterInside, WorldBoundary3DState.Inside),\n\t\t\t\tt(WorldBoundary3DState.Touching, WorldBoundary3DEvent.TouchBoundary, WorldBoundary3DState.Touching),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): WorldBoundary3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tgetLastHits(): WorldBoundary3DHits {\n\t\treturn this.lastHits;\n\t}\n\n\tgetMovement(\n\t\tmoveX: number,\n\t\tmoveY: number,\n\t\tmoveZ: number,\n\t): { moveX: number; moveY: number; moveZ: number } {\n\t\treturn constrainMovementToBounds3D(this.lastHits, moveX, moveY, moveZ);\n\t}\n\n\tgetLastPosition(): WorldBoundary3DPosition | null {\n\t\treturn this.lastPosition;\n\t}\n\n\tgetLastClampedPosition(): WorldBoundary3DPosition | null {\n\t\treturn this.lastClampedPosition;\n\t}\n\n\tgetLastUpdatedAtMs(): number | null {\n\t\treturn this.lastUpdatedAtMs;\n\t}\n\n\tupdate(\n\t\tposition: WorldBoundary3DPosition,\n\t\tbounds: WorldBoundary3DBounds,\n\t\tpadding?: Bounds3DPaddingInput,\n\t): WorldBoundary3DHits {\n\t\tconst effectiveBounds = insetBounds3D({\n\t\t\tminX: bounds.left,\n\t\t\tmaxX: bounds.right,\n\t\t\tminY: bounds.bottom,\n\t\t\tmaxY: bounds.top,\n\t\t\tminZ: bounds.back,\n\t\t\tmaxZ: bounds.front,\n\t\t}, padding);\n\n\t\tconst hits = computeBounds3DHits(position, effectiveBounds);\n\t\tthis.lastHits = hits;\n\t\tthis.lastPosition = { x: position.x, y: position.y, z: position.z };\n\t\tthis.lastClampedPosition = clampPointToBounds3D(position, effectiveBounds);\n\t\tthis.lastUpdatedAtMs = Date.now();\n\n\t\tif (hasAnyWorldBoundary3DHit(hits)) {\n\t\t\tthis.dispatch(WorldBoundary3DEvent.TouchBoundary);\n\t\t} else {\n\t\t\tthis.dispatch(WorldBoundary3DEvent.EnterInside);\n\t\t}\n\n\t\treturn hits;\n\t}\n\n\tprivate dispatch(event: WorldBoundary3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n}\n","import { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport type { Bounds3DPaddingInput } from '../shared/bounds-3d';\nimport {\n\tWorldBoundary3DFSM,\n\ttype WorldBoundary3DBounds,\n\ttype WorldBoundary3DHits,\n\ttype WorldBoundary3DPosition,\n} from './world-boundary-3d-fsm';\nimport {\n\tStageBoundaryDim,\n\ttype WasmStageRuntime,\n} from '../../runtime/wasm-stage-runtime';\n\nexport interface WorldBoundary3DOptions {\n\tboundaries: WorldBoundary3DBounds;\n\tpadding?: Bounds3DPaddingInput;\n}\n\nexport interface WorldBoundary3DHandle {\n\tgetLastHits(): WorldBoundary3DHits | null;\n\tgetMovement(\n\t\tmoveX: number,\n\t\tmoveY: number,\n\t\tmoveZ: number,\n\t): { moveX: number; moveY: number; moveZ: number };\n\tgetLastClampedPosition(): WorldBoundary3DPosition | null;\n}\n\nconst defaultOptions: WorldBoundary3DOptions = {\n\tboundaries: { top: 0, bottom: 0, left: 0, right: 0, back: 0, front: 0 },\n\tpadding: 0,\n};\n\nconst WORLD_BOUNDARY_3D_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:world-boundary-3d',\n);\n\nfunction createWorldBoundary3DHandle(\n\tref: BehaviorRef<WorldBoundary3DOptions>,\n): WorldBoundary3DHandle {\n\treturn {\n\t\tgetLastHits: () => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getLastHits() ?? null;\n\t\t},\n\t\tgetMovement: (moveX: number, moveY: number, moveZ: number) => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getMovement(moveX, moveY, moveZ) ?? { moveX, moveY, moveZ };\n\t\t},\n\t\tgetLastClampedPosition: () => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getLastClampedPosition() ?? null;\n\t\t},\n\t};\n}\n\nclass WorldBoundary3DSystem implements BehaviorSystem {\n\tprivate attachedRuntimeSlots = new Set<number>();\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate wasmStage: WasmStageRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: unknown, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(WORLD_BOUNDARY_3D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst boundaryRef = link.ref as any;\n\t\t\tconst options = boundaryRef.options as WorldBoundary3DOptions;\n\t\t\tif (!boundaryRef.fsm) {\n\t\t\t\tboundaryRef.fsm = new WorldBoundary3DFSM();\n\t\t\t}\n\n\t\t\tconst handle = (gameEntity.runtimeHandle ?? -1) as number;\n\t\t\tif (this.wasmStage && handle >= 0) {\n\t\t\t\tthis.ensureWasmAttached(handle, options);\n\t\t\t\tconst query = this.wasmStage.queryWorldBoundary(handle);\n\t\t\t\tif (query) {\n\t\t\t\t\tboundaryRef.fsm.update(\n\t\t\t\t\t\t{ x: query.clamped[0], y: query.clamped[1], z: query.clamped[2] },\n\t\t\t\t\t\toptions.boundaries,\n\t\t\t\t\t\toptions.padding,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!gameEntity.body) continue;\n\t\t\tconst pos = gameEntity.body.translation();\n\t\t\tboundaryRef.fsm.update(\n\t\t\t\t{ x: pos.x, y: pos.y, z: pos.z },\n\t\t\t\toptions.boundaries,\n\t\t\t\toptions.padding,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: WorldBoundary3DOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tconst padding = typeof options.padding === 'number' ? options.padding : 0;\n\t\tthis.wasmStage.attachWorldBoundary(handle, StageBoundaryDim.Three, {\n\t\t\ttop: options.boundaries.top,\n\t\t\tbottom: options.boundaries.bottom,\n\t\t\tleft: options.boundaries.left,\n\t\t\tright: options.boundaries.right,\n\t\t\tfront: options.boundaries.front,\n\t\t\tback: options.boundaries.back,\n\t\t\tpadding,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\nexport const WorldBoundary3DBehavior = defineBehavior({\n\tname: 'world-boundary-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew WorldBoundary3DSystem(ctx.world, ctx.wasmStage ?? null, ctx.getBehaviorLinks),\n\tcreateHandle: createWorldBoundary3DHandle,\n});\n"],"mappings":"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","names":["WorldBoundary3DState","WorldBoundary3DEvent"]}
@@ -41,3 +41,4 @@ export {
41
41
  SyncStateMachine,
42
42
  t
43
43
  };
44
+ //# sourceMappingURL=chunk-4URF65BR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/core/utility/sync-state-machine.ts"],"sourcesContent":["import {\n\tStateMachine as BaseStateMachine,\n\ttype ILogger,\n\ttype ITransition,\n\ttype SyncCallback,\n} from 'typescript-fsm';\n\nexport { t } from 'typescript-fsm';\nexport type { ILogger, ITransition, SyncCallback };\n\n/**\n * Local wrapper around typescript-fsm's SyncStateMachine.\n *\n * typescript-fsm@1.6.0 incorrectly reports callback-less transitions as\n * unhandled even after moving to the next state, which causes noisy\n * `No transition...` console errors for valid FSM dispatches.\n */\nexport class SyncStateMachine<\n\tSTATE extends string | number | symbol,\n\tEVENT extends string | number | symbol,\n\tCALLBACK extends Record<EVENT, SyncCallback> = Record<EVENT, SyncCallback>,\n> extends BaseStateMachine<STATE, EVENT, CALLBACK> {\n\tconstructor(\n\t\tinit: STATE,\n\t\ttransitions: ITransition<STATE, EVENT, CALLBACK[EVENT]>[] = [],\n\t\tlogger: ILogger = console,\n\t) {\n\t\tsuper(init, transitions, logger);\n\t}\n\n\tdispatch<E extends EVENT>(_event: E, ..._args: unknown[]): Promise<void> {\n\t\tthrow new Error('SyncStateMachine does not support async dispatch.');\n\t}\n\n\tsyncDispatch<E extends EVENT>(event: E, ...args: unknown[]): boolean {\n\t\tconst found = this.transitions.some((transition) => {\n\t\t\tif (transition.fromState !== this._current || transition.event !== event) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst current = this._current;\n\t\t\tthis._current = transition.toState;\n\n\t\t\tif (!transition.cb) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\ttransition.cb(...args);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tthis._current = current;\n\t\t\t\tthis.logger.error('Exception in callback', error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tif (!found) {\n\t\t\tconst errorMessage = this.formatErr(this._current, event);\n\t\t\tthis.logger.error(errorMessage);\n\t\t}\n\n\t\treturn found;\n\t}\n}\n"],"mappings":";AAAA;AAAA,EACC,gBAAgB;AAAA,OAIV;AAEP,SAAS,SAAS;AAUX,IAAM,mBAAN,cAIG,iBAAyC;AAAA,EAClD,YACC,MACA,cAA4D,CAAC,GAC7D,SAAkB,SACjB;AACD,UAAM,MAAM,aAAa,MAAM;AAAA,EAChC;AAAA,EAEA,SAA0B,WAAc,OAAiC;AACxE,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACpE;AAAA,EAEA,aAA8B,UAAa,MAA0B;AACpE,UAAM,QAAQ,KAAK,YAAY,KAAK,CAAC,eAAe;AACnD,UAAI,WAAW,cAAc,KAAK,YAAY,WAAW,UAAU,OAAO;AACzE,eAAO;AAAA,MACR;AAEA,YAAM,UAAU,KAAK;AACrB,WAAK,WAAW,WAAW;AAE3B,UAAI,CAAC,WAAW,IAAI;AACnB,eAAO;AAAA,MACR;AAEA,UAAI;AACH,mBAAW,GAAG,GAAG,IAAI;AACrB,eAAO;AAAA,MACR,SAAS,OAAO;AACf,aAAK,WAAW;AAChB,aAAK,OAAO,MAAM,yBAAyB,KAAK;AAChD,cAAM;AAAA,MACP;AAAA,IACD,CAAC;AAED,QAAI,CAAC,OAAO;AACX,YAAM,eAAe,KAAK,UAAU,KAAK,UAAU,KAAK;AACxD,WAAK,OAAO,MAAM,YAAY;AAAA,IAC/B;AAEA,WAAO;AAAA,EACR;AACD;","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  directionFromAngle2D,
4
4
  getRotationAngle2D,
5
5
  normalizeDirection2D
6
- } from "./chunk-7U4WFBWM.js";
6
+ } from "./chunk-ID5QJYF5.js";
7
7
 
8
8
  // src/lib/coordinators/shared/top-down-aim.ts
9
9
  function getEntityFacingAngle2D(entity) {
@@ -35,3 +35,4 @@ export {
35
35
  getEntityFacingAngle2D,
36
36
  resolveAim2D
37
37
  };
38
+ //# sourceMappingURL=chunk-6C6NXNEW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/coordinators/shared/top-down-aim.ts"],"sourcesContent":["import {\n\tangleFromDirection2D,\n\tdirectionFromAngle2D,\n\tgetRotationAngle2D,\n\tnormalizeDirection2D,\n} from '../../behaviors/shared/direction-2d';\n\nexport interface ResolvedAim2D {\n\tangle: number;\n\tdirection: { x: number; y: number };\n\thasAimInput: boolean;\n}\n\nexport function getEntityFacingAngle2D(entity: any): number {\n\tif (entity.topDownMovementState) {\n\t\treturn entity.topDownMovementState.facingAngle;\n\t}\n\n\tif (entity.body?.rotation) {\n\t\treturn getRotationAngle2D(entity.body.rotation());\n\t}\n\n\treturn entity._rotation2DAngle ?? 0;\n}\n\nexport function resolveAim2D(\n\taimX: number,\n\taimY: number,\n\tfallbackAngle: number,\n): ResolvedAim2D {\n\tconst direction = normalizeDirection2D(aimX, aimY);\n\tif (direction) {\n\t\treturn {\n\t\t\tangle: angleFromDirection2D(direction),\n\t\t\tdirection,\n\t\t\thasAimInput: true,\n\t\t};\n\t}\n\n\treturn {\n\t\tangle: fallbackAngle,\n\t\tdirection: directionFromAngle2D(fallbackAngle),\n\t\thasAimInput: false,\n\t};\n}\n"],"mappings":";;;;;;;;AAaO,SAAS,uBAAuB,QAAqB;AAC3D,MAAI,OAAO,sBAAsB;AAChC,WAAO,OAAO,qBAAqB;AAAA,EACpC;AAEA,MAAI,OAAO,MAAM,UAAU;AAC1B,WAAO,mBAAmB,OAAO,KAAK,SAAS,CAAC;AAAA,EACjD;AAEA,SAAO,OAAO,oBAAoB;AACnC;AAEO,SAAS,aACf,MACA,MACA,eACgB;AAChB,QAAM,YAAY,qBAAqB,MAAM,IAAI;AACjD,MAAI,WAAW;AACd,WAAO;AAAA,MACN,OAAO,qBAAqB,SAAS;AAAA,MACrC;AAAA,MACA,aAAa;AAAA,IACd;AAAA,EACD;AAEA,SAAO;AAAA,IACN,OAAO;AAAA,IACP,WAAW,qBAAqB,aAAa;AAAA,IAC7C,aAAa;AAAA,EACd;AACD;","names":[]}
@@ -2628,3 +2628,4 @@ export {
2628
2628
  magicPresets,
2629
2629
  waterPresets
2630
2630
  };
2631
+ //# sourceMappingURL=chunk-7JJEIADR.js.map