@datamoc/mw_games 0.1.1 → 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 (360) hide show
  1. package/README.md +57 -32
  2. package/dist/actors/Appearances.js +1 -1
  3. package/dist/actors/Aura.d.ts +29 -0
  4. package/dist/actors/Aura.d.ts.map +1 -0
  5. package/dist/actors/Aura.js +69 -0
  6. package/dist/actors/Aura.js.map +1 -0
  7. package/dist/actors/ItemStatusEffect.d.ts +27 -0
  8. package/dist/actors/ItemStatusEffect.d.ts.map +1 -0
  9. package/dist/actors/ItemStatusEffect.js +35 -0
  10. package/dist/actors/ItemStatusEffect.js.map +1 -0
  11. package/dist/actors/Resource.d.ts.map +1 -1
  12. package/dist/actors/Resource.js +13 -5
  13. package/dist/actors/Resource.js.map +1 -1
  14. package/dist/actors/Support.d.ts +32 -0
  15. package/dist/actors/Support.d.ts.map +1 -0
  16. package/dist/actors/Support.js +60 -0
  17. package/dist/actors/Support.js.map +1 -0
  18. package/dist/actors/Traits.d.ts +29 -0
  19. package/dist/actors/Traits.d.ts.map +1 -0
  20. package/dist/actors/Traits.js +21 -0
  21. package/dist/actors/Traits.js.map +1 -0
  22. package/dist/actors/craft.d.ts.map +1 -1
  23. package/dist/actors/craft.js +6 -2
  24. package/dist/actors/craft.js.map +1 -1
  25. package/dist/actors/index.d.ts +8 -0
  26. package/dist/actors/index.d.ts.map +1 -1
  27. package/dist/actors/index.js +4 -0
  28. package/dist/actors/index.js.map +1 -1
  29. package/dist/assets/Streaming.d.ts +40 -0
  30. package/dist/assets/Streaming.d.ts.map +1 -0
  31. package/dist/assets/Streaming.js +79 -0
  32. package/dist/assets/Streaming.js.map +1 -0
  33. package/dist/assets/index.d.ts +14 -1
  34. package/dist/assets/index.d.ts.map +1 -1
  35. package/dist/assets/index.js +19 -0
  36. package/dist/assets/index.js.map +1 -1
  37. package/dist/audio/Captions.d.ts +15 -0
  38. package/dist/audio/Captions.d.ts.map +1 -0
  39. package/dist/audio/Captions.js +4 -0
  40. package/dist/audio/Captions.js.map +1 -0
  41. package/dist/audio/Midi.d.ts +75 -0
  42. package/dist/audio/Midi.d.ts.map +1 -0
  43. package/dist/audio/Midi.js +186 -0
  44. package/dist/audio/Midi.js.map +1 -0
  45. package/dist/audio/Orchestrator.d.ts +40 -0
  46. package/dist/audio/Orchestrator.d.ts.map +1 -0
  47. package/dist/audio/Orchestrator.js +48 -0
  48. package/dist/audio/Orchestrator.js.map +1 -0
  49. package/dist/audio/Sound.d.ts +3 -0
  50. package/dist/audio/Sound.d.ts.map +1 -1
  51. package/dist/audio/Sound.js +4 -0
  52. package/dist/audio/Sound.js.map +1 -1
  53. package/dist/audio/Synth.d.ts +35 -0
  54. package/dist/audio/Synth.d.ts.map +1 -0
  55. package/dist/audio/Synth.js +96 -0
  56. package/dist/audio/Synth.js.map +1 -0
  57. package/dist/audio/index.d.ts +8 -0
  58. package/dist/audio/index.d.ts.map +1 -1
  59. package/dist/audio/index.js +4 -0
  60. package/dist/audio/index.js.map +1 -1
  61. package/dist/battle/Party.d.ts.map +1 -1
  62. package/dist/battle/Party.js +2 -0
  63. package/dist/battle/Party.js.map +1 -1
  64. package/dist/board/Army.d.ts +17 -0
  65. package/dist/board/Army.d.ts.map +1 -0
  66. package/dist/board/Army.js +48 -0
  67. package/dist/board/Army.js.map +1 -0
  68. package/dist/board/Classics.d.ts.map +1 -1
  69. package/dist/board/Classics.js +14 -6
  70. package/dist/board/Classics.js.map +1 -1
  71. package/dist/board/FogOfWar.d.ts +23 -0
  72. package/dist/board/FogOfWar.d.ts.map +1 -0
  73. package/dist/board/FogOfWar.js +40 -0
  74. package/dist/board/FogOfWar.js.map +1 -0
  75. package/dist/board/Tactics.d.ts +2 -0
  76. package/dist/board/Tactics.d.ts.map +1 -1
  77. package/dist/board/Tactics.js +36 -8
  78. package/dist/board/Tactics.js.map +1 -1
  79. package/dist/board/index.d.ts +5 -1
  80. package/dist/board/index.d.ts.map +1 -1
  81. package/dist/board/index.js +3 -1
  82. package/dist/board/index.js.map +1 -1
  83. package/dist/core/Feedback.d.ts +23 -0
  84. package/dist/core/Feedback.d.ts.map +1 -0
  85. package/dist/core/Feedback.js +35 -0
  86. package/dist/core/Feedback.js.map +1 -0
  87. package/dist/core/Game.d.ts +27 -1
  88. package/dist/core/Game.d.ts.map +1 -1
  89. package/dist/core/Game.js +61 -5
  90. package/dist/core/Game.js.map +1 -1
  91. package/dist/core/Input.d.ts +59 -1
  92. package/dist/core/Input.d.ts.map +1 -1
  93. package/dist/core/Input.js +135 -0
  94. package/dist/core/Input.js.map +1 -1
  95. package/dist/core/Loading.d.ts +48 -0
  96. package/dist/core/Loading.d.ts.map +1 -0
  97. package/dist/core/Loading.js +102 -0
  98. package/dist/core/Loading.js.map +1 -0
  99. package/dist/core/News.d.ts +46 -0
  100. package/dist/core/News.d.ts.map +1 -0
  101. package/dist/core/News.js +79 -0
  102. package/dist/core/News.js.map +1 -0
  103. package/dist/core/PlayerInput.d.ts +38 -0
  104. package/dist/core/PlayerInput.d.ts.map +1 -0
  105. package/dist/core/PlayerInput.js +57 -0
  106. package/dist/core/PlayerInput.js.map +1 -0
  107. package/dist/core/Random.d.ts +2 -2
  108. package/dist/core/Random.js +2 -2
  109. package/dist/core/RunHistory.d.ts +43 -0
  110. package/dist/core/RunHistory.d.ts.map +1 -0
  111. package/dist/core/RunHistory.js +41 -0
  112. package/dist/core/RunHistory.js.map +1 -0
  113. package/dist/core/Sanitize.d.ts +56 -0
  114. package/dist/core/Sanitize.d.ts.map +1 -0
  115. package/dist/core/Sanitize.js +87 -0
  116. package/dist/core/Sanitize.js.map +1 -0
  117. package/dist/core/Save.d.ts +31 -7
  118. package/dist/core/Save.d.ts.map +1 -1
  119. package/dist/core/Save.js +56 -0
  120. package/dist/core/Save.js.map +1 -1
  121. package/dist/core/SaveSync.d.ts +26 -0
  122. package/dist/core/SaveSync.d.ts.map +1 -0
  123. package/dist/core/SaveSync.js +52 -0
  124. package/dist/core/SaveSync.js.map +1 -0
  125. package/dist/core/Scramble.d.ts +13 -0
  126. package/dist/core/Scramble.d.ts.map +1 -0
  127. package/dist/core/Scramble.js +44 -0
  128. package/dist/core/Scramble.js.map +1 -0
  129. package/dist/core/Session.d.ts +21 -0
  130. package/dist/core/Session.d.ts.map +1 -0
  131. package/dist/core/Session.js +11 -0
  132. package/dist/core/Session.js.map +1 -0
  133. package/dist/core/Spawner.d.ts +48 -0
  134. package/dist/core/Spawner.d.ts.map +1 -0
  135. package/dist/core/Spawner.js +65 -0
  136. package/dist/core/Spawner.js.map +1 -0
  137. package/dist/core/Tween.d.ts +25 -0
  138. package/dist/core/Tween.d.ts.map +1 -0
  139. package/dist/core/Tween.js +60 -0
  140. package/dist/core/Tween.js.map +1 -0
  141. package/dist/core/UndoHistory.d.ts +37 -0
  142. package/dist/core/UndoHistory.d.ts.map +1 -0
  143. package/dist/core/UndoHistory.js +49 -0
  144. package/dist/core/UndoHistory.js.map +1 -0
  145. package/dist/core/index.d.ts +22 -0
  146. package/dist/core/index.d.ts.map +1 -1
  147. package/dist/core/index.js +12 -0
  148. package/dist/core/index.js.map +1 -1
  149. package/dist/i18n/Fluent.d.ts +7 -0
  150. package/dist/i18n/Fluent.d.ts.map +1 -0
  151. package/dist/i18n/Fluent.js +86 -0
  152. package/dist/i18n/Fluent.js.map +1 -0
  153. package/dist/i18n/index.d.ts +15 -1
  154. package/dist/i18n/index.d.ts.map +1 -1
  155. package/dist/i18n/index.js +17 -2
  156. package/dist/i18n/index.js.map +1 -1
  157. package/dist/index.d.ts +1 -0
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.js +1 -0
  160. package/dist/index.js.map +1 -1
  161. package/dist/mw_games.global.js +351 -79
  162. package/dist/render/Camera.d.ts +32 -4
  163. package/dist/render/Camera.d.ts.map +1 -1
  164. package/dist/render/Camera.js +58 -23
  165. package/dist/render/Camera.js.map +1 -1
  166. package/dist/render/Capabilities.d.ts +51 -0
  167. package/dist/render/Capabilities.d.ts.map +1 -0
  168. package/dist/render/Capabilities.js +56 -0
  169. package/dist/render/Capabilities.js.map +1 -0
  170. package/dist/render/ColorBlindness.d.ts +16 -0
  171. package/dist/render/ColorBlindness.d.ts.map +1 -0
  172. package/dist/render/ColorBlindness.js +41 -0
  173. package/dist/render/ColorBlindness.js.map +1 -0
  174. package/dist/render/ColorTransformBatcher.d.ts +9 -0
  175. package/dist/render/ColorTransformBatcher.d.ts.map +1 -1
  176. package/dist/render/ColorTransformBatcher.js +131 -19
  177. package/dist/render/ColorTransformBatcher.js.map +1 -1
  178. package/dist/render/Minimap.d.ts +52 -0
  179. package/dist/render/Minimap.d.ts.map +1 -0
  180. package/dist/render/Minimap.js +95 -0
  181. package/dist/render/Minimap.js.map +1 -0
  182. package/dist/render/TileMap.d.ts +2 -2
  183. package/dist/render/TileMap.d.ts.map +1 -1
  184. package/dist/render/TileMap.js +12 -12
  185. package/dist/render/TileMap.js.map +1 -1
  186. package/dist/render/TintedSprite.d.ts +1 -8
  187. package/dist/render/TintedSprite.d.ts.map +1 -1
  188. package/dist/render/TintedSprite.js +3 -111
  189. package/dist/render/TintedSprite.js.map +1 -1
  190. package/dist/render/Viewport.d.ts +46 -0
  191. package/dist/render/Viewport.d.ts.map +1 -0
  192. package/dist/render/Viewport.js +52 -0
  193. package/dist/render/Viewport.js.map +1 -0
  194. package/dist/render/index.d.ts +9 -1
  195. package/dist/render/index.d.ts.map +1 -1
  196. package/dist/render/index.js +5 -1
  197. package/dist/render/index.js.map +1 -1
  198. package/dist/roguelike/FieldOfView.d.ts +1 -1
  199. package/dist/roguelike/Level.d.ts +2 -2
  200. package/dist/roguelike/Level.d.ts.map +1 -1
  201. package/dist/roguelike/Level.js +1 -1
  202. package/dist/roguelike/Level.js.map +1 -1
  203. package/dist/roguelike/Pathfinder.d.ts +3 -3
  204. package/dist/roguelike/Pathfinder.js +2 -2
  205. package/dist/roguelike/Scheduler.d.ts +1 -1
  206. package/dist/roguelike/Scheduler.js +1 -1
  207. package/dist/roguelike/Stealth.d.ts +34 -0
  208. package/dist/roguelike/Stealth.d.ts.map +1 -0
  209. package/dist/roguelike/Stealth.js +35 -0
  210. package/dist/roguelike/Stealth.js.map +1 -0
  211. package/dist/roguelike/generate.d.ts +3 -3
  212. package/dist/roguelike/generate.js +1 -1
  213. package/dist/roguelike/generate.js.map +1 -1
  214. package/dist/roguelike/index.d.ts +2 -0
  215. package/dist/roguelike/index.d.ts.map +1 -1
  216. package/dist/roguelike/index.js +1 -0
  217. package/dist/roguelike/index.js.map +1 -1
  218. package/dist/rpg/Collision.d.ts +42 -0
  219. package/dist/rpg/Collision.d.ts.map +1 -0
  220. package/dist/rpg/Collision.js +77 -0
  221. package/dist/rpg/Collision.js.map +1 -0
  222. package/dist/rpg/FreeMover.d.ts +45 -0
  223. package/dist/rpg/FreeMover.d.ts.map +1 -0
  224. package/dist/rpg/FreeMover.js +68 -0
  225. package/dist/rpg/FreeMover.js.map +1 -0
  226. package/dist/rpg/Marshal.d.ts +65 -0
  227. package/dist/rpg/Marshal.d.ts.map +1 -0
  228. package/dist/rpg/Marshal.js +393 -0
  229. package/dist/rpg/Marshal.js.map +1 -0
  230. package/dist/rpg/Quest.d.ts +41 -0
  231. package/dist/rpg/Quest.d.ts.map +1 -1
  232. package/dist/rpg/Quest.js +39 -6
  233. package/dist/rpg/Quest.js.map +1 -1
  234. package/dist/rpg/index.d.ts +7 -1
  235. package/dist/rpg/index.d.ts.map +1 -1
  236. package/dist/rpg/index.js +3 -0
  237. package/dist/rpg/index.js.map +1 -1
  238. package/dist/stage/DialogueStage.d.ts +2 -3
  239. package/dist/stage/DialogueStage.d.ts.map +1 -1
  240. package/dist/stage/DialogueStage.js +21 -30
  241. package/dist/stage/DialogueStage.js.map +1 -1
  242. package/dist/stage/index.d.ts +1 -1
  243. package/dist/stage/index.d.ts.map +1 -1
  244. package/dist/stage/script.d.ts +32 -3
  245. package/dist/stage/script.d.ts.map +1 -1
  246. package/dist/stage/script.js +0 -0
  247. package/dist/stage/script.js.map +1 -1
  248. package/dist/three-d/Character3D.d.ts +48 -0
  249. package/dist/three-d/Character3D.d.ts.map +1 -0
  250. package/dist/three-d/Character3D.js +96 -0
  251. package/dist/three-d/Character3D.js.map +1 -0
  252. package/dist/three-d/Engine3D.d.ts +23 -0
  253. package/dist/three-d/Engine3D.d.ts.map +1 -0
  254. package/dist/three-d/Engine3D.js +45 -0
  255. package/dist/three-d/Engine3D.js.map +1 -0
  256. package/dist/three-d/Grid.d.ts +14 -0
  257. package/dist/three-d/Grid.d.ts.map +1 -0
  258. package/dist/three-d/Grid.js +13 -0
  259. package/dist/three-d/Grid.js.map +1 -0
  260. package/dist/three-d/Heightmap.d.ts +35 -0
  261. package/dist/three-d/Heightmap.d.ts.map +1 -0
  262. package/dist/three-d/Heightmap.js +29 -0
  263. package/dist/three-d/Heightmap.js.map +1 -0
  264. package/dist/three-d/Models.d.ts +12 -0
  265. package/dist/three-d/Models.d.ts.map +1 -0
  266. package/dist/three-d/Models.js +14 -0
  267. package/dist/three-d/Models.js.map +1 -0
  268. package/dist/three-d/TileGrid3D.d.ts +21 -0
  269. package/dist/three-d/TileGrid3D.d.ts.map +1 -0
  270. package/dist/three-d/TileGrid3D.js +65 -0
  271. package/dist/three-d/TileGrid3D.js.map +1 -0
  272. package/dist/three-d/Vox.d.ts +24 -0
  273. package/dist/three-d/Vox.d.ts.map +1 -0
  274. package/dist/three-d/Vox.js +93 -0
  275. package/dist/three-d/Vox.js.map +1 -0
  276. package/dist/three-d/index.d.ts +13 -0
  277. package/dist/three-d/index.d.ts.map +1 -0
  278. package/dist/three-d/index.js +7 -0
  279. package/dist/three-d/index.js.map +1 -0
  280. package/dist/ui/Bar.d.ts +49 -0
  281. package/dist/ui/Bar.d.ts.map +1 -0
  282. package/dist/ui/Bar.js +70 -0
  283. package/dist/ui/Bar.js.map +1 -0
  284. package/dist/ui/BitmapLabel.d.ts +42 -0
  285. package/dist/ui/BitmapLabel.d.ts.map +1 -0
  286. package/dist/ui/BitmapLabel.js +59 -0
  287. package/dist/ui/BitmapLabel.js.map +1 -0
  288. package/dist/ui/Button.d.ts +52 -0
  289. package/dist/ui/Button.d.ts.map +1 -0
  290. package/dist/ui/Button.js +147 -0
  291. package/dist/ui/Button.js.map +1 -0
  292. package/dist/ui/FloatingText.d.ts +28 -0
  293. package/dist/ui/FloatingText.d.ts.map +1 -0
  294. package/dist/ui/FloatingText.js +39 -0
  295. package/dist/ui/FloatingText.js.map +1 -0
  296. package/dist/ui/HelpScreen.d.ts +29 -0
  297. package/dist/ui/HelpScreen.d.ts.map +1 -0
  298. package/dist/ui/HelpScreen.js +39 -0
  299. package/dist/ui/HelpScreen.js.map +1 -0
  300. package/dist/ui/IconGrid.d.ts +8 -0
  301. package/dist/ui/IconGrid.d.ts.map +1 -1
  302. package/dist/ui/IconGrid.js +27 -1
  303. package/dist/ui/IconGrid.js.map +1 -1
  304. package/dist/ui/Label.d.ts +10 -1
  305. package/dist/ui/Label.d.ts.map +1 -1
  306. package/dist/ui/Label.js +25 -2
  307. package/dist/ui/Label.js.map +1 -1
  308. package/dist/ui/ListView.d.ts +12 -1
  309. package/dist/ui/ListView.d.ts.map +1 -1
  310. package/dist/ui/ListView.js +56 -2
  311. package/dist/ui/ListView.js.map +1 -1
  312. package/dist/ui/LoadingScreen.d.ts +31 -0
  313. package/dist/ui/LoadingScreen.d.ts.map +1 -0
  314. package/dist/ui/LoadingScreen.js +60 -0
  315. package/dist/ui/LoadingScreen.js.map +1 -0
  316. package/dist/ui/MessageBox.d.ts +27 -1
  317. package/dist/ui/MessageBox.d.ts.map +1 -1
  318. package/dist/ui/MessageBox.js +63 -14
  319. package/dist/ui/MessageBox.js.map +1 -1
  320. package/dist/ui/RebindScreen.d.ts +55 -0
  321. package/dist/ui/RebindScreen.d.ts.map +1 -0
  322. package/dist/ui/RebindScreen.js +114 -0
  323. package/dist/ui/RebindScreen.js.map +1 -0
  324. package/dist/ui/Toast.d.ts +44 -0
  325. package/dist/ui/Toast.d.ts.map +1 -0
  326. package/dist/ui/Toast.js +89 -0
  327. package/dist/ui/Toast.js.map +1 -0
  328. package/dist/ui/VerticalLabel.d.ts +5 -0
  329. package/dist/ui/VerticalLabel.d.ts.map +1 -1
  330. package/dist/ui/VerticalLabel.js +18 -7
  331. package/dist/ui/VerticalLabel.js.map +1 -1
  332. package/dist/ui/Window.d.ts +6 -0
  333. package/dist/ui/Window.d.ts.map +1 -1
  334. package/dist/ui/Window.js +16 -1
  335. package/dist/ui/Window.js.map +1 -1
  336. package/dist/ui/WindowStack.d.ts +1 -0
  337. package/dist/ui/WindowStack.d.ts.map +1 -1
  338. package/dist/ui/WindowStack.js +4 -1
  339. package/dist/ui/WindowStack.js.map +1 -1
  340. package/dist/ui/index.d.ts +17 -1
  341. package/dist/ui/index.d.ts.map +1 -1
  342. package/dist/ui/index.js +9 -1
  343. package/dist/ui/index.js.map +1 -1
  344. package/dist/ui/theme.d.ts +21 -0
  345. package/dist/ui/theme.d.ts.map +1 -1
  346. package/dist/ui/theme.js +42 -0
  347. package/dist/ui/theme.js.map +1 -1
  348. package/dist/version.d.ts +13 -0
  349. package/dist/version.d.ts.map +1 -0
  350. package/dist/version.js +13 -0
  351. package/dist/version.js.map +1 -0
  352. package/dist/world/Environment.d.ts +35 -0
  353. package/dist/world/Environment.d.ts.map +1 -0
  354. package/dist/world/Environment.js +55 -0
  355. package/dist/world/Environment.js.map +1 -0
  356. package/dist/world/index.d.ts +2 -0
  357. package/dist/world/index.d.ts.map +1 -1
  358. package/dist/world/index.js +1 -0
  359. package/dist/world/index.js.map +1 -1
  360. package/package.json +40 -4
