@datamoc/mw_games 0.44.2 → 0.46.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 (1695) hide show
  1. package/3d/models.d.ts +1 -0
  2. package/3d/models.js +1 -0
  3. package/3d.d.ts +1 -0
  4. package/3d.js +1 -0
  5. package/README.md +5 -732
  6. package/actors.d.ts +1 -0
  7. package/actors.js +1 -0
  8. package/ai/lua.d.ts +1 -0
  9. package/ai/lua.js +1 -0
  10. package/ai.d.ts +1 -0
  11. package/ai.js +1 -0
  12. package/assets/binary.d.ts +1 -0
  13. package/assets/binary.js +1 -0
  14. package/assets/paths.d.ts +1 -0
  15. package/assets/paths.js +1 -0
  16. package/assets.d.ts +1 -0
  17. package/assets.js +1 -0
  18. package/audio.d.ts +1 -0
  19. package/audio.js +1 -0
  20. package/battle.d.ts +1 -0
  21. package/battle.js +1 -0
  22. package/board.d.ts +1 -0
  23. package/board.js +1 -0
  24. package/core.d.ts +1 -0
  25. package/core.js +1 -0
  26. package/headless.d.ts +1 -0
  27. package/headless.js +1 -0
  28. package/i18n.d.ts +1 -0
  29. package/i18n.js +1 -0
  30. package/index.d.ts +1 -0
  31. package/index.js +1 -0
  32. package/mwl/presentation.d.ts +1 -0
  33. package/mwl/presentation.js +1 -0
  34. package/mwl/pyroeis.d.ts +1 -0
  35. package/mwl/pyroeis.js +1 -0
  36. package/mwl.d.ts +1 -0
  37. package/mwl.js +1 -0
  38. package/package.json +212 -394
  39. package/physics/xpbd.d.ts +1 -0
  40. package/physics/xpbd.js +1 -0
  41. package/physics.d.ts +1 -0
  42. package/physics.js +1 -0
  43. package/roguelike.d.ts +1 -0
  44. package/roguelike.js +1 -0
  45. package/rpg.d.ts +1 -0
  46. package/rpg.js +1 -0
  47. package/simulation.d.ts +1 -0
  48. package/simulation.js +1 -0
  49. package/skeleton.d.ts +1 -0
  50. package/skeleton.js +1 -0
  51. package/testing.d.ts +1 -0
  52. package/testing.js +1 -0
  53. package/threads.d.ts +1 -0
  54. package/threads.js +1 -0
  55. package/tools/asset-report.d.mts +1 -37
  56. package/tools/asset-report.mjs +1 -157
  57. package/tools/audio.d.mts +1 -75
  58. package/tools/audio.mjs +1 -437
  59. package/tools/audit-adoptions.d.mts +1 -65
  60. package/tools/audit-adoptions.mjs +1 -252
  61. package/tools/benchmark-browser.d.mts +1 -33
  62. package/tools/benchmark-browser.mjs +1 -169
  63. package/tools/benchmark-history.d.mts +1 -8
  64. package/tools/benchmark-history.mjs +1 -31
  65. package/tools/browser-driver.d.mts +1 -122
  66. package/tools/browser-driver.mjs +1 -861
  67. package/tools/browser-smoke.d.mts +1 -30
  68. package/tools/browser-smoke.mjs +1 -184
  69. package/tools/build-tablebases.d.mts +1 -22
  70. package/tools/build-tablebases.mjs +1 -557
  71. package/tools/bundle-size.d.mts +1 -11
  72. package/tools/bundle-size.mjs +1 -142
  73. package/tools/classic-html.d.mts +1 -6
  74. package/tools/classic-html.mjs +1 -69
  75. package/tools/compile-openings.d.mts +1 -20
  76. package/tools/compile-openings.mjs +1 -138
  77. package/tools/compile-resources.d.mts +1 -66
  78. package/tools/compile-resources.mjs +1 -406
  79. package/tools/compress-dist.d.mts +1 -42
  80. package/tools/compress-dist.mjs +1 -193
  81. package/tools/csp.d.mts +1 -7
  82. package/tools/csp.mjs +1 -65
  83. package/tools/emit-page.d.mts +1 -61
  84. package/tools/emit-page.mjs +1 -273
  85. package/tools/extract-html.d.mts +1 -18
  86. package/tools/extract-html.mjs +1 -235
  87. package/tools/extract-rgssad.d.mts +1 -5
  88. package/tools/extract-rgssad.mjs +1 -64
  89. package/tools/find-chrome.d.mts +1 -7
  90. package/tools/find-chrome.mjs +1 -106
  91. package/tools/i18n-edit.d.mts +1 -29
  92. package/tools/i18n-edit.mjs +1 -748
  93. package/tools/init.d.mts +1 -5
  94. package/tools/init.mjs +1 -155
  95. package/tools/make-example-assets.d.mts +1 -2
  96. package/tools/make-example-assets.mjs +1 -731
  97. package/tools/multiplayer-server.d.mts +1 -27
  98. package/tools/multiplayer-server.mjs +1 -199
  99. package/tools/play-uci.d.mts +1 -26
  100. package/tools/play-uci.mjs +1 -205
  101. package/tools/sbom.d.mts +1 -83
  102. package/tools/sbom.mjs +1 -340
  103. package/tools/single-file.d.mts +1 -33
  104. package/tools/single-file.mjs +1 -239
  105. package/tools/soundfonts.d.mts +1 -79
  106. package/tools/soundfonts.mjs +1 -301
  107. package/tools/svg-optimise.d.mts +1 -8
  108. package/tools/svg-optimise.mjs +1 -45
  109. package/tools/verify-scenarios.d.mts +1 -15
  110. package/tools/verify-scenarios.mjs +1 -133
  111. package/tools/vite.d.mts +1 -17
  112. package/tools/vite.mjs +1 -102
  113. package/tools/webp-convert.d.mts +1 -8
  114. package/tools/webp-convert.mjs +1 -98
  115. package/two-d/pixi-interop.d.ts +1 -0
  116. package/two-d/pixi-interop.js +1 -0
  117. package/two-d/presentation.d.ts +1 -0
  118. package/two-d/presentation.js +1 -0
  119. package/two-d/render.d.ts +1 -0
  120. package/two-d/render.js +1 -0
  121. package/two-d/stage.d.ts +1 -0
  122. package/two-d/stage.js +1 -0
  123. package/two-d/ui.d.ts +1 -0
  124. package/two-d/ui.js +1 -0
  125. package/two-d.d.ts +1 -0
  126. package/two-d.js +1 -0
  127. package/world.d.ts +1 -0
  128. package/world.js +1 -0
  129. package/CHANGELOG.md +0 -3196
  130. package/LICENSE +0 -373
  131. package/MWG - Best Practices.md +0 -97
  132. package/MWG - Deep Code and Architecture Review.md +0 -238
  133. package/REFERENCE.md +0 -2256
  134. package/api-surface.json +0 -18128
  135. package/data/microgm-essential.PROVENANCE.md +0 -13
  136. package/data/microgm-essential.sf2 +0 -0
  137. package/data/microgm-opt.PROVENANCE.md +0 -23
  138. package/data/microgm-opt.sf2 +0 -0
  139. package/data/soundfont-catalog.json +0 -191
  140. package/dist/actors/Advancement.d.ts +0 -90
  141. package/dist/actors/Advancement.d.ts.map +0 -1
  142. package/dist/actors/Advancement.js +0 -115
  143. package/dist/actors/Advancement.js.map +0 -1
  144. package/dist/actors/Affix.d.ts +0 -96
  145. package/dist/actors/Affix.d.ts.map +0 -1
  146. package/dist/actors/Affix.js +0 -68
  147. package/dist/actors/Affix.js.map +0 -1
  148. package/dist/actors/Appearances.d.ts +0 -48
  149. package/dist/actors/Appearances.d.ts.map +0 -1
  150. package/dist/actors/Appearances.js +0 -62
  151. package/dist/actors/Appearances.js.map +0 -1
  152. package/dist/actors/Aura.d.ts +0 -45
  153. package/dist/actors/Aura.d.ts.map +0 -1
  154. package/dist/actors/Aura.js +0 -85
  155. package/dist/actors/Aura.js.map +0 -1
  156. package/dist/actors/Barrier.d.ts +0 -60
  157. package/dist/actors/Barrier.d.ts.map +0 -1
  158. package/dist/actors/Barrier.js +0 -70
  159. package/dist/actors/Barrier.js.map +0 -1
  160. package/dist/actors/Charges.d.ts +0 -66
  161. package/dist/actors/Charges.d.ts.map +0 -1
  162. package/dist/actors/Charges.js +0 -61
  163. package/dist/actors/Charges.js.map +0 -1
  164. package/dist/actors/EntityTemplate.d.ts +0 -127
  165. package/dist/actors/EntityTemplate.d.ts.map +0 -1
  166. package/dist/actors/EntityTemplate.js +0 -117
  167. package/dist/actors/EntityTemplate.js.map +0 -1
  168. package/dist/actors/Equipment.d.ts +0 -88
  169. package/dist/actors/Equipment.d.ts.map +0 -1
  170. package/dist/actors/Equipment.js +0 -107
  171. package/dist/actors/Equipment.js.map +0 -1
  172. package/dist/actors/Inventory.d.ts +0 -123
  173. package/dist/actors/Inventory.d.ts.map +0 -1
  174. package/dist/actors/Inventory.js +0 -165
  175. package/dist/actors/Inventory.js.map +0 -1
  176. package/dist/actors/ItemState.d.ts +0 -43
  177. package/dist/actors/ItemState.d.ts.map +0 -1
  178. package/dist/actors/ItemState.js +0 -63
  179. package/dist/actors/ItemState.js.map +0 -1
  180. package/dist/actors/ItemStatusEffect.d.ts +0 -40
  181. package/dist/actors/ItemStatusEffect.d.ts.map +0 -1
  182. package/dist/actors/ItemStatusEffect.js +0 -39
  183. package/dist/actors/ItemStatusEffect.js.map +0 -1
  184. package/dist/actors/Loot.d.ts +0 -38
  185. package/dist/actors/Loot.d.ts.map +0 -1
  186. package/dist/actors/Loot.js +0 -28
  187. package/dist/actors/Loot.js.map +0 -1
  188. package/dist/actors/Progression.d.ts +0 -52
  189. package/dist/actors/Progression.d.ts.map +0 -1
  190. package/dist/actors/Progression.js +0 -59
  191. package/dist/actors/Progression.js.map +0 -1
  192. package/dist/actors/Resource.d.ts +0 -53
  193. package/dist/actors/Resource.d.ts.map +0 -1
  194. package/dist/actors/Resource.js +0 -57
  195. package/dist/actors/Resource.js.map +0 -1
  196. package/dist/actors/Scaling.d.ts +0 -30
  197. package/dist/actors/Scaling.d.ts.map +0 -1
  198. package/dist/actors/Scaling.js +0 -9
  199. package/dist/actors/Scaling.js.map +0 -1
  200. package/dist/actors/Shop.d.ts +0 -40
  201. package/dist/actors/Shop.d.ts.map +0 -1
  202. package/dist/actors/Shop.js +0 -36
  203. package/dist/actors/Shop.js.map +0 -1
  204. package/dist/actors/SkillPoints.d.ts +0 -72
  205. package/dist/actors/SkillPoints.d.ts.map +0 -1
  206. package/dist/actors/SkillPoints.js +0 -87
  207. package/dist/actors/SkillPoints.js.map +0 -1
  208. package/dist/actors/StatBlock.d.ts +0 -86
  209. package/dist/actors/StatBlock.d.ts.map +0 -1
  210. package/dist/actors/StatBlock.js +0 -110
  211. package/dist/actors/StatBlock.js.map +0 -1
  212. package/dist/actors/StatusEffect.d.ts +0 -67
  213. package/dist/actors/StatusEffect.d.ts.map +0 -1
  214. package/dist/actors/StatusEffect.js +0 -59
  215. package/dist/actors/StatusEffect.js.map +0 -1
  216. package/dist/actors/Support.d.ts +0 -43
  217. package/dist/actors/Support.d.ts.map +0 -1
  218. package/dist/actors/Support.js +0 -71
  219. package/dist/actors/Support.js.map +0 -1
  220. package/dist/actors/Traits.d.ts +0 -43
  221. package/dist/actors/Traits.d.ts.map +0 -1
  222. package/dist/actors/Traits.js +0 -35
  223. package/dist/actors/Traits.js.map +0 -1
  224. package/dist/actors/craft.d.ts +0 -63
  225. package/dist/actors/craft.d.ts.map +0 -1
  226. package/dist/actors/craft.js +0 -86
  227. package/dist/actors/craft.js.map +0 -1
  228. package/dist/actors/index.d.ts +0 -46
  229. package/dist/actors/index.d.ts.map +0 -1
  230. package/dist/actors/index.js +0 -24
  231. package/dist/actors/index.js.map +0 -1
  232. package/dist/actors/skillCheck.d.ts +0 -21
  233. package/dist/actors/skillCheck.d.ts.map +0 -1
  234. package/dist/actors/skillCheck.js +0 -24
  235. package/dist/actors/skillCheck.js.map +0 -1
  236. package/dist/ai/Heuristics.d.ts +0 -240
  237. package/dist/ai/Heuristics.d.ts.map +0 -1
  238. package/dist/ai/Heuristics.js +0 -298
  239. package/dist/ai/Heuristics.js.map +0 -1
  240. package/dist/ai/Neural.d.ts +0 -65
  241. package/dist/ai/Neural.d.ts.map +0 -1
  242. package/dist/ai/Neural.js +0 -169
  243. package/dist/ai/Neural.js.map +0 -1
  244. package/dist/ai/Suggest.d.ts +0 -54
  245. package/dist/ai/Suggest.d.ts.map +0 -1
  246. package/dist/ai/Suggest.js +0 -48
  247. package/dist/ai/Suggest.js.map +0 -1
  248. package/dist/ai/index.d.ts +0 -136
  249. package/dist/ai/index.d.ts.map +0 -1
  250. package/dist/ai/index.js +0 -207
  251. package/dist/ai/index.js.map +0 -1
  252. package/dist/ai/lua.d.ts +0 -74
  253. package/dist/ai/lua.d.ts.map +0 -1
  254. package/dist/ai/lua.js +0 -217
  255. package/dist/ai/lua.js.map +0 -1
  256. package/dist/ai/score.d.ts +0 -162
  257. package/dist/ai/score.d.ts.map +0 -1
  258. package/dist/ai/score.js +0 -147
  259. package/dist/ai/score.js.map +0 -1
  260. package/dist/ai/search.d.ts +0 -108
  261. package/dist/ai/search.d.ts.map +0 -1
  262. package/dist/ai/search.js +0 -148
  263. package/dist/ai/search.js.map +0 -1
  264. package/dist/assets/ByteProgress.d.ts +0 -37
  265. package/dist/assets/ByteProgress.d.ts.map +0 -1
  266. package/dist/assets/ByteProgress.js +0 -54
  267. package/dist/assets/ByteProgress.js.map +0 -1
  268. package/dist/assets/Streaming.d.ts +0 -56
  269. package/dist/assets/Streaming.d.ts.map +0 -1
  270. package/dist/assets/Streaming.js +0 -100
  271. package/dist/assets/Streaming.js.map +0 -1
  272. package/dist/assets/SvgParts.d.ts +0 -31
  273. package/dist/assets/SvgParts.d.ts.map +0 -1
  274. package/dist/assets/SvgParts.js +0 -54
  275. package/dist/assets/SvgParts.js.map +0 -1
  276. package/dist/assets/SvgSource.d.ts +0 -3
  277. package/dist/assets/SvgSource.d.ts.map +0 -1
  278. package/dist/assets/SvgSource.js +0 -22
  279. package/dist/assets/SvgSource.js.map +0 -1
  280. package/dist/assets/binary.d.ts +0 -52
  281. package/dist/assets/binary.d.ts.map +0 -1
  282. package/dist/assets/binary.js +0 -57
  283. package/dist/assets/binary.js.map +0 -1
  284. package/dist/assets/index.d.ts +0 -27
  285. package/dist/assets/index.d.ts.map +0 -1
  286. package/dist/assets/index.js +0 -20
  287. package/dist/assets/index.js.map +0 -1
  288. package/dist/assets/loader.d.ts +0 -70
  289. package/dist/assets/loader.d.ts.map +0 -1
  290. package/dist/assets/loader.js +0 -115
  291. package/dist/assets/loader.js.map +0 -1
  292. package/dist/assets/paths.d.ts +0 -73
  293. package/dist/assets/paths.d.ts.map +0 -1
  294. package/dist/assets/paths.js +0 -91
  295. package/dist/assets/paths.js.map +0 -1
  296. package/dist/assets/svg.d.ts +0 -87
  297. package/dist/assets/svg.d.ts.map +0 -1
  298. package/dist/assets/svg.js +0 -166
  299. package/dist/assets/svg.js.map +0 -1
  300. package/dist/audio/AdaptiveMusic.d.ts +0 -85
  301. package/dist/audio/AdaptiveMusic.d.ts.map +0 -1
  302. package/dist/audio/AdaptiveMusic.js +0 -230
  303. package/dist/audio/AdaptiveMusic.js.map +0 -1
  304. package/dist/audio/AudioLoader.d.ts +0 -33
  305. package/dist/audio/AudioLoader.d.ts.map +0 -1
  306. package/dist/audio/AudioLoader.js +0 -58
  307. package/dist/audio/AudioLoader.js.map +0 -1
  308. package/dist/audio/AudioViews.d.ts +0 -70
  309. package/dist/audio/AudioViews.d.ts.map +0 -1
  310. package/dist/audio/AudioViews.js +0 -119
  311. package/dist/audio/AudioViews.js.map +0 -1
  312. package/dist/audio/BusBudget.d.ts +0 -89
  313. package/dist/audio/BusBudget.d.ts.map +0 -1
  314. package/dist/audio/BusBudget.js +0 -120
  315. package/dist/audio/BusBudget.js.map +0 -1
  316. package/dist/audio/Captions.d.ts +0 -27
  317. package/dist/audio/Captions.d.ts.map +0 -1
  318. package/dist/audio/Captions.js +0 -16
  319. package/dist/audio/Captions.js.map +0 -1
  320. package/dist/audio/Channels.d.ts +0 -282
  321. package/dist/audio/Channels.d.ts.map +0 -1
  322. package/dist/audio/Channels.js +0 -573
  323. package/dist/audio/Channels.js.map +0 -1
  324. package/dist/audio/CoreHost.d.ts +0 -114
  325. package/dist/audio/CoreHost.d.ts.map +0 -1
  326. package/dist/audio/CoreHost.js +0 -335
  327. package/dist/audio/CoreHost.js.map +0 -1
  328. package/dist/audio/DecoderGuard.d.ts +0 -139
  329. package/dist/audio/DecoderGuard.d.ts.map +0 -1
  330. package/dist/audio/DecoderGuard.js +0 -208
  331. package/dist/audio/DecoderGuard.js.map +0 -1
  332. package/dist/audio/Fft.d.ts +0 -3
  333. package/dist/audio/Fft.d.ts.map +0 -1
  334. package/dist/audio/Fft.js +0 -45
  335. package/dist/audio/Fft.js.map +0 -1
  336. package/dist/audio/LoopTags.d.ts +0 -55
  337. package/dist/audio/LoopTags.d.ts.map +0 -1
  338. package/dist/audio/LoopTags.js +0 -136
  339. package/dist/audio/LoopTags.js.map +0 -1
  340. package/dist/audio/Midi.d.ts +0 -219
  341. package/dist/audio/Midi.d.ts.map +0 -1
  342. package/dist/audio/Midi.js +0 -409
  343. package/dist/audio/Midi.js.map +0 -1
  344. package/dist/audio/MidiRender.d.ts +0 -144
  345. package/dist/audio/MidiRender.d.ts.map +0 -1
  346. package/dist/audio/MidiRender.js +0 -448
  347. package/dist/audio/MidiRender.js.map +0 -1
  348. package/dist/audio/MidiSynth.d.ts +0 -147
  349. package/dist/audio/MidiSynth.d.ts.map +0 -1
  350. package/dist/audio/MidiSynth.js +0 -205
  351. package/dist/audio/MidiSynth.js.map +0 -1
  352. package/dist/audio/Music.d.ts +0 -70
  353. package/dist/audio/Music.d.ts.map +0 -1
  354. package/dist/audio/Music.js +0 -191
  355. package/dist/audio/Music.js.map +0 -1
  356. package/dist/audio/MusicPlayer.d.ts +0 -80
  357. package/dist/audio/MusicPlayer.d.ts.map +0 -1
  358. package/dist/audio/MusicPlayer.js +0 -147
  359. package/dist/audio/MusicPlayer.js.map +0 -1
  360. package/dist/audio/Orchestrator.d.ts +0 -58
  361. package/dist/audio/Orchestrator.d.ts.map +0 -1
  362. package/dist/audio/Orchestrator.js +0 -74
  363. package/dist/audio/Orchestrator.js.map +0 -1
  364. package/dist/audio/Playable.d.ts +0 -38
  365. package/dist/audio/Playable.d.ts.map +0 -1
  366. package/dist/audio/Playable.js +0 -29
  367. package/dist/audio/Playable.js.map +0 -1
  368. package/dist/audio/Positional.d.ts +0 -133
  369. package/dist/audio/Positional.d.ts.map +0 -1
  370. package/dist/audio/Positional.js +0 -138
  371. package/dist/audio/Positional.js.map +0 -1
  372. package/dist/audio/Resample.d.ts +0 -61
  373. package/dist/audio/Resample.d.ts.map +0 -1
  374. package/dist/audio/Resample.js +0 -97
  375. package/dist/audio/Resample.js.map +0 -1
  376. package/dist/audio/SampleDecoder.d.ts +0 -55
  377. package/dist/audio/SampleDecoder.d.ts.map +0 -1
  378. package/dist/audio/SampleDecoder.js +0 -74
  379. package/dist/audio/SampleDecoder.js.map +0 -1
  380. package/dist/audio/Settings.d.ts +0 -99
  381. package/dist/audio/Settings.d.ts.map +0 -1
  382. package/dist/audio/Settings.js +0 -134
  383. package/dist/audio/Settings.js.map +0 -1
  384. package/dist/audio/Sfx.d.ts +0 -148
  385. package/dist/audio/Sfx.d.ts.map +0 -1
  386. package/dist/audio/Sfx.js +0 -213
  387. package/dist/audio/Sfx.js.map +0 -1
  388. package/dist/audio/Sound.d.ts +0 -57
  389. package/dist/audio/Sound.d.ts.map +0 -1
  390. package/dist/audio/Sound.js +0 -79
  391. package/dist/audio/Sound.js.map +0 -1
  392. package/dist/audio/SoundFont.d.ts +0 -192
  393. package/dist/audio/SoundFont.d.ts.map +0 -1
  394. package/dist/audio/SoundFont.js +0 -862
  395. package/dist/audio/SoundFont.js.map +0 -1
  396. package/dist/audio/SpectralDistance.d.ts +0 -34
  397. package/dist/audio/SpectralDistance.d.ts.map +0 -1
  398. package/dist/audio/SpectralDistance.js +0 -64
  399. package/dist/audio/SpectralDistance.js.map +0 -1
  400. package/dist/audio/StreamChannel.d.ts +0 -150
  401. package/dist/audio/StreamChannel.d.ts.map +0 -1
  402. package/dist/audio/StreamChannel.js +0 -390
  403. package/dist/audio/StreamChannel.js.map +0 -1
  404. package/dist/audio/StreamPlayable.d.ts +0 -73
  405. package/dist/audio/StreamPlayable.d.ts.map +0 -1
  406. package/dist/audio/StreamPlayable.js +0 -130
  407. package/dist/audio/StreamPlayable.js.map +0 -1
  408. package/dist/audio/Synth.d.ts +0 -64
  409. package/dist/audio/Synth.d.ts.map +0 -1
  410. package/dist/audio/Synth.js +0 -133
  411. package/dist/audio/Synth.js.map +0 -1
  412. package/dist/audio/SyxBank.d.ts +0 -73
  413. package/dist/audio/SyxBank.d.ts.map +0 -1
  414. package/dist/audio/SyxBank.js +0 -130
  415. package/dist/audio/SyxBank.js.map +0 -1
  416. package/dist/audio/Underrun.d.ts +0 -25
  417. package/dist/audio/Underrun.d.ts.map +0 -1
  418. package/dist/audio/Underrun.js +0 -18
  419. package/dist/audio/Underrun.js.map +0 -1
  420. package/dist/audio/Wav.d.ts +0 -56
  421. package/dist/audio/Wav.d.ts.map +0 -1
  422. package/dist/audio/Wav.js +0 -164
  423. package/dist/audio/Wav.js.map +0 -1
  424. package/dist/audio/WebMidi.d.ts +0 -58
  425. package/dist/audio/WebMidi.d.ts.map +0 -1
  426. package/dist/audio/WebMidi.js +0 -79
  427. package/dist/audio/WebMidi.js.map +0 -1
  428. package/dist/audio/humanize/Groove.d.ts +0 -80
  429. package/dist/audio/humanize/Groove.d.ts.map +0 -1
  430. package/dist/audio/humanize/Groove.js +0 -102
  431. package/dist/audio/humanize/Groove.js.map +0 -1
  432. package/dist/audio/humanize/GrooveConverter.d.ts +0 -49
  433. package/dist/audio/humanize/GrooveConverter.d.ts.map +0 -1
  434. package/dist/audio/humanize/GrooveConverter.js +0 -344
  435. package/dist/audio/humanize/GrooveConverter.js.map +0 -1
  436. package/dist/audio/humanize/GrooveExtractor.d.ts +0 -49
  437. package/dist/audio/humanize/GrooveExtractor.d.ts.map +0 -1
  438. package/dist/audio/humanize/GrooveExtractor.js +0 -179
  439. package/dist/audio/humanize/GrooveExtractor.js.map +0 -1
  440. package/dist/audio/humanize/GrooveHumanizer.d.ts +0 -34
  441. package/dist/audio/humanize/GrooveHumanizer.d.ts.map +0 -1
  442. package/dist/audio/humanize/GrooveHumanizer.js +0 -37
  443. package/dist/audio/humanize/GrooveHumanizer.js.map +0 -1
  444. package/dist/audio/humanize/Humanize.d.ts +0 -54
  445. package/dist/audio/humanize/Humanize.d.ts.map +0 -1
  446. package/dist/audio/humanize/Humanize.js +0 -239
  447. package/dist/audio/humanize/Humanize.js.map +0 -1
  448. package/dist/audio/humanize/HumanizerFactory.d.ts +0 -68
  449. package/dist/audio/humanize/HumanizerFactory.d.ts.map +0 -1
  450. package/dist/audio/humanize/HumanizerFactory.js +0 -84
  451. package/dist/audio/humanize/HumanizerFactory.js.map +0 -1
  452. package/dist/audio/humanize/LiteHumanizer.d.ts +0 -30
  453. package/dist/audio/humanize/LiteHumanizer.d.ts.map +0 -1
  454. package/dist/audio/humanize/LiteHumanizer.js +0 -35
  455. package/dist/audio/humanize/LiteHumanizer.js.map +0 -1
  456. package/dist/audio/humanize/Onsets.d.ts +0 -26
  457. package/dist/audio/humanize/Onsets.d.ts.map +0 -1
  458. package/dist/audio/humanize/Onsets.js +0 -121
  459. package/dist/audio/humanize/Onsets.js.map +0 -1
  460. package/dist/audio/index.d.ts +0 -75
  461. package/dist/audio/index.d.ts.map +0 -1
  462. package/dist/audio/index.js +0 -38
  463. package/dist/audio/index.js.map +0 -1
  464. package/dist/battle/AttackDialog.d.ts +0 -75
  465. package/dist/battle/AttackDialog.d.ts.map +0 -1
  466. package/dist/battle/AttackDialog.js +0 -115
  467. package/dist/battle/AttackDialog.js.map +0 -1
  468. package/dist/battle/AttackPreview.d.ts +0 -70
  469. package/dist/battle/AttackPreview.d.ts.map +0 -1
  470. package/dist/battle/AttackPreview.js +0 -78
  471. package/dist/battle/AttackPreview.js.map +0 -1
  472. package/dist/battle/BattleAI.d.ts +0 -40
  473. package/dist/battle/BattleAI.d.ts.map +0 -1
  474. package/dist/battle/BattleAI.js +0 -63
  475. package/dist/battle/BattleAI.js.map +0 -1
  476. package/dist/battle/BattleStats.d.ts +0 -45
  477. package/dist/battle/BattleStats.d.ts.map +0 -1
  478. package/dist/battle/BattleStats.js +0 -63
  479. package/dist/battle/BattleStats.js.map +0 -1
  480. package/dist/battle/Evolution.d.ts +0 -34
  481. package/dist/battle/Evolution.d.ts.map +0 -1
  482. package/dist/battle/Evolution.js +0 -37
  483. package/dist/battle/Evolution.js.map +0 -1
  484. package/dist/battle/Field.d.ts +0 -36
  485. package/dist/battle/Field.d.ts.map +0 -1
  486. package/dist/battle/Field.js +0 -31
  487. package/dist/battle/Field.js.map +0 -1
  488. package/dist/battle/Hooks.d.ts +0 -39
  489. package/dist/battle/Hooks.d.ts.map +0 -1
  490. package/dist/battle/Hooks.js +0 -38
  491. package/dist/battle/Hooks.js.map +0 -1
  492. package/dist/battle/Move.d.ts +0 -45
  493. package/dist/battle/Move.d.ts.map +0 -1
  494. package/dist/battle/Move.js +0 -23
  495. package/dist/battle/Move.js.map +0 -1
  496. package/dist/battle/Party.d.ts +0 -32
  497. package/dist/battle/Party.d.ts.map +0 -1
  498. package/dist/battle/Party.js +0 -62
  499. package/dist/battle/Party.js.map +0 -1
  500. package/dist/battle/Species.d.ts +0 -50
  501. package/dist/battle/Species.d.ts.map +0 -1
  502. package/dist/battle/Species.js +0 -41
  503. package/dist/battle/Species.js.map +0 -1
  504. package/dist/battle/StatStages.d.ts +0 -52
  505. package/dist/battle/StatStages.d.ts.map +0 -1
  506. package/dist/battle/StatStages.js +0 -51
  507. package/dist/battle/StatStages.js.map +0 -1
  508. package/dist/battle/TypeMatrix.d.ts +0 -25
  509. package/dist/battle/TypeMatrix.d.ts.map +0 -1
  510. package/dist/battle/TypeMatrix.js +0 -35
  511. package/dist/battle/TypeMatrix.js.map +0 -1
  512. package/dist/battle/UnitSelector.d.ts +0 -72
  513. package/dist/battle/UnitSelector.d.ts.map +0 -1
  514. package/dist/battle/UnitSelector.js +0 -117
  515. package/dist/battle/UnitSelector.js.map +0 -1
  516. package/dist/battle/Whiteboard.d.ts +0 -50
  517. package/dist/battle/Whiteboard.d.ts.map +0 -1
  518. package/dist/battle/Whiteboard.js +0 -94
  519. package/dist/battle/Whiteboard.js.map +0 -1
  520. package/dist/battle/index.d.ts +0 -26
  521. package/dist/battle/index.d.ts.map +0 -1
  522. package/dist/battle/index.js +0 -15
  523. package/dist/battle/index.js.map +0 -1
  524. package/dist/board/Army.d.ts +0 -92
  525. package/dist/board/Army.d.ts.map +0 -1
  526. package/dist/board/Army.js +0 -123
  527. package/dist/board/Army.js.map +0 -1
  528. package/dist/board/Classics.d.ts +0 -419
  529. package/dist/board/Classics.d.ts.map +0 -1
  530. package/dist/board/Classics.js +0 -754
  531. package/dist/board/Classics.js.map +0 -1
  532. package/dist/board/Engine.d.ts +0 -95
  533. package/dist/board/Engine.d.ts.map +0 -1
  534. package/dist/board/Engine.js +0 -545
  535. package/dist/board/Engine.js.map +0 -1
  536. package/dist/board/FogOfWar.d.ts +0 -79
  537. package/dist/board/FogOfWar.d.ts.map +0 -1
  538. package/dist/board/FogOfWar.js +0 -150
  539. package/dist/board/FogOfWar.js.map +0 -1
  540. package/dist/board/HexSkirmish.d.ts +0 -213
  541. package/dist/board/HexSkirmish.d.ts.map +0 -1
  542. package/dist/board/HexSkirmish.js +0 -268
  543. package/dist/board/HexSkirmish.js.map +0 -1
  544. package/dist/board/Tactics.d.ts +0 -212
  545. package/dist/board/Tactics.d.ts.map +0 -1
  546. package/dist/board/Tactics.js +0 -303
  547. package/dist/board/Tactics.js.map +0 -1
  548. package/dist/board/bitboard.d.ts +0 -132
  549. package/dist/board/bitboard.d.ts.map +0 -1
  550. package/dist/board/bitboard.js +0 -495
  551. package/dist/board/bitboard.js.map +0 -1
  552. package/dist/board/chess.d.ts +0 -167
  553. package/dist/board/chess.d.ts.map +0 -1
  554. package/dist/board/chess.js +0 -578
  555. package/dist/board/chess.js.map +0 -1
  556. package/dist/board/index.d.ts +0 -23
  557. package/dist/board/index.d.ts.map +0 -1
  558. package/dist/board/index.js +0 -12
  559. package/dist/board/index.js.map +0 -1
  560. package/dist/board/openings.d.ts +0 -58
  561. package/dist/board/openings.d.ts.map +0 -1
  562. package/dist/board/openings.js +0 -45
  563. package/dist/board/openings.js.map +0 -1
  564. package/dist/board/tablebase.d.ts +0 -118
  565. package/dist/board/tablebase.d.ts.map +0 -1
  566. package/dist/board/tablebase.js +0 -414
  567. package/dist/board/tablebase.js.map +0 -1
  568. package/dist/board/tourney.d.ts +0 -97
  569. package/dist/board/tourney.d.ts.map +0 -1
  570. package/dist/board/tourney.js +0 -1002
  571. package/dist/board/tourney.js.map +0 -1
  572. package/dist/core/Achievements.d.ts +0 -101
  573. package/dist/core/Achievements.d.ts.map +0 -1
  574. package/dist/core/Achievements.js +0 -141
  575. package/dist/core/Achievements.js.map +0 -1
  576. package/dist/core/ActionJournal.d.ts +0 -43
  577. package/dist/core/ActionJournal.d.ts.map +0 -1
  578. package/dist/core/ActionJournal.js +0 -77
  579. package/dist/core/ActionJournal.js.map +0 -1
  580. package/dist/core/Blob.d.ts +0 -79
  581. package/dist/core/Blob.d.ts.map +0 -1
  582. package/dist/core/Blob.js +0 -140
  583. package/dist/core/Blob.js.map +0 -1
  584. package/dist/core/Clone.d.ts +0 -31
  585. package/dist/core/Clone.d.ts.map +0 -1
  586. package/dist/core/Clone.js +0 -84
  587. package/dist/core/Clone.js.map +0 -1
  588. package/dist/core/Collection.d.ts +0 -59
  589. package/dist/core/Collection.d.ts.map +0 -1
  590. package/dist/core/Collection.js +0 -77
  591. package/dist/core/Collection.js.map +0 -1
  592. package/dist/core/Csv.d.ts +0 -74
  593. package/dist/core/Csv.d.ts.map +0 -1
  594. package/dist/core/Csv.js +0 -201
  595. package/dist/core/Csv.js.map +0 -1
  596. package/dist/core/DialogueText.d.ts +0 -72
  597. package/dist/core/DialogueText.d.ts.map +0 -1
  598. package/dist/core/DialogueText.js +0 -68
  599. package/dist/core/DialogueText.js.map +0 -1
  600. package/dist/core/Entity.d.ts +0 -42
  601. package/dist/core/Entity.d.ts.map +0 -1
  602. package/dist/core/Entity.js +0 -61
  603. package/dist/core/Entity.js.map +0 -1
  604. package/dist/core/Feedback.d.ts +0 -27
  605. package/dist/core/Feedback.d.ts.map +0 -1
  606. package/dist/core/Feedback.js +0 -33
  607. package/dist/core/Feedback.js.map +0 -1
  608. package/dist/core/FixedStepper.d.ts +0 -38
  609. package/dist/core/FixedStepper.d.ts.map +0 -1
  610. package/dist/core/FixedStepper.js +0 -56
  611. package/dist/core/FixedStepper.js.map +0 -1
  612. package/dist/core/Grid.d.ts +0 -179
  613. package/dist/core/Grid.d.ts.map +0 -1
  614. package/dist/core/Grid.js +0 -201
  615. package/dist/core/Grid.js.map +0 -1
  616. package/dist/core/Handles.d.ts +0 -42
  617. package/dist/core/Handles.d.ts.map +0 -1
  618. package/dist/core/Handles.js +0 -38
  619. package/dist/core/Handles.js.map +0 -1
  620. package/dist/core/Hex.d.ts +0 -79
  621. package/dist/core/Hex.d.ts.map +0 -1
  622. package/dist/core/Hex.js +0 -161
  623. package/dist/core/Hex.js.map +0 -1
  624. package/dist/core/Hooks.d.ts +0 -48
  625. package/dist/core/Hooks.d.ts.map +0 -1
  626. package/dist/core/Hooks.js +0 -33
  627. package/dist/core/Hooks.js.map +0 -1
  628. package/dist/core/HttpTransport.d.ts +0 -53
  629. package/dist/core/HttpTransport.d.ts.map +0 -1
  630. package/dist/core/HttpTransport.js +0 -108
  631. package/dist/core/HttpTransport.js.map +0 -1
  632. package/dist/core/Input.d.ts +0 -256
  633. package/dist/core/Input.d.ts.map +0 -1
  634. package/dist/core/Input.js +0 -557
  635. package/dist/core/Input.js.map +0 -1
  636. package/dist/core/JavaRandom.d.ts +0 -55
  637. package/dist/core/JavaRandom.d.ts.map +0 -1
  638. package/dist/core/JavaRandom.js +0 -81
  639. package/dist/core/JavaRandom.js.map +0 -1
  640. package/dist/core/Loading.d.ts +0 -65
  641. package/dist/core/Loading.d.ts.map +0 -1
  642. package/dist/core/Loading.js +0 -119
  643. package/dist/core/Loading.js.map +0 -1
  644. package/dist/core/Log.d.ts +0 -48
  645. package/dist/core/Log.d.ts.map +0 -1
  646. package/dist/core/Log.js +0 -59
  647. package/dist/core/Log.js.map +0 -1
  648. package/dist/core/Math.d.ts +0 -14
  649. package/dist/core/Math.d.ts.map +0 -1
  650. package/dist/core/Math.js +0 -16
  651. package/dist/core/Math.js.map +0 -1
  652. package/dist/core/Motion.d.ts +0 -47
  653. package/dist/core/Motion.d.ts.map +0 -1
  654. package/dist/core/Motion.js +0 -122
  655. package/dist/core/Motion.js.map +0 -1
  656. package/dist/core/Multiplayer.d.ts +0 -101
  657. package/dist/core/Multiplayer.d.ts.map +0 -1
  658. package/dist/core/Multiplayer.js +0 -156
  659. package/dist/core/Multiplayer.js.map +0 -1
  660. package/dist/core/News.d.ts +0 -51
  661. package/dist/core/News.d.ts.map +0 -1
  662. package/dist/core/News.js +0 -65
  663. package/dist/core/News.js.map +0 -1
  664. package/dist/core/Pathfinding.d.ts +0 -41
  665. package/dist/core/Pathfinding.d.ts.map +0 -1
  666. package/dist/core/Pathfinding.js +0 -86
  667. package/dist/core/Pathfinding.js.map +0 -1
  668. package/dist/core/PlayerInput.d.ts +0 -57
  669. package/dist/core/PlayerInput.d.ts.map +0 -1
  670. package/dist/core/PlayerInput.js +0 -82
  671. package/dist/core/PlayerInput.js.map +0 -1
  672. package/dist/core/Presentation.d.ts +0 -56
  673. package/dist/core/Presentation.d.ts.map +0 -1
  674. package/dist/core/Presentation.js +0 -78
  675. package/dist/core/Presentation.js.map +0 -1
  676. package/dist/core/Random.d.ts +0 -259
  677. package/dist/core/Random.d.ts.map +0 -1
  678. package/dist/core/Random.js +0 -408
  679. package/dist/core/Random.js.map +0 -1
  680. package/dist/core/Reactions.d.ts +0 -67
  681. package/dist/core/Reactions.d.ts.map +0 -1
  682. package/dist/core/Reactions.js +0 -92
  683. package/dist/core/Reactions.js.map +0 -1
  684. package/dist/core/Registry.d.ts +0 -31
  685. package/dist/core/Registry.d.ts.map +0 -1
  686. package/dist/core/Registry.js +0 -46
  687. package/dist/core/Registry.js.map +0 -1
  688. package/dist/core/Replay.d.ts +0 -126
  689. package/dist/core/Replay.d.ts.map +0 -1
  690. package/dist/core/Replay.js +0 -162
  691. package/dist/core/Replay.js.map +0 -1
  692. package/dist/core/ReplayFile.d.ts +0 -197
  693. package/dist/core/ReplayFile.d.ts.map +0 -1
  694. package/dist/core/ReplayFile.js +0 -257
  695. package/dist/core/ReplayFile.js.map +0 -1
  696. package/dist/core/RunHistory.d.ts +0 -54
  697. package/dist/core/RunHistory.d.ts.map +0 -1
  698. package/dist/core/RunHistory.js +0 -40
  699. package/dist/core/RunHistory.js.map +0 -1
  700. package/dist/core/Sanitize.d.ts +0 -101
  701. package/dist/core/Sanitize.d.ts.map +0 -1
  702. package/dist/core/Sanitize.js +0 -162
  703. package/dist/core/Sanitize.js.map +0 -1
  704. package/dist/core/Save.d.ts +0 -123
  705. package/dist/core/Save.d.ts.map +0 -1
  706. package/dist/core/Save.js +0 -216
  707. package/dist/core/Save.js.map +0 -1
  708. package/dist/core/SaveSync.d.ts +0 -43
  709. package/dist/core/SaveSync.d.ts.map +0 -1
  710. package/dist/core/SaveSync.js +0 -56
  711. package/dist/core/SaveSync.js.map +0 -1
  712. package/dist/core/Scene.d.ts +0 -63
  713. package/dist/core/Scene.d.ts.map +0 -1
  714. package/dist/core/Scene.js +0 -81
  715. package/dist/core/Scene.js.map +0 -1
  716. package/dist/core/SceneComponents.d.ts +0 -67
  717. package/dist/core/SceneComponents.d.ts.map +0 -1
  718. package/dist/core/SceneComponents.js +0 -76
  719. package/dist/core/SceneComponents.js.map +0 -1
  720. package/dist/core/SceneStack.d.ts +0 -61
  721. package/dist/core/SceneStack.d.ts.map +0 -1
  722. package/dist/core/SceneStack.js +0 -91
  723. package/dist/core/SceneStack.js.map +0 -1
  724. package/dist/core/Scramble.d.ts +0 -21
  725. package/dist/core/Scramble.d.ts.map +0 -1
  726. package/dist/core/Scramble.js +0 -52
  727. package/dist/core/Scramble.js.map +0 -1
  728. package/dist/core/Session.d.ts +0 -31
  729. package/dist/core/Session.d.ts.map +0 -1
  730. package/dist/core/Session.js +0 -11
  731. package/dist/core/Session.js.map +0 -1
  732. package/dist/core/Settings.d.ts +0 -96
  733. package/dist/core/Settings.d.ts.map +0 -1
  734. package/dist/core/Settings.js +0 -190
  735. package/dist/core/Settings.js.map +0 -1
  736. package/dist/core/Signal.d.ts +0 -35
  737. package/dist/core/Signal.d.ts.map +0 -1
  738. package/dist/core/Signal.js +0 -41
  739. package/dist/core/Signal.js.map +0 -1
  740. package/dist/core/Spawner.d.ts +0 -65
  741. package/dist/core/Spawner.d.ts.map +0 -1
  742. package/dist/core/Spawner.js +0 -82
  743. package/dist/core/Spawner.js.map +0 -1
  744. package/dist/core/State.d.ts +0 -97
  745. package/dist/core/State.d.ts.map +0 -1
  746. package/dist/core/State.js +0 -177
  747. package/dist/core/State.js.map +0 -1
  748. package/dist/core/Stats.d.ts +0 -46
  749. package/dist/core/Stats.d.ts.map +0 -1
  750. package/dist/core/Stats.js +0 -47
  751. package/dist/core/Stats.js.map +0 -1
  752. package/dist/core/StoredValue.d.ts +0 -30
  753. package/dist/core/StoredValue.d.ts.map +0 -1
  754. package/dist/core/StoredValue.js +0 -38
  755. package/dist/core/StoredValue.js.map +0 -1
  756. package/dist/core/SyncGuard.d.ts +0 -57
  757. package/dist/core/SyncGuard.d.ts.map +0 -1
  758. package/dist/core/SyncGuard.js +0 -116
  759. package/dist/core/SyncGuard.js.map +0 -1
  760. package/dist/core/Telemetry.d.ts +0 -63
  761. package/dist/core/Telemetry.d.ts.map +0 -1
  762. package/dist/core/Telemetry.js +0 -83
  763. package/dist/core/Telemetry.js.map +0 -1
  764. package/dist/core/Twee.d.ts +0 -101
  765. package/dist/core/Twee.d.ts.map +0 -1
  766. package/dist/core/Twee.js +0 -174
  767. package/dist/core/Twee.js.map +0 -1
  768. package/dist/core/Tween.d.ts +0 -60
  769. package/dist/core/Tween.d.ts.map +0 -1
  770. package/dist/core/Tween.js +0 -98
  771. package/dist/core/Tween.js.map +0 -1
  772. package/dist/core/UndoHistory.d.ts +0 -52
  773. package/dist/core/UndoHistory.d.ts.map +0 -1
  774. package/dist/core/UndoHistory.js +0 -49
  775. package/dist/core/UndoHistory.js.map +0 -1
  776. package/dist/core/index.d.ts +0 -94
  777. package/dist/core/index.d.ts.map +0 -1
  778. package/dist/core/index.js +0 -53
  779. package/dist/core/index.js.map +0 -1
  780. package/dist/headless/index.d.ts +0 -87
  781. package/dist/headless/index.d.ts.map +0 -1
  782. package/dist/headless/index.js +0 -87
  783. package/dist/headless/index.js.map +0 -1
  784. package/dist/i18n/Content.d.ts +0 -151
  785. package/dist/i18n/Content.d.ts.map +0 -1
  786. package/dist/i18n/Content.js +0 -218
  787. package/dist/i18n/Content.js.map +0 -1
  788. package/dist/i18n/EditSession.d.ts +0 -101
  789. package/dist/i18n/EditSession.d.ts.map +0 -1
  790. package/dist/i18n/EditSession.js +0 -150
  791. package/dist/i18n/EditSession.js.map +0 -1
  792. package/dist/i18n/Fluent.d.ts +0 -7
  793. package/dist/i18n/Fluent.d.ts.map +0 -1
  794. package/dist/i18n/Fluent.js +0 -98
  795. package/dist/i18n/Fluent.js.map +0 -1
  796. package/dist/i18n/Format.d.ts +0 -25
  797. package/dist/i18n/Format.d.ts.map +0 -1
  798. package/dist/i18n/Format.js +0 -32
  799. package/dist/i18n/Format.js.map +0 -1
  800. package/dist/i18n/FormatSpec.d.ts +0 -76
  801. package/dist/i18n/FormatSpec.d.ts.map +0 -1
  802. package/dist/i18n/FormatSpec.js +0 -306
  803. package/dist/i18n/FormatSpec.js.map +0 -1
  804. package/dist/i18n/Po.d.ts +0 -54
  805. package/dist/i18n/Po.d.ts.map +0 -1
  806. package/dist/i18n/Po.js +0 -192
  807. package/dist/i18n/Po.js.map +0 -1
  808. package/dist/i18n/SemanticMessage.d.ts +0 -84
  809. package/dist/i18n/SemanticMessage.d.ts.map +0 -1
  810. package/dist/i18n/SemanticMessage.js +0 -54
  811. package/dist/i18n/SemanticMessage.js.map +0 -1
  812. package/dist/i18n/SoundMarkers.d.ts +0 -38
  813. package/dist/i18n/SoundMarkers.d.ts.map +0 -1
  814. package/dist/i18n/SoundMarkers.js +0 -48
  815. package/dist/i18n/SoundMarkers.js.map +0 -1
  816. package/dist/i18n/Validate.d.ts +0 -82
  817. package/dist/i18n/Validate.d.ts.map +0 -1
  818. package/dist/i18n/Validate.js +0 -106
  819. package/dist/i18n/Validate.js.map +0 -1
  820. package/dist/i18n/index.d.ts +0 -177
  821. package/dist/i18n/index.d.ts.map +0 -1
  822. package/dist/i18n/index.js +0 -331
  823. package/dist/i18n/index.js.map +0 -1
  824. package/dist/index.d.ts +0 -26
  825. package/dist/index.d.ts.map +0 -1
  826. package/dist/index.js +0 -26
  827. package/dist/index.js.map +0 -1
  828. package/dist/mw_games.global.js +0 -1410
  829. package/dist/mwl/MapFile.d.ts +0 -41
  830. package/dist/mwl/MapFile.d.ts.map +0 -1
  831. package/dist/mwl/MapFile.js +0 -53
  832. package/dist/mwl/MapFile.js.map +0 -1
  833. package/dist/mwl/actors.d.ts +0 -62
  834. package/dist/mwl/actors.d.ts.map +0 -1
  835. package/dist/mwl/actors.js +0 -82
  836. package/dist/mwl/actors.js.map +0 -1
  837. package/dist/mwl/campaign.d.ts +0 -51
  838. package/dist/mwl/campaign.d.ts.map +0 -1
  839. package/dist/mwl/campaign.js +0 -58
  840. package/dist/mwl/campaign.js.map +0 -1
  841. package/dist/mwl/carryover.d.ts +0 -86
  842. package/dist/mwl/carryover.d.ts.map +0 -1
  843. package/dist/mwl/carryover.js +0 -70
  844. package/dist/mwl/carryover.js.map +0 -1
  845. package/dist/mwl/catalog.d.ts +0 -98
  846. package/dist/mwl/catalog.d.ts.map +0 -1
  847. package/dist/mwl/catalog.js +0 -259
  848. package/dist/mwl/catalog.js.map +0 -1
  849. package/dist/mwl/compiler.d.ts +0 -135
  850. package/dist/mwl/compiler.d.ts.map +0 -1
  851. package/dist/mwl/compiler.js +0 -216
  852. package/dist/mwl/compiler.js.map +0 -1
  853. package/dist/mwl/conditions.d.ts +0 -30
  854. package/dist/mwl/conditions.d.ts.map +0 -1
  855. package/dist/mwl/conditions.js +0 -212
  856. package/dist/mwl/conditions.js.map +0 -1
  857. package/dist/mwl/content.d.ts +0 -140
  858. package/dist/mwl/content.d.ts.map +0 -1
  859. package/dist/mwl/content.js +0 -179
  860. package/dist/mwl/content.js.map +0 -1
  861. package/dist/mwl/expression.d.ts +0 -42
  862. package/dist/mwl/expression.d.ts.map +0 -1
  863. package/dist/mwl/expression.js +0 -164
  864. package/dist/mwl/expression.js.map +0 -1
  865. package/dist/mwl/grammar.d.ts +0 -100
  866. package/dist/mwl/grammar.d.ts.map +0 -1
  867. package/dist/mwl/grammar.js +0 -588
  868. package/dist/mwl/grammar.js.map +0 -1
  869. package/dist/mwl/hooks.d.ts +0 -201
  870. package/dist/mwl/hooks.d.ts.map +0 -1
  871. package/dist/mwl/hooks.js +0 -165
  872. package/dist/mwl/hooks.js.map +0 -1
  873. package/dist/mwl/index.d.ts +0 -51
  874. package/dist/mwl/index.d.ts.map +0 -1
  875. package/dist/mwl/index.js +0 -26
  876. package/dist/mwl/index.js.map +0 -1
  877. package/dist/mwl/objects.d.ts +0 -31
  878. package/dist/mwl/objects.d.ts.map +0 -1
  879. package/dist/mwl/objects.js +0 -83
  880. package/dist/mwl/objects.js.map +0 -1
  881. package/dist/mwl/package-container.d.ts +0 -185
  882. package/dist/mwl/package-container.d.ts.map +0 -1
  883. package/dist/mwl/package-container.js +0 -446
  884. package/dist/mwl/package-container.js.map +0 -1
  885. package/dist/mwl/package-document.d.ts +0 -217
  886. package/dist/mwl/package-document.d.ts.map +0 -1
  887. package/dist/mwl/package-document.js +0 -639
  888. package/dist/mwl/package-document.js.map +0 -1
  889. package/dist/mwl/package-rom.d.ts +0 -37
  890. package/dist/mwl/package-rom.d.ts.map +0 -1
  891. package/dist/mwl/package-rom.js +0 -96
  892. package/dist/mwl/package-rom.js.map +0 -1
  893. package/dist/mwl/package-verify.d.ts +0 -34
  894. package/dist/mwl/package-verify.d.ts.map +0 -1
  895. package/dist/mwl/package-verify.js +0 -111
  896. package/dist/mwl/package-verify.js.map +0 -1
  897. package/dist/mwl/package.d.ts +0 -184
  898. package/dist/mwl/package.d.ts.map +0 -1
  899. package/dist/mwl/package.js +0 -382
  900. package/dist/mwl/package.js.map +0 -1
  901. package/dist/mwl/persistence.d.ts +0 -67
  902. package/dist/mwl/persistence.d.ts.map +0 -1
  903. package/dist/mwl/persistence.js +0 -135
  904. package/dist/mwl/persistence.js.map +0 -1
  905. package/dist/mwl/presentation.d.ts +0 -86
  906. package/dist/mwl/presentation.d.ts.map +0 -1
  907. package/dist/mwl/presentation.js +0 -419
  908. package/dist/mwl/presentation.js.map +0 -1
  909. package/dist/mwl/pyroeis-runtime.d.ts +0 -82
  910. package/dist/mwl/pyroeis-runtime.d.ts.map +0 -1
  911. package/dist/mwl/pyroeis-runtime.js +0 -535
  912. package/dist/mwl/pyroeis-runtime.js.map +0 -1
  913. package/dist/mwl/pyroeis.d.ts +0 -54
  914. package/dist/mwl/pyroeis.d.ts.map +0 -1
  915. package/dist/mwl/pyroeis.js +0 -189
  916. package/dist/mwl/pyroeis.js.map +0 -1
  917. package/dist/mwl/readers.d.ts +0 -77
  918. package/dist/mwl/readers.d.ts.map +0 -1
  919. package/dist/mwl/readers.js +0 -150
  920. package/dist/mwl/readers.js.map +0 -1
  921. package/dist/mwl/report.d.ts +0 -44
  922. package/dist/mwl/report.d.ts.map +0 -1
  923. package/dist/mwl/report.js +0 -88
  924. package/dist/mwl/report.js.map +0 -1
  925. package/dist/mwl/runtime.d.ts +0 -577
  926. package/dist/mwl/runtime.d.ts.map +0 -1
  927. package/dist/mwl/runtime.js +0 -1741
  928. package/dist/mwl/runtime.js.map +0 -1
  929. package/dist/mwl/schema.d.ts +0 -151
  930. package/dist/mwl/schema.d.ts.map +0 -1
  931. package/dist/mwl/schema.js +0 -979
  932. package/dist/mwl/schema.js.map +0 -1
  933. package/dist/mwl/scripts.d.ts +0 -26
  934. package/dist/mwl/scripts.d.ts.map +0 -1
  935. package/dist/mwl/scripts.js +0 -34
  936. package/dist/mwl/scripts.js.map +0 -1
  937. package/dist/mwl/tables.d.ts +0 -95
  938. package/dist/mwl/tables.d.ts.map +0 -1
  939. package/dist/mwl/tables.js +0 -100
  940. package/dist/mwl/tables.js.map +0 -1
  941. package/dist/mwl/utils.d.ts +0 -10
  942. package/dist/mwl/utils.d.ts.map +0 -1
  943. package/dist/mwl/utils.js +0 -40
  944. package/dist/mwl/utils.js.map +0 -1
  945. package/dist/physics/PhysicsWorld.d.ts +0 -158
  946. package/dist/physics/PhysicsWorld.d.ts.map +0 -1
  947. package/dist/physics/PhysicsWorld.js +0 -376
  948. package/dist/physics/PhysicsWorld.js.map +0 -1
  949. package/dist/physics/XpbdWorld.d.ts +0 -213
  950. package/dist/physics/XpbdWorld.d.ts.map +0 -1
  951. package/dist/physics/XpbdWorld.js +0 -337
  952. package/dist/physics/XpbdWorld.js.map +0 -1
  953. package/dist/physics/cloth/index.d.ts +0 -99
  954. package/dist/physics/cloth/index.d.ts.map +0 -1
  955. package/dist/physics/cloth/index.js +0 -226
  956. package/dist/physics/cloth/index.js.map +0 -1
  957. package/dist/physics/index.d.ts +0 -7
  958. package/dist/physics/index.d.ts.map +0 -1
  959. package/dist/physics/index.js +0 -4
  960. package/dist/physics/index.js.map +0 -1
  961. package/dist/physics/spring/index.d.ts +0 -91
  962. package/dist/physics/spring/index.d.ts.map +0 -1
  963. package/dist/physics/spring/index.js +0 -120
  964. package/dist/physics/spring/index.js.map +0 -1
  965. package/dist/physics/xpbd.d.ts +0 -3
  966. package/dist/physics/xpbd.d.ts.map +0 -1
  967. package/dist/physics/xpbd.js +0 -2
  968. package/dist/physics/xpbd.js.map +0 -1
  969. package/dist/roguelike/Boss.d.ts +0 -79
  970. package/dist/roguelike/Boss.d.ts.map +0 -1
  971. package/dist/roguelike/Boss.js +0 -126
  972. package/dist/roguelike/Boss.js.map +0 -1
  973. package/dist/roguelike/Cave.d.ts +0 -124
  974. package/dist/roguelike/Cave.d.ts.map +0 -1
  975. package/dist/roguelike/Cave.js +0 -216
  976. package/dist/roguelike/Cave.js.map +0 -1
  977. package/dist/roguelike/Combat.d.ts +0 -35
  978. package/dist/roguelike/Combat.d.ts.map +0 -1
  979. package/dist/roguelike/Combat.js +0 -33
  980. package/dist/roguelike/Combat.js.map +0 -1
  981. package/dist/roguelike/ContentRoll.d.ts +0 -53
  982. package/dist/roguelike/ContentRoll.d.ts.map +0 -1
  983. package/dist/roguelike/ContentRoll.js +0 -48
  984. package/dist/roguelike/ContentRoll.js.map +0 -1
  985. package/dist/roguelike/Doors.d.ts +0 -73
  986. package/dist/roguelike/Doors.d.ts.map +0 -1
  987. package/dist/roguelike/Doors.js +0 -115
  988. package/dist/roguelike/Doors.js.map +0 -1
  989. package/dist/roguelike/DungeonParity.d.ts +0 -57
  990. package/dist/roguelike/DungeonParity.d.ts.map +0 -1
  991. package/dist/roguelike/DungeonParity.js +0 -87
  992. package/dist/roguelike/DungeonParity.js.map +0 -1
  993. package/dist/roguelike/Elevation.d.ts +0 -41
  994. package/dist/roguelike/Elevation.d.ts.map +0 -1
  995. package/dist/roguelike/Elevation.js +0 -52
  996. package/dist/roguelike/Elevation.js.map +0 -1
  997. package/dist/roguelike/Features.d.ts +0 -59
  998. package/dist/roguelike/Features.d.ts.map +0 -1
  999. package/dist/roguelike/Features.js +0 -76
  1000. package/dist/roguelike/Features.js.map +0 -1
  1001. package/dist/roguelike/FieldOfView.d.ts +0 -86
  1002. package/dist/roguelike/FieldOfView.d.ts.map +0 -1
  1003. package/dist/roguelike/FieldOfView.js +0 -148
  1004. package/dist/roguelike/FieldOfView.js.map +0 -1
  1005. package/dist/roguelike/Level.d.ts +0 -139
  1006. package/dist/roguelike/Level.d.ts.map +0 -1
  1007. package/dist/roguelike/Level.js +0 -189
  1008. package/dist/roguelike/Level.js.map +0 -1
  1009. package/dist/roguelike/MonsterAI.d.ts +0 -54
  1010. package/dist/roguelike/MonsterAI.d.ts.map +0 -1
  1011. package/dist/roguelike/MonsterAI.js +0 -83
  1012. package/dist/roguelike/MonsterAI.js.map +0 -1
  1013. package/dist/roguelike/MultiStageAbility.d.ts +0 -59
  1014. package/dist/roguelike/MultiStageAbility.d.ts.map +0 -1
  1015. package/dist/roguelike/MultiStageAbility.js +0 -76
  1016. package/dist/roguelike/MultiStageAbility.js.map +0 -1
  1017. package/dist/roguelike/MultiTurnBeam.d.ts +0 -108
  1018. package/dist/roguelike/MultiTurnBeam.d.ts.map +0 -1
  1019. package/dist/roguelike/MultiTurnBeam.js +0 -164
  1020. package/dist/roguelike/MultiTurnBeam.js.map +0 -1
  1021. package/dist/roguelike/Overworld.d.ts +0 -89
  1022. package/dist/roguelike/Overworld.d.ts.map +0 -1
  1023. package/dist/roguelike/Overworld.js +0 -325
  1024. package/dist/roguelike/Overworld.js.map +0 -1
  1025. package/dist/roguelike/Pathfinder.d.ts +0 -103
  1026. package/dist/roguelike/Pathfinder.d.ts.map +0 -1
  1027. package/dist/roguelike/Pathfinder.js +0 -213
  1028. package/dist/roguelike/Pathfinder.js.map +0 -1
  1029. package/dist/roguelike/Placement.d.ts +0 -62
  1030. package/dist/roguelike/Placement.d.ts.map +0 -1
  1031. package/dist/roguelike/Placement.js +0 -79
  1032. package/dist/roguelike/Placement.js.map +0 -1
  1033. package/dist/roguelike/RoomBuilders.d.ts +0 -60
  1034. package/dist/roguelike/RoomBuilders.d.ts.map +0 -1
  1035. package/dist/roguelike/RoomBuilders.js +0 -57
  1036. package/dist/roguelike/RoomBuilders.js.map +0 -1
  1037. package/dist/roguelike/Scheduler.d.ts +0 -96
  1038. package/dist/roguelike/Scheduler.d.ts.map +0 -1
  1039. package/dist/roguelike/Scheduler.js +0 -154
  1040. package/dist/roguelike/Scheduler.js.map +0 -1
  1041. package/dist/roguelike/Secrets.d.ts +0 -57
  1042. package/dist/roguelike/Secrets.d.ts.map +0 -1
  1043. package/dist/roguelike/Secrets.js +0 -77
  1044. package/dist/roguelike/Secrets.js.map +0 -1
  1045. package/dist/roguelike/Stealth.d.ts +0 -47
  1046. package/dist/roguelike/Stealth.d.ts.map +0 -1
  1047. package/dist/roguelike/Stealth.js +0 -48
  1048. package/dist/roguelike/Stealth.js.map +0 -1
  1049. package/dist/roguelike/Targeting.d.ts +0 -312
  1050. package/dist/roguelike/Targeting.d.ts.map +0 -1
  1051. package/dist/roguelike/Targeting.js +0 -483
  1052. package/dist/roguelike/Targeting.js.map +0 -1
  1053. package/dist/roguelike/TriggerTracker.d.ts +0 -46
  1054. package/dist/roguelike/TriggerTracker.d.ts.map +0 -1
  1055. package/dist/roguelike/TriggerTracker.js +0 -59
  1056. package/dist/roguelike/TriggerTracker.js.map +0 -1
  1057. package/dist/roguelike/generate.d.ts +0 -139
  1058. package/dist/roguelike/generate.d.ts.map +0 -1
  1059. package/dist/roguelike/generate.js +0 -166
  1060. package/dist/roguelike/generate.js.map +0 -1
  1061. package/dist/roguelike/index.d.ts +0 -48
  1062. package/dist/roguelike/index.d.ts.map +0 -1
  1063. package/dist/roguelike/index.js +0 -27
  1064. package/dist/roguelike/index.js.map +0 -1
  1065. package/dist/rpg/Collision.d.ts +0 -61
  1066. package/dist/rpg/Collision.d.ts.map +0 -1
  1067. package/dist/rpg/Collision.js +0 -94
  1068. package/dist/rpg/Collision.js.map +0 -1
  1069. package/dist/rpg/Event.d.ts +0 -50
  1070. package/dist/rpg/Event.d.ts.map +0 -1
  1071. package/dist/rpg/Event.js +0 -36
  1072. package/dist/rpg/Event.js.map +0 -1
  1073. package/dist/rpg/EventRunner.d.ts +0 -139
  1074. package/dist/rpg/EventRunner.d.ts.map +0 -1
  1075. package/dist/rpg/EventRunner.js +0 -125
  1076. package/dist/rpg/EventRunner.js.map +0 -1
  1077. package/dist/rpg/FreeMover.d.ts +0 -59
  1078. package/dist/rpg/FreeMover.d.ts.map +0 -1
  1079. package/dist/rpg/FreeMover.js +0 -79
  1080. package/dist/rpg/FreeMover.js.map +0 -1
  1081. package/dist/rpg/GameState.d.ts +0 -36
  1082. package/dist/rpg/GameState.d.ts.map +0 -1
  1083. package/dist/rpg/GameState.js +0 -49
  1084. package/dist/rpg/GameState.js.map +0 -1
  1085. package/dist/rpg/GridMover.d.ts +0 -71
  1086. package/dist/rpg/GridMover.d.ts.map +0 -1
  1087. package/dist/rpg/GridMover.js +0 -119
  1088. package/dist/rpg/GridMover.js.map +0 -1
  1089. package/dist/rpg/Marshal.d.ts +0 -81
  1090. package/dist/rpg/Marshal.d.ts.map +0 -1
  1091. package/dist/rpg/Marshal.js +0 -422
  1092. package/dist/rpg/Marshal.js.map +0 -1
  1093. package/dist/rpg/MovableSprite.d.ts +0 -31
  1094. package/dist/rpg/MovableSprite.d.ts.map +0 -1
  1095. package/dist/rpg/MovableSprite.js +0 -10
  1096. package/dist/rpg/MovableSprite.js.map +0 -1
  1097. package/dist/rpg/MoveRoute.d.ts +0 -118
  1098. package/dist/rpg/MoveRoute.d.ts.map +0 -1
  1099. package/dist/rpg/MoveRoute.js +0 -139
  1100. package/dist/rpg/MoveRoute.js.map +0 -1
  1101. package/dist/rpg/Quest.d.ts +0 -173
  1102. package/dist/rpg/Quest.d.ts.map +0 -1
  1103. package/dist/rpg/Quest.js +0 -221
  1104. package/dist/rpg/Quest.js.map +0 -1
  1105. package/dist/rpg/automap.d.ts +0 -81
  1106. package/dist/rpg/automap.d.ts.map +0 -1
  1107. package/dist/rpg/automap.js +0 -107
  1108. package/dist/rpg/automap.js.map +0 -1
  1109. package/dist/rpg/dialogue-text.d.ts +0 -81
  1110. package/dist/rpg/dialogue-text.d.ts.map +0 -1
  1111. package/dist/rpg/dialogue-text.js +0 -88
  1112. package/dist/rpg/dialogue-text.js.map +0 -1
  1113. package/dist/rpg/index.d.ts +0 -25
  1114. package/dist/rpg/index.d.ts.map +0 -1
  1115. package/dist/rpg/index.js +0 -14
  1116. package/dist/rpg/index.js.map +0 -1
  1117. package/dist/rpg/twee-events.d.ts +0 -48
  1118. package/dist/rpg/twee-events.d.ts.map +0 -1
  1119. package/dist/rpg/twee-events.js +0 -35
  1120. package/dist/rpg/twee-events.js.map +0 -1
  1121. package/dist/simulation/Campaign.d.ts +0 -60
  1122. package/dist/simulation/Campaign.d.ts.map +0 -1
  1123. package/dist/simulation/Campaign.js +0 -89
  1124. package/dist/simulation/Campaign.js.map +0 -1
  1125. package/dist/simulation/CampaignSave.d.ts +0 -68
  1126. package/dist/simulation/CampaignSave.d.ts.map +0 -1
  1127. package/dist/simulation/CampaignSave.js +0 -54
  1128. package/dist/simulation/CampaignSave.js.map +0 -1
  1129. package/dist/simulation/EventPresentation.d.ts +0 -111
  1130. package/dist/simulation/EventPresentation.d.ts.map +0 -1
  1131. package/dist/simulation/EventPresentation.js +0 -120
  1132. package/dist/simulation/EventPresentation.js.map +0 -1
  1133. package/dist/simulation/Harness.d.ts +0 -26
  1134. package/dist/simulation/Harness.d.ts.map +0 -1
  1135. package/dist/simulation/Harness.js +0 -26
  1136. package/dist/simulation/Harness.js.map +0 -1
  1137. package/dist/simulation/Runtime.d.ts +0 -189
  1138. package/dist/simulation/Runtime.d.ts.map +0 -1
  1139. package/dist/simulation/Runtime.js +0 -244
  1140. package/dist/simulation/Runtime.js.map +0 -1
  1141. package/dist/simulation/Scenario.d.ts +0 -44
  1142. package/dist/simulation/Scenario.d.ts.map +0 -1
  1143. package/dist/simulation/Scenario.js +0 -40
  1144. package/dist/simulation/Scenario.js.map +0 -1
  1145. package/dist/simulation/Training.d.ts +0 -220
  1146. package/dist/simulation/Training.d.ts.map +0 -1
  1147. package/dist/simulation/Training.js +0 -366
  1148. package/dist/simulation/Training.js.map +0 -1
  1149. package/dist/simulation/Turns.d.ts +0 -40
  1150. package/dist/simulation/Turns.d.ts.map +0 -1
  1151. package/dist/simulation/Turns.js +0 -41
  1152. package/dist/simulation/Turns.js.map +0 -1
  1153. package/dist/simulation/index.d.ts +0 -25
  1154. package/dist/simulation/index.d.ts.map +0 -1
  1155. package/dist/simulation/index.js +0 -16
  1156. package/dist/simulation/index.js.map +0 -1
  1157. package/dist/skeleton/index.d.ts +0 -212
  1158. package/dist/skeleton/index.d.ts.map +0 -1
  1159. package/dist/skeleton/index.js +0 -325
  1160. package/dist/skeleton/index.js.map +0 -1
  1161. package/dist/testing/FakeAudio.d.ts +0 -149
  1162. package/dist/testing/FakeAudio.d.ts.map +0 -1
  1163. package/dist/testing/FakeAudio.js +0 -219
  1164. package/dist/testing/FakeAudio.js.map +0 -1
  1165. package/dist/testing/SceneControls.d.ts +0 -35
  1166. package/dist/testing/SceneControls.d.ts.map +0 -1
  1167. package/dist/testing/SceneControls.js +0 -49
  1168. package/dist/testing/SceneControls.js.map +0 -1
  1169. package/dist/testing/index.d.ts +0 -125
  1170. package/dist/testing/index.d.ts.map +0 -1
  1171. package/dist/testing/index.js +0 -157
  1172. package/dist/testing/index.js.map +0 -1
  1173. package/dist/threads/index.d.ts +0 -3
  1174. package/dist/threads/index.d.ts.map +0 -1
  1175. package/dist/threads/index.js +0 -2
  1176. package/dist/threads/index.js.map +0 -1
  1177. package/dist/threads/spawn.d.ts +0 -73
  1178. package/dist/threads/spawn.d.ts.map +0 -1
  1179. package/dist/threads/spawn.js +0 -167
  1180. package/dist/threads/spawn.js.map +0 -1
  1181. package/dist/threads/worker.d.ts +0 -51
  1182. package/dist/threads/worker.d.ts.map +0 -1
  1183. package/dist/threads/worker.js +0 -84
  1184. package/dist/threads/worker.js.map +0 -1
  1185. package/dist/three-d/Character3D.d.ts +0 -74
  1186. package/dist/three-d/Character3D.d.ts.map +0 -1
  1187. package/dist/three-d/Character3D.js +0 -122
  1188. package/dist/three-d/Character3D.js.map +0 -1
  1189. package/dist/three-d/Collision3D.d.ts +0 -111
  1190. package/dist/three-d/Collision3D.d.ts.map +0 -1
  1191. package/dist/three-d/Collision3D.js +0 -119
  1192. package/dist/three-d/Collision3D.js.map +0 -1
  1193. package/dist/three-d/Engine3D.d.ts +0 -25
  1194. package/dist/three-d/Engine3D.d.ts.map +0 -1
  1195. package/dist/three-d/Engine3D.js +0 -45
  1196. package/dist/three-d/Engine3D.js.map +0 -1
  1197. package/dist/three-d/Grid.d.ts +0 -30
  1198. package/dist/three-d/Grid.d.ts.map +0 -1
  1199. package/dist/three-d/Grid.js +0 -24
  1200. package/dist/three-d/Grid.js.map +0 -1
  1201. package/dist/three-d/Heightmap.d.ts +0 -38
  1202. package/dist/three-d/Heightmap.d.ts.map +0 -1
  1203. package/dist/three-d/Heightmap.js +0 -29
  1204. package/dist/three-d/Heightmap.js.map +0 -1
  1205. package/dist/three-d/Models.d.ts +0 -49
  1206. package/dist/three-d/Models.d.ts.map +0 -1
  1207. package/dist/three-d/Models.js +0 -77
  1208. package/dist/three-d/Models.js.map +0 -1
  1209. package/dist/three-d/TileGrid3D.d.ts +0 -27
  1210. package/dist/three-d/TileGrid3D.d.ts.map +0 -1
  1211. package/dist/three-d/TileGrid3D.js +0 -66
  1212. package/dist/three-d/TileGrid3D.js.map +0 -1
  1213. package/dist/three-d/Vox.d.ts +0 -43
  1214. package/dist/three-d/Vox.d.ts.map +0 -1
  1215. package/dist/three-d/Vox.js +0 -108
  1216. package/dist/three-d/Vox.js.map +0 -1
  1217. package/dist/three-d/index.d.ts +0 -15
  1218. package/dist/three-d/index.d.ts.map +0 -1
  1219. package/dist/three-d/index.js +0 -8
  1220. package/dist/three-d/index.js.map +0 -1
  1221. package/dist/two-d/Game.d.ts +0 -240
  1222. package/dist/two-d/Game.d.ts.map +0 -1
  1223. package/dist/two-d/Game.js +0 -487
  1224. package/dist/two-d/Game.js.map +0 -1
  1225. package/dist/two-d/QualityScaler.d.ts +0 -63
  1226. package/dist/two-d/QualityScaler.d.ts.map +0 -1
  1227. package/dist/two-d/QualityScaler.js +0 -92
  1228. package/dist/two-d/QualityScaler.js.map +0 -1
  1229. package/dist/two-d/ResolutionFit.d.ts +0 -28
  1230. package/dist/two-d/ResolutionFit.d.ts.map +0 -1
  1231. package/dist/two-d/ResolutionFit.js +0 -39
  1232. package/dist/two-d/ResolutionFit.js.map +0 -1
  1233. package/dist/two-d/Scene2D.d.ts +0 -43
  1234. package/dist/two-d/Scene2D.d.ts.map +0 -1
  1235. package/dist/two-d/Scene2D.js +0 -53
  1236. package/dist/two-d/Scene2D.js.map +0 -1
  1237. package/dist/two-d/index.d.ts +0 -22
  1238. package/dist/two-d/index.d.ts.map +0 -1
  1239. package/dist/two-d/index.js +0 -19
  1240. package/dist/two-d/index.js.map +0 -1
  1241. package/dist/two-d/pixi-interop.d.ts +0 -66
  1242. package/dist/two-d/pixi-interop.d.ts.map +0 -1
  1243. package/dist/two-d/pixi-interop.js +0 -72
  1244. package/dist/two-d/pixi-interop.js.map +0 -1
  1245. package/dist/two-d/presentation/MwlPresentation.d.ts +0 -117
  1246. package/dist/two-d/presentation/MwlPresentation.d.ts.map +0 -1
  1247. package/dist/two-d/presentation/MwlPresentation.js +0 -755
  1248. package/dist/two-d/presentation/MwlPresentation.js.map +0 -1
  1249. package/dist/two-d/presentation/index.d.ts +0 -3
  1250. package/dist/two-d/presentation/index.d.ts.map +0 -1
  1251. package/dist/two-d/presentation/index.js +0 -2
  1252. package/dist/two-d/presentation/index.js.map +0 -1
  1253. package/dist/two-d/render/ActorAnimator.d.ts +0 -92
  1254. package/dist/two-d/render/ActorAnimator.d.ts.map +0 -1
  1255. package/dist/two-d/render/ActorAnimator.js +0 -97
  1256. package/dist/two-d/render/ActorAnimator.js.map +0 -1
  1257. package/dist/two-d/render/AnimatedSprite.d.ts +0 -154
  1258. package/dist/two-d/render/AnimatedSprite.d.ts.map +0 -1
  1259. package/dist/two-d/render/AnimatedSprite.js +0 -197
  1260. package/dist/two-d/render/AnimatedSprite.js.map +0 -1
  1261. package/dist/two-d/render/Autotile.d.ts +0 -74
  1262. package/dist/two-d/render/Autotile.d.ts.map +0 -1
  1263. package/dist/two-d/render/Autotile.js +0 -149
  1264. package/dist/two-d/render/Autotile.js.map +0 -1
  1265. package/dist/two-d/render/Beam.d.ts +0 -136
  1266. package/dist/two-d/render/Beam.d.ts.map +0 -1
  1267. package/dist/two-d/render/Beam.js +0 -203
  1268. package/dist/two-d/render/Beam.js.map +0 -1
  1269. package/dist/two-d/render/Camera.d.ts +0 -255
  1270. package/dist/two-d/render/Camera.d.ts.map +0 -1
  1271. package/dist/two-d/render/Camera.js +0 -376
  1272. package/dist/two-d/render/Camera.js.map +0 -1
  1273. package/dist/two-d/render/Capabilities.d.ts +0 -84
  1274. package/dist/two-d/render/Capabilities.d.ts.map +0 -1
  1275. package/dist/two-d/render/Capabilities.js +0 -129
  1276. package/dist/two-d/render/Capabilities.js.map +0 -1
  1277. package/dist/two-d/render/ClothSprite.d.ts +0 -83
  1278. package/dist/two-d/render/ClothSprite.d.ts.map +0 -1
  1279. package/dist/two-d/render/ClothSprite.js +0 -105
  1280. package/dist/two-d/render/ClothSprite.js.map +0 -1
  1281. package/dist/two-d/render/ColorBlindness.d.ts +0 -39
  1282. package/dist/two-d/render/ColorBlindness.d.ts.map +0 -1
  1283. package/dist/two-d/render/ColorBlindness.js +0 -45
  1284. package/dist/two-d/render/ColorBlindness.js.map +0 -1
  1285. package/dist/two-d/render/ColorTransformBatcher.d.ts +0 -143
  1286. package/dist/two-d/render/ColorTransformBatcher.d.ts.map +0 -1
  1287. package/dist/two-d/render/ColorTransformBatcher.js +0 -395
  1288. package/dist/two-d/render/ColorTransformBatcher.js.map +0 -1
  1289. package/dist/two-d/render/Flights.d.ts +0 -90
  1290. package/dist/two-d/render/Flights.d.ts.map +0 -1
  1291. package/dist/two-d/render/Flights.js +0 -135
  1292. package/dist/two-d/render/Flights.js.map +0 -1
  1293. package/dist/two-d/render/FogLayer.d.ts +0 -68
  1294. package/dist/two-d/render/FogLayer.d.ts.map +0 -1
  1295. package/dist/two-d/render/FogLayer.js +0 -83
  1296. package/dist/two-d/render/FogLayer.js.map +0 -1
  1297. package/dist/two-d/render/Halo.d.ts +0 -58
  1298. package/dist/two-d/render/Halo.d.ts.map +0 -1
  1299. package/dist/two-d/render/Halo.js +0 -48
  1300. package/dist/two-d/render/Halo.js.map +0 -1
  1301. package/dist/two-d/render/HazeLayer.d.ts +0 -112
  1302. package/dist/two-d/render/HazeLayer.d.ts.map +0 -1
  1303. package/dist/two-d/render/HazeLayer.js +0 -186
  1304. package/dist/two-d/render/HazeLayer.js.map +0 -1
  1305. package/dist/two-d/render/ImageModifiers.d.ts +0 -312
  1306. package/dist/two-d/render/ImageModifiers.d.ts.map +0 -1
  1307. package/dist/two-d/render/ImageModifiers.js +0 -728
  1308. package/dist/two-d/render/ImageModifiers.js.map +0 -1
  1309. package/dist/two-d/render/LayeredSprite.d.ts +0 -54
  1310. package/dist/two-d/render/LayeredSprite.d.ts.map +0 -1
  1311. package/dist/two-d/render/LayeredSprite.js +0 -80
  1312. package/dist/two-d/render/LayeredSprite.js.map +0 -1
  1313. package/dist/two-d/render/LightningArc.d.ts +0 -57
  1314. package/dist/two-d/render/LightningArc.d.ts.map +0 -1
  1315. package/dist/two-d/render/LightningArc.js +0 -91
  1316. package/dist/two-d/render/LightningArc.js.map +0 -1
  1317. package/dist/two-d/render/LiquidLayer.d.ts +0 -62
  1318. package/dist/two-d/render/LiquidLayer.d.ts.map +0 -1
  1319. package/dist/two-d/render/LiquidLayer.js +0 -102
  1320. package/dist/two-d/render/LiquidLayer.js.map +0 -1
  1321. package/dist/two-d/render/Minimap.d.ts +0 -100
  1322. package/dist/two-d/render/Minimap.d.ts.map +0 -1
  1323. package/dist/two-d/render/Minimap.js +0 -157
  1324. package/dist/two-d/render/Minimap.js.map +0 -1
  1325. package/dist/two-d/render/NeonGlow.d.ts +0 -100
  1326. package/dist/two-d/render/NeonGlow.d.ts.map +0 -1
  1327. package/dist/two-d/render/NeonGlow.js +0 -184
  1328. package/dist/two-d/render/NeonGlow.js.map +0 -1
  1329. package/dist/two-d/render/PaletteRemap.d.ts +0 -154
  1330. package/dist/two-d/render/PaletteRemap.d.ts.map +0 -1
  1331. package/dist/two-d/render/PaletteRemap.js +0 -217
  1332. package/dist/two-d/render/PaletteRemap.js.map +0 -1
  1333. package/dist/two-d/render/Particles.d.ts +0 -262
  1334. package/dist/two-d/render/Particles.d.ts.map +0 -1
  1335. package/dist/two-d/render/Particles.js +0 -371
  1336. package/dist/two-d/render/Particles.js.map +0 -1
  1337. package/dist/two-d/render/Projectile.d.ts +0 -67
  1338. package/dist/two-d/render/Projectile.d.ts.map +0 -1
  1339. package/dist/two-d/render/Projectile.js +0 -78
  1340. package/dist/two-d/render/Projectile.js.map +0 -1
  1341. package/dist/two-d/render/RpgmAutotile.d.ts +0 -324
  1342. package/dist/two-d/render/RpgmAutotile.d.ts.map +0 -1
  1343. package/dist/two-d/render/RpgmAutotile.js +0 -933
  1344. package/dist/two-d/render/RpgmAutotile.js.map +0 -1
  1345. package/dist/two-d/render/SceneTransition.d.ts +0 -301
  1346. package/dist/two-d/render/SceneTransition.d.ts.map +0 -1
  1347. package/dist/two-d/render/SceneTransition.js +0 -458
  1348. package/dist/two-d/render/SceneTransition.js.map +0 -1
  1349. package/dist/two-d/render/ScreenEffects.d.ts +0 -124
  1350. package/dist/two-d/render/ScreenEffects.d.ts.map +0 -1
  1351. package/dist/two-d/render/ScreenEffects.js +0 -215
  1352. package/dist/two-d/render/ScreenEffects.js.map +0 -1
  1353. package/dist/two-d/render/Shape2D.d.ts +0 -146
  1354. package/dist/two-d/render/Shape2D.d.ts.map +0 -1
  1355. package/dist/two-d/render/Shape2D.js +0 -166
  1356. package/dist/two-d/render/Shape2D.js.map +0 -1
  1357. package/dist/two-d/render/SkeletalSprite.d.ts +0 -121
  1358. package/dist/two-d/render/SkeletalSprite.d.ts.map +0 -1
  1359. package/dist/two-d/render/SkeletalSprite.js +0 -214
  1360. package/dist/two-d/render/SkeletalSprite.js.map +0 -1
  1361. package/dist/two-d/render/SpringSprite.d.ts +0 -40
  1362. package/dist/two-d/render/SpringSprite.d.ts.map +0 -1
  1363. package/dist/two-d/render/SpringSprite.js +0 -39
  1364. package/dist/two-d/render/SpringSprite.js.map +0 -1
  1365. package/dist/two-d/render/SpriteAttachment.d.ts +0 -55
  1366. package/dist/two-d/render/SpriteAttachment.d.ts.map +0 -1
  1367. package/dist/two-d/render/SpriteAttachment.js +0 -60
  1368. package/dist/two-d/render/SpriteAttachment.js.map +0 -1
  1369. package/dist/two-d/render/SpriteDeform.d.ts +0 -156
  1370. package/dist/two-d/render/SpriteDeform.d.ts.map +0 -1
  1371. package/dist/two-d/render/SpriteDeform.js +0 -278
  1372. package/dist/two-d/render/SpriteDeform.js.map +0 -1
  1373. package/dist/two-d/render/SpriteGroup.d.ts +0 -83
  1374. package/dist/two-d/render/SpriteGroup.d.ts.map +0 -1
  1375. package/dist/two-d/render/SpriteGroup.js +0 -107
  1376. package/dist/two-d/render/SpriteGroup.js.map +0 -1
  1377. package/dist/two-d/render/SpriteMotion.d.ts +0 -121
  1378. package/dist/two-d/render/SpriteMotion.d.ts.map +0 -1
  1379. package/dist/two-d/render/SpriteMotion.js +0 -193
  1380. package/dist/two-d/render/SpriteMotion.js.map +0 -1
  1381. package/dist/two-d/render/SpriteSheet.d.ts +0 -62
  1382. package/dist/two-d/render/SpriteSheet.d.ts.map +0 -1
  1383. package/dist/two-d/render/SpriteSheet.js +0 -122
  1384. package/dist/two-d/render/SpriteSheet.js.map +0 -1
  1385. package/dist/two-d/render/StatusVisuals.d.ts +0 -86
  1386. package/dist/two-d/render/StatusVisuals.d.ts.map +0 -1
  1387. package/dist/two-d/render/StatusVisuals.js +0 -111
  1388. package/dist/two-d/render/StatusVisuals.js.map +0 -1
  1389. package/dist/two-d/render/SvgSkeleton.d.ts +0 -54
  1390. package/dist/two-d/render/SvgSkeleton.d.ts.map +0 -1
  1391. package/dist/two-d/render/SvgSkeleton.js +0 -112
  1392. package/dist/two-d/render/SvgSkeleton.js.map +0 -1
  1393. package/dist/two-d/render/TerrainGraphics.d.ts +0 -142
  1394. package/dist/two-d/render/TerrainGraphics.d.ts.map +0 -1
  1395. package/dist/two-d/render/TerrainGraphics.js +0 -161
  1396. package/dist/two-d/render/TerrainGraphics.js.map +0 -1
  1397. package/dist/two-d/render/TerrainGraphicsLayer.d.ts +0 -55
  1398. package/dist/two-d/render/TerrainGraphicsLayer.d.ts.map +0 -1
  1399. package/dist/two-d/render/TerrainGraphicsLayer.js +0 -54
  1400. package/dist/two-d/render/TerrainGraphicsLayer.js.map +0 -1
  1401. package/dist/two-d/render/TileMap.d.ts +0 -395
  1402. package/dist/two-d/render/TileMap.d.ts.map +0 -1
  1403. package/dist/two-d/render/TileMap.js +0 -967
  1404. package/dist/two-d/render/TileMap.js.map +0 -1
  1405. package/dist/two-d/render/TiledMap.d.ts +0 -113
  1406. package/dist/two-d/render/TiledMap.d.ts.map +0 -1
  1407. package/dist/two-d/render/TiledMap.js +0 -129
  1408. package/dist/two-d/render/TiledMap.js.map +0 -1
  1409. package/dist/two-d/render/TintedSprite.d.ts +0 -60
  1410. package/dist/two-d/render/TintedSprite.d.ts.map +0 -1
  1411. package/dist/two-d/render/TintedSprite.js +0 -88
  1412. package/dist/two-d/render/TintedSprite.js.map +0 -1
  1413. package/dist/two-d/render/Types2D.d.ts +0 -56
  1414. package/dist/two-d/render/Types2D.d.ts.map +0 -1
  1415. package/dist/two-d/render/Types2D.js +0 -45
  1416. package/dist/two-d/render/Types2D.js.map +0 -1
  1417. package/dist/two-d/render/Viewport.d.ts +0 -68
  1418. package/dist/two-d/render/Viewport.d.ts.map +0 -1
  1419. package/dist/two-d/render/Viewport.js +0 -74
  1420. package/dist/two-d/render/Viewport.js.map +0 -1
  1421. package/dist/two-d/render/index.d.ts +0 -81
  1422. package/dist/two-d/render/index.d.ts.map +0 -1
  1423. package/dist/two-d/render/index.js +0 -43
  1424. package/dist/two-d/render/index.js.map +0 -1
  1425. package/dist/two-d/stage/DialogueStage.d.ts +0 -90
  1426. package/dist/two-d/stage/DialogueStage.d.ts.map +0 -1
  1427. package/dist/two-d/stage/DialogueStage.js +0 -218
  1428. package/dist/two-d/stage/DialogueStage.js.map +0 -1
  1429. package/dist/two-d/stage/StoryScreen.d.ts +0 -110
  1430. package/dist/two-d/stage/StoryScreen.d.ts.map +0 -1
  1431. package/dist/two-d/stage/StoryScreen.js +0 -178
  1432. package/dist/two-d/stage/StoryScreen.js.map +0 -1
  1433. package/dist/two-d/stage/dialogue-text.d.ts +0 -81
  1434. package/dist/two-d/stage/dialogue-text.d.ts.map +0 -1
  1435. package/dist/two-d/stage/dialogue-text.js +0 -95
  1436. package/dist/two-d/stage/dialogue-text.js.map +0 -1
  1437. package/dist/two-d/stage/index.d.ts +0 -10
  1438. package/dist/two-d/stage/index.d.ts.map +0 -1
  1439. package/dist/two-d/stage/index.js +0 -6
  1440. package/dist/two-d/stage/index.js.map +0 -1
  1441. package/dist/two-d/stage/script.d.ts +0 -160
  1442. package/dist/two-d/stage/script.d.ts.map +0 -1
  1443. package/dist/two-d/stage/script.js +0 -207
  1444. package/dist/two-d/stage/script.js.map +0 -1
  1445. package/dist/two-d/stage/twee.d.ts +0 -35
  1446. package/dist/two-d/stage/twee.d.ts.map +0 -1
  1447. package/dist/two-d/stage/twee.js +0 -28
  1448. package/dist/two-d/stage/twee.js.map +0 -1
  1449. package/dist/two-d/ui/Bar.d.ts +0 -83
  1450. package/dist/two-d/ui/Bar.d.ts.map +0 -1
  1451. package/dist/two-d/ui/Bar.js +0 -110
  1452. package/dist/two-d/ui/Bar.js.map +0 -1
  1453. package/dist/two-d/ui/BitmapLabel.d.ts +0 -58
  1454. package/dist/two-d/ui/BitmapLabel.d.ts.map +0 -1
  1455. package/dist/two-d/ui/BitmapLabel.js +0 -82
  1456. package/dist/two-d/ui/BitmapLabel.js.map +0 -1
  1457. package/dist/two-d/ui/Button.d.ts +0 -133
  1458. package/dist/two-d/ui/Button.d.ts.map +0 -1
  1459. package/dist/two-d/ui/Button.js +0 -254
  1460. package/dist/two-d/ui/Button.js.map +0 -1
  1461. package/dist/two-d/ui/Checkbox.d.ts +0 -44
  1462. package/dist/two-d/ui/Checkbox.d.ts.map +0 -1
  1463. package/dist/two-d/ui/Checkbox.js +0 -89
  1464. package/dist/two-d/ui/Checkbox.js.map +0 -1
  1465. package/dist/two-d/ui/DataTable.d.ts +0 -79
  1466. package/dist/two-d/ui/DataTable.d.ts.map +0 -1
  1467. package/dist/two-d/ui/DataTable.js +0 -164
  1468. package/dist/two-d/ui/DataTable.js.map +0 -1
  1469. package/dist/two-d/ui/Dropdown.d.ts +0 -79
  1470. package/dist/two-d/ui/Dropdown.d.ts.map +0 -1
  1471. package/dist/two-d/ui/Dropdown.js +0 -136
  1472. package/dist/two-d/ui/Dropdown.js.map +0 -1
  1473. package/dist/two-d/ui/DropdownView.d.ts +0 -100
  1474. package/dist/two-d/ui/DropdownView.d.ts.map +0 -1
  1475. package/dist/two-d/ui/DropdownView.js +0 -234
  1476. package/dist/two-d/ui/DropdownView.js.map +0 -1
  1477. package/dist/two-d/ui/EventDialogue.d.ts +0 -23
  1478. package/dist/two-d/ui/EventDialogue.d.ts.map +0 -1
  1479. package/dist/two-d/ui/EventDialogue.js +0 -33
  1480. package/dist/two-d/ui/EventDialogue.js.map +0 -1
  1481. package/dist/two-d/ui/FloatingText.d.ts +0 -123
  1482. package/dist/two-d/ui/FloatingText.d.ts.map +0 -1
  1483. package/dist/two-d/ui/FloatingText.js +0 -153
  1484. package/dist/two-d/ui/FloatingText.js.map +0 -1
  1485. package/dist/two-d/ui/FloatingTextStack.d.ts +0 -150
  1486. package/dist/two-d/ui/FloatingTextStack.d.ts.map +0 -1
  1487. package/dist/two-d/ui/FloatingTextStack.js +0 -170
  1488. package/dist/two-d/ui/FloatingTextStack.js.map +0 -1
  1489. package/dist/two-d/ui/HelpScreen.d.ts +0 -45
  1490. package/dist/two-d/ui/HelpScreen.d.ts.map +0 -1
  1491. package/dist/two-d/ui/HelpScreen.js +0 -59
  1492. package/dist/two-d/ui/HelpScreen.js.map +0 -1
  1493. package/dist/two-d/ui/IconGrid.d.ts +0 -143
  1494. package/dist/two-d/ui/IconGrid.d.ts.map +0 -1
  1495. package/dist/two-d/ui/IconGrid.js +0 -327
  1496. package/dist/two-d/ui/IconGrid.js.map +0 -1
  1497. package/dist/two-d/ui/Label.d.ts +0 -63
  1498. package/dist/two-d/ui/Label.d.ts.map +0 -1
  1499. package/dist/two-d/ui/Label.js +0 -134
  1500. package/dist/two-d/ui/Label.js.map +0 -1
  1501. package/dist/two-d/ui/Layout.d.ts +0 -139
  1502. package/dist/two-d/ui/Layout.d.ts.map +0 -1
  1503. package/dist/two-d/ui/Layout.js +0 -221
  1504. package/dist/two-d/ui/Layout.js.map +0 -1
  1505. package/dist/two-d/ui/ListView.d.ts +0 -130
  1506. package/dist/two-d/ui/ListView.d.ts.map +0 -1
  1507. package/dist/two-d/ui/ListView.js +0 -326
  1508. package/dist/two-d/ui/ListView.js.map +0 -1
  1509. package/dist/two-d/ui/LoadingScreen.d.ts +0 -54
  1510. package/dist/two-d/ui/LoadingScreen.d.ts.map +0 -1
  1511. package/dist/two-d/ui/LoadingScreen.js +0 -87
  1512. package/dist/two-d/ui/LoadingScreen.js.map +0 -1
  1513. package/dist/two-d/ui/MarkupText.d.ts +0 -66
  1514. package/dist/two-d/ui/MarkupText.d.ts.map +0 -1
  1515. package/dist/two-d/ui/MarkupText.js +0 -156
  1516. package/dist/two-d/ui/MarkupText.js.map +0 -1
  1517. package/dist/two-d/ui/MessageBox.d.ts +0 -134
  1518. package/dist/two-d/ui/MessageBox.d.ts.map +0 -1
  1519. package/dist/two-d/ui/MessageBox.js +0 -263
  1520. package/dist/two-d/ui/MessageBox.js.map +0 -1
  1521. package/dist/two-d/ui/MessageLog.d.ts +0 -90
  1522. package/dist/two-d/ui/MessageLog.d.ts.map +0 -1
  1523. package/dist/two-d/ui/MessageLog.js +0 -131
  1524. package/dist/two-d/ui/MessageLog.js.map +0 -1
  1525. package/dist/two-d/ui/Meter.d.ts +0 -76
  1526. package/dist/two-d/ui/Meter.d.ts.map +0 -1
  1527. package/dist/two-d/ui/Meter.js +0 -134
  1528. package/dist/two-d/ui/Meter.js.map +0 -1
  1529. package/dist/two-d/ui/NinePatch.d.ts +0 -49
  1530. package/dist/two-d/ui/NinePatch.d.ts.map +0 -1
  1531. package/dist/two-d/ui/NinePatch.js +0 -59
  1532. package/dist/two-d/ui/NinePatch.js.map +0 -1
  1533. package/dist/two-d/ui/OnScreenKeyboard.d.ts +0 -91
  1534. package/dist/two-d/ui/OnScreenKeyboard.d.ts.map +0 -1
  1535. package/dist/two-d/ui/OnScreenKeyboard.js +0 -109
  1536. package/dist/two-d/ui/OnScreenKeyboard.js.map +0 -1
  1537. package/dist/two-d/ui/RadioGroup.d.ts +0 -68
  1538. package/dist/two-d/ui/RadioGroup.d.ts.map +0 -1
  1539. package/dist/two-d/ui/RadioGroup.js +0 -177
  1540. package/dist/two-d/ui/RadioGroup.js.map +0 -1
  1541. package/dist/two-d/ui/RebindScreen.d.ts +0 -70
  1542. package/dist/two-d/ui/RebindScreen.d.ts.map +0 -1
  1543. package/dist/two-d/ui/RebindScreen.js +0 -129
  1544. package/dist/two-d/ui/RebindScreen.js.map +0 -1
  1545. package/dist/two-d/ui/RichLabel.d.ts +0 -62
  1546. package/dist/two-d/ui/RichLabel.d.ts.map +0 -1
  1547. package/dist/two-d/ui/RichLabel.js +0 -146
  1548. package/dist/two-d/ui/RichLabel.js.map +0 -1
  1549. package/dist/two-d/ui/ScrollBox.d.ts +0 -163
  1550. package/dist/two-d/ui/ScrollBox.d.ts.map +0 -1
  1551. package/dist/two-d/ui/ScrollBox.js +0 -340
  1552. package/dist/two-d/ui/ScrollBox.js.map +0 -1
  1553. package/dist/two-d/ui/ScrollText.d.ts +0 -131
  1554. package/dist/two-d/ui/ScrollText.d.ts.map +0 -1
  1555. package/dist/two-d/ui/ScrollText.js +0 -218
  1556. package/dist/two-d/ui/ScrollText.js.map +0 -1
  1557. package/dist/two-d/ui/SelectionModel.d.ts +0 -50
  1558. package/dist/two-d/ui/SelectionModel.d.ts.map +0 -1
  1559. package/dist/two-d/ui/SelectionModel.js +0 -73
  1560. package/dist/two-d/ui/SelectionModel.js.map +0 -1
  1561. package/dist/two-d/ui/SettingsScreen.d.ts +0 -112
  1562. package/dist/two-d/ui/SettingsScreen.d.ts.map +0 -1
  1563. package/dist/two-d/ui/SettingsScreen.js +0 -338
  1564. package/dist/two-d/ui/SettingsScreen.js.map +0 -1
  1565. package/dist/two-d/ui/Skins.d.ts +0 -59
  1566. package/dist/two-d/ui/Skins.d.ts.map +0 -1
  1567. package/dist/two-d/ui/Skins.js +0 -77
  1568. package/dist/two-d/ui/Skins.js.map +0 -1
  1569. package/dist/two-d/ui/Slider.d.ts +0 -91
  1570. package/dist/two-d/ui/Slider.d.ts.map +0 -1
  1571. package/dist/two-d/ui/Slider.js +0 -170
  1572. package/dist/two-d/ui/Slider.js.map +0 -1
  1573. package/dist/two-d/ui/Spinner.d.ts +0 -67
  1574. package/dist/two-d/ui/Spinner.d.ts.map +0 -1
  1575. package/dist/two-d/ui/Spinner.js +0 -137
  1576. package/dist/two-d/ui/Spinner.js.map +0 -1
  1577. package/dist/two-d/ui/StatsScreen.d.ts +0 -40
  1578. package/dist/two-d/ui/StatsScreen.d.ts.map +0 -1
  1579. package/dist/two-d/ui/StatsScreen.js +0 -42
  1580. package/dist/two-d/ui/StatsScreen.js.map +0 -1
  1581. package/dist/two-d/ui/TabbedList.d.ts +0 -118
  1582. package/dist/two-d/ui/TabbedList.d.ts.map +0 -1
  1583. package/dist/two-d/ui/TabbedList.js +0 -221
  1584. package/dist/two-d/ui/TabbedList.js.map +0 -1
  1585. package/dist/two-d/ui/TextModel.d.ts +0 -90
  1586. package/dist/two-d/ui/TextModel.d.ts.map +0 -1
  1587. package/dist/two-d/ui/TextModel.js +0 -175
  1588. package/dist/two-d/ui/TextModel.js.map +0 -1
  1589. package/dist/two-d/ui/TextPrompt.d.ts +0 -122
  1590. package/dist/two-d/ui/TextPrompt.d.ts.map +0 -1
  1591. package/dist/two-d/ui/TextPrompt.js +0 -236
  1592. package/dist/two-d/ui/TextPrompt.js.map +0 -1
  1593. package/dist/two-d/ui/TextSharpness.d.ts +0 -33
  1594. package/dist/two-d/ui/TextSharpness.d.ts.map +0 -1
  1595. package/dist/two-d/ui/TextSharpness.js +0 -56
  1596. package/dist/two-d/ui/TextSharpness.js.map +0 -1
  1597. package/dist/two-d/ui/Toast.d.ts +0 -57
  1598. package/dist/two-d/ui/Toast.d.ts.map +0 -1
  1599. package/dist/two-d/ui/Toast.js +0 -101
  1600. package/dist/two-d/ui/Toast.js.map +0 -1
  1601. package/dist/two-d/ui/Tooltip.d.ts +0 -177
  1602. package/dist/two-d/ui/Tooltip.d.ts.map +0 -1
  1603. package/dist/two-d/ui/Tooltip.js +0 -275
  1604. package/dist/two-d/ui/Tooltip.js.map +0 -1
  1605. package/dist/two-d/ui/TreeView.d.ts +0 -68
  1606. package/dist/two-d/ui/TreeView.d.ts.map +0 -1
  1607. package/dist/two-d/ui/TreeView.js +0 -133
  1608. package/dist/two-d/ui/TreeView.js.map +0 -1
  1609. package/dist/two-d/ui/VerticalLabel.d.ts +0 -69
  1610. package/dist/two-d/ui/VerticalLabel.d.ts.map +0 -1
  1611. package/dist/two-d/ui/VerticalLabel.js +0 -110
  1612. package/dist/two-d/ui/VerticalLabel.js.map +0 -1
  1613. package/dist/two-d/ui/Window.d.ts +0 -188
  1614. package/dist/two-d/ui/Window.d.ts.map +0 -1
  1615. package/dist/two-d/ui/Window.js +0 -311
  1616. package/dist/two-d/ui/Window.js.map +0 -1
  1617. package/dist/two-d/ui/WindowStack.d.ts +0 -63
  1618. package/dist/two-d/ui/WindowStack.d.ts.map +0 -1
  1619. package/dist/two-d/ui/WindowStack.js +0 -132
  1620. package/dist/two-d/ui/WindowStack.js.map +0 -1
  1621. package/dist/two-d/ui/a11y.d.ts +0 -43
  1622. package/dist/two-d/ui/a11y.d.ts.map +0 -1
  1623. package/dist/two-d/ui/a11y.js +0 -79
  1624. package/dist/two-d/ui/a11y.js.map +0 -1
  1625. package/dist/two-d/ui/contrast.d.ts +0 -30
  1626. package/dist/two-d/ui/contrast.d.ts.map +0 -1
  1627. package/dist/two-d/ui/contrast.js +0 -42
  1628. package/dist/two-d/ui/contrast.js.map +0 -1
  1629. package/dist/two-d/ui/index.d.ts +0 -96
  1630. package/dist/two-d/ui/index.d.ts.map +0 -1
  1631. package/dist/two-d/ui/index.js +0 -49
  1632. package/dist/two-d/ui/index.js.map +0 -1
  1633. package/dist/two-d/ui/markdown.d.ts +0 -55
  1634. package/dist/two-d/ui/markdown.d.ts.map +0 -1
  1635. package/dist/two-d/ui/markdown.js +0 -147
  1636. package/dist/two-d/ui/markdown.js.map +0 -1
  1637. package/dist/two-d/ui/markup.d.ts +0 -189
  1638. package/dist/two-d/ui/markup.d.ts.map +0 -1
  1639. package/dist/two-d/ui/markup.js +0 -387
  1640. package/dist/two-d/ui/markup.js.map +0 -1
  1641. package/dist/two-d/ui/reveal.d.ts +0 -41
  1642. package/dist/two-d/ui/reveal.d.ts.map +0 -1
  1643. package/dist/two-d/ui/reveal.js +0 -22
  1644. package/dist/two-d/ui/reveal.js.map +0 -1
  1645. package/dist/two-d/ui/theme.d.ts +0 -133
  1646. package/dist/two-d/ui/theme.d.ts.map +0 -1
  1647. package/dist/two-d/ui/theme.js +0 -122
  1648. package/dist/two-d/ui/theme.js.map +0 -1
  1649. package/dist/two-d/ui/themedText.d.ts +0 -20
  1650. package/dist/two-d/ui/themedText.d.ts.map +0 -1
  1651. package/dist/two-d/ui/themedText.js +0 -9
  1652. package/dist/two-d/ui/themedText.js.map +0 -1
  1653. package/dist/version.d.ts +0 -13
  1654. package/dist/version.d.ts.map +0 -1
  1655. package/dist/version.js +0 -13
  1656. package/dist/version.js.map +0 -1
  1657. package/dist/world/Encounters.d.ts +0 -32
  1658. package/dist/world/Encounters.d.ts.map +0 -1
  1659. package/dist/world/Encounters.js +0 -9
  1660. package/dist/world/Encounters.js.map +0 -1
  1661. package/dist/world/Environment.d.ts +0 -58
  1662. package/dist/world/Environment.d.ts.map +0 -1
  1663. package/dist/world/Environment.js +0 -89
  1664. package/dist/world/Environment.js.map +0 -1
  1665. package/dist/world/Overworld.d.ts +0 -39
  1666. package/dist/world/Overworld.d.ts.map +0 -1
  1667. package/dist/world/Overworld.js +0 -40
  1668. package/dist/world/Overworld.js.map +0 -1
  1669. package/dist/world/SideTurns.d.ts +0 -115
  1670. package/dist/world/SideTurns.d.ts.map +0 -1
  1671. package/dist/world/SideTurns.js +0 -138
  1672. package/dist/world/SideTurns.js.map +0 -1
  1673. package/dist/world/TurnClock.d.ts +0 -41
  1674. package/dist/world/TurnClock.d.ts.map +0 -1
  1675. package/dist/world/TurnClock.js +0 -49
  1676. package/dist/world/TurnClock.js.map +0 -1
  1677. package/dist/world/World.d.ts +0 -64
  1678. package/dist/world/World.d.ts.map +0 -1
  1679. package/dist/world/World.js +0 -91
  1680. package/dist/world/World.js.map +0 -1
  1681. package/dist/world/index.d.ts +0 -12
  1682. package/dist/world/index.d.ts.map +0 -1
  1683. package/dist/world/index.js +0 -7
  1684. package/dist/world/index.js.map +0 -1
  1685. package/sbom.cdx.json +0 -5996
  1686. package/tools/mwl.mjs +0 -466
  1687. package/tools/vendored/rgssad-wasm/LICENSE-MIT +0 -21
  1688. package/tools/vendored/rgssad-wasm/README.md +0 -15
  1689. package/tools/vendored/rgssad-wasm/package.json +0 -17
  1690. package/tools/vendored/rgssad-wasm/rgssad_wasm.d.ts +0 -41
  1691. package/tools/vendored/rgssad-wasm/rgssad_wasm.js +0 -6
  1692. package/tools/vendored/rgssad-wasm/rgssad_wasm_bg.js +0 -399
  1693. package/tools/vendored/rgssad-wasm/rgssad_wasm_bg.wasm +0 -0
  1694. package/tools/vendored/rgssad-wasm/rgssad_wasm_bg.wasm.d.ts +0 -17
  1695. package/tools.md +0 -219
