@zylem/behaviors 0.3.1 → 0.4.0

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 (138) hide show
  1. package/dist/{behavior-system-DYbx-x_-.d.ts → behavior-system-DSNek0W9.d.ts} +205 -29
  2. package/dist/{chunk-Y6UJOUE5.js → chunk-4V7TIRO2.js} +1 -1
  3. package/dist/chunk-4V7TIRO2.js.map +1 -0
  4. package/dist/{chunk-DYLH6K7B.js → chunk-4WH2ZN7P.js} +1 -1
  5. package/dist/{chunk-DYLH6K7B.js.map → chunk-4WH2ZN7P.js.map} +1 -1
  6. package/dist/{chunk-ZPSAXX73.js → chunk-5SM5SH5O.js} +26 -26
  7. package/dist/chunk-5SM5SH5O.js.map +1 -0
  8. package/dist/{chunk-STCCNLPC.js → chunk-5XZWTFGF.js} +5 -3
  9. package/dist/chunk-5XZWTFGF.js.map +1 -0
  10. package/dist/{chunk-OYWFPIHF.js → chunk-64HKCSXD.js} +19 -16
  11. package/dist/chunk-64HKCSXD.js.map +1 -0
  12. package/dist/{chunk-JAN34G6S.js → chunk-FRJDQM23.js} +108 -154
  13. package/dist/chunk-FRJDQM23.js.map +1 -0
  14. package/dist/{chunk-RTRVBEIB.js → chunk-FTDZAKZW.js} +5 -18
  15. package/dist/chunk-FTDZAKZW.js.map +1 -0
  16. package/dist/{chunk-XIJNE67Y.js → chunk-GFARAJV2.js} +3 -5
  17. package/dist/{chunk-XIJNE67Y.js.map → chunk-GFARAJV2.js.map} +1 -1
  18. package/dist/{chunk-SS7ELMJ7.js → chunk-GTLA6LOJ.js} +16 -22
  19. package/dist/chunk-GTLA6LOJ.js.map +1 -0
  20. package/dist/{chunk-VAN4WW3F.js → chunk-H4TJ7X4O.js} +4 -7
  21. package/dist/chunk-H4TJ7X4O.js.map +1 -0
  22. package/dist/{chunk-4I6E6DGV.js → chunk-HNESASBB.js} +4 -6
  23. package/dist/{chunk-4I6E6DGV.js.map → chunk-HNESASBB.js.map} +1 -1
  24. package/dist/{chunk-KS72RZHX.js → chunk-IZJFUAXB.js} +1 -1
  25. package/dist/{chunk-KS72RZHX.js.map → chunk-IZJFUAXB.js.map} +1 -1
  26. package/dist/{chunk-SVLNF434.js → chunk-JXMF4NUI.js} +51 -3
  27. package/dist/chunk-JXMF4NUI.js.map +1 -0
  28. package/dist/chunk-KFFETUAL.js +40 -0
  29. package/dist/chunk-KFFETUAL.js.map +1 -0
  30. package/dist/chunk-LL4FLHIY.js +12 -0
  31. package/dist/chunk-LL4FLHIY.js.map +1 -0
  32. package/dist/{chunk-2CLT36VB.js → chunk-MJFMNRMZ.js} +13 -14
  33. package/dist/chunk-MJFMNRMZ.js.map +1 -0
  34. package/dist/{chunk-RTVRUNYR.js → chunk-OTLSUYQQ.js} +2 -2
  35. package/dist/chunk-OTLSUYQQ.js.map +1 -0
  36. package/dist/{chunk-XG2YMCJW.js → chunk-PWF757B6.js} +4 -6
  37. package/dist/{chunk-XG2YMCJW.js.map → chunk-PWF757B6.js.map} +1 -1
  38. package/dist/{chunk-LD5SMIB3.js → chunk-QVCMJ4Q2.js} +1 -1
  39. package/dist/{chunk-LD5SMIB3.js.map → chunk-QVCMJ4Q2.js.map} +1 -1
  40. package/dist/{chunk-F3KRX2V4.js → chunk-RONH2KDI.js} +10 -12
  41. package/dist/chunk-RONH2KDI.js.map +1 -0
  42. package/dist/chunk-RTRFJVCZ.js +454 -0
  43. package/dist/chunk-RTRFJVCZ.js.map +1 -0
  44. package/dist/{chunk-6C6NXNEW.js → chunk-UL6Q5HDP.js} +25 -3
  45. package/dist/chunk-UL6Q5HDP.js.map +1 -0
  46. package/dist/{chunk-KOZUNIIE.js → chunk-V74N7D6Q.js} +7 -7
  47. package/dist/{chunk-KOZUNIIE.js.map → chunk-V74N7D6Q.js.map} +1 -1
  48. package/dist/{chunk-YUO6SKJD.js → chunk-WXXXJ22R.js} +11 -13
  49. package/dist/chunk-WXXXJ22R.js.map +1 -0
  50. package/dist/{chunk-ARJWUNRE.js → chunk-XLUJDKCT.js} +7 -7
  51. package/dist/{chunk-ARJWUNRE.js.map → chunk-XLUJDKCT.js.map} +1 -1
  52. package/dist/{chunk-GCNRXAKH.js → chunk-XP3ASVGJ.js} +13 -10
  53. package/dist/chunk-XP3ASVGJ.js.map +1 -0
  54. package/dist/{chunk-ID5QJYF5.js → chunk-Y7YIAWPW.js} +11 -1
  55. package/dist/chunk-Y7YIAWPW.js.map +1 -0
  56. package/dist/{chunk-FPTWVCPN.js → chunk-ZA43LPRM.js} +4 -24
  57. package/dist/chunk-ZA43LPRM.js.map +1 -0
  58. package/dist/{chunk-K3UNLQ7W.js → chunk-ZRQWSURL.js} +2 -2
  59. package/dist/chunk-ZRQWSURL.js.map +1 -0
  60. package/dist/cooldown.d.ts +2 -1
  61. package/dist/cooldown.js +1 -1
  62. package/dist/coordinators/boundary-ricochet-3d.d.ts +12 -5
  63. package/dist/coordinators/boundary-ricochet-3d.js +2 -1
  64. package/dist/coordinators/boundary-ricochet.d.ts +9 -7
  65. package/dist/coordinators/boundary-ricochet.js +2 -1
  66. package/dist/coordinators/first-person-shooter.d.ts +9 -8
  67. package/dist/coordinators/first-person-shooter.js +3 -3
  68. package/dist/coordinators/multidirectional-space-shooter.d.ts +12 -9
  69. package/dist/coordinators/multidirectional-space-shooter.js +4 -4
  70. package/dist/coordinators/top-down-shooter.d.ts +9 -8
  71. package/dist/coordinators/top-down-shooter.js +3 -3
  72. package/dist/core.d.ts +4 -4
  73. package/dist/core.js +4 -32
  74. package/dist/core.js.map +1 -1
  75. package/dist/destructible-3d.d.ts +2 -1
  76. package/dist/first-person.d.ts +12 -12
  77. package/dist/first-person.js +8 -8
  78. package/dist/index.d.ts +37 -14
  79. package/dist/index.js +73 -44
  80. package/dist/jumper-2d.d.ts +7 -6
  81. package/dist/jumper-2d.js +5 -5
  82. package/dist/jumper-3d.d.ts +12 -11
  83. package/dist/jumper-3d.js +6 -6
  84. package/dist/{moveable-BCRpjAQb.d.ts → moveable-BLTHO7Jq.d.ts} +2 -78
  85. package/dist/particle-emitter.d.ts +1 -1
  86. package/dist/particle-emitter.js +1 -1
  87. package/dist/platformer-2d.d.ts +306 -0
  88. package/dist/platformer-2d.js +23 -0
  89. package/dist/platformer-3d.d.ts +74 -87
  90. package/dist/platformer-3d.js +4 -4
  91. package/dist/ricochet-2d.d.ts +1 -1
  92. package/dist/ricochet-2d.js +2 -2
  93. package/dist/ricochet-3d.d.ts +1 -1
  94. package/dist/ricochet-3d.js +2 -2
  95. package/dist/runtime-2d.d.ts +93 -2
  96. package/dist/runtime-2d.js +145 -22
  97. package/dist/runtime-2d.js.map +1 -1
  98. package/dist/screen-visibility.d.ts +2 -1
  99. package/dist/screen-wrap.d.ts +2 -1
  100. package/dist/screen-wrap.js +1 -1
  101. package/dist/shooter-2d.d.ts +5 -3
  102. package/dist/shooter-2d.js +2 -2
  103. package/dist/shooter-fire-DGripl0z.d.ts +55 -0
  104. package/dist/thruster.d.ts +8 -18
  105. package/dist/thruster.js +6 -6
  106. package/dist/top-down-movement.d.ts +7 -4
  107. package/dist/top-down-movement.js +5 -5
  108. package/dist/{use-behavior-D_82jAL3.d.ts → use-behavior-h9-T5FSv.d.ts} +1 -1
  109. package/dist/world-boundary-2d.d.ts +2 -1
  110. package/dist/world-boundary-2d.js +2 -2
  111. package/dist/world-boundary-3d.d.ts +2 -1
  112. package/dist/world-boundary-3d.js +2 -2
  113. package/package.json +5 -5
  114. package/dist/chunk-2C3Z5GE7.js +0 -176
  115. package/dist/chunk-2C3Z5GE7.js.map +0 -1
  116. package/dist/chunk-2CLT36VB.js.map +0 -1
  117. package/dist/chunk-3PYGRHAL.js +0 -35
  118. package/dist/chunk-3PYGRHAL.js.map +0 -1
  119. package/dist/chunk-6C6NXNEW.js.map +0 -1
  120. package/dist/chunk-F3KRX2V4.js.map +0 -1
  121. package/dist/chunk-FPTWVCPN.js.map +0 -1
  122. package/dist/chunk-GCNRXAKH.js.map +0 -1
  123. package/dist/chunk-ID5QJYF5.js.map +0 -1
  124. package/dist/chunk-JAN34G6S.js.map +0 -1
  125. package/dist/chunk-K3UNLQ7W.js.map +0 -1
  126. package/dist/chunk-OYWFPIHF.js.map +0 -1
  127. package/dist/chunk-RTRVBEIB.js.map +0 -1
  128. package/dist/chunk-RTVRUNYR.js.map +0 -1
  129. package/dist/chunk-SS7ELMJ7.js.map +0 -1
  130. package/dist/chunk-STCCNLPC.js.map +0 -1
  131. package/dist/chunk-SVLNF434.js.map +0 -1
  132. package/dist/chunk-VAN4WW3F.js.map +0 -1
  133. package/dist/chunk-Y6UJOUE5.js.map +0 -1
  134. package/dist/chunk-YUO6SKJD.js.map +0 -1
  135. package/dist/chunk-ZPSAXX73.js.map +0 -1
  136. package/dist/runtime-pong.d.ts +0 -92
  137. package/dist/runtime-pong.js +0 -38
  138. /package/dist/{runtime-pong.js.map → platformer-2d.js.map} +0 -0