@@ -0,0 +1,40 @@
1
+ import type { Music } from './Music.ts';
2
+ import type { Sound } from './Sound.ts';
3
+ /** what playing this state's music should look like - `fadeDuration` follows `Music.play`'s own default */
4
+ export interface OrchestratorState {
5
+ track: string;
6
+ fadeDuration?: number;
7
+ }
8
+ /**
9
+ * The data a game writes once instead of scattering `Music.play`/`Sound.play` calls across
10
+ * every place a fight starts or a menu opens: name the states ("exploring", "combat",
11
+ * "boss", "menu") and the cues ("hit", "levelUp"), and call `enter`/`trigger` by name from
12
+ * then on.
13
+ *
14
+ * `enter` is idempotent by track, not by state name - two state names that happen to map to
15
+ * the same track will not refade into each other either, since there is nothing to refade
16
+ * to. Re-entering "combat" mid-fight (the same fight, the same track) must not reset the
17
+ * music, which is the one behaviour a direct `Music.play` call at every call site cannot
18
+ * give you for free: the orchestrator remembers the current track and treats entering an
19
+ * already-current one as a no-op.
20
+ *
21
+ * Cues are separate from states because they are fire-and-forget one-shots (`Sound`, not
22
+ * `Music`) - folding them into `enter` would conflate "this is where we are" with "this just
23
+ * happened".
24
+ */
25
+ export declare class Orchestrator {
26
+ private states;
27
+ private cues;
28
+ private currentTrack;
29
+ private music;
30
+ constructor(music: Music);
31
+ /** defines or replaces one state's music mapping */
32
+ define(state: string, mapping: OrchestratorState): void;
33
+ /** switches to `state`'s track, crossfading; a no-op if that track is already playing */
34
+ enter(state: string): void;
35
+ /** registers the one-shot sound played by `trigger(event)` */
36
+ on(event: string, cue: Sound): void;
37
+ /** plays the sound registered for `event`, if any; silently does nothing otherwise */
38
+ trigger(event: string): void;
39
+ }
40
+ //# sourceMappingURL=Orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Orchestrator.d.ts","sourceRoot":"","sources":["../../src/audio/Orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,2GAA2G;AAC3G,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAQ;IAErB,YAAY,KAAK,EAAE,KAAK,EAEvB;IAED,oDAAoD;IACpD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAEtD;IAED,yFAAyF;IACzF,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAQzB;IAED,8DAA8D;IAC9D,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI,CAElC;IAED,sFAAsF;IACtF,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE3B;CACD"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The data a game writes once instead of scattering `Music.play`/`Sound.play` calls across
3
+ * every place a fight starts or a menu opens: name the states ("exploring", "combat",
4
+ * "boss", "menu") and the cues ("hit", "levelUp"), and call `enter`/`trigger` by name from
5
+ * then on.
6
+ *
7
+ * `enter` is idempotent by track, not by state name - two state names that happen to map to
8
+ * the same track will not refade into each other either, since there is nothing to refade
9
+ * to. Re-entering "combat" mid-fight (the same fight, the same track) must not reset the
10
+ * music, which is the one behaviour a direct `Music.play` call at every call site cannot
11
+ * give you for free: the orchestrator remembers the current track and treats entering an
12
+ * already-current one as a no-op.
13
+ *
14
+ * Cues are separate from states because they are fire-and-forget one-shots (`Sound`, not
15
+ * `Music`) - folding them into `enter` would conflate "this is where we are" with "this just
16
+ * happened".
17
+ */
18
+ export class Orchestrator {
19
+ constructor(music) {
20
+ this.states = new Map();
21
+ this.cues = new Map();
22
+ this.currentTrack = null;
23
+ this.music = music;
24
+ }
25
+ /** defines or replaces one state's music mapping */
26
+ define(state, mapping) {
27
+ this.states.set(state, mapping);
28
+ }
29
+ /** switches to `state`'s track, crossfading; a no-op if that track is already playing */
30
+ enter(state) {
31
+ const mapping = this.states.get(state);
32
+ if (!mapping)
33
+ throw new Error(`Orchestrator: no state defined for "${state}"`);
34
+ if (mapping.track === this.currentTrack)
35
+ return;
36
+ this.music.play(mapping.track, mapping.fadeDuration);
37
+ this.currentTrack = mapping.track;
38
+ }
39
+ /** registers the one-shot sound played by `trigger(event)` */
40
+ on(event, cue) {
41
+ this.cues.set(event, cue);
42
+ }
43
+ /** plays the sound registered for `event`, if any; silently does nothing otherwise */
44
+ trigger(event) {
45
+ this.cues.get(event)?.play();
46
+ }
47
+ }
48
+ //# sourceMappingURL=Orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Orchestrator.js","sourceRoot":"","sources":["../../src/audio/Orchestrator.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,YAAY;IAMxB,YAAY,KAAY;QALhB,WAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;QAC9C,SAAI,GAAG,IAAI,GAAG,EAAiB,CAAC;QAChC,iBAAY,GAAkB,IAAI,CAAC;QAI1C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,oDAAoD;IACpD,MAAM,CAAC,KAAa,EAAE,OAA0B;QAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,KAAa;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,KAAK,GAAG,CAAC,CAAC;QAE/E,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY;YAAE,OAAO;QAEhD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,8DAA8D;IAC9D,EAAE,CAAC,KAAa,EAAE,GAAU;QAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,sFAAsF;IACtF,OAAO,CAAC,KAAa;QACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;CACD"}
@@ -5,6 +5,8 @@ export interface SoundOptions {
5
5
  volume?: number;
6
6
  /** creates one playable instance for the resolved path; defaults to a real `Audio` element */
7
7
  create?: (path: string) => Playable;
8
+ /** shown by a captioning overlay (via `Captions.onCaption`) every time this sound plays */
9
+ caption?: string;
8
10
  }
