@datamoc/mw_games 0.1.2 → 0.2.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 (317) hide show
  1. package/README.md +42 -17
  2. package/dist/actors/Aura.d.ts +29 -0
  3. package/dist/actors/Aura.d.ts.map +1 -0
  4. package/dist/actors/Aura.js +69 -0
  5. package/dist/actors/Aura.js.map +1 -0
  6. package/dist/actors/ItemStatusEffect.d.ts +27 -0
  7. package/dist/actors/ItemStatusEffect.d.ts.map +1 -0
  8. package/dist/actors/ItemStatusEffect.js +35 -0
  9. package/dist/actors/ItemStatusEffect.js.map +1 -0
  10. package/dist/actors/Support.d.ts +32 -0
  11. package/dist/actors/Support.d.ts.map +1 -0
  12. package/dist/actors/Support.js +60 -0
  13. package/dist/actors/Support.js.map +1 -0
  14. package/dist/actors/Traits.d.ts +29 -0
  15. package/dist/actors/Traits.d.ts.map +1 -0
  16. package/dist/actors/Traits.js +21 -0
  17. package/dist/actors/Traits.js.map +1 -0
  18. package/dist/actors/index.d.ts +8 -0
  19. package/dist/actors/index.d.ts.map +1 -1
  20. package/dist/actors/index.js +4 -0
  21. package/dist/actors/index.js.map +1 -1
  22. package/dist/assets/Streaming.d.ts +40 -0
  23. package/dist/assets/Streaming.d.ts.map +1 -0
  24. package/dist/assets/Streaming.js +79 -0
  25. package/dist/assets/Streaming.js.map +1 -0
  26. package/dist/assets/index.d.ts +13 -0
  27. package/dist/assets/index.d.ts.map +1 -1
  28. package/dist/assets/index.js +19 -0
  29. package/dist/assets/index.js.map +1 -1
  30. package/dist/audio/Captions.d.ts +15 -0
  31. package/dist/audio/Captions.d.ts.map +1 -0
  32. package/dist/audio/Captions.js +4 -0
  33. package/dist/audio/Captions.js.map +1 -0
  34. package/dist/audio/Midi.d.ts +75 -0
  35. package/dist/audio/Midi.d.ts.map +1 -0
  36. package/dist/audio/Midi.js +186 -0
  37. package/dist/audio/Midi.js.map +1 -0
  38. package/dist/audio/Orchestrator.d.ts +40 -0
  39. package/dist/audio/Orchestrator.d.ts.map +1 -0
  40. package/dist/audio/Orchestrator.js +48 -0
  41. package/dist/audio/Orchestrator.js.map +1 -0
  42. package/dist/audio/Sound.d.ts +3 -0
  43. package/dist/audio/Sound.d.ts.map +1 -1
  44. package/dist/audio/Sound.js +4 -0
  45. package/dist/audio/Sound.js.map +1 -1
  46. package/dist/audio/Synth.d.ts +35 -0
  47. package/dist/audio/Synth.d.ts.map +1 -0
  48. package/dist/audio/Synth.js +96 -0
  49. package/dist/audio/Synth.js.map +1 -0
  50. package/dist/audio/index.d.ts +8 -0
  51. package/dist/audio/index.d.ts.map +1 -1
  52. package/dist/audio/index.js +4 -0
  53. package/dist/audio/index.js.map +1 -1
  54. package/dist/board/Army.d.ts +17 -0
  55. package/dist/board/Army.d.ts.map +1 -0
  56. package/dist/board/Army.js +48 -0
  57. package/dist/board/Army.js.map +1 -0
  58. package/dist/board/FogOfWar.d.ts +23 -0
  59. package/dist/board/FogOfWar.d.ts.map +1 -0
  60. package/dist/board/FogOfWar.js +40 -0
  61. package/dist/board/FogOfWar.js.map +1 -0
  62. package/dist/board/Tactics.d.ts +2 -0
  63. package/dist/board/Tactics.d.ts.map +1 -1
  64. package/dist/board/Tactics.js +29 -7
  65. package/dist/board/Tactics.js.map +1 -1
  66. package/dist/board/index.d.ts +5 -1
  67. package/dist/board/index.d.ts.map +1 -1
  68. package/dist/board/index.js +3 -1
  69. package/dist/board/index.js.map +1 -1
  70. package/dist/core/Feedback.d.ts +23 -0
  71. package/dist/core/Feedback.d.ts.map +1 -0
  72. package/dist/core/Feedback.js +35 -0
  73. package/dist/core/Feedback.js.map +1 -0
  74. package/dist/core/Game.d.ts +11 -0
  75. package/dist/core/Game.d.ts.map +1 -1
  76. package/dist/core/Game.js +54 -0
  77. package/dist/core/Game.js.map +1 -1
  78. package/dist/core/Input.d.ts +58 -0
  79. package/dist/core/Input.d.ts.map +1 -1
  80. package/dist/core/Input.js +135 -0
  81. package/dist/core/Input.js.map +1 -1
  82. package/dist/core/Loading.d.ts +48 -0
  83. package/dist/core/Loading.d.ts.map +1 -0
  84. package/dist/core/Loading.js +102 -0
  85. package/dist/core/Loading.js.map +1 -0
  86. package/dist/core/News.d.ts +46 -0
  87. package/dist/core/News.d.ts.map +1 -0
  88. package/dist/core/News.js +79 -0
  89. package/dist/core/News.js.map +1 -0
  90. package/dist/core/PlayerInput.d.ts +38 -0
  91. package/dist/core/PlayerInput.d.ts.map +1 -0
  92. package/dist/core/PlayerInput.js +57 -0
  93. package/dist/core/PlayerInput.js.map +1 -0
  94. package/dist/core/RunHistory.d.ts +43 -0
  95. package/dist/core/RunHistory.d.ts.map +1 -0
  96. package/dist/core/RunHistory.js +41 -0
  97. package/dist/core/RunHistory.js.map +1 -0
  98. package/dist/core/Sanitize.d.ts +56 -0
  99. package/dist/core/Sanitize.d.ts.map +1 -0
  100. package/dist/core/Sanitize.js +87 -0
  101. package/dist/core/Sanitize.js.map +1 -0
  102. package/dist/core/Save.d.ts +31 -7
  103. package/dist/core/Save.d.ts.map +1 -1
  104. package/dist/core/Save.js +56 -0
  105. package/dist/core/Save.js.map +1 -1
  106. package/dist/core/SaveSync.d.ts +26 -0
  107. package/dist/core/SaveSync.d.ts.map +1 -0
  108. package/dist/core/SaveSync.js +52 -0
  109. package/dist/core/SaveSync.js.map +1 -0
  110. package/dist/core/Scramble.d.ts +13 -0
  111. package/dist/core/Scramble.d.ts.map +1 -0
  112. package/dist/core/Scramble.js +44 -0
  113. package/dist/core/Scramble.js.map +1 -0
  114. package/dist/core/Spawner.d.ts +48 -0
  115. package/dist/core/Spawner.d.ts.map +1 -0
  116. package/dist/core/Spawner.js +65 -0
  117. package/dist/core/Spawner.js.map +1 -0
  118. package/dist/core/Tween.d.ts +25 -0
  119. package/dist/core/Tween.d.ts.map +1 -0
  120. package/dist/core/Tween.js +60 -0
  121. package/dist/core/Tween.js.map +1 -0
  122. package/dist/core/UndoHistory.d.ts +37 -0
  123. package/dist/core/UndoHistory.d.ts.map +1 -0
  124. package/dist/core/UndoHistory.js +49 -0
  125. package/dist/core/UndoHistory.js.map +1 -0
  126. package/dist/core/index.d.ts +20 -0
  127. package/dist/core/index.d.ts.map +1 -1
  128. package/dist/core/index.js +11 -0
  129. package/dist/core/index.js.map +1 -1
  130. package/dist/i18n/Fluent.d.ts +7 -0
  131. package/dist/i18n/Fluent.d.ts.map +1 -0
  132. package/dist/i18n/Fluent.js +86 -0
  133. package/dist/i18n/Fluent.js.map +1 -0
  134. package/dist/i18n/index.d.ts +15 -1
  135. package/dist/i18n/index.d.ts.map +1 -1
  136. package/dist/i18n/index.js +17 -2
  137. package/dist/i18n/index.js.map +1 -1
  138. package/dist/index.d.ts +1 -0
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +1 -0
  141. package/dist/index.js.map +1 -1
  142. package/dist/mw_games.global.js +351 -79
  143. package/dist/render/Camera.d.ts +29 -2
  144. package/dist/render/Camera.d.ts.map +1 -1
  145. package/dist/render/Camera.js +40 -11
  146. package/dist/render/Camera.js.map +1 -1
  147. package/dist/render/Capabilities.d.ts +51 -0
  148. package/dist/render/Capabilities.d.ts.map +1 -0
  149. package/dist/render/Capabilities.js +56 -0
  150. package/dist/render/Capabilities.js.map +1 -0
  151. package/dist/render/ColorBlindness.d.ts +16 -0
  152. package/dist/render/ColorBlindness.d.ts.map +1 -0
  153. package/dist/render/ColorBlindness.js +41 -0
  154. package/dist/render/ColorBlindness.js.map +1 -0
  155. package/dist/render/Minimap.d.ts +52 -0
  156. package/dist/render/Minimap.d.ts.map +1 -0
  157. package/dist/render/Minimap.js +95 -0
  158. package/dist/render/Minimap.js.map +1 -0
  159. package/dist/render/Viewport.d.ts +46 -0
  160. package/dist/render/Viewport.d.ts.map +1 -0
  161. package/dist/render/Viewport.js +52 -0
  162. package/dist/render/Viewport.js.map +1 -0
  163. package/dist/render/index.d.ts +9 -1
  164. package/dist/render/index.d.ts.map +1 -1
  165. package/dist/render/index.js +5 -1
  166. package/dist/render/index.js.map +1 -1
  167. package/dist/roguelike/Stealth.d.ts +34 -0
  168. package/dist/roguelike/Stealth.d.ts.map +1 -0
  169. package/dist/roguelike/Stealth.js +35 -0
  170. package/dist/roguelike/Stealth.js.map +1 -0
  171. package/dist/roguelike/index.d.ts +2 -0
  172. package/dist/roguelike/index.d.ts.map +1 -1
  173. package/dist/roguelike/index.js +1 -0
  174. package/dist/roguelike/index.js.map +1 -1
  175. package/dist/rpg/Collision.d.ts +42 -0
  176. package/dist/rpg/Collision.d.ts.map +1 -0
  177. package/dist/rpg/Collision.js +77 -0
  178. package/dist/rpg/Collision.js.map +1 -0
  179. package/dist/rpg/FreeMover.d.ts +45 -0
  180. package/dist/rpg/FreeMover.d.ts.map +1 -0
  181. package/dist/rpg/FreeMover.js +68 -0
  182. package/dist/rpg/FreeMover.js.map +1 -0
  183. package/dist/rpg/Marshal.d.ts +65 -0
  184. package/dist/rpg/Marshal.d.ts.map +1 -0
  185. package/dist/rpg/Marshal.js +393 -0
  186. package/dist/rpg/Marshal.js.map +1 -0
  187. package/dist/rpg/Quest.d.ts +41 -0
  188. package/dist/rpg/Quest.d.ts.map +1 -1
  189. package/dist/rpg/Quest.js +39 -6
  190. package/dist/rpg/Quest.js.map +1 -1
  191. package/dist/rpg/index.d.ts +7 -1
  192. package/dist/rpg/index.d.ts.map +1 -1
  193. package/dist/rpg/index.js +3 -0
  194. package/dist/rpg/index.js.map +1 -1
  195. package/dist/stage/DialogueStage.d.ts +1 -2
  196. package/dist/stage/DialogueStage.d.ts.map +1 -1
  197. package/dist/stage/DialogueStage.js +7 -22
  198. package/dist/stage/DialogueStage.js.map +1 -1
  199. package/dist/stage/index.d.ts +1 -1
  200. package/dist/stage/index.d.ts.map +1 -1
  201. package/dist/stage/script.d.ts +29 -0
  202. package/dist/stage/script.d.ts.map +1 -1
  203. package/dist/stage/script.js +0 -0
  204. package/dist/stage/script.js.map +1 -1
  205. package/dist/three-d/Character3D.d.ts +48 -0
  206. package/dist/three-d/Character3D.d.ts.map +1 -0
  207. package/dist/three-d/Character3D.js +96 -0
  208. package/dist/three-d/Character3D.js.map +1 -0
  209. package/dist/three-d/Engine3D.d.ts +23 -0
  210. package/dist/three-d/Engine3D.d.ts.map +1 -0
  211. package/dist/three-d/Engine3D.js +45 -0
  212. package/dist/three-d/Engine3D.js.map +1 -0
  213. package/dist/three-d/Grid.d.ts +14 -0
  214. package/dist/three-d/Grid.d.ts.map +1 -0
  215. package/dist/three-d/Grid.js +13 -0
  216. package/dist/three-d/Grid.js.map +1 -0
  217. package/dist/three-d/Heightmap.d.ts +35 -0
  218. package/dist/three-d/Heightmap.d.ts.map +1 -0
  219. package/dist/three-d/Heightmap.js +29 -0
  220. package/dist/three-d/Heightmap.js.map +1 -0
  221. package/dist/three-d/Models.d.ts +12 -0
  222. package/dist/three-d/Models.d.ts.map +1 -0
  223. package/dist/three-d/Models.js +14 -0
  224. package/dist/three-d/Models.js.map +1 -0
  225. package/dist/three-d/TileGrid3D.d.ts +21 -0
  226. package/dist/three-d/TileGrid3D.d.ts.map +1 -0
  227. package/dist/three-d/TileGrid3D.js +65 -0
  228. package/dist/three-d/TileGrid3D.js.map +1 -0
  229. package/dist/three-d/Vox.d.ts +24 -0
  230. package/dist/three-d/Vox.d.ts.map +1 -0
  231. package/dist/three-d/Vox.js +93 -0
  232. package/dist/three-d/Vox.js.map +1 -0
  233. package/dist/three-d/index.d.ts +13 -0
  234. package/dist/three-d/index.d.ts.map +1 -0
  235. package/dist/three-d/index.js +7 -0
  236. package/dist/three-d/index.js.map +1 -0
  237. package/dist/ui/Bar.d.ts +49 -0
  238. package/dist/ui/Bar.d.ts.map +1 -0
  239. package/dist/ui/Bar.js +70 -0
  240. package/dist/ui/Bar.js.map +1 -0
  241. package/dist/ui/BitmapLabel.d.ts +42 -0
  242. package/dist/ui/BitmapLabel.d.ts.map +1 -0
  243. package/dist/ui/BitmapLabel.js +59 -0
  244. package/dist/ui/BitmapLabel.js.map +1 -0
  245. package/dist/ui/Button.d.ts +52 -0
  246. package/dist/ui/Button.d.ts.map +1 -0
  247. package/dist/ui/Button.js +147 -0
  248. package/dist/ui/Button.js.map +1 -0
  249. package/dist/ui/FloatingText.d.ts +28 -0
  250. package/dist/ui/FloatingText.d.ts.map +1 -0
  251. package/dist/ui/FloatingText.js +39 -0
  252. package/dist/ui/FloatingText.js.map +1 -0
  253. package/dist/ui/HelpScreen.d.ts +29 -0
  254. package/dist/ui/HelpScreen.d.ts.map +1 -0
  255. package/dist/ui/HelpScreen.js +39 -0
  256. package/dist/ui/HelpScreen.js.map +1 -0
  257. package/dist/ui/IconGrid.d.ts +8 -0
  258. package/dist/ui/IconGrid.d.ts.map +1 -1
  259. package/dist/ui/IconGrid.js +27 -1
  260. package/dist/ui/IconGrid.js.map +1 -1
  261. package/dist/ui/Label.d.ts +9 -0
  262. package/dist/ui/Label.d.ts.map +1 -1
  263. package/dist/ui/Label.js +24 -1
  264. package/dist/ui/Label.js.map +1 -1
  265. package/dist/ui/ListView.d.ts +11 -0
  266. package/dist/ui/ListView.d.ts.map +1 -1
  267. package/dist/ui/ListView.js +55 -1
  268. package/dist/ui/ListView.js.map +1 -1
  269. package/dist/ui/LoadingScreen.d.ts +31 -0
  270. package/dist/ui/LoadingScreen.d.ts.map +1 -0
  271. package/dist/ui/LoadingScreen.js +60 -0
  272. package/dist/ui/LoadingScreen.js.map +1 -0
  273. package/dist/ui/MessageBox.d.ts +26 -0
  274. package/dist/ui/MessageBox.d.ts.map +1 -1
  275. package/dist/ui/MessageBox.js +62 -13
  276. package/dist/ui/MessageBox.js.map +1 -1
  277. package/dist/ui/RebindScreen.d.ts +55 -0
  278. package/dist/ui/RebindScreen.d.ts.map +1 -0
  279. package/dist/ui/RebindScreen.js +114 -0
  280. package/dist/ui/RebindScreen.js.map +1 -0
  281. package/dist/ui/Toast.d.ts +44 -0
  282. package/dist/ui/Toast.d.ts.map +1 -0
  283. package/dist/ui/Toast.js +89 -0
  284. package/dist/ui/Toast.js.map +1 -0
  285. package/dist/ui/VerticalLabel.d.ts +5 -0
  286. package/dist/ui/VerticalLabel.d.ts.map +1 -1
  287. package/dist/ui/VerticalLabel.js +18 -7
  288. package/dist/ui/VerticalLabel.js.map +1 -1
  289. package/dist/ui/Window.d.ts +6 -0
  290. package/dist/ui/Window.d.ts.map +1 -1
  291. package/dist/ui/Window.js +16 -1
  292. package/dist/ui/Window.js.map +1 -1
  293. package/dist/ui/WindowStack.d.ts +1 -0
  294. package/dist/ui/WindowStack.d.ts.map +1 -1
  295. package/dist/ui/WindowStack.js +4 -1
  296. package/dist/ui/WindowStack.js.map +1 -1
  297. package/dist/ui/index.d.ts +17 -1
  298. package/dist/ui/index.d.ts.map +1 -1
  299. package/dist/ui/index.js +9 -1
  300. package/dist/ui/index.js.map +1 -1
  301. package/dist/ui/theme.d.ts +21 -0
  302. package/dist/ui/theme.d.ts.map +1 -1
  303. package/dist/ui/theme.js +42 -0
  304. package/dist/ui/theme.js.map +1 -1
  305. package/dist/version.d.ts +13 -0
  306. package/dist/version.d.ts.map +1 -0
  307. package/dist/version.js +13 -0
  308. package/dist/version.js.map +1 -0
  309. package/dist/world/Environment.d.ts +35 -0
  310. package/dist/world/Environment.d.ts.map +1 -0
  311. package/dist/world/Environment.js +55 -0
  312. package/dist/world/Environment.js.map +1 -0
  313. package/dist/world/index.d.ts +2 -0
  314. package/dist/world/index.d.ts.map +1 -1
  315. package/dist/world/index.js +1 -0
  316. package/dist/world/index.js.map +1 -1
  317. package/package.json +40 -4
