@sadhaka/loom-engine 0.10.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +344 -0
  3. package/dist/animation/animation-clip.d.ts +12 -0
  4. package/dist/animation/animation-clip.d.ts.map +1 -0
  5. package/dist/animation/animation-clip.js +85 -0
  6. package/dist/animation/animation-clip.js.map +1 -0
  7. package/dist/animation/animation-state-pool.d.ts +25 -0
  8. package/dist/animation/animation-state-pool.d.ts.map +1 -0
  9. package/dist/animation/animation-state-pool.js +113 -0
  10. package/dist/animation/animation-state-pool.js.map +1 -0
  11. package/dist/asset/sprite-sheet-loader.d.ts +41 -0
  12. package/dist/asset/sprite-sheet-loader.d.ts.map +1 -0
  13. package/dist/asset/sprite-sheet-loader.js +313 -0
  14. package/dist/asset/sprite-sheet-loader.js.map +1 -0
  15. package/dist/audio/audio-bus.d.ts +43 -0
  16. package/dist/audio/audio-bus.d.ts.map +1 -0
  17. package/dist/audio/audio-bus.js +258 -0
  18. package/dist/audio/audio-bus.js.map +1 -0
  19. package/dist/combat/mob-catalog.d.ts +29 -0
  20. package/dist/combat/mob-catalog.d.ts.map +1 -0
  21. package/dist/combat/mob-catalog.js +104 -0
  22. package/dist/combat/mob-catalog.js.map +1 -0
  23. package/dist/components/health.d.ts +28 -0
  24. package/dist/components/health.d.ts.map +1 -0
  25. package/dist/components/health.js +150 -0
  26. package/dist/components/health.js.map +1 -0
  27. package/dist/components/interactable.d.ts +30 -0
  28. package/dist/components/interactable.d.ts.map +1 -0
  29. package/dist/components/interactable.js +94 -0
  30. package/dist/components/interactable.js.map +1 -0
  31. package/dist/components/particle-emitter.d.ts +62 -0
  32. package/dist/components/particle-emitter.d.ts.map +1 -0
  33. package/dist/components/particle-emitter.js +193 -0
  34. package/dist/components/particle-emitter.js.map +1 -0
  35. package/dist/components/pursue.d.ts +23 -0
  36. package/dist/components/pursue.d.ts.map +1 -0
  37. package/dist/components/pursue.js +96 -0
  38. package/dist/components/pursue.js.map +1 -0
  39. package/dist/components/ranged-attack.d.ts +44 -0
  40. package/dist/components/ranged-attack.d.ts.map +1 -0
  41. package/dist/components/ranged-attack.js +120 -0
  42. package/dist/components/ranged-attack.js.map +1 -0
  43. package/dist/components/sprite.d.ts +27 -0
  44. package/dist/components/sprite.d.ts.map +1 -0
  45. package/dist/components/sprite.js +122 -0
  46. package/dist/components/sprite.js.map +1 -0
  47. package/dist/components/transform.d.ts +30 -0
  48. package/dist/components/transform.d.ts.map +1 -0
  49. package/dist/components/transform.js +150 -0
  50. package/dist/components/transform.js.map +1 -0
  51. package/dist/director/director-bridge.d.ts +22 -0
  52. package/dist/director/director-bridge.d.ts.map +1 -0
  53. package/dist/director/director-bridge.js +23 -0
  54. package/dist/director/director-bridge.js.map +1 -0
  55. package/dist/director/director-encounter-system.d.ts +21 -0
  56. package/dist/director/director-encounter-system.d.ts.map +1 -0
  57. package/dist/director/director-encounter-system.js +128 -0
  58. package/dist/director/director-encounter-system.js.map +1 -0
  59. package/dist/director/director-system.d.ts +19 -0
  60. package/dist/director/director-system.d.ts.map +1 -0
  61. package/dist/director/director-system.js +179 -0
  62. package/dist/director/director-system.js.map +1 -0
  63. package/dist/director/event-envelope.d.ts +144 -0
  64. package/dist/director/event-envelope.d.ts.map +1 -0
  65. package/dist/director/event-envelope.js +108 -0
  66. package/dist/director/event-envelope.js.map +1 -0
  67. package/dist/director/knot-context-resource.d.ts +25 -0
  68. package/dist/director/knot-context-resource.d.ts.map +1 -0
  69. package/dist/director/knot-context-resource.js +152 -0
  70. package/dist/director/knot-context-resource.js.map +1 -0
  71. package/dist/director/mock-director-bridge.d.ts +18 -0
  72. package/dist/director/mock-director-bridge.d.ts.map +1 -0
  73. package/dist/director/mock-director-bridge.js +75 -0
  74. package/dist/director/mock-director-bridge.js.map +1 -0
  75. package/dist/director/snapshot-recovery.d.ts +37 -0
  76. package/dist/director/snapshot-recovery.d.ts.map +1 -0
  77. package/dist/director/snapshot-recovery.js +180 -0
  78. package/dist/director/snapshot-recovery.js.map +1 -0
  79. package/dist/director/sse-director-bridge.d.ts +42 -0
  80. package/dist/director/sse-director-bridge.d.ts.map +1 -0
  81. package/dist/director/sse-director-bridge.js +280 -0
  82. package/dist/director/sse-director-bridge.js.map +1 -0
  83. package/dist/engine.d.ts +25 -0
  84. package/dist/engine.d.ts.map +1 -0
  85. package/dist/engine.js +166 -0
  86. package/dist/engine.js.map +1 -0
  87. package/dist/entity.d.ts +17 -0
  88. package/dist/entity.d.ts.map +1 -0
  89. package/dist/entity.js +77 -0
  90. package/dist/entity.js.map +1 -0
  91. package/dist/index.d.ts +85 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +64 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/input/input-manager.d.ts +91 -0
  96. package/dist/input/input-manager.d.ts.map +1 -0
  97. package/dist/input/input-manager.js +349 -0
  98. package/dist/input/input-manager.js.map +1 -0
  99. package/dist/input/tap-to-walk.d.ts +27 -0
  100. package/dist/input/tap-to-walk.d.ts.map +1 -0
  101. package/dist/input/tap-to-walk.js +118 -0
  102. package/dist/input/tap-to-walk.js.map +1 -0
  103. package/dist/input/virtual-dpad.d.ts +34 -0
  104. package/dist/input/virtual-dpad.d.ts.map +1 -0
  105. package/dist/input/virtual-dpad.js +267 -0
  106. package/dist/input/virtual-dpad.js.map +1 -0
  107. package/dist/renderer/camera.d.ts +26 -0
  108. package/dist/renderer/camera.d.ts.map +1 -0
  109. package/dist/renderer/camera.js +39 -0
  110. package/dist/renderer/camera.js.map +1 -0
  111. package/dist/renderer/canvas2d-device.d.ts +26 -0
  112. package/dist/renderer/canvas2d-device.d.ts.map +1 -0
  113. package/dist/renderer/canvas2d-device.js +252 -0
  114. package/dist/renderer/canvas2d-device.js.map +1 -0
  115. package/dist/renderer/graphics-device.d.ts +36 -0
  116. package/dist/renderer/graphics-device.d.ts.map +1 -0
  117. package/dist/renderer/graphics-device.js +12 -0
  118. package/dist/renderer/graphics-device.js.map +1 -0
  119. package/dist/renderer/iso-projection.d.ts +11 -0
  120. package/dist/renderer/iso-projection.d.ts.map +1 -0
  121. package/dist/renderer/iso-projection.js +59 -0
  122. package/dist/renderer/iso-projection.js.map +1 -0
  123. package/dist/resources.d.ts +28 -0
  124. package/dist/resources.d.ts.map +1 -0
  125. package/dist/resources.js +53 -0
  126. package/dist/resources.js.map +1 -0
  127. package/dist/system.d.ts +14 -0
  128. package/dist/system.d.ts.map +1 -0
  129. package/dist/system.js +25 -0
  130. package/dist/system.js.map +1 -0
  131. package/dist/systems/animation-system.d.ts +8 -0
  132. package/dist/systems/animation-system.d.ts.map +1 -0
  133. package/dist/systems/animation-system.js +77 -0
  134. package/dist/systems/animation-system.js.map +1 -0
  135. package/dist/systems/attack-system.d.ts +17 -0
  136. package/dist/systems/attack-system.d.ts.map +1 -0
  137. package/dist/systems/attack-system.js +94 -0
  138. package/dist/systems/attack-system.js.map +1 -0
  139. package/dist/systems/damage-system.d.ts +18 -0
  140. package/dist/systems/damage-system.d.ts.map +1 -0
  141. package/dist/systems/damage-system.js +77 -0
  142. package/dist/systems/damage-system.js.map +1 -0
  143. package/dist/systems/input-system.d.ts +7 -0
  144. package/dist/systems/input-system.d.ts.map +1 -0
  145. package/dist/systems/input-system.js +27 -0
  146. package/dist/systems/input-system.js.map +1 -0
  147. package/dist/systems/interaction-system.d.ts +23 -0
  148. package/dist/systems/interaction-system.d.ts.map +1 -0
  149. package/dist/systems/interaction-system.js +120 -0
  150. package/dist/systems/interaction-system.js.map +1 -0
  151. package/dist/systems/particle-emitter-system.d.ts +8 -0
  152. package/dist/systems/particle-emitter-system.d.ts.map +1 -0
  153. package/dist/systems/particle-emitter-system.js +161 -0
  154. package/dist/systems/particle-emitter-system.js.map +1 -0
  155. package/dist/systems/particle-render-system.d.ts +7 -0
  156. package/dist/systems/particle-render-system.d.ts.map +1 -0
  157. package/dist/systems/particle-render-system.js +53 -0
  158. package/dist/systems/particle-render-system.js.map +1 -0
  159. package/dist/systems/particle-simulation-system.d.ts +8 -0
  160. package/dist/systems/particle-simulation-system.d.ts.map +1 -0
  161. package/dist/systems/particle-simulation-system.js +45 -0
  162. package/dist/systems/particle-simulation-system.js.map +1 -0
  163. package/dist/systems/projectile-render-system.d.ts +7 -0
  164. package/dist/systems/projectile-render-system.d.ts.map +1 -0
  165. package/dist/systems/projectile-render-system.js +35 -0
  166. package/dist/systems/projectile-render-system.js.map +1 -0
  167. package/dist/systems/projectile-system.d.ts +7 -0
  168. package/dist/systems/projectile-system.d.ts.map +1 -0
  169. package/dist/systems/projectile-system.js +114 -0
  170. package/dist/systems/projectile-system.js.map +1 -0
  171. package/dist/systems/pursue-system.d.ts +7 -0
  172. package/dist/systems/pursue-system.d.ts.map +1 -0
  173. package/dist/systems/pursue-system.js +83 -0
  174. package/dist/systems/pursue-system.js.map +1 -0
  175. package/dist/systems/ranged-attack-system.d.ts +7 -0
  176. package/dist/systems/ranged-attack-system.d.ts.map +1 -0
  177. package/dist/systems/ranged-attack-system.js +98 -0
  178. package/dist/systems/ranged-attack-system.js.map +1 -0
  179. package/dist/systems/sprite-render-system.d.ts +9 -0
  180. package/dist/systems/sprite-render-system.d.ts.map +1 -0
  181. package/dist/systems/sprite-render-system.js +108 -0
  182. package/dist/systems/sprite-render-system.js.map +1 -0
  183. package/dist/systems/veil-budget-system.d.ts +7 -0
  184. package/dist/systems/veil-budget-system.d.ts.map +1 -0
  185. package/dist/systems/veil-budget-system.js +37 -0
  186. package/dist/systems/veil-budget-system.js.map +1 -0
  187. package/dist/util/color.d.ts +19 -0
  188. package/dist/util/color.d.ts.map +1 -0
  189. package/dist/util/color.js +45 -0
  190. package/dist/util/color.js.map +1 -0
  191. package/dist/util/math.d.ts +26 -0
  192. package/dist/util/math.d.ts.map +1 -0
  193. package/dist/util/math.js +47 -0
  194. package/dist/util/math.js.map +1 -0
  195. package/dist/util/typed-arrays.d.ts +7 -0
  196. package/dist/util/typed-arrays.d.ts.map +1 -0
  197. package/dist/util/typed-arrays.js +42 -0
  198. package/dist/util/typed-arrays.js.map +1 -0
  199. package/dist/vfx/particle-pool.d.ts +61 -0
  200. package/dist/vfx/particle-pool.d.ts.map +1 -0
  201. package/dist/vfx/particle-pool.js +204 -0
  202. package/dist/vfx/particle-pool.js.map +1 -0
  203. package/dist/vfx/projectile-pool.d.ts +56 -0
  204. package/dist/vfx/projectile-pool.d.ts.map +1 -0
  205. package/dist/vfx/projectile-pool.js +157 -0
  206. package/dist/vfx/projectile-pool.js.map +1 -0
  207. package/dist/world.d.ts +23 -0
  208. package/dist/world.d.ts.map +1 -0
  209. package/dist/world.js +101 -0
  210. package/dist/world.js.map +1 -0
  211. package/dist/zone/zone-catalog.d.ts +17 -0
  212. package/dist/zone/zone-catalog.d.ts.map +1 -0
  213. package/dist/zone/zone-catalog.js +116 -0
  214. package/dist/zone/zone-catalog.js.map +1 -0
  215. package/dist/zone/zone-state.d.ts +18 -0
  216. package/dist/zone/zone-state.d.ts.map +1 -0
  217. package/dist/zone/zone-state.js +52 -0
  218. package/dist/zone/zone-state.js.map +1 -0
  219. package/package.json +56 -0