9
11
  /**
10
12
  * A sound effect, pooled so the same clip can overlap itself. A dozen arrows landing in the
@@ -15,6 +17,7 @@ export interface SoundOptions {
15
17
  export declare class Sound {
16
18
  private pool;
17
19
  private next;
20
+ private caption?;
18
21
  volume: number;
19
22
  constructor(path: string, options?: SoundOptions);
20
23
  play(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"Sound.d.ts","sourceRoot":"","sources":["../../src/audio/Sound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC;CACpC;AAED;;;;;GAKG;AACH,qBAAa,KAAK;IACjB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,IAAI,CAAK;IACjB,MAAM,EAAE,MAAM,CAAC;IAEf,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,EAKnD;IAED,IAAI,IAAI,IAAI,CAOX;IAED,OAAO,IAAI,IAAI,CAKd;CACD"}
1
+ {"version":3,"file":"Sound.d.ts","sourceRoot":"","sources":["../../src/audio/Sound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,WAAW,YAAY;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC;IAEpC,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,KAAK;IACjB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,MAAM,EAAE,MAAM,CAAC;IAEf,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,EAMnD;IAED,IAAI,IAAI,IAAI,CASX;IAED,OAAO,IAAI,IAAI,CAKd;CACD"}
@@ -1,4 +1,5 @@
1
1
  import { createAudio } from './Playable.js';
2
+ import { onCaption } from './Captions.js';
2
3
  /**
3
4
  * A sound effect, pooled so the same clip can overlap itself. A dozen arrows landing in the
4
5
  * same second must not cut each other off, which a single `<audio>` element would - the
@@ -11,6 +12,7 @@ export class Sound {
11
12
  const size = Math.max(1, options.poolSize ?? 4);
12
13
  const create = options.create ?? createAudio;
13
14
  this.volume = options.volume ?? 1;
15
+ this.caption = options.caption;
14
16
  this.pool = Array.from({ length: size }, () => create(path));
15
17
  }
16
18
  play() {
@@ -19,6 +21,8 @@ export class Sound {
19
21
  audio.volume = this.volume;
20
22
  audio.currentTime = 0;
21
23
  void audio.play();
24
+ if (this.caption)
25
+ onCaption.dispatch({ text: this.caption });
22
26
  }
23
27
  stopAll() {
24
28
  for (const audio of this.pool) {
@@ -1 +1 @@
1
- {"version":3,"file":"Sound.js","sourceRoot":"","sources":["../../src/audio/Sound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAW3D;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IAKjB,YAAY,IAAY,EAAE,OAAO,GAAiB,EAAE;QAH5C,SAAI,GAAG,CAAC,CAAC;QAIhB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAE/C,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACtB,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAED,OAAO;QACN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD"}
1
+ {"version":3,"file":"Sound.js","sourceRoot":"","sources":["../../src/audio/Sound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAc1C;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IAMjB,YAAY,IAAY,EAAE,OAAO,GAAiB,EAAE;QAJ5C,SAAI,GAAG,CAAC,CAAC;QAKhB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAE/C,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACtB,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QAElB,IAAI,IAAI,CAAC,OAAO;YAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO;QACN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD"}
@@ -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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Party.d.ts","sourceRoot":"","sources":["../../src/battle/Party.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC;IACnB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAW;IAE1B,YAAY,UAAU,EAAE,MAAM,EAE7B;IAED,IAAI,OAAO,IAAI,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAEnC;IAED,IAAI,KAAK,IAAI,SAAS,CAAC,EAAE,CAExB;IAED,sEAAsE;IACtE,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAIrB;IAED,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMzB;IAED,2FAA2F;IAC3F,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAQvD;IAED,qCAAqC;IACrC,IAAI,aAAa,IAAI,CAAC,EAAE,CAEvB;CACD"}
1
+ {"version":3,"file":"Party.d.ts","sourceRoot":"","sources":["../../src/battle/Party.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC;IACnB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAW;IAE1B,YAAY,UAAU,EAAE,MAAM,EAE7B;IAED,IAAI,OAAO,IAAI,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAEnC;IAED,IAAI,KAAK,IAAI,SAAS,CAAC,EAAE,CAExB;IAED,sEAAsE;IACtE,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAIrB;IAED,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMzB;IAED,2FAA2F;IAC3F,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CASvD;IAED,qCAAqC;IACrC,IAAI,aAAa,IAAI,CAAC,EAAE,CAEvB;CACD"}
@@ -32,6 +32,8 @@ export class Party {
32
32
  }
33
33
  /** brings a boxed creature into a specific active slot, swapping out whatever was there */