@@ -53,7 +53,7 @@ function getCooldownStore() {
53
53
  return cooldownStore;
54
54
  }
55
55
 
56
- // src/lib/behaviors/cooldown/cooldown-behavior.ts
56
+ // src/lib/behaviors/cooldown/cooldown.descriptor.ts
57
57
  var COOLDOWN_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for("zylem:behavior:cooldown");
58
58
  var CooldownSystem = class {
59
59
  constructor(getBehaviorLinks) {
@@ -115,4 +115,4 @@ export {
115
115
  getCooldownStore,
116
116
  CooldownBehavior
117
117
  };
118
- //# sourceMappingURL=chunk-K3UNLQ7W.js.map
118
+ //# sourceMappingURL=chunk-ZRQWSURL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/behaviors/cooldown/cooldown-store.ts","../src/lib/behaviors/cooldown/cooldown.descriptor.ts"],"sourcesContent":["import { proxy } from 'valtio';\n\n/**\n * A single cooldown entry in the global store.\n */\nexport interface CooldownEntry {\n\t/** Identifier for this cooldown */\n\tname: string;\n\t/** Total cooldown time in seconds */\n\tduration: number;\n\t/** Time accumulated since last fire */\n\telapsed: number;\n\t/** Whether the cooldown is ready (elapsed >= duration) */\n\tready: boolean;\n\t/** Normalized progress 0..1 (0 = just fired, 1 = ready) */\n\tprogress: number;\n\t/** Whether this cooldown is currently counting down */\n\tactive: boolean;\n}\n\n/**\n * Global reactive cooldown registry (valtio proxy).\n * Accessible from entities, behaviors, and UI components.\n */\nconst cooldownStore = proxy<Record<string, CooldownEntry>>({});\n\n/**\n * Register a named cooldown in the global store.\n * If a cooldown with the same name already exists, it is overwritten.\n *\n * @param name Unique cooldown identifier\n * @param duration Cooldown duration in seconds\n * @param immediate If true, the cooldown starts ready (default: true)\n */\nexport function registerCooldown(\n\tname: string,\n\tduration: number,\n\timmediate: boolean = true,\n): void {\n\tcooldownStore[name] = {\n\t\tname,\n\t\tduration,\n\t\telapsed: immediate ? duration : 0,\n\t\tready: immediate,\n\t\tprogress: immediate ? 1 : 0,\n\t\tactive: !immediate,\n\t};\n}\n\n/**\n * Get a cooldown entry by name.\n * Returns undefined if the cooldown has not been registered.\n */\nexport function getCooldown(name: string): CooldownEntry | undefined {\n\treturn cooldownStore[name];\n}\n\n/**\n * Fire (trigger) a cooldown, resetting its timer.\n * Sets the cooldown to not-ready and starts the countdown.\n */\nexport function fireCooldown(name: string): void {\n\tconst entry = cooldownStore[name];\n\tif (!entry) return;\n\tentry.elapsed = 0;\n\tentry.ready = false;\n\tentry.progress = 0;\n\tentry.active = true;\n}\n\n/**\n * Force a cooldown to ready immediately.\n */\nexport function resetCooldown(name: string): void {\n\tconst entry = cooldownStore[name];\n\tif (!entry) return;\n\tentry.elapsed = entry.duration;\n\tentry.ready = true;\n\tentry.progress = 1;\n\tentry.active = false;\n}\n\n/**\n * Advance all active cooldowns by delta seconds.\n * Called once per frame by the CooldownBehavior system.\n */\nexport function tickCooldowns(delta: number): void {\n\tfor (const name in cooldownStore) {\n\t\tconst entry = cooldownStore[name];\n\t\tif (!entry.active) continue;\n\n\t\tentry.elapsed += delta;\n\t\tif (entry.elapsed >= entry.duration) {\n\t\t\tentry.elapsed = entry.duration;\n\t\t\tentry.ready = true;\n\t\t\tentry.progress = 1;\n\t\t\tentry.active = false;\n\t\t} else {\n\t\t\tentry.progress = entry.duration > 0 ? entry.elapsed / entry.duration : 1;\n\t\t}\n\t}\n}\n\n/**\n * Get the raw cooldown store (for advanced/debugging use).\n */\nexport function getCooldownStore(): Record<string, CooldownEntry> {\n\treturn cooldownStore;\n}\n","/**\n * CooldownBehavior\n *\n * A stage-scoped behavior that manages named cooldowns via the global CooldownStore.\n * Entities use this to register, check, and fire cooldowns.\n * UI components (CooldownIcon) can read from the same store.\n */\n\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tregisterCooldown,\n\tgetCooldown,\n\tfireCooldown,\n\tresetCooldown,\n\ttickCooldowns,\n} from './cooldown-store';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CooldownConfig {\n\t/** Duration in seconds */\n\tduration: number;\n\t/** Whether the cooldown starts ready (default: true) */\n\timmediate?: boolean;\n}\n\nexport interface CooldownOptions {\n\t/**\n\t * Named cooldowns to register.\n\t * Keys are the cooldown names, values are their config.\n\t */\n\tcooldowns: Record<string, CooldownConfig>;\n}\n\ninterface CompiledCooldownEntry {\n\tname: string;\n\tduration: number;\n\timmediate: boolean;\n}\n\nconst COOLDOWN_BEHAVIOR_KEY = Symbol.for('zylem:behavior:cooldown');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Handle\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Handle methods returned by entity.use(CooldownBehavior, ...).\n */\nexport interface CooldownHandle {\n\t/** Check if a named cooldown is ready */\n\tisReady(name: string): boolean;\n\t/** Fire (trigger) a named cooldown, resetting its timer */\n\tfire(name: string): void;\n\t/** Force a cooldown to ready immediately */\n\treset(name: string): void;\n\t/** Get cooldown progress 0..1 (0 = just fired, 1 = ready) */\n\tgetProgress(name: string): number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// System\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass CooldownSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) { }\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(COOLDOWN_BEHAVIOR_KEY);\n\t\tif (links) {\n\t\t\tfor (const link of links) {\n\t\t\t\tensureCooldownEntriesRegistered(link.ref as BehaviorRef<CooldownOptions>);\n\t\t\t}\n\t\t}\n\n\t\ttickCooldowns(delta);\n\t}\n\n\tdestroy(_ecs: unknown): void { }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Handle factory\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction createCooldownHandle(ref: BehaviorRef<CooldownOptions>): CooldownHandle {\n\tensureCooldownEntriesRegistered(ref);\n\n\treturn {\n\t\tisReady: (name: string) => getCooldown(name)?.ready ?? false,\n\t\tfire: (name: string) => fireCooldown(name),\n\t\treset: (name: string) => resetCooldown(name),\n\t\tgetProgress: (name: string) => getCooldown(name)?.progress ?? 1,\n\t};\n}\n\nfunction getCompiledCooldownEntries(\n\tref: BehaviorRef<CooldownOptions>,\n): CompiledCooldownEntry[] {\n\tconst compiled = (ref as any).__compiledCooldownEntries as CompiledCooldownEntry[] | undefined;\n\tif (compiled) return compiled;\n\n\tconst entries = Object.entries(ref.options.cooldowns).map(([name, config]) => ({\n\t\tname,\n\t\tduration: config.duration,\n\t\timmediate: config.immediate ?? true,\n\t}));\n\t(ref as any).__compiledCooldownEntries = entries;\n\treturn entries;\n}\n\nfunction ensureCooldownEntriesRegistered(ref: BehaviorRef<CooldownOptions>): void {\n\tif ((ref as any).__cooldownsRegistered) return;\n\n\tfor (const entry of getCompiledCooldownEntries(ref)) {\n\t\tregisterCooldown(entry.name, entry.duration, entry.immediate);\n\t}\n\n\t(ref as any).__cooldownsRegistered = true;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Behavior Definition\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * CooldownBehavior\n *\n * @example\n * ```ts\n * import { CooldownBehavior } from '@zylem/game-lib/behavior';\n * import { moveBy } from '@zylem/game-lib/actions';\n *\n * const hero = createBox({ ... });\n * const cd = hero.use(CooldownBehavior, {\n * cooldowns: {\n * attack: { duration: 5 },\n * dash: { duration: 2, immediate: false },\n * },\n * });\n *\n * hero.onUpdate(({ me, inputs }) => {\n * if (cd.isReady('attack') && inputs.p1.buttons.A.pressed) {\n * cd.fire('attack');\n * // perform attack\n * }\n * if (cd.isReady('dash') && inputs.p1.buttons.B.pressed) {\n * cd.fire('dash');\n * me.runAction(moveBy({ x: 10, duration: 0.3 }));\n * }\n * });\n * ```\n */\nexport const CooldownBehavior = defineBehavior<CooldownOptions, CooldownHandle>({\n\tname: 'cooldown',\n\tdefaultOptions: { cooldowns: {} },\n\tsystemFactory: (ctx) =>\n\t\tnew CooldownSystem(ctx.getBehaviorLinks),\n\tcreateHandle: createCooldownHandle,\n});\n"],"mappings":";;;;;AAAA,SAAS,aAAa;AAwBtB,IAAM,gBAAgB,MAAqC,CAAC,CAAC;AAUtD,SAAS,iBACf,MACA,UACA,YAAqB,MACd;AACP,gBAAc,IAAI,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA,SAAS,YAAY,WAAW;AAAA,IAChC,OAAO;AAAA,IACP,UAAU,YAAY,IAAI;AAAA,IAC1B,QAAQ,CAAC;AAAA,EACV;AACD;AAMO,SAAS,YAAY,MAAyC;AACpE,SAAO,cAAc,IAAI;AAC1B;AAMO,SAAS,aAAa,MAAoB;AAChD,QAAM,QAAQ,cAAc,IAAI;AAChC,MAAI,CAAC,MAAO;AACZ,QAAM,UAAU;AAChB,QAAM,QAAQ;AACd,QAAM,WAAW;AACjB,QAAM,SAAS;AAChB;AAKO,SAAS,cAAc,MAAoB;AACjD,QAAM,QAAQ,cAAc,IAAI;AAChC,MAAI,CAAC,MAAO;AACZ,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ;AACd,QAAM,WAAW;AACjB,QAAM,SAAS;AAChB;AAMO,SAAS,cAAc,OAAqB;AAClD,aAAW,QAAQ,eAAe;AACjC,UAAM,QAAQ,cAAc,IAAI;AAChC,QAAI,CAAC,MAAM,OAAQ;AAEnB,UAAM,WAAW;AACjB,QAAI,MAAM,WAAW,MAAM,UAAU;AACpC,YAAM,UAAU,MAAM;AACtB,YAAM,QAAQ;AACd,YAAM,WAAW;AACjB,YAAM,SAAS;AAAA,IAChB,OAAO;AACN,YAAM,WAAW,MAAM,WAAW,IAAI,MAAM,UAAU,MAAM,WAAW;AAAA,IACxE;AAAA,EACD;AACD;AAKO,SAAS,mBAAkD;AACjE,SAAO;AACR;;;ACjEA,IAAM,wBAAwB,uBAAO,IAAI,yBAAyB;AAwBlE,IAAM,iBAAN,MAA+C;AAAA,EAC9C,YACS,kBACP;AADO;AAAA,EACL;AAAA,EADK;AAAA,EAGT,OAAO,MAAe,OAAqB;AAC1C,UAAM,QAAQ,KAAK,mBAAmB,qBAAqB;AAC3D,QAAI,OAAO;AACV,iBAAW,QAAQ,OAAO;AACzB,wCAAgC,KAAK,GAAmC;AAAA,MACzE;AAAA,IACD;AAEA,kBAAc,KAAK;AAAA,EACpB;AAAA,EAEA,QAAQ,MAAqB;AAAA,EAAE;AAChC;AAMA,SAAS,qBAAqB,KAAmD;AAChF,kCAAgC,GAAG;AAEnC,SAAO;AAAA,IACN,SAAS,CAAC,SAAiB,YAAY,IAAI,GAAG,SAAS;AAAA,IACvD,MAAM,CAAC,SAAiB,aAAa,IAAI;AAAA,IACzC,OAAO,CAAC,SAAiB,cAAc,IAAI;AAAA,IAC3C,aAAa,CAAC,SAAiB,YAAY,IAAI,GAAG,YAAY;AAAA,EAC/D;AACD;AAEA,SAAS,2BACR,KAC0B;AAC1B,QAAM,WAAY,IAAY;AAC9B,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,OAAO,QAAQ,IAAI,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,OAAO;AAAA,IAC9E;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,WAAW,OAAO,aAAa;AAAA,EAChC,EAAE;AACF,EAAC,IAAY,4BAA4B;AACzC,SAAO;AACR;AAEA,SAAS,gCAAgC,KAAyC;AACjF,MAAK,IAAY,sBAAuB;AAExC,aAAW,SAAS,2BAA2B,GAAG,GAAG;AACpD,qBAAiB,MAAM,MAAM,MAAM,UAAU,MAAM,SAAS;AAAA,EAC7D;AAEA,EAAC,IAAY,wBAAwB;AACtC;AAkCO,IAAM,mBAAmB,eAAgD;AAAA,EAC/E,MAAM;AAAA,EACN,gBAAgB,EAAE,WAAW,CAAC,EAAE;AAAA,EAChC,eAAe,CAAC,QACf,IAAI,eAAe,IAAI,gBAAgB;AAAA,EACxC,cAAc;AACf,CAAC;","names":[]}
@@ -1,4 +1,5 @@
1
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
1
+ import { a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
2
+ import '@dimforge/rapier3d-compat';
2
3
 
3
4
  /**
4
5
  * CooldownBehavior
package/dist/cooldown.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  registerCooldown,
7
7
  resetCooldown,
8
8
  tickCooldowns
9
- } from "./chunk-K3UNLQ7W.js";
9
+ } from "./chunk-ZRQWSURL.js";
10
10
  import "./chunk-EZNCCO4L.js";
11
11
  export {
12
12
  CooldownBehavior,
@@ -1,19 +1,26 @@
1
- import { G as GameEntity } from '../behavior-system-DYbx-x_-.js';
2
- import { M as MoveableEntity } from '../moveable-BCRpjAQb.js';
1
+ import { M as MoveableEntity } from '../moveable-BLTHO7Jq.js';
2
+ import { B as BaseEntityInterface } from '../entity-types-CmtQ-IBp.js';
3
3
  import { Ricochet3DHandle } from '../ricochet-3d.js';
4
4
  import { WorldBoundary3DHandle } from '../world-boundary-3d.js';
5
5
  import 'three';
6
6
  import '@dimforge/rapier3d-compat';
7
+ import '../behavior-system-DSNek0W9.js';
7
8
  import '../sync-state-machine-CZyspBpj.js';
8
9
  import 'typescript-fsm';
9
- import '../entity-types-CmtQ-IBp.js';
10
10
 
11
+ /** Entity shape required by the 3D boundary-ricochet coordinator. */
12
+ type BoundaryRicochet3DEntity = BaseEntityInterface & MoveableEntity;
13
+ /**
14
+ * Coordinator that bridges WorldBoundary3DBehavior and Ricochet3DBehavior.
15
+ * Snaps the body back to the boundary's clamped position before reflecting,
16
+ * so fast entities can't tunnel outside the box between frames.
17
+ */
11
18
  declare class BoundaryRicochet3DCoordinator {
12
19
  private entity;
13
20
  private boundary;
14
21
  private ricochet;
15
- constructor(entity: GameEntity<any> & MoveableEntity, boundary: WorldBoundary3DHandle, ricochet: Ricochet3DHandle);
22
+ constructor(entity: BoundaryRicochet3DEntity, boundary: WorldBoundary3DHandle, ricochet: Ricochet3DHandle);
16
23
  update(): boolean;
17
24
  }
18
25
 
19
- export { BoundaryRicochet3DCoordinator };
26
+ export { BoundaryRicochet3DCoordinator, type BoundaryRicochet3DEntity };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  BoundaryRicochet3DCoordinator
3
- } from "../chunk-3PYGRHAL.js";
3
+ } from "../chunk-KFFETUAL.js";
4
4
  import "../chunk-OHCPV2NT.js";
5
+ import "../chunk-LL4FLHIY.js";
5
6
  export {
6
7
  BoundaryRicochet3DCoordinator
7
8
  };
@@ -1,13 +1,15 @@
1
- import { G as GameEntity } from '../behavior-system-DYbx-x_-.js';
2
1
  import { Ricochet2DHandle } from '../ricochet-2d.js';
3
2
  import { WorldBoundary2DHandle } from '../world-boundary-2d.js';
4
- import { M as MoveableEntity } from '../moveable-BCRpjAQb.js';
5
- import '../entity-types-CmtQ-IBp.js';
6
- import 'three';
7
- import '@dimforge/rapier3d-compat';
3
+ import { M as MoveableEntity } from '../moveable-BLTHO7Jq.js';
4
+ import { B as BaseEntityInterface } from '../entity-types-CmtQ-IBp.js';
8
5
  import '../sync-state-machine-CZyspBpj.js';
9
6
  import 'typescript-fsm';
7
+ import '../behavior-system-DSNek0W9.js';
8
+ import '@dimforge/rapier3d-compat';
9
+ import 'three';
10
10
 
11
+ /** Entity shape required by the 2D boundary-ricochet coordinator. */
12
+ type BoundaryRicochetEntity = BaseEntityInterface & MoveableEntity;
11
13
  /**
12
14
  * Coordinator that bridges WorldBoundary2DBehavior and Ricochet2DBehavior.
13
15
  *
@@ -21,7 +23,7 @@ declare class BoundaryRicochetCoordinator {
21
23
  private entity;
22
24
  private boundary;
23
25
  private ricochet;
24
- constructor(entity: GameEntity<any> & MoveableEntity, boundary: WorldBoundary2DHandle, ricochet: Ricochet2DHandle);
26
+ constructor(entity: BoundaryRicochetEntity, boundary: WorldBoundary2DHandle, ricochet: Ricochet2DHandle);
25
27
  /**
26
28
  * Update loop - call this every frame.
27
29
  * Applies ricochet via transformStore and notifies listeners.
@@ -31,4 +33,4 @@ declare class BoundaryRicochetCoordinator {
31
33
  update(): boolean;
32
34
  }
33
35
 
34
- export { BoundaryRicochetCoordinator };
36
+ export { BoundaryRicochetCoordinator, type BoundaryRicochetEntity };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  BoundaryRicochetCoordinator
3
- } from "../chunk-GCNRXAKH.js";
3
+ } from "../chunk-XP3ASVGJ.js";
4
4
  import "../chunk-KDY5N6J4.js";
5
+ import "../chunk-LL4FLHIY.js";
5
6
  export {
6
7
  BoundaryRicochetCoordinator
7
8
  };
@@ -1,4 +1,3 @@
1
- import { G as GameEntity } from '../behavior-system-DYbx-x_-.js';
2
1
  import { F as FirstPersonInputComponent } from '../components-qWwOsvwh.js';
3
2
  import { b as JumpInput3D } from '../components--hjBMTnz.js';
4
3
 
@@ -16,20 +15,22 @@ interface FirstPersonShooterInput {
16
15
  interface FirstPersonShooterControllerHandle {
17
16
  getYaw(): number;
18
17
  }
19
- interface FirstPersonShooterJumperHandle {
20
- getState(): unknown;
21
- }
22
- type FirstPersonShooterEntity = GameEntity<any> & {
18
+ type FirstPersonShooterEntity = {
23
19
  $fps?: FirstPersonInputComponent;
24
20
  $jumper?: JumpInput3D;
25
21
  };
22
+ /**
23
+ * Coordinator that fans a single input snapshot out to the first-person
24
+ * behavior (`$fps`) and the Jumper3D behavior (`$jumper`), converting local
25
+ * move axes into the camera-relative world direction the jumper uses for
26
+ * air control.
27
+ */
26
28
  declare class FirstPersonShooterCoordinator {
27
29
  private entity;
28
30
  private fpsController;
29
- private jumper;
30
- constructor(entity: FirstPersonShooterEntity, fpsController: FirstPersonShooterControllerHandle, jumper: FirstPersonShooterJumperHandle);
31
+ constructor(entity: FirstPersonShooterEntity, fpsController: FirstPersonShooterControllerHandle);
31
32
  update(input: FirstPersonShooterInput): void;
32
33
  private getMoveDirWorld;
33
34
  }
34
35
 
35
- export { FirstPersonShooterCoordinator, type FirstPersonShooterInput };
36
+ export { FirstPersonShooterCoordinator, type FirstPersonShooterEntity, type FirstPersonShooterInput };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  FirstPersonShooterCoordinator
3
- } from "../chunk-VAN4WW3F.js";
4
- import "../chunk-LD5SMIB3.js";
5
- import "../chunk-DYLH6K7B.js";
3
+ } from "../chunk-H4TJ7X4O.js";
4
+ import "../chunk-QVCMJ4Q2.js";
5
+ import "../chunk-4WH2ZN7P.js";
6
6
  export {
7
7
  FirstPersonShooterCoordinator
8
8
  };