package/REFERENCE.md DELETED
@@ -1,2256 +0,0 @@
1
- # mwg reference
2
-
3
- A one-line-per-export index of `@datamoc/mw_games`'s public API - what exists and where,
4
- not how to use it. The published Documentation page is this file rendered as HTML; the
5
- full generated API (every parameter, every doc comment) lives beside it at
6
- `webpage/documentation/api/`, with an examples index beside it at
7
- `webpage/documentation/examples.html` listing every `@example` per module (all from
8
- `npm run webpage:docs`). For *why* the framework
9
- is shaped this way and what it's for, see `README.md`'s capability spec. For architecture
10
- and build commands, see `DEVELOPMENT.md`. For the order things shipped in and the reasoning
11
- behind it, see `CLOSED.md`; for what's still open, see `ROADMAP.md`.
12
-
13
- Every module is its own barrel: `import { X } from '@datamoc/mw_games/core'` (or the
14
- matching subpath for any module below), or `import { X } from '@datamoc/mw_games'` for the
15
- root re-export.
16
-
17
- **Two rendering worlds, and a core that belongs to neither.** `mwg/two-d` is everything drawn
18
- through PixiJS (`Game`, `Scene2D`, and the `render`, `ui` and `stage` modules beneath it);
19
- `mwg/3d` is everything drawn through Babylon. `mwg/core` holds what both need and neither
20
- renders: the scene lifecycle, `SceneStack`, input, saves, RNG, signals, achievements.
21
-
22
- **Which entry points reach a renderer**, checked by a test that walks the real import graph
23
- (`tests/renderer-isolation.test.ts`) rather than by good intentions:
24
-
25
- | renderer-free | Pixi | Babylon |
26
- | --- | --- | --- |
27
- | `core`, `i18n`, `actors`, `world`, `battle`, `simulation`, `roguelike`, `board`, `audio`, `rpg`, `ai`, `mwl`, `assets/paths` | `two-d` (and `two-d/render`, `two-d/ui`, `two-d/stage`), `assets` | `three-d` (the `3d` subpath) |
28
-
29
- `roguelike` adds only `rot-js`, and `pixi.js`, `@babylonjs/core`/`@babylonjs/loaders` and
30
- `@capacitor/core` are optional peer dependencies rather than installed ones, so a project names
31
- only the renderer it actually draws with. A Babylon game importing `core` + `3d` pulls in no Pixi
32
- at all, and a 2D game importing `core` + `two-d` pulls in no Babylon. `rpg` is renderer-free too:
33
- its event interpreter takes an injected `DialoguePresenter` rather than building a widget, so
34
- a 3D game can run map events, dialogue and quests without a 2D renderer anywhere in reach.
35
-
36
- ## MWL presentation
37
-
38
- The optional compiler at `@datamoc/mw_games/mwl/presentation` is renderer-free. The
39
- runtime at `@datamoc/mw_games/two-d/presentation` imports Pixi and is kept off the root
40
- barrel. The browser consumes compiled data, with no MWL parser or network requests.
41
-
42
- - `compilePresentation(files, manifest)` validates and compiles top-level
43
- `theme_definition`, `presentation_context`, `component_variant`, `ui_component` and
44
- `scene_definition` nodes. It checks named actions/adapters, binding types, assets,
45
- reusable-component cycles, duplicate IDs, overrides and token references at build time,
46
- with source-file/line diagnostics. The manifest's asset names must be generated files
47
- that the game's asset build actually includes.
48
- - `emitPresentationModule(data)` emits deterministic TypeScript data, `PresentationId`
49
- (including keyed instance paths) and `PresentationSceneId` literal types. A game's build
50
- script writes this module plus `data.messages` and `data.assets` into its existing MWL
51
- artifact pipeline. See `examples/mwl-presentation/generate.mjs`.
52
- - `MwlPresentation(data, sceneId, options)` mounts existing `Button`, `Label`, `Bar`,
53
- `Window`, `WindowStack` and `Camera` components. `get(id)`, `focusId`, `palette` and
54
- `activeContext` expose instances and presentation state. `update(dt)`, `resize(width,
55
- height)`, `setContext(id)` and `destroy()` drive its lifecycle; `handleAction(action)`
56
- offers modal windows input first. Register destruction with the owning scene's
57
- `onDestroy`; it detaches input, theme, controller and adapter subscriptions.
58
-
59
- Declare the TypeScript manifest with `values: { name: 'string' | 'number' | 'boolean' }`,
60
- or `{ type: 'items', fields: { id: 'string', text: 'string', selected: 'boolean' } }` for
61
- collections, plus `actions`, optional `adapters` and `assets` name lists. The runtime's
62
- `options.state()` supplies those values; `options.actions` implements the named callbacks.
63
- Repeated-item actions receive the current item, even after reorder. Optional `subscribe`
64
- returns a disposer, and `translate` resolves authored/gettext text. Asset textures must
65
- be loaded before mounting. `PresentationAdapter` exposes a view plus optional `update`,
66
- `resize`, `restyle` and `destroy`: the runtime destroys the view, while the adapter
67
- detaches its own subscriptions. Cleanup continues even if an adapter throws.
68
-
69
- Scenes contain `scene_camera` (zoom, position or fit dimensions), `scene_layer` (world or
70
- screen space, optional generated image or named procedural adapter) and UI trees.
71
- `ui_mount` expands a reusable component at build time. UI trees use `ui_container`,
72
- `ui_row` (wrapping by default), `ui_column`, `ui_grid` (equal grow columns), `ui_label`,
73
- `ui_button`, `ui_bar`, `ui_window`, `ui_repeat` and `ui_adapter`. Every node has an `id`;
74
- runtime paths start with the scene ID and join descendant IDs with `/`. Repeats insert
75
- the URI-encoded stable key before their single template child's ID, preserving instances
76
- and focus on updates. A reusable component using item fields may declare `items_binding`
77
- so even an unused template can be validated against its collection.
78
-
79
- Properties include pixel dimensions, anchors, offsets (`x`, `y`), spacing, alpha and
80
- semantic color tokens. Bindings use `text_binding`, `title_binding`, `value_binding`,
81
- `max_binding`, `color_binding`, `visible_binding`, `selected_binding` and
82
- `disabled_binding`; item fields use `item.field`. Buttons name an `action`, windows may
83
- name a `close_action`, and repeats declare `items_binding` plus a string/number `key`.
84
- Window close actions should update the controller's visibility binding. Closed windows
85
- stay closed until their visibility transitions false then true; reopening creates a
86
- fresh window, because existing `Window.close()` destroys its contents.
87
-
88
- Themes require `panel`, `text`, `accent`, `success`, `warning`, `danger` and `selection`
89
- 24-bit color tokens; games may add scenery tokens and choose font/padding metrics.
90
- Text/panel contrast must reach 4.5, and danger/selection against panel must reach 3.
91
- Contexts choose a theme and may override tokens or authored-node properties using
92
- `ui_override.target`, such as `component:controls/toolbar` or `scene:bridge/decor`.
93
- Image overrides on scene layers select generated scenery. Precedence is base properties,
94
- context overrides, component variant, then `ui_state` (`idle`, `hover`, `pressed`,
95
- `disabled`, `selected`, `focused`). A game's biome schema selects a context; MWG defines
96
- no biome rules. Context switches preserve mounted adapters and controller state.
97
-
98
- One active presentation owns the existing global UI theme. Destruction restores its prior
99
- theme if nobody replaced it meanwhile. Existing widgets also expose local palette updates:
100
- `Button.setColors` (`ButtonColors`), `Window.setColors` (`WindowColors`) and
101
- `Bar.setBackground`, for variants that must follow token changes without remounting.
102
-
103
- ## Conventions
104
-
105
- Three rules the whole API follows, so a name means one thing everywhere:
106
-
107
- - **`advance(turns)` moves a clock forward in whole turns or rounds; `update(dt)` moves one
108
- forward in real seconds.** `TurnClock`, `Charges`, `Field`, `Barrier` and `AbilityCycle`
109
- take turns; everything in `render`, `ui`, `audio` and `world.EnvironmentClock` takes `dt`.
110
- Anything that is not time passing gets its own verb rather than borrowing one of these
111
- (`QuestLog.advanceStage`, `BossPhases.check`).
112
- - **`toJSON()` / `static fromJSON(defs, data)` is how a class saves and reloads.** Definitions
113
- a game owns (item tables, quest definitions, growth curves, terrain kinds) are supplied
114
- fresh as `defs` rather than written into the save, so rebalancing reaches old saves.
115
- Namespace-level state uses `exportX`/`importX` free functions instead (`Input` bindings);
116
- `Random.Generator` keeps `getState`/`setState`, which resumes a live stream in place rather
117
- than producing a payload.
118
- - **"Nothing to pick" is always `null`**, never `-1` or `undefined`: `Random.weighted`,
119
- `Random.element`, `Random.weightedKey`, `rollEncounter`, `rollLoot`, `rollAffix`,
120
- `pickBuilder`.
121
-
122
- ## Contents
123
-
124
- [core](#core) · [two-d](#two-d) · [render](#two-drender) · [ui](#two-dui) · [stage](#two-dstage) ·
125
- [assets](#assets) · [audio](#audio) · [battle](#battle) · [board](#board) ·
126
- [actors](#actors) · [roguelike](#roguelike) · [rpg](#rpg) · [simulation](#simulation) ·
127
- [three-d](#three-d-optional) · [world](#world) · [i18n](#i18n) · [mwl](#mwl) · [mwl/pyroeis](#mwlpyroeis) ·
128
- [skeleton](#skeleton) · [physics](#physics) · [ai](#ai) ·
129
- [testing](#testing) · [threads](#threads) · [headless](#headless)
130
-
131
- ## `core`
132
-
133
- The scene lifecycle, signals, RNG, input, and every save/telemetry/replay primitive - the one
134
- module every game imports, whichever renderer it uses, and the only one that depends on no
135
- other `mwg` module and no renderer at all.
136
-
137
- - `Scene` - one screen of the game, as lifecycle only: `create`, `update(dt)`, `resize`, the
138
- `onSuspend`/`onResume` pair a pushed scene needs, and a `destroy` that fires once. It owns
139
- no display node; `two-d.Scene2D` adds the Pixi container, and a Babylon game supplies its own.
140
- - `SceneStack` - `push`/`pop`/`replace`: suspends the current scene, layers another over or
141
- instead of it, and resumes with a result once it pops (minigames, pause menus). Generic over
142
- the scene type and typed against the lifecycle above, so it drives a 3D game just as well.
143
- - `SceneComponentHost`/`SceneComponent` - composes a scene out of named sections (map logic,
144
- encounter logic, UI wiring), each its own module implementing whichever `Scene` lifecycle
145
- hooks it needs, instead of one scene class accreting every responsibility. A scene owns one
146
- host and forwards `update`/`resize`/`onSuspend`/`onResume`/`destroy` to it - composition, not
147
- a base class, so it works the same whether the scene extends `Scene` or `two-d.Scene2D`.
148
- - `Registry` - a named lookup registered once and read back by name: `register`/`get`/`has`/
149
- `list`, throwing on a duplicate or missing name by that name. The dispatch primitive
150
- underneath a catalog of factories or handlers (`SceneComponentHost` uses one internally) -
151
- a game still imports and registers each entry itself, no auto-discovery.
152
- - `createHandles`/`Handles` - numeric leases for values a plain-data command cannot carry
153
- (callbacks, RNG streams, query closures): `put` stores a value and returns its id, `get`
154
- resolves it, `drop`/`clear` end leases, and `with` scopes a lease so the drop runs even
155
- when the body throws. Ids start at 1 and are never reused.
156
- - `Logger` - categories, four severity levels, a filter, and a sink tests can capture,
157
- instead of bare `console.log`/`console.error`.
158
- Three shapes cover what "an event" means here, kept deliberately distinct rather than folded
159
- into one bus: a **GameEvent** is a rule's ordered *output* - what happened, described after the
160
- fact - realised as the generic `Event` type parameter `simulation`'s `SimulationRule`/
161
- `SimulationRuntimeRule` already return, never something a handler reacts to mid-calculation. A
162
- **Hook** (`HookRegistry`, below) is a point of *modification* a rule consults while it runs -
163
- `modifyDamage`, "can this creature act this turn" - synchronous, and read back by the same rule
164
- that asked. A **Signal** is a plain *notification* with no bearing on any rule - `sceneChanged`,
165
- `saveCompleted`. Reaching for a global bus that several `AttackRequested`/`DamageCalculated`/
166
- `HpChanged`-style events all dispatch onto, each triggering the next, is the shape to avoid: it
167
- turns a rule's synchronous, readable logic into a chain no single function owns.
168
-
169
- - `Signal` - a typed event emitter: one event, one payload, LIFO listeners, and a listener
170
- can consume it.
171
- - `HookRegistry`/`Hook` - many events keyed by name, dispatched in registration order, with a
172
- `source` tag so everything one ability or worn item registered comes off in a single
173
- `offSource` call. `battle.BattleHooks` and `roguelike.CombatHooks` are both this with their
174
- argument types fixed; they were two copies of one class until they were merged.
175
- - `PresentationQueue` - plays a batch of simulation events one at a time, at whatever pace
176
- `play(event)` (a tween, a sound, a floating number) says to wait before the next - the
177
- presentation-side counterpart to a `SimulationRuntime.dispatch()`/`runScenario()` result, kept
178
- out of the logical commit that already happened. The same queued/timed shape as `two-d.ui.
179
- Toast`, generalised to any event type and needing no renderer.
180
- - `parseCSV`/`CsvOptions`/`CsvColumnType` - a header-row CSV into an array of typed row
181
- objects, so a content designer edits a spreadsheet instead of a `.ts` object literal for a
182
- table shaped like `actors.AffixTable`. `columns` names which fields coerce to
183
- `'number'`/`'boolean'`/`'list'` (semicolon-separated)/`'map'` (semicolon-separated
184
- `key=value` pairs); an empty cell omits that field entirely, the same as an optional
185
- property never set. Takes a raw string with no opinion on how it was loaded, the same
186
- boundary `i18n.parseFTL` already draws.
187
- - `clamp` - `value` restricted to `[min, max]`. Shared so `two-d.render.Camera`'s bounds
188
- clamp and `rpg.Collision`'s tile-edge resolver stop being the same three-line function
189
- written twice.
190
- - `parseDialogueLines`/`DialogueLine` - the terse `@id text`/`-`-alternation dialogue-text
191
- parsing engine behind both `two-d/stage.parseDialogueText` and `rpg.parseDialogueText`, so
192
- the two-speaker state machine lives once instead of twice: each module's own wrapper only
193
- renames `DialogueLine.speaker` onto its own command shape (`StageCommand.as` versus
194
- `EventCommand.speaker`).
195
- - `parseTwee`/`TweeCommand`/`TweeChoice`/`TweeStory` - the Twee-notation parsing engine
196
- behind both `two-d/stage.importTwee` and `rpg.importTwee`, for the same reason: passages,
197
- `[[links]]` and `StoryData`/`StoryTitle` parse once here, and `TweeCommand`/`TweeChoice`
198
- are structurally compatible with both `StoryScript`/`StageChoice` and
199
- `EventStoryScript`/`EventChoice`, so each module's wrapper needs no per-field conversion.
200
- - `Random` (namespace) - seeded RNG: `int`, `float`, `weighted`, `element`, `shuffle` and the
201
- rest; every "pick one" returns `null` when there is nothing to pick.
202
- - `Generator` - the seeded RNG class `Random` wraps directly, for a game that wants its own instance.
203
- - `JavaRandom`/`JavaRandomDraw`/`JavaRandomOptions` - `java.util.Random`'s 48-bit generator bit for bit
204
- (`nextInt`, `nextInt(bound)`, `nextLong`, `nextDouble`, `nextFloat`, `nextBoolean`), so a
205
- game ported from the JVM replays the same seed; `onDraw` logs every underlying draw for a
206
- parity diff against a JVM run. Not for general use, that is `Generator`.
207
- - `MersenneTwister`/`MersenneTwisterState` - MT19937 with `mt_rng`'s `seed`/`discard`/
208
- `discardCount` bookkeeping, for a port that consumes the reference's raw 32-bit stream; the
209
- engine matches the standard test vector, while the int mapping is MWG's own unbiased
210
- reduction (C++'s `uniform_int_distribution` is implementation-defined).
211
- - `RandomStreams` - named, independent MT19937 streams over one base seed, so a loot draw and
212
- an AI draw never shift each other, with `getState`/`setState` for a save and `reseed`.
213
- - `Input` (namespace, so `Input.onAction`, not a bare `onAction` import) - named-action input: `bind`/`isDown`/`justPressed`/`justReleased`
214
- over keyboard, `bindButton`/`bindAxis`/`pollGamepads` over a gamepad,
215
- `bindTouch`/`pressTouch`/`releaseTouch`/`attachSwipe` over touch, `attachPointer` for
216
- down/move/drag/up signals with target-relative and (through `toWorld`) world positions, `actionsForKey` for
217
- rebind-conflict detection, `rumble` for gamepad haptics. `onText` carries the character a
218
- key press produces (via `textFromKey`/`dispatchText`) and `onAction` the named action a
219
- key fires, each with its own programmatic counterpart (`dispatchText`,
220
- `dispatchAction`) so an on-screen keyboard feeds the same signals a physical key
221
- travels; `onComposition` follows an IME through `start`/`update`/`end`, so a free text
222
- field can be built on top.
223
- - `PlayerInput` - a per-player scoped `Input`, for local multiplayer/split-screen.
224
- - `StoredValue`/`defaultStorage` - one JSON value under one storage key (`read(fallback)`/
225
- `write`/`remove`) over the same storage `SaveSystem` uses: a game's structured progress or
226
- best scores without a save slot.
227
- - `FixedStepper` - turns the variable `Scene.update(dt)` into fixed simulation steps
228
- (`advance(dt, tick)`, a `maxSubsteps` cap, `alpha` for interpolated drawing): the deterministic,
229
- refresh-rate-independent loop a physics solver or lockstep game needs.
230
- - `SaveSystem` - named, versioned save slots over `localStorage` (in-memory fallback under
231
- `file://`); a `migrations` chain, and `importExternal` as a plug-in point for a foreign
232
- save format's own `normalize` function. `load`, `list` and `importSlot` read every slot
233
- through `parseInbound` plus a `{ meta: { version, savedAt }, state }` shape check: a
234
- corrupt or tampered slot loads as `null` and is left out of `list`.
235
- - `StateRegistry`/`StateExtension`/`StateRestoreDiagnostic` - named game-owned state extensions with deep-cloned
236
- snapshots and transaction rollback, with independent versions, ordered migrations and
237
- explicit handling of extensions absent from a restored save, so custom save data has one
238
- atomic boundary.
239
- - `ActionJournal` - serializable ordered action and outcome batches with checkpoints,
240
- incremental reads, truncation and validated restore for replay, undo and synchronization.
241
- Actions and events are copied on `append`, so both must be plain data.
242
- - `cloneData`/`uncloneablePath` - `structuredClone` with an error naming the first value that
243
- cannot be copied (`action.target.reactions.rules[0].when`), and that path on its own. The
244
- journal and `simulation.SimulationRuntime` use it, so a command carrying a live actor fails
245
- with where and why instead of a bare `DataCloneError`.
246
- - `scramble`/`unscramble` - light save-data obfuscation, not encryption.
247
- - `SaveSyncClient` - pushes/pulls save data to a server the game supplies.
248
- - `LockstepClient` - deterministic multiplayer over an injectable WebSocket, tick-driven.
249
- Server messages are size-capped (`maxMessageBytes`, 1 MB) and type-checked; a malformed one
250
- is dropped and reported on `onProtocolError` instead of throwing out of `onmessage`.
251
- - `stateChecksum`/`SyncGuard` - out-of-sync detection for lockstep: a key-order-stable 32-bit
252
- checksum of JSON state, and a guard comparing the checksums two peers compute for each tick,
253
- recording the first tick they disagree on.
254
- - `RunHistory` - a local record of completed runs (score, cause of death, whatever a game's
255
- own `summary` holds), distinct from `SaveSystem`'s continuable slots.
256
- - `PlayerStats` - a lifetime running total folded in one run's summary at a time, distinct
257
- from `RunHistory`'s per-run records.
258
- - `TelemetryClient` - sends usage/error events to a server the game supplies.
259
- - `NewsClient`/`NewsSeenTracker` - a game's own patch-notes/announcement feed, with a
260
- seen-tracker so a player is only notified of what's actually new.
261
- - `checkSize`/`checkNoControlCharacters`/`sanitizeInboundText`/`validateSchema`/`parseInbound` -
262
- security sanitization of inbound data: an imported save, a network payload, player-typed
263
- text. `parseInbound` is the whole pass in one call (size, control characters, `JSON.parse`
264
- refusing `__proto__`/`constructor`/`prototype` at any depth), and every `core` reader of
265
- JSON it did not just produce uses it: save slots, `Collection`, stored values, settings,
266
- `NewsClient` and `LockstepClient`. Under `file://` Chromium shares one `localStorage`
267
- between every local page, so a game's own storage is inbound data too.
268
- - `Collection` - named, queryable record collections over `localStorage`
269
- (`all`/`get`/`put`/`remove`/`where`/`clear`) - a quest log or bestiary, not a save blob.
270
- - `Recorder`/`Player`/`serializeReplay`/`deserializeReplay` - records `Input.onAction`
271
- against `Game`'s own frame counter and replays it deterministically, for testing.
272
- Both resume mid-run: `Recorder` takes `fromFrame` so a restored run continues its
273
- recording where the checkpoint left it, and `Player` takes `fromFrame` so playback
274
- skips what the restored state already contains. `parseReplayEvents` validates an
275
- already-parsed event array, the half of the check `deserializeReplay` applies after
276
- its own `JSON.parse`.
277
- - `exportReplayFile`/`importReplayFile`/`LastRun`/`runCheckpoint`/`resumeRunPlayer` -
278
- a run made durable (roadmap 396). The file is a versioned, self-describing envelope
279
- (`format: 'mwg-replay'`, `version`, `framework`, `game`, optional `seed` and
280
- `recordedAt`, `events`), and import refuses another game or another framework build
281
- by name, treating the file as inbound data the way a save slot is treated.
282
- `LastRun` keeps the newest recording, one deep and bounded, through the same storage
283
- a save slot uses; `runCheckpoint(recorder, state)` pairs the partial recording with
284
- the game state a save already captured, and `resumeRunPlayer` turns the restored
285
- checkpoint back into a mid-run `Player`. The `file://` plumbing rides along:
286
- `downloadReplayFile` is a Blob download (no `fetch()`), `pickReplayFile` is the file
287
- picker resolving null on cancel, and `readReplayFile` reads any `Blob`, headless
288
- Node included.
289
- - `Achievements` - counters crossing a target unlock a named milestone; `drainNew()`
290
- queues unlocks for a UI to announce. An achievement can name several `criteria`
291
- instead of one `counter`/`target` (item 273's sub-achievements, "recruit every unit
292
- type"), unlocking only once every criterion is met; `subProgress` reads them individually.
293
- - `Settings`/`GameSettings`/`SettingsOptions`/`CustomSettingValue` - persisted player
294
- settings over the same storage `SaveSystem` uses (in-memory fallback under `file://`):
295
- music and sound-effect levels, master mute, zoom preference, key bindings (applied to
296
- `Input` on load), and a game-defined `custom` bag for the rest (`hints`, `violence`,
297
- ...). `defaultSettings` names the fresh-game values, `effectiveMusicVolume`/
298
- `effectiveSfxVolume` read 0 while muted, corrupt storage reads as defaults.
299
- - `Session` - counts launches over the same storage `SaveSystem` uses, for a native
300
- wrapper's own rating-prompt timing; never prompts itself.
301
- - `FeedbackClient`/`HttpTransport`/`HttpTransportOptions` - an injectable HTTPS JSON transport for
302
- player-submitted feedback; the game owns the endpoint, consent flow, and server-side storage.
303
- Every `HttpTransportOptions` client (`FeedbackClient`, `NewsClient`, `SaveSyncClient`,
304
- `TelemetryClient`) and `LockstepClient` refuses an `http:`/`ws:` url to anything but
305
- `localhost`/`127.0.0.1`/`[::1]` unless `allowInsecure: true`, and a response body is read up
306
- to `maxResponseBytes` (10 MB), refused as soon as it passes the limit.
307
- - `Spawner` - a `dt`-driven, timed, escalating wave spawner (a horde mode, a survival
308
- minigame), distinct from `roguelike.Scheduler`'s turn-order primitive.
309
- - `hexNeighbors`/`hexDistance`/`hexLine`/`hexRange`/`hexToPixel`/`pixelToHex` with
310
- `HexShape`/`HexOrientation`/`HexOffset` - hex grid geometry: cube-based neighbours, lines and
311
- ranges, and the pixel projection in both orientations and both offset parities, defaulting to the
312
- flat-top odd-q layout this module always had. `pixelToHex` answers with the nearest cell centre
313
- rather than a closed-form inverse per combination, so it cannot disagree with `hexToPixel` at a
314
- hex's edge.
315
- - `weightedFlood`/`WeightedCell`/`WeightedFloodOptions` - renderer- and rules-neutral Dijkstra
316
- flood over any cell topology, with injected costs, blockers, budget and stopping rules.
317
- - `cellInside`/`cellIndex`/`cellX`/`cellY`/`cellKey`/`cellFromKey` - bounded-grid indexing:
318
- the row-major arithmetic and bounds check that `roguelike.Level` and the `board` modules used
319
- to spell out for themselves, now stated once (the Wesnoth port asked for exactly this, to stop
320
- duplicating it in its own systems). `cellInside` is the shared bounds check and `cellIndex` is
321
- deliberately *unchecked* arithmetic, so a loop that has already proved its coordinates pays
322
- nothing while a module that wants a throw or a `-1` keeps that policy in its own method;
323
- `cellKey`/`cellFromKey` are the `'x,y'` spelling for `Map`/`Set` membership.
324
- - `NEIGHBOURS4`/`NEIGHBOURS8`/`CIRCLE8`/`euclidean`/`chebyshev` - one frozen offset table per square
325
- neighbourhood, shared instead of copied: axial north/east/south/west, the eight
326
- surrounding cells in row-major order, and the same ring clockwise from north (the
327
- sequence `roguelike`'s `neighbourOffsets(8)` always returned, now returned as-is from
328
- here). `euclidean` is the straight-line ruler, `chebyshev` the king-move one (a
329
- diagonal costs one step), and `manhattan` the orthogonal-step count; `distance` measures
330
- with the ruler a `DistanceMetric` names, so a data-authored rule picks its geometry by
331
- name. `roguelike`'s `chebyshevDistance` delegates to `chebyshev`.
332
- - `Blob` - a spreading volume field over a grid: a per-cell number that `spread` diffuses a
333
- share of into its open 4-neighbours and decays the rest (`decay: 1` conserves and only
334
- moves volume around). `seed` adds to a cell, `clear` zeroes one cell and leaves its
335
- neighbours alone, and `cellsAbove` lists what a game applies its effect on; what a volume
336
- means (fire, gas, ooze, water) stays the game's own reading.
337
- - `reducedMotion`/`setReducedMotion`/`prefersReducedMotion`/`watchReducedMotion` - the one
338
- answer to "should this animate": the OS `prefers-reduced-motion` preference, overridable per
339
- game, with a change subscription for something long-lived that has to stop mid-flight.
340
- `motionDuration(duration, intent)` is the policy built on it, and `MotionIntent` is the
341
- caller's declaration: a `decorative` motion (the default) collapses, a `meaningful` one is
342
- shortened rather than deleted, because a change that motion conveys stays readable. `Tweener`,
343
- `Camera` (shake and follow), `ScreenEffects`, `ParticleEmitter` and `FloatingText` consult it.
344
- `AnimatedSprite` deliberately does not: a frame cycle is usually game state.
345
- - `Tweener`/`Easing`/`TweenOptions` - a generic `tween(duration, apply, ease?)` plus a small
346
- linear/quad/cubic easing-curve set. The third argument also takes `{ ease, intent, alternate }`:
347
- `alternate` is the non-vestibular variant to run instead under reduced motion (a fade where a
348
- slide was), and it is ignored while the preference is off.
349
- - `UndoHistory` - gameplay-level undo/redo over pushed, reference-held states.
350
- - `LoadQueue` - a reusable loading-screen lifecycle: named tasks, aggregate progress,
351
- cancellation.
352
- - `EntityRegistry`/`EntityId` - assigns and looks up stable string ids for live objects, so
353
- events, saves, AI targets and buffs can name a creature or item without holding it; not an
354
- ECS, and distinct from `Collection`'s persisted, queryable records. `idOf` is what a game
355
- passes as `roguelike.Scheduler.toJSON`'s or `simulation.SimulationRuntime`'s `actorId`.
356
- - `ReactionTable`/`ReactionRule` - declarative `when`/`action` rules checked against any
357
- state shape (a `StatBlock`'s values, a plain object's own fields), firing edge-triggered
358
- so a still-true condition never re-fires; `once` retires a rule after its first firing. The
359
- generic alternative to a branch cascade of `if HP < n` checks in game code, and works the
360
- same for a character or an inanimate object such as an item's durability.
361
-
362
- ## `two-d`
363
-
364
- Everything drawn through PixiJS, and the counterpart to `three-d`. The barrel re-exports
365
- `render`, `ui` and `stage` below, so `mwg/two-d` is a one-stop 2D import; the granular
366
- subpaths (`mwg/two-d/render`, `mwg/two-d/ui`, `mwg/two-d/stage`) are what a game watching its
367
- bundle should reach for.
368
-
369
- - `Game` - owns the Pixi `Application`, the frame loop, and the current scene; reachable as
370
- the singleton `Game.current`. `step(dt)` drives one frame by hand, which defeats Chrome's
371
- background-tab throttling of `requestAnimationFrame`. With `autoPause` (the default) it
372
- suspends the loop and silences its `audio` rig (`AudioSuspendRig`, an `Orchestrator`
373
- fits) on page hide and resumes both on show, via `suspend`/`resume`: the clock parks at
374
- 0, the top scene hears `onSuspend`/`onResume`, and the player's mute setting is never
375
- touched. `qualityScaling` steps the backing-store ratio down after sustained
376
- over-budget frames (and back up only after a much longer streak inside budget) via a
377
- `QualityScaler` over the static fit, off unless given. It draws at the display's
378
- `devicePixelRatio`, reduced to the largest whole number whose backing store fits the device's
379
- `MAX_TEXTURE_SIZE`, with a warning naming the limit when that happens: WebGL clamps a larger
380
- request silently, so a device with a small limit renders softer rather than not at all.
381
- - `Scene2D` - `core.Scene`'s lifecycle plus the `stage` container everything this screen draws
382
- hangs off, destroyed with the scene. This is what a 2D game extends.
383
-
384
- ### `two-d/render`
385
-
386
- Pixi-backed 2D rendering: sprites, tile maps, camera, animation. All Pixi
387
- batcher/high-shader internals are confined to `ColorTransformBatcher.ts`.
388
-
389
- - `ColorTransformBatcher`/`packColorAdd`/`packTintAdd`/`NO_COLOR_ADD` - a per-sprite
390
- `texel × M + A` colour transform (multiply *and* add) in the batch shader.
391
- - `TintedSprite`/`registerColorTransform` - a sprite drawn through the colour-transform
392
- batcher; register the extension once via `GameOptions.extensions`.
393
- - `parseImagePath`/`imageModifier`/`colorShiftMatrix`/`applyImageModifiers`/`croppedTexture` - parses common
394
- image suffix modifiers such as `~FL`, `~GS`, `~SCALE` and `~CROP`, then applies the supported
395
- Pixi presentation changes without mutating shared source textures. `channelScaleMatrix`
396
- (`~R`/`~G`/`~B`) builds the `ColorMatrixFilter` matrix `applyImageModifiers` also applies for
397
- `~O` (opacity) and `~CHAN` (`channelSwapMatrix` - a channel-source swap/constant, not
398
- Wesnoth's own per-channel formula language). `applyTextureModifiers`/`ImageTextureProbe`
399
- cover the modifiers that need real pixel access, a sibling texture, or have to rotate the
400
- actual art rather than a sprite transform: `~RC`/`~PAL` (exact palette swap - see
401
- `recolorTexture` below - accepting hex or, via `probe.resolveColor`, a named colour;
402
- `parseColorPairs`/`parsePaletteLists` are the argument parsers, the latter reconstructing
403
- `~PAL`'s two comma-separated colour lists since `parseImagePath`'s own comma split does not
404
- respect that list boundary), `~BLIT`/`~MASK` (composite/mask against a `probe.resolveTexture`-
405
- resolved sibling texture at an offset - it receives the argument exactly as written, nested
406
- modifiers included, not a bare path; `maskPixels` is `~MASK`'s renderer-free alpha-multiply
407
- core), `~BLEND` (`blendPixels`, an exact per-pixel lerp towards a colour, baked once - not the
408
- runtime `ColorMatrixFilter` approximation `blendMatrix` still offers on its own) and `~ROTATE`
409
- (`rotatePixels`, which rotates the source pixels and expands the surface, unlike a sprite's own
410
- `rotation`; `~ROTATE(degrees)` samples nearest-neighbour, exact at quarter turns, and
411
- `~ROTATE(degrees,linear)` blends the four pixels around each sample point instead - what a
412
- non-square angle onto a hex grid needs. `parseRotateMode` is the second argument's parser, and
413
- both modes sample premultiplied so a transparent neighbour contributes coverage and never
414
- colour. It is bake-time work: measured, `linear` costs 2.4 to 4.2 times `nearest` per image -
415
- 0.45 ms against 0.12 ms for a 64x64 tile at 60 degrees, 3.6 ms against 1.5 ms at 256x256 - for a
416
- visibly smooth edge, once, while the texture is built).
417
- `spriteColorMatrix(sprite, matrix)` (item 309) attaches any of the matrix
418
- builders above (or `blendMatrix`, or a game's own) to a sprite as a `ColorMatrixFilter`, the
419
- one remaining case that needed a direct `pixi.js` import just to construct that one class.
420
- `applyAllImageModifiers(sprite, parsed, probe?, scale?)` (item 310) is the two-step recipe
421
- `applyImageModifiers`'s own doc comment names, run for a caller in one call: it bakes
422
- `applyTextureModifiers`'s exact pixel-level result into `sprite.texture` first, then applies
423
- the sprite-property/filter modifiers on top, so a `~BLEND`/`~ROTATE` path never silently gets
424
- `applyImageModifiers`'s no-op for them.
425
- - `remapPixels`/`paletteRangeMapping`/`recolorTexture`/`withTextureCanvas`/`PaletteMapping`/
426
- `PaletteRange`/`PaletteRemapMode` - palette-remap recolouring (team colour by range, not
427
- multiply/add): `remapPixels` is the renderer-free core, `'exact'` by default (a pixel is
428
- repainted only on an exact match to a `from` colour, correct for a short specific list like
429
- `~RC`/`~PAL` and for a `paletteRangeMapping` over a reference palette, where the pixels outside
430
- it are the ones the art deliberately left alone) or `'nearest'` (every opaque pixel repainted by
431
- closest match, which a palette covering the whole image wants - the wrong mode for a sparse
432
- list, where it silently recolours the entire image). `paletteRangeMapping` builds a
433
- `[color_range]`-shaped mapping: the reference palette's *first* colour is its anchor and becomes
434
- `mid`, and every other entry is shaded by its own brightness, darker towards `min` and brighter
435
- towards `max`, with the floored average and truncated blend a Wesnoth `[color_range]` team
436
- colour is defined in, so a range's shades come out byte for byte as the engine's own. The
437
- reference after its anchor needs no order. `recolorTexture` is the canvas-backed wrapper, built
438
- on the shared `withTextureCanvas` helper `applyTextureModifiers` above also uses.
439
- - `AnimatedSprite`/`Animation` - frame-sequence sprite animation. A frame may carry its own
440
- duration (Wesnoth's `image=a.png:120,b.png:80`), and an animation may start partway into itself
441
- or after a delay (`startTime`, which is what `start_time=-450` on an attack means: begin four and
442
- a half frames in, so the hit lines up with the damage frame). A frame may also carry an offset,
443
- reported through `AnimatedSprite.frameOffset` for the caller to add where it positions the sprite,
444
- because that position is the caller's (`GridMover`, a walk tween) and a sprite that overwrote it
445
- every frame would undo it every frame.
446
- - `SpriteGroup`/`isOnScreen` (item 369) - animate only what is on screen: `update(camera, dt)`
447
- advances the members inside `camera.view` (plus `margin`) and leaves the rest on their current
448
- frame, so a crowd of `AnimatedSprite`s (or `ParticleEmitter`s, which satisfy the same
449
- `SpriteGroupMember` shape) costs no CPU off screen. Never freezes anything visible: under a
450
- rotated camera the tested box is the over-inclusive one `TileMap.cull` uses.
451
- - `SpriteSheet` - a grid-sliced sprite sheet, or, built with no frame size, one whose frames are
452
- its own `rect(index, x, y, width, height)` declarations: a hand-packed icon atlas, a strip of bar
453
- segments, an item whose art is smaller than its cell. A rect is cached under its index like any
454
- grid frame, so `get`/`region`/`name`/`pick` treat the two the same and no site hand-builds a
455
- `Texture`.
456
- - `Camera`/`createCamera`/`snapZoom` - world-to-screen camera; `snapZoom` keeps tile edges
457
- pixel-aligned at a fractional zoom. Fixed-angle view rotation (item 285): `grid` picks four
458
- quarter turns (square, the default) or six 60-degree steps (hex), `setRotationStep`/`rotate`
459
- move through them, `toScreen`/`toWorld` invert the turn so a click still lands on the cell aimed
460
- at, `view` reports the box around the turned viewport for culling, and `uprightRotation` is the
461
- angle that keeps a label drawn into the world upright. Free rotation (item 286): `rotateTo` turns
462
- to any angle immediately and `animateRotationTo` eases towards one, shorter way around the turn,
463
- sharing the same angle and the same `toScreen`/`toWorld`/`view` math the stepped API uses.
464
- `shakeScreen(intensity, duration)` (item 303) is `shake` taking screen pixels instead of world
465
- units, dividing by the current `zoom` once so a caller thinking in screen pixels (a convention
466
- several engines use for this call) does not have to at every call site.
467
- - `Viewport`/`splitScreenHalves` - a camera scoped to one screen region, for split-screen.
468
- - `createColorBlindnessFilter`/`COLOR_BLINDNESS_MATRICES` - accessibility colour filters.
469
- - `Minimap`/`newlyRevealed`/`minimapCellCenter`/`MinimapMarker` - bakes an explored-cell set
470
- into a persistent `RenderTexture`, never redrawing an already-baked cell, and supports
471
- several game-owned unit or quest markers.
472
- - `TileMap`/`EMPTY`/`tileFrame`/`tileFrameSheet`/`tileFrameIndex` - tile map rendering:
473
- square/hex/isometric/staggered projections, multi-sheet tiles, elevation columns.
474
- - `LayeredSprite` - layered character sprites (body/hair/equipment as separate layers).
475
- - `SkeletalSprite`/`ArticulatedChain`/`ChainRig` (items 399/400) - bones driving drawn
476
- parts: the pose math lives in the renderer-free `skeleton` module (bone tree, keyframed
477
- clips, crossfade, priority layers), `SkeletalSprite` binds a part to a bone by name and
478
- `update(dt)` places it at the bone's world transform, and `ArticulatedChain` is the
479
- follower rule a keyframe cannot express - a serpent's spine whose segments ease toward
480
- their parent's previous position within per-segment rotation limits.- `Projectile` - tweens a sprite in a straight line for a thrown/shot visual flourish; an
481
- optional `animation` (item 311) advances flight frames with the tween's own elapsed time, read
482
- back through `frame`/`frameOffset` so the caller can apply the frame's offset where it already
483
- positions the sprite. `Flights` owns the live ones: `add(sprite | texture, from, to,
484
- { speed, tint?, spin? | spinDegrees?, fadeIn?, onArrive? })` returns a handle, `update(dt)` drives
485
- positions and dispatches each arrival exactly once, `cancel()`/`clear()` forget without
486
- dispatching; caller sprites stay caller-owned while texture-built sprites are parented
487
- here and destroyed with their flight. `spinDegrees` is `spin` in degrees per second
488
- (converted once, so an authored angular speed needs no radian arithmetic at the call
489
- site) and `fadeIn: 'progress'` (or `true`) eases the sprite's alpha 0 to 1 along the
490
- tween's own progress instead of seconds from launch.
491
- - `LightningArc` - the position data for a jittered line between two points (a bolt, a tether):
492
- `points` tapers to zero offset at both endpoints, `retarget` moves either endpoint for a
493
- tether following two moving units, and an optional `flickerInterval` re-rolls the jitter on a
494
- timer. Geometry only, drawn by the caller through `Shape2D`'s `Graphics`. `Beam` is the
495
- drawn one-shot counterpart (a fading line, or a texture strip - repeating by default,
496
- or `BeamTextureOptions`' `stretch: true` for art that spans the whole beam once, with an
497
- `anchor` placing it across the thickness - additive by default, `retarget` moving
498
- either end, `thin` narrowing the body as it fades, `update` reporting expiry once);
499
- `Beams` owns the live ones with `add`/`update`/`clear` and destroys finished beams.
500
- - `SpriteAttachment` - ties a second sprite's position to a first one's: `follow(x, y)` applies
501
- an offset, and an optional `duration` makes `update(dt)` report `done` once it elapses, so a
502
- permanent shadow and a temporary status icon are the same class with different options.
503
- Renderer-neutral like `Projectile`/`LightningArc`; z-order and parenting stay the caller's.
504
- - `LiquidLayer`/`LiquidLayerOptions` - an animated liquid surface under a map: one scrolling
505
- tiling quad per liquid cell with its own visibility tint (`setCellColor`), and `ripple` rings
506
- that grow and fade; pure decoration, every child opts out of pointer events.
507
- - `FogLayer`/`paintFogPixels`/`FogCell`/`FogColor`/`FogLayerOptions` - a smooth fog-of-war
508
- overlay: a small linear-filtered canvas with `resolution` pixels per tile, so fog edges blur
509
- across cells and one cell can be shaded in parts; `paintFogPixels` is the same shading as a
510
- pure function over an RGBA buffer.
511
- - `TileMap.stampRect` copies a block of frames into a layer at a tile position and throws when
512
- it does not fit; `AutotileSet.mode: 'mixed'` reads the MV A4 sheet's alternating rows with the
513
- floor table (wall tops) and the wall table (wall faces).
514
- - `Halo`/`HALO_ANIMATION` - the glow around a unit, an aura, a shrine's light: an `AnimatedSprite`
515
- drawn additively (Wesnoth's `[halo] blend_mode=add`) whose `follow(x, y)` applies the halo's own
516
- offset once instead of in every game that draws one. Z-order stays the caller's, because a halo
517
- that belongs behind its unit is added before it and one that belongs in front is added after, and
518
- a framework that guessed would be wrong half the time.
519
- - `ParticleEmitter`/`Particle` - a pooled, seeded particle emitter (sparks, dust, rain):
520
- `burst`/`start`/`stop` over a pool allocated once at `max`. Runs the whole simulation with
521
- no `texture` given, which is how it is tested without a renderer. `ParticleSpawnArea` gives
522
- births a local `rect` or `ellipse` extent instead of the emitter's single origin. `scale` and
523
- `alpha` take a `ParticleCurve` (`t` over the particle's life) as well as the birth-to-death
524
- pair, `tint` takes a `[from, to]` range each particle draws its own colour from channel by
525
- channel, and `flicker` wobbles the scale every frame with a seeded draw (dropped under reduced
526
- motion). All three draws happen only when used, so an existing emitter's seeded spray is
527
- unchanged. `attach(target)` follows a display object or position thunk on every tick (with `offsetX`/`offsetY`, an `enabled` callback gating tick emission, a `visible` callback hiding the whole spray (fog-of-war gates) while the simulation steps on behind the invisibility, and auto-detach for destroyed targets); `detach()` keeps the last position.
528
- - `ScreenEffects`/`ScreenEffectStep` - a full-screen colour wash: `fadeOut`/`fadeIn`/`flash`/
529
- `setTint`, driven by `update(dt)` returning true on the frame an effect completes.
530
- `sequence(steps)` (item 302) chains fade/hold/flash steps end to end as one call, for the
531
- hold-then-fade-back transition the four individual methods cannot express alone; `update`
532
- keeps returning false at every step boundary, true only once the whole sequence finishes.
533
- - `SceneTransition`/`TransitionOptions`/`TransitionRunner`/`TransitionDisposition` + `transitionDisposition`, `tileShrink`, `shrink`, `pop`, `grow`, `slide`, `iris`
534
- and `dissolve` - screen transitions: `Game.switchScene(Next, { transition, duration, easing })` photographs the
535
- outgoing scene and animates it away (or grows the new one over it), `Scene2D.transitionTo(swap, options)` does
536
- the same for a scene changing its own content, `Game.transitioning` tells a scene to ignore input, a second
537
- transition requested while one plays is ignored unless its options say `queue: true` or `interrupt: true`
538
- (`transitionDisposition` is that rule as a plain function), and
539
- reduced motion skips it. `tileDelays`, `tileProgress`, `popScale`, `openAnimationFrame` and `resolveEasing` are the
540
- timing as plain functions.
541
- - `ActorAnimator` - an idle/move/action animation state machine with one interruption rule.
542
- - `StatusVisuals` - composes every active status effect's colour additively onto a sprite's
543
- `colorAdd` (item 301), instead of one status winning by declaration order; each channel clips
544
- at 1 rather than wrapping. Never touches the multiply `tint`, so a sprite's own identity
545
- tint (a team colour) survives underneath. `flash(color, strength, duration)` layers a
546
- one-shot, linearly-decaying pulse (a hit, a heal) on top of whatever is active.
547
- - `SpriteMotion` - squash, hop, bob, wobble, spin, shear and flip over any display object's
548
- transform through a `Tweener` (item 404). Effects compose from the rest pose captured at
549
- construction, never drift, return a `MotionHandle` (`done`, `cancel()`), and follow
550
- `setReducedMotion`; `destroy` restores the rest pose, flips included.
551
- - `ClothSprite` - a `physics` `Cloth` mesh drawn as a textured sprite on the 414 mesh
552
- path (item 423): owns the simulation, `update(dt)` steps it and re-uploads the vertex
553
- buffer, the top edge starts pinned, UVs are never rewritten. `setWind`/`pinPoint`/
554
- `unpinPoint` tune it, and it honours `setReducedMotion`.
555
- - `Spring` - a damped 2D chase spring for secondary motion (item 424): the anchor
556
- teleports, the bob lags, overshoots and settles through pure arithmetic, O(1) per
557
- update, deterministic for a fixed `update(dt)` sequence. `place(target)` parks a
558
- follower on the bob; honours `setReducedMotion`. `SpringSprite` draws the
559
- anchor-to-bob line, redrawn by an explicit `sync()` after stepping.
560
- - `HazeLayer`/`hazeField`/`paintHazePixels` - an atmospheric haze sheet, never fog of war:
561
- translucent drifting weather with soft edges, density and per-plane wind, on a small
562
- canvas scaled up with linear filtering. `paintHazePixels` is the same shading as a pure
563
- function over an RGBA buffer, which is how it is tested without a renderer.
564
- - `NeonGlow`/`glowFalloff`/`paintGlowPixels` - a soft additive halo baked from a shape or
565
- mask, with colour, radius, intensity and flicker; a global bloom stays optional.
566
- - `loadTiledMap`/`TiledMapData`/`TiledTilesetData`/`TilesetSheet`/`LoadedTiledMap` - loads
567
- Tiled JSON maps into a `TileMap`: orthogonal, isometric and staggered orientations, multiple
568
- tilesets (embedded or external `.tsx`). Lives here rather than in `rpg` because what it
569
- builds is a `TileMap` out of `SpriteSheet`s.
570
- - `blobIndex`/`autotileFrames`/`BLOB_SHAPES` - auto-tiling: the 47-shape "blob tile"
571
- reduction of 8-neighbour terrain matches.
572
- - `rpgmAutotileFrame`/`RpgmAutotileAtlas` - renderer-neutral RPG Maker MV autotile atlas
573
- geometry: decode one of the four atlas slots, select its four 24px source quadrants for a
574
- shape, and describe their 48px output position. `RpgmAutotileAtlas` caches repeated frame
575
- descriptions. `RPGM_FLOOR_AUTOTILE_TABLE`/`RPGM_WALL_AUTOTILE_TABLE` are the standard MV
576
- shape tables, `RPGM_AUTOTILE_SLOT_BASES`/`RPGM_AUTOTILE_SLOT_COUNTS` the family address
577
- facts, and `rpgmAutotileSlot` classifies a raw map id into its family (item 370).
578
- - `TileMap` `addAutotileLayer` over `AutotileSet`/`AutotileCell` - a native autotile layer:
579
- raw MV ids or XP values route to the set claiming them, and the map assembles each
580
- cell's quadrant halves straight from the source sheet (item 370). `setAutotileFrame`/
581
- `getAutotileFrame` advance and read the animation frame; `setTile`/`getTile` keep
582
- working with raw ids. `XP_AUTOTILE_PATTERNS`/`XP_NEIGHBORS_TO_PATTERN` are the XP
583
- template and neighbourhood tables, `xpAutotileRef`/`xpAutotilePattern` decode and
584
- compute XP cells, and `autotileCellParts`/`assertAutotileLayout` resolve and validate
585
- one cell's pieces renderer-free.
586
- - `AutotileSet.tableEdge` with `rpgmTableEdgeCells` over `RpgmTableEdgeMap` - the front-edge strip
587
- the engine draws under an A2 table: `rpgmTableEdgeCells` finds the cells that get one (table
588
- above, none here, no A3/A4 wall on the ground layer) and the set draws its two half-height
589
- pieces. `TileMap` `addShadowLayer` over `ShadowLayerOptions` adds the engine's shadow bits
590
- (map layer 4) as translucent quarter-tile quads.
591
- - `resolveTerrainGraphics`/`matchTerrainRule`/`squareRotate`/`hexRotate` over `TerrainRule`/
592
- `TerrainCondition`/`TerrainImage`/`TerrainPlacement`/`TerrainFlagsAt` - a rule-driven
593
- `[terrain_graphics]`-style transition pass for what `Autotile`'s fixed 47-shape table cannot
594
- express: flag conditions at arbitrary offsets, one rule placing more than one image (so a
595
- piece bigger than one cell is the rule's own data, not something `TileMap` has to hold),
596
- `rotations` (`squareRotate`'s 4 exact steps or `hexRotate`'s 6) and `probability` breaking a
597
- tie among rules matching at equal specificity. Returns plain placement data.
598
- - `TerrainGraphicsLayer` over `TerrainGraphicsLayerOptions` - the renderer for that data: one
599
- `Sprite2D` per placement, added in `layer` order (a stable sort, so the rule pass's own
600
- row-major walk survives within a layer), each resolved through the asset resolver at the pixel
601
- position the caller's `project` callback reports. `setPlacements` redraws; z-order against the
602
- rest of the scene is the caller's, as it is for `Halo`.
603
- - `inspectGraphicsCapabilities`/`detectWebGpu`/`RENDERING_DECISIONS` - checks
604
- WebGL/WebGPU/WGSL support and records this project's own rendering-backend decisions.
605
- - `Container2D`/`Texture2D`/`Rectangle2D`/`Rect`/`TextureRegion`/`rectOf` - the renderer
606
- boundary names for common 2D values. The first three work in both type and value positions,
607
- so a game can construct a container or use texture and rectangle constants without naming
608
- `pixi.js`. For the rare need the facade does not cover, `two-d/pixi-interop` re-exports the
609
- underlying Pixi classes explicitly.
610
- - `Node2D`/`Shape2D`/`Text2D`/`Sprite2D`/`TiledSprite`/`Gradient` - bare, MWG-named
611
- re-exports of Pixi's `Container`/`Graphics`/`Text`/`Sprite`/`TilingSprite`/`FillGradient`:
612
- a plain grouping layer, vector drawing, one-off text, a plain untinted sprite, a
613
- repeating/scrolling texture, and a gradient fill/stroke, none of which needed new
614
- behaviour, only a name a game can import without naming `pixi.js` itself. Prefer
615
- `ui.Label`/`BitmapLabel` over `Text2D` for anything styled through `ui.theme()`, and
616
- `render.TintedSprite` over `Sprite2D` the moment a colour transform is needed.
617
- - `createLayers(parent, names)` (item 312) - builds one labeled `Node2D` per name, attached to
618
- `parent` in the order given and returned keyed by name, so a game's conventionally-ordered
619
- layer stack (terrain, units, effects, UI, ...) is one call rather than a dozen hand-wired
620
- containers.
621
-
622
- ### `two-d/ui`
623
-
624
- Windows, lists, message boxes, HUD widgets - all themed from one live-swappable `Theme`.
625
-
626
- - `theme`/`setTheme`/`defaultTheme`/`highContrastTheme`/`themeChanged` - the active theme;
627
- `setTheme` fires `themeChanged` so already-built widgets restyle in place.
628
- - `Label` - a themed text wrapper over Pixi `Text`; `stroke`/`resolution`/`roundPixels`
629
- options, useful for text over artwork.
630
- - `parseMarkup`/`stripMarkup`/`markupToHtml`/`escapeHtml` over `MarkupSpan`/`MarkupOptions` - inline
631
- markup (`<b>`, `<i>`, `<span color='…' size='…'>`, `<br/>`, `<img>path</img>`, `$name`, and the
632
- five entities) as a renderer-neutral contract: a `MarkupSpan` is a `MarkdownSpan` plus the colour,
633
- size and image a renderer may use, kept as written because resolving them is the renderer's
634
- business. Unknown tags, malformed tags and unset variables stay literal rather than disappearing,
635
- and `markupToHtml` is the escaped HTML fragment for a renderer that speaks HTML text - it now
636
- also renders colour and size, as an inline style. `MarkupOptions.tags` (item 313) names extra
637
- tags to treat as styling containers; a run inside one carries its name in `MarkupSpan.tag`, so a
638
- renderer can resolve its style (Pixi's `tagStyles`) while the parser stays renderer-neutral, and
639
- `markupToHtml` re-emits that tag as a real element for `HTMLText`. `markupAccessibilityText` is the proper
640
- accessibility projection (an image becomes a caller-described string, not its raw path, which
641
- `stripMarkup` keeps for round-tripping instead). `layoutMarkupLines` wraps already-parsed spans
642
- word by word against a caller-supplied `MarkupMeasure`, each word measured under its own
643
- span's style - wrapping computed *after* styling, so a bold or larger run wraps where its own
644
- wider glyphs actually land - and `positionMarkupLines` places those already-laid-out lines into
645
- `PositionedMarkupSpan` runs (one `x`/`y` per span) under a `MarkupLayout`'s `direction`/`align`,
646
- so an `rtl` line flows right to left and alignment defaults to the direction's own edge. Both
647
- are backend-neutral: the same spans, `measure` and `maxWidth` decide the same line breaks and
648
- the same runs whether a caller then draws them through `HTMLText` or a canvas `Text2D` pass.
649
- - `MarkupText`/`MarkupTextOptions` - the canvas backend for that contract, the counterpart to
650
- `RichLabel`'s HTML text: one `Text2D` per styled run and one `Sprite2D` per `<img>` span,
651
- resolved through the asset resolver, so an image is drawn rather than a caller positioning it
652
- itself at a `layoutMarkupLines` offset. It reads `direction` from the theme and takes
653
- `maxWidth`/`lineHeight`/`align`/`resolveImage`/`variables`/`resolution` options, plus
654
- `tagStyles` (item 313): a Pixi `TextStyleOptions` record keyed by custom tag, applied to each
655
- run and used when measuring it, so `<quest>...</quest>` is styled and wraps under its own font.
656
- - `RichLabel`/`parseMarkdown`/`stripMarkdown`/`sliceSpans` - basic inline markdown (`**bold**`,
657
- `*italic*`, combined `***both***`, backslash escapes) through Pixi `HTMLText`, which is
658
- what makes mixed styles inside one string possible at all. `parseMarkdown` is pure
659
- span-splitting (unmatched markers stay literal); `stripMarkdown` recovers plain text;
660
- `sliceSpans` takes the first N visible characters with styles kept, for progressive
661
- reveal without leaking half-shown markers. Costs more than a `Label`, so this is for
662
- descriptions and help bodies, not per-frame numbers. `tagStyles` (item 313) takes Pixi
663
- `HTMLTextStyleOptions` keyed by custom tag; a registered tag survives escaping as a real element
664
- for `HTMLText` to style, while an unregistered one is still escaped as literal text.
665
- - `startReveal`/`advanceReveal`/`completeReveal`/`revealComplete` - the shared
666
- progressive-display primitive: one character count behind `MessageBox` pages (which
667
- already revealed this way), `Label` lines, and `RichLabel` markdown. `Label` and
668
- `RichLabel` expose it as `showProgressive`/`updateReveal`/`completeReveal`, driven by
669
- the game's own frame loop; `MessageBox` keeps its confirm-completes-then-advances rule
670
- on top unchanged.
671
- - `BitmapLabel`/`bitmapLabelStyle` - bitmap-font-backed text, for a HUD value redrawn
672
- every frame where `Label`'s per-string texture re-render would be wasteful.
673
- - `NinePatch` - a resizable nine-slice panel.
674
- - `Window` - a themed panel container. `open({ animation, from })` plays `pop`, `grow`, `slide` or `fade`
675
- (`WindowAnimation`) and `close({ animation })` plays it backwards before closing, both driven by
676
- `update(dt)` and skipped under reduced motion. `close()` frees the window and its contents and is
677
- idempotent; `closed` is the guard for the caller's reference afterwards (input and `place` on a
678
- closed window are no-ops), and `WindowStack.push` refuses one with a named error. A window's own
679
- area is not clickable, so a click travels to whatever is under it; `blocker: true` adds the
680
- full-viewport layer that swallows clicks and dismisses the window for a click outside it
681
- (`handleOutsideClick` is that decision).
682
- - `WindowStack` - keyboard focus goes to the top window only; dims what's underneath; `blocker` on
683
- a window is what stops clicks reaching the map behind it. `handleAction(action)` is public so a
684
- scene with its own key handling can ask the windows first: `Input.onAction` offers an action to
685
- the most recently registered listener first, so a scene that registers after building its stack
686
- is asked before the windows are and can swallow a key they need.
687
- - `MessageBox.blocker` - whether a click under the box reaches the map behind it; on by default,
688
- and since the box is not closable that can only ever swallow clicks rather than dismiss it.
689
- `blocker: false` is for a box the player is meant to click past.
690
- - `ListView` - a scrollable, keyboard- and pointer-navigable row list (click, wheel-scroll);
691
- `multiple` checks rows instead of picking one, read back through `checkedIndexes`.
692
- - `IconGrid` - a multi-column icon-grid inventory view; tap-then-tap "drag and drop",
693
- frame-driven long-press for a quickslot.
694
- - `TabbedList`/`ListTab`/`TabbedListOptions` - a renderer-free model for an inventory, journal,
695
- shop or codex: caller-supplied tabs and rows (no assumed taxonomy), an optional label,
696
- filter and disabled predicate, selection that skips disabled rows, a page derived from the
697
- selection rather than tracked beside it, and an `openDetail`/`closeDetail` state.
698
- - `Slider`/`SliderOptions` + `sliderFraction`/`sliderValueAt` - a draggable knob on a themed track;
699
- the two pure functions are the value/track arithmetic (clamping, the step grid, the degenerate
700
- range), so a game routing its own input snaps the same way.
701
- - `Checkbox`/`CheckboxOptions` - a ticked-or-not box; a caption is a `Label` the game places beside
702
- it, and `onChange` fires only when the state moves.
703
- - `RadioGroup`/`RadioOption`/`RadioGroupOptions` - exactly one choice among several: arrows
704
- move the selection and select at once, a tap selects directly, disabled options are skipped.
705
- - `Spinner`/`SpinnerOptions` + `spinValue` - an up/down numeric stepper; `spinValue` is the rule
706
- (snap to the step, then clamp at the ends or wrap past them).
707
- - `DropdownView`/`DropdownViewOptions` - the widget over a `Dropdown` model: a button showing the choice
708
- that opens a column of `Button`s on an opaque backdrop, the highlighted one marked with
709
- `Button.setSelected`. `maxVisibleRows` makes a long list scroll (wheel, touch, keys, scrollbar) and it opens with
710
- the chosen row in view; `autoWidth` fits the longest label, `maxWidth` caps that widening, and `resize(width)`
711
- re-lays the button and list in place; `handleKey` (arrows, Page, Home/End, Enter,
712
- Escape) and `handleOutsideClick` are what the scene forwards from its own input; `fitBelow` limits the
713
- rows to what the viewport leaves under the button.
714
- - `Dropdown`/`DropdownOption`/`DropdownOptions` - a renderer-free option button: a selected entry,
715
- an open list, a highlight that starts on the selection and skips disabled options. `setHighlight(i)`
716
- opens the list on that row, so `setHighlight(i); confirm()` is a whole programmatic pick.
717
- - `TextModel`/`TextModelOptions` - the editing state behind a text field, fed by `core.Input`'s
718
- `onText`: caret, anchor, selection-replacing edits, a length cap and a mask. Renderer-free.
719
- `multiline` keeps real newlines with row navigation (`lineCount`, `caretLine`, `lineRange`,
720
- `moveCaretLine` holding a sticky goal column); single-line fields strip them on every edit.
721
- - `TextPrompt`/`TextPromptOptions` - a modal single-line text field over a `TextModel` (a name
722
- entry, a save-slot label): typing through `onText`, caret and edits through `left`/`right`/
723
- `backspace`/`delete` actions, `confirm` gated by `validate` (the error shows and announces
724
- assertively, the prompt stays open), `cancel` giving up. IME compositions preview until
725
- they commit, and the message plus validation errors announce through `screenReader`.
726
- The interface example's Name button is the reviewed hosting pattern: push it on a
727
- `WindowStack` and it owns focus, closing and the stack's un-popping by itself.
728
- The touch half (roadmap 402): `keyboard: UPPERCASE_KEYBOARD` (or any `KeyboardLayout`)
729
- hosts one beneath the field and resizes the window to fit it - `OnScreenKeyboard`,
730
- next.
731
- - `OnScreenKeyboard`/`KeyboardLayout`/`KeyboardKey` + `UPPERCASE_KEYBOARD`/`pressKey`/
732
- `layoutKeys` - pointer-only typing: a layout is rows of keys as plain data (ragged rows
733
- fine), each key a caption, the `text` it types (defaulting to its label), or the named
734
- `action` it fires instead, plus a `span` in row units for a space bar. The class renders
735
- it through the theme's own `Button` and reports `contentHeight` so a host can size
736
- itself; `pressKey` is the pure dispatch rule (`dispatchText` for a typing key,
737
- `dispatchAction` for an action key, the two paths a physical key travels, so no
738
- listener can tell a tap from a keystroke) and `layoutKeys` the rows-to-buttons
739
- arithmetic behind it. `UPPERCASE_KEYBOARD` is the one shipped default: the alphabet
740
- over a digit row, then `Bksp`, caret moves, space, `OK`, `Esc`.
741
- - `DataTable`/`TableColumn`/`DataTableOptions` - a renderer-free columned table: sort by a column
742
- (toggling direction), a highlight that skips disabled rows, and a page derived from the
743
- highlight.
744
- - `TreeView`/`TreeNode`/`TreeRow`/`TreeViewOptions` - a renderer-free collapsible tree, flattened to
745
- the rows on screen; collapsing the branch the highlight is inside lands it on the branch.
746
- - `ScrollBox`/`ScrollBoxOptions`/`ScrollKey` + `scrollOffset` - a clipped viewport with a themed scrollbar;
747
- `scrollOffset` is the clamping rule the wheel, `scrollBy` and `scrollIntoView` all share. `touch: true` lets a
748
- finger drag the content (a drag cancels the tap on the row under it) and coast on release, `handleKey`
749
- scrolls by line, page and to either end, the thumb drags and the track jumps, and `autoHeight` sizes the
750
- viewport to the content up to `height`. The box owns its `hitArea` (its viewport, kept current by `resize` and
751
- `setContentHeight`), so the wheel reaches it without a row under the pointer. `update(dt)` drives the coasting.
752
- - `ScrollDrag` - touch scrolling as plain numbers (`start`/`move`/`end`/`step`): how far the content follows a
753
- finger and how it coasts after release, with no pointer events or clock of its own.
754
- - `ScrollText`/`ScrollTextOptions` - a wrapped `Label` in a self-sizing `ScrollBox`: as tall as the text up to
755
- `maxHeight`, scrolling beyond it, re-measured by `setText` and re-wrapped in place by `resize(width)`.
756
- - `MarqueeLabel`/`MarqueeLabelOptions` + `marqueeOffset` - one line that stays on one line: a long text slides
757
- back and forth in a clipped window (and holds still, cut short, under reduced motion).
758
- - `ellipsize` and `truncateLines` - cut a text to a width or a number of lines, ending in an ellipsis, with the
759
- caller supplying the measuring function.
760
- - `flowLayout(items, width, { gap, align })` - left-to-right rows that wrap, returning each item's
761
- position and the total height: a toolbar that takes two rows on a phone.
762
- - `Grid`/`GridSpec`/`GridTrack` + `resolveAnchor`/`anchorAlign` with `Anchor`/`AnchorSpec`/
763
- `LayoutRect` - data-driven shell layout (item 263): named anchors placed inside bounds (margin,
764
- offset, fill), and columns/rows that are `size` or `grow`, so one sidebar plus one content column
765
- needs neither side to know the window's width. Pure geometry, renderer-free.
766
- - `Skins` with `Skin`/`SkinStates`/`SkinData`/`WidgetState` - per-widget, per-state looks looked up
767
- by name, the counterpart the one global `Theme` has no room for. A lookup falls back widget state
768
- -> widget idle -> wildcard state -> wildcard idle -> `{}`, and `Skins.from` reads the plain data a
769
- config file would parse into.
770
- - `MessageBox` - dialogue text box: paged reveal, choices, ADV/NVL display modes,
771
- `autoAdvance`, and timed `{sound:path}` markers delivered through `onSound`.
772
- - `messageBoxPresenter` - wires `rpg.EventRunner`'s dialogue to a `MessageBox` on a
773
- `WindowStack`, in one argument: `present: messageBoxPresenter(this.windows)`.
774
- - `VerticalLabel`/`layoutVertical` - vertical writing layout, with CJK glyph rotation.
775
- - `RebindScreen` - a keybind-rebinding flow over `Input`, with an optional conflict hook.
776
- - `SettingsScreen`/`SettingsCustomRow`/`SettingsScreenOptions` (item 364) - a ready-made
777
- settings screen over `core.Settings`: music/sfx sliders, mute checkbox, zoom slider,
778
- one row per `custom` descriptor (boolean/number/choice), an embedded controls page
779
- that writes rebinds back into `Settings` on exit, and a reset row. `cancel` on the
780
- main page returns false for the caller to close.
781
- - `Button`/`ButtonSkin`/`ButtonState` - idle/hover/pressed/disabled clickable region, icon
782
- and/or text, optional per-button nine-patch skin with per-state tints.
783
- - `Bar` - a filled-proportion track (health/mana/XP); flat colour or texture, optional
784
- `roundUpToPixel` so a nonzero value never rounds down to invisible.
785
- - `Meter`/`MeterOptions` (item 368) - a discrete meter: N icons with a value filled, the
786
- heart row or star rating to `Bar`'s continuous fill. Fractions clip mid-icon through a
787
- mask, so halves need no extra art; flat theme pips by default, a game-supplied
788
- filled/empty texture pair (which must come together) otherwise.
789
- - `FloatingText`/`floatingTextAlpha`/`floatingTextRise`/`floatingTextAgeAtLeast` - a rising, fading
790
- damage/pickup number and its pure motion, opacity and age curves; `FloatingTextStack` with
791
- `floatingTextStackLift`/`floatingTextStackMoves`/`floatingTextStackLifePenalty` and
792
- `FLOATING_TEXT_STACK_GAP` stacks simultaneous pop-ups at one world point without overlap, lifting
793
- the lines already there the way Java's `FloatingText.push()` does.
794
- - `MessageLog`/`linesToDrop`/`takeLastEntries`/`MessageLogEntry`/`MessageLevel`/`MessageLogOptions` - a player-facing message pane:
795
- one coloured block per message (info, positive, negative, warning, highlight) that drops the
796
- oldest blocks once the wrapped lines pass a cap; `linesToDrop` is that budget as a pure function,
797
- and `lastEntries(n)` reads the newest retained entries back as `{ text, level }` records
798
- (oldest first) without scraping rendered children.
799
- - `fitWindowZoom`/`sharpenText` - step a window stack's integer zoom down until its content fits
800
- the viewport, and re-rasterise every `Text` under a zoomed container at device ratio times its
801
- on-screen scale so it is not magnified 1x text.
802
- - `Toast` - a queued, timed pop-up notification (fade in, hold, fade out).
803
- - `Tooltip` - a hover explanation over a themed `Window`: a frame-driven hover delay, and
804
- edge-aware placement that flips rather than letting the panel run off screen.
805
- - `TooltipHost`/`TooltipHostOptions`/`TooltipTarget` - drives one `Tooltip` from rectangles: a press that rests
806
- for `longPress` seconds shows the text on a touch screen, and a disabled `Button` (which gets no pointer
807
- events) is still explained from its bounds and its `tooltip`. `attach(pointer)` wires an
808
- `Input.attachPointer` tracker.
809
- - `HelpScreen` - a topic-list-plus-body help/controls screen.
810
- - `StatsScreen` - a player-stats display screen.
811
- - `LoadingScreen` - a progress-bar loading screen wired to `core.LoadQueue`.
812
- - `ScreenReader`/`screenReader` - the screen-reader bridge: `Window` announces its title,
813
- `MessageBox` each page and its choices, and `TextPrompt` its message and validation errors
814
- through a visually hidden `aria-live` region, and a game's own widgets use the same
815
- `screenReader.announce(text, { assertive })`. No-ops where there is no DOM, so ordinary
816
- scene code needs no guard around it.
817
- - `contrastRatio`/`meetsContrast`/`relativeLuminance`/`ContrastLevel` - WCAG contrast for a
818
- `theme` palette: the standard luminance and ratio formulas with AA/AAA thresholds, so a
819
- game checks its own colours rather than guessing.
820
-
821
- ### `two-d/stage`
822
-
823
- Dialogue scenes: backdrop, characters, a script runner - the visual-novel half.
824
-
825
- - `DialogueStage`/`CharacterDefinition`/`ShowOptions` - backdrop plus character
826
- conversation scenes; the speaking character lit, others dimmed.
827
- - `StageScript`/`StageCommand`/`StageChoice`/`StoryScript` - a command interpreter;
828
- `runStory` follows a named-passage graph (`{goto}`, choice jumps); `history`/`showLast`
829
- for read-only dialogue rollback; `skipSeen` for auto-advancing already-read lines;
830
- `ScriptOptions.mode: 'nvl'` for the accumulating-block presentation.
831
- - `importTwee`/`TwineStory` - imports Twee-notation Twine stories into `StageScript`'s
832
- command format, a thin wrapper around `core.parseTwee` naming the `StoryScript` return
833
- type. `rpg.importTwee` is the same wrapper around the same engine, targeting
834
- `EventStoryScript` instead, so a text-only RPG needs no Pixi dependency to import a
835
- branching Twee story, and a visual novel that never touches map events needs no `rpg`
836
- dependency either.
837
- - `parseDialogueText`/`extractDialogueCatalog` - a terse line-based dialogue format for
838
- straight (non-branching) scenes: `@id text` names the speaker, an unprefixed line
839
- narrates, and `- text` alternates between the first two speakers established by `@id`
840
- lines (capped at two - a third distinct speaker is refused). A thin wrapper around
841
- `core.parseDialogueLines`, mapping its `speaker` field onto `StageCommand`'s `as`.
842
- `extractDialogueCatalog` builds an identity `i18n` catalog from the resulting commands
843
- (or a `StoryScript`), the same shape MWL's own `extractCatalog` builds from
844
- `_("...")`-marked strings. `rpg.parseDialogueText` is the same wrapper around the same
845
- engine, targeting `EventCommand` instead, so a text-only RPG needs no Pixi dependency to
846
- use it, and a visual novel that never touches map events needs no `rpg` dependency either.
847
- - `StoryScreen`/`StoryScreenOptions` with `StorySequence`/`StoryBeat` - the between-scenario
848
- interlude `DialogueStage` is not: a full-screen backdrop, title and text advanced by a click. The
849
- sequencing (advance/back/`goTo`/`skip`/`restart`, and the current beat's `music` reported as a
850
- signal so the game plays it) lives in the renderer-free `StorySequence`, and a `StoryBeat` has
851
- the same `{ text, title, image, music }` shape as `MwlWorld.story`.
852
-
853
- ## `assets`
854
-
855
- The `file://` story: a compiled build resolves paths through a `data:` URI map; dev mode
856
- serves them normally. Load once per scene; everything after is synchronous. The compiler side
857
- of this (`tools/compile-resources.mjs`, `tools/emit-page.mjs`, `tools/single-file.mjs`) offers
858
- independent build options on top of that one story - multi-file vs. single-file output,
859
- compression (gzip or brotli, single-file only), WebP image conversion and SVG optimisation
860
- (`svgo: true`, ids and `viewBox` kept, only when smaller) - documented in
861
- `DEVELOPMENT.md`'s "Build options" section and `tools.md`'s tool reference; none of them
862
- change what a game calls to load an asset.
863
-
864
- Split by renderer specificity: `assets/paths.ts` resolves paths and needs no renderer,
865
- `assets/binary.ts` caches raw bytes just as renderer-free, `assets/loader.ts` fetches and
866
- decodes *textures* through Pixi. The `assets` barrel exposes all three; a game rendering
867
- through something else imports `@datamoc/mw_games/assets/paths` or
868
- `@datamoc/mw_games/assets/binary` and pays nothing for Pixi, which is how `3d` and `audio`
869
- reach the compiled asset map without it.
870
-
871
- - `setBase`/`setAssetMap`/`isCompiled`/`paths`/`has`/`resolve` - dev-vs-compiled path
872
- resolution, renderer-free (also its own entry point, `@datamoc/mw_games/assets/paths`).
873
- `setAssetMap` hands these a game's own path-to-URI map directly (item 300), for a game
874
- bundled by its own tool rather than `tools/compile-resources`, and takes priority over
875
- `window.__MWG_ASSETS__` while set; `undefined` reverts to it.
876
- - `load`/`texture`/`get`/`isLoaded`/`release` - load assets by path, read them back
877
- synchronously, and free GPU memory once a zone is no longer needed. `load(paths,
878
- { resolution })` rasterizes a vector source (SVG) at a multiple of its intrinsic size, so a
879
- game that zooms into an icon asks for a `2` or `3` instead of shipping a soft bitmap;
880
- `onProgress` is the same `LoadQueue` seam whether passed alone or in the options. `optional`
881
- loads those paths separately so one missing file never aborts the required batch, calling
882
- `onMissing` for each; `texture`/`get` take a `fallback` returned instead of a throw for a
883
- path that never loaded, so a caller stops needing its own try/catch around a missing asset.
884
- - `sanitizeSvg`/`svgScaleVariants`/`svgDataUri`/`splitSvgGroups` (item 398) - SVG as
885
- inbound data: `sanitizeSvg` refuses what it cannot prove inert by name (script,
886
- `foreignObject`, event handlers, `javascript:` and active `data:` URLs - a gate, never
887
- a silent rewrite), `svgScaleVariants` rasterizes one proven-inert source once per named
888
- scale with its resolution hint, and `splitSvgGroups` loads a group-authored SVG as one
889
- standalone part per top-level `<g id=...` group, the authoring form for an SVG puppet. `load` also supplies Pixi's `Assets.add` a `format` hint - the original path's own extension
890
- - whenever the resolved `src` is a compiled build's `data:` URI (item 308): a `data:` URI
891
- carries no extension of its own for Pixi's resolver to pick a parser from, which otherwise
892
- left a game no way to load a compiled asset without building its own `{src, parser}`
893
- descriptor by hand.
894
- - `loadBinary`/`getBinary`/`isBinaryLoaded`/`releaseBinary` - the renderer-free counterpart
895
- to `load`/`texture`/.../`release`, caching raw `ArrayBuffer`s instead of Pixi textures
896
- (also its own entry point, `@datamoc/mw_games/assets/binary`); `3d/models`' `Vox.parseVox`
897
- is the direct consumer, taking bytes this now fetches and caches instead of a game doing
898
- it by hand.
899
- - `AssetStream`/`AssetBundle` - preloads likely-next bundles with LRU eviction under a
900
- byte budget, for progressive loading between scenes.
901
- - `fetchWithByteProgress`/`ByteProgress`/`OnByteProgress` - real cumulative byte-progress
902
- reporting, for a server or desktop host (not `file://`, which blocks `fetch` entirely).
903
-
904
- ## `audio`
905
-
906
- - `Sound` - a pooled, round-robin one-shot sound effect player. `play(gain, pitch)` takes an
907
- optional pitch as `HTMLAudioElement.playbackRate` (1 unchanged); there is no matching `pan` -
908
- a plain `<audio>` element has no pan of its own, the same reason `Positional.audioPan` only
909
- reports a number rather than owning a panner node. `suspend` cuts in-flight sounds and
910
- silences `play` until `resume`.
911
- - `onCaption`/`CaptionEvent` - accessibility captions fired alongside a sound cue.
912
- - `Music` - crossfading background music. `suspend` pauses the current and fading tracks
913
- and freezes `update` until `resume` restarts the current one where it paused. `duck`
914
- glides to an attenuated level until `unduck`, for dialogue and menus.
915
- - `createAudio`/`Playable` - an injectable audio backend (tests supply a fake in place of `new Audio()`).
916
- - `Orchestrator`/`OrchestratorState` - maps a named game state ("combat", "boss") to a
917
- `Music` track and crossfade, and fires one-shot cues by event name; re-entering the same
918
- state never restarts its track. `suspend`/`resume` silence and restore the music and
919
- every cue.
920
- - `AudioListener`/`SoundSource`/`AudioFalloff` - positional audio: a listener the game moves,
921
- a `Sound` placed at a point, and `audioGain`/`audioPan` turning distance and heading into a
922
- volume and a stereo position. `SoundSource.playFor` applies the distance gain through
923
- `Sound.play`; panning is reported for a backend that has a panner. `Music` stays global.
924
- - `XpbdWorld` (`@datamoc/mw_games/physics/xpbd`) - a deterministic structure solver
925
- (extended position-based dynamics): `addNode`/`addLink` (stiffness, `tensionOnly` cables, `strength`/
926
- `tensionStrength`), `applyForce`, `step()` on fixed substeps, the load of every link read back
927
- (`force`, smoothed `ratio`, `peakRatio`) and `onBreak` when a link passes its strength; `ground` (a height or a function of x) holds nodes
928
- on a surface with `groundFriction`. The engine of
929
- Pontifex, generalised: bridges, trusses, cranes, anything where the question is which beam fails.
930
- `XpbdWorld<T>`/`XpbdLink<T>`/`XpbdLinkSpec<T>` carry game-owned link `data` without
931
- affecting the solver. `breakLink(index)` dispatches rupture once. `linksInBox` includes
932
- segment crossings; `linksNear` orders nearby unbroken segments by distance. `snapshot()`
933
- returns positions, velocities, load state and queued forces as detached arrays; `hash()`
934
- compares their exact numeric bits for runs with the same configuration. Payloads and ground
935
- callbacks are excluded. The bridge example applies a moving vehicle's weight with `applyForce`.
936
- - `PhysicsWorld` (`@datamoc/mw_games/physics`) - rigid bodies and constraints in plain TypeScript, no engine
937
- dependency: `addBox`/`addCircle`/`addConstraint`/`remove`, `update(dt)` from
938
- `Scene.update`, `onContact`, `alpha` for interpolation. A constraint with `maxStretch` breaks when pulled
939
- that far past its rest length (`onBreak`, `stretchOf`). Bodies never spin; `angle` is a display offset.
940
- - `synthesizeTone`/`synthesizeSound`/`playTone`/`Waveform` - a runtime square/triangle/sine/noise/sawtooth
941
- waveform synth for a procedural tone or SFX, no sample library; `synthesizeSound` returns a
942
- pooled `Sound` over the tone.
943
- - `parseMidi`/`scheduleMidi`/`midiLoopStart`/`noteToFrequency`/`MidiPlayer` - a small `.mid` file player
944
- built on `synthesizeTone` rather than a licensed instrument library: program, bank,
945
- controller and pitch-bend events plus the controller-111 loop start, with each
946
- scheduled note carrying its channel voice. `MidiPlayer.create(file, { humanize })`
947
- humanizes first and then schedules, for the same player with a performance behind it.
948
- - `renderMidiToBuffer` - renders a parsed `.mid` file to stereo PCM frames, offline and
949
- deterministic: browsers cannot decode MIDI, so the file is synthesized once and plays
950
- back like any decoded track, with its controller-111 loop region. An optional game-supplied
951
- `SoundFont` voices real samples; without one the built-in waveform synth plays.
952
- - `renderMidiToBufferAsync` - the same render as raw MIDI bytes, run on a worker thread so
953
- the seconds a real track costs (2 to 11.8) do not freeze the loading screen. Parse,
954
- schedule and voice lookup stay on the caller's thread; the stereo buffers come back
955
- transferred rather than copied, and the result is bit-identical to the synchronous
956
- render because both call the same function. `soundFontBytes` takes raw SoundFont 2 data.
957
- - `parseSoundFont` - reads SoundFont 2 bytes into layered preset voices (key and velocity
958
- ranges, tuning, loops, envelopes, pan, attenuation); the font file itself stays the
959
- game's to ship and to license. A SoundFont 3 (Ogg Vorbis samples) is refused by name
960
- rather than read as noise: `loadSoundFont` reads either kind.
961
- - `loadSoundFont` - reads a SoundFont 2 or 3 into layered preset voices: a plain font goes
962
- straight to `parseSoundFont`, a SoundFont 3 is decoded first, through
963
- `webAudioSampleDecoder()` in a browser unless `{ decode }` names another decoder. It
964
- is what a game calls on the bytes it ships, whichever kind they are.
965
- - `decodeSoundFont` - a SoundFont 3 as plain SoundFont 2 bytes: every sample a preset reaches
966
- goes through the decoder once (an unreachable one never does), and the loop points a
967
- SoundFont 3 states relative to its sample become the absolute ones SoundFont 2 uses. A
968
- SoundFont 2 comes back unchanged. The result feeds anything that takes SoundFont 2 bytes,
969
- `renderMidiToBufferAsync` included.
970
- - `webAudioSampleDecoder`/`SoundFontSampleDecoder` - the decoder contract (Ogg bytes and the
971
- sample's own rate in, mono 16-bit frames out, synchronous or not) and the browser
972
- implementation of it over `decodeAudioData`: each sample decodes in a context created at its
973
- own rate, so the browser never resamples it. A Node tool passes a decoder of its own.
974
- - `collectSoundFontUsage` - lists the (bank, program) pairs scheduled notes actually
975
- request across MIDI files, drums as bank 128, for the compile step to keep.
976
- - `missingSoundFontPrograms` - the pairs of a usage list a font does not carry (the bank 0
977
- fallback counts as carried, a drum kit needs that exact kit), on a SoundFont 2 or 3. The
978
- build runs it for you: each embedded font's result lists its `missing` programs and
979
- `mwg-emit` warns.
980
- - `mergeSoundFonts` - joins several SoundFont 2 files (or several SoundFont 3 files, the
981
- Ogg bytes copied untouched) into one, presets in the order given and the first font winning
982
- a shared (bank, program), which is how single-instrument files (the per-program collection
983
- `mwg-soundfonts fetch` reads) become the one file a game ships.
984
- - `subsetSoundFont` - writes a smaller valid SoundFont 2 (or 3) file carrying only the used
985
- programs, zones and samples copied verbatim and indexes remapped, so a game ships
986
- megabytes instead of tens of megabytes with identical voices. The build does this
987
- on its own: `compileResources` (and so `emitPage` and `mwgPage`) embeds `.mid`,
988
- `.sf2` and `.sf3` assets, and subsets every embedded SoundFont to the programs the embedded
989
- MIDI files use. `soundFont: false` embeds the font whole, `soundFontUsage` names
990
- the programs explicitly, and with no shipped MIDI the font embeds whole because
991
- the usage is unknowable. The reference bank in `data/microgm-opt.sf2` (2.6 MB,
992
- WTFPL, shipped in the npm package for a game to copy into its assets) drops to
993
- tens of kilobytes per game this way: measured, piano and drums come to 264 KB, eight
994
- essential programs (piano, guitar, bass, strings, brass, flute, synth lead, drums) to 421 KB,
995
- sixteen to 585 KB. A program the font lacks plays the font's own piano (preset 0:0) and,
996
- only when it has no piano either, the built-in synthesizer; `parseSoundFont(data, { missingProgram:
997
- 'synth' })` (also on `loadSoundFont` and `renderMidiToBufferAsync`) hands those instruments to
998
- the synthesizer instead of a piano line, and a bank missing the program or a drum kit still falls
999
- back to bank 0 or the standard kit, never to a melodic preset. It is the default bank. A game that wants another
1000
- picks it from `data/soundfont-catalog.json` and fetches just its instruments with
1001
- `mwg-soundfonts` (see [tools.md](tools.md)). A SoundFont 3 stays compressed all the way to
1002
- the page (FluidR3's piano, guitar and drums: 2.7 MB, against 20 MB decoded to a SoundFont 2),
1003
- and `loadSoundFont` decodes it at load, so prefer it over a SoundFont 2 for anything but the
1004
- smallest banks.
1005
- - `createAudioLoader`/`AudioLoaderOptions` - a cached loader for embedded audio and MIDI,
1006
- shared by all `AudioBus` lifetimes. MIDI is detected by header and rendered on a worker;
1007
- other files use `decodeAudioData`. Options select SoundFont/render settings or a byte source.
1008
- `AudioBus` uses this loader by default, so `playBgm` and `playSe` accept asset paths with
1009
- the same volume, pitch and pan fields. BGM/BGS loop; ME/SE play once.
1010
- - `MusicPlayer`/`MusicPlayerOptions`/`MusicPlayOptions` - one loaded `AudioBuffer` or
1011
- `RenderedMidi`, with play, pause, resume, seek, position, volume and an `onEnded` signal.
1012
- Call `update()` each frame to dispatch track completion and choose the next track.
1013
- `toAudioBuffer(context, rendered)` copies rendered stereo samples into an `AudioBuffer`.
1014
- - `Channel`/`AudioBus` - buffered WebAudio music: a `Channel` plays one looping track with
1015
- volume, pitch, pan, a loop region and a seekable playhead, and an `AudioBus` wires two of
1016
- them into independent BGM/BGS loops, ME jingles that suspend and resume the BGM,
1017
- overlapping SE one-shots, save and replay with playheads, and plain-data snapshots.
1018
- `AudioBus.setMixer(kind, { volume, muted })` scales a whole kind on top of each track's
1019
- own volume, without changing what snapshots report.
1020
- - `MidiSynth`/`MidiSynthFactory`/`MidiSynthRequest` + `registerMidiSynth`, `unregisterMidiSynth`,
1021
- `midiSynthNames`, `resolveMidiSynth`, `renderMidiThroughSynth`, `renderMidiStems`,
1022
- `onMidiSynthFallback` and `INTERNAL_MIDI_ENGINES` - the named-engine contract for MIDI:
1023
- a package registers a synth under a name (`retro:mt32`), content asks for it by name, and
1024
- resolution walks the request, then the internal names (`gm-soundfont`, `builtin`), firing
1025
- `onMidiSynthFallback` whenever another engine voices the file instead. `timedMidiMessages`
1026
- is the raw timed message stream a synth is driven by.
1027
- - `StreamPlayable`/`StreamChannel` - the streaming half of the `Playable` contract: seek and
1028
- `currentTime` on a synthesised stream, `playbackRate` by resampling, and a playhead counted
1029
- in frames, so endless formats (NSF, SID) play without a whole-track render.
1030
- - `TrackCache`/`createBudgetedLoader`/`BusBudgetPolicy` + `bufferBytes` - bus render budgets:
1031
- an LRU cache of decoded tracks under a megabyte and entry cap, with `maxSeconds`, mono or
1032
- half-rate rendering for ambience through `fitToBudget` and `resampleStereo`.
1033
- - `DEFAULT_DECODER_LIMITS`/`decoderLimits`/`DecodeBudgetError`/`InstructionBudget` +
1034
- `assertInputSize`, `guardBlockSource` and `inflateBounded` - the decoder guards for
1035
- untrusted retro formats: input and inflate ceilings, an instruction budget per second of
1036
- sound, and one named error per breach instead of a hang.
1037
- - `SfxBank`/`SfxSound`/`SfxArbiter` + `sfxSeed` - data sound effects: synthesised chip
1038
- effects with a deterministic seed, arbitrated against the `se` bus by priority, firing
1039
- captions like a file effect.
1040
- - `AudioSettings`/`AudioSettingsData`/`AudioRegion`/`OutputStage` + `regionPlaybackRate`,
1041
- `softenCutoff` and `dynamicsLimit` - the player-facing audio settings in one plain-data
1042
- object: volume per bus (applied to an `AudioBus` by `applyToBus`), the preferred MIDI
1043
- engine name, PAL or NTSC region (a tune authored for one runs slower or faster on the
1044
- other, `regionPlaybackRate`), a faithful or clean output stage, caption display, a
1045
- dynamics control (a soft limiter, `dynamicsLimit`) and bright-sound softening (a falling
1046
- low-pass cutoff, `softenCutoff`). A CPU and underrun indicator reads `AudioCoreHost`'s
1047
- stats and `onAudioUnderrun`.
1048
- - `waveformEnvelope`/`channelEnvelopes`/`WaveformBucket` and
1049
- `trackerPattern`/`trackerNoteName`/`TrackerRow` - the data cores of the audio views: a
1050
- waveform as per-bucket min/max pairs per channel (what an oscilloscope draws), and a
1051
- MIDI file as tracker rows, one column per channel on the file's own tick grid. A game
1052
- draws them with its own widgets; the reduction and the grid live here and are tested as
1053
- arithmetic.
1054
- - `SyxBank`/`SyxPatch` + `splitSysex` and `dx7PatchNames` - a `.syx` bank a player drops:
1055
- its whole sysex messages, the patch names of every checksummed DX7 32-voice bulk dump in
1056
- it (another maker's bank names nothing rather than guessing), and an `audition` that
1057
- loads a patch into a `MidiSynth` and renders one note through it for a settings screen.
1058
- - `connectWebMidi`/`requestWebMidiInput`/`WebMidiConnection` - live Web MIDI into a
1059
- `MidiSynth`: every input port of a `MIDIAccess` is wired to the synth (channel messages
1060
- to `event`, sysex to `sysex`, transport dropped), and `requestWebMidiInput` is the
1061
- browser entry that returns null where Web MIDI does not exist or was refused.
1062
- - `AdaptiveMusic` - adaptive tracks: mute and unmute stems of a running track with a fade,
1063
- and switch between two versions at the same frame position; `loopRegionFromFile` reads
1064
- the loop region a file declares as the default.
1065
- - `AudioCoreHost` + `onAudioUnderrun` - the off-main-thread audio host: a synthesis core in
1066
- a worker behind the same `Playable` facade, with a main-thread fallback and an underrun
1067
- signal feeding bounded telemetry.
1068
- - `encodeWav`/`decodeWav`/`wavInfo` and `spectralDistance` - WAVE as plain bytes (the
1069
- `mwg-audio` tool's convert and compare verbs over the same code), and a spectral distance
1070
- between two renders for a listening check that can be automated.
1071
- - `parseVorbisLoopTags`/`loopRegionFromTags` - read the `LOOPSTART`/`LOOPLENGTH` comments an
1072
- Ogg Vorbis file carries (a bounded walk of the first pages, null on anything malformed) and
1073
- turn them into the seconds-based `LoopRegion` a `Channel` or the bus loader hands back.
1074
- - `humanizeMidi`/`HumanizerFactory`/`HumanizeRequest`/`MidiHumanizerEngine` - the entry point
1075
- for a performance that sounds played rather than played back. `humanizeMidi(file, options)`
1076
- resolves the tier from the request (a `GrooveTemplate` in it means the groove tier, anything
1077
- else the lite one) and returns a new file; `HumanizerFactory.create(tier)` is for holding one
1078
- engine across several files. The pass never mutates its input: `intensity: 0` reproduces the
1079
- file exactly, a `seed` reproduces a run, note durations and every tempo, program, controller
1080
- and meta event survive, events come back sorted by tick with ties in file order, and nothing
1081
- lands before tick 0 (a shift that would cross it stops there instead). `create('magenta')`
1082
- throws naming what is missing rather than loading: `@magenta/music` and a PerformanceRNN
1083
- checkpoint cannot be fetched from a `file://` build.
1084
- - `LiteHumanizer`/`GrooveHumanizer`/`HumanizationOptions`/`HumanizeStyle`/`HumanizerTier` - the
1085
- two shipped engines and their options. Tier 1 moves timing and velocity by gaussian noise
1086
- over a seeded gradient drift, scaled by `intensity` and by `style` (jazz wide, classical
1087
- tight), and holds the kick and the lowest notes to a few milliseconds of their slot; tier 2
1088
- applies a template's per-slot offsets and velocities instead, converted through the file's
1089
- own tempo map when the template was recorded at another tempo (which says so through
1090
- `onWarn` rather than staying quiet), plus contextual rules - an accent on a local melody
1091
- peak, restraint on the beat. `initialize()` is idempotent on both.
1092
- - `subdivisionCount`/`assertGrooveTemplate`/`GrooveTemplate`/`GridSubdivision`/`GrooveOffset` -
1093
- the units everything else is measured in: how many slots a bar of a signature holds at a
1094
- grid (`subdivisionCount([4, 4], '16n')` is 16, `[6, 8]` at `8n` is 6, and a grid that does
1095
- not tile the bar throws), and the validator for a template's invariants - dense offsets in
1096
- subdivision order, whole ticks, a power-of-two denominator, a velocity factor between 0 and
1097
- 1 - run when one is built and when one is imported.
1098
- - `GrooveExtractor` - a reusable template out of three kinds of evidence, each reduced to the
1099
- same thing: the median of each slot's deviations, so one flubbed note cannot drag it and a
1100
- slot nobody played stays on the grid. Mode A matches a played pass against a straight one,
1101
- note-on to nearest note-on of the same channel and pitch within half a slot; mode B projects
1102
- a single file onto its own implied grid, which is exactly the residual a quantization would
1103
- discard; mode C takes an `AudioBuffer`, detecting attacks by spectral flux (hand-rolled FFT,
1104
- no analysis dependency) and taking the tempo as an argument because timing means nothing
1105
- without one, with velocity left at the neutral 1 since a recording carries none.
1106
- - `GrooveConverter` - a template to and from the two formats that can carry one. JSON is
1107
- exact; the MIDI encoding is one note per slot behind an anchor a subdivision ahead, with
1108
- velocity at 1/64 per unit of `velocityFactor`, so the writer enforces `|offset|` below the
1109
- slot and a factor of 1/64 to 127/64 instead of rounding past them, and the file gets its own
1110
- reader because the round trip needs the tempo, time-signature and name metas that `parseMidi`
1111
- deliberately drops. `GrooveFormat` also names `ableton-agr` and `reaper-groove`, both of
1112
- which throw saying they are not shipped rather than returning a file that resembles one.
1113
-
1114
- ## `battle`
1115
-
1116
- The Pokémon-shaped half of the capability spec: species/stats/party/type-matrix/turn-order.
1117
- No move, formula, or number belongs here - only the shape.
1118
-
1119
- - `Creature`/`Species` - wraps `actors.StatBlock`/`Progression`, not a separate stat system.
1120
- - `TypeMatrix` - attack-type effectiveness lookup.
1121
- - `Party` - a roster of creatures.
1122
- - `battleOrder`/`Move`/`BattleAction` - one round's priority-then-speed turn order.
1123
- - `checkEvolution`/`EvolutionRule` - level/condition-based species evolution.
1124
- - `StatStages` - a bounded, symmetric stage ladder over a stat (±`max`), replacing rather
1125
- than stacking the modifier for a stat's current stage.
1126
- - `chooseMove`/`chooseSwitch` - battle AI built on `TypeMatrix`.
1127
- - `BattleHooks`/`BattleHook` - `core.HookRegistry` with battle's argument shape: a handler
1128
- receives the creature plus a shared mutable `context`, for passive effects, abilities and
1129
- turn-skipping statuses.
1130
- - `Field`/`FieldCondition` - field-wide conditions: weather, terrain, screens; named,
1131
- optionally timed, ticked down by `advance(rounds)`.
1132
- - `AttackPreview`/`AttackPreviewOptions`/`AttackFrame`/`PreviewCombatant` - the damage totals and
1133
- one-frame-per-strike timeline an attack dialog prints and animates, from damage the game's own
1134
- formula produced (`totalDamage`, chance-weighted `expectedDamage`, `hits` for a rolled outcome,
1135
- `sampleAt` on the animation clock). It computes no damage itself.
1136
- - `AttackDialog`/`AttackDialogOptions`/`StrikeNumbers` - the dialog's whole renderer-free state: a
1137
- `UnitSelector` to choose the pair, the `AttackPreview` built from a game-supplied `damageFor`, and
1138
- the `update(dt)`/`finished` clock that drives the animation.
1139
- - `UnitSelector`/`UnitSelectorOptions`/`SelectableUnit`/`SelectorStage` - the two-step attack
1140
- selector: enabled units on the selecting side as candidates, then the enemies `canTarget` allows
1141
- as targets; `back` undoes the attacker choice.
1142
- - `Whiteboard`/`WhiteboardEntry` - planned turn orders with one plan per unit, `undo`/`redo` (a new
1143
- plan clears the redo stack) and `commit` handing the plans back.
1144
- - `BattleStats`/`BattleStatCategory` (item 273) - a per-run breakdown by category (`recruits`,
1145
- `recalls`, `advances`, `kills`, `deaths`, `damageDealt`, `damageTaken`) and unit type, the shape
1146
- `core.PlayerStats`'s opaque `T` cannot give a game for free; `record` adds to one unit type's
1147
- count, `total`/`breakdown` read a category back summed or per type, and `toJSON` folds into a
1148
- `core.RunHistory` entry or `core.PlayerStats` total like any other run summary.
1149
-
1150
- ## `board`
1151
-
1152
- Board/card/dice games and generic tactics - traditional public-domain rules, no formula
1153
- borrowed from any licensed game.
1154
-
1155
- - **chess** (`chess.ts`): `startingChess`/`parseFen`/`positionKey`/`cloneChess`/`legalMoves`/
1156
- `applyMove`/`inCheck`/`gameResult`/`sq`/`squareName` - full rules: legality, check/mate/
1157
- stalemate, castling, en passant, promotion, FEN in both directions (positions keyed
1158
- without clocks).
1159
- - **engine** (`Engine.ts`): `chessGame`/`chooseMove`/`search` - the chess rules adapter and
1160
- convenience wrapper over the shared `ai.alphaBetaSearch`, with material evaluation and
1161
- depth/node limits. `searchAsync` scores each root move on a worker thread and combines
1162
- the scores first-wins, so a depth-3 search stops dropping frames; inside the node
1163
- budget it chooses exactly the move `search` would. The minigame path keeps this small search and never pays for the tournament module below. `searchAsync` combines root-move scores first-wins.
1164
-
1165
- - **bitboards** (`bitboard.ts`): the same rules on twelve 64-bit boards
1166
- (`startingBitboard`, `bitboardFromChess`, `bitboardMoves`, `makeMove`/`unmakeMove`,
1167
- `perft`), the mutable board the tournament engine searches. `bitboardFromChess`
1168
- bridges from a `chess.ts` position; the differential tests keep both rule sets in
1169
- agreement.
1170
- - **openings** (`openings.ts`): `probeBook` looks a position up in a compiled opening
1171
- book (ECO, name where a known line ends, UCI continuations), `parseUciMove` reads a
1172
- UCI move back. The book is a game-side artifact built by `tools/compile-openings`
1173
- from vendored CC0 tables, so no table ships with the framework.
1174
- - **tourney** (`tourney.ts`): `searchTourney`/`searchTourneyAsync` over one
1175
- self-contained `tourneyThink` task, so the worker side cannot diverge from the
1176
- main-thread side: negamax alpha-beta with principal variation search, null-move
1177
- pruning, late-move reductions, iterative deepening with aspiration windows, a bounded
1178
- Zobrist transposition table, quiescence over captures and promotions, hash/MVV-LVA/
1179
- killer/history ordering, and classical material plus in-house piece-square evaluation.
1180
- Positions are plain bitboard data and structured-clone straight into workers.
1181
- `TourneyResult.rootScores` is populated by an async search with legal root moves and
1182
- scores from the mover's view, in root order, for near-best selection without a
1183
- second search. The
1184
- chess example plays its reply through `searchTourneyAsync`, with a thinking indicator,
1185
- a per-move time cap, side and depth choice, a promotion picker and an in-check
1186
- highlight.
1187
- - **tablebase** (`tablebase.ts`): `probeTablebase`/`loadTablebaseEnding`/`tablebaseId`
1188
- plus the `huffEncode`/`huffDecode` codec - WDL outcomes with distance-to-mate for
1189
- pawnless white-extras-against-lone-king endings, fifty-move-adjudicated against an
1190
- explicit halfmove clock, generated and verified by `tools/build-tablebases` and
1191
- shipped compiled under `data/tablebases` (3-piece; 4-piece stays a tool run away,
1192
- full 4-piece tables are tens of megabytes each).
1193
- - **classics** (`Classics.ts`): `BoardGrid`; checkers
1194
- (`startingCheckers`/`checkersMoves`/`applyCheckersMove`, forced multi-jump captures); go
1195
- (`startingGo`/`playGo`/`passGo`/`goResult`/`goScore`, ko and area scoring); backgammon
1196
- (`startingBackgammon`/`rollBackgammonDice`/`backgammonMoves`/`applyBackgammonMove`, bar
1197
- and bearing off); cards (`createDeck`/`shuffleDeck`/`deal`/`trickWinner`); solitaire
1198
- (`dealSolitaire`/`drawSolitaire`/`moveSolitaireTableau`/`moveSolitaireToFoundation`/
1199
- `solitaireWon`, seeded Klondike); dice (`rollDice`/`rollExpression`/`DiceCup`/`scoreDice`,
1200
- Yahtzee-shaped keep-and-reroll scoring).
1201
- - **tactics** (`Tactics.ts`): `startingTactics`/`addTacticalUnit`/`canPlaceTacticalUnit`/
1202
- `tacticalMoves`/`moveTacticalUnit`/`setTacticalOverwatch`/`triggerTacticalOverwatch`/
1203
- `tacticalAttack`/`endTacticalTurn` - squad tactics: action points, cover, overwatch, and
1204
- zone of control baked into `tacticalMoves`/move cost.
1205
- - `FactionFog`/`VisionCell` - fog of war as a per-faction union of every controlled unit's
1206
- own vision, with explored memory retained. `share` puts factions on one map, sight and memory
1207
- alike, which is Wesnoth's `share_vision`; nothing shares until asked. `sees` hands a side's sight
1208
- out as a predicate for anything that asks what it can see.
1209
- - **army** (`Army.ts`): `startingArmy`/`recruit`/`recall`/`bankUnit`/`armyIncome`/
1210
- `applyUpkeep` - recruiting/recalling units against a currency total, per-turn income and
1211
- upkeep, no specific rate baked in.
1212
- - **hex skirmish** (`HexSkirmish.ts`): `startingSkirmish`/`setSkirmishTerrain`/
1213
- `canPlaceSkirmishUnit`/`addSkirmishUnit`/`skirmishMoves`/`moveSkirmishUnit`/
1214
- `skirmishAttack`/`skirmishIncome`/`endSkirmishTurn` - a Wesnoth-style hex army-game rules
1215
- layer distinct from `tactics` above: per-terrain movement cost and defence, adjacency-only
1216
- attacks where a surviving defender always strikes back, capturable villages that grant
1217
- income and heal whoever owns them, no zone of control.
1218
- - `BoardPiece` (type, from `Classics.ts`) - a generic owned/countable/capturable/promotable
1219
- token distinct from `roguelike`'s `Creature`-shaped actors; every game above builds on it.
1220
-
1221
- ## `actors`
1222
-
1223
- Stat blocks, equipment, inventory, and the numbers layer nearly every other module builds
1224
- on. This is the *shape* - a game names its own attributes and formulas.
1225
-
1226
- - `StatBlock`/`Modifier`/`DerivedStat` - base attributes plus derived stats, combined
1227
- through ordered modifiers (add → multiply → set). `toJSON` saves base values only:
1228
- modifiers are reapplied on load by whatever owns them (equipment, status effects, auras),
1229
- so saving them too would double every bonus.
1230
- - `composeModifiers` - the same canonical modifier composition as `StatBlock`, available to
1231
- adapters that resolve declarative effect lists without creating a stat block.
1232
- - `Progression`/`powerCurve` - levelling from experience against a growth curve; `toJSON`
1233
- saves level and experience, the curve being a definition.
1234
- - `skillCheck` - value-plus-modifiers against a difficulty, one dice roll.
1235
- - `SkillPoints` - a spendable ledger that raises a stat's base rank, with per-stat caps and
1236
- a rising cost per rank. `toJSON` saves only unspent points; the ranks bought are already
1237
- in the `StatBlock`'s own base values.
1238
- - `EquipmentSlots`/`EquippableItem`/`SavedEquipment` - equip/unequip applies or removes an
1239
- item's modifiers immediately; an optional `locked` predicate refuses unequip/swap for
1240
- cursed/quest gear. `toJSON(identify)` records slot-to-id, and `fromJSON` re-equips so every
1241
- modifier lands back on the `StatBlock`; a locked item is restored still worn.
1242
- - `Inventory`/`InventoryItem`/`ItemDefinition`/`SavedInventory` - stacking (by id, and by
1243
- `instanceId` when either item sets one), weight, capacity, containers holding their own
1244
- `Inventory`. `toJSON` saves per-item instance state (level, wear, affix, identified,
1245
- `instanceId`) while `fromJSON(defs, data)` takes kind-level fields from the game's item
1246
- table, so a rebalanced weight reaches an old save.
1247
- - `craft`/`Recipe`/`Ingredient` - resolves a recipe against an `Inventory`: all-or-nothing, with a
1248
- capacity-rollback path if the result doesn't fit. An ingredient may match an exact `id` (or a
1249
- list of them), a `category` on the item's definition ("any herb"), or a `matches` predicate; the
1250
- allocation is made against a working copy so two flexible ingredients cannot count one stack
1251
- twice. `InventoryItem.category`/`ItemDefinition` carry the kind-level grouping (supplied by the
1252
- game on load, like `stackable` and `weight`).
1253
- - `applyStatusEffect`/`EffectClock`/`StatusEffectHandle` - a `StatBlock` modifier tied to a
1254
- `TurnClock`'s automatic expiry; `cancel()` for early removal.
1255
- - `identify`/`enchant`/`damageItem`/`repairItem` - identification; enchant/upgrade level
1256
- (`enchant`'s `affixPolicy: 'keep' | 'remove'` decides whether an upgrade strips an
1257
- affix); durability wear and repair, opt-in per item.
1258
- - `applyItemStatusEffect` - a status effect sourced from an item rather than a spell.
1259
- - `Charges`/`ChargesOptions` - a resource regenerating in banked-turn chunks via
1260
- `advance(turns)`; `refund()` restores charges directly (a kill or crit), outside that path.
1261
- `toJSON` saves the count *and* the progress banked towards the next, so reloading cannot
1262
- shorten a recharge.
1263
- - `rollLoot`/`LootEntry`/`LootTable` - rolls whether anything drops, then weight-picks
1264
- which, the same "roll whether, then which" shape `world.rollEncounter` shares.
1265
- - `Advancement` - level-gated tiers granting ledger points, with mutually-exclusive
1266
- branch/capstone choices.
1267
- - `rollAffix`/`affixOf`/`applyAffix`/`removeAffix`/`copyAffix`/`matchesContext` - named
1268
- item affixes: weight-picked, applied/removed on `InventoryItem.affix`, copied between
1269
- item instances, and matched against a fired trigger's attack `kind` via `AffixDef.kinds`.
1270
- - `scaledModifiers`/`LevelScale` - level-scaled gear: `{stat, op, base, perLevel}` resolved
1271
- to a plain `Modifier`.
1272
- - `assignAppearances`/`Appearances` - per-run appearance shuffling for unidentified items,
1273
- seeded and fixed for the run.
1274
- - `buy`/`sell`/`Price`/`ShopOptions` - a currency-`StatBlock` transaction against an
1275
- `Inventory`, all-or-nothing with rollback.
1276
- - `canAfford`/`spend`/`refund`/`convertToCharges`/`ResourceCost` - a spendable `StatBlock`
1277
- pool (mana, stamina): check, all-or-nothing spend, mirror-image refund (optionally
1278
- fractional), or convert a spent amount into `Charges` at a rate.
1279
- - `Barrier`/`BarrierLayer` - a layered shield/absorption pool; the most recently added
1280
- layer drains first, with optional independent per-layer decay ticked by `advance(turns)`.
1281
- - `assignTraits`/`TraitDef`/`AssignedTrait` - per-instance random traits drawn from a
1282
- shared pool at creation, applied as permanent modifiers.
1283
- - `AuraField`/`AuraDef`/`AuraParticipant` - continuously reapplies a carrier's modifiers to
1284
- whoever is currently adjacent, diffing rather than reapplying every tick.
1285
- - `SupportLedger` - a pair-order-independent, thresholded bond/support relationship between
1286
- two units, growing through proximity or shared battles; `toJSON`/`fromJSON` round-trip it.
1287
- - `buildEntity`/`buildEntities`/`EntityTemplateRow`/`EntityTemplateCatalog`/`BuiltEntity` - one
1288
- row of a hero or monster file (typically a `core.parseCSV` result) into a fully wired
1289
- entity: a `StatBlock` of base stats (every non-reserved column), an optional `Progression`
1290
- against a named growth curve, a starting item carrying a named starting affix, and a
1291
- `ReactionTable` already holding a low-HP rule if the row names a threshold. What each named
1292
- growth curve/affix/item actually is stays the game's own `EntityTemplateCatalog`.
1293
- - `toEntitySaveState`/`fromEntitySaveState`/`EntitySaveState` - a `BuiltEntity`'s mutable state
1294
- (base stat values, level/experience, the carried item) in the same "definitions supplied
1295
- fresh on load" shape `StatBlock`/`Progression` already draw. `fromEntitySaveState` rebuilds
1296
- via `buildEntity` from the same row and catalog, then overlays the saved state on top.
1297
-
1298
- ## `roguelike`
1299
-
1300
- FOV, pathfinding, the energy scheduler, level generation, and combat-adjacent primitives -
1301
- the dungeon-crawl half of the capability spec.
1302
-
1303
- - `Level`/`WALL`/`FLOOR`/`rectCenter`/`rectsOverlap` - the tile grid: terrain kinds,
1304
- passability/transparency, square or hex `shape`.
1305
- - `generateDungeon`/`findFreeCell`/`furthestRoom`/`DUNGEON_KINDS` - procedural dungeon
1306
- generation.
1307
- - `generateDungeonGraph` - the same pipeline as `generateDungeon`, also returning the room
1308
- graph (corridor edges, backbone then extra loops) and a rejected-placement retry count;
1309
- `DungeonOptions.hooks` fires `onRoomPlaced`/`onCorridorCarved` as the pipeline runs, the
1310
- seam a regional generator hangs hand-placed rooms, branches, wells, plants, statues,
1311
- chasms, doors and traps from.
1312
- - `generateCave` (item 407) - the cave counterpart: chambers grown as random blobs
1313
- (`jagged` the chance a growth step wanders), passages as biased random walks
1314
- (`windiness`, `width`, `chance`), starts on chamber centres with cleared rings,
1315
- `villageDensity` returning picked clear cells as data, and a forced join so a cave is
1316
- always connected whatever the rolls did. Seeded through the `Random` stack like the
1317
- dungeon.
1318
- - `generateOverworld` (item 410) - a whole realm as plain tile data: seeded elevation and
1319
- moisture fields classify water, plains, forest, hills, mountains, desert and swamp behind
1320
- a `seaLevel` knob; rivers run downhill to the sea, merging when they meet, drowning a
1321
- lake at a ridge instead of crossing it; settlements place themselves by suitability
1322
- (buildable ground, water within reach, spaced apart) and join into a road tree that
1323
- prefers flat ground, water a ford rather than a wall; points of interest carry a
1324
- `leadsTo` id for `Overworld` locations, and every cell carries a coarse region id for
1325
- encounter tables. The realm invents itself from the seed: no reference game's map data.
1326
- - `shape: 'hex'` on `generateDungeon`, `generateDungeonGraph`, `generateCave` and
1327
- `generateOverworld` lays the same generator out on a hex grid (odd-q offsets, the `Level`
1328
- convention): the dungeon and cave `Level` carry the hex shape, a dungeon corridor leg runs
1329
- as a hex line, a cave grows its chambers by hex distance and walks passages toward their
1330
- target in true on-screen distance, and the overworld samples its noise where each hex is
1331
- drawn and steps rivers and roads across the six edges. The default stays square, byte for
1332
- byte. `generateCave` also takes `random` (a `RandomSource`, such as a `Generator`) in place
1333
- of `seed`: it draws from, and advances, that stream, leaving the ambient `Random` stack
1334
- untouched.
1335
- - `RoomBuilder`/`hallBuilder`/`eligibleBuilders`/`pickBuilder` - composable room interiors:
1336
- the generator places and joins rooms, a builder carves each one, picked by weight among
1337
- those whose size constraints fit. `DungeonOptions.builders` wires them in; a room no
1338
- builder fits falls back to a plain hall rather than staying solid rock.
1339
- - `FeatureLayer` - a floor feature/event layer: named kinds with `inspect`/`interact`/
1340
- `consequence`/`persistent` rules attached to generated cells; definitions supplied fresh
1341
- on load, only cell-to-kind pairs are save data.
1342
- - `rollRoster` - a variant-spawn/content-roll API: weighted regular entries, rare additions,
1343
- per-entry alternative swaps, and a shuffle, in that order; every roll (including an
1344
- explicitly disabled rare entry's non-roll) is traced for parity tests.
1345
- - `candidateCells`/`cellsNear`/`selectDistinctCells` - deterministic content placement over a
1346
- `Level`: `candidateCells` filters by terrain kind, occupancy and an optional region;
1347
- `cellsNear` walks outward by radius for a cluster anchor; `selectDistinctCells` shuffles and
1348
- slices a de-duplicated pool, bounded to however many candidates exist rather than throwing.
1349
- Composes for neighbouring-item clusters, scattered decorations, and single room/branch
1350
- rewards; nothing is placed until the caller commits, and the returned trace is plain
1351
- JSON-safe data for `DungeonArtifacts.content` or a save file.
1352
- - `compareDungeonArtifacts`/`checkDeterminism` - a dungeon parity/test harness: diffs a
1353
- seeded run's room graph, retries, terrain, features and content rolls against a reference
1354
- or golden fixture, tagging every mismatch `'graph'` or `'paint'`; `checkDeterminism` repeats
1355
- a generation call and confirms every run matches the first.
1356
- - `FieldOfView`/`HeightSight` - shadowcast (square) or straight-line (hex) visibility, with
1357
- `Elevation`-aware asymmetric cliff sight.
1358
- - `Elevation` - whole-level height per cell, read by `FieldOfView`/`Pathfinder`.
1359
- - `Pathfinder`/`neighbourOffsets` - A*(square)/Dijkstra(hex or elevation-aware) pathing,
1360
- `distanceMap`/`descend`/`autoExplore`, an optional climb limit.
1361
- - `Scheduler`/`Actor`/`SchedulerSnapshot` - energy-cost turn order, the sole authority on
1362
- logical time; fractional costs, `postpone` (delaying an actor other than the current one),
1363
- and `toJSON`/`restore` for a deterministic snapshot keyed by a caller-supplied actor id.
1364
- - `decideMonsterAI`/`AIState`/`AIDecision`/`Disposition` - wander/hunt/flee built on
1365
- `FieldOfView`/`Pathfinder`/`Scheduler`; peaceful/neutral/hostile disposition, provoked
1366
- override.
1367
- - `Secrets` - disguised terrain (secret doors, hidden traps) that passes every
1368
- passable/transparent check as its disguise until revealed.
1369
- - `Doors` - open/closed/locked door state; locking is independent of open/closed.
1370
- - `chebyshevDistance`/`traceLine`/`ballistica`/`hasLineOfSight`/`canTarget`/`resolveArea` -
1371
- targeting and collision paths: range/line-of-sight checks, configurable stopping cells,
1372
- and single/line/burst/cone area resolution.
1373
- - `TargetingController` - the input-facing half of targeting: a cursor moved by keyboard
1374
- (`move`) or by a caller-resolved pointer cell (`moveTo`), range and line-of-sight
1375
- validation with an optional game `validate` hook, a `preview` of the shape's cells, and a
1376
- `confirm`/`cancel` result. It returns cells only; the game keeps legality details, damage
1377
- and drawing.
1378
- - `coneCells`/`chainTargets`/`knockbackPath` - a widening cone spray, a greedy nearest-hop
1379
- chain, and a shove's path until the first impassable cell.
1380
- - `coneSector`/`ConeSectorOptions` - a circular sector aimed at an angle: rays cast every 0.5
1381
- degrees across an arc of `degrees`, each clamped to `range` and stopped by the first wall, so a
1382
- wall shadows what is behind it while the rest of the cone reaches. Unlike `coneCells`, the aim
1383
- is not snapped to one of the eight directions.
1384
- - `resolveAreaOnLevel`/`hexConeCells` - topology-aware area resolution and widening hex cones,
1385
- complementing the square-grid targeting helpers.
1386
- - `rangeMultiplier`/`areaFalloffMultiplier`/`RangeBand` - a range-band damage multiplier
1387
- lookup, and a per-target falloff multiplier for an area effect hitting several targets.
1388
- - `BossPhases`/`AbilityCycle` - an HP-fraction phase ladder whose `check(hpFraction)` reports
1389
- newly entered phases, and a named-cooldown ability rotation (`ready`/`use`/`advance`).
1390
- - `CombatHooks`/`CombatEvent`/`DamageContext` - `core.HookRegistry` with combat's argument
1391
- shape (one mutable `DamageContext`), plus `modifyDamage`'s pre-damage seam.
1392
- - `Stealth`/`StealthOptions` - sticky, one-way detection: `checkDetection` returns true
1393
- only on the call that first brings an observer within radius.
1394
- - `TriggerTracker` - a streak counter (combo, kill-streak) that extends within a turn
1395
- window and restarts once the window lapses.
1396
- - `MultiStageAbility`/`AbilityStage` - an ability that unfolds through named, turn-timed
1397
- stages (windup/active/recovery) once started.
1398
- - `Minimap`/`minimapCellCenter` - exploration minimap rendering and overlay coordinates for
1399
- square and odd-q hex maps.
1400
- - `MultiTurnBeam` - a deterministic one-front-per-turn beam. The default shape is a straight line;
1401
- `fronts` opts into a per-turn front resolver (cone, burst, fork, moving front), `blocker` is the
1402
- explicit terrain/`none`/custom policy with `isBlocked` as an extra game rule, `onCell` sees every
1403
- reached cell, and a save carries the shape name so a reload resumes the same one. Live target
1404
- lookup, game-owned damage application, cancellation and save/restore as before.
1405
- - `BeamBlocker`/`BeamStep`/`MultiTurnBeamSave` - the blocker policy, one turn's reached cells and
1406
- damage, and the serialisable front list with its shape identity.
1407
-
1408
- ## `rpg`
1409
-
1410
- Tiled map/event data, the map-event interpreter, switches/variables, and grid movement -
1411
- the classic top-down RPG half.
1412
-
1413
- - `automap`/`AutomapRule`/`AutomapTarget`/`AUTOMAP_EMPTY` - Tiled-style automapping:
1414
- `input`/`output` pattern rules applied in order, each rule's matches collected before any
1415
- write. Takes any grid exposing `getTile`/`setTile` (a `TileMap` satisfies it structurally),
1416
- so automapping needs no renderer.
1417
- - `GameState` - switches and variables.
1418
- - `activePage`/`conditionHolds`/`EventPage`/`MapEvent` - last-matching-page resolution for
1419
- a map event, re-checked rather than cached.
1420
- - `EventRunner`/`EventCommand`/`DialoguePresenter`/`DialogueRequest`/`EventChoice` - a
1421
- `StageScript`-shaped command interpreter for map events. Dialogue goes through an injected
1422
- `present` function rather than a widget, so the interpreter is renderer-free and a game can
1423
- drive it from a 3D scene, a DOM overlay, or a test asserting on script order.
1424
- `two-d/ui.messageBoxPresenter` is the ready-made 2D implementation. `DialogueRequest.portrait`
1425
- is an opaque, renderer-specific value (`Texture2D` for `messageBoxPresenter`), kept untyped
1426
- here so `rpg` stays renderer-free. `EventRunner.runStory`/`EventStoryScript` follow a named-
1427
- passage graph the same way `StageScript.runStory`/`StoryScript` do - a `goto` command, or a
1428
- choice's own `goto`, jumps to a different passage; a plain `run()` refuses a stray `goto`
1429
- rather than silently ignoring it, the same guard `StageScript.run` applies.
1430
- `EventRunnerOptions.onUnknownCommand` hears every command the runner has no handler for (and a
1431
- `goto` in a straight `run()`, which then ends the list instead of throwing), so a game converting
1432
- foreign event data can make every dropped command loud.
1433
- - `importTwee`/`EventTwineStory` - imports Twee-notation Twine stories into `EventStoryScript`,
1434
- a thin wrapper around `core.parseTwee` (the same engine `two-d/stage.importTwee` wraps for
1435
- `StageCommand`/`StoryScript` instead) naming the `EventStoryScript` return type, so a
1436
- text-only RPG can import a branching Twee story without depending on `two-d` for anything.
1437
- - `GridMover`/`Direction4` - tweened tile-to-tile movement plus a walk-cycle hook.
1438
- `GridMover.jumpBy` repositions instantly, with no tween or walk animation, for a move-route
1439
- "jump" step.
1440
- - `MoveRouteRunner`/`MoveRoute`/`MoveRouteStep`/`MoveRouteOptions` - drives any `GridMover`
1441
- (the player's or an NPC's) through a scripted route over successive `update(dt)` calls:
1442
- fixed/random/toward/away directional steps, a turn-in-place step, a jump step, and a wait
1443
- step, with `repeat` and `skippable` policies. Whether a step is passable is asked through the
1444
- same `canMove` contract `GridMover` itself expects of its own caller.
1445
- - `FreeMover` - continuous (non-grid) position and facing, for action-game movement.
1446
- - `MovableSprite` - what both movers actually require: `x`/`y`, and optionally `update`/`has`/
1447
- `play`. A static sprite, a 3D mesh wrapper or a plain test record all satisfy it.
1448
- - `aabbOverlap`/`circleOverlap`/`circleAabbOverlap`/`resolveAabbAgainstTiles` - 2D
1449
- collision: shape overlap tests, and an axis-separated sweep against solid tiles.
1450
- - `QuestLog`/`QuestStage`/`QuestDefinition`/`QuestMarker` - quest stages advanced one at a
1451
- time by `advanceStage`, prerequisites, `markerFor` deriving `'offer'`/`'turnIn'`/`'none'`,
1452
- and a tracked-quest pointer/location.
1453
- - `questsFromRows`/`QuestStageRow` - groups a flat table of stage rows (typically a
1454
- `core.parseCSV` result, one row per stage sharing a `questId`) into `QuestDefinition`s a
1455
- `QuestLog` can `define`.
1456
- - `decodeMarshal`/`encodeMarshal`/`RubySymbol` - Ruby `Marshal` 4.8 binary serialization
1457
- (the container format RPG Maker's own `.rxdata` saves use).
1458
- - `hashDefaultOf`/`withHashDefault` - reads and attaches a Ruby hash's default value, which
1459
- `Marshal` carries alongside the entries rather than as one of them.
1460
- - `parseDialogueText`/`extractDialogueCatalog` - the terse `@id text`/`-`-alternation dialogue
1461
- format targeting `EventCommand`, a thin wrapper around `core.parseDialogueLines` (the same
1462
- engine `two-d/stage.parseDialogueText` wraps for `StageCommand` instead), so a text-only
1463
- RPG (`core` plus `rpg`, no renderer at all) can author dialogue without depending on
1464
- `two-d` for anything. `extractDialogueCatalog` builds an identity `i18n` catalog from the
1465
- result, the same shape MWL's own `extractCatalog` builds from `_("...")`-marked strings.
1466
-
1467
- ## `simulation`
1468
-
1469
- `TrainingEnvironment` adapts game-owned `TrainingRules` around the existing
1470
- `SimulationRule`, with no renderer, DOM, audio or animation loop. `reset(seed)`
1471
- returns a `TrainingFrame` with per-agent observations, rewards, `terminated` and
1472
- `truncated`. `step(actions)` takes one action index per agent (or `null` only for
1473
- an all-masked idle agent), invokes the same rule used during play and returns the
1474
- next frame. Rewards inspect a cloned pre-transition state, so mutable rules work.
1475
- The agent roster stays fixed within an episode. `maxSteps` is required and capped
1476
- at one million; reaching it truncates an unfinished episode, while rule completion
1477
- terminates it. Real-time games advance fixed simulation ticks inside their rules;
1478
- turn-based games advance turns. Neither waits for wall-clock time. A throwing
1479
- rule can mutate its state, as with `runScenario`; reset or restore before continuing.
1480
-
1481
- `snapshot()`/`restore()` use `TrainingSnapshot`: versioned environment state, schema,
1482
- step limit, completion flags, seed and RNG state. `TrainingCheckpoint<State, TrainerState>`
1483
- combines that snapshot with the `NeuralModel` and game-owned optimizer/exploration
1484
- state. Persist every random stream the trainer uses in `trainerState`. Train with
1485
- the same observation schema and action ordering used by the playable game.
1486
-
1487
- `runRollouts(environment, model, RolloutOptions)` chooses actions from each new
1488
- observation until completion. Options provide episode seeds, optional seeded
1489
- softmax sampling and `trajectoryLimit` (first transitions per episode, zero by
1490
- default). `RolloutEpisode` reports steps, cumulative per-agent rewards, completion
1491
- flags and a bounded array of `TrainingTransition`s. No command journal or presentation
1492
- events are retained. Batches accept at most 10000 episodes and 10000 stored transitions.
1493
-
1494
- `runRolloutsAsync(TrainingFactory, config, model, options)` shards episodes across
1495
- workers (default four, configurable `jobs` in 1..64). Each worker keeps its model,
1496
- environment and inference buffers for the whole shard. Results stay in seed order;
1497
- `signal` and per-worker `timeout` terminate work, and any failure terminates sibling
1498
- workers. The factory must be self-contained, like `threads.spawn`, accepting the
1499
- supplied `TrainingEnvironment` constructor and structured-cloneable configuration;
1500
- it cannot close over module imports. Both paths run the same classes and inference
1501
- code, including in a compiled `file://` page. Training algorithms and rewards are
1502
- game-owned; `tools/train-neural.ts` shows a seeded evolution optimizer, resumable
1503
- checkpoint and model export, and `examples/neural` loads its trained weights.
1504
-
1505
- `imitationFromReplay(environment, { actions, events, seed })` turns a persisted run
1506
- (roadmap 397) into imitation targets: it walks the recorded actions against the
1507
- same seeded environment they were played on and returns the `(observation, action)`
1508
- samples a game's own trainer fits, sourced from how its players played rather than a
1509
- generated expert. One recorded event is one environment step; the environment must
1510
- expose exactly one agent (the recorded player - anything else that moves is part of
1511
- the rule, like the maze chase's ghosts); a recorded action outside the list is a
1512
- named error, never a silently skipped event.
1513
-
1514
- `runSeededEpisode(environment, choose, { seed })` plays one whole run with the AI
1515
- choosing, from a named seed: the same seed and the same deterministic `choose` make
1516
- the same decisions, so runs compare across builds, policies and machines. Unlike
1517
- `runRollouts` the chooser is not a `NeuralModel` - a heuristic, a `NeuralPolicy`'s
1518
- argmax, or any named function works - and the result records every chosen action and
1519
- the cumulative rewards, with the environment's `maxSteps` as the truncation bound.
1520
-
1521
- Headless, deterministic turn/scenario running - for testing and benchmarking without a
1522
- live game loop.
1523
-
1524
- - `advanceToInput`/`ScheduledTurns`/`TurnRules`/`TurnResult` - drives turns forward under a
1525
- rule set until the next input is due.
1526
- - `runScenario`/`Scenario`/`ScenarioResult` - a bounded, scripted simulation run against a
1527
- set of expectations.
1528
- - `Campaign`/`CampaignLevel`/`CampaignLevelResult`/`CampaignSnapshot` - generic level order,
1529
- result, carry-over, reminder and transition state, with JSON-safe save/restore.
1530
- - `runHeadlessScenario`/`HeadlessScenario`/`HeadlessScenarioResult` - seeded, renderer-free
1531
- scenario execution returning the final state, ordered events and resumable random state.
1532
- - `SimulationRuntime`/`SimulationContext`/`SimulationOutcome`/`SimulationRuntimeRule`/
1533
- `SimulationSnapshot` - a facade over one state + one `roguelike.Scheduler` + one `core.
1534
- Generator`, for the interactive half of a turn-based simulation: `dispatch` runs a single
1535
- command through the game's rule, threading `random`/`scheduler` as context and charging any
1536
- returned cost; `snapshot`/`restore` capture and rebuild the whole triple. Commands, events and
1537
- (with `history`) state are journalled through `structuredClone`, so they must be plain data:
1538
- name an actor by id, never pass the live object. A `dispatch` that cannot copy them throws
1539
- with the offending path and commits nothing. Composes with
1540
- `advanceToInput` against the same scheduler for the automatic-actor loop, rather than
1541
- replacing it.
1542
- - `EventPresentation`/`EventPresentationOptions` - the documented pattern tying a
1543
- `SimulationRuntime` to a `core.PresentationQueue`: `submit` commits a command and starts its
1544
- events, `locked` is the animation lock `submit` refuses under, `followUp` schedules a
1545
- secondary actor's commands for after the current batch, `cancel` drops the rest of the show
1546
- without rolling the committed turn back, and `snapshot`/`restore` deliberately leave the
1547
- queue out of a save so a load resumes idle.
1548
- - `Scheduler`/`Actor`/`SchedulerSnapshot` - re-exported here from `roguelike` (its real home),
1549
- since every `SimulationRuntime` needs one; a simulation-first game need not import a second
1550
- module just to construct the class its own runtime is built around.
1551
- - `CampaignSave`/`CampaignSaveState`/`CampaignSaveParts` - one `core.SaveSystem` slot for a whole
1552
- campaign: `save` captures the `Campaign` snapshot, the game's own world payload and the
1553
- `SimulationRuntime` snapshot together, `load` reads them back migrated, and `list`/`delete` are
1554
- `SaveSystem`'s. The world is opaque, so an `MwlWorld`, a `Level` or a game's own scenario object
1555
- all fit.
1556
-
1557
- ## `skeleton`
1558
-
1559
- Skeletal pose math, renderer-free: a bone tree, keyframed clips and layered blending, as
1560
- pure data and arithmetic so it loads headless and tests without a renderer. Clips are plain
1561
- JSON-shaped data a game authors itself. `import * as Skeleton from '@datamoc/mw_games/skeleton'`.
1562
-
1563
- - `create(bones)` - builds a `SkeletonBones` from `Bone`s (`name`, `parent`, `length`,
1564
- `origin`, `rest` `rotation` in degrees, optional `limits`), throwing by name on a duplicate
1565
- bone, a cycle, a missing parent or inverted joint limits. `boneOrder` lists names parents
1566
- first.
1567
- - `resolve(skeleton, pose?)` - walks the tree and returns one `BoneTransform` per bone (world
1568
- `x`/`y`, `angle`, composed scale, a 2D `matrix`, and the `tipX`/`tipY` the children start
1569
- from). A `Pose` is one rotation per bone name; a `TransformPose` adds per-bone translations
1570
- and scales.
1571
- - `samplePose`/`sampleTransformPose(clip, time, skeleton?)` - a `Clip` (`duration`, `loop`,
1572
- ascending `Keyframe`s) interpolated at a time: a looping clip wraps, a one-shot holds its
1573
- last frame. Passing the skeleton validates the result.
1574
- - `advancePlayback`/`createMixer`/`crossfadeTo`/`advance`/`advancePose` - a `Mixer` holds a base
1575
- `Playback` plus weighted, prioritised additive `Layer`s. `advance(mixer, dt)` ticks every
1576
- playhead, folds in a running crossfade and the layers, and returns rotations;
1577
- `advancePose` returns the full `TransformPose`. `mixPoses` blends rotation poses by layer
1578
- priority and weight.
1579
- - `validatePose` - refuses non-finite rotations and angles outside a bone's `limits`.
1580
- - `solveTwoBoneIK(skeleton, first, second, target, bend?, pose?)` - solves a connected
1581
- two-bone chain toward a world target without stretching; throws for an unreachable target
1582
- or a second bone with a non-zero origin.
1583
-
1584
- ## `physics`
1585
-
1586
- Small deterministic simulations, renderer-free, with no third-party engine. Three entry
1587
- points: `@datamoc/mw_games/physics` (rigid bodies, cloth, spring) and
1588
- `@datamoc/mw_games/physics/xpbd` (a structure solver). Everything is plain arithmetic, so a
1589
- game's headless tests run the same world.
1590
-
1591
- - `PhysicsWorld` - rigid circles and axis-aligned boxes (never rotating: `angle` is a display
1592
- offset), stepped on a `FixedStepper` so results do not depend on the display refresh rate.
1593
- Semi-implicit Euler, impulse contacts with restitution and friction, and distance joints.
1594
- `addBox`/`addCircle` return a plain `PhysicsBody` (`position`, `velocity`, `angle`, `label`,
1595
- `isStatic`); `connect` joins two bodies or a body and a world point
1596
- (`ConstraintOptions`: `stiffness`, `damping`, `length`, attachment points, and `maxStretch`
1597
- to make the joint breakable); `remove` takes a body or constraint; `stretchOf` reads a
1598
- joint's strain; `update(dt)` runs the fixed steps it covers and returns their count.
1599
- `onContact` and `onBreak` are `Signal`s.
1600
- - `XpbdWorld` (`physics/xpbd`) - point masses (`addNode`, `fixed` anchors) joined by springs
1601
- (`addLink`: `stiffness`, `rest`, `tensionOnly` cables, `strength`/`tensionStrength`),
1602
- solved with extended position-based dynamics and the force in each link read back, so a link
1603
- breaks at a real load. Fixed steps and no randomness make a replay identical on every
1604
- machine. `step()` advances one frame; `applyForce` pushes a node for one step; `ground` is a
1605
- height or a function of x; `breaking` gates breaking so a structure can settle first;
1606
- `onBreak` fires per broken link and `peakRatio` is a strain gauge. It has no rigid bodies or
1607
- collisions, which is what `PhysicsWorld` is for.
1608
- - `Cloth` - a pinned-point Verlet grid (top row pinned) with structural links only, no
1609
- allocation per step. `indexOf`/`pointPosition`/`pointLinks`/`writePositions` read it back;
1610
- `pinPoint`/`unpinPoint`, `setWind`/`setGravity`, `reset` and `update(dt)` drive it.
1611
- `two-d`'s `ClothSprite` draws one as a mesh on the GPU path.
1612
- - `Spring` - a damped chase spring for secondary motion (hair, hems, panels): `setAnchor`
1613
- moves the target, `displace` shoves the bob, `offset`/`length`/`settled(tolerance)` read the
1614
- lag, `place(target)` positions a display object, `update(dt)` steps it. Under reduced motion
1615
- it follows `SpringOptions.intent` (`decorative` snaps to the anchor).
1616
-
1617
- ## `testing`
1618
-
1619
- Test doubles for the seams mwg takes by injection (item 388), so a game's tests and this
1620
- repository's own share one copy of each. Renderer-free, dependency-free, and off the root barrel:
1621
- nothing here reaches a shipped game unless a test imports it.
1622
- - `createSceneControls` (item 408) - named steps a game opts into (`enterScenario`,
1623
- `finishTurn`, `advanceDialogue` in the Wesnoth port), driven by name from a test or a
1624
- headless Chrome: the game decides what a step does, the controls only promise that a
1625
- registered name runs and an unknown one is refused by name.
1626
- - `memoryStorage` - a `SaveStorage` held in memory, for `SaveSystem`, `Settings`, `Collection`,
1627
- `PlayerStats` and the other stored values; the same class `core` falls back to where
1628
- `localStorage` is missing.
1629
- - `exposeForTests(name, object)` - publishes inspectable game state under
1630
- `window.__mwg_test__[name]` for browser tests; does nothing outside a browser.
1631
- - `fakeAudio`/`fakeAudioWithEnded`/`FakePlayable` - a `Playable` for `Sound`/`Music`'s `create`
1632
- that counts its plays; the second also has the `onended` slot a backend reporting track ends
1633
- has.
1634
- - `FakeAudioContext`/`FakeBuffer`/`FakeBufferSource`/`FakeGain`/`FakeBlockSource` - a fake
1635
- WebAudio graph for the audio tests: sources, gains and buffers a test can inspect, and a
1636
- block source for a `StreamChannel`, with no real `AudioContext` anywhere.
1637
- - `FakeRetroPlayer` - a `MidiSynth` double for a retro engine: it records every message it
1638
- was driven with and renders a flat level while a note is on, so a renderer test reads what
1639
- was sent and what sounded, with `FakeAudioContext.advance()` as the clock it moves by hand.
1640
- - `FakeSocket` - a `WebSocketLike` for `LockstepClient`'s `create`: `sent`, `receive(message)`,
1641
- `receiveRaw(text)`, `close()`.
1642
- - `fakeFetch`/`FakeFetchCall` - a `fetch` for every `HttpTransport` client, answering with a
1643
- `Response` or a value sent as JSON, recording each call.
1644
- - `fakeGamepad` - a `Gamepad` from button values (pressed above 0.5) and axes, for `Input` and
1645
- `PlayerInput`.
1646
-
1647
- ## `threads`
1648
-
1649
- Runs a self-contained function on a worker thread, so a blocking computation costs a
1650
- background thread instead of a dropped frame. mwg's own runtime rather than a dependency:
1651
- a classic blob worker in the browser, because that is the one shape a double-clicked
1652
- `file://` page accepts (the shipped CSP allows `worker-src blob:` and `new Function`, and
1653
- a module worker loaded from `file://` fails CORS whatever the policy says), and
1654
- `node:worker_threads` in Node. Off the root barrel like `testing`: a game that never
1655
- spawns a worker pays nothing for it, and imports `@datamoc/mw_games/threads` when it
1656
- wants one.
1657
-
1658
- - `openWorker(source, events)` - opens a long-lived worker from a self-contained script
1659
- (blob worker in a browser, `node:worker_threads` in Node, null where neither exists) and
1660
- returns its message link; `spawn` is the one-task use of it, a service such as the audio
1661
- core host keeps its worker and talks to it.
1662
- - `spawn(fn, args?, options?)` - runs `fn` on a worker and resolves with its value. The
1663
- task is serialized with `Function.prototype.toString`, so it must be self-contained:
1664
- no closures over module scope, no imports, no bound or native functions - everything it
1665
- needs arrives as `args`, structured-cloned in. `options.transfer` moves listed buffers
1666
- instead, detaching them from the caller's thread. The result returns structured-cloned
1667
- with every `ArrayBuffer` inside it transferred rather than copied, since the worker is
1668
- finished with them. A task that throws, closes over something the worker cannot see, or
1669
- kills its worker without answering rejects the promise instead of hanging it;
1670
- `options.timeout` abandons a task that never returns, and `options.signal` (an
1671
- `AbortSignal`) cancels one on demand. One worker per task, terminated the moment it
1672
- settles. In Node an unsettled task keeps the process alive, so settle or cancel every
1673
- task before exit.
1674
-
1675
- ## `headless`
1676
-
1677
- The blessed renderer-free entry: every module that loads in bare Node, in one import,
1678
- with no DOM or WebGL globals. A rule imported through here is headless by construction;
1679
- anything outside it belongs in presentation, not in the rule.
1680
-
1681
- - `core`/`simulation`/`mwl` - scenes, saves, RNG, headless scenarios and content tables.
1682
- - `i18n`/`actors`/`world`/`battle` - messages, stats, maps, encounters and type matchups.
1683
- - `roguelike`/`board`/`audio`/`rpg` - dungeon generation, board rules, sound/music
1684
- primitives (inject `create`, as under plain `audio`) and map events.
1685
- - `ai`/`testing` - decision runners and the shared test doubles.
1686
- - `assetPaths`/`assetBinary` - the two renderer-free asset halves (path resolution and
1687
- byte caching) beside the Pixi-backed `assets` loader.
1688
-
1689
- Excluded with reasons in `src/headless/index.ts`: `three-d` (needs Babylon at import),
1690
- the Lua runtimes (`mwl/pyroeis`, `ai/lua`), and every `two-d/*` module.
1691
-
1692
- ## `three-d` (optional)
1693
-
1694
- Babylon.js-backed 3D, kept fully separate from the 2D default - nothing in `core` imports
1695
- this module.
1696
-
1697
- - `Engine3D` - owns Babylon's engine, scene, orbit camera, light, resize, and render loop.
1698
- - `gridPoint3D`/`GridCell3D`/`GridShape3D` - square/hex 3D grid cell projection.
1699
- - `createTileGrid3D` - a thin-instanced 3D tile floor (square or hex) with elevation
1700
- columns for nonzero cell heights.
1701
- - `Character3D` - moves an imported mesh or a camera-facing billboard sprite through
1702
- continuous world coordinates; `playAnimation` plays a clip an imported model carries.
1703
- - `parseVox`/`createVoxModel3D` - MagicaVoxel `.vox` import, batched by colour.
1704
- - `loadModel3D`/`loadModelContainer3D`/`isModelContainerLoaded`/`releaseModelContainer`
1705
- (`@datamoc/mw_games/3d/models`, kept out of the main `3d` barrel so a scene that never
1706
- imports a model pays nothing for the loader) - glTF/GLB import. `loadModel3D` imports
1707
- straight into the scene, for one copy; `loadModelContainer3D` fetches and parses a source
1708
- once, caches the `AssetContainer`, and a game calls `instantiateModelsToScene()` on it for
1709
- each independent, unaliased copy it wants placed - Babylon's own answer to "load once,
1710
- place many" without a second network fetch.
1711
- - `createHeightmapTerrain3D` - a continuous displaced-mesh terrain from a greyscale
1712
- heightmap image, alongside `createTileGrid3D`'s stepped floors.
1713
- - `buildHeightIndex`/`cellAt`/`heightAt`/`resolveCapsuleAgainstGrid` - horizontal collision
1714
- for a moving capsule against `createTileGrid3D`'s stepped grid.
1715
-
1716
- ## `world`
1717
-
1718
- Many maps, transitions, persistence, the turn clock, encounter tables - the connective
1719
- tissue between scenes.
1720
-
1721
- - `World` - many maps, each created once and kept alive (or rebuilt fresh per entry when
1722
- defined `persistent: false`); `unload` frees a map's own state.
1723
- - `Overworld`/`Location` - named-location lookup.
1724
- - `TurnClock`/`TimedEffect` - hunger/poison-style timed effects, ticked on `advance`.
1725
- - `rollEncounter`/`EncounterTable` - rolls whether an encounter fires, then weight-picks
1726
- which.
1727
- - `EnvironmentClock`/`DayPhase`/`EnvironmentSnapshot` - a continuous day/night-phase and
1728
- weather clock above any one encounter, driven by `update(dt)` in real seconds, with change
1729
- notifications and `toJSON`/`fromJSON`.
1730
- - `SideTurns`/`SideTurn`/`TimeOfDay`/`TimeArea`/`Alignment`/`alignmentBonus` - the reference
1731
- strategy game's outer turn model: sides take turns in order, a round is all of them, and the
1732
- time-of-day schedule steps on per round. `lawfulBonusAt` applies a unit's alignment to the
1733
- current time's `lawfulBonus`, and a `TimeArea` overrides the schedule for part of the map,
1734
- which is what makes the bonus per-hex. `toJSON`/`fromJSON` resume the exact position.
1735
-
1736
- ## `i18n`
1737
-
1738
- Message tables, plurals, interpolation, and direction - pure logic, no Pixi dependency.
1739
-
1740
- - `Direction`/`Catalog`/`MessageValue` - the message-table shape: locale, direction,
1741
- messages, an optional Fluent-parsed or plain-string/plural-form value.
1742
- - `setBase`/`setActive`/`locale`/`direction` - the active and fallback language, and the
1743
- direction `ui`'s `Theme.direction` reads from; `reset` clears both back to unset.
1744
- - `t`/`tRaw`/`formatSpec`/`tokenizeMessage`/`diffPlaceholders`/`MessageParams` - resolves a key, selecting a plural form via `Intl.PluralRules` and
1745
- interpolating `{token}`s, including dotted paths that walk into nested params
1746
- (`{side.stored.hitpoints}` against `{ side: { stored: { hitpoints: 12 } } }`); falls back to the
1747
- base language, then to the raw key. Placeholders
1748
- also take Python f-string-style specs (`{dmg:03d}`, `{hp:.1%}`, `{name:>12}`), `!s`/`!r`/`!a`
1749
- conversions and `=` debugging, resolved through `formatSpec` (verified case by case against
1750
- CPython; an ill-fitting spec stays untouched rather than throwing). `tokenizeMessage` is
1751
- the single definition of that placeholder grammar, shared by interpolation and by
1752
- `diffPlaceholders`, which compares a reference string against its translation (dropped,
1753
- added, or reshaped tokens) for `tools/i18n-edit` to surface. `tRaw`
1754
- skips the display-text decoration (typographic spacing, RTL wrapping) for catalog values
1755
- that are not shown to the player, such as a sound path.
1756
- - `parseSoundMarkers`/`stripSoundMarkers`/`InlineSoundCue`/`ParsedSoundText` - extracts
1757
- `{sound:path}` markers from translated text, returning marker-free display text and each
1758
- cue's visible-character offset. `MessageBox` consumes these markers during its reveal;
1759
- `t()` and `tRaw()` preserve them for the presentation layer.
1760
- - `typographic` - locale-aware curly-apostrophe substitution (French/Italian/Dutch elisions);
1761
- for French, also a narrow no-break space before `; ! ? :` and around `« »`, and a plain
1762
- no-break space between a numbering word and its number ("Chapitre 3"); for German, a
1763
- no-break space between a number and its unit ("5 kg") and after a small set of
1764
- abbreviations ("Nr. 3", "Dr. Müller").
1765
- - `nonBreakingUnit` - joins a value and a game-defined unit ("pièces d'or", "points de vie")
1766
- with whichever no-break space French/German typography calls for; the unit's own text is
1767
- always the game's vocabulary, never MWG's.
1768
- - `has` - whether a key resolves to something real, in either language.
1769
- - `parseFTL`/`FluentOptions` - parses Project Fluent `.ftl` message resources into the same
1770
- `Catalog`/`t()` surface, with variables, exact and plural variants.
1771
- - `parsePo`/`PoOptions` - parses a gettext `.po` file into the same `Catalog`/`t()` surface:
1772
- `msgid`/`msgstr`, `msgctxt`, `msgid_plural` with `msgstr[N]` mapped onto the locale's CLDR
1773
- categories, the header entry dropped, untranslated entries left out for base fallback - which
1774
- includes a `#, fuzzy` one, the way gettext's own tools treat it - and a non-default gettext
1775
- `domain` prefixing keys.
1776
- - `SemanticMessage`/`MessageChannel`/`MessageFormatter`/`createCatalogFormatter` - a typed
1777
- `{ type, params }` communication intent rendered differently per channel (log/compact/
1778
- accessibility/debug/audio) from the same underlying catalog: `createCatalogFormatter` looks up
1779
- `${type}.${channel}`, falling back to `${type}` alone, then formats through `t()`. A
1780
- simulation emits the message once; the channel is a presentation choice, not a rule. The
1781
- `audio` channel holds a sound path (played game-side through `audio`'s `Sound`), resolves
1782
- through `tRaw` rather than `t()`, returns `''` when no `<type>.audio` entry exists, and
1783
- never falls back to a bare type holding a sentence.
1784
- - `EntityTextResolver`/`GrammaticalEntity` - type contracts a game uses while building a
1785
- `SemanticMessage`'s params (resolving an id to display text, or carrying gender/number/
1786
- proper-noun metadata for its own catalog's grammar); MWG never calls or interprets either.
1787
- - `formatNumber`/`formatDate`/`formatList` - locale-aware `Intl.NumberFormat`/
1788
- `DateTimeFormat`/`ListFormat` wrappers reading the active locale from `locale()`, for a
1789
- message that needs more than `{token}` substitution - a game calls these while building a
1790
- `t()`/`SemanticMessage` param, the same way it resolves an entity id to display text.
1791
- - `diffCatalogKeys`/`validateCatalog`/`CatalogKeyDiff`/`CatalogIssue` - catalog consistency
1792
- checks: `diffCatalogKeys` compares two catalogs' key sets (a base language against a
1793
- translation); `validateCatalog` flags empty messages and plural forms missing their
1794
- `other` branch within one catalog. Deliberately not a parameter schema validator - a
1795
- `SemanticMessage<TType, TParams>`'s own generics already give a game compile-time
1796
- parameter safety, which is the primary mechanism the source document calls for.
1797
- - `validateMessageAudio`/`AudioIssue` - structural checks over `<type>.audio` sound-cue
1798
- entries: empty paths and non-string (plural/select) values, which would reduce silently
1799
- at lookup time rather than selecting per play.
1800
- - `EditSession`/`EditRow`/`RowFilter`/`AUDIO_SUFFIX`/`createEditSession`/`sessionKeys`/
1801
- `sessionRow`/`sessionRows`/`setTargetText`/`copyFromBase`/`deleteTargetKey`/
1802
- `setTargetSound`/`cueKeyFor`/`sessionCompleteness`/`swapSession`/`isAudioKey` - the pure
1803
- session core behind `tools/i18n-edit`: translatable rows with reference/target text and
1804
- an effective cue (a channel key shares its semantic family's `<type>.audio`, one cue per
1805
- family), completeness ignoring cue keys, and swapping which catalog is the reference.
1806
- `tools/i18n-edit.mjs` is the terminal split-screen editor over it, with a `--check`
1807
- mode for CI.
1808
- - `messageText`/`levenshteinDistance`/`findSimilarMessages` - content-management over a
1809
- catalog's actual message text rather than only its key shape: `messageText` reduces any
1810
- `MessageValue` to plain comparable text, `levenshteinDistance` is the classic edit-distance
1811
- primitive, and `findSimilarMessages` surfaces near-duplicate messages worth merging by
1812
- similarity threshold, most-similar first.
1813
- - `catalogUsage`/`catalogCompleteness`/`pluralFormCoverage` - catalog statistics:
1814
- `catalogUsage` compares a catalog's keys against a caller-supplied referenced-keys list
1815
- (mwg has no view into a game's own source) for used/unused counts; `catalogCompleteness`
1816
- is a 0-1 translated fraction built on `diffCatalogKeys`; `pluralFormCoverage` tallies which
1817
- CLDR plural categories a catalog's plural-form messages actually define.
1818
- - `mergeCatalogKeys` - drops a merged key from one catalog, keeping the surviving key's text
1819
- untouched; rewriting call sites that used the merged key stays the caller's own job, the
1820
- same boundary `catalogUsage`'s `referencedKeys` already draws.
1821
-
1822
- ## `mwl`
1823
-
1824
- MWL is the build-time, game-neutral content layer. It uses a WML-inspired syntax for data
1825
- such as units, items, maps, events, AI hooks, translations, and asset references. The runtime
1826
- consumes generated data and does not parse `.mwl` source files in the browser.
1827
-
1828
- - `mwl build` - reads one file or a directory of `.mwl` files in stable path order and emits
1829
- `game-data.ts`, `i18n.json`, and `assets.json` in one step.
1830
- - `mwl build --asset-root public/assets` - optionally verifies every extracted asset before
1831
- emitting the generated files. Missing paths include their MWL source location; without this
1832
- flag the build stays portable for games that resolve assets elsewhere.
1833
- - `contentReport` / `loadContent` / `mwl report` - counts tags, lists opaque names, reports
1834
- resources, dependencies and unresolved references, and returns structured load diagnostics
1835
- for parity checks and CI.
1836
- - `validateCatalog`/`validateCatalogNodes`/`MwlValidationOptions` - semantic checks shared by
1837
- every game: `MWL_DUPLICATE_ID`, `MWL_UNKNOWN_SLOT`, `MWL_INCOMPLETE_EFFECT`,
1838
- `MWL_INVALID_HOOK`/`MWL_UNKNOWN_HOOK`. `MWL_DUPLICATE_ID`'s `tag:id` key is scoped by
1839
- `rowIdScope` (item 304): `'global'` (the default) checks the whole compiled catalog, every
1840
- source file combined; `'file'` folds each node's own source file into the key too, for a game
1841
- whose id convention is meaningful only within one file and reuses ids across files on purpose
1842
- - a real duplicate within one file still reports.
1843
- - `[campaign]` - declares game-owned campaign metadata (`id`, optional `name`, `title`,
1844
- `description`, and `start_scene`). Its children are intentionally open so a game can define
1845
- scenario and progression tags without changing the core MWL schema; metadata is exposed by
1846
- `contentCatalog(game).campaigns`.
1847
- - `campaignChain` - points a `[campaign]` at `simulation.Campaign`: `first_scenario` opens the chain,
1848
- each `[scenario]`'s `next_scenario` is where it goes when it is won, and a scenario that ends the
1849
- chain ends the campaign. The order is content, the playing stays the game's (`run` is a callback),
1850
- and a scenario that decides for itself - a runtime `[endlevel]` - keeps its decision. The
1851
- `[campaign]` schema reads `first_scenario`, and the catalog exposes each campaign's `scenarios`.
1852
- - `endLevelCarryover`/`carryoverIntoScenario`/`MWL_DEFAULT_CARRYOVER_PERCENTAGE` with `[endlevel]` -
1853
- a scenario's end as the reference models it: a share of the side's gold (80% by default), a bonus
1854
- on top, that side's surviving units as the recall list, and the next scenario. `result=victory`
1855
- ends it won, `result=defeat` lost, and the arithmetic is the same for both.
1856
- - One side identity (item 277): the `id` a `[side]` declares (now a `string`, so a named side like
1857
- `id=rebels` validates) keys `world.sides` and `world.gold`, marks a map keep (`rebels Kh`), and
1858
- is what `unit.side`, `MwlMessage.side` and every `side`/`side_filter` filter hold. `MwlSideRef`
1859
- is just that id.
1860
- - `nodesToObjects`/`MwlObject` - converts compiled nodes to JSON objects using the tag
1861
- schema: declared numbers and booleans become typed fields, child tags become ordered
1862
- arrays, and a `cardinality.max` of 1 selects a single object. Missing optional fields stay
1863
- absent. Check the returned diagnostics for conversion errors and field collisions.
1864
- Attributes not listed in `MwlTagSchema.required` are optional; use `number`, not `number?`.
1865
- - `readAttributes` / `readChildren` - shared typed readers for compiled nodes. They coerce
1866
- scalars and lists and return source-located diagnostics instead of silently guessing.
1867
- - `MwlNode.attributeLocations` / `valueLocations` - parsed JSON5 nodes retain the exact key and
1868
- value start for each attribute, and schema diagnostics use those locations when available.
1869
- - `MwlValidationOptions.mapBounds` - an adapter can supply map dimensions so `validateCatalog`
1870
- rejects out-of-bounds integer, list, and range coordinates without embedding a map system in MWG.
1871
- - `readTableMap` / `readTableIndex` / `tableKey` - project typed table rows into a `Map`, use
1872
- collision-free native composite keys, and build inverse indexes that retain every matching row.
1873
- - A `key="""..."""` value (item 317) is the one attribute form that may span lines, and its text
1874
- is exactly what sits between the delimiters, so wrapped message, objective and option-label
1875
- text survives a conversion without the whitespace-collapsing workaround it otherwise needs. It
1876
- carries the `_` gettext marker like any other value; `text="""done"""` is the same form on one
1877
- line. (A line starting with `#` is still a comment wherever it appears, so a block cannot
1878
- carry one at the start of a line.)
1879
- - MWL tables use `[table] columns=name:type|...` with typed `[row]` attributes. The compiler
1880
- validates column shape and values, and `contentCatalog(game).tables` exposes typed rows.
1881
- Supported column types match `core.parseCSV`: `string`, `number`, `boolean`, `list`, and
1882
- `map`, with configurable list and map delimiters. `typedRows`/`MwlTypedRow`/
1883
- `MwlColumnValueType` read rows through the declared columns (every field optional, an
1884
- absent cell omits the key), and `emitTableTypes` emits one named row interface plus one
1885
- typed accessor per table for a game's build script to write and import, so a changed
1886
- column type or a removed column fails type-checking at every use.
1887
- `emitTableTypes(tables, { literalColumns: ['id', 'sprite'] })` also exports sorted,
1888
- deduplicated readonly value lists and literal unions such as `VehiclesSprite` from the
1889
- current string-column values. Regenerate them with the catalog to catch stale game ids.
1890
- - `MwlValidationOptions.tableReferences`/`MwlTableReference` (item 362) - declarative
1891
- cross-table checks, so no game hand-rolls one validator per table: a column declares
1892
- `references: { table, column }` or `oneOf: [...]`, and `validateCatalog` checks every cell
1893
- once for all tables, reporting `MWL_TABLE_REFERENCE` with the table, the row, and the
1894
- offending value. The declarations' contents stay game data; absent or empty cells are
1895
- skipped and a `list` cell checks each entry under the table's own delimiter.
1896
- - `composeEffects` - resolves MWL effects through `actors.composeModifiers`, so declarative
1897
- item effects and actor stats use one composition rule.
1898
- - `evaluateCondition` - evaluates bounded content conditions with comparisons, `and`/`or`/`not`,
1899
- arithmetic, literals, `where` bindings, and explicitly supplied pure helpers. There are no loops, assignments,
1900
- dynamic code loading, or implicit game rules.
1901
- - `mwl validate` - checks syntax and content structure without generating runtime files.
1902
- - `mwl diagnostics` / `mwl ci` - emit stable JSON diagnostics, with `ci` additionally exposing
1903
- a boolean `valid` result and returning a failing process status when errors exist.
1904
- - `mwl format` / `mwl migrate --to 1.0` - expand and emit a deterministic canonical MWL document;
1905
- migration requires an explicit target and currently normalizes the MWL 1.0 syntax surface.
1906
- - `mwl compile`/`mwl extract-i18n`/`mwl hooks` - lower-level commands for a generated module,
1907
- translation extraction, or hook manifest when a build pipeline needs separate outputs.
1908
- - `parse`/`compile`/`validate`/`extractI18n` - the programmatic compiler surface exported from
1909
- `@datamoc/mw_games/mwl`; games provide their own hook implementations and interpret
1910
- game-specific effects.
1911
- - The `[side]` surface Wesnoth's own data writes, and the one key of it with behaviour here (item
1912
- 252): `team_name`, `user_team_name`, `share_vision`, `village_gold`, `heal`, `fog`, `shroud`,
1913
- `hidden` and `flag` are read onto `MwlWorld.sides` as written, `yes`/`no` becoming booleans.
1914
- `sideVisionGroups` turns `team_name` and `share_vision` into the groups `FactionFog.share` takes,
1915
- so a scenario's teams see together without every game re-deriving who shares with whom.
1916
- `leader=` names either a `[unit]` id already declared (that unit is the side's leader; nothing
1917
- is spawned) or a unit type (one leader per free start cell, with that type's stats); a value
1918
- that is neither is refused by name (item 405).
1919
- - A `[side]`'s own `[victory]`/`[defeat]` children (item 283): a side condition that names no
1920
- `side`/`side_filter` reads as that side's own, its result lands in `MwlWorld.sideStatus` keyed by
1921
- the side id, and the aggregate `MwlWorld.status` ends the scenario as a scenario-wide condition
1922
- would (a side victory outranking another side's defeat when both fire at once). `[win]`/`[lose]`
1923
- record the side they name too.
1924
- - Public MWL exports - `MwlRuntime`, `MwlSyntaxError`, `collectHookReferences`, `compileNodes`,
1925
- `compileSources`, `compileAndEmitSources`, `emitArtifacts`, `coerceTableValue`, `decodeSaveEnvelope`,
1926
- `parseTableColumns`, `contentCatalog`, `createWorld`, `decodeSave`, `effectToModifier`,
1927
- `emitHooksDeclaration`, `emitModule`, `emitTableTypes`, `encodeSave`, `evaluateExpression`,
1928
- `execute`,
1929
- `extractCatalog`, `hookTypes`, `inventoryItem`, `isGettext`, `isMwlId`, `itemDefinition`,
1930
- `PACKAGE_TAGS`, `PACKAGE_ASSET_KINDS`, `PACKAGE_MEDIA_KINDS`, `PACKAGE_SCRIPT_ACTIONS`,
1931
- `KNOWN_PACKAGE_CAPABILITIES`, `DEFAULT_PACKAGE_LIMITS`, `PackageError`, `PackageFormatError`,
1932
- `PackageIntegrityError`, `PackageLimitError`, `PackagePathError`, `PackageConflictError`,
1933
- `encodePackage`, `decodePackage`, `verifyPackage`, `loadPackage`, `mergePackage`,
1934
- `compilePackages`, `packageContent`, `packageRef`, `parsePackageRef`, `parsePackageDocument`,
1935
- `checkPackagePath`, `checkPackagePolicy`, `checkConditionSyntax`, `compareVersions`,
1936
- `satisfiesVersionRange`, `requestedCapabilities`, `detectRomImage`, `registerRomDigest`,
1937
- `generateCredits` and `sha256Hex` (self-contained `.mwp` content packages: one compressed
1938
- container with per-entry digests and declared limits, a capability policy the game accepts
1939
- or refuses, `id@version` namespaces in saves, and a ROM-image refusal with generated credits),
1940
- `parseExpression`, `parseHookReference`, `parseMapFile`, `parseTerrain`, `parseValue`, `preprocess`,
1941
- `schema01`, `typedRows`, `validateCatalogNodes`, `validateHookReferences`, `loadContent`, and `validateWorld`.
1942
- - `parseMapFile`/`MwlMapFile` (item 284) - reads a Wesnoth-shaped `.map`: the `key=value` header
1943
- is split off and kept, and the comma-separated rows go through the same `parseTerrain` an inline
1944
- `[map] terrain=` uses, overlays (`Gg^Vh`) and `<side> <code>` starts included. Header keys are
1945
- not interpreted here, the same way `[terrain_graphics]` rules stay content's business.
1946
- - `MwlHookDeclaration`/`validateHookAttributes` (item 321) - a hook may declare the attributes its
1947
- own `[hook]` calls carry (`attributes`, typed the way a tag schema types its own, or
1948
- `openAttributes`), and `validateCatalog`'s `hooks` option takes it in place of a bare
1949
- `type:name` id, so a typo in one of a command hook's eighteen modes is a compile-time
1950
- `MWL_VALUE` rather than a throw mid-scenario. The declaration is the hook's, not the tag's:
1951
- only `[hook]` calls are checked, where every attribute but `name` belongs to the hook. The
1952
- rule itself is `validAttributeValue`/`attributeTypeDescription`, exported because the tag
1953
- schema and a hook declaration check values the same way rather than two ways that drift.
1954
- - `MwlDomainHook`/`MwlDomainHookRegistry` - game-declared hook namespaces such as
1955
- `item-effect:potion-strength` use a typed context/input/output boundary. MWG validates and
1956
- emits the reference shape, while the game owns the domain types, rules, and implementation.
1957
- - `HookWorld`/`Emit` (item 319) - the hook boundary's two halves. `world.variableAt(path)`
1958
- resolves a nested variable through the same walker `[variable] name=` reads through, and
1959
- `emit.setVariable(path, value)` is its write, so a hook asks for `stored_naga.hitpoints` and
1960
- means the same variable content does; writing `world.variables` directly gets a flat dotted
1961
- key no reader finds.
1962
- - `HookWorld.random`/`MwlRuntimeOptions.random` - a hook draws from the runtime's own seeded
1963
- `core.Generator` instead of `Math.random()`, so a `generator`/`ai`/domain hook stays reproducible;
1964
- the draw position is carried on `MwlWorld.random` and resumes exactly across save/restore.
1965
- - `MwlTraceEvent`/`MwlRuntimeOptions.onTrace` - opt-in lifecycle tracing for event claims,
1966
- completions, variable writes and runtime errors. `MwlHookRegistry.predicate` lets an adapter
1967
- register named, typed filter predicates without putting game-specific semantics in MWG.
1968
- - `MwlSaveableHookState` / `MwlHookRegistry.saveable` - a game may explicitly expose JSON-safe
1969
- hook state; `MwlRuntime.save()` includes it and `restore()` hands it back to the same adapter.
1970
- - `MwlRuntime.journal` / `MwlRuntimeAction` - public runtime triggers and their trace batches are
1971
- recorded in order and persisted with the save, providing a replay and diagnostics input without
1972
- making MWG interpret game-specific commands.
1973
- - `validateCatalog` also reports `MWL_ALIAS_CYCLE` for cycles among resolved `aliasof` references;
1974
- aliases outside the catalog remain available for game-defined sentinel values.
1975
- - `validateSimulationReplay` - replays a `SimulationRuntime` journal from a checkpoint, compares
1976
- each deterministic event batch, and optionally verifies the final state with a stable checksum.
1977
- - `SimulationRuntime` accepts an optional `history: { actorOf, limit? }`; `canUndo`, `canRedo`,
1978
- `undo()` and `redo()` restore complete state, scheduler, RNG and journal checkpoints.
1979
- - `CanonicalState` / `CanonicalStateSnapshot` - a defensive, JSON-safe root state combined with
1980
- `StateRegistry` extensions; snapshots, version migrations, transactions and restores cover all
1981
- pieces atomically.
1982
- - `LockstepClient` supports optional command validation, receives a session seed and initial
1983
- state, and can submit per-tick state checksums; `onDesync` reports differing peer checksums.
1984
- `createLockstepServer` accepts matching `seed`, `initialState` and `validateInput` options.
1985
- - `MWL_SCHEMA_01` / `MWL_SCHEMA_10` and `schema01` / `schema10` identify the supported MWL
1986
- vocabularies; `mwl migrate --to 1.0` updates the document version without changing its data.
1987
- Schema 1.0 additionally enforces declared required attributes and child cardinalities.
1988
- - `ScriptHost` and `createExpressionScriptHost` - the game-owned boundary for executable content.
1989
- The expression host is the statement-free default. The main `mwl` entry point
1990
- exports its types without loading a scripting VM. Projects that opt in to the optional
1991
- `@datamoc/pyroeis` dependency can import `createPyroeisScriptHost` from `@datamoc/mw_games/mwl/pyroeis`.
1992
- It provides Lua 5.4 evaluation, chunks, named function calls, JSON-shaped context values, and
1993
- `mwg_emit(name, payload)` events. The adapter opens only the sandbox-safe standard libraries
1994
- (base, coroutine, math, string, table, utf8): `io`, `os`, `debug` and `package` with its
1995
- `require` are never constructed, identically in Node and the browser, the base library's `load`,
1996
- `loadfile` and `dofile` are removed, and chunks compile in text mode only, so a binary
1997
- `\x1bLua` dump is rejected. It replaces `math.random` with seeded deterministic random, and
1998
- enforces an
1999
- instruction budget and a `memoryLimit` (bytes of string and buffer data one call may
2000
- allocate, 32 MB by default, parsing included), since one `..` or `string.rep` instruction
2001
- can allocate without bound. Scripts get `local x <const>`, `local x <close>` (with `__close`,
2002
- run on a normal exit, `break`, `return` and error, and unwound by a limit error too) and
2003
- `coroutine.close`, from fork 0.3.0; a `__close` cannot yield. The byte budget is the VM's
2004
- per-call allocation limit (`limits.totalAllocation` on `PyroeisVm`), so a script's own `pcall`
2005
- sees the standard `not enough memory`
2006
- while the host still rejects the call. `getmetatable("")` returns `false`. Globals persist between calls on one host, so
2007
- mutually untrusted scripts need a host each. Lua VM state is not save data: reload scripts
2008
- from the game's entry point.
2009
-
2010
- - `createPyroeisRuntime` (the same optional `mwl/pyroeis` subpath) returns a
2011
- `PyroeisRuntime` for games that need synchronous API responses, live state and
2012
- resumable handlers. It keeps the smaller `ScriptHost` contract intact.
2013
- `defineFunction(path, callback)` exposes a host function with arguments and a
2014
- result, and `get`/`set` use dotted global paths made of identifiers. `run` executes
2015
- text and returns its first result; `call` accepts a path or a `PyroeisReference`.
2016
- `reference(path)` retains a Lua table or function's identity, including callbacks
2017
- registered by Lua; dispose references when finished, or dispose the entire runtime.
2018
- `PyroeisValue` includes plain values, arrays, objects, Maps, BigInts, binary strings
2019
- as Uint8Arrays and owned references. Ordinary tables are copied on read; contiguous
2020
- sequences become arrays. Bound tables retain their references even inside lists.
2021
- Nil maps to null; assigning it removes a Lua table entry. Lua VM state and references
2022
- are not JSON save data.
2023
- `createTable(PyroeisTableBinding)` creates a live proxy: `get` and optional `set`
2024
- run on ordinary indexed reads/writes, with optional `keys` for `pairs` and `length`
2025
- for `#`. Nested bindings can return other proxy references, allowing a game to expose
2026
- a side list, each side's resources, a variable namespace or an entity lookup.
2027
- Its metatable is hidden; Lua `rawget`/`rawset` still bypass bindings, so callbacks
2028
- must enforce game rules themselves.
2029
- `PyroeisRuntimeOptions.modules` snapshots exact module IDs and embedded source
2030
- strings. Lua `require` caches the first result with Lua identity; `dofile` reruns
2031
- a source and returns all results. A game can alias `game.require = require` without
2032
- copying a loader. Unknown IDs, cyclic loads and binary chunks are rejected.
2033
- No filesystem, fetch or XHR is involved; `io`, `os`, `debug`, `package`, `load` and
2034
- `loadfile` stay absent. Closing a suspended module load clears its loading marker.
2035
- `defineYieldingFunction` returns request values to the host; a
2036
- `PyroeisCoroutine` created by `coroutine(pathOrReference)` exposes `status`,
2037
- `resume(args)` and `close()`. It can also adopt a thread created by Lua, including
2038
- one already suspended by the script; each thread has one host controller.
2039
- Each resume returns `{ done, values }`, with scene
2040
- answers supplied as the next resume's arguments. Close handlers run on explicit
2041
- closure or runtime disposal; failed handlers retain their error until closure.
2042
- Instruction and string/buffer allocation budgets cover compilation, modules,
2043
- host-side indexing and coroutine resumes. Nested host calls share the current
2044
- budget; a later top-level call/resume gets a fresh budget. Optional `timeLimit`
2045
- bounds wall-clock time, including callbacks, but cannot preempt host JavaScript.
2046
- Randomness is seeded; bounded `math.random` intervals require safe integers.
2047
- Total JavaScript heap and some native operations remain outside these bounds.
2048
- - `luaToJs(source, { format?, header? })` (same subpath) translates Lua to readable
2049
- JavaScript without running it and returns `{ code, warnings, exports, freeGlobals }`.
2050
- Metatables, coroutines, general `goto` and some patterns stay as `TODO(lua2js)`
2051
- comments with a matching warning; invalid Lua throws `LuaSyntaxError`. Pyroeis's
2052
- runtime numeric `compile` is not used: it is skipped whenever execution limits are on.
2053
-
2054
- `MwlRuntime` exposes `fireEvent(id)` for named event execution. Event conditions compare
2055
- numeric variables numerically, `set_variable` accepts the bounded MWL expression syntax,
2056
- filters can match a unit id, `unit_at` can constrain a side, and both moveto events and unit
2057
- filters take coordinates as comma-separated lists or inclusive ranges (`x=1,2,4-5`). A
2058
- `set_variable` (either spelling, `[set_variable]` or `[command] name="set_variable"`) may
2059
- declare what its own `value=` means with `mode=literal|number|expression`: `literal` keeps the
2060
- text exactly as written, `number` parses it and refuses anything else, `expression` evaluates
2061
- it and treats a missing variable as an error. Without a mode the value is inferred from its
2062
- shape (`$name` copies a variable, a finite number is a number, operator characters or a
2063
- numeric variable's name evaluate), which is what hand-authored content relies on and what a
2064
- compiler target cannot, since a literal such as `Raise Walking Corpse (8 Gold)` would be read
2065
- as an expression. `path=` is that same write with a target built from variables
2066
- (`zombies[$index].allow_recruit`, or `$target` for a variable holding a path), expanded before
2067
- the path is walked; a reference that names nothing throws rather than leaving an empty segment.
2068
- `name=`/`target=` stay literal (a `$` there is not a reference today, so it is not read as one
2069
- now), which keeps every existing write meaning exactly what it did. Top-level
2070
- `say` commands execute normally. Dialogue choices are
2071
- delivered in `MwlMessage.choices` and answered with `answerDialogue`; pending choices are
2072
- included in save data. Commands after a dialogue in the same event run immediately, before
2073
- the answer, so deferred follow-up commands belong in the selected choice event.
2074
-
2075
- The WML action vocabulary (item 250) is on the same event surface. `fire_event` runs another event
2076
- by id. `store_unit` writes matching units into a world variable, `unstore_unit` and `recall` write
2077
- them back (recall can move one to a chosen hex and side), `modify_unit` changes what its `[set]`
2078
- names and `heal_unit` adds `amount` (or sets `hp`). A unit carries its own `name`, `role`/function
2079
- and `can_recruit` leader flag: `[unit]` sets them, a side's own leader is `can_recruit`, and
2080
- `unitMatchesFilter` reads all three, so `[filter] role=courier`, `name=Kalenz` and
2081
- `can_recruit=yes` select on them (`[store_unit]` and the save keep them too). `set_terrain` changes
2082
- one map cell, `capture_village` records ownership in `MwlWorld.villages`, and `clear_shroud`
2083
- records the hexes a side has uncovered in `MwlWorld.clearedShroud`; the fog itself stays a game
2084
- layer. At scenario level, `[role]` fills `MwlWorld.roles` and stamps the role onto the units it
2085
- matches, `[object]` lands in `MwlWorld.objects`, and `[story]` in `MwlWorld.story` as data
2086
- (rendering a story screen is its own item), all kept in the save. `[item]` is deliberately not
2087
- among them: the tag already means an inventory item definition here, so WML's map-placement shape
2088
- would have collided with it.
2089
-
2090
- Typical build-time usage:
2091
-
2092
- ```sh
2093
- npm run mwl -- build content/ -o generated/
2094
- ```
2095
-
2096
- The executable [`mwl-content` example](../examples/view.html?ex=mwl-content) shows the full
2097
- path: authored content, generated catalog and manifests, then a small game reading the result
2098
- at runtime. A Wesnoth adapter can convert native `.cfg` files to the same MWL input model
2099
- before invoking this build step.
2100
-
2101
- ## `mwl/pyroeis`
2102
-
2103
- The optional Lua 5.4 entry point, `@datamoc/mw_games/mwl/pyroeis`, kept off the `mwl` barrel
2104
- so the Pyroeis VM (the optional `@datamoc/pyroeis` dependency) loads only when a game imports
2105
- it. The `mwl` section above describes its behaviour in full; the exports are:
2106
-
2107
- - `createPyroeisScriptHost(options?)` - a sandboxed `ScriptHost` (`PyroeisScriptHostOptions`:
2108
- `instructionLimit`, `memoryLimit`, `seed`). Only the base, coroutine, math, string, table and
2109
- utf8 libraries are opened, `load` is removed, `math.random` is seeded, and every call is
2110
- bounded; globals persist per host.
2111
- - `createPyroeisRuntime(options?)` - a `PyroeisRuntime` for synchronous host calls and live
2112
- state: `run`, `call`, `get`/`set` on dotted paths, `reference`, `defineFunction`,
2113
- `defineYieldingFunction`, `createTable` (live proxy tables), `coroutine` and `dispose`.
2114
- Types: `PyroeisValue`, `PyroeisReference`, `PyroeisCoroutine`, `PyroeisTableBinding`,
2115
- `PyroeisRuntimeOptions`.
2116
- - `luaToJs(source, options?)` - translates Lua to readable JavaScript without running it
2117
- (`LuaToJsOptions`/`LuaToJsResult` are re-exported).
2118
-
2119
- ## `ai`
2120
-
2121
- Renderer-free decision runners. The game owns perception, navigation, combat rules and
2122
- goals; these modules provide the execution boundary, deterministic choice support, explicit
2123
- actions, serialisable state, diagnostics and budgets.
2124
-
2125
- - `NeuralPolicy` over `NeuralModel`/`DenseLayer`: dependency-free dense inference,
2126
- ReLU hidden layers and linear output scores, with flat row-major weights and an
2127
- explicit `observationVersion`. Construction validates dimensions and finite values
2128
- before copying the weights; limits are 32 layers, 4096 neurons per layer and one
2129
- million parameters. `predict(input, output?)` reuses activation buffers and can
2130
- write into a caller-owned `Float64Array`. `exportModel()` returns a plain-data copy
2131
- suitable for bundling in a local-file game.
2132
- `selectAction(NeuralObservation, random?)` masks illegal actions, chooses the first
2133
- best score on ties and returns `null` when all actions are masked. A seeded random
2134
- callback enables stable-softmax sampling. `behavior(id, actions, observe, sample?)`
2135
- maps the same policy into `JavaScriptAI`, using its seeded random callback when
2136
- sampling. `predictBatchAsync(inputs, { signal?, timeout? })` runs a whole inference
2137
- batch on one worker. The caller owns stale-result rejection if a scene or position
2138
- changes while awaiting it. Tiny predictions are usually cheaper synchronously;
2139
- measure batches before offloading them.
2140
-
2141
- - `JavaScriptAI` - registers named behaviours, checks them in declaration order, and returns
2142
- a JSON-shaped action or an idle decision. A behaviour receives perception, mutable plain
2143
- state, seeded `random()`, `emit()` and a cooperative `checkpoint()` for cancellation and
2144
- step or wall-clock budgets. JavaScript cannot interrupt a synchronous function that never
2145
- checks its checkpoint, so long-running behaviours must cooperate.
2146
- - `Suggester` - the suggestion mode (roadmap 397): the same decision call a game makes
2147
- for the AI, pointed at a hint UI instead of the world, throttled by a frame-count
2148
- budget (`every`, never wall clock) so a hint does not tax the frame budget. The
2149
- first `update` decides immediately, throttled updates return null while `latest`
2150
- keeps the previous suggestion, an `idle` decision is a suggestion the UI reads
2151
- (`decision.action === null`), and `clear` drops it. The decider must not mutate
2152
- game state to compute a suggestion; what the player does with one is the game's.
2153
- - `alphaBetaSearch`/`AlphaBetaGame` - deterministic minimax with alpha-beta pruning over a
2154
- game-owned immutable-state adapter. The adapter supplies legal moves, transitions, terminal
2155
- detection, current player and evaluation from the root player's perspective. `depth`,
2156
- `maxNodes`, cancellation and node diagnostics bound the search; the same primitive works
2157
- for a local actor and for a top-level controller such as a chess master.
2158
- `rootSplits`/`firstWins` are the root-split halves of an off-thread search: the split
2159
- pairs each root move with its child in game order, and first-wins reduces scored moves
2160
- so ties keep the earlier move.
2161
- - `personalScoreView`/`sideScoreView`/`scoreWith` over `ScoreSubject`/`ScoreView`/
2162
- `ScorePersonality` - the numbers a mind that weighs outcomes needs, for the case where a search
2163
- is the wrong tool. The game owns what anything is worth (`scoreOf`), the framework owns how a
2164
- view is assembled (own, allies and enemies kept apart, plus a `seen` count), and the mind owns
2165
- what it cares about: a personality is weights, so a selfish scout and a loyal one are content
2166
- rather than two AI implementations. Both scopes read through the same code and differ only in
2167
- the visibility set they are handed, a unit's own sight or `FactionFog.sees(side)`. `ScoreSubject`
2168
- also carries an optional `type`, `role`/function, `can_recruit` leader flag and `name`, and
2169
- `subjectsWhere`/`ScoreSubjectFilter` select a world on any of them, so a mind finds "the enemy
2170
- leader" (`{ side: 'red', can_recruit: true }`) without re-deriving it from ids.
2171
-
2172
- - The heuristic AI (item 269): `Aspects`/`AspectValues`/`AspectValue` - the named tuning knobs
2173
- (`aggression`, `caution`, `keep_away`, `recruitment_pattern`, ...) with typed readers and no
2174
- built-in values, since the numbers are content; `Difficulty`/`DifficultyLevel` - named levels as
2175
- aspect overrides on a base set; `Goals`/`Goal`/`GoalKind` - per-unit orders a stage's `weigh`
2176
- reads; `RecruitmentPattern` - a side's recruit order, cycled, with a fallback. `HeuristicAI`
2177
- runs candidate actions through `HeuristicStage`s in order, the first whose `when` passes scoring
2178
- every `HeuristicCandidate` and taking the best (earlier candidate on a tie); a candidate may carry
2179
- the acting unit's own `type`/`role`/`can_recruit`/`name` for a custom `weigh` to read.
2180
- `defaultWeigh` is each factor times the aspect of the same name with `keepAwayScore` for a
2181
- candidate's `distance`; `goalScore` is what a custom `weigh` adds for a goal.
2182
- - `AIDecision`/`AIDecisionInput`/`AIAction` - the shared contract for perception, explicit
2183
- action objects, status (`action`, `idle`, `cancelled`, or `budget-exceeded`), emitted
2184
- diagnostics and state snapshots.
2185
- - `AICancelledError`/`AIBudgetExceededError` - the cooperative control-flow errors used by
2186
- a JavaScript behaviour when it observes cancellation or exceeds its configured budget.
2187
- - `exportState`/`importState` - versioned, JSON-shaped agent state. Function closures, VM
2188
- state and arbitrary object graphs never become save data.
2189
- - `LuaAI`/`createLuaAI` from `@datamoc/mw_games/ai/lua` - optional Lua 5.4 provider with the same
2190
- action and state envelope. A Lua function receives `(perception, state)` and returns an action
2191
- table or `{ action, state, events }`. It uses the existing optional Pyroeis host, which
2192
- removes filesystem, process, module-loading, clock and debug access, supplies seeded random,
2193
- and enforces an instruction budget.
2194
- - `AIAgentDefinition`/`AIBehavior` - JavaScript registrations; Lua registrations instead
2195
- provide a source chunk and an entry function name. Both remain game-owned content and
2196
- do not include any reference game's code or data.
2197
-
2198
- MWL `[ai]` profiles describe the boundary without embedding executable game rules: `scope`
2199
- is `actor` or `controller`, `provider` is `javascript` or `lua`, `algorithm` can be
2200
- `rules` or `alpha_beta`, and `depth`, `max_nodes`, `player`, `moves`, `apply`, `terminal`
2201
- and `evaluate` identify search limits and game-owned operations. A game resolves those names
2202
- to JavaScript behaviours or Lua functions and supplies the actual state, legal moves and
2203
- evaluation.
2204
-
2205
- ### Skeleton extensions (417-421)
2206
-
2207
- - `skeleton.solveTwoBoneIK(skeleton, first, second, target, bend, pose)` solves a connected
2208
- two-bone chain in world coordinates. `bend` is +1 or -1; positive bends clockwise on screen.
2209
- Positive finite lengths and a zero origin on the second bone are required. Unreachable
2210
- targets throw with the chain names. Rest rotations and rotated ancestors are supported.
2211
- - `Bone.limits: { min, max }` bounds the absolute local rotation in degrees, including rest
2212
- rotation. `skeleton.validatePose` checks an authored pose; `samplePose` and
2213
- `sampleTransformPose` accept an optional skeleton for validation. Mixers and `resolve`
2214
- validate automatically. Use a nonnegative or nonpositive interval to constrain bend direction.
2215
- - `Keyframe.translations` and `Keyframe.scales` map bone names to `{ x, y }` channels.
2216
- `skeleton.sampleTransformPose` and `skeleton.advancePose` return a `TransformPose`, with
2217
- `rotations`, `translations` and `scales`. Missing channels interpolate toward zero translation
2218
- or unit scale. Looping, reverse playback, holding, priority layers and crossfades share the
2219
- rotation timeline. Legacy `samplePose` and `advance` return rotations only.
2220
- - `SkeletalSprite.apply` accepts either rotation poses or `TransformPose`; its mixer uses
2221
- `advancePose` automatically. `setDiagnostics(true)` explicitly enables bone lines, pivot
2222
- crosses, joint circles and tips. Omit it in release builds; disabled rigs allocate no overlay.
2223
- - `assets.loadSvgParts(sourceOrPath, { resolution, groups })` returns borrowed textures keyed
2224
- by top-level SVG group name. It preserves the full SVG canvas, group attributes, shared defs
2225
- and styles. Repeated loads reuse textures; resolutions have separate cache entries. Compiled
2226
- asset paths decode directly from data URIs under `file://`. Unknown groups and invalid
2227
- resolutions throw by name. `releaseSvgParts(parts)` unloads them once no sprite uses them.
2228
- - `node tools/check-skeleton-extensions-browser.mjs [local-vehicle.svg]` builds a classic
2229
- local-file page, verifies WebGL rendering, texture reuse, resolution isolation and diagnostic
2230
- cleanup, and writes screenshots under `benchmark-results/skeleton-extensions/`. The default
2231
- vehicle is generated; passing a local consumer SVG embeds it only into ignored scratch output.
2232
-
2233
- ### Deformation, articulated SVG loading and asset filtering (414-416)
2234
-
2235
- - `PinnedDeform` / `DeformableSprite` expose pinned control points. `dragVertex`, `nudgeVertex`
2236
- and `resetVertices` change GPU vertex positions without changing UVs or rotating the sprite.
2237
- `dragVertices([{ index, x, y }, ...])` validates a batch before applying it and uploads once;
2238
- the pure `PinnedDeform.dragMany` performs the same batch operation without a renderer.
2239
- - `loadSvgSkeleton(sourceOrPath, { skeleton, bindings?, pivots?, resolution?, mixer? })` returns
2240
- `{ sprite, textures }`. `sprite` is a `SkeletalSprite` with named SVG groups already bound.
2241
- By default matching groups bind in SVG document order. Explicit `bindings` provide draw order,
2242
- group-to-bone mapping and optional pivot/rest-angle overrides. Pivots come from `data-pivot-x`
2243
- and `data-pivot-y` (root SVG user coordinates), or a `pivots` map keyed by group id. Missing
2244
- pivots, groups, bones and duplicate bindings fail by name. Separately bound descendants are
2245
- removed from parent textures; ancestor transforms, shared styles and defs survive. Artwork is
2246
- normalized against each bone's rest angle so poses rotate the correct limbs about their pivots.
2247
- Browser DOMParser/XMLSerializer are required. Compiled paths work under `file://`. Destroy the
2248
- sprite with `{ children: true }`, then call `releaseSvgParts(textures)` when all users are done.
2249
- - `mwgPage({ assetFiles: ['hero.svg', 'music/theme.ogg'] })` embeds only those asset-folder paths.
2250
- Omit `assetFiles` to keep all supported assets; `[]` embeds none. Unknown or unsupported named
2251
- entries fail before replacing compiled asset scripts. Both `emitPage` and `compileResources`
2252
- accept the same option. `credits.json` generates `CREDITS.txt` when selected, or with no filter.
2253
- - Browser checks: `node tools/check-sprite-deform-browser.mjs [local-bird.svg]` and
2254
- `node tools/check-svg-skeleton-browser.mjs [local-character.svg] [local-manifest.json]` build
2255
- local-file WebGL pages and save rest/posed screenshots under `benchmark-results/`. Defaults
2256
- use generated art; consumer inputs remain in ignored scratch output only.