34
34
  withdraw(storageIndex, activeSlot) {
35
+ if (activeSlot < 0 || activeSlot >= this.active.length)
36
+ return;
35
37
  const creature = this.storage[storageIndex];
36
38
  if (!creature)
37
39
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"Party.js","sourceRoot":"","sources":["../../src/battle/Party.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,KAAK;IAIjB,YAAY,UAAkB;QAFtB,YAAO,GAAQ,EAAE,CAAC;QAGzB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,sEAAsE;IACtE,GAAG,CAAC,QAAW;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;;YACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,KAAa;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,2FAA2F;IAC3F,QAAQ,CAAC,YAAoB,EAAE,UAAkB;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QACnC,IAAI,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,qCAAqC;IACrC,IAAI,aAAa;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAU,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACtD,CAAC;CACD"}
1
+ {"version":3,"file":"Party.js","sourceRoot":"","sources":["../../src/battle/Party.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,KAAK;IAIjB,YAAY,UAAkB;QAFtB,YAAO,GAAQ,EAAE,CAAC;QAGzB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,sEAAsE;IACtE,GAAG,CAAC,QAAW;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;;YACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,KAAa;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,2FAA2F;IAC3F,QAAQ,CAAC,YAAoB,EAAE,UAAkB;QAChD,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QACnC,IAAI,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,qCAAqC;IACrC,IAAI,aAAa;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAU,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACtD,CAAC;CACD"}
@@ -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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Classics.d.ts","sourceRoot":"","sources":["../../src/board/Classics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Classics.d.ts","sourceRoot":"","sources":["../../src/board/Classics.ts"],"names":[],"mappings":"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"}
@@ -103,12 +103,22 @@ export function playGo(state, x, y) {
103
103
  board[index] = state.turn;
104
104
  const enemy = state.turn === 'black' ? 'white' : 'black';
105
105
  let captured = 0;
106
- for (const neighbour of goNeighbours(state, index))
107
- if (board[neighbour] === enemy && liberties(board, state.size, neighbour) === 0)
108
- captured += removeGroup(board, state.size, neighbour);
106
+ //tracked directly rather than diffed against the old board afterwards, since the played
107
+ //stone's own cell also differs and diffing can't tell the two apart
108
+ let soleCaptured = null;
109
+ for (const neighbour of goNeighbours(state, index)) {
110
+ if (board[neighbour] !== enemy || liberties(board, state.size, neighbour) !== 0)
111
+ continue;
112
+ const removed = group(board, state.size, neighbour);
113
+ if (removed.length === 1)
114
+ soleCaptured = removed[0];
115
+ for (const cell of removed)
116
+ board[cell] = null;
117
+ captured += removed.length;
118
+ }
109
119
  if (liberties(board, state.size, index) === 0)
110
120
  throw new Error('suicide is not a legal Go move');
111
- state.ko = captured === 1 && liberties(board, state.size, index) === 1 ? state.board.findIndex((stone, i) => stone !== board[i]) : null;
121
+ state.ko = captured === 1 && liberties(board, state.size, index) === 1 ? soleCaptured : null;
112
122
  state.board = board;
113
123
  state.turn = enemy;
114
124
  state.passes = 0;
@@ -158,8 +168,6 @@ function liberties(board, size, start) { const cells = group(board, size, start)
158
168
  if (nx >= 0 && ny >= 0 && nx < size && ny < size && board[ny * size + nx] === null)
159
169
  empty.add(ny * size + nx);
160
170
  } return empty.size; }
161
- function removeGroup(board, size, start) { const cells = group(board, size, start); for (const index of cells)
162
- board[index] = null; return cells.length; }
163
171
  export function startingBackgammon() { const points = new Array(24).fill(0); points[0] = 2; points[11] = 5; points[16] = 3; points[18] = 5; points[23] = -2; points[12] = -5; points[7] = -3; points[5] = -5; return { points, bar: { white: 0, black: 0 }, off: { white: 0, black: 0 }, turn: 'white' }; }
164
172
  export function rollBackgammonDice() { const dice = rollDice(2, 6); return dice[0] === dice[1] ? [...dice, ...dice] : dice; }
165
173
  export function backgammonMoves(state, dice) { const side = state.turn === 'white' ? 1 : -1; const out = []; for (const die of dice) {