@@ -1,21 +1,24 @@
1
- import { G as GameEntity } from '../behavior-system-DYbx-x_-.js';
2
1
  import { T as ThrusterInputComponent } from '../components-B29WHGQN.js';
3
2
  import { Shooter2DSourceEntity, Shooter2DHandle, Shooter2DStageLike } from '../shooter-2d.js';
3
+ import { S as Shooter2DAimFireInput } from '../shooter-fire-DGripl0z.js';
4
+ import '../behavior-system-DSNek0W9.js';
5
+ import '@dimforge/rapier3d-compat';
4
6
  import '../vector-Bm65-FOG.js';
5
7
  import 'three';
6
- import '@dimforge/rapier3d-compat';
7
8
 
8
- interface MultidirectionalSpaceShooterInput {
9
+ interface MultidirectionalSpaceShooterInput extends Shooter2DAimFireInput {
9
10
  moveX: number;
10
11
  moveY: number;
11
- aimX: number;
12
- aimY: number;
13
- shootPressed: boolean;
14
- shootHeld: boolean;
15
12
  }
16
- type MultidirectionalSpaceShooterEntity = GameEntity<any> & Shooter2DSourceEntity & {
13
+ type MultidirectionalSpaceShooterEntity = Shooter2DSourceEntity & {
17
14
  $thruster?: ThrusterInputComponent;
15
+ setRotationZ(angle: number): void;
18
16
  };
17
+ /**
18
+ * Coordinator that fans a single input snapshot out to the thruster behavior
19
+ * (vector thrust), entity rotation (aim), and the Shooter2D behavior (fire
20
+ * requests).
21
+ */
19
22
  declare class MultidirectionalSpaceShooterCoordinator {
20
23
  private entity;
21
24
  private shooter;
@@ -24,4 +27,4 @@ declare class MultidirectionalSpaceShooterCoordinator {
24
27
  update(input: MultidirectionalSpaceShooterInput): void;
25
28
  }
26
29
 
27
- export { MultidirectionalSpaceShooterCoordinator, type MultidirectionalSpaceShooterInput };
30
+ export { MultidirectionalSpaceShooterCoordinator, type MultidirectionalSpaceShooterEntity, type MultidirectionalSpaceShooterInput };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  MultidirectionalSpaceShooterCoordinator
3
- } from "../chunk-RTRVBEIB.js";
4
- import "../chunk-6C6NXNEW.js";
5
- import "../chunk-KS72RZHX.js";
6
- import "../chunk-ID5QJYF5.js";
3
+ } from "../chunk-FTDZAKZW.js";
4
+ import "../chunk-UL6Q5HDP.js";
5
+ import "../chunk-IZJFUAXB.js";
6
+ import "../chunk-Y7YIAWPW.js";
7
7
  export {
8
8
  MultidirectionalSpaceShooterCoordinator
9
9
  };
@@ -1,21 +1,22 @@
1
1
  import { a as TopDownMovementInputComponent } from '../components-XCpL6IYt.js';
2
2
  import { Shooter2DSourceEntity, Shooter2DHandle, Shooter2DStageLike } from '../shooter-2d.js';
3
- import '../behavior-system-DYbx-x_-.js';
3
+ import { S as Shooter2DAimFireInput } from '../shooter-fire-DGripl0z.js';
4
+ import '../behavior-system-DSNek0W9.js';
5
+ import '@dimforge/rapier3d-compat';
4
6
  import '../vector-Bm65-FOG.js';
5
7
  import 'three';
6
- import '@dimforge/rapier3d-compat';
7
8
 
8
- interface TopDownShooterInput {
9
+ interface TopDownShooterInput extends Shooter2DAimFireInput {
9
10
  moveX: number;
10
11
  moveY: number;
11
- aimX: number;
12
- aimY: number;
13
- shootPressed: boolean;
14
- shootHeld: boolean;
15
12
  }
16
13
  type TopDownShooterEntity = Shooter2DSourceEntity & {
17
14
  $topDownMovement?: TopDownMovementInputComponent;
18
15
  };
16
+ /**
17
+ * Coordinator that fans a single input snapshot out to the top-down movement
18
+ * behavior (move + face axes) and the Shooter2D behavior (fire requests).
19
+ */
19
20
  declare class TopDownShooterCoordinator {
20
21
  private entity;
21
22
  private shooter;
@@ -24,4 +25,4 @@ declare class TopDownShooterCoordinator {
24
25
  update(input: TopDownShooterInput): void;
25
26
  }
26
27
 
27
- export { TopDownShooterCoordinator, type TopDownShooterInput };
28
+ export { TopDownShooterCoordinator, type TopDownShooterEntity, type TopDownShooterInput };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  TopDownShooterCoordinator
3
- } from "../chunk-FPTWVCPN.js";
4
- import "../chunk-6C6NXNEW.js";
3
+ } from "../chunk-ZA43LPRM.js";
4
+ import "../chunk-UL6Q5HDP.js";
5
5
  import "../chunk-EIWQM6U3.js";
6
- import "../chunk-ID5QJYF5.js";
6
+ import "../chunk-Y7YIAWPW.js";
7
7
  export {
8
8
  TopDownShooterCoordinator
9
9
  };
package/dist/core.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BaseBehaviorHandle, a as BehaviorDescriptor, b as BehaviorEcsHandle, c as BehaviorEntityLink, d as BehaviorHandle, e as BehaviorRef, f as BehaviorSystem, g as BehaviorSystemContext, h as BehaviorSystemFactory, C as CreateEntityFn, D as DefineBehaviorConfig, G as GameEntity, i as GameEntityOptions, S as StageBodyKind, j as StageBoundaryDim, k as StageEventType, l as StageRicochetDim, m as StageRicochetReflection, n as StageTopDownPlane, W as WasmStageRuntime, o as WasmStageRuntimeOptions, p as defineBehavior } from './behavior-system-DYbx-x_-.js';
2
- export { u as useBehavior } from './use-behavior-D_82jAL3.js';
1
+ import { H as VelocityIntentMode, T as TransformState } from './behavior-system-DSNek0W9.js';
2
+ export { B as BaseBehaviorHandle, a as BehaviorDescriptor, b as BehaviorEntityLink, c as BehaviorHandle, d as BehaviorRef, e as BehaviorSystem, f as BehaviorSystemContext, g as BehaviorSystemFactory, C as CreateEntityFn, D as DefineBehaviorConfig, G as GameEntity, h as GameEntityOptions, S as StageBodyKind, i as StageBoundaryDim, j as StageBoundaryDimValue, k as StageEventType, l as StageFirstPersonInput, m as StageFirstPersonOptions, n as StageJumper2DOptions, o as StageJumper3DOptions, p as StagePlatformer3DOptions, q as StagePose, r as StageRicochetDim, s as StageRicochetDimValue, t as StageRicochetOptions, u as StageRicochetReflection, v as StageRicochetReflectionValue, w as StageScreenWrapOptions, x as StageShooter2DOptions, y as StageThrusterOptions, z as StageTopDownOptions, A as StageTopDownPlane, E as StageTopDownPlaneValue, F as StageWorldBoundaryOptions, V as VelocityIntent, W as WasmStageRuntime, I as WasmStageRuntimeOptions, J as createTransformStore, K as defineBehavior } from './behavior-system-DSNek0W9.js';
3
+ export { u as useBehavior } from './use-behavior-h9-T5FSv.js';
3
4
  export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent } from './components-BWG1GkZA.js';