@@ -0,0 +1,35 @@
1
+ import type { Playable } from './Playable.ts';
2
+ /**
3
+ * A small runtime waveform generator - the licence-avoiding synthesis
4
+ * `tools/make-example-assets.mjs` already does offline for this project's own example
5
+ * sounds, exposed here as something a running game can call itself to generate a tone or a
6
+ * procedural SFX on the fly, rather than only ever play a pre-baked clip.
7
+ */
8
+ export type Waveform = 'square' | 'triangle' | 'sine' | 'noise';
9
+ export interface ToneOptions {
10
+ waveform?: Waveform;
11
+ /** Hz; ignored for `'noise'` */
12
+ frequency?: number;
13
+ /** seconds */
14
+ duration?: number;
15
+ /** peak sample amplitude, 0 to 1 */
16
+ volume?: number;
17
+ /** exponential envelope rate over the tone's duration; 0 disables the fade-out */
18
+ decay?: number;
19
+ sampleRate?: number;
20
+ /** seeds `'noise'`, so the same options reproduce the same waveform */
21
+ seed?: number;
22
+ }
23
+ /**
24
+ * Renders a short tone to a `data:audio/wav` URI, ready to hand to an `Audio` element (or
25
+ * any other `Playable` source) without touching the network or `mwg/assets` - nothing here
26
+ * is loaded, only computed.
27
+ */
28
+ export declare function synthesizeTone(options?: ToneOptions): string;
29
+ /**
30
+ * Synthesizes a tone and plays it once, fire-and-forget - the runtime counterpart to
31
+ * `Sound.play`, generating instead of loading. `create` is injectable the same way
32
+ * `Sound`/`Music` already are, so a test never needs a real `Audio` element.
33
+ */
34
+ export declare function playTone(options?: ToneOptions, create?: (dataUri: string) => Playable): Playable;
35
+ //# sourceMappingURL=Synth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Synth.d.ts","sourceRoot":"","sources":["../../src/audio/Synth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,WAAgB,GAAG,MAAM,CAsBhE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,WAAgB,EAAE,MAAM,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,QAAkC,GAAG,QAAQ,CAI7H"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Renders a short tone to a `data:audio/wav` URI, ready to hand to an `Audio` element (or
3
+ * any other `Playable` source) without touching the network or `mwg/assets` - nothing here
4
+ * is loaded, only computed.
5
+ */
6
+ export function synthesizeTone(options = {}) {
7
+ const waveform = options.waveform ?? 'square';
8
+ const frequency = options.frequency ?? 440;
9
+ const duration = options.duration ?? 0.15;
10
+ const volume = options.volume ?? 0.3;
11
+ const decay = options.decay ?? 8;
12
+ const sampleRate = options.sampleRate ?? 22050;
13
+ const seed = options.seed ?? 1;
14
+ if (!(duration > 0))
15
+ throw new Error('tone duration must be positive');
16
+ if (waveform !== 'noise' && !(frequency > 0))
17
+ throw new Error('tone frequency must be positive');
18
+ if (!(sampleRate > 0))
19
+ throw new Error('tone sample rate must be positive');
20
+ const count = Math.max(1, Math.round(duration * sampleRate));
21
+ const samples = new Float32Array(count);
22
+ for (let i = 0; i < count; i++) {
23
+ const t = i / sampleRate;
24
+ const envelope = decay > 0 ? Math.exp((-decay * i) / count) : 1;
25
+ const phase = 2 * Math.PI * frequency * t;
26
+ samples[i] = volume * envelope * waveSample(waveform, phase, seed, i);
27
+ }
28
+ return encodeWav(samples, sampleRate);
29
+ }
30
+ /**
31
+ * Synthesizes a tone and plays it once, fire-and-forget - the runtime counterpart to
32
+ * `Sound.play`, generating instead of loading. `create` is injectable the same way
33
+ * `Sound`/`Music` already are, so a test never needs a real `Audio` element.
34
+ */
35
+ export function playTone(options = {}, create = (uri) => new Audio(uri)) {
36
+ const playable = create(synthesizeTone(options));
37
+ void playable.play();
38
+ return playable;
39
+ }
40
+ function waveSample(waveform, phase, seed, index) {
41
+ switch (waveform) {
42
+ case 'sine':
43
+ return Math.sin(phase);
44
+ case 'square':
45
+ return Math.sin(phase) >= 0 ? 1 : -1;
46
+ case 'triangle': {
47
+ const cycles = phase / (2 * Math.PI);
48
+ const f = cycles - Math.floor(cycles);
49
+ return 4 * Math.abs(f - 0.5) - 1;
50
+ }
51
+ case 'noise':
52
+ return noiseSample(seed, index);
53
+ }
54
+ }
55
+ /** a deterministic hash-based pseudo-random sample in [-1, 1], so a given seed always reproduces the same noise */
56
+ function noiseSample(seed, index) {
57
+ let h = Math.imul(seed ^ index, 2654435761) >>> 0;
58
+ h = Math.imul(h ^ (h >>> 15), 2246822519) >>> 0;
59
+ h = Math.imul(h ^ (h >>> 13), 3266489917) >>> 0;
60
+ h ^= h >>> 16;
61
+ return (h >>> 0) / 4294967295 * 2 - 1;
62
+ }
63
+ function encodeWav(samples, sampleRate) {
64
+ const dataSize = samples.length * 2;
65
+ const buffer = new ArrayBuffer(44 + dataSize);
66
+ const view = new DataView(buffer);
67
+ writeAscii(view, 0, 'RIFF');
68
+ view.setUint32(4, 36 + dataSize, true);
69
+ writeAscii(view, 8, 'WAVE');
70
+ writeAscii(view, 12, 'fmt ');
71
+ view.setUint32(16, 16, true); // fmt chunk size
72
+ view.setUint16(20, 1, true); // PCM
73
+ view.setUint16(22, 1, true); // mono
74
+ view.setUint32(24, sampleRate, true);
75
+ view.setUint32(28, sampleRate * 2, true); // byte rate
76
+ view.setUint16(32, 2, true); // block align
77
+ view.setUint16(34, 16, true); // bits per sample
78
+ writeAscii(view, 36, 'data');
79
+ view.setUint32(40, dataSize, true);
80
+ let offset = 44;
81
+ for (const sample of samples) {
82
+ const clamped = Math.max(-1, Math.min(1, sample));
83
+ view.setInt16(offset, Math.round(clamped * (clamped < 0 ? 0x8000 : 0x7fff)), true);
84
+ offset += 2;
85
+ }
86
+ let binary = '';
87
+ const bytes = new Uint8Array(buffer);
88
+ for (const byte of bytes)
89
+ binary += String.fromCharCode(byte);
90
+ return `data:audio/wav;base64,${btoa(binary)}`;
91
+ }
92
+ function writeAscii(view, offset, text) {
93
+ for (let i = 0; i < text.length; i++)
94
+ view.setUint8(offset + i, text.charCodeAt(i));
95
+ }
96
+ //# sourceMappingURL=Synth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Synth.js","sourceRoot":"","sources":["../../src/audio/Synth.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,15 @@
1
1
  export { Sound } from './Sound.ts';