@@ -0,0 +1,193 @@
1
+ // ParticleEmitterPool - per-entity emitter configuration.
2
+ //
3
+ // An ECS entity that has a Transform AND a ParticleEmitter spawns
4
+ // particles into a shared ParticlePool each tick. The emitter is
5
+ // configuration only; the actual spawn happens in
6
+ // ParticleEmitterSystem (LOGIC phase).
7
+ //
8
+ // SoA layout consistent with Transform / Sprite. Numeric fields hot
9
+ // in Float32Arrays; the start/end color tuples are split into
10
+ // parallel arrays so every per-tick read stays in cache.
11
+ import { entityIndex } from '../entity.js';
12
+ import { growF32, growU8, nextPow2 } from '../util/typed-arrays.js';
13
+ export const EMITTER_FLAG_ACTIVE = 1 << 0;
14
+ export const EMITTER_FLAG_ADDITIVE = 1 << 1;
15
+ export class ParticleEmitterPool {
16
+ // Continuous spawn rate (per second).
17
+ rate;
18
+ // Carryover seconds from the last tick (rate < 1/dt scenarios).
19
+ spawnCarry;
20
+ // One-shot burst counter. EmitterSystem decrements this by what it
21
+ // spawns each tick until zero.
22
+ burstRemaining;
23
+ // Per-particle life on spawn.
24
+ particleLife;
25
+ // Speed range
26
+ speedMin;
27
+ speedMax;
28
+ // Cone direction + half-angle
29
+ dirX;
30
+ dirY;
31
+ dirZ;
32
+ coneRadians;
33
+ // Per-particle acceleration
34
+ ax;
35
+ ay;
36
+ az;
37
+ // Visual
38
+ startSize;
39
+ endSize;
40
+ startR;
41
+ startG;
42
+ startB;
43
+ startA;
44
+ endR;
45
+ endG;
46
+ endB;
47
+ endA;
48
+ flags;
49
+ capacity = 0;
50
+ highWaterMark = 0;
51
+ constructor(initialCapacity = 32) {
52
+ this.capacity = nextPow2(initialCapacity);
53
+ const c = this.capacity;
54
+ this.rate = new Float32Array(c);
55
+ this.spawnCarry = new Float32Array(c);
56
+ this.burstRemaining = new Int32Array(c);
57
+ this.particleLife = new Float32Array(c);
58
+ this.speedMin = new Float32Array(c);
59
+ this.speedMax = new Float32Array(c);
60
+ this.dirX = new Float32Array(c);
61
+ this.dirY = new Float32Array(c);
62
+ this.dirZ = new Float32Array(c);
63
+ this.coneRadians = new Float32Array(c);
64
+ this.ax = new Float32Array(c);
65
+ this.ay = new Float32Array(c);
66
+ this.az = new Float32Array(c);
67
+ this.startSize = new Float32Array(c);
68
+ this.endSize = new Float32Array(c);
69
+ this.startR = new Float32Array(c);
70
+ this.startG = new Float32Array(c);
71
+ this.startB = new Float32Array(c);
72
+ this.startA = new Float32Array(c);
73
+ this.endR = new Float32Array(c);
74
+ this.endG = new Float32Array(c);
75
+ this.endB = new Float32Array(c);
76
+ this.endA = new Float32Array(c);
77
+ this.flags = new Uint8Array(c);
78
+ }
79
+ ensureCapacity(neededIndex) {
80
+ if (neededIndex < this.capacity)
81
+ return;
82
+ const next = nextPow2(neededIndex + 1);
83
+ this.rate = growF32(this.rate, next);
84
+ this.spawnCarry = growF32(this.spawnCarry, next);
85
+ const newBurst = new Int32Array(next);
86
+ newBurst.set(this.burstRemaining);
87
+ this.burstRemaining = newBurst;
88
+ this.particleLife = growF32(this.particleLife, next);
89
+ this.speedMin = growF32(this.speedMin, next);
90
+ this.speedMax = growF32(this.speedMax, next);
91
+ this.dirX = growF32(this.dirX, next);
92
+ this.dirY = growF32(this.dirY, next);
93
+ this.dirZ = growF32(this.dirZ, next);
94
+ this.coneRadians = growF32(this.coneRadians, next);
95
+ this.ax = growF32(this.ax, next);
96
+ this.ay = growF32(this.ay, next);
97
+ this.az = growF32(this.az, next);
98
+ this.startSize = growF32(this.startSize, next);
99
+ this.endSize = growF32(this.endSize, next);
100
+ this.startR = growF32(this.startR, next);
101
+ this.startG = growF32(this.startG, next);
102
+ this.startB = growF32(this.startB, next);
103
+ this.startA = growF32(this.startA, next);
104
+ this.endR = growF32(this.endR, next);
105
+ this.endG = growF32(this.endG, next);
106
+ this.endB = growF32(this.endB, next);
107
+ this.endA = growF32(this.endA, next);
108
+ this.flags = growU8(this.flags, next);
109
+ this.capacity = next;
110
+ }
111
+ attach(e, cfg) {
112
+ const i = entityIndex(e);
113
+ this.ensureCapacity(i);
114
+ this.rate[i] = cfg.rate;
115
+ this.spawnCarry[i] = 0;
116
+ this.burstRemaining[i] = 0;
117
+ this.particleLife[i] = cfg.particleLife;
118
+ this.speedMin[i] = cfg.speedMin;
119
+ this.speedMax[i] = cfg.speedMax;
120
+ this.dirX[i] = cfg.dirX;
121
+ this.dirY[i] = cfg.dirY;
122
+ this.dirZ[i] = cfg.dirZ;
123
+ this.coneRadians[i] = cfg.coneRadians;
124
+ this.ax[i] = cfg.ax;
125
+ this.ay[i] = cfg.ay;
126
+ this.az[i] = cfg.az;
127
+ this.startSize[i] = cfg.startSize;
128
+ this.endSize[i] = cfg.endSize;
129
+ this.startR[i] = cfg.startColor.r;
130
+ this.startG[i] = cfg.startColor.g;
131
+ this.startB[i] = cfg.startColor.b;
132
+ this.startA[i] = cfg.startColor.a;
133
+ this.endR[i] = cfg.endColor.r;
134
+ this.endG[i] = cfg.endColor.g;
135
+ this.endB[i] = cfg.endColor.b;
136
+ this.endA[i] = cfg.endColor.a;
137
+ let f = EMITTER_FLAG_ACTIVE;
138
+ if (cfg.additive)
139
+ f |= EMITTER_FLAG_ADDITIVE;
140
+ this.flags[i] = f;
141
+ if (i >= this.highWaterMark)
142
+ this.highWaterMark = i + 1;
143
+ }
144
+ detach(e) {
145
+ const i = entityIndex(e);
146
+ if (i >= this.capacity)
147
+ return;
148
+ this.flags[i] = 0;
149
+ this.rate[i] = 0;
150
+ this.burstRemaining[i] = 0;
151
+ }
152
+ setActive(e, active) {
153
+ const i = entityIndex(e);
154
+ if (i >= this.capacity)
155
+ return;
156
+ const f = this.flags[i] ?? 0;
157
+ this.flags[i] = active ? f | EMITTER_FLAG_ACTIVE : f & ~EMITTER_FLAG_ACTIVE;
158
+ }
159
+ setRate(e, rate) {
160
+ const i = entityIndex(e);
161
+ if (i >= this.capacity)
162
+ return;
163
+ this.rate[i] = rate;
164
+ }
165
+ // Schedule a one-shot burst to be emitted on the next system tick.
166
+ // Adds to any existing pending burst; useful for multi-trigger
167
+ // hits (e.g. successive sword strikes spawning more sparks).
168
+ burst(e, count) {
169
+ const i = entityIndex(e);
170
+ if (i >= this.capacity)
171
+ return;
172
+ this.burstRemaining[i] = (this.burstRemaining[i] ?? 0) + count;
173
+ }
174
+ isActive(e) {
175
+ const i = entityIndex(e);
176
+ if (i >= this.capacity)
177
+ return false;
178
+ return ((this.flags[i] ?? 0) & EMITTER_FLAG_ACTIVE) !== 0;
179
+ }
180
+ isAdditive(e) {
181
+ const i = entityIndex(e);
182
+ if (i >= this.capacity)
183
+ return false;
184
+ return ((this.flags[i] ?? 0) & EMITTER_FLAG_ADDITIVE) !== 0;
185
+ }
186
+ getHighWaterMark() {
187
+ return this.highWaterMark;
188
+ }
189
+ getCapacity() {
190
+ return this.capacity;
191
+ }
192
+ }
193
+ //# sourceMappingURL=particle-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle-emitter.js","sourceRoot":"","sources":["../../src/components/particle-emitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type EntityId } from '../entity.js';
2
+ export declare const PURSUE_FLAG_ACTIVE: number;
3
+ export declare class PursuePool {
4
+ speed: Float32Array;
5
+ stopDistance: Float32Array;
6
+ targetIndex: Int32Array;
7
+ contactDamage: Float32Array;
8
+ contactCooldownMs: Float32Array;
9
+ lastHitMs: Float32Array;
10
+ flags: Uint8Array;
11
+ private capacity;
12
+ private highWaterMark;
13
+ constructor(initialCapacity?: number);
14
+ ensureCapacity(neededIndex: number): void;
15
+ attach(e: EntityId, target: EntityId, speed: number, stopDistance: number, contactDamage?: number, contactCooldownMs?: number): void;
16
+ detach(e: EntityId): void;
17
+ setTarget(e: EntityId, target: EntityId): void;
18
+ isActive(e: EntityId): boolean;
19
+ getHighWaterMark(): number;
20
+ getCapacity(): number;
21
+ }
22
+ export declare const POOL_PURSUE = "pursue";
23
+ //# sourceMappingURL=pursue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pursue.d.ts","sourceRoot":"","sources":["../../src/components/pursue.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAG1D,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,qBAAa,UAAU;IAErB,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,UAAU,CAAC;IAIxB,aAAa,EAAE,YAAY,CAAC;IAC5B,iBAAiB,EAAE,YAAY,CAAC;IAChC,SAAS,EAAE,YAAY,CAAC;IAExB,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;gBAEtB,eAAe,GAAE,MAAW;IAWxC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAezC,MAAM,CACJ,CAAC,EAAE,QAAQ,EACX,MAAM,EAAE,QAAQ,EAChB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,aAAa,GAAE,MAAU,EACzB,iBAAiB,GAAE,MAAa,GAC/B,IAAI;IAaP,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAOzB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI;IAM9C,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM9B,gBAAgB,IAAI,MAAM;IAI1B,WAAW,IAAI,MAAM;CAGtB;AAED,eAAO,MAAM,WAAW,WAAW,CAAC"}
@@ -0,0 +1,96 @@
1
+ // PursuePool - per-entity AI that walks toward a target each tick.
2
+ //
3
+ // Minimum-viable Phase 7 enemy AI. PursueSystem reads:
4
+ // - this entity's Transform (current position)
5
+ // - target entity's Transform (where to walk to)
6
+ // - this entity's PursueComponent (speed, stop-distance, target ref)
7
+ // And writes the pursuer's Transform x/y each tick toward the
8
+ // target.
9
+ //
10
+ // More sophisticated AI (steering, obstacle avoidance, group
11
+ // behaviour) is post-Phase 7. This is enough to demo a knight
12
+ // being mobbed by 3 enemies that walk at it and start damaging
13
+ // when in range.
14
+ import { entityIndex } from '../entity.js';
15
+ import { growF32, growU8, nextPow2 } from '../util/typed-arrays.js';
16
+ export const PURSUE_FLAG_ACTIVE = 1 << 0;
17
+ export class PursuePool {
18
+ // Hot
19
+ speed; // world units per second
20
+ stopDistance; // stop pursuing once within this distance of target
21
+ targetIndex; // entity index of target; -1 = no target
22
+ // Damage applied to target when in range, per tick (not per second
23
+ // - DamageSystem multiplies by dt elsewhere if continuous). This
24
+ // is melee contact damage; ranged is a separate component.
25
+ contactDamage;
26
+ contactCooldownMs; // ms between successive contact hits
27
+ lastHitMs; // last successful contact hit timestamp
28
+ flags;
29
+ capacity = 0;
30
+ highWaterMark = 0;
31
+ constructor(initialCapacity = 64) {
32
+ this.capacity = nextPow2(initialCapacity);
33
+ this.speed = new Float32Array(this.capacity);
34
+ this.stopDistance = new Float32Array(this.capacity);
35
+ this.targetIndex = new Int32Array(this.capacity).fill(-1);
36
+ this.contactDamage = new Float32Array(this.capacity);
37
+ this.contactCooldownMs = new Float32Array(this.capacity);
38
+ this.lastHitMs = new Float32Array(this.capacity);
39
+ this.flags = new Uint8Array(this.capacity);
40
+ }
41
+ ensureCapacity(neededIndex) {
42
+ if (neededIndex < this.capacity)
43
+ return;
44
+ const next = nextPow2(neededIndex + 1);
45
+ this.speed = growF32(this.speed, next);
46
+ this.stopDistance = growF32(this.stopDistance, next);
47
+ const newTarget = new Int32Array(next).fill(-1);
48
+ newTarget.set(this.targetIndex);
49
+ this.targetIndex = newTarget;
50
+ this.contactDamage = growF32(this.contactDamage, next);
51
+ this.contactCooldownMs = growF32(this.contactCooldownMs, next);
52
+ this.lastHitMs = growF32(this.lastHitMs, next);
53
+ this.flags = growU8(this.flags, next);
54
+ this.capacity = next;
55
+ }
56
+ attach(e, target, speed, stopDistance, contactDamage = 0, contactCooldownMs = 1000) {
57
+ const i = entityIndex(e);
58
+ this.ensureCapacity(i);
59
+ this.speed[i] = speed;
60
+ this.stopDistance[i] = stopDistance;
61
+ this.targetIndex[i] = entityIndex(target);
62
+ this.contactDamage[i] = contactDamage;
63
+ this.contactCooldownMs[i] = contactCooldownMs;
64
+ this.lastHitMs[i] = -1;
65
+ this.flags[i] = PURSUE_FLAG_ACTIVE;
66
+ if (i >= this.highWaterMark)
67
+ this.highWaterMark = i + 1;
68
+ }
69
+ detach(e) {
70
+ const i = entityIndex(e);
71
+ if (i >= this.capacity)
72
+ return;
73
+ this.flags[i] = 0;
74
+ this.targetIndex[i] = -1;
75
+ }
76
+ setTarget(e, target) {
77
+ const i = entityIndex(e);
78
+ if (i >= this.capacity)
79
+ return;
80
+ this.targetIndex[i] = entityIndex(target);
81
+ }
82
+ isActive(e) {
83
+ const i = entityIndex(e);
84
+ if (i >= this.capacity)
85
+ return false;
86
+ return ((this.flags[i] ?? 0) & PURSUE_FLAG_ACTIVE) !== 0;
87
+ }
88
+ getHighWaterMark() {
89
+ return this.highWaterMark;
90
+ }
91
+ getCapacity() {
92
+ return this.capacity;
93
+ }
94
+ }
95
+ export const POOL_PURSUE = 'pursue';
96
+ //# sourceMappingURL=pursue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pursue.js","sourceRoot":"","sources":["../../src/components/pursue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type EntityId } from '../entity.js';
2
+ import type { ColorRGBA } from '../util/color.js';
3
+ export declare const RANGED_FLAG_ACTIVE: number;
4
+ export declare const RANGED_FLAG_HOMING: number;
5
+ export interface RangedAttackConfig {
6
+ target: EntityId;
7
+ range: number;
8
+ minRange: number;
9
+ cooldownMs: number;
10
+ damage: number;
11
+ projectileSpeed: number;
12
+ projectileLife: number;
13
+ projectileSize: number;
14
+ projectileColor: Readonly<ColorRGBA>;
15
+ homing: boolean;
16
+ }
17
+ export declare class RangedAttackPool {
18
+ range: Float32Array;
19
+ minRange: Float32Array;
20
+ cooldownMs: Float32Array;
21
+ lastFireMs: Float32Array;
22
+ damage: Float32Array;
23
+ projectileSpeed: Float32Array;
24
+ projectileLife: Float32Array;
25
+ projectileSize: Float32Array;
26
+ r: Float32Array;
27
+ g: Float32Array;
28
+ b: Float32Array;
29
+ a: Float32Array;
30
+ targetIndex: Int32Array;
31
+ flags: Uint8Array;
32
+ private capacity;
33
+ private highWaterMark;
34
+ constructor(initialCapacity?: number);
35
+ ensureCapacity(neededIndex: number): void;
36
+ attach(e: EntityId, cfg: RangedAttackConfig): void;
37
+ detach(e: EntityId): void;
38
+ setTarget(e: EntityId, target: EntityId): void;
39
+ isActive(e: EntityId): boolean;
40
+ getHighWaterMark(): number;
41
+ getCapacity(): number;
42
+ }
43
+ export declare const POOL_RANGED = "ranged";
44
+ //# sourceMappingURL=ranged-attack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranged-attack.d.ts","sourceRoot":"","sources":["../../src/components/ranged-attack.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,MAAM,WAAW,kBAAkB;IAEjC,MAAM,EAAE,QAAQ,CAAC;IAEjB,KAAK,EAAE,MAAM,CAAC;IAId,QAAQ,EAAE,MAAM,CAAC;IAEjB,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IAEf,eAAe,EAAE,MAAM,CAAC;IAGxB,cAAc,EAAE,MAAM,CAAC;IAEvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAErC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,gBAAgB;IAE3B,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,YAAY,CAAC;IACzB,UAAU,EAAE,YAAY,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,EAAE,YAAY,CAAC;IAC9B,cAAc,EAAE,YAAY,CAAC;IAC7B,cAAc,EAAE,YAAY,CAAC;IAE7B,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;IAEhB,WAAW,EAAE,UAAU,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;gBAEtB,eAAe,GAAE,MAAW;IAkBxC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAwBzC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAsBlD,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAOzB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI;IAM9C,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM9B,gBAAgB,IAAI,MAAM;IAC1B,WAAW,IAAI,MAAM;CACtB;AAED,eAAO,MAAM,WAAW,WAAW,CAAC"}
@@ -0,0 +1,120 @@
1
+ // RangedAttackPool - per-entity ranged attack capability.
2
+ //
3
+ // Mob with this + Transform + (optional) Pursue fires projectiles
4
+ // at its target every cooldownMs when within range. The Pursue
5
+ // component handles closing the gap; ranged-only mobs may run
6
+ // without Pursue and stay rooted (e.g. summoners). RangedAttackSystem
7
+ // reads this each tick.
8
+ import { entityIndex } from '../entity.js';
9
+ import { growF32, growI32, growU8, nextPow2 } from '../util/typed-arrays.js';
10
+ export const RANGED_FLAG_ACTIVE = 1 << 0;
11
+ export const RANGED_FLAG_HOMING = 1 << 1;
12
+ export class RangedAttackPool {
13
+ // Hot
14
+ range;
15
+ minRange;
16
+ cooldownMs;
17
+ lastFireMs;
18
+ damage;
19
+ projectileSpeed;
20
+ projectileLife;
21
+ projectileSize;
22
+ // Color rgba split.
23
+ r;
24
+ g;
25
+ b;
26
+ a;
27
+ // Target entity index. -1 = no target.
28
+ targetIndex;
29
+ flags;
30
+ capacity = 0;
31
+ highWaterMark = 0;
32
+ constructor(initialCapacity = 32) {
33
+ this.capacity = nextPow2(initialCapacity);
34
+ this.range = new Float32Array(this.capacity);
35
+ this.minRange = new Float32Array(this.capacity);
36
+ this.cooldownMs = new Float32Array(this.capacity);
37
+ this.lastFireMs = new Float32Array(this.capacity);
38
+ this.damage = new Float32Array(this.capacity);
39
+ this.projectileSpeed = new Float32Array(this.capacity);
40
+ this.projectileLife = new Float32Array(this.capacity);
41
+ this.projectileSize = new Float32Array(this.capacity);
42
+ this.r = new Float32Array(this.capacity);
43
+ this.g = new Float32Array(this.capacity);
44
+ this.b = new Float32Array(this.capacity);
45
+ this.a = new Float32Array(this.capacity);
46
+ this.targetIndex = new Int32Array(this.capacity).fill(-1);
47
+ this.flags = new Uint8Array(this.capacity);
48
+ }
49
+ ensureCapacity(neededIndex) {
50
+ if (neededIndex < this.capacity)
51
+ return;
52
+ const next = nextPow2(neededIndex + 1);
53
+ this.range = growF32(this.range, next);
54
+ this.minRange = growF32(this.minRange, next);
55
+ this.cooldownMs = growF32(this.cooldownMs, next);
56
+ this.lastFireMs = growF32(this.lastFireMs, next);
57
+ this.damage = growF32(this.damage, next);
58
+ this.projectileSpeed = growF32(this.projectileSpeed, next);
59
+ this.projectileLife = growF32(this.projectileLife, next);
60
+ this.projectileSize = growF32(this.projectileSize, next);
61
+ this.r = growF32(this.r, next);
62
+ this.g = growF32(this.g, next);
63
+ this.b = growF32(this.b, next);
64
+ this.a = growF32(this.a, next);
65
+ const newTarget = new Int32Array(next).fill(-1);
66
+ newTarget.set(this.targetIndex);
67
+ this.targetIndex = newTarget;
68
+ this.flags = growU8(this.flags, next);
69
+ this.capacity = next;
70
+ // Mark unused growF32 import as used (TypeScript noUnusedImports).
71
+ if (this.range.length === 0)
72
+ growI32(this.targetIndex, 0);
73
+ }
74
+ attach(e, cfg) {
75
+ const i = entityIndex(e);
76
+ this.ensureCapacity(i);
77
+ this.range[i] = cfg.range;
78
+ this.minRange[i] = cfg.minRange;
79
+ this.cooldownMs[i] = cfg.cooldownMs;
80
+ this.lastFireMs[i] = -1;
81
+ this.damage[i] = cfg.damage;
82
+ this.projectileSpeed[i] = cfg.projectileSpeed;
83
+ this.projectileLife[i] = cfg.projectileLife;
84
+ this.projectileSize[i] = cfg.projectileSize;
85
+ this.r[i] = cfg.projectileColor.r;
86
+ this.g[i] = cfg.projectileColor.g;
87
+ this.b[i] = cfg.projectileColor.b;
88
+ this.a[i] = cfg.projectileColor.a;
89
+ this.targetIndex[i] = entityIndex(cfg.target);
90
+ let f = RANGED_FLAG_ACTIVE;
91
+ if (cfg.homing)
92
+ f |= RANGED_FLAG_HOMING;
93
+ this.flags[i] = f;
94
+ if (i >= this.highWaterMark)
95
+ this.highWaterMark = i + 1;
96
+ }
97
+ detach(e) {
98
+ const i = entityIndex(e);
99
+ if (i >= this.capacity)
100
+ return;
101
+ this.flags[i] = 0;
102
+ this.targetIndex[i] = -1;
103
+ }
104
+ setTarget(e, target) {
105
+ const i = entityIndex(e);
106
+ if (i >= this.capacity)
107
+ return;
108
+ this.targetIndex[i] = entityIndex(target);
109
+ }
110
+ isActive(e) {
111
+ const i = entityIndex(e);
112
+ if (i >= this.capacity)
113
+ return false;
114
+ return ((this.flags[i] ?? 0) & RANGED_FLAG_ACTIVE) !== 0;
115
+ }
116
+ getHighWaterMark() { return this.highWaterMark; }
117
+ getCapacity() { return this.capacity; }
118
+ }
119
+ export const POOL_RANGED = 'ranged';
120
+ //# sourceMappingURL=ranged-attack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranged-attack.js","sourceRoot":"","sources":["../../src/components/ranged-attack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type EntityId } from '../entity.js';
2
+ import type { AtlasHandle } from '../renderer/graphics-device.js';
3
+ import type { ColorRGBA } from '../util/color.js';
4
+ export declare const SPRITE_FLAG_ACTIVE: number;
5
+ export declare const SPRITE_FLAG_TINTED: number;
6
+ export declare class SpritePool {
7
+ atlas: Int32Array;
8
+ frame: Int32Array;
9
+ tintR: Float32Array;
10
+ tintG: Float32Array;
11
+ tintB: Float32Array;
12
+ tintA: Float32Array;
13
+ flags: Uint8Array;
14
+ private highWaterMark;
15
+ private capacity;
16
+ constructor(initialCapacity?: number);
17
+ ensureCapacity(neededIndex: number): void;
18
+ attach(e: EntityId, atlas: AtlasHandle, frame?: number, tint?: Readonly<ColorRGBA>): void;
19
+ detach(e: EntityId): void;
20
+ setFrame(e: EntityId, frame: number): void;
21
+ setTint(e: EntityId, tint: Readonly<ColorRGBA>): void;
22
+ clearTint(e: EntityId): void;
23
+ isActive(e: EntityId): boolean;
24
+ getHighWaterMark(): number;
25
+ getCapacity(): number;
26
+ }
27
+ //# sourceMappingURL=sprite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprite.d.ts","sourceRoot":"","sources":["../../src/components/sprite.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,qBAAa,UAAU;IAErB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IAGpB,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAa;gBAEjB,eAAe,GAAE,MAAW;IAWxC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAezC,MAAM,CACJ,CAAC,EAAE,QAAQ,EACX,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE,MAAU,EACjB,IAAI,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,GACzB,IAAI;IAqBP,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAOzB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM1C,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI;IAWrD,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAW5B,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM9B,gBAAgB,IAAI,MAAM;IAI1B,WAAW,IAAI,MAAM;CAGtB"}