4
- import { a as VelocityIntentMode, T as TransformState } from './moveable-BCRpjAQb.js';
5
- export { E as EntityWithBody, M as MoveableEntity, V as VelocityIntent, c as createTransformStore, g as getPosition, b as getVelocity, m as makeMoveable, d as move, e as moveForwardXY, f as moveX, h as moveXY, i as moveXZ, j as moveY, k as moveZ, r as resetTransformStore, l as resetVelocity, s as setPosition, n as setPositionX, o as setPositionY, p as setPositionZ, w as wrapAround3D, q as wrapAroundXY } from './moveable-BCRpjAQb.js';
5
+ export { E as EntityWithBody, M as MoveableEntity, g as getPosition, a as getVelocity, m as makeMoveable, b as move, c as moveForwardXY, d as moveX, e as moveXY, f as moveXZ, h as moveY, i as moveZ, r as resetVelocity, s as setPosition, j as setPositionX, k as setPositionY, l as setPositionZ, w as wrapAround3D, n as wrapAroundXY } from './moveable-BLTHO7Jq.js';
6
6
  export { V as VEC2_ONE, a as VEC2_ZERO, b as VEC3_ONE, c as VEC3_ZERO, d as Vec2, e as Vec2Components, f as Vec2Input, g as Vec3, h as Vec3Components, i as Vec3Input, j as isVec2Input, k as isVec3Input, n as normalizeVec2, l as normalizeVec3, t as toRapierVector3, m as toThreeVector2, o as toThreeVector3 } from './vector-Bm65-FOG.js';