2
2
  export type { SoundOptions } from './Sound.ts';
3
+ export { onCaption } from './Captions.ts';
4
+ export type { CaptionEvent } from './Captions.ts';
3
5
  export { Music } from './Music.ts';
4
6
  export type { MusicOptions } from './Music.ts';
5
7
  export { createAudio } from './Playable.ts';
6
8
  export type { Playable } from './Playable.ts';
9
+ export { Orchestrator } from './Orchestrator.ts';
10
+ export type { OrchestratorState } from './Orchestrator.ts';
11
+ export { synthesizeTone, playTone } from './Synth.ts';
12
+ export type { Waveform, ToneOptions } from './Synth.ts';
13
+ export { parseMidi, scheduleMidi, noteToFrequency, MidiPlayer } from './Midi.ts';
14
+ export type { MidiFile, MidiEvent, MidiNoteEvent, MidiTempoEvent, ScheduledNote, MidiPlayerOptions } from './Midi.ts';
7
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACjF,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
@@ -1,4 +1,8 @@
1
1
  export { Sound } from './Sound.js';
2
+ export { onCaption } from './Captions.js';
2
3
  export { Music } from './Music.js';
3
4
  export { createAudio } from './Playable.js';
5
+ export { Orchestrator } from './Orchestrator.js';
6
+ export { synthesizeTone, playTone } from './Synth.js';
7
+ export { parseMidi, scheduleMidi, noteToFrequency, MidiPlayer } from './Midi.js';
4
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { TacticalState, TacticalUnit } from './Tactics.ts';
2
+ export type UnitTemplate = Omit<TacticalUnit, 'x' | 'y'>;
3
+ export interface ArmyState {
4
+ currency: number;
5
+ pool: UnitTemplate[];
6
+ }
7
+ export declare function startingArmy(currency: number): ArmyState;
8
+ export declare function recruit(army: ArmyState, board: TacticalState, unit: TacticalUnit, cost: number): boolean;
9
+ export declare function recall(army: ArmyState, board: TacticalState, unitId: string, x: number, y: number): boolean;
10
+ export declare function bankUnit(army: ArmyState, board: TacticalState, unitId: string): boolean;
11
+ export interface UpkeepRates {
12
+ incomePerUnit: number;
13
+ upkeepPerUnit: number;
14
+ }
15
+ export declare function armyIncome(board: TacticalState, owner: string, rates: UpkeepRates): number;
16
+ export declare function applyUpkeep(army: ArmyState, board: TacticalState, owner: string, rates: UpkeepRates): number;
17
+ //# sourceMappingURL=Army.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Army.d.ts","sourceRoot":"","sources":["../../src/board/Army.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKhE,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;AAEzD,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,YAAY,EAAE,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAExD;AAKD,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxG;AAID,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAM3G;AAID,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOvF;AAED,MAAM,WAAW,WAAW;IAAG,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;CAAE;AAK9E,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAG1F;AAGD,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAG5G"}
@@ -0,0 +1,48 @@
1
+ import { addTacticalUnit, canPlaceTacticalUnit } from './Tactics.js';
2
+ export function startingArmy(currency) {
3
+ return { currency, pool: [] };
4
+ }
5
+ //deducts cost and places a fresh unit, all-or-nothing like actors.Shop's buy/sell: touches
6
+ //neither currency nor the board unless every check already passed - canPlaceTacticalUnit is
7
+ //checked up front rather than letting addTacticalUnit's own throw escape a boolean contract
8
+ export function recruit(army, board, unit, cost) {
9
+ if (army.currency < cost || !canPlaceTacticalUnit(board, unit.x, unit.y))
10
+ return false;
11
+ addTacticalUnit(board, unit);
12
+ army.currency -= cost;
13
+ return true;
14
+ }
15
+ //pulls a previously-fielded unit back onto the map instead of minting a fresh one - the
16
+ //template stays in the pool until recalled, then leaves it the way stock leaves a shop's shelf
17
+ export function recall(army, board, unitId, x, y) {
18
+ const index = army.pool.findIndex((template) => template.id === unitId);
19
+ if (index === -1 || !canPlaceTacticalUnit(board, x, y))
20
+ return false;
21
+ addTacticalUnit(board, { ...army.pool[index], x, y });
22
+ army.pool.splice(index, 1);
23
+ return true;
24
+ }
25
+ //moves a fielded unit into the recall pool instead of discarding it outright - the inverse of
26
+ //recall, for retreating a unit off the map between engagements rather than losing it for good
27
+ export function bankUnit(army, board, unitId) {
28
+ const index = board.units.findIndex((unit) => unit.id === unitId);
29
+ if (index === -1)
30
+ return false;
31
+ const { x: _x, y: _y, ...template } = board.units[index];
32
+ army.pool.push(template);
33
+ board.units.splice(index, 1);
34
+ return true;
35
+ }
36
+ //net currency delta for one turn's income minus upkeep, purely a function of how many units
37
+ //an owner controls on the board - no formula beyond that belongs here, per this project's
38
+ //policy against borrowing any specific game's numbers
39
+ export function armyIncome(board, owner, rates) {
40
+ const controlled = board.units.filter((unit) => unit.owner === owner).length;
41
+ return controlled * (rates.incomePerUnit - rates.upkeepPerUnit);
42
+ }
43
+ //applies one turn's income/upkeep tick to an army's currency and returns the new total
44
+ export function applyUpkeep(army, board, owner, rates) {
45
+ army.currency += armyIncome(board, owner, rates);
46
+ return army.currency;
47
+ }
48
+ //# sourceMappingURL=Army.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Army.js","sourceRoot":"","sources":["../../src/board/Army.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAWrE,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC5C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC/B,CAAC;AAED,2FAA2F;AAC3F,4FAA4F;AAC5F,4FAA4F;AAC5F,MAAM,UAAU,OAAO,CAAC,IAAe,EAAE,KAAoB,EAAE,IAAkB,EAAE,IAAY;IAC9F,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvF,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;IACtB,OAAO,IAAI,CAAC;AACb,CAAC;AAED,wFAAwF;AACxF,+FAA+F;AAC/F,MAAM,UAAU,MAAM,CAAC,IAAe,EAAE,KAAoB,EAAE,MAAc,EAAE,CAAS,EAAE,CAAS;IACjG,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACxE,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,eAAe,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,8FAA8F;AAC9F,8FAA8F;AAC9F,MAAM,UAAU,QAAQ,CAAC,IAAe,EAAE,KAAoB,EAAE,MAAc;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACb,CAAC;AAID,4FAA4F;AAC5F,0FAA0F;AAC1F,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,KAAoB,EAAE,KAAa,EAAE,KAAkB;IACjF,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;IAC7E,OAAO,UAAU,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;AACjE,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,WAAW,CAAC,IAAe,EAAE,KAAoB,EAAE,KAAa,EAAE,KAAkB;IACnG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,QAAQ,CAAC;AACtB,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface VisionCell {
2
+ x: number;
3
+ y: number;
4
+ }
5
+ /**
6
+ * Unions the visible cells of several units for each faction and retains explored memory.
7
+ * The caller supplies visibility because board games differ in terrain, range, and blockers.
8
+ */
9
+ export declare class FactionFog {
10
+ readonly width: number;
11
+ readonly height: number;
12
+ private visible;
13
+ private explored;
14
+ constructor(width: number, height: number);
15
+ sync(faction: string, sources: readonly VisionCell[], cells: (source: VisionCell) => Iterable<VisionCell>): void;
16
+ isVisible(faction: string, x: number, y: number): boolean;
17
+ isExplored(faction: string, x: number, y: number): boolean;
18
+ visibleCells(faction: string): readonly number[];
19
+ exploredCells(faction: string): readonly number[];
20
+ private inside;
21
+ private index;
22
+ }
23
+ //# sourceMappingURL=FogOfWar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FogOfWar.d.ts","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;CAAE;AAErD;;;GAGG;AACH,qBAAa,UAAU;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,QAAQ,CAAkC;IAElD,YAAY,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAIxC;IAED,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAU/G;IAED,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAExD;IAED,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzD;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAmD;IACnG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAoD;IAErG,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;CACb"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Unions the visible cells of several units for each faction and retains explored memory.
3
+ * The caller supplies visibility because board games differ in terrain, range, and blockers.
4
+ */
5
+ export class FactionFog {
6
+ constructor(width, height) {
7
+ this.visible = new Map();
8
+ this.explored = new Map();
9
+ if (width < 1 || height < 1)
10
+ throw new Error('fog needs positive dimensions');
11
+ this.width = width;
12
+ this.height = height;
13
+ }
14
+ sync(faction, sources, cells) {
15
+ if (!faction)
16
+ throw new Error('fog needs a faction id');
17
+ const next = new Set();
18
+ for (const source of sources)
19
+ for (const cell of cells(source)) {
20
+ if (this.inside(cell.x, cell.y))
21
+ next.add(this.index(cell.x, cell.y));
22
+ }
23
+ this.visible.set(faction, next);
24
+ const memory = this.explored.get(faction) ?? new Set();
25
+ for (const cell of next)
26
+ memory.add(cell);
27
+ this.explored.set(faction, memory);
28
+ }
29
+ isVisible(faction, x, y) {
30
+ return this.visible.get(faction)?.has(this.index(x, y)) ?? false;
31
+ }
32
+ isExplored(faction, x, y) {
33
+ return this.explored.get(faction)?.has(this.index(x, y)) ?? false;
34
+ }
35
+ visibleCells(faction) { return [...(this.visible.get(faction) ?? [])]; }
36
+ exploredCells(faction) { return [...(this.explored.get(faction) ?? [])]; }
37
+ inside(x, y) { return x >= 0 && y >= 0 && x < this.width && y < this.height; }
38
+ index(x, y) { return this.inside(x, y) ? y * this.width + x : -1; }
39
+ }
40
+ //# sourceMappingURL=FogOfWar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FogOfWar.js","sourceRoot":"","sources":["../../src/board/FogOfWar.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,UAAU;IAMtB,YAAY,KAAa,EAAE,MAAc;QAHjC,YAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;QACzC,aAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;QAGjD,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC9E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAA8B,EAAE,KAAmD;QACxG,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;oBAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QAC/D,KAAK,MAAM,IAAI,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,SAAS,CAAC,OAAe,EAAE,CAAS,EAAE,CAAS;QAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IAClE,CAAC;IAED,UAAU,CAAC,OAAe,EAAE,CAAS,EAAE,CAAS;QAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IACnE,CAAC;IAED,YAAY,CAAC,OAAe,IAAuB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnG,aAAa,CAAC,OAAe,IAAuB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7F,MAAM,CAAC,CAAS,EAAE,CAAS,IAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACvG,KAAK,CAAC,CAAS,EAAE,CAAS,IAAY,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACnG"}
@@ -36,6 +36,8 @@ export interface TacticalAttack {
36
36
  killed: boolean;
37
37
  }
38
38
  export declare function startingTactics(width: number, height: number, shape?: TacticalShape): TacticalState;
39
+ /** whether a unit could be placed at (x, y) right now - on the map, and not already occupied */
40
+ export declare function canPlaceTacticalUnit(state: TacticalState, x: number, y: number): boolean;
39
41
  export declare function addTacticalUnit(state: TacticalState, unit: TacticalUnit): void;
40
42
  export declare function tacticalMoves(state: TacticalState, unitId: string): TacticalMove[];
41
43
  export declare function moveTacticalUnit(state: TacticalState, move: TacticalMove): void;
@@ -1 +1 @@
1
- {"version":3,"file":"Tactics.d.ts","sourceRoot":"","sources":["../../src/board/Tactics.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC7C,MAAM,WAAW,YAAY;IAAG,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAAE;AACpE,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAAE;AACnJ,MAAM,WAAW,aAAa;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAClK,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAAE;AACnF,MAAM,WAAW,cAAc;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;CAAE;AAEvH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,aAAqB,GAAG,aAAa,CAG1G;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAI9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAUlF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAO/E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK/E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAarH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAW3H;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAO1D"}
1
+ {"version":3,"file":"Tactics.d.ts","sourceRoot":"","sources":["../../src/board/Tactics.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC7C,MAAM,WAAW,YAAY;IAAG,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAAE;AACpE,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAAE;AACnJ,MAAM,WAAW,aAAa;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAAE;AAClK,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAAE;AACnF,MAAM,WAAW,cAAc;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;CAAE;AAEvH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,aAAqB,GAAG,aAAa,CAG1G;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAExF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAI9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAelF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAO/E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK/E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAarH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAW3H;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAO1D"}
@@ -4,8 +4,12 @@ export function startingTactics(width, height, shape = 'hex') {
4
4
  throw new Error('a tactical map needs positive dimensions');
5
5
  return { width, height, shape, cells: Array.from({ length: width * height }, () => ({ passable: true, cover: 0 })), units: [], turn: '', round: 1 };
6
6
  }
7
+ /** whether a unit could be placed at (x, y) right now - on the map, and not already occupied */
8
+ export function canPlaceTacticalUnit(state, x, y) {
9
+ return tacticalInside(state, x, y) && !occupied(state, x, y);
10
+ }
7
11
  export function addTacticalUnit(state, unit) {
8
- if (!tacticalInside(state, unit.x, unit.y) || state.units.some((other) => other.x === unit.x && other.y === unit.y))
12
+ if (!canPlaceTacticalUnit(state, unit.x, unit.y))
9
13
  throw new Error('tactical unit cannot be placed there');
10
14
  state.units.push({ ...unit });
11
15
  if (!state.turn)
@@ -15,12 +19,17 @@ export function tacticalMoves(state, unitId) {
15
19
  const unit = getUnit(state, unitId);
16
20
  if (unit.owner !== state.turn || unit.actions <= 0)
17
21
  return [];
22
+ //computed once per call rather than once per candidate cell - tacticalPathCost used to
23
+ //redo this same enemy scan and neighbour allocation for every one of the up to width*height
24
+ //cells below, which is pure repeated work: neither depends on the candidate destination
25
+ const engaged = tacticalEngaged(state, unit);
26
+ const zone = tacticalZone(state, unit, engaged);
18
27
  const out = [];
19
28
  for (let y = 0; y < state.height; y++)
20
29
  for (let x = 0; x < state.width; x++) {
21
30
  if ((x === unit.x && y === unit.y) || !state.cells[y * state.width + x].passable || occupied(state, x, y))
22
31
  continue;
23
- const cost = tacticalPathCost(state, unit, x, y, unit.actions);
32
+ const cost = tacticalPathCost(state, unit, x, y, unit.actions, zone);
24
33
  if (cost !== null)
25
34
  out.push({ unit: unitId, x, y, cost });
26
35
  }
@@ -95,13 +104,26 @@ function occupied(state, x, y) { return state.units.some((unit) => unit.x === x
95
104
  function tacticalInside(state, x, y) { return x >= 0 && y >= 0 && x < state.width && y < state.height; }
96
105
  function tacticalNeighbours(state, x, y) { return state.shape === 'hex' ? hexNeighbors(x, y) : [{ x: x - 1, y }, { x: x + 1, y }, { x, y: y - 1 }, { x, y: y + 1 }]; }
97
106
  function tacticalDistance(state, a, b) { return state.shape === 'hex' ? hexDistance(a, b) : Math.abs(a.x - b.x) + Math.abs(a.y - b.y); }
98
- //the real walking distance to (targetX, targetY), never exceeding `budget` steps, or null
99
- //if it cannot be reached within that budget - a move's true cost, not straight-line distance
100
- function tacticalPathCost(state, unit, targetX, targetY, budget) { const todo = [{ x: unit.x, y: unit.y, distance: 0 }]; const seen = new Set([`${unit.x},${unit.y}`]); while (todo.length) {
101
- const current = todo.shift();
107
+ //enemies already adjacent to the unit before it moves - engaging one already lifts its zone
108
+ function tacticalEngaged(state, unit) { return new Set(state.units.filter((other) => other.owner !== unit.owner && tacticalNeighbours(state, unit.x, unit.y).some((cell) => cell.x === other.x && cell.y === other.y)).map((other) => other.id)); }
109
+ //cells adjacent to an enemy the unit is not already engaged with - stepping into one uses up
110
+ //the rest of a move (standard zone-of-control), though it can still be entered as a final stop
111
+ function tacticalZone(state, unit, engaged) { const zone = new Set(); for (const enemy of state.units) {
112
+ if (enemy.owner === unit.owner || engaged.has(enemy.id))
113
+ continue;
114
+ for (const cell of tacticalNeighbours(state, enemy.x, enemy.y))
115
+ zone.add(`${cell.x},${cell.y}`);
116
+ } return zone; }
117
+ //the real walking distance to (targetX, targetY), never exceeding `budget` steps, or null if
118
+ //it cannot be reached within that budget - a move's true cost, not straight-line distance.
119
+ //`zone` is precomputed once by the caller (see tacticalMoves) rather than recomputed here on
120
+ //every call, since neither depends on the candidate target; a plain index cursor stands in
121
+ //for `todo.shift()`, which is O(n) per pop and would make this BFS quadratic in path length
122
+ function tacticalPathCost(state, unit, targetX, targetY, budget, zone) { const todo = [{ x: unit.x, y: unit.y, distance: 0 }]; let head = 0; const seen = new Set([`${unit.x},${unit.y}`]); while (head < todo.length) {
123
+ const current = todo[head++];
102
124
  if (current.x === targetX && current.y === targetY)
103
125
  return current.distance;
104
- if (current.distance >= budget)
126
+ if (current.distance >= budget || (current.distance > 0 && zone.has(`${current.x},${current.y}`)))
105
127
  continue;
106
128
  for (const next of tacticalNeighbours(state, current.x, current.y)) {
107
129
  const key = `${next.x},${next.y}`;
@@ -1 +1 @@
1
- {"version":3,"file":"Tactics.js","sourceRoot":"","sources":["../../src/board/Tactics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Tactics.js","sourceRoot":"","sources":["../../src/board/Tactics.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,10 @@ export { chooseMove, search } from './Engine.ts';
4
4
  export type { ChessEngineOptions, ChessSearchResult } from './Engine.ts';
5
5
  export { BoardGrid, startingCheckers, checkersMoves, applyCheckersMove, startingGo, playGo, passGo, goResult, goScore, startingBackgammon, rollBackgammonDice, backgammonMoves, applyBackgammonMove, createDeck, shuffleDeck, deal, trickWinner, dealSolitaire, drawSolitaire, moveSolitaireTableau, moveSolitaireToFoundation, solitaireWon, rollDice, rollExpression, DiceCup, scoreDice, } from './Classics.ts';
6
6
  export type { BoardOwner, BoardPiece, CheckersSide, CheckersPiece, CheckersMove, CheckersState, GoStone, GoState, DiceCategory, TrickPlay, BackgammonState, BackgammonMove, CardSuit, CardRank, Card, SolitaireState, } from './Classics.ts';
7
- export { startingTactics, addTacticalUnit, tacticalMoves, moveTacticalUnit, setTacticalOverwatch, triggerTacticalOverwatch, tacticalAttack, endTacticalTurn } from './Tactics.ts';
7
+ export { startingTactics, addTacticalUnit, canPlaceTacticalUnit, tacticalMoves, moveTacticalUnit, setTacticalOverwatch, triggerTacticalOverwatch, tacticalAttack, endTacticalTurn } from './Tactics.ts';
8
8
  export type { TacticalShape, TacticalCell, TacticalUnit, TacticalState, TacticalMove, TacticalAttack } from './Tactics.ts';
9
+ export { FactionFog } from './FogOfWar.ts';
10
+ export type { VisionCell } from './FogOfWar.ts';
11
+ export { startingArmy, recruit, recall, bankUnit, armyIncome, applyUpkeep } from './Army.ts';
12
+ export type { UnitTemplate, ArmyState, UpkeepRates } from './Army.ts';
9
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/board/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,EAAE,EACF,UAAU,GACV,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACX,aAAa,EACb,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,OAAO,EACP,SAAS,GACT,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,SAAS,EACT,eAAe,EACf,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,cAAc,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClL,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/board/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,EAAE,EACF,UAAU,GACV,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,EACX,aAAa,EACb,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,OAAO,EACP,SAAS,GACT,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,SAAS,EACT,eAAe,EACf,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,cAAc,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxM,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3H,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export { startingChess, parseFen, cloneChess, legalMoves, applyMove, inCheck, gameResult, sq, squareName, } from './chess.js';
2
2
  export { chooseMove, search } from './Engine.js';
3
3
  export { BoardGrid, startingCheckers, checkersMoves, applyCheckersMove, startingGo, playGo, passGo, goResult, goScore, startingBackgammon, rollBackgammonDice, backgammonMoves, applyBackgammonMove, createDeck, shuffleDeck, deal, trickWinner, dealSolitaire, drawSolitaire, moveSolitaireTableau, moveSolitaireToFoundation, solitaireWon, rollDice, rollExpression, DiceCup, scoreDice, } from './Classics.js';
4
- export { startingTactics, addTacticalUnit, tacticalMoves, moveTacticalUnit, setTacticalOverwatch, triggerTacticalOverwatch, tacticalAttack, endTacticalTurn } from './Tactics.js';
4
+ export { startingTactics, addTacticalUnit, canPlaceTacticalUnit, tacticalMoves, moveTacticalUnit, setTacticalOverwatch, triggerTacticalOverwatch, tacticalAttack, endTacticalTurn } from './Tactics.js';
5
+ export { FactionFog } from './FogOfWar.js';
6
+ export { startingArmy, recruit, recall, bankUnit, armyIncome, applyUpkeep } from './Army.js';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/board/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,EAAE,EACF,UAAU,GACV,MAAM,YAAY,CAAC;AAYpB,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,OAAO,EACP,SAAS,GACT,MAAM,eAAe,CAAC;AAmBvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/board/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,EAAE,EACF,UAAU,GACV,MAAM,YAAY,CAAC;AAYpB,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,IAAI,EACJ,WAAW,EACX,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,OAAO,EACP,SAAS,GACT,MAAM,eAAe,CAAC;AAmBvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAExM,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface FeedbackRequest {
2
+ message: string;
3
+ contact?: string;
4
+ context?: Record<string, string | number | boolean>;
5
+ }
6
+ export interface FeedbackOptions {
7
+ endpoint: string;
8
+ timeoutMs?: number;
9
+ fetch?: typeof globalThis.fetch;
10
+ }
11
+ export interface FeedbackResponse {
12
+ ok: boolean;
13
+ status: number;
14
+ }
15
+ /** Small, injectable transport for a game's own feedback endpoint. */
16
+ export declare class FeedbackClient {
17
+ private readonly endpoint;
18
+ private readonly timeoutMs;
19
+ private readonly fetchFn;
20
+ constructor(options: FeedbackOptions);
21
+ submit(request: FeedbackRequest): Promise<FeedbackResponse>;
22
+ }
23
+ //# sourceMappingURL=Feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Feedback.d.ts","sourceRoot":"","sources":["../../src/core/Feedback.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CACf;AAED,sEAAsE;AACtE,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD,YAAY,OAAO,EAAE,eAAe,EAOnC;IAEK,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgBhE;CACD"}
@@ -0,0 +1,35 @@
1
+ /** Small, injectable transport for a game's own feedback endpoint. */
2
+ export class FeedbackClient {
3
+ constructor(options) {
4
+ if (!options.endpoint)
5
+ throw new Error('feedback endpoint is required');
6
+ this.endpoint = options.endpoint;
7
+ this.timeoutMs = options.timeoutMs ?? 10000;
8
+ if (!(this.timeoutMs > 0))
9
+ throw new Error('feedback timeout must be positive');
10
+ this.fetchFn = options.fetch ?? globalThis.fetch;
11
+ if (!this.fetchFn)
12
+ throw new Error('fetch is unavailable; provide FeedbackOptions.fetch');
13
+ }
14
+ async submit(request) {
15
+ if (!request.message?.trim())
16
+ throw new Error('feedback message cannot be empty');
17
+ const controller = new AbortController();
18
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
19
+ try {
20
+ const response = await this.fetchFn(this.endpoint, {
21
+ method: 'POST',
22
+ headers: { 'content-type': 'application/json' },
23
+ body: JSON.stringify(request),
24
+ signal: controller.signal,
25
+ });
26
+ if (!response.ok)
27
+ throw new Error(`feedback request failed with HTTP ${response.status}`);
28
+ return { ok: true, status: response.status };
29
+ }
30
+ finally {
31
+ clearTimeout(timer);
32
+ }
33
+ }
34
+ }
35
+ //# sourceMappingURL=Feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Feedback.js","sourceRoot":"","sources":["../../src/core/Feedback.ts"],"names":[],"mappings":"AAiBA,sEAAsE;AACtE,MAAM,OAAO,cAAc;IAK1B,YAAY,OAAwB;QACnC,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAChF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAwB;QACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACnE,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAClD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;aACzB,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC1F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9C,CAAC;gBAAS,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACF,CAAC;CACD"}
@@ -61,10 +61,13 @@ export declare class Game {
61
61
  timeScale: number;
62
62
  /** fires after every frame's update, for systems that are not scene-owned */
63
63
  readonly onFrame: Signal<number>;
64
+ private hitStopRemaining;
65
+ private hitStopScale;
64
66
  private stack;
65
67
  private pending;
66
68
  private options;
67
69
  private started;
70
+ private stopWatchingDpr;
68
71
  constructor(options?: GameOptions);
69
72
  /** the viewport width in css pixels, which is what scenes lay out against */
70
73
  get width(): number;
@@ -95,6 +98,14 @@ export declare class Game {
95
98
  popScene(result?: unknown): void;
96
99
  /** the scene currently updating: the top of the stack */
97
100
  get currentScene(): Scene | null;
101
+ /**
102
+ * Briefly dips `timeScale` toward `scale` for `duration` real seconds, then restores it
103
+ * to 1 - a heavy hit's momentary freeze-frame, distinct from `render.Camera.shake` (which
104
+ * moves the view, not the clock) and from `ui.FloatingText` (a damage number, not a time
105
+ * effect). A second call while one is still running simply replaces it, the same way
106
+ * `Camera.shake` restarts rather than stacking.
107
+ */
108
+ hitStop(duration: number, scale?: number): void;
98
109
  /**
99
110
  * Advances the game by one frame and draws it, without waiting for the browser.
100
111
  *