7
7
  export { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
8
8
  export { F as FirstPersonPerspective } from './first-person-perspective-C9Mptl0-.js';
package/dist/core.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  StageRicochetDim,
11
11
  StageRicochetReflection,
12
12
  StageTopDownPlane
13
- } from "./chunk-Y6UJOUE5.js";
13
+ } from "./chunk-4V7TIRO2.js";
14
14
  import {
15
15
  VEC2_ONE,
16
16
  VEC2_ZERO,
@@ -27,7 +27,7 @@ import {
27
27
  import {
28
28
  clearVelocityIntent,
29
29
  setVelocityIntent
30
- } from "./chunk-RTVRUNYR.js";
30
+ } from "./chunk-OTLSUYQQ.js";
31
31
  import {
32
32
  SyncStateMachine,
33
33
  t
@@ -36,7 +36,7 @@ import {
36
36
  defineBehavior
37
37
  } from "./chunk-EZNCCO4L.js";
38
38
 
39
- // src/lib/actions/capabilities/transform-store.ts
39
+ // src/lib/capabilities/transform-store.ts
40
40
  import { proxy } from "valtio";
41
41
  function createTransformStore(initial) {
42
42
  const defaultState = {
@@ -48,7 +48,6 @@ function createTransformStore(initial) {
48
48
  dirty: {
49
49
  position: false,
50
50
  rotation: false,
51
- velocity: false,
52
51
  velocityX: false,
53
52
  velocityY: false,
54
53
  velocityZ: false,
@@ -66,34 +65,8 @@ function createTransformStore(initial) {
66
65
  }
67
66
  });
68
67
  }
69
- function resetTransformStore(store) {
70
- store.position.x = 0;
71
- store.position.y = 0;
72
- store.position.z = 0;
73
- store.rotation.x = 0;
74
- store.rotation.y = 0;
75
- store.rotation.z = 0;
76
- store.rotation.w = 1;
77
- store.velocity.x = 0;
78
- store.velocity.y = 0;
79
- store.velocity.z = 0;
80
- store.angularVelocity.x = 0;
81
- store.angularVelocity.y = 0;
82
- store.angularVelocity.z = 0;
83
- for (const sourceId of Object.keys(store.velocityChannels)) {
84
- delete store.velocityChannels[sourceId];
85
- }
86
- store.dirty.position = false;
87
- store.dirty.rotation = false;
88
- store.dirty.velocity = false;
89
- store.dirty.velocityX = false;
90
- store.dirty.velocityY = false;
91
- store.dirty.velocityZ = false;
92
- store.dirty.velocityChannels = false;
93
- store.dirty.angularVelocity = false;
94
- }
95
68
 
96
- // src/lib/actions/capabilities/moveable.ts
69
+ // src/lib/capabilities/moveable.ts
97
70
  import { Vector3 } from "three";
98
71
  function moveX(entity, delta) {
99
72
  if (!entity.transformStore) return;
@@ -309,7 +282,6 @@ export {
309
282
  moveZ,
310
283
  normalizeVec2,
311
284
  normalizeVec3,
312
- resetTransformStore,
313
285
  resetVelocity,
314
286
  setPosition,
315
287
  setPositionX,
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/actions/capabilities/transform-store.ts","../src/lib/actions/capabilities/moveable.ts","../src/lib/entities/entity.ts"],"sourcesContent":["import { proxy } from 'valtio';\n\nexport type VelocityIntentMode = 'replace' | 'add';\n\nexport interface VelocityIntent {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\tmode: VelocityIntentMode;\n\tpriority?: number;\n}\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\n\t/** Per-source velocity intents composed once per frame */\n\tvelocityChannels: Record<string, VelocityIntent>;\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\t/** @deprecated Use per-axis velocityX/Y/Z flags for new code */\n\t\tvelocity: boolean;\n\t\tvelocityX: boolean;\n\t\tvelocityY: boolean;\n\t\tvelocityZ: boolean;\n\t\tvelocityChannels: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tvelocityChannels: {},\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocity: false,\n\t\t\tvelocityX: false,\n\t\t\tvelocityY: false,\n\t\t\tvelocityZ: false,\n\t\t\tvelocityChannels: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n/**\n * Reset a transform store to its initial clean state.\n * Called after applying changes to prepare for the next frame.\n * \n * @param store The transform store to reset\n */\nexport function resetTransformStore(store: TransformState): void {\n\t// Reset position deltas\n\tstore.position.x = 0;\n\tstore.position.y = 0;\n\tstore.position.z = 0;\n\n\t// Reset rotation to identity quaternion\n\tstore.rotation.x = 0;\n\tstore.rotation.y = 0;\n\tstore.rotation.z = 0;\n\tstore.rotation.w = 1;\n\n\t// Reset velocity\n\tstore.velocity.x = 0;\n\tstore.velocity.y = 0;\n\tstore.velocity.z = 0;\n\n\t// Reset angular velocity\n\tstore.angularVelocity.x = 0;\n\tstore.angularVelocity.y = 0;\n\tstore.angularVelocity.z = 0;\n\n\t// Reset per-source velocity intents\n\tfor (const sourceId of Object.keys(store.velocityChannels)) {\n\t\tdelete store.velocityChannels[sourceId];\n\t}\n\n\t// Clear all dirty flags\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.velocityX = false;\n\tstore.dirty.velocityY = false;\n\tstore.dirty.velocityZ = false;\n\tstore.dirty.velocityChannels = false;\n\tstore.dirty.angularVelocity = false;\n}\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\nimport { setVelocityIntent } from './velocity-intents';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { x: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { y: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { z: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, y: deltaY },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, z: deltaZ },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: vector.x, y: vector.y, z: vector.z },\n\t\t{ mode: 'add' },\n\t);\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","import type {\n\tBehaviorDescriptor,\n\tBehaviorHandle,\n\tBehaviorRef,\n} from '../behaviors/behavior-descriptor';\n\n/**\n * Minimal, runtime-agnostic entity options contract.\n *\n * The full engine entity (in `@zylem/game-lib`) provides a richer options type,\n * but behaviors only rely on this loose shape.\n */\nexport interface GameEntityOptions {\n\t[key: string]: any;\n\tname?: string;\n}\n\n/**\n * Structural stand-in for the engine `GameEntity`.\n *\n * Behaviors annotate against this loose contract so that `@zylem/behaviors`\n * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete\n * `@zylem/game-lib` entity implementation. The real engine entity is\n * structurally assignable to this type.\n */\nexport class GameEntity<TOptions = unknown> {\n\t[key: string]: any;\n\n\tuuid!: string;\n\tname!: string;\n\ttype!: string;\n\toptions?: TOptions & Record<string, unknown>;\n\tgroup: any = null;\n\tmesh?: any;\n\tmaterials?: any[];\n\tbody: any = null;\n\tcollider: any = null;\n\tcolliderDesc?: any;\n\tcolliderDescs: any[] = [];\n\tbodyDesc?: any;\n\tphysicsAttached = false;\n\truntimeHandle?: number;\n\ttransformStore?: any;\n\tnodeDestroy?: any;\n\tisInstanced?: boolean;\n\n\tprivate __behaviorRefs: BehaviorRef<any>[] = [];\n\n\tcreate(): this {\n\t\treturn this;\n\t}\n\n\tonCleanup(callback: () => void): this {\n\t\tvoid callback;\n\t\treturn this;\n\t}\n\n\tsetPosition(_x: number, _y: number, _z: number): void {}\n\tsetRotation(_x: number, _y: number, _z: number): void {}\n\tsetRotationZ(_z: number): void {}\n\tsetScale(_x: number, _y: number, _z: number): void {}\n\n\t/**\n\t * Attach a behavior to this entity. The real engine entity does substantially\n\t * more, but this functional stub stores the merged ref and builds the handle\n\t * so descriptor/handle logic (and tests that drive behaviors directly) work\n\t * without the full engine.\n\t */\n\tuse<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst mergedOptions = {\n\t\t\t...(descriptor.defaultOptions as O),\n\t\t\t...(options ?? {}),\n\t\t} as O;\n\t\tconst ref: BehaviorRef<O> = { descriptor, options: mergedOptions };\n\t\tthis.__behaviorRefs.push(ref as BehaviorRef<any>);\n\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => ref.fsm ?? null,\n\t\t\tgetOptions: () => ref.options,\n\t\t\tref,\n\t\t};\n\t\tconst extra = descriptor.createHandle\n\t\t\t? descriptor.createHandle(ref)\n\t\t\t: ({} as H);\n\t\treturn { ...baseHandle, ...extra } as BehaviorHandle<O, H>;\n\t}\n\n\t/** Live behavior refs attached via {@link use}. */\n\tgetBehaviorRefs(): BehaviorRef<any>[] {\n\t\treturn this.__behaviorRefs;\n\t}\n}\n\n/**\n * Factory contract injected into behavior systems via\n * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real\n * entity factory at stage-construction time.\n */\nexport type CreateEntityFn = (\n\toptions?: Partial<GameEntityOptions>,\n) => GameEntity<GameEntityOptions>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/capabilities/transform-store.ts","../src/lib/capabilities/moveable.ts","../src/lib/entities/entity.ts"],"sourcesContent":["import { proxy } from 'valtio';\n\nexport type VelocityIntentMode = 'replace' | 'add';\n\nexport interface VelocityIntent {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\tmode: VelocityIntentMode;\n\tpriority?: number;\n}\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\n\t/** Per-source velocity intents composed once per frame */\n\tvelocityChannels: Record<string, VelocityIntent>;\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocityX: boolean;\n\t\tvelocityY: boolean;\n\t\tvelocityZ: boolean;\n\t\tvelocityChannels: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tvelocityChannels: {},\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocityX: false,\n\t\t\tvelocityY: false,\n\t\t\tvelocityZ: false,\n\t\t\tvelocityChannels: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\nimport { setVelocityIntent } from './velocity-intents';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { x: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { y: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { z: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, y: deltaY },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, z: deltaZ },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: vector.x, y: vector.y, z: vector.z },\n\t\t{ mode: 'add' },\n\t);\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","import type { Collider, RigidBody } from '@dimforge/rapier3d-compat';\nimport type {\n\tBehaviorDescriptor,\n\tBehaviorHandle,\n\tBehaviorRef,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../capabilities/transform-store';\n\n/**\n * Minimal, runtime-agnostic entity options contract.\n *\n * The full engine entity (in `@zylem/game-lib`) provides a richer options type,\n * but behaviors only rely on this loose shape.\n */\nexport interface GameEntityOptions {\n\t[key: string]: any;\n\tname?: string;\n}\n\n/**\n * Structural stand-in for the engine `GameEntity`.\n *\n * Behaviors annotate against this loose contract so that `@zylem/behaviors`\n * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete\n * `@zylem/game-lib` entity implementation. The real engine entity is\n * structurally assignable to this type.\n */\nexport class GameEntity<TOptions = unknown> {\n\t[key: string]: any;\n\n\tuuid!: string;\n\tname!: string;\n\ttype!: string;\n\toptions?: TOptions & Record<string, unknown>;\n\tgroup: any = null;\n\tmesh?: any;\n\tmaterials?: any[];\n\tbody: RigidBody | null = null;\n\tcollider: Collider | null = null;\n\tcolliderDesc?: any;\n\tcolliderDescs: any[] = [];\n\tbodyDesc?: any;\n\tphysicsAttached = false;\n\truntimeHandle?: number;\n\ttransformStore?: TransformState;\n\tnodeDestroy?: any;\n\tisInstanced?: boolean;\n\n\tprivate __behaviorRefs: BehaviorRef<any>[] = [];\n\n\tcreate(): this {\n\t\treturn this;\n\t}\n\n\tonCleanup(callback: () => void): this {\n\t\tvoid callback;\n\t\treturn this;\n\t}\n\n\tsetPosition(_x: number, _y: number, _z: number): void {}\n\tsetRotation(_x: number, _y: number, _z: number): void {}\n\tsetRotationZ(_z: number): void {}\n\tsetScale(_x: number, _y: number, _z: number): void {}\n\n\t/**\n\t * Attach a behavior to this entity. The real engine entity does substantially\n\t * more, but this functional stub stores the merged ref and builds the handle\n\t * so descriptor/handle logic (and tests that drive behaviors directly) work\n\t * without the full engine.\n\t */\n\tuse<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst mergedOptions = {\n\t\t\t...(descriptor.defaultOptions as O),\n\t\t\t...(options ?? {}),\n\t\t} as O;\n\t\tconst ref: BehaviorRef<O> = { descriptor, options: mergedOptions };\n\t\tthis.__behaviorRefs.push(ref as BehaviorRef<any>);\n\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => ref.fsm ?? null,\n\t\t\tgetOptions: () => ref.options,\n\t\t\tref,\n\t\t};\n\t\tconst extra = descriptor.createHandle\n\t\t\t? descriptor.createHandle(ref)\n\t\t\t: ({} as H);\n\t\treturn { ...baseHandle, ...extra } as BehaviorHandle<O, H>;\n\t}\n\n\t/** Live behavior refs attached via {@link use}. */\n\tgetBehaviorRefs(): BehaviorRef<any>[] {\n\t\treturn this.__behaviorRefs;\n\t}\n}\n\n/**\n * Factory contract injected into behavior systems via\n * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real\n * entity factory at stage-construction time.\n */\nexport type CreateEntityFn = (\n\toptions?: Partial<GameEntityOptions>,\n) => GameEntity<GameEntityOptions>;\n"],"mappings":"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","names":[]}
@@ -1,8 +1,9 @@
1
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
1
+ import { a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
2
2
  import { Material } from 'three';
3
3
  import { FractureOptions, DestructibleMesh } from '@dgreenheck/three-pinata';
4
4
  export { DestructibleMesh, FractureOptions, VoronoiOptions } from '@dgreenheck/three-pinata';
5
5
  export { D as DestructiblePrebakeWorkerAPI, P as PlainBufferGeometryPayload, a as PlainFractureOptions, c as PrebakeWorkerRequest, d as PrebakeWorkerResponse } from './payload-BQzu-oY_.js';
6
+ import '@dimforge/rapier3d-compat';
6
7
 
7
8
  type FractureOptionsInput = NonNullable<ConstructorParameters<typeof FractureOptions>[0]>;
8
9
  type Destructible3DFragmentColliderShape = 'convexHull' | 'cuboid' | 'trimesh';
@@ -2,11 +2,11 @@ import { F as FirstPersonInputComponent, b as FirstPersonStateComponent, a as Fi
2
2
  export { c as createFirstPersonInputComponent, d as createFirstPersonMovementComponent, e as createFirstPersonStateComponent } from './components-qWwOsvwh.js';
3
3
  import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
4
4
  import { Vector3, Euler } from 'three';
5
+ import { RigidBody } from '@dimforge/rapier3d-compat';
5
6
  import { F as FirstPersonPerspective } from './first-person-perspective-C9Mptl0-.js';
6
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
7
+ import { T as TransformState, Z as ZylemWorld, a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
7
8
  import { i as Vec3Input } from './vector-Bm65-FOG.js';
8
9
  import 'typescript-fsm';
9
- import '@dimforge/rapier3d-compat';
10
10
 
11
11
  /**
12
12
  * First Person Controller Finite State Machine
@@ -89,8 +89,8 @@ interface ViewmodelConfig {
89
89
  */
90
90
  interface FirstPersonEntity {
91
91
  uuid: string;
92
- body: any;
93
- transformStore: any;
92
+ body: RigidBody | null;
93
+ transformStore: TransformState;
94
94
  firstPerson: FirstPersonMovementComponent;
95
95
  $fps: FirstPersonInputComponent;
96
96
  firstPersonState: FirstPersonStateComponent;
@@ -101,11 +101,11 @@ interface FirstPersonEntity {
101
101
  * Core movement + look system for first-person cameras.
102
102
  * Reads from entity.$fps input component and drives a FirstPersonPerspective.
103
103
  */
104
- declare class FirstPersonControllerBehavior {
104
+ declare class FirstPersonSystem {
105
105
  private world;
106
106
  private perspectives;
107
107
  private viewmodels;
108
- constructor(world: any);
108
+ constructor(world: ZylemWorld | null);
109
109
  /**
110
110
  * Associate a FirstPersonPerspective with an entity (by uuid).
111
111
  * Called once by the descriptor system when the behavior is initialized.
@@ -140,7 +140,7 @@ declare class FirstPersonControllerBehavior {
140
140
  /**
141
141
  * First-person controller behavior options (typed for entity.use() autocomplete).
142
142
  */
143
- interface FirstPersonControllerOptions {
143
+ interface FirstPersonBehaviorOptions {
144
144
  /** Base walking speed (default: 8) */
145
145
  walkSpeed?: number;
146
146
  /** Sprint/run speed (default: 16) */
@@ -159,7 +159,7 @@ interface FirstPersonControllerOptions {
159
159
  };
160
160
  }
161
161
  /**
162
- * FirstPersonController - typed descriptor for first-person movement and camera control.
162
+ * FirstPersonBehavior - typed descriptor for first-person movement and camera control.
163
163
  *
164
164
  * Provides complete first-person controller including:
165
165
  * - WASD movement relative to camera yaw
@@ -169,7 +169,7 @@ interface FirstPersonControllerOptions {
169
169
  *
170
170
  * @example
171
171
  * ```typescript
172
- * import { FirstPersonController } from "@zylem/game-lib/behavior";
172
+ * import { FirstPersonBehavior } from "@zylem/game-lib/behavior";
173
173
  * import { createCamera, Perspectives, FirstPersonPerspective } from "@zylem/game-lib/core";
174
174
  * import { createActor } from "@zylem/game-lib/entity";
175
175
  *
@@ -177,7 +177,7 @@ interface FirstPersonControllerOptions {
177
177
  * const fps = fpsCamera.getPerspective<FirstPersonPerspective>();
178
178
  *
179
179
  * const player = createActor({ name: 'player', ... });
180
- * const controller = player.use(FirstPersonController, {
180
+ * const controller = player.use(FirstPersonBehavior, {
181
181
  * perspective: fps,
182
182
  * walkSpeed: 8,
183
183
  * runSpeed: 16,
@@ -194,11 +194,11 @@ interface FirstPersonControllerOptions {
194
194
  * });
195
195
  * ```
196
196
  */
197
- declare const FirstPersonController: BehaviorDescriptor<FirstPersonControllerOptions, {
197
+ declare const FirstPersonBehavior: BehaviorDescriptor<FirstPersonBehaviorOptions, {
198
198
  getState: () => FirstPersonState;
199
199
  getYaw: () => number;
200
200
  getPitch: () => number;
201
201
  attachViewmodel: (entity: any, offset: Vec3Input) => void;
202
202
  }, FirstPersonEntity>;
203
203
 
204
- export { type FirstPersonContext, FirstPersonController, FirstPersonControllerBehavior, type FirstPersonControllerOptions, type FirstPersonEntity, FirstPersonEvent, FirstPersonFSM, FirstPersonInputComponent, FirstPersonMovementComponent, FirstPersonState, FirstPersonStateComponent, type ViewmodelConfig };
204
+ export { FirstPersonBehavior, type FirstPersonBehaviorOptions, type FirstPersonContext, type FirstPersonEntity, FirstPersonEvent, FirstPersonFSM, FirstPersonInputComponent, FirstPersonMovementComponent, FirstPersonState, FirstPersonStateComponent, FirstPersonSystem, type ViewmodelConfig };
@@ -1,25 +1,25 @@
1
1
  import {
2
- FirstPersonController,
3
- FirstPersonControllerBehavior,
2
+ FirstPersonBehavior,
4
3
  FirstPersonEvent,
5
4
  FirstPersonFSM,
6
- FirstPersonState
7
- } from "./chunk-YUO6SKJD.js";
5
+ FirstPersonState,
6
+ FirstPersonSystem
7
+ } from "./chunk-WXXXJ22R.js";
8
8
  import {
9
9
  createFirstPersonInputComponent,
10
10
  createFirstPersonMovementComponent,
11
11
  createFirstPersonStateComponent
12
- } from "./chunk-LD5SMIB3.js";
12
+ } from "./chunk-QVCMJ4Q2.js";
13
13
  import "./chunk-WWVD5DR5.js";
14
- import "./chunk-RTVRUNYR.js";
14
+ import "./chunk-OTLSUYQQ.js";
15
15
  import "./chunk-4URF65BR.js";
16
16
  import "./chunk-EZNCCO4L.js";
17
17
  export {
18
- FirstPersonController,
19
- FirstPersonControllerBehavior,
18
+ FirstPersonBehavior,
20
19
  FirstPersonEvent,
21
20
  FirstPersonFSM,
22
21
  FirstPersonState,
22
+ FirstPersonSystem,
23
23
  createFirstPersonInputComponent,
24
24
  createFirstPersonMovementComponent,
25
25
  createFirstPersonStateComponent