1681-engine 0.0.0-stage → 0.5.8

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 (1014) hide show
  1. package/CHANGELOG.md +304 -0
  2. package/LICENSE +21 -0
  3. package/README.md +164 -2
  4. package/dist/1681-engine.js +417 -0
  5. package/dist/1681-engine.js.map +1 -0
  6. package/dist/ambient/ColorGrade.js +41 -0
  7. package/dist/ambient/ColorGrade.js.map +1 -0
  8. package/dist/ambient/DayClock.js +57 -0
  9. package/dist/ambient/DayClock.js.map +1 -0
  10. package/dist/ambient/WeatherLayer.js +91 -0
  11. package/dist/ambient/WeatherLayer.js.map +1 -0
  12. package/dist/ambient/grade.js +13 -0
  13. package/dist/ambient/grade.js.map +1 -0
  14. package/dist/ambient/weather.js +52 -0
  15. package/dist/ambient/weather.js.map +1 -0
  16. package/dist/anim/AnimStateMachine.js +164 -0
  17. package/dist/anim/AnimStateMachine.js.map +1 -0
  18. package/dist/anim/Animator.js +67 -0
  19. package/dist/anim/Animator.js.map +1 -0
  20. package/dist/anim/animStateCompile.js +113 -0
  21. package/dist/anim/animStateCompile.js.map +1 -0
  22. package/dist/anim/animStateSystem.js +17 -0
  23. package/dist/anim/animStateSystem.js.map +1 -0
  24. package/dist/anim/animationSystem.js +15 -0
  25. package/dist/anim/animationSystem.js.map +1 -0
  26. package/dist/anim/asepriteSlices.js +22 -0
  27. package/dist/anim/asepriteSlices.js.map +1 -0
  28. package/dist/anim/asepriteTags.js +35 -0
  29. package/dist/anim/asepriteTags.js.map +1 -0
  30. package/dist/anim/parseAseprite.js +83 -0
  31. package/dist/anim/parseAseprite.js.map +1 -0
  32. package/dist/assets/AssetLoader.js +104 -0
  33. package/dist/assets/AssetLoader.js.map +1 -0
  34. package/dist/assets/loadAseprite.js +50 -0
  35. package/dist/assets/loadAseprite.js.map +1 -0
  36. package/dist/assets/takeCleanerWorker-DTcI_Jqr.js +31 -0
  37. package/dist/assets/takeCleanerWorker-DTcI_Jqr.js.map +1 -0
  38. package/dist/audio/Footsteps.js +26 -0
  39. package/dist/audio/Footsteps.js.map +1 -0
  40. package/dist/audio/MusicPlayer.js +78 -0
  41. package/dist/audio/MusicPlayer.js.map +1 -0
  42. package/dist/audio/SoundEngine.js +119 -0
  43. package/dist/audio/SoundEngine.js.map +1 -0
  44. package/dist/audio/cleanTake.js +30 -0
  45. package/dist/audio/cleanTake.js.map +1 -0
  46. package/dist/audio/music/ElementVoice.js +35 -0
  47. package/dist/audio/music/ElementVoice.js.map +1 -0
  48. package/dist/audio/music/GraphVoice.js +39 -0
  49. package/dist/audio/music/GraphVoice.js.map +1 -0
  50. package/dist/audio/music/MusicChannel.js +58 -0
  51. package/dist/audio/music/MusicChannel.js.map +1 -0
  52. package/dist/audio/music/musicVoice.js +13 -0
  53. package/dist/audio/music/musicVoice.js.map +1 -0
  54. package/dist/audio/sampleBank.js +82 -0
  55. package/dist/audio/sampleBank.js.map +1 -0
  56. package/dist/audio/soundTable.js +9 -0
  57. package/dist/audio/soundTable.js.map +1 -0
  58. package/dist/audio/synth.js +36 -0
  59. package/dist/audio/synth.js.map +1 -0
  60. package/dist/core/BitmapLabel.js +49 -0
  61. package/dist/core/BitmapLabel.js.map +1 -0
  62. package/dist/core/Camera.js +150 -0
  63. package/dist/core/Camera.js.map +1 -0
  64. package/dist/core/Clock.js +30 -0
  65. package/dist/core/Clock.js.map +1 -0
  66. package/dist/core/Graphics.js +69 -0
  67. package/dist/core/Graphics.js.map +1 -0
  68. package/dist/core/Group.js +29 -0
  69. package/dist/core/Group.js.map +1 -0
  70. package/dist/core/Image.js +51 -0
  71. package/dist/core/Image.js.map +1 -0
  72. package/dist/core/ObjectFactory.js +55 -0
  73. package/dist/core/ObjectFactory.js.map +1 -0
  74. package/dist/core/Pointer.js +58 -0
  75. package/dist/core/Pointer.js.map +1 -0
  76. package/dist/core/Rectangle.js +51 -0
  77. package/dist/core/Rectangle.js.map +1 -0
  78. package/dist/core/Stage.js +86 -0
  79. package/dist/core/Stage.js.map +1 -0
  80. package/dist/core/Text.js +22 -0
  81. package/dist/core/Text.js.map +1 -0
  82. package/dist/core/TextureRegistry.js +111 -0
  83. package/dist/core/TextureRegistry.js.map +1 -0
  84. package/dist/core/Timeline.js +211 -0
  85. package/dist/core/Timeline.js.map +1 -0
  86. package/dist/core/TimelineBuilder.js +73 -0
  87. package/dist/core/TimelineBuilder.js.map +1 -0
  88. package/dist/core/TimelineChild.js +84 -0
  89. package/dist/core/TimelineChild.js.map +1 -0
  90. package/dist/core/Tweener.js +136 -0
  91. package/dist/core/Tweener.js.map +1 -0
  92. package/dist/core/atlas.js +38 -0
  93. package/dist/core/atlas.js.map +1 -0
  94. package/dist/core/atlasPlan.js +22 -0
  95. package/dist/core/atlasPlan.js.map +1 -0
  96. package/dist/core/eases.js +21 -0
  97. package/dist/core/eases.js.map +1 -0
  98. package/dist/core/gameObject.js +115 -0
  99. package/dist/core/gameObject.js.map +1 -0
  100. package/dist/core/pixiPatches.js +18 -0
  101. package/dist/core/pixiPatches.js.map +1 -0
  102. package/dist/core/timelinePlace.js +24 -0
  103. package/dist/core/timelinePlace.js.map +1 -0
  104. package/dist/core/tweenProps.js +12 -0
  105. package/dist/core/tweenProps.js.map +1 -0
  106. package/dist/debug/DebugOverlay.js +94 -0
  107. package/dist/debug/DebugOverlay.js.map +1 -0
  108. package/dist/debug/DrawCallCounter.js +41 -0
  109. package/dist/debug/DrawCallCounter.js.map +1 -0
  110. package/dist/debug/ErrorLog.js +22 -0
  111. package/dist/debug/ErrorLog.js.map +1 -0
  112. package/dist/debug/FrameStats.js +42 -0
  113. package/dist/debug/FrameStats.js.map +1 -0
  114. package/dist/debug/inspectWorld.js +29 -0
  115. package/dist/debug/inspectWorld.js.map +1 -0
  116. package/dist/diagnostics/ErrorDeduper.js +27 -0
  117. package/dist/diagnostics/ErrorDeduper.js.map +1 -0
  118. package/dist/diagnostics/FrameSampler.js +42 -0
  119. package/dist/diagnostics/FrameSampler.js.map +1 -0
  120. package/dist/diagnostics/bootWatch.js +21 -0
  121. package/dist/diagnostics/bootWatch.js.map +1 -0
  122. package/dist/diagnostics/captureErrors.js +27 -0
  123. package/dist/diagnostics/captureErrors.js.map +1 -0
  124. package/dist/diagnostics/contextLoss.js +25 -0
  125. package/dist/diagnostics/contextLoss.js.map +1 -0
  126. package/dist/diagnostics/frameStats.js +31 -0
  127. package/dist/diagnostics/frameStats.js.map +1 -0
  128. package/dist/diagnostics/gpuInfo.js +22 -0
  129. package/dist/diagnostics/gpuInfo.js.map +1 -0
  130. package/dist/diagnostics/renderGuard.js +24 -0
  131. package/dist/diagnostics/renderGuard.js.map +1 -0
  132. package/dist/ecs/SparseSet.js +55 -0
  133. package/dist/ecs/SparseSet.js.map +1 -0
  134. package/dist/ecs/World.js +307 -0
  135. package/dist/ecs/World.js.map +1 -0
  136. package/dist/ecs/fields.js +26 -0
  137. package/dist/ecs/fields.js.map +1 -0
  138. package/dist/engine/Engine.js +82 -0
  139. package/dist/engine/Engine.js.map +1 -0
  140. package/dist/engine/FixedLoop.js +37 -0
  141. package/dist/engine/FixedLoop.js.map +1 -0
  142. package/dist/engine/Scene.js +79 -0
  143. package/dist/engine/Scene.js.map +1 -0
  144. package/dist/engine/SceneManager.js +73 -0
  145. package/dist/engine/SceneManager.js.map +1 -0
  146. package/dist/events/EventBus.js +42 -0
  147. package/dist/events/EventBus.js.map +1 -0
  148. package/dist/fx/FloatingText.js +72 -0
  149. package/dist/fx/FloatingText.js.map +1 -0
  150. package/dist/fx/hitStop.js +28 -0
  151. package/dist/fx/hitStop.js.map +1 -0
  152. package/dist/fx/viewCull.js +10 -0
  153. package/dist/fx/viewCull.js.map +1 -0
  154. package/dist/i18n/Translator.js +72 -0
  155. package/dist/i18n/Translator.js.map +1 -0
  156. package/dist/i18n/extractStrings.js +58 -0
  157. package/dist/i18n/extractStrings.js.map +1 -0
  158. package/dist/i18n/formatMessage.js +19 -0
  159. package/dist/i18n/formatMessage.js.map +1 -0
  160. package/dist/input/Actions.js +131 -0
  161. package/dist/input/Actions.js.map +1 -0
  162. package/dist/input/AimGesture.js +75 -0
  163. package/dist/input/AimGesture.js.map +1 -0
  164. package/dist/input/Keyboard.js +54 -0
  165. package/dist/input/Keyboard.js.map +1 -0
  166. package/dist/input/Keymap.js +171 -0
  167. package/dist/input/Keymap.js.map +1 -0
  168. package/dist/input/TargetLock.js +73 -0
  169. package/dist/input/TargetLock.js.map +1 -0
  170. package/dist/input/aimAxis.js +8 -0
  171. package/dist/input/aimAxis.js.map +1 -0
  172. package/dist/input/keyChord.js +29 -0
  173. package/dist/input/keyChord.js.map +1 -0
  174. package/dist/input/longPress.js +32 -0
  175. package/dist/input/longPress.js.map +1 -0
  176. package/dist/input/stickAxis.js +23 -0
  177. package/dist/input/stickAxis.js.map +1 -0
  178. package/dist/input/touchDetect.js +7 -0
  179. package/dist/input/touchDetect.js.map +1 -0
  180. package/dist/light/LightLayer.js +84 -0
  181. package/dist/light/LightLayer.js.map +1 -0
  182. package/dist/nav/MinHeap.js +39 -0
  183. package/dist/nav/MinHeap.js.map +1 -0
  184. package/dist/nav/findPath.js +78 -0
  185. package/dist/nav/findPath.js.map +1 -0
  186. package/dist/nav/navGrid.js +36 -0
  187. package/dist/nav/navGrid.js.map +1 -0
  188. package/dist/nav/nearestOpen.js +19 -0
  189. package/dist/nav/nearestOpen.js.map +1 -0
  190. package/dist/nav/straightenPath.js +51 -0
  191. package/dist/nav/straightenPath.js.map +1 -0
  192. package/dist/net/Connection.js +84 -0
  193. package/dist/net/Connection.js.map +1 -0
  194. package/dist/net/InterpolationBuffer.js +57 -0
  195. package/dist/net/InterpolationBuffer.js.map +1 -0
  196. package/dist/net/PredictedMover.js +61 -0
  197. package/dist/net/PredictedMover.js.map +1 -0
  198. package/dist/net/Room.js +92 -0
  199. package/dist/net/Room.js.map +1 -0
  200. package/dist/net/RoomHost.js +101 -0
  201. package/dist/net/RoomHost.js.map +1 -0
  202. package/dist/net/cadence.js +22 -0
  203. package/dist/net/cadence.js.map +1 -0
  204. package/dist/net/constants.js +11 -0
  205. package/dist/net/constants.js.map +1 -0
  206. package/dist/net/lobby/LobbyClient.js +124 -0
  207. package/dist/net/lobby/LobbyClient.js.map +1 -0
  208. package/dist/net/lobby/LobbyHost.js +366 -0
  209. package/dist/net/lobby/LobbyHost.js.map +1 -0
  210. package/dist/net/lobby/LobbyRooms.js +66 -0
  211. package/dist/net/lobby/LobbyRooms.js.map +1 -0
  212. package/dist/net/lobby/Matchmaker.js +106 -0
  213. package/dist/net/lobby/Matchmaker.js.map +1 -0
  214. package/dist/net/movement.js +83 -0
  215. package/dist/net/movement.js.map +1 -0
  216. package/dist/net/protocol.js +11 -0
  217. package/dist/net/protocol.js.map +1 -0
  218. package/dist/net/serverClock.js +22 -0
  219. package/dist/net/serverClock.js.map +1 -0
  220. package/dist/net/snapshotCodec.js +92 -0
  221. package/dist/net/snapshotCodec.js.map +1 -0
  222. package/dist/parallax/Parallax.js +32 -0
  223. package/dist/parallax/Parallax.js.map +1 -0
  224. package/dist/parallax/ParallaxLayer.js +70 -0
  225. package/dist/parallax/ParallaxLayer.js.map +1 -0
  226. package/dist/parallax/parallaxMath.js +27 -0
  227. package/dist/parallax/parallaxMath.js.map +1 -0
  228. package/dist/particles/Emitter.js +108 -0
  229. package/dist/particles/Emitter.js.map +1 -0
  230. package/dist/particles/ParticleBudget.js +32 -0
  231. package/dist/particles/ParticleBudget.js.map +1 -0
  232. package/dist/particles/ParticleSim.js +60 -0
  233. package/dist/particles/ParticleSim.js.map +1 -0
  234. package/dist/particles/particleCurves.js +48 -0
  235. package/dist/particles/particleCurves.js.map +1 -0
  236. package/dist/particles/particleSampling.js +30 -0
  237. package/dist/particles/particleSampling.js.map +1 -0
  238. package/dist/physics/Body.js +202 -0
  239. package/dist/physics/Body.js.map +1 -0
  240. package/dist/physics/BroadPhase.js +56 -0
  241. package/dist/physics/BroadPhase.js.map +1 -0
  242. package/dist/physics/Contact.js +76 -0
  243. package/dist/physics/Contact.js.map +1 -0
  244. package/dist/physics/ContactSolver.js +70 -0
  245. package/dist/physics/ContactSolver.js.map +1 -0
  246. package/dist/physics/PhysicsWorld.js +221 -0
  247. package/dist/physics/PhysicsWorld.js.map +1 -0
  248. package/dist/physics/SpatialHash.js +39 -0
  249. package/dist/physics/SpatialHash.js.map +1 -0
  250. package/dist/physics/collide.js +76 -0
  251. package/dist/physics/collide.js.map +1 -0
  252. package/dist/physics/collidePolygon.js +94 -0
  253. package/dist/physics/collidePolygon.js.map +1 -0
  254. package/dist/physics/contactReport.js +14 -0
  255. package/dist/physics/contactReport.js.map +1 -0
  256. package/dist/physics/drawColliders.js +31 -0
  257. package/dist/physics/drawColliders.js.map +1 -0
  258. package/dist/physics/physicsSystem.js +8 -0
  259. package/dist/physics/physicsSystem.js.map +1 -0
  260. package/dist/physics/polygon.js +80 -0
  261. package/dist/physics/polygon.js.map +1 -0
  262. package/dist/physics/raycast.js +62 -0
  263. package/dist/physics/raycast.js.map +1 -0
  264. package/dist/physics/syncToBody.js +19 -0
  265. package/dist/physics/syncToBody.js.map +1 -0
  266. package/dist/physics/tileBodies.js +59 -0
  267. package/dist/physics/tileBodies.js.map +1 -0
  268. package/dist/physics/types.js +8 -0
  269. package/dist/physics/types.js.map +1 -0
  270. package/dist/pixel/Darkness.js +166 -0
  271. package/dist/pixel/Darkness.js.map +1 -0
  272. package/dist/pixel/DitherVignette.js +57 -0
  273. package/dist/pixel/DitherVignette.js.map +1 -0
  274. package/dist/pixel/Evaporation.js +85 -0
  275. package/dist/pixel/Evaporation.js.map +1 -0
  276. package/dist/pixel/NightShade.js +34 -0
  277. package/dist/pixel/NightShade.js.map +1 -0
  278. package/dist/pixel/PixelLayer.js +211 -0
  279. package/dist/pixel/PixelLayer.js.map +1 -0
  280. package/dist/pixel/SwayProp.js +75 -0
  281. package/dist/pixel/SwayProp.js.map +1 -0
  282. package/dist/pixel/lights.js +44 -0
  283. package/dist/pixel/lights.js.map +1 -0
  284. package/dist/pixel/nineSlice.js +62 -0
  285. package/dist/pixel/nineSlice.js.map +1 -0
  286. package/dist/pixel/paintLayer.js +36 -0
  287. package/dist/pixel/paintLayer.js.map +1 -0
  288. package/dist/pixel/palette.js +57 -0
  289. package/dist/pixel/palette.js.map +1 -0
  290. package/dist/pixel/pixel.js +278 -0
  291. package/dist/pixel/pixel.js.map +1 -0
  292. package/dist/pixel/pixelPaint.js +194 -0
  293. package/dist/pixel/pixelPaint.js.map +1 -0
  294. package/dist/pixel/pixelTone.js +164 -0
  295. package/dist/pixel/pixelTone.js.map +1 -0
  296. package/dist/pixel/propKit.js +41 -0
  297. package/dist/pixel/propKit.js.map +1 -0
  298. package/dist/pixel/ramp.js +102 -0
  299. package/dist/pixel/ramp.js.map +1 -0
  300. package/dist/pixel/selout.js +35 -0
  301. package/dist/pixel/selout.js.map +1 -0
  302. package/dist/pixel/spritePixels.js +59 -0
  303. package/dist/pixel/spritePixels.js.map +1 -0
  304. package/dist/pixel/swayRig.js +87 -0
  305. package/dist/pixel/swayRig.js.map +1 -0
  306. package/dist/pixel/vignetteMask.js +24 -0
  307. package/dist/pixel/vignetteMask.js.map +1 -0
  308. package/dist/pixel/weatherArt.js +61 -0
  309. package/dist/pixel/weatherArt.js.map +1 -0
  310. package/dist/pixel.js +90 -0
  311. package/dist/pixel.js.map +1 -0
  312. package/dist/platform/touch.js +33 -0
  313. package/dist/platform/touch.js.map +1 -0
  314. package/dist/postfx/BloomFilter.js +65 -0
  315. package/dist/postfx/BloomFilter.js.map +1 -0
  316. package/dist/postfx/ChromaticAberrationFilter.js +25 -0
  317. package/dist/postfx/ChromaticAberrationFilter.js.map +1 -0
  318. package/dist/postfx/ColorAdjustFilter.js +76 -0
  319. package/dist/postfx/ColorAdjustFilter.js.map +1 -0
  320. package/dist/postfx/CrtFilter.js +42 -0
  321. package/dist/postfx/CrtFilter.js.map +1 -0
  322. package/dist/postfx/PixelateFilter.js +27 -0
  323. package/dist/postfx/PixelateFilter.js.map +1 -0
  324. package/dist/postfx/PostFx.js +123 -0
  325. package/dist/postfx/PostFx.js.map +1 -0
  326. package/dist/postfx/ShockwaveFilter.js +49 -0
  327. package/dist/postfx/ShockwaveFilter.js.map +1 -0
  328. package/dist/postfx/VignetteFilter.js +37 -0
  329. package/dist/postfx/VignetteFilter.js.map +1 -0
  330. package/dist/postfx/fxAnimator.js +38 -0
  331. package/dist/postfx/fxAnimator.js.map +1 -0
  332. package/dist/postfx/fxShader.js +128 -0
  333. package/dist/postfx/fxShader.js.map +1 -0
  334. package/dist/postfx.js +26 -0
  335. package/dist/postfx.js.map +1 -0
  336. package/dist/react/ChoiceDialog.js +51 -0
  337. package/dist/react/ChoiceDialog.js.map +1 -0
  338. package/dist/react/ConfirmDialog.js +53 -0
  339. package/dist/react/ConfirmDialog.js.map +1 -0
  340. package/dist/react/Glyph.js +63 -0
  341. package/dist/react/Glyph.js.map +1 -0
  342. package/dist/react/Modal.js +38 -0
  343. package/dist/react/Modal.js.map +1 -0
  344. package/dist/react/Panel.js +24 -0
  345. package/dist/react/Panel.js.map +1 -0
  346. package/dist/react/PixelImage.js +24 -0
  347. package/dist/react/PixelImage.js.map +1 -0
  348. package/dist/react/Select.js +99 -0
  349. package/dist/react/Select.js.map +1 -0
  350. package/dist/react/Slider.js +62 -0
  351. package/dist/react/Slider.js.map +1 -0
  352. package/dist/react/SplitPane.js +24 -0
  353. package/dist/react/SplitPane.js.map +1 -0
  354. package/dist/react/TabStrip.js +32 -0
  355. package/dist/react/TabStrip.js.map +1 -0
  356. package/dist/react/TitleTips.js +42 -0
  357. package/dist/react/TitleTips.js.map +1 -0
  358. package/dist/react/Tooltip.js +28 -0
  359. package/dist/react/Tooltip.js.map +1 -0
  360. package/dist/react/UiProvider.js +50 -0
  361. package/dist/react/UiProvider.js.map +1 -0
  362. package/dist/react/baseCss.js +222 -0
  363. package/dist/react/baseCss.js.map +1 -0
  364. package/dist/react/choiceStore.js +23 -0
  365. package/dist/react/choiceStore.js.map +1 -0
  366. package/dist/react/classNames.js +19 -0
  367. package/dist/react/classNames.js.map +1 -0
  368. package/dist/react/confirmStore.js +30 -0
  369. package/dist/react/confirmStore.js.map +1 -0
  370. package/dist/react/labels.js +18 -0
  371. package/dist/react/labels.js.map +1 -0
  372. package/dist/react/placement.js +49 -0
  373. package/dist/react/placement.js.map +1 -0
  374. package/dist/react/useFillSheet.js +23 -0
  375. package/dist/react/useFillSheet.js.map +1 -0
  376. package/dist/react/useFitToViewport.js +29 -0
  377. package/dist/react/useFitToViewport.js.map +1 -0
  378. package/dist/react/usePicked.js +13 -0
  379. package/dist/react/usePicked.js.map +1 -0
  380. package/dist/react/useStore.js +9 -0
  381. package/dist/react/useStore.js.map +1 -0
  382. package/dist/react/useViewport.js +17 -0
  383. package/dist/react/useViewport.js.map +1 -0
  384. package/dist/react.js +78 -0
  385. package/dist/react.js.map +1 -0
  386. package/dist/rig/PosePlayer.js +92 -0
  387. package/dist/rig/PosePlayer.js.map +1 -0
  388. package/dist/rig/RigView.js +125 -0
  389. package/dist/rig/RigView.js.map +1 -0
  390. package/dist/rig/Skeleton.js +31 -0
  391. package/dist/rig/Skeleton.js.map +1 -0
  392. package/dist/rig/humanoid.js +6 -0
  393. package/dist/rig/humanoid.js.map +1 -0
  394. package/dist/rig/humanoid.json.js +30 -0
  395. package/dist/rig/humanoid.json.js.map +1 -0
  396. package/dist/rig/humanoidPoses.js +30 -0
  397. package/dist/rig/humanoidPoses.js.map +1 -0
  398. package/dist/rig/poseMath.js +54 -0
  399. package/dist/rig/poseMath.js.map +1 -0
  400. package/dist/rig/poses.json.js +150 -0
  401. package/dist/rig/poses.json.js.map +1 -0
  402. package/dist/save/Autosaver.js +54 -0
  403. package/dist/save/Autosaver.js.map +1 -0
  404. package/dist/save/MemoryBackend.js +19 -0
  405. package/dist/save/MemoryBackend.js.map +1 -0
  406. package/dist/save/SaveStore.js +103 -0
  407. package/dist/save/SaveStore.js.map +1 -0
  408. package/dist/save/WebStorageBackend.js +27 -0
  409. package/dist/save/WebStorageBackend.js.map +1 -0
  410. package/dist/save/checksum.js +10 -0
  411. package/dist/save/checksum.js.map +1 -0
  412. package/dist/save/migrateSave.js +27 -0
  413. package/dist/save/migrateSave.js.map +1 -0
  414. package/dist/settings.js +27 -0
  415. package/dist/settings.js.map +1 -0
  416. package/dist/tilemap/TilemapView.js +69 -0
  417. package/dist/tilemap/TilemapView.js.map +1 -0
  418. package/dist/tilemap/collision.js +25 -0
  419. package/dist/tilemap/collision.js.map +1 -0
  420. package/dist/tilemap/tiled.js +138 -0
  421. package/dist/tilemap/tiled.js.map +1 -0
  422. package/dist/transitions/CrossfadeTransition.js +24 -0
  423. package/dist/transitions/CrossfadeTransition.js.map +1 -0
  424. package/dist/transitions/DitherWipeTransition.js +70 -0
  425. package/dist/transitions/DitherWipeTransition.js.map +1 -0
  426. package/dist/transitions/FadeTransition.js +34 -0
  427. package/dist/transitions/FadeTransition.js.map +1 -0
  428. package/dist/transitions/Letterbox.js +42 -0
  429. package/dist/transitions/Letterbox.js.map +1 -0
  430. package/dist/transitions/ditherMask.js +15 -0
  431. package/dist/transitions/ditherMask.js.map +1 -0
  432. package/dist/transitions/transitionTo.js +28 -0
  433. package/dist/transitions/transitionTo.js.map +1 -0
  434. package/dist/transitions/tweenDone.js +15 -0
  435. package/dist/transitions/tweenDone.js.map +1 -0
  436. package/dist/types/ambient/ColorGrade.d.ts +41 -0
  437. package/dist/types/ambient/ColorGrade.d.ts.map +1 -0
  438. package/dist/types/ambient/DayClock.d.ts +80 -0
  439. package/dist/types/ambient/DayClock.d.ts.map +1 -0
  440. package/dist/types/ambient/WeatherLayer.d.ts +78 -0
  441. package/dist/types/ambient/WeatherLayer.d.ts.map +1 -0
  442. package/dist/types/ambient/grade.d.ts +22 -0
  443. package/dist/types/ambient/grade.d.ts.map +1 -0
  444. package/dist/types/ambient/weather.d.ts +49 -0
  445. package/dist/types/ambient/weather.d.ts.map +1 -0
  446. package/dist/types/anim/AnimStateMachine.d.ts +80 -0
  447. package/dist/types/anim/AnimStateMachine.d.ts.map +1 -0
  448. package/dist/types/anim/Animator.d.ts +50 -0
  449. package/dist/types/anim/Animator.d.ts.map +1 -0
  450. package/dist/types/anim/animStateCompile.d.ts +52 -0
  451. package/dist/types/anim/animStateCompile.d.ts.map +1 -0
  452. package/dist/types/anim/animStateSystem.d.ts +10 -0
  453. package/dist/types/anim/animStateSystem.d.ts.map +1 -0
  454. package/dist/types/anim/animStateTypes.d.ts +50 -0
  455. package/dist/types/anim/animStateTypes.d.ts.map +1 -0
  456. package/dist/types/anim/animationSystem.d.ts +13 -0
  457. package/dist/types/anim/animationSystem.d.ts.map +1 -0
  458. package/dist/types/anim/asepriteSlices.d.ts +19 -0
  459. package/dist/types/anim/asepriteSlices.d.ts.map +1 -0
  460. package/dist/types/anim/asepriteTags.d.ts +16 -0
  461. package/dist/types/anim/asepriteTags.d.ts.map +1 -0
  462. package/dist/types/anim/asepriteTypes.d.ts +159 -0
  463. package/dist/types/anim/asepriteTypes.d.ts.map +1 -0
  464. package/dist/types/anim/parseAseprite.d.ts +21 -0
  465. package/dist/types/anim/parseAseprite.d.ts.map +1 -0
  466. package/dist/types/assets/AssetLoader.d.ts +85 -0
  467. package/dist/types/assets/AssetLoader.d.ts.map +1 -0
  468. package/dist/types/assets/loadAseprite.d.ts +27 -0
  469. package/dist/types/assets/loadAseprite.d.ts.map +1 -0
  470. package/dist/types/audio/Footsteps.d.ts +33 -0
  471. package/dist/types/audio/Footsteps.d.ts.map +1 -0
  472. package/dist/types/audio/MusicPlayer.d.ts +65 -0
  473. package/dist/types/audio/MusicPlayer.d.ts.map +1 -0
  474. package/dist/types/audio/SoundEngine.d.ts +42 -0
  475. package/dist/types/audio/SoundEngine.d.ts.map +1 -0
  476. package/dist/types/audio/cleanTake.d.ts +3 -0
  477. package/dist/types/audio/cleanTake.d.ts.map +1 -0
  478. package/dist/types/audio/music/ElementVoice.d.ts +14 -0
  479. package/dist/types/audio/music/ElementVoice.d.ts.map +1 -0
  480. package/dist/types/audio/music/GraphVoice.d.ts +22 -0
  481. package/dist/types/audio/music/GraphVoice.d.ts.map +1 -0
  482. package/dist/types/audio/music/MusicChannel.d.ts +35 -0
  483. package/dist/types/audio/music/MusicChannel.d.ts.map +1 -0
  484. package/dist/types/audio/music/musicVoice.d.ts +26 -0
  485. package/dist/types/audio/music/musicVoice.d.ts.map +1 -0
  486. package/dist/types/audio/sampleBank.d.ts +27 -0
  487. package/dist/types/audio/sampleBank.d.ts.map +1 -0
  488. package/dist/types/audio/soundTable.d.ts +14 -0
  489. package/dist/types/audio/soundTable.d.ts.map +1 -0
  490. package/dist/types/audio/synth.d.ts +34 -0
  491. package/dist/types/audio/synth.d.ts.map +1 -0
  492. package/dist/types/audio/takeCleanerWorker.d.ts +2 -0
  493. package/dist/types/audio/takeCleanerWorker.d.ts.map +1 -0
  494. package/dist/types/core/BitmapLabel.d.ts +36 -0
  495. package/dist/types/core/BitmapLabel.d.ts.map +1 -0
  496. package/dist/types/core/Camera.d.ts +115 -0
  497. package/dist/types/core/Camera.d.ts.map +1 -0
  498. package/dist/types/core/Clock.d.ts +11 -0
  499. package/dist/types/core/Clock.d.ts.map +1 -0
  500. package/dist/types/core/Graphics.d.ts +37 -0
  501. package/dist/types/core/Graphics.d.ts.map +1 -0
  502. package/dist/types/core/Group.d.ts +15 -0
  503. package/dist/types/core/Group.d.ts.map +1 -0
  504. package/dist/types/core/Image.d.ts +25 -0
  505. package/dist/types/core/Image.d.ts.map +1 -0
  506. package/dist/types/core/ObjectFactory.d.ts +34 -0
  507. package/dist/types/core/ObjectFactory.d.ts.map +1 -0
  508. package/dist/types/core/Pointer.d.ts +27 -0
  509. package/dist/types/core/Pointer.d.ts.map +1 -0
  510. package/dist/types/core/Rectangle.d.ts +26 -0
  511. package/dist/types/core/Rectangle.d.ts.map +1 -0
  512. package/dist/types/core/Stage.d.ts +58 -0
  513. package/dist/types/core/Stage.d.ts.map +1 -0
  514. package/dist/types/core/Text.d.ts +22 -0
  515. package/dist/types/core/Text.d.ts.map +1 -0
  516. package/dist/types/core/TextureRegistry.d.ts +51 -0
  517. package/dist/types/core/TextureRegistry.d.ts.map +1 -0
  518. package/dist/types/core/Timeline.d.ts +115 -0
  519. package/dist/types/core/Timeline.d.ts.map +1 -0
  520. package/dist/types/core/TimelineBuilder.d.ts +53 -0
  521. package/dist/types/core/TimelineBuilder.d.ts.map +1 -0
  522. package/dist/types/core/TimelineChild.d.ts +51 -0
  523. package/dist/types/core/TimelineChild.d.ts.map +1 -0
  524. package/dist/types/core/Tweener.d.ts +70 -0
  525. package/dist/types/core/Tweener.d.ts.map +1 -0
  526. package/dist/types/core/atlas.d.ts +16 -0
  527. package/dist/types/core/atlas.d.ts.map +1 -0
  528. package/dist/types/core/atlasPlan.d.ts +34 -0
  529. package/dist/types/core/atlasPlan.d.ts.map +1 -0
  530. package/dist/types/core/eases.d.ts +3 -0
  531. package/dist/types/core/eases.d.ts.map +1 -0
  532. package/dist/types/core/gameObject.d.ts +42 -0
  533. package/dist/types/core/gameObject.d.ts.map +1 -0
  534. package/dist/types/core/pixiPatches.d.ts +9 -0
  535. package/dist/types/core/pixiPatches.d.ts.map +1 -0
  536. package/dist/types/core/timelinePlace.d.ts +23 -0
  537. package/dist/types/core/timelinePlace.d.ts.map +1 -0
  538. package/dist/types/core/tweenProps.d.ts +8 -0
  539. package/dist/types/core/tweenProps.d.ts.map +1 -0
  540. package/dist/types/core/types.d.ts +4 -0
  541. package/dist/types/core/types.d.ts.map +1 -0
  542. package/dist/types/debug/DebugOverlay.d.ts +63 -0
  543. package/dist/types/debug/DebugOverlay.d.ts.map +1 -0
  544. package/dist/types/debug/DrawCallCounter.d.ts +20 -0
  545. package/dist/types/debug/DrawCallCounter.d.ts.map +1 -0
  546. package/dist/types/debug/ErrorLog.d.ts +20 -0
  547. package/dist/types/debug/ErrorLog.d.ts.map +1 -0
  548. package/dist/types/debug/FrameStats.d.ts +21 -0
  549. package/dist/types/debug/FrameStats.d.ts.map +1 -0
  550. package/dist/types/debug/inspectWorld.d.ts +14 -0
  551. package/dist/types/debug/inspectWorld.d.ts.map +1 -0
  552. package/dist/types/diagnostics/ErrorDeduper.d.ts +17 -0
  553. package/dist/types/diagnostics/ErrorDeduper.d.ts.map +1 -0
  554. package/dist/types/diagnostics/FrameSampler.d.ts +37 -0
  555. package/dist/types/diagnostics/FrameSampler.d.ts.map +1 -0
  556. package/dist/types/diagnostics/bootWatch.d.ts +25 -0
  557. package/dist/types/diagnostics/bootWatch.d.ts.map +1 -0
  558. package/dist/types/diagnostics/captureErrors.d.ts +24 -0
  559. package/dist/types/diagnostics/captureErrors.d.ts.map +1 -0
  560. package/dist/types/diagnostics/contextLoss.d.ts +35 -0
  561. package/dist/types/diagnostics/contextLoss.d.ts.map +1 -0
  562. package/dist/types/diagnostics/frameStats.d.ts +30 -0
  563. package/dist/types/diagnostics/frameStats.d.ts.map +1 -0
  564. package/dist/types/diagnostics/gpuInfo.d.ts +9 -0
  565. package/dist/types/diagnostics/gpuInfo.d.ts.map +1 -0
  566. package/dist/types/diagnostics/renderGuard.d.ts +12 -0
  567. package/dist/types/diagnostics/renderGuard.d.ts.map +1 -0
  568. package/dist/types/ecs/SparseSet.d.ts +25 -0
  569. package/dist/types/ecs/SparseSet.d.ts.map +1 -0
  570. package/dist/types/ecs/World.d.ts +137 -0
  571. package/dist/types/ecs/World.d.ts.map +1 -0
  572. package/dist/types/ecs/fields.d.ts +34 -0
  573. package/dist/types/ecs/fields.d.ts.map +1 -0
  574. package/dist/types/engine/Engine.d.ts +80 -0
  575. package/dist/types/engine/Engine.d.ts.map +1 -0
  576. package/dist/types/engine/FixedLoop.d.ts +32 -0
  577. package/dist/types/engine/FixedLoop.d.ts.map +1 -0
  578. package/dist/types/engine/Scene.d.ts +67 -0
  579. package/dist/types/engine/Scene.d.ts.map +1 -0
  580. package/dist/types/engine/SceneManager.d.ts +36 -0
  581. package/dist/types/engine/SceneManager.d.ts.map +1 -0
  582. package/dist/types/events/EventBus.d.ts +20 -0
  583. package/dist/types/events/EventBus.d.ts.map +1 -0
  584. package/dist/types/fx/FloatingText.d.ts +71 -0
  585. package/dist/types/fx/FloatingText.d.ts.map +1 -0
  586. package/dist/types/fx/hitStop.d.ts +20 -0
  587. package/dist/types/fx/hitStop.d.ts.map +1 -0
  588. package/dist/types/fx/viewCull.d.ts +14 -0
  589. package/dist/types/fx/viewCull.d.ts.map +1 -0
  590. package/dist/types/i18n/Translator.d.ts +52 -0
  591. package/dist/types/i18n/Translator.d.ts.map +1 -0
  592. package/dist/types/i18n/extractStrings.d.ts +25 -0
  593. package/dist/types/i18n/extractStrings.d.ts.map +1 -0
  594. package/dist/types/i18n/formatMessage.d.ts +10 -0
  595. package/dist/types/i18n/formatMessage.d.ts.map +1 -0
  596. package/dist/types/index.d.ts +149 -0
  597. package/dist/types/index.d.ts.map +1 -0
  598. package/dist/types/input/Actions.d.ts +94 -0
  599. package/dist/types/input/Actions.d.ts.map +1 -0
  600. package/dist/types/input/AimGesture.d.ts +106 -0
  601. package/dist/types/input/AimGesture.d.ts.map +1 -0
  602. package/dist/types/input/Keyboard.d.ts +30 -0
  603. package/dist/types/input/Keyboard.d.ts.map +1 -0
  604. package/dist/types/input/Keymap.d.ts +85 -0
  605. package/dist/types/input/Keymap.d.ts.map +1 -0
  606. package/dist/types/input/TargetLock.d.ts +56 -0
  607. package/dist/types/input/TargetLock.d.ts.map +1 -0
  608. package/dist/types/input/aimAxis.d.ts +9 -0
  609. package/dist/types/input/aimAxis.d.ts.map +1 -0
  610. package/dist/types/input/keyChord.d.ts +15 -0
  611. package/dist/types/input/keyChord.d.ts.map +1 -0
  612. package/dist/types/input/longPress.d.ts +21 -0
  613. package/dist/types/input/longPress.d.ts.map +1 -0
  614. package/dist/types/input/stickAxis.d.ts +26 -0
  615. package/dist/types/input/stickAxis.d.ts.map +1 -0
  616. package/dist/types/input/touchDetect.d.ts +18 -0
  617. package/dist/types/input/touchDetect.d.ts.map +1 -0
  618. package/dist/types/light/LightLayer.d.ts +65 -0
  619. package/dist/types/light/LightLayer.d.ts.map +1 -0
  620. package/dist/types/nav/MinHeap.d.ts +15 -0
  621. package/dist/types/nav/MinHeap.d.ts.map +1 -0
  622. package/dist/types/nav/findPath.d.ts +38 -0
  623. package/dist/types/nav/findPath.d.ts.map +1 -0
  624. package/dist/types/nav/navGrid.d.ts +48 -0
  625. package/dist/types/nav/navGrid.d.ts.map +1 -0
  626. package/dist/types/nav/nearestOpen.d.ts +8 -0
  627. package/dist/types/nav/nearestOpen.d.ts.map +1 -0
  628. package/dist/types/nav/straightenPath.d.ts +13 -0
  629. package/dist/types/nav/straightenPath.d.ts.map +1 -0
  630. package/dist/types/net/Connection.d.ts +66 -0
  631. package/dist/types/net/Connection.d.ts.map +1 -0
  632. package/dist/types/net/InterpolationBuffer.d.ts +36 -0
  633. package/dist/types/net/InterpolationBuffer.d.ts.map +1 -0
  634. package/dist/types/net/PredictedMover.d.ts +43 -0
  635. package/dist/types/net/PredictedMover.d.ts.map +1 -0
  636. package/dist/types/net/Room.d.ts +69 -0
  637. package/dist/types/net/Room.d.ts.map +1 -0
  638. package/dist/types/net/RoomHost.d.ts +74 -0
  639. package/dist/types/net/RoomHost.d.ts.map +1 -0
  640. package/dist/types/net/cadence.d.ts +22 -0
  641. package/dist/types/net/cadence.d.ts.map +1 -0
  642. package/dist/types/net/constants.d.ts +24 -0
  643. package/dist/types/net/constants.d.ts.map +1 -0
  644. package/dist/types/net/lobby/LobbyClient.d.ts +107 -0
  645. package/dist/types/net/lobby/LobbyClient.d.ts.map +1 -0
  646. package/dist/types/net/lobby/LobbyHost.d.ts +147 -0
  647. package/dist/types/net/lobby/LobbyHost.d.ts.map +1 -0
  648. package/dist/types/net/lobby/LobbyRooms.d.ts +56 -0
  649. package/dist/types/net/lobby/LobbyRooms.d.ts.map +1 -0
  650. package/dist/types/net/lobby/Matchmaker.d.ts +57 -0
  651. package/dist/types/net/lobby/Matchmaker.d.ts.map +1 -0
  652. package/dist/types/net/lobby/index.d.ts +6 -0
  653. package/dist/types/net/lobby/index.d.ts.map +1 -0
  654. package/dist/types/net/lobby/lobbyProtocol.d.ts +143 -0
  655. package/dist/types/net/lobby/lobbyProtocol.d.ts.map +1 -0
  656. package/dist/types/net/movement.d.ts +50 -0
  657. package/dist/types/net/movement.d.ts.map +1 -0
  658. package/dist/types/net/protocol.d.ts +59 -0
  659. package/dist/types/net/protocol.d.ts.map +1 -0
  660. package/dist/types/net/serverClock.d.ts +14 -0
  661. package/dist/types/net/serverClock.d.ts.map +1 -0
  662. package/dist/types/net/snapshotCodec.d.ts +55 -0
  663. package/dist/types/net/snapshotCodec.d.ts.map +1 -0
  664. package/dist/types/parallax/Parallax.d.ts +37 -0
  665. package/dist/types/parallax/Parallax.d.ts.map +1 -0
  666. package/dist/types/parallax/ParallaxLayer.d.ts +80 -0
  667. package/dist/types/parallax/ParallaxLayer.d.ts.map +1 -0
  668. package/dist/types/parallax/parallaxMath.d.ts +50 -0
  669. package/dist/types/parallax/parallaxMath.d.ts.map +1 -0
  670. package/dist/types/particles/Emitter.d.ts +97 -0
  671. package/dist/types/particles/Emitter.d.ts.map +1 -0
  672. package/dist/types/particles/ParticleBudget.d.ts +28 -0
  673. package/dist/types/particles/ParticleBudget.d.ts.map +1 -0
  674. package/dist/types/particles/ParticleSim.d.ts +38 -0
  675. package/dist/types/particles/ParticleSim.d.ts.map +1 -0
  676. package/dist/types/particles/particleCurves.d.ts +21 -0
  677. package/dist/types/particles/particleCurves.d.ts.map +1 -0
  678. package/dist/types/particles/particleSampling.d.ts +20 -0
  679. package/dist/types/particles/particleSampling.d.ts.map +1 -0
  680. package/dist/types/physics/Body.d.ts +130 -0
  681. package/dist/types/physics/Body.d.ts.map +1 -0
  682. package/dist/types/physics/BroadPhase.d.ts +26 -0
  683. package/dist/types/physics/BroadPhase.d.ts.map +1 -0
  684. package/dist/types/physics/Contact.d.ts +62 -0
  685. package/dist/types/physics/Contact.d.ts.map +1 -0
  686. package/dist/types/physics/ContactSolver.d.ts +29 -0
  687. package/dist/types/physics/ContactSolver.d.ts.map +1 -0
  688. package/dist/types/physics/PhysicsWorld.d.ts +78 -0
  689. package/dist/types/physics/PhysicsWorld.d.ts.map +1 -0
  690. package/dist/types/physics/PhysicsWorldOptions.d.ts +24 -0
  691. package/dist/types/physics/PhysicsWorldOptions.d.ts.map +1 -0
  692. package/dist/types/physics/SpatialHash.d.ts +23 -0
  693. package/dist/types/physics/SpatialHash.d.ts.map +1 -0
  694. package/dist/types/physics/collide.d.ts +27 -0
  695. package/dist/types/physics/collide.d.ts.map +1 -0
  696. package/dist/types/physics/collidePolygon.d.ts +14 -0
  697. package/dist/types/physics/collidePolygon.d.ts.map +1 -0
  698. package/dist/types/physics/contactReport.d.ts +8 -0
  699. package/dist/types/physics/contactReport.d.ts.map +1 -0
  700. package/dist/types/physics/drawColliders.d.ts +43 -0
  701. package/dist/types/physics/drawColliders.d.ts.map +1 -0
  702. package/dist/types/physics/physicsSystem.d.ts +5 -0
  703. package/dist/types/physics/physicsSystem.d.ts.map +1 -0
  704. package/dist/types/physics/polygon.d.ts +28 -0
  705. package/dist/types/physics/polygon.d.ts.map +1 -0
  706. package/dist/types/physics/raycast.d.ts +19 -0
  707. package/dist/types/physics/raycast.d.ts.map +1 -0
  708. package/dist/types/physics/syncToBody.d.ts +16 -0
  709. package/dist/types/physics/syncToBody.d.ts.map +1 -0
  710. package/dist/types/physics/tileBodies.d.ts +36 -0
  711. package/dist/types/physics/tileBodies.d.ts.map +1 -0
  712. package/dist/types/physics/types.d.ts +116 -0
  713. package/dist/types/physics/types.d.ts.map +1 -0
  714. package/dist/types/pixel/Darkness.d.ts +78 -0
  715. package/dist/types/pixel/Darkness.d.ts.map +1 -0
  716. package/dist/types/pixel/DitherVignette.d.ts +35 -0
  717. package/dist/types/pixel/DitherVignette.d.ts.map +1 -0
  718. package/dist/types/pixel/Evaporation.d.ts +30 -0
  719. package/dist/types/pixel/Evaporation.d.ts.map +1 -0
  720. package/dist/types/pixel/NightShade.d.ts +38 -0
  721. package/dist/types/pixel/NightShade.d.ts.map +1 -0
  722. package/dist/types/pixel/PixelLayer.d.ts +85 -0
  723. package/dist/types/pixel/PixelLayer.d.ts.map +1 -0
  724. package/dist/types/pixel/SwayProp.d.ts +52 -0
  725. package/dist/types/pixel/SwayProp.d.ts.map +1 -0
  726. package/dist/types/pixel/index.d.ts +31 -0
  727. package/dist/types/pixel/index.d.ts.map +1 -0
  728. package/dist/types/pixel/lights.d.ts +34 -0
  729. package/dist/types/pixel/lights.d.ts.map +1 -0
  730. package/dist/types/pixel/nineSlice.d.ts +71 -0
  731. package/dist/types/pixel/nineSlice.d.ts.map +1 -0
  732. package/dist/types/pixel/paintLayer.d.ts +35 -0
  733. package/dist/types/pixel/paintLayer.d.ts.map +1 -0
  734. package/dist/types/pixel/palette.d.ts +58 -0
  735. package/dist/types/pixel/palette.d.ts.map +1 -0
  736. package/dist/types/pixel/pixel.d.ts +80 -0
  737. package/dist/types/pixel/pixel.d.ts.map +1 -0
  738. package/dist/types/pixel/pixelPaint.d.ts +43 -0
  739. package/dist/types/pixel/pixelPaint.d.ts.map +1 -0
  740. package/dist/types/pixel/pixelTone.d.ts +51 -0
  741. package/dist/types/pixel/pixelTone.d.ts.map +1 -0
  742. package/dist/types/pixel/propKit.d.ts +26 -0
  743. package/dist/types/pixel/propKit.d.ts.map +1 -0
  744. package/dist/types/pixel/ramp.d.ts +57 -0
  745. package/dist/types/pixel/ramp.d.ts.map +1 -0
  746. package/dist/types/pixel/selout.d.ts +3 -0
  747. package/dist/types/pixel/selout.d.ts.map +1 -0
  748. package/dist/types/pixel/spritePixels.d.ts +29 -0
  749. package/dist/types/pixel/spritePixels.d.ts.map +1 -0
  750. package/dist/types/pixel/swayRig.d.ts +72 -0
  751. package/dist/types/pixel/swayRig.d.ts.map +1 -0
  752. package/dist/types/pixel/vignetteMask.d.ts +16 -0
  753. package/dist/types/pixel/vignetteMask.d.ts.map +1 -0
  754. package/dist/types/pixel/weatherArt.d.ts +29 -0
  755. package/dist/types/pixel/weatherArt.d.ts.map +1 -0
  756. package/dist/types/platform/touch.d.ts +10 -0
  757. package/dist/types/platform/touch.d.ts.map +1 -0
  758. package/dist/types/postfx/BloomFilter.d.ts +33 -0
  759. package/dist/types/postfx/BloomFilter.d.ts.map +1 -0
  760. package/dist/types/postfx/ChromaticAberrationFilter.d.ts +11 -0
  761. package/dist/types/postfx/ChromaticAberrationFilter.d.ts.map +1 -0
  762. package/dist/types/postfx/ColorAdjustFilter.d.ts +32 -0
  763. package/dist/types/postfx/ColorAdjustFilter.d.ts.map +1 -0
  764. package/dist/types/postfx/CrtFilter.d.ts +16 -0
  765. package/dist/types/postfx/CrtFilter.d.ts.map +1 -0
  766. package/dist/types/postfx/PixelateFilter.d.ts +8 -0
  767. package/dist/types/postfx/PixelateFilter.d.ts.map +1 -0
  768. package/dist/types/postfx/PostFx.d.ts +92 -0
  769. package/dist/types/postfx/PostFx.d.ts.map +1 -0
  770. package/dist/types/postfx/ShockwaveFilter.d.ts +20 -0
  771. package/dist/types/postfx/ShockwaveFilter.d.ts.map +1 -0
  772. package/dist/types/postfx/VignetteFilter.d.ts +19 -0
  773. package/dist/types/postfx/VignetteFilter.d.ts.map +1 -0
  774. package/dist/types/postfx/fxAnimator.d.ts +32 -0
  775. package/dist/types/postfx/fxAnimator.d.ts.map +1 -0
  776. package/dist/types/postfx/fxShader.d.ts +49 -0
  777. package/dist/types/postfx/fxShader.d.ts.map +1 -0
  778. package/dist/types/postfx/index.d.ts +11 -0
  779. package/dist/types/postfx/index.d.ts.map +1 -0
  780. package/dist/types/react/ChoiceDialog.d.ts +8 -0
  781. package/dist/types/react/ChoiceDialog.d.ts.map +1 -0
  782. package/dist/types/react/ConfirmDialog.d.ts +9 -0
  783. package/dist/types/react/ConfirmDialog.d.ts.map +1 -0
  784. package/dist/types/react/Glyph.d.ts +54 -0
  785. package/dist/types/react/Glyph.d.ts.map +1 -0
  786. package/dist/types/react/Modal.d.ts +22 -0
  787. package/dist/types/react/Modal.d.ts.map +1 -0
  788. package/dist/types/react/Panel.d.ts +29 -0
  789. package/dist/types/react/Panel.d.ts.map +1 -0
  790. package/dist/types/react/PixelImage.d.ts +19 -0
  791. package/dist/types/react/PixelImage.d.ts.map +1 -0
  792. package/dist/types/react/Select.d.ts +27 -0
  793. package/dist/types/react/Select.d.ts.map +1 -0
  794. package/dist/types/react/Slider.d.ts +24 -0
  795. package/dist/types/react/Slider.d.ts.map +1 -0
  796. package/dist/types/react/SplitPane.d.ts +26 -0
  797. package/dist/types/react/SplitPane.d.ts.map +1 -0
  798. package/dist/types/react/TabStrip.d.ts +31 -0
  799. package/dist/types/react/TabStrip.d.ts.map +1 -0
  800. package/dist/types/react/TitleTips.d.ts +15 -0
  801. package/dist/types/react/TitleTips.d.ts.map +1 -0
  802. package/dist/types/react/Tooltip.d.ts +22 -0
  803. package/dist/types/react/Tooltip.d.ts.map +1 -0
  804. package/dist/types/react/UiProvider.d.ts +52 -0
  805. package/dist/types/react/UiProvider.d.ts.map +1 -0
  806. package/dist/types/react/baseCss.d.ts +27 -0
  807. package/dist/types/react/baseCss.d.ts.map +1 -0
  808. package/dist/types/react/choiceStore.d.ts +34 -0
  809. package/dist/types/react/choiceStore.d.ts.map +1 -0
  810. package/dist/types/react/classNames.d.ts +12 -0
  811. package/dist/types/react/classNames.d.ts.map +1 -0
  812. package/dist/types/react/confirmStore.d.ts +30 -0
  813. package/dist/types/react/confirmStore.d.ts.map +1 -0
  814. package/dist/types/react/index.d.ts +33 -0
  815. package/dist/types/react/index.d.ts.map +1 -0
  816. package/dist/types/react/labels.d.ts +24 -0
  817. package/dist/types/react/labels.d.ts.map +1 -0
  818. package/dist/types/react/placement.d.ts +59 -0
  819. package/dist/types/react/placement.d.ts.map +1 -0
  820. package/dist/types/react/useFillSheet.d.ts +9 -0
  821. package/dist/types/react/useFillSheet.d.ts.map +1 -0
  822. package/dist/types/react/useFitToViewport.d.ts +20 -0
  823. package/dist/types/react/useFitToViewport.d.ts.map +1 -0
  824. package/dist/types/react/usePicked.d.ts +9 -0
  825. package/dist/types/react/usePicked.d.ts.map +1 -0
  826. package/dist/types/react/useStore.d.ts +8 -0
  827. package/dist/types/react/useStore.d.ts.map +1 -0
  828. package/dist/types/react/useViewport.d.ts +4 -0
  829. package/dist/types/react/useViewport.d.ts.map +1 -0
  830. package/dist/types/rig/PosePlayer.d.ts +64 -0
  831. package/dist/types/rig/PosePlayer.d.ts.map +1 -0
  832. package/dist/types/rig/RigView.d.ts +68 -0
  833. package/dist/types/rig/RigView.d.ts.map +1 -0
  834. package/dist/types/rig/Skeleton.d.ts +14 -0
  835. package/dist/types/rig/Skeleton.d.ts.map +1 -0
  836. package/dist/types/rig/humanoid.d.ts +4 -0
  837. package/dist/types/rig/humanoid.d.ts.map +1 -0
  838. package/dist/types/rig/humanoidPoses.d.ts +117 -0
  839. package/dist/types/rig/humanoidPoses.d.ts.map +1 -0
  840. package/dist/types/rig/poseMath.d.ts +14 -0
  841. package/dist/types/rig/poseMath.d.ts.map +1 -0
  842. package/dist/types/rig/rigTypes.d.ts +82 -0
  843. package/dist/types/rig/rigTypes.d.ts.map +1 -0
  844. package/dist/types/save/Autosaver.d.ts +43 -0
  845. package/dist/types/save/Autosaver.d.ts.map +1 -0
  846. package/dist/types/save/MemoryBackend.d.ts +10 -0
  847. package/dist/types/save/MemoryBackend.d.ts.map +1 -0
  848. package/dist/types/save/SaveBackend.d.ts +14 -0
  849. package/dist/types/save/SaveBackend.d.ts.map +1 -0
  850. package/dist/types/save/SaveStore.d.ts +73 -0
  851. package/dist/types/save/SaveStore.d.ts.map +1 -0
  852. package/dist/types/save/WebStorageBackend.d.ts +14 -0
  853. package/dist/types/save/WebStorageBackend.d.ts.map +1 -0
  854. package/dist/types/save/checksum.d.ts +7 -0
  855. package/dist/types/save/checksum.d.ts.map +1 -0
  856. package/dist/types/save/migrateSave.d.ts +17 -0
  857. package/dist/types/save/migrateSave.d.ts.map +1 -0
  858. package/dist/types/settings.d.ts +25 -0
  859. package/dist/types/settings.d.ts.map +1 -0
  860. package/dist/types/tilemap/TilemapView.d.ts +42 -0
  861. package/dist/types/tilemap/TilemapView.d.ts.map +1 -0
  862. package/dist/types/tilemap/collision.d.ts +16 -0
  863. package/dist/types/tilemap/collision.d.ts.map +1 -0
  864. package/dist/types/tilemap/tiled.d.ts +104 -0
  865. package/dist/types/tilemap/tiled.d.ts.map +1 -0
  866. package/dist/types/transitions/CrossfadeTransition.d.ts +20 -0
  867. package/dist/types/transitions/CrossfadeTransition.d.ts.map +1 -0
  868. package/dist/types/transitions/DitherWipeTransition.d.ts +35 -0
  869. package/dist/types/transitions/DitherWipeTransition.d.ts.map +1 -0
  870. package/dist/types/transitions/FadeTransition.d.ts +20 -0
  871. package/dist/types/transitions/FadeTransition.d.ts.map +1 -0
  872. package/dist/types/transitions/Letterbox.d.ts +33 -0
  873. package/dist/types/transitions/Letterbox.d.ts.map +1 -0
  874. package/dist/types/transitions/Transition.d.ts +22 -0
  875. package/dist/types/transitions/Transition.d.ts.map +1 -0
  876. package/dist/types/transitions/ditherMask.d.ts +13 -0
  877. package/dist/types/transitions/ditherMask.d.ts.map +1 -0
  878. package/dist/types/transitions/transitionTo.d.ts +16 -0
  879. package/dist/types/transitions/transitionTo.d.ts.map +1 -0
  880. package/dist/types/transitions/tweenDone.d.ts +5 -0
  881. package/dist/types/transitions/tweenDone.d.ts.map +1 -0
  882. package/dist/types/ui/Bar.d.ts +41 -0
  883. package/dist/types/ui/Bar.d.ts.map +1 -0
  884. package/dist/types/ui/Button.d.ts +47 -0
  885. package/dist/types/ui/Button.d.ts.map +1 -0
  886. package/dist/types/ui/Dialog.d.ts +47 -0
  887. package/dist/types/ui/Dialog.d.ts.map +1 -0
  888. package/dist/types/ui/FocusManager.d.ts +53 -0
  889. package/dist/types/ui/FocusManager.d.ts.map +1 -0
  890. package/dist/types/ui/Label.d.ts +24 -0
  891. package/dist/types/ui/Label.d.ts.map +1 -0
  892. package/dist/types/ui/List.d.ts +23 -0
  893. package/dist/types/ui/List.d.ts.map +1 -0
  894. package/dist/types/ui/Panel.d.ts +38 -0
  895. package/dist/types/ui/Panel.d.ts.map +1 -0
  896. package/dist/types/ui/ScrollView.d.ts +56 -0
  897. package/dist/types/ui/ScrollView.d.ts.map +1 -0
  898. package/dist/types/ui/Slider.d.ts +47 -0
  899. package/dist/types/ui/Slider.d.ts.map +1 -0
  900. package/dist/types/ui/Stack.d.ts +16 -0
  901. package/dist/types/ui/Stack.d.ts.map +1 -0
  902. package/dist/types/ui/Toggle.d.ts +31 -0
  903. package/dist/types/ui/Toggle.d.ts.map +1 -0
  904. package/dist/types/ui/UiHost.d.ts +18 -0
  905. package/dist/types/ui/UiHost.d.ts.map +1 -0
  906. package/dist/types/ui/UiPointerGate.d.ts +17 -0
  907. package/dist/types/ui/UiPointerGate.d.ts.map +1 -0
  908. package/dist/types/ui/UiRoot.d.ts +73 -0
  909. package/dist/types/ui/UiRoot.d.ts.map +1 -0
  910. package/dist/types/ui/Widget.d.ts +56 -0
  911. package/dist/types/ui/Widget.d.ts.map +1 -0
  912. package/dist/types/ui/dom/DomOverlay.d.ts +52 -0
  913. package/dist/types/ui/dom/DomOverlay.d.ts.map +1 -0
  914. package/dist/types/ui/dom/DomWorldAnchors.d.ts +50 -0
  915. package/dist/types/ui/dom/DomWorldAnchors.d.ts.map +1 -0
  916. package/dist/types/ui/dom/InputShield.d.ts +20 -0
  917. package/dist/types/ui/dom/InputShield.d.ts.map +1 -0
  918. package/dist/types/ui/dom/createStore.d.ts +22 -0
  919. package/dist/types/ui/dom/createStore.d.ts.map +1 -0
  920. package/dist/types/ui/dom/shieldDecision.d.ts +34 -0
  921. package/dist/types/ui/dom/shieldDecision.d.ts.map +1 -0
  922. package/dist/types/ui/dom/worldToScreen.d.ts +24 -0
  923. package/dist/types/ui/dom/worldToScreen.d.ts.map +1 -0
  924. package/dist/types/ui/index.d.ts +38 -0
  925. package/dist/types/ui/index.d.ts.map +1 -0
  926. package/dist/types/ui/layout/anchor.d.ts +9 -0
  927. package/dist/types/ui/layout/anchor.d.ts.map +1 -0
  928. package/dist/types/ui/layout/barDrain.d.ts +25 -0
  929. package/dist/types/ui/layout/barDrain.d.ts.map +1 -0
  930. package/dist/types/ui/layout/fitToViewport.d.ts +32 -0
  931. package/dist/types/ui/layout/fitToViewport.d.ts.map +1 -0
  932. package/dist/types/ui/layout/focusNav.d.ts +13 -0
  933. package/dist/types/ui/layout/focusNav.d.ts.map +1 -0
  934. package/dist/types/ui/layout/geometry.d.ts +35 -0
  935. package/dist/types/ui/layout/geometry.d.ts.map +1 -0
  936. package/dist/types/ui/layout/listWidth.d.ts +13 -0
  937. package/dist/types/ui/layout/listWidth.d.ts.map +1 -0
  938. package/dist/types/ui/layout/placeTooltip.d.ts +23 -0
  939. package/dist/types/ui/layout/placeTooltip.d.ts.map +1 -0
  940. package/dist/types/ui/layout/scroll.d.ts +17 -0
  941. package/dist/types/ui/layout/scroll.d.ts.map +1 -0
  942. package/dist/types/ui/layout/slider.d.ts +7 -0
  943. package/dist/types/ui/layout/slider.d.ts.map +1 -0
  944. package/dist/types/ui/layout/stack.d.ts +26 -0
  945. package/dist/types/ui/layout/stack.d.ts.map +1 -0
  946. package/dist/types/ui/layout/wrapRow.d.ts +6 -0
  947. package/dist/types/ui/layout/wrapRow.d.ts.map +1 -0
  948. package/dist/ui/Bar.js +54 -0
  949. package/dist/ui/Bar.js.map +1 -0
  950. package/dist/ui/Button.js +58 -0
  951. package/dist/ui/Button.js.map +1 -0
  952. package/dist/ui/Dialog.js +56 -0
  953. package/dist/ui/Dialog.js.map +1 -0
  954. package/dist/ui/FocusManager.js +97 -0
  955. package/dist/ui/FocusManager.js.map +1 -0
  956. package/dist/ui/Label.js +36 -0
  957. package/dist/ui/Label.js.map +1 -0
  958. package/dist/ui/List.js +45 -0
  959. package/dist/ui/List.js.map +1 -0
  960. package/dist/ui/Panel.js +38 -0
  961. package/dist/ui/Panel.js.map +1 -0
  962. package/dist/ui/ScrollView.js +96 -0
  963. package/dist/ui/ScrollView.js.map +1 -0
  964. package/dist/ui/Slider.js +55 -0
  965. package/dist/ui/Slider.js.map +1 -0
  966. package/dist/ui/Stack.js +28 -0
  967. package/dist/ui/Stack.js.map +1 -0
  968. package/dist/ui/Toggle.js +37 -0
  969. package/dist/ui/Toggle.js.map +1 -0
  970. package/dist/ui/UiHost.js +9 -0
  971. package/dist/ui/UiHost.js.map +1 -0
  972. package/dist/ui/UiPointerGate.js +25 -0
  973. package/dist/ui/UiPointerGate.js.map +1 -0
  974. package/dist/ui/UiRoot.js +93 -0
  975. package/dist/ui/UiRoot.js.map +1 -0
  976. package/dist/ui/Widget.js +90 -0
  977. package/dist/ui/Widget.js.map +1 -0
  978. package/dist/ui/dom/DomOverlay.js +59 -0
  979. package/dist/ui/dom/DomOverlay.js.map +1 -0
  980. package/dist/ui/dom/DomWorldAnchors.js +59 -0
  981. package/dist/ui/dom/DomWorldAnchors.js.map +1 -0
  982. package/dist/ui/dom/InputShield.js +27 -0
  983. package/dist/ui/dom/InputShield.js.map +1 -0
  984. package/dist/ui/dom/createStore.js +42 -0
  985. package/dist/ui/dom/createStore.js.map +1 -0
  986. package/dist/ui/dom/shieldDecision.js +36 -0
  987. package/dist/ui/dom/shieldDecision.js.map +1 -0
  988. package/dist/ui/dom/worldToScreen.js +11 -0
  989. package/dist/ui/dom/worldToScreen.js.map +1 -0
  990. package/dist/ui/layout/anchor.js +20 -0
  991. package/dist/ui/layout/anchor.js.map +1 -0
  992. package/dist/ui/layout/barDrain.js +25 -0
  993. package/dist/ui/layout/barDrain.js.map +1 -0
  994. package/dist/ui/layout/fitToViewport.js +17 -0
  995. package/dist/ui/layout/fitToViewport.js.map +1 -0
  996. package/dist/ui/layout/focusNav.js +42 -0
  997. package/dist/ui/layout/focusNav.js.map +1 -0
  998. package/dist/ui/layout/geometry.js +21 -0
  999. package/dist/ui/layout/geometry.js.map +1 -0
  1000. package/dist/ui/layout/listWidth.js +10 -0
  1001. package/dist/ui/layout/listWidth.js.map +1 -0
  1002. package/dist/ui/layout/placeTooltip.js +28 -0
  1003. package/dist/ui/layout/placeTooltip.js.map +1 -0
  1004. package/dist/ui/layout/scroll.js +24 -0
  1005. package/dist/ui/layout/scroll.js.map +1 -0
  1006. package/dist/ui/layout/slider.js +20 -0
  1007. package/dist/ui/layout/slider.js.map +1 -0
  1008. package/dist/ui/layout/stack.js +27 -0
  1009. package/dist/ui/layout/stack.js.map +1 -0
  1010. package/dist/ui/layout/wrapRow.js +13 -0
  1011. package/dist/ui/layout/wrapRow.js.map +1 -0
  1012. package/dist/ui.js +85 -0
  1013. package/dist/ui.js.map +1 -0
  1014. package/package.json +115 -4
@@ -0,0 +1,119 @@
1
+ import { engineSettings as m } from "../settings.js";
2
+ import { SampleBank as E, hasTakes as y } from "./sampleBank.js";
3
+ import { SOUNDS as u } from "./soundTable.js";
4
+ import { renderRecipe as R, SYNTH_RATE as k } from "./synth.js";
5
+ const p = 480, _ = 10, q = 6, B = 60, F = 0.45, O = 0.05, w = 80, g = [18e3, 1800], T = { freq: 3500, gainDb: -7 }, V = 11e3;
6
+ class C {
7
+ ctx = null;
8
+ master = null;
9
+ buffers = /* @__PURE__ */ new Map();
10
+ samples = new E();
11
+ lastAt = /* @__PURE__ */ new Map();
12
+ voices = 0;
13
+ /** Where the local player stands, set by the world scene; null off the world screens. */
14
+ listener = () => null;
15
+ onRunning = () => {
16
+ };
17
+ constructor() {
18
+ if (typeof window > "u") return;
19
+ const t = () => {
20
+ const s = this.context();
21
+ if (!s || s.state === "running") return;
22
+ s.resume();
23
+ const r = s.createBufferSource();
24
+ r.buffer = s.createBuffer(1, 1, 22050), r.connect(s.destination), r.start();
25
+ }, n = ["pointerdown", "pointerup", "touchend", "keydown"], e = (s) => {
26
+ for (const r of n)
27
+ s ? window.addEventListener(r, t, { capture: !0 }) : window.removeEventListener(r, t, { capture: !0 });
28
+ };
29
+ this.onRunning = (s) => e(!s), e(!0);
30
+ const i = navigator.audioSession;
31
+ i && (i.type = "ambient"), m.subscribe((s) => {
32
+ this.ctx && this.master && this.master.gain.setTargetAtTime(this.level(s.sfxVolume), this.ctx.currentTime, 0.02);
33
+ });
34
+ }
35
+ play(t, n = {}) {
36
+ if (!t || !u.recipes[t] && !y(t) || m.getState().sfxVolume <= 0) return;
37
+ const e = this.ctx;
38
+ if (!e || e.state !== "running" || this.voices >= (n.minor ? q : _)) return;
39
+ let i = (n.gain ?? 1) * (n.local ? 1 : F), s = 0, r = 0;
40
+ if (n.x !== void 0 && n.y !== void 0) {
41
+ const o = this.listener();
42
+ if (o) {
43
+ const M = n.x - o.x, d = Math.hypot(M, n.y - o.y), b = Math.min(p, n.range ?? p);
44
+ if (d >= b) return;
45
+ i *= Math.pow(1 - d / b, 1.5), r = d / p, s = Math.max(-0.7, Math.min(0.7, M / 320));
46
+ }
47
+ }
48
+ if (i < 0.03) return;
49
+ const x = performance.now();
50
+ if (x - (this.lastAt.get(t) ?? -1e9) < B) return;
51
+ const v = this.samples.take(e, t), l = v ?? this.buffer(e, t);
52
+ if (!l) return;
53
+ v && (i *= u.recipes[t]?.fileGain ?? 1), this.lastAt.set(t, x);
54
+ const c = e.createBufferSource();
55
+ c.buffer = l;
56
+ const S = u.recipes[t]?.jitter ?? O;
57
+ c.playbackRate.value = 1 + (Math.random() * 2 - 1) * S;
58
+ const a = e.createGain();
59
+ a.gain.value = Math.min(1, i);
60
+ const h = e.createStereoPanner();
61
+ h.pan.value = s;
62
+ const f = e.createBiquadFilter();
63
+ f.type = "lowpass", f.frequency.value = g[0] * Math.pow(g[1] / g[0], r), c.connect(f).connect(a).connect(h).connect(this.master), this.voices++, c.onended = () => {
64
+ this.voices--, c.disconnect(), f.disconnect(), a.disconnect(), h.disconnect();
65
+ }, c.start();
66
+ const A = l.duration / c.playbackRate.value * 1e3;
67
+ if (n.maxMs !== void 0 && A > n.maxMs) {
68
+ const o = e.currentTime + Math.max(w, n.maxMs) / 1e3;
69
+ a.gain.setValueAtTime(a.gain.value, o - w / 1e3), a.gain.linearRampToValueAtTime(0, o), c.stop(o);
70
+ }
71
+ }
72
+ level(t) {
73
+ return Math.max(0, Math.min(1, t)) * u.master;
74
+ }
75
+ context() {
76
+ if (this.ctx) return this.ctx;
77
+ if (typeof AudioContext > "u") return null;
78
+ this.ctx = new AudioContext(), this.master = this.ctx.createGain(), this.master.gain.value = this.level(m.getState().sfxVolume);
79
+ const t = this.ctx.createBiquadFilter();
80
+ t.type = "highshelf", t.frequency.value = T.freq, t.gain.value = T.gainDb;
81
+ const n = this.ctx.createBiquadFilter();
82
+ n.type = "lowpass", n.frequency.value = V, this.master.connect(t).connect(n).connect(this.ctx.destination);
83
+ const e = this.ctx, i = () => {
84
+ const s = e.state === "running";
85
+ this.onRunning(s), s && this.prerender(e);
86
+ };
87
+ return e.addEventListener("statechange", i), e.state === "running" && queueMicrotask(i), e;
88
+ }
89
+ /**
90
+ * Starts decoding every recorded take and renders every recipe not rendered yet, one per task, once the context
91
+ * first runs — so the first swing of a fight does not pay for its sound in that frame.
92
+ */
93
+ prerender(t) {
94
+ for (const i of this.samples.names()) this.samples.load(t, i);
95
+ const n = Object.keys(u.recipes).filter((i) => !this.buffers.has(i) && !y(i)), e = () => {
96
+ const i = n.shift();
97
+ i !== void 0 && (this.buffer(t, i), setTimeout(e, 0));
98
+ };
99
+ e();
100
+ }
101
+ /** Rendered on first use or by `prerender` (a few ms each), then kept. */
102
+ buffer(t, n) {
103
+ const e = this.buffers.get(n);
104
+ if (e !== void 0) return e;
105
+ const i = u.recipes[n];
106
+ let s = null;
107
+ if (i) {
108
+ const r = R(i);
109
+ s = t.createBuffer(1, r.length, k), s.getChannelData(0).set(r);
110
+ }
111
+ return this.buffers.set(n, s), s;
112
+ }
113
+ }
114
+ const H = new C();
115
+ export {
116
+ C as SoundEngine,
117
+ H as sound
118
+ };
119
+ //# sourceMappingURL=SoundEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SoundEngine.js","sources":["../../src/audio/SoundEngine.ts"],"sourcesContent":["import { engineSettings } from '../settings';\nimport { hasTakes, SampleBank } from './sampleBank';\nimport { SOUNDS } from './soundTable';\nimport { renderRecipe, SYNTH_RATE } from './synth';\n\n/**\n * Plays sound effects through Web Audio, on a gain of their own (`engineSettings.sfxVolume`, beside the music's).\n * A sound is one of its recorded takes (`registerTakes`, `SampleBank`) when it has\n * any, else its `sounds.json` recipe rendered once into a buffer the first time it is asked for. A sound in the\n * world fades with its distance from the local player, pans with where it happened and loses its highs as it goes\n * (`MUFFLE`); the local player's own swings and blows play at full weight, everyone else's at `OTHERS`.\n *\n * Kept lean on purpose (an earlier, much larger set of effects was taken out for being too busy): one sound per\n * kind per `MIN_GAP_MS`, never more than `MAX_VOICES` at once, and nothing but combat.\n */\n\n/** Beyond this (px) a sound in the world is not heard at all. */\nconst HEARING = 480;\nconst MAX_VOICES = 10;\n/** Minor sounds (footsteps) start only while fewer than this are playing, so they never take a blow's voice. */\nconst MINOR_VOICES = 6;\n/** The same kind twice inside this (ms) is one sound: a cleave clipping six bodies lands once. */\nconst MIN_GAP_MS = 60;\n/** Weight of what other players, pets and monsters do, against the local player's own. */\nconst OTHERS = 0.45;\nconst DEFAULT_JITTER = 0.05;\n/** A sound cut short by `maxMs` fades out over this, so the cut does not click. */\nconst CUT_FADE_MS = 80;\n/** Low-pass cutoff (Hz) right beside the listener and at the edge of hearing: far blows sound dull, not just quiet. */\nconst MUFFLE: [number, number] = [18000, 1800];\n/**\n * The tone of the whole effects bus: the recorded takes came back bright (hiss, glassy ice, blade scrapes) and read\n * as shrill next to the music, so the highs are shelved down and the very top cut, for every sound at once.\n */\nconst TAME_SHELF = { freq: 3500, gainDb: -7 };\nconst TAME_TOP = 11000;\n\nexport interface SoundOptions {\n /** Where it happened in the world; absent for what happens to or is done by the local player. */\n x?: number;\n y?: number;\n /** Done by (or to) the local player: full weight. */\n local?: boolean;\n /** Extra weight (default 1). */\n gain?: number;\n /** How far away it can be heard (px), when nearer than `HEARING`. */\n range?: number;\n /** Skipped when the mix is busy (footsteps). */\n minor?: boolean;\n /** Cut off after this long (ms), faded over `CUT_FADE_MS`: a cast's sound ends with the cast. */\n maxMs?: number;\n}\n\nexport class SoundEngine {\n private ctx: AudioContext | null = null;\n private master: GainNode | null = null;\n private readonly buffers = new Map<string, AudioBuffer | null>();\n private readonly samples = new SampleBank();\n private readonly lastAt = new Map<string, number>();\n private voices = 0;\n /** Where the local player stands, set by the world scene; null off the world screens. */\n listener: () => { x: number; y: number } | null = () => null;\n private onRunning: (running: boolean) => void = () => {};\n\n constructor() {\n if (typeof window === 'undefined') return;\n // iOS lets a page start sound only inside a gesture, counts `touchend` (not `pointerdown`) as one, and leaves\n // the context 'interrupted' after the app comes back from the background: every touch retries until it runs\n const unlock = () => {\n const ctx = this.context();\n if (!ctx || ctx.state === 'running') return;\n void ctx.resume();\n // one silent sample started inside the gesture is what WebKit needs to open the output\n const blank = ctx.createBufferSource();\n blank.buffer = ctx.createBuffer(1, 1, 22050);\n blank.connect(ctx.destination);\n blank.start();\n };\n // listening only while the context is not running: once it runs a touch has nothing to do, and the listeners\n // come back the moment it stops (the interrupted iOS case)\n const types = ['pointerdown', 'pointerup', 'touchend', 'keydown'] as const;\n const listen = (on: boolean) => {\n for (const type of types) {\n if (on) window.addEventListener(type, unlock, { capture: true });\n else window.removeEventListener(type, unlock, { capture: true });\n }\n };\n this.onRunning = (running) => listen(!running);\n listen(true);\n // game sound, not media: it follows the ring/silent switch and mixes with the player's own music (iOS 17+)\n const session = (navigator as Navigator & { audioSession?: { type: string } }).audioSession;\n if (session) session.type = 'ambient';\n engineSettings.subscribe((s) => {\n if (this.ctx && this.master) this.master.gain.setTargetAtTime(this.level(s.sfxVolume), this.ctx.currentTime, 0.02);\n });\n }\n\n play(name: string | undefined, opts: SoundOptions = {}): void {\n if (!name || (!SOUNDS.recipes[name] && !hasTakes(name))) return;\n if (engineSettings.getState().sfxVolume <= 0) return;\n const ctx = this.ctx;\n if (!ctx || ctx.state !== 'running' || this.voices >= (opts.minor ? MINOR_VOICES : MAX_VOICES)) return;\n let gain = (opts.gain ?? 1) * (opts.local ? 1 : OTHERS);\n let pan = 0;\n let far = 0;\n if (opts.x !== undefined && opts.y !== undefined) {\n const me = this.listener();\n if (me) {\n const dx = opts.x - me.x;\n const d = Math.hypot(dx, opts.y - me.y);\n const hearing = Math.min(HEARING, opts.range ?? HEARING);\n if (d >= hearing) return;\n gain *= Math.pow(1 - d / hearing, 1.5);\n far = d / HEARING;\n pan = Math.max(-0.7, Math.min(0.7, dx / 320));\n }\n }\n if (gain < 0.03) return;\n const now = performance.now();\n if (now - (this.lastAt.get(name) ?? -1e9) < MIN_GAP_MS) return;\n const take = this.samples.take(ctx, name);\n const buffer = take ?? this.buffer(ctx, name);\n if (!buffer) return;\n if (take) gain *= SOUNDS.recipes[name]?.fileGain ?? 1;\n this.lastAt.set(name, now);\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n const jitter = SOUNDS.recipes[name]?.jitter ?? DEFAULT_JITTER;\n src.playbackRate.value = 1 + (Math.random() * 2 - 1) * jitter;\n const g = ctx.createGain();\n g.gain.value = Math.min(1, gain);\n const p = ctx.createStereoPanner();\n p.pan.value = pan;\n const lp = ctx.createBiquadFilter();\n lp.type = 'lowpass';\n lp.frequency.value = MUFFLE[0] * Math.pow(MUFFLE[1] / MUFFLE[0], far);\n src.connect(lp).connect(g).connect(p).connect(this.master!);\n this.voices++;\n src.onended = () => {\n this.voices--;\n src.disconnect();\n lp.disconnect();\n g.disconnect();\n p.disconnect();\n };\n src.start();\n const lasts = (buffer.duration / src.playbackRate.value) * 1000;\n if (opts.maxMs !== undefined && lasts > opts.maxMs) {\n const end = ctx.currentTime + Math.max(CUT_FADE_MS, opts.maxMs) / 1000;\n g.gain.setValueAtTime(g.gain.value, end - CUT_FADE_MS / 1000);\n g.gain.linearRampToValueAtTime(0, end);\n src.stop(end);\n }\n }\n\n private level(volume: number): number {\n return Math.max(0, Math.min(1, volume)) * SOUNDS.master;\n }\n\n private context(): AudioContext | null {\n if (this.ctx) return this.ctx;\n if (typeof AudioContext === 'undefined') return null;\n this.ctx = new AudioContext();\n this.master = this.ctx.createGain();\n this.master.gain.value = this.level(engineSettings.getState().sfxVolume);\n const shelf = this.ctx.createBiquadFilter();\n shelf.type = 'highshelf';\n shelf.frequency.value = TAME_SHELF.freq;\n shelf.gain.value = TAME_SHELF.gainDb;\n const top = this.ctx.createBiquadFilter();\n top.type = 'lowpass';\n top.frequency.value = TAME_TOP;\n this.master.connect(shelf).connect(top).connect(this.ctx.destination);\n const ctx = this.ctx;\n const changed = () => {\n const running = ctx.state === 'running';\n this.onRunning(running);\n if (running) this.prerender(ctx);\n };\n ctx.addEventListener('statechange', changed);\n // a context allowed to run from the start changes no state\n if (ctx.state === 'running') queueMicrotask(changed);\n return ctx;\n }\n\n /**\n * Starts decoding every recorded take and renders every recipe not rendered yet, one per task, once the context\n * first runs — so the first swing of a fight does not pay for its sound in that frame.\n */\n private prerender(ctx: AudioContext): void {\n for (const name of this.samples.names()) this.samples.load(ctx, name);\n // a sound with recorded takes plays them; its recipe is only the fallback while they decode, not worth a 40 ms task\n const todo = Object.keys(SOUNDS.recipes).filter((name) => !this.buffers.has(name) && !hasTakes(name));\n const next = () => {\n const name = todo.shift();\n if (name === undefined) return;\n this.buffer(ctx, name);\n setTimeout(next, 0);\n };\n next();\n }\n\n /** Rendered on first use or by `prerender` (a few ms each), then kept. */\n private buffer(ctx: AudioContext, name: string): AudioBuffer | null {\n const cached = this.buffers.get(name);\n if (cached !== undefined) return cached;\n const recipe = SOUNDS.recipes[name];\n let buf: AudioBuffer | null = null;\n if (recipe) {\n const data = renderRecipe(recipe);\n buf = ctx.createBuffer(1, data.length, SYNTH_RATE);\n buf.getChannelData(0).set(data);\n }\n this.buffers.set(name, buf);\n return buf;\n }\n}\n\nexport const sound = new SoundEngine();\n"],"names":["HEARING","MAX_VOICES","MINOR_VOICES","MIN_GAP_MS","OTHERS","DEFAULT_JITTER","CUT_FADE_MS","MUFFLE","TAME_SHELF","TAME_TOP","SoundEngine","SampleBank","unlock","ctx","blank","types","listen","on","type","running","session","engineSettings","name","opts","SOUNDS","hasTakes","gain","pan","far","me","dx","hearing","now","take","buffer","src","jitter","g","p","lp","lasts","end","volume","shelf","top","changed","todo","next","cached","recipe","buf","data","renderRecipe","SYNTH_RATE","sound"],"mappings":";;;;AAiBA,MAAMA,IAAU,KACVC,IAAa,IAEbC,IAAe,GAEfC,IAAa,IAEbC,IAAS,MACTC,IAAiB,MAEjBC,IAAc,IAEdC,IAA2B,CAAC,MAAO,IAAI,GAKvCC,IAAa,EAAE,MAAM,MAAM,QAAQ,GAAA,GACnCC,IAAW;AAkBV,MAAMC,EAAY;AAAA,EACf,MAA2B;AAAA,EAC3B,SAA0B;AAAA,EACjB,8BAAc,IAAA;AAAA,EACd,UAAU,IAAIC,EAAA;AAAA,EACd,6BAAa,IAAA;AAAA,EACtB,SAAS;AAAA;AAAA,EAEjB,WAAkD,MAAM;AAAA,EAChD,YAAwC,MAAM;AAAA,EAAC;AAAA,EAEvD,cAAc;AACZ,QAAI,OAAO,SAAW,IAAa;AAGnC,UAAMC,IAAS,MAAM;AACnB,YAAMC,IAAM,KAAK,QAAA;AACjB,UAAI,CAACA,KAAOA,EAAI,UAAU,UAAW;AACrC,MAAKA,EAAI,OAAA;AAET,YAAMC,IAAQD,EAAI,mBAAA;AAClB,MAAAC,EAAM,SAASD,EAAI,aAAa,GAAG,GAAG,KAAK,GAC3CC,EAAM,QAAQD,EAAI,WAAW,GAC7BC,EAAM,MAAA;AAAA,IACR,GAGMC,IAAQ,CAAC,eAAe,aAAa,YAAY,SAAS,GAC1DC,IAAS,CAACC,MAAgB;AAC9B,iBAAWC,KAAQH;AACjB,QAAIE,WAAW,iBAAiBC,GAAMN,GAAQ,EAAE,SAAS,IAAM,WACnD,oBAAoBM,GAAMN,GAAQ,EAAE,SAAS,IAAM;AAAA,IAEnE;AACA,SAAK,YAAY,CAACO,MAAYH,EAAO,CAACG,CAAO,GAC7CH,EAAO,EAAI;AAEX,UAAMI,IAAW,UAA8D;AAC/E,IAAIA,QAAiB,OAAO,YAC5BC,EAAe,UAAU,CAAC,MAAM;AAC9B,MAAI,KAAK,OAAO,KAAK,UAAQ,KAAK,OAAO,KAAK,gBAAgB,KAAK,MAAM,EAAE,SAAS,GAAG,KAAK,IAAI,aAAa,IAAI;AAAA,IACnH,CAAC;AAAA,EACH;AAAA,EAEA,KAAKC,GAA0BC,IAAqB,IAAU;AAE5D,QADI,CAACD,KAAS,CAACE,EAAO,QAAQF,CAAI,KAAK,CAACG,EAASH,CAAI,KACjDD,EAAe,WAAW,aAAa,EAAG;AAC9C,UAAMR,IAAM,KAAK;AACjB,QAAI,CAACA,KAAOA,EAAI,UAAU,aAAa,KAAK,WAAWU,EAAK,QAAQrB,IAAeD,GAAa;AAChG,QAAIyB,KAAQH,EAAK,QAAQ,MAAMA,EAAK,QAAQ,IAAInB,IAC5CuB,IAAM,GACNC,IAAM;AACV,QAAIL,EAAK,MAAM,UAAaA,EAAK,MAAM,QAAW;AAChD,YAAMM,IAAK,KAAK,SAAA;AAChB,UAAIA,GAAI;AACN,cAAMC,IAAKP,EAAK,IAAIM,EAAG,GACjB,IAAI,KAAK,MAAMC,GAAIP,EAAK,IAAIM,EAAG,CAAC,GAChCE,IAAU,KAAK,IAAI/B,GAASuB,EAAK,SAASvB,CAAO;AACvD,YAAI,KAAK+B,EAAS;AAClB,QAAAL,KAAQ,KAAK,IAAI,IAAI,IAAIK,GAAS,GAAG,GACrCH,IAAM,IAAI5B,GACV2B,IAAM,KAAK,IAAI,MAAM,KAAK,IAAI,KAAKG,IAAK,GAAG,CAAC;AAAA,MAC9C;AAAA,IACF;AACA,QAAIJ,IAAO,KAAM;AACjB,UAAMM,IAAM,YAAY,IAAA;AACxB,QAAIA,KAAO,KAAK,OAAO,IAAIV,CAAI,KAAK,QAAQnB,EAAY;AACxD,UAAM8B,IAAO,KAAK,QAAQ,KAAKpB,GAAKS,CAAI,GAClCY,IAASD,KAAQ,KAAK,OAAOpB,GAAKS,CAAI;AAC5C,QAAI,CAACY,EAAQ;AACb,IAAID,MAAMP,KAAQF,EAAO,QAAQF,CAAI,GAAG,YAAY,IACpD,KAAK,OAAO,IAAIA,GAAMU,CAAG;AACzB,UAAMG,IAAMtB,EAAI,mBAAA;AAChB,IAAAsB,EAAI,SAASD;AACb,UAAME,IAASZ,EAAO,QAAQF,CAAI,GAAG,UAAUjB;AAC/C,IAAA8B,EAAI,aAAa,QAAQ,KAAK,KAAK,OAAA,IAAW,IAAI,KAAKC;AACvD,UAAMC,IAAIxB,EAAI,WAAA;AACd,IAAAwB,EAAE,KAAK,QAAQ,KAAK,IAAI,GAAGX,CAAI;AAC/B,UAAMY,IAAIzB,EAAI,mBAAA;AACd,IAAAyB,EAAE,IAAI,QAAQX;AACd,UAAMY,IAAK1B,EAAI,mBAAA;AACf,IAAA0B,EAAG,OAAO,WACVA,EAAG,UAAU,QAAQhC,EAAO,CAAC,IAAI,KAAK,IAAIA,EAAO,CAAC,IAAIA,EAAO,CAAC,GAAGqB,CAAG,GACpEO,EAAI,QAAQI,CAAE,EAAE,QAAQF,CAAC,EAAE,QAAQC,CAAC,EAAE,QAAQ,KAAK,MAAO,GAC1D,KAAK,UACLH,EAAI,UAAU,MAAM;AAClB,WAAK,UACLA,EAAI,WAAA,GACJI,EAAG,WAAA,GACHF,EAAE,WAAA,GACFC,EAAE,WAAA;AAAA,IACJ,GACAH,EAAI,MAAA;AACJ,UAAMK,IAASN,EAAO,WAAWC,EAAI,aAAa,QAAS;AAC3D,QAAIZ,EAAK,UAAU,UAAaiB,IAAQjB,EAAK,OAAO;AAClD,YAAMkB,IAAM5B,EAAI,cAAc,KAAK,IAAIP,GAAaiB,EAAK,KAAK,IAAI;AAClE,MAAAc,EAAE,KAAK,eAAeA,EAAE,KAAK,OAAOI,IAAMnC,IAAc,GAAI,GAC5D+B,EAAE,KAAK,wBAAwB,GAAGI,CAAG,GACrCN,EAAI,KAAKM,CAAG;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,MAAMC,GAAwB;AACpC,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAM,CAAC,IAAIlB,EAAO;AAAA,EACnD;AAAA,EAEQ,UAA+B;AACrC,QAAI,KAAK,IAAK,QAAO,KAAK;AAC1B,QAAI,OAAO,eAAiB,IAAa,QAAO;AAChD,SAAK,MAAM,IAAI,aAAA,GACf,KAAK,SAAS,KAAK,IAAI,WAAA,GACvB,KAAK,OAAO,KAAK,QAAQ,KAAK,MAAMH,EAAe,SAAA,EAAW,SAAS;AACvE,UAAMsB,IAAQ,KAAK,IAAI,mBAAA;AACvB,IAAAA,EAAM,OAAO,aACbA,EAAM,UAAU,QAAQnC,EAAW,MACnCmC,EAAM,KAAK,QAAQnC,EAAW;AAC9B,UAAMoC,IAAM,KAAK,IAAI,mBAAA;AACrB,IAAAA,EAAI,OAAO,WACXA,EAAI,UAAU,QAAQnC,GACtB,KAAK,OAAO,QAAQkC,CAAK,EAAE,QAAQC,CAAG,EAAE,QAAQ,KAAK,IAAI,WAAW;AACpE,UAAM/B,IAAM,KAAK,KACXgC,IAAU,MAAM;AACpB,YAAM1B,IAAUN,EAAI,UAAU;AAC9B,WAAK,UAAUM,CAAO,GAClBA,KAAS,KAAK,UAAUN,CAAG;AAAA,IACjC;AACA,WAAAA,EAAI,iBAAiB,eAAegC,CAAO,GAEvChC,EAAI,UAAU,aAAW,eAAegC,CAAO,GAC5ChC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,UAAUA,GAAyB;AACzC,eAAWS,KAAQ,KAAK,QAAQ,MAAA,EAAS,MAAK,QAAQ,KAAKT,GAAKS,CAAI;AAEpE,UAAMwB,IAAO,OAAO,KAAKtB,EAAO,OAAO,EAAE,OAAO,CAACF,MAAS,CAAC,KAAK,QAAQ,IAAIA,CAAI,KAAK,CAACG,EAASH,CAAI,CAAC,GAC9FyB,IAAO,MAAM;AACjB,YAAMzB,IAAOwB,EAAK,MAAA;AAClB,MAAIxB,MAAS,WACb,KAAK,OAAOT,GAAKS,CAAI,GACrB,WAAWyB,GAAM,CAAC;AAAA,IACpB;AACA,IAAAA,EAAA;AAAA,EACF;AAAA;AAAA,EAGQ,OAAOlC,GAAmBS,GAAkC;AAClE,UAAM0B,IAAS,KAAK,QAAQ,IAAI1B,CAAI;AACpC,QAAI0B,MAAW,OAAW,QAAOA;AACjC,UAAMC,IAASzB,EAAO,QAAQF,CAAI;AAClC,QAAI4B,IAA0B;AAC9B,QAAID,GAAQ;AACV,YAAME,IAAOC,EAAaH,CAAM;AAChC,MAAAC,IAAMrC,EAAI,aAAa,GAAGsC,EAAK,QAAQE,CAAU,GACjDH,EAAI,eAAe,CAAC,EAAE,IAAIC,CAAI;AAAA,IAChC;AACA,gBAAK,QAAQ,IAAI7B,GAAM4B,CAAG,GACnBA;AAAA,EACT;AACF;AAEO,MAAMI,IAAQ,IAAI5C,EAAA;"}
@@ -0,0 +1,30 @@
1
+ function L(c, h) {
2
+ const l = c[0]?.length ?? 0, E = 1 / Math.max(1, c.length), a = new Float32Array(l);
3
+ for (const t of c) for (let n = 0; n < l; n++) a[n] += t[n] * E;
4
+ let s = 0;
5
+ for (let t = 0; t < l; t++) {
6
+ const n = Math.abs(a[t]);
7
+ n > s && (s = n);
8
+ }
9
+ if (s < 5e-3) return null;
10
+ const f = s * 0.01;
11
+ let e = 0;
12
+ for (; e < l && Math.abs(a[e]) < f; ) e++;
13
+ let r = l;
14
+ for (; r > e && Math.abs(a[r - 1]) < f; ) r--;
15
+ if (r <= e) return null;
16
+ e = Math.max(0, e - Math.round(2e-3 * h));
17
+ const o = a.slice(e, r);
18
+ let i = 0;
19
+ for (let t = 0; t < o.length; t++) i += o[t] * o[t];
20
+ const A = Math.sqrt(i / o.length), u = Math.min(0.16 / Math.max(A, 1e-6), 0.95 / s), M = Math.min(o.length, Math.round(0.01 * h));
21
+ for (let t = 0; t < o.length; t++) {
22
+ const n = o.length - t;
23
+ o[t] *= u * (n < M ? n / M : 1);
24
+ }
25
+ return o;
26
+ }
27
+ export {
28
+ L as cleanSamples
29
+ };
30
+ //# sourceMappingURL=cleanTake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanTake.js","sources":["../../src/audio/cleanTake.ts"],"sourcesContent":["/*\n * Cleans one recorded take (`SampleBank`): folded to mono, the silence an encoder or the model leaves at the start cut\n * (a swing heard 30 ms late reads as lag) and at the end trimmed, and brought to one loudness (`LOUDNESS`, RMS of what\n * is left, never past `PEAK`), so takes from different prompts sit at one level. Pure: run in `takeCleanerWorker.ts`,\n * because on the main thread the first blows of a fight froze the game 70–170 ms a take on a Mac and several times\n * that on a phone (profiled).\n */\n\n/** Below this share of the take's own peak a sample counts as silence when trimming (-40 dB). */\nconst FLOOR = 0.01;\n/** A take whose peak is under this is treated as empty (about -46 dBFS): the model returned near-silence. */\nconst EMPTY = 0.005;\n/** Target RMS of a cleaned take (-16 dBFS) and the peak it may not pass. */\nconst LOUDNESS = 0.16;\nconst PEAK = 0.95;\n/** Kept before the first loud sample, so the attack is not clipped into a click (s). */\nconst LEAD = 0.002;\n/** A short fade over the cut end, so a trimmed tail does not click (s). */\nconst TAIL_FADE = 0.01;\n\n/** The cleaned mono samples, or null for a take that is silence. */\nexport function cleanSamples(channels: Float32Array[], sampleRate: number): Float32Array | null {\n const n = channels[0]?.length ?? 0;\n const k0 = 1 / Math.max(1, channels.length);\n const mono = new Float32Array(n);\n for (const ch of channels) for (let i = 0; i < n; i++) mono[i]! += ch[i]! * k0;\n let top = 0;\n for (let i = 0; i < n; i++) {\n const a = Math.abs(mono[i]!);\n if (a > top) top = a;\n }\n if (top < EMPTY) return null;\n const floor = top * FLOOR;\n let start = 0;\n while (start < n && Math.abs(mono[start]!) < floor) start++;\n let end = n;\n while (end > start && Math.abs(mono[end - 1]!) < floor) end--;\n if (end <= start) return null;\n start = Math.max(0, start - Math.round(LEAD * sampleRate));\n const data = mono.slice(start, end);\n let power = 0;\n for (let i = 0; i < data.length; i++) power += data[i]! * data[i]!;\n const rms = Math.sqrt(power / data.length);\n const k = Math.min(LOUDNESS / Math.max(rms, 1e-6), PEAK / top);\n const fade = Math.min(data.length, Math.round(TAIL_FADE * sampleRate));\n for (let i = 0; i < data.length; i++) {\n const left = data.length - i;\n data[i]! *= k * (left < fade ? left / fade : 1);\n }\n return data;\n}\n"],"names":["cleanSamples","channels","sampleRate","n","k0","mono","ch","i","top","a","floor","start","end","data","power","rms","k","fade","left"],"mappings":"AAqBO,SAASA,EAAaC,GAA0BC,GAAyC;AAC9F,QAAMC,IAAIF,EAAS,CAAC,GAAG,UAAU,GAC3BG,IAAK,IAAI,KAAK,IAAI,GAAGH,EAAS,MAAM,GACpCI,IAAO,IAAI,aAAaF,CAAC;AAC/B,aAAWG,KAAML,EAAU,UAASM,IAAI,GAAGA,IAAIJ,GAAGI,IAAK,CAAAF,EAAKE,CAAC,KAAMD,EAAGC,CAAC,IAAKH;AAC5E,MAAII,IAAM;AACV,WAASD,IAAI,GAAGA,IAAIJ,GAAGI,KAAK;AAC1B,UAAME,IAAI,KAAK,IAAIJ,EAAKE,CAAC,CAAE;AAC3B,IAAIE,IAAID,MAAKA,IAAMC;AAAA,EACrB;AACA,MAAID,IAAM,KAAO,QAAO;AACxB,QAAME,IAAQF,IAAM;AACpB,MAAIG,IAAQ;AACZ,SAAOA,IAAQR,KAAK,KAAK,IAAIE,EAAKM,CAAK,CAAE,IAAID,IAAO,CAAAC;AACpD,MAAIC,IAAMT;AACV,SAAOS,IAAMD,KAAS,KAAK,IAAIN,EAAKO,IAAM,CAAC,CAAE,IAAIF,IAAO,CAAAE;AACxD,MAAIA,KAAOD,EAAO,QAAO;AACzB,EAAAA,IAAQ,KAAK,IAAI,GAAGA,IAAQ,KAAK,MAAM,OAAOT,CAAU,CAAC;AACzD,QAAMW,IAAOR,EAAK,MAAMM,GAAOC,CAAG;AAClC,MAAIE,IAAQ;AACZ,WAASP,IAAI,GAAGA,IAAIM,EAAK,QAAQN,IAAK,CAAAO,KAASD,EAAKN,CAAC,IAAKM,EAAKN,CAAC;AAChE,QAAMQ,IAAM,KAAK,KAAKD,IAAQD,EAAK,MAAM,GACnCG,IAAI,KAAK,IAAI,OAAW,KAAK,IAAID,GAAK,IAAI,GAAG,OAAOP,CAAG,GACvDS,IAAO,KAAK,IAAIJ,EAAK,QAAQ,KAAK,MAAM,OAAYX,CAAU,CAAC;AACrE,WAASK,IAAI,GAAGA,IAAIM,EAAK,QAAQN,KAAK;AACpC,UAAMW,IAAOL,EAAK,SAASN;AAC3B,IAAAM,EAAKN,CAAC,KAAMS,KAAKE,IAAOD,IAAOC,IAAOD,IAAO;AAAA,EAC/C;AACA,SAAOJ;AACT;"}
@@ -0,0 +1,35 @@
1
+ import { clamp01 as l } from "./musicVoice.js";
2
+ class m {
3
+ constructor(e) {
4
+ this.el = e;
5
+ }
6
+ el;
7
+ fading = null;
8
+ level() {
9
+ return this.el.volume;
10
+ }
11
+ set(e) {
12
+ this.stopFade(), this.el.volume = l(e);
13
+ }
14
+ fade(e, t, o) {
15
+ this.stopFade();
16
+ const i = this.el.volume, a = performance.now(), s = () => {
17
+ const n = t > 0 ? Math.min(1, (performance.now() - a) / t) : 1;
18
+ this.el.volume = l(i + (e - i) * n), n < 1 ? this.fading = requestAnimationFrame(s) : (this.fading = null, o?.());
19
+ };
20
+ this.fading = requestAnimationFrame(s);
21
+ }
22
+ get busy() {
23
+ return this.fading !== null;
24
+ }
25
+ dispose() {
26
+ this.stopFade(), this.el.pause(), this.el.removeAttribute("src"), this.el.load();
27
+ }
28
+ stopFade() {
29
+ this.fading !== null && cancelAnimationFrame(this.fading), this.fading = null;
30
+ }
31
+ }
32
+ export {
33
+ m as ElementVoice
34
+ };
35
+ //# sourceMappingURL=ElementVoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementVoice.js","sources":["../../../src/audio/music/ElementVoice.ts"],"sourcesContent":["import { clamp01, type MusicVoice } from './musicVoice';\n\n/** A track on the `<audio>` element's own volume, faded frame by frame: nothing between the file and the speaker. */\nexport class ElementVoice implements MusicVoice {\n private fading: number | null = null;\n\n constructor(readonly el: HTMLAudioElement) {}\n\n level(): number {\n return this.el.volume;\n }\n\n set(level: number): void {\n this.stopFade();\n this.el.volume = clamp01(level);\n }\n\n fade(to: number, ms: number, done?: () => void): void {\n this.stopFade();\n const from = this.el.volume;\n const start = performance.now();\n const step = () => {\n const k = ms > 0 ? Math.min(1, (performance.now() - start) / ms) : 1;\n this.el.volume = clamp01(from + (to - from) * k);\n if (k < 1) this.fading = requestAnimationFrame(step);\n else {\n this.fading = null;\n done?.();\n }\n };\n this.fading = requestAnimationFrame(step);\n }\n\n get busy(): boolean {\n return this.fading !== null;\n }\n\n dispose(): void {\n this.stopFade();\n this.el.pause();\n this.el.removeAttribute('src');\n this.el.load();\n }\n\n private stopFade(): void {\n if (this.fading !== null) cancelAnimationFrame(this.fading);\n this.fading = null;\n }\n}\n"],"names":["ElementVoice","el","level","clamp01","to","ms","done","from","start","step","k"],"mappings":";AAGO,MAAMA,EAAmC;AAAA,EAG9C,YAAqBC,GAAsB;AAAtB,SAAA,KAAAA;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAFb,SAAwB;AAAA,EAIhC,QAAgB;AACd,WAAO,KAAK,GAAG;AAAA,EACjB;AAAA,EAEA,IAAIC,GAAqB;AACvB,SAAK,SAAA,GACL,KAAK,GAAG,SAASC,EAAQD,CAAK;AAAA,EAChC;AAAA,EAEA,KAAKE,GAAYC,GAAYC,GAAyB;AACpD,SAAK,SAAA;AACL,UAAMC,IAAO,KAAK,GAAG,QACfC,IAAQ,YAAY,IAAA,GACpBC,IAAO,MAAM;AACjB,YAAMC,IAAIL,IAAK,IAAI,KAAK,IAAI,IAAI,YAAY,IAAA,IAAQG,KAASH,CAAE,IAAI;AACnE,WAAK,GAAG,SAASF,EAAQI,KAAQH,IAAKG,KAAQG,CAAC,GAC3CA,IAAI,IAAG,KAAK,SAAS,sBAAsBD,CAAI,KAEjD,KAAK,SAAS,MACdH,IAAA;AAAA,IAEJ;AACA,SAAK,SAAS,sBAAsBG,CAAI;AAAA,EAC1C;AAAA,EAEA,IAAI,OAAgB;AAClB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,UAAgB;AACd,SAAK,SAAA,GACL,KAAK,GAAG,MAAA,GACR,KAAK,GAAG,gBAAgB,KAAK,GAC7B,KAAK,GAAG,KAAA;AAAA,EACV;AAAA,EAEQ,WAAiB;AACvB,IAAI,KAAK,WAAW,QAAM,qBAAqB,KAAK,MAAM,GAC1D,KAAK,SAAS;AAAA,EAChB;AACF;"}
@@ -0,0 +1,39 @@
1
+ import { clamp01 as a } from "./musicVoice.js";
2
+ class h {
3
+ constructor(t, e) {
4
+ this.el = t, this.graph = e, this.source = e.createMediaElementSource(t), this.gain = e.createGain(), this.gain.gain.value = 0, this.source.connect(this.gain).connect(e.destination);
5
+ }
6
+ el;
7
+ graph;
8
+ gain;
9
+ source;
10
+ timer = null;
11
+ level() {
12
+ return this.gain.gain.value;
13
+ }
14
+ set(t) {
15
+ this.stopFade();
16
+ const e = this.gain.gain;
17
+ e.cancelScheduledValues(this.graph.currentTime), e.setValueAtTime(a(t), this.graph.currentTime);
18
+ }
19
+ fade(t, e, n) {
20
+ this.stopFade();
21
+ const i = this.gain.gain, s = this.graph.currentTime;
22
+ i.cancelScheduledValues(s), i.setValueAtTime(i.value, s), i.linearRampToValueAtTime(a(t), s + e / 1e3), this.timer = setTimeout(() => {
23
+ this.timer = null, n?.();
24
+ }, e);
25
+ }
26
+ get busy() {
27
+ return this.timer !== null;
28
+ }
29
+ dispose() {
30
+ this.stopFade(), this.el.pause(), this.source.disconnect(), this.gain.disconnect();
31
+ }
32
+ stopFade() {
33
+ this.timer && clearTimeout(this.timer), this.timer = null;
34
+ }
35
+ }
36
+ export {
37
+ h as GraphVoice
38
+ };
39
+ //# sourceMappingURL=GraphVoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphVoice.js","sources":["../../../src/audio/music/GraphVoice.ts"],"sourcesContent":["import { clamp01, type MusicVoice } from './musicVoice';\n\n/**\n * A track routed `<audio>` → MediaElementSource → gain → speakers, so its volume and crossfades work where the\n * element's own `volume` is read-only (iOS). The fade is scheduled on the audio clock (a ramp), so it runs even while\n * the page draws no frames. A cross-origin file without CORS headers plays silent this way: serve music from the\n * game's own origin, or keep `ElementVoice` where volume works.\n */\nexport class GraphVoice implements MusicVoice {\n private readonly gain: GainNode;\n private readonly source: MediaElementAudioSourceNode;\n private timer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n readonly el: HTMLAudioElement,\n private readonly graph: AudioContext,\n ) {\n this.source = graph.createMediaElementSource(el);\n this.gain = graph.createGain();\n this.gain.gain.value = 0;\n this.source.connect(this.gain).connect(graph.destination);\n }\n\n level(): number {\n return this.gain.gain.value;\n }\n\n set(level: number): void {\n this.stopFade();\n const g = this.gain.gain;\n g.cancelScheduledValues(this.graph.currentTime);\n g.setValueAtTime(clamp01(level), this.graph.currentTime);\n }\n\n fade(to: number, ms: number, done?: () => void): void {\n this.stopFade();\n const g = this.gain.gain;\n const now = this.graph.currentTime;\n g.cancelScheduledValues(now);\n g.setValueAtTime(g.value, now);\n g.linearRampToValueAtTime(clamp01(to), now + ms / 1000);\n this.timer = setTimeout(() => {\n this.timer = null;\n done?.();\n }, ms);\n }\n\n get busy(): boolean {\n return this.timer !== null;\n }\n\n dispose(): void {\n this.stopFade();\n this.el.pause();\n this.source.disconnect();\n this.gain.disconnect();\n }\n\n private stopFade(): void {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n"],"names":["GraphVoice","el","graph","level","g","clamp01","to","ms","done","now"],"mappings":";AAQO,MAAMA,EAAiC;AAAA,EAK5C,YACWC,GACQC,GACjB;AAFS,SAAA,KAAAD,GACQ,KAAA,QAAAC,GAEjB,KAAK,SAASA,EAAM,yBAAyBD,CAAE,GAC/C,KAAK,OAAOC,EAAM,WAAA,GAClB,KAAK,KAAK,KAAK,QAAQ,GACvB,KAAK,OAAO,QAAQ,KAAK,IAAI,EAAE,QAAQA,EAAM,WAAW;AAAA,EAC1D;AAAA,EAPW;AAAA,EACQ;AAAA,EANF;AAAA,EACA;AAAA,EACT,QAA8C;AAAA,EAYtD,QAAgB;AACd,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AAAA,EAEA,IAAIC,GAAqB;AACvB,SAAK,SAAA;AACL,UAAMC,IAAI,KAAK,KAAK;AACpB,IAAAA,EAAE,sBAAsB,KAAK,MAAM,WAAW,GAC9CA,EAAE,eAAeC,EAAQF,CAAK,GAAG,KAAK,MAAM,WAAW;AAAA,EACzD;AAAA,EAEA,KAAKG,GAAYC,GAAYC,GAAyB;AACpD,SAAK,SAAA;AACL,UAAMJ,IAAI,KAAK,KAAK,MACdK,IAAM,KAAK,MAAM;AACvB,IAAAL,EAAE,sBAAsBK,CAAG,GAC3BL,EAAE,eAAeA,EAAE,OAAOK,CAAG,GAC7BL,EAAE,wBAAwBC,EAAQC,CAAE,GAAGG,IAAMF,IAAK,GAAI,GACtD,KAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ,MACbC,IAAA;AAAA,IACF,GAAGD,CAAE;AAAA,EACP;AAAA,EAEA,IAAI,OAAgB;AAClB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,UAAgB;AACd,SAAK,SAAA,GACL,KAAK,GAAG,MAAA,GACR,KAAK,OAAO,WAAA,GACZ,KAAK,KAAK,WAAA;AAAA,EACZ;AAAA,EAEQ,WAAiB;AACvB,IAAI,KAAK,SAAO,aAAa,KAAK,KAAK,GACvC,KAAK,QAAQ;AAAA,EACf;AACF;"}
@@ -0,0 +1,58 @@
1
+ class h {
2
+ constructor(e, t) {
3
+ this.volume = e, this.makeVoice = t;
4
+ }
5
+ volume;
6
+ makeVoice;
7
+ voice = null;
8
+ url = null;
9
+ level = 1;
10
+ /** The url of the track playing (or fading in), if any. */
11
+ get current() {
12
+ return this.url;
13
+ }
14
+ /** Plays `url`, crossfading from what plays now; the track already playing only takes the new `volume`. */
15
+ play(e, t = {}) {
16
+ const s = Math.min(1, Math.max(0, t.volume ?? 1));
17
+ if (e === this.url) {
18
+ s !== this.level && (this.level = s, this.refresh());
19
+ return;
20
+ }
21
+ if (typeof Audio > "u") return;
22
+ const o = Math.max(0, t.fadeMs ?? 1200);
23
+ this.fadeOut(o), this.url = e, this.level = s;
24
+ const i = new Audio(e);
25
+ i.loop = t.loop !== !1, i.preload = "auto";
26
+ const l = this.makeVoice(i);
27
+ l.set(0), this.voice = l, i.play().catch(() => {
28
+ }), l.fade(this.target(), o);
29
+ }
30
+ /** Fades this channel out and stops it. */
31
+ stop(e = 1200) {
32
+ this.fadeOut(Math.max(0, e)), this.url = null;
33
+ }
34
+ /** Retries a start the browser refused, and follows the music volume. */
35
+ refresh() {
36
+ const e = this.voice;
37
+ e && (e.el.paused && e.el.play().catch(() => {
38
+ }), e.busy || e.set(this.target()));
39
+ }
40
+ /** Stops where it is (the app went to the background); `refresh` picks it up again. */
41
+ pause() {
42
+ this.voice?.el.pause();
43
+ }
44
+ dispose() {
45
+ this.voice?.dispose(), this.voice = null, this.url = null;
46
+ }
47
+ target() {
48
+ return Math.max(0, Math.min(1, this.volume() * this.level));
49
+ }
50
+ fadeOut(e) {
51
+ const t = this.voice;
52
+ this.voice = null, t && t.fade(0, e, () => t.dispose());
53
+ }
54
+ }
55
+ export {
56
+ h as MusicChannel
57
+ };
58
+ //# sourceMappingURL=MusicChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MusicChannel.js","sources":["../../../src/audio/music/MusicChannel.ts"],"sourcesContent":["import type { MusicVoice } from './musicVoice';\n\nexport interface PlayOptions {\n /** Crossfade from what this channel plays now, ms (default 1200). */\n fadeMs?: number;\n /** Start over at the end (default true). */\n loop?: boolean;\n /** This track's own level, 0–1, under the music volume (default 1). */\n volume?: number;\n}\n\n/**\n * One layer of music (the score, a place's ambience…): one looping track at a time, crossfaded when it changes, at\n * its own level under the player's music volume.\n */\nexport class MusicChannel {\n private voice: MusicVoice | null = null;\n private url: string | null = null;\n private level = 1;\n\n constructor(\n private readonly volume: () => number,\n private readonly makeVoice: (el: HTMLAudioElement) => MusicVoice,\n ) {}\n\n /** The url of the track playing (or fading in), if any. */\n get current(): string | null {\n return this.url;\n }\n\n /** Plays `url`, crossfading from what plays now; the track already playing only takes the new `volume`. */\n play(url: string, options: PlayOptions = {}): void {\n const level = Math.min(1, Math.max(0, options.volume ?? 1));\n if (url === this.url) {\n if (level !== this.level) {\n this.level = level;\n this.refresh();\n }\n return;\n }\n if (typeof Audio === 'undefined') return;\n const fadeMs = Math.max(0, options.fadeMs ?? 1200);\n this.fadeOut(fadeMs);\n this.url = url;\n this.level = level;\n const el = new Audio(url);\n el.loop = options.loop !== false;\n el.preload = 'auto';\n const voice = this.makeVoice(el);\n voice.set(0);\n this.voice = voice;\n void el.play().catch(() => {\n // refused until the first gesture; the player's unlock retries it\n });\n voice.fade(this.target(), fadeMs);\n }\n\n /** Fades this channel out and stops it. */\n stop(fadeMs = 1200): void {\n this.fadeOut(Math.max(0, fadeMs));\n this.url = null;\n }\n\n /** Retries a start the browser refused, and follows the music volume. */\n refresh(): void {\n const v = this.voice;\n if (!v) return;\n if (v.el.paused) void v.el.play().catch(() => {});\n if (!v.busy) v.set(this.target());\n }\n\n /** Stops where it is (the app went to the background); `refresh` picks it up again. */\n pause(): void {\n this.voice?.el.pause();\n }\n\n dispose(): void {\n this.voice?.dispose();\n this.voice = null;\n this.url = null;\n }\n\n private target(): number {\n return Math.max(0, Math.min(1, this.volume() * this.level));\n }\n\n private fadeOut(ms: number): void {\n const old = this.voice;\n this.voice = null;\n if (old) old.fade(0, ms, () => old.dispose());\n }\n}\n"],"names":["MusicChannel","volume","makeVoice","url","options","level","fadeMs","el","voice","v","ms","old"],"mappings":"AAeO,MAAMA,EAAa;AAAA,EAKxB,YACmBC,GACAC,GACjB;AAFiB,SAAA,SAAAD,GACA,KAAA,YAAAC;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EANX,QAA2B;AAAA,EAC3B,MAAqB;AAAA,EACrB,QAAQ;AAAA;AAAA,EAQhB,IAAI,UAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,KAAKC,GAAaC,IAAuB,IAAU;AACjD,UAAMC,IAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGD,EAAQ,UAAU,CAAC,CAAC;AAC1D,QAAID,MAAQ,KAAK,KAAK;AACpB,MAAIE,MAAU,KAAK,UACjB,KAAK,QAAQA,GACb,KAAK,QAAA;AAEP;AAAA,IACF;AACA,QAAI,OAAO,QAAU,IAAa;AAClC,UAAMC,IAAS,KAAK,IAAI,GAAGF,EAAQ,UAAU,IAAI;AACjD,SAAK,QAAQE,CAAM,GACnB,KAAK,MAAMH,GACX,KAAK,QAAQE;AACb,UAAME,IAAK,IAAI,MAAMJ,CAAG;AACxB,IAAAI,EAAG,OAAOH,EAAQ,SAAS,IAC3BG,EAAG,UAAU;AACb,UAAMC,IAAQ,KAAK,UAAUD,CAAE;AAC/B,IAAAC,EAAM,IAAI,CAAC,GACX,KAAK,QAAQA,GACRD,EAAG,OAAO,MAAM,MAAM;AAAA,IAE3B,CAAC,GACDC,EAAM,KAAK,KAAK,OAAA,GAAUF,CAAM;AAAA,EAClC;AAAA;AAAA,EAGA,KAAKA,IAAS,MAAY;AACxB,SAAK,QAAQ,KAAK,IAAI,GAAGA,CAAM,CAAC,GAChC,KAAK,MAAM;AAAA,EACb;AAAA;AAAA,EAGA,UAAgB;AACd,UAAMG,IAAI,KAAK;AACf,IAAKA,MACDA,EAAE,GAAG,UAAaA,EAAE,GAAG,OAAO,MAAM,MAAM;AAAA,IAAC,CAAC,GAC3CA,EAAE,UAAQ,IAAI,KAAK,QAAQ;AAAA,EAClC;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,OAAO,GAAG,MAAA;AAAA,EACjB;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,QAAA,GACZ,KAAK,QAAQ,MACb,KAAK,MAAM;AAAA,EACb;AAAA,EAEQ,SAAiB;AACvB,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,OAAA,IAAW,KAAK,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEQ,QAAQC,GAAkB;AAChC,UAAMC,IAAM,KAAK;AACjB,SAAK,QAAQ,MACTA,OAAS,KAAK,GAAGD,GAAI,MAAMC,EAAI,SAAS;AAAA,EAC9C;AACF;"}
@@ -0,0 +1,13 @@
1
+ function n() {
2
+ if (typeof Audio > "u") return !1;
3
+ const e = typeof navigator < "u" ? navigator : null;
4
+ if (e && (/iPhone|iPad|iPod/.test(e.userAgent) || /Macintosh/.test(e.userAgent) && e.maxTouchPoints > 1)) return !0;
5
+ const t = new Audio();
6
+ return t.volume = 0.5, Math.abs(t.volume - 0.5) > 0.01;
7
+ }
8
+ const o = (e) => Math.max(0, Math.min(1, e));
9
+ export {
10
+ o as clamp01,
11
+ n as elementVolumeLocked
12
+ };
13
+ //# sourceMappingURL=musicVoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"musicVoice.js","sources":["../../../src/audio/music/musicVoice.ts"],"sourcesContent":["/**\n * One looping track playing on one channel of `MusicPlayer`, with a volume that can be set and faded. Two ways to get\n * one: `ElementVoice` (the `<audio>` element's own volume) and `GraphVoice` (the element routed through a Web Audio\n * gain, for where an `<audio>`'s `volume` is read-only: iOS).\n */\nexport interface MusicVoice {\n readonly el: HTMLAudioElement;\n /** The volume now (0..1). */\n level(): number;\n /** Sets it at once, cancelling a fade in flight. */\n set(level: number): void;\n /** Fades to `level` over `ms`; `done` runs at the end (not if a later fade or `set` takes over). */\n fade(level: number, ms: number, done?: () => void): void;\n /** A fade is in flight: the channel leaves the volume setting alone until it ends. */\n readonly busy: boolean;\n /** Stops the sound and lets the element go. */\n dispose(): void;\n}\n\n/**\n * True where an `<audio>` ignores `volume` (iOS WebKit), so music has to go through Web Audio to be faded at all.\n * Newer iOS reads a set volume back while the speaker ignores it, so the probe alone misses it: an iPhone, iPod or an\n * iPad posing as a Mac is named first.\n */\nexport function elementVolumeLocked(): boolean {\n if (typeof Audio === 'undefined') return false;\n const nav = typeof navigator !== 'undefined' ? navigator : null;\n if (nav && (/iPhone|iPad|iPod/.test(nav.userAgent) || (/Macintosh/.test(nav.userAgent) && nav.maxTouchPoints > 1))) return true;\n const probe = new Audio();\n probe.volume = 0.5;\n return Math.abs(probe.volume - 0.5) > 0.01;\n}\n\nexport const clamp01 = (n: number): number => Math.max(0, Math.min(1, n));\n"],"names":["elementVolumeLocked","nav","probe","clamp01","n"],"mappings":"AAwBO,SAASA,IAA+B;AAC7C,MAAI,OAAO,QAAU,IAAa,QAAO;AACzC,QAAMC,IAAM,OAAO,YAAc,MAAc,YAAY;AAC3D,MAAIA,MAAQ,mBAAmB,KAAKA,EAAI,SAAS,KAAM,YAAY,KAAKA,EAAI,SAAS,KAAKA,EAAI,iBAAiB,GAAK,QAAO;AAC3H,QAAMC,IAAQ,IAAI,MAAA;AAClB,SAAAA,EAAM,SAAS,KACR,KAAK,IAAIA,EAAM,SAAS,GAAG,IAAI;AACxC;AAEO,MAAMC,IAAU,CAACC,MAAsB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAC,CAAC;"}
@@ -0,0 +1,82 @@
1
+ import { cleanSamples as d } from "./cleanTake.js";
2
+ const c = {};
3
+ function k(e) {
4
+ for (const [n, t] of Object.entries(e)) {
5
+ const r = /(?:^|\/)([a-z_]+?)(?:_\d+)?\.mp3$/.exec(n);
6
+ r && (c[r[1]] ??= []).push(t);
7
+ }
8
+ }
9
+ const y = (e) => !!c[e];
10
+ class M {
11
+ decoded = /* @__PURE__ */ new Map();
12
+ loading = /* @__PURE__ */ new Set();
13
+ last = /* @__PURE__ */ new Map();
14
+ names() {
15
+ return Object.keys(c);
16
+ }
17
+ /** A decoded take, or null while none is ready (the caller then synthesises); starts loading on first ask. */
18
+ take(n, t) {
19
+ const r = this.decoded.get(t);
20
+ if (!r?.length)
21
+ return this.load(n, t), null;
22
+ let s = Math.floor(Math.random() * r.length);
23
+ return r.length > 1 && s === this.last.get(t) && (s = (s + 1) % r.length), this.last.set(t, s), r[s];
24
+ }
25
+ load(n, t) {
26
+ const r = c[t];
27
+ if (!r || this.loading.has(t)) return;
28
+ this.loading.add(t);
29
+ const s = [];
30
+ this.decoded.set(t, s);
31
+ for (const l of r)
32
+ fetch(l).then((a) => a.arrayBuffer()).then((a) => n.decodeAudioData(a)).then((a) => p(a)).then((a) => {
33
+ if (!a) return;
34
+ const h = n.createBuffer(1, a.length, n.sampleRate);
35
+ h.copyToChannel(a, 0), s.push(h);
36
+ }).catch(() => {
37
+ });
38
+ }
39
+ }
40
+ let o, f = 0;
41
+ const i = /* @__PURE__ */ new Map();
42
+ function m() {
43
+ if (o !== void 0) return o;
44
+ try {
45
+ o = new Worker(new URL(
46
+ /* @vite-ignore */
47
+ "" + new URL("../assets/takeCleanerWorker-DTcI_Jqr.js", import.meta.url).href,
48
+ import.meta.url
49
+ ), { type: "module" }), o.onmessage = (e) => {
50
+ i.get(e.data.id)?.(e.data.data), i.delete(e.data.id);
51
+ }, o.onerror = () => {
52
+ o?.terminate(), o = null;
53
+ for (const e of i.values()) e(null);
54
+ i.clear();
55
+ };
56
+ } catch {
57
+ o = null;
58
+ }
59
+ return o;
60
+ }
61
+ let u = Promise.resolve();
62
+ function p(e) {
63
+ return new Promise((n) => {
64
+ u = u.then(() => new Promise((t) => setTimeout(t, 0))).then(() => {
65
+ g(e).then(n, () => n(null));
66
+ });
67
+ });
68
+ }
69
+ function g(e) {
70
+ const n = Array.from({ length: e.numberOfChannels }, (s, l) => e.getChannelData(l).slice()), t = m();
71
+ if (!t) return Promise.resolve(d(n, e.sampleRate));
72
+ const r = f++;
73
+ return new Promise((s) => {
74
+ i.set(r, s), t.postMessage({ id: r, channels: n, sampleRate: e.sampleRate }, { transfer: n.map((l) => l.buffer) });
75
+ });
76
+ }
77
+ export {
78
+ M as SampleBank,
79
+ y as hasTakes,
80
+ k as registerTakes
81
+ };
82
+ //# sourceMappingURL=sampleBank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampleBank.js","sources":["../../src/audio/sampleBank.ts"],"sourcesContent":["/**\n * The recorded takes of the sounds, registered by the game (`registerTakes`): `<sound>.mp3`, and `<sound>_2.mp3`…\n * when a sound has more than one. A\n * sound with takes plays one of them at random, never the same one twice running when it has more; a sound without\n * any — or whose takes have not decoded yet — falls back to its synth recipe in `SoundEngine`.\n *\n * Every take is cleaned once on decode (`cleanTake.ts`: mono, silence trimmed, one loudness), off the main thread\n * in `takeCleanerWorker.ts`, so `sounds.json`'s `fileGain` is the only mix knob. Measured on the first batch, peaks\n * alone left their loudness 20 dB apart.\n */\n\nimport { cleanSamples } from './cleanTake';\n\nconst TAKES: Record<string, string[]> = {};\n\n/**\n * Registers recorded takes by file path → url, e.g. a Vite `import.meta.glob('./sfx/*.mp3', { query: '?url',\n * import: 'default', eager: true })`. `hit.mp3`, `hit_2.mp3`… are takes of `hit`; sound names carry no digits.\n */\nexport function registerTakes(urls: Record<string, string>): void {\n for (const [path, url] of Object.entries(urls)) {\n const m = /(?:^|\\/)([a-z_]+?)(?:_\\d+)?\\.mp3$/.exec(path);\n if (m) (TAKES[m[1]!] ??= []).push(url);\n }\n}\n\n/** The sound has recorded takes in the build (decoded or not). */\nexport const hasTakes = (name: string): boolean => !!TAKES[name];\n\nexport class SampleBank {\n private readonly decoded = new Map<string, AudioBuffer[]>();\n private readonly loading = new Set<string>();\n private readonly last = new Map<string, number>();\n\n names(): string[] {\n return Object.keys(TAKES);\n }\n\n /** A decoded take, or null while none is ready (the caller then synthesises); starts loading on first ask. */\n take(ctx: AudioContext, name: string): AudioBuffer | null {\n const list = this.decoded.get(name);\n if (!list?.length) {\n this.load(ctx, name);\n return null;\n }\n let i = Math.floor(Math.random() * list.length);\n if (list.length > 1 && i === this.last.get(name)) i = (i + 1) % list.length;\n this.last.set(name, i);\n return list[i]!;\n }\n\n load(ctx: AudioContext, name: string): void {\n const urlsOf = TAKES[name];\n if (!urlsOf || this.loading.has(name)) return;\n this.loading.add(name);\n const list: AudioBuffer[] = [];\n this.decoded.set(name, list);\n for (const url of urlsOf) {\n fetch(url)\n .then((r) => r.arrayBuffer())\n .then((data) => ctx.decodeAudioData(data))\n .then((buf) => clean(buf))\n .then((data) => {\n if (!data) return;\n const out = ctx.createBuffer(1, data.length, ctx.sampleRate);\n out.copyToChannel(data as Float32Array<ArrayBuffer>, 0);\n list.push(out);\n })\n .catch(() => {});\n }\n }\n}\n\nlet worker: Worker | null | undefined;\nlet nextId = 0;\nconst waiting = new Map<number, (data: Float32Array | null) => void>();\n\n/** The cleaner worker, started on first use; null where workers cannot start (then takes are cleaned here). */\nfunction cleaner(): Worker | null {\n if (worker !== undefined) return worker;\n try {\n worker = new Worker(new URL('./takeCleanerWorker.ts', import.meta.url), { type: 'module' });\n worker.onmessage = (e: MessageEvent<{ id: number; data: Float32Array | null }>) => {\n waiting.get(e.data.id)?.(e.data.data);\n waiting.delete(e.data.id);\n };\n worker.onerror = () => {\n worker?.terminate();\n worker = null;\n for (const done of waiting.values()) done(null);\n waiting.clear();\n };\n } catch {\n worker = null;\n }\n return worker;\n}\n\n/** Takes handed over one per task: a fight's first blows ask for a dozen at once, and copying them all out in one\n * task still froze a frame. */\nlet turn: Promise<void> = Promise.resolve();\n\n/** A decoded take cleaned at the context's own rate (decodeAudioData resamples to it). */\nfunction clean(buf: AudioBuffer): Promise<Float32Array | null> {\n return new Promise((resolve) => {\n turn = turn\n .then(() => new Promise<void>((r) => setTimeout(r, 0)))\n .then(() => {\n send(buf).then(resolve, () => resolve(null));\n });\n });\n}\n\nfunction send(buf: AudioBuffer): Promise<Float32Array | null> {\n const channels = Array.from({ length: buf.numberOfChannels }, (_, c) => buf.getChannelData(c).slice());\n const w = cleaner();\n if (!w) return Promise.resolve(cleanSamples(channels, buf.sampleRate));\n const id = nextId++;\n return new Promise((resolve) => {\n waiting.set(id, resolve);\n w.postMessage({ id, channels, sampleRate: buf.sampleRate }, { transfer: channels.map((c) => c.buffer as ArrayBuffer) });\n });\n}\n"],"names":["TAKES","registerTakes","urls","path","url","m","hasTakes","name","SampleBank","ctx","list","i","urlsOf","r","data","buf","clean","out","worker","nextId","waiting","cleaner","done","turn","resolve","send","channels","_","c","w","cleanSamples","id"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ const s = { master: 1, recipes: {} };
2
+ function r(e) {
3
+ e.master !== void 0 && (s.master = e.master), e.recipes && Object.assign(s.recipes, e.recipes);
4
+ }
5
+ export {
6
+ s as SOUNDS,
7
+ r as registerSounds
8
+ };
9
+ //# sourceMappingURL=soundTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"soundTable.js","sources":["../../src/audio/soundTable.ts"],"sourcesContent":["import type { SynthRecipe } from './synth';\n\n/**\n * The sounds the engine can play: synthesised recipes by name, plus the master share every sound plays at. Empty\n * until the game registers its own (`registerSounds`); the mapping from game happenings to sound names stays in\n * the game.\n */\nexport interface SoundTable {\n /** Share of the effects volume everything plays at: keeps full volume modest next to the music. */\n master: number;\n recipes: Record<string, SynthRecipe>;\n}\n\nexport const SOUNDS: SoundTable = { master: 1, recipes: {} };\n\nexport function registerSounds(table: Partial<SoundTable>): void {\n if (table.master !== undefined) SOUNDS.master = table.master;\n if (table.recipes) Object.assign(SOUNDS.recipes, table.recipes);\n}\n"],"names":["SOUNDS","registerSounds","table"],"mappings":"AAaO,MAAMA,IAAqB,EAAE,QAAQ,GAAG,SAAS,CAAA,EAAC;AAElD,SAASC,EAAeC,GAAkC;AAC/D,EAAIA,EAAM,WAAW,WAAWF,EAAO,SAASE,EAAM,SAClDA,EAAM,WAAS,OAAO,OAAOF,EAAO,SAASE,EAAM,OAAO;AAChE;"}
@@ -0,0 +1,36 @@
1
+ const Y = 22050, N = {
2
+ sine: (e) => Math.sin(e * Math.PI * 2),
3
+ square: (e, a) => e < a ? 1 : -1,
4
+ tri: (e) => 1 - 4 * Math.abs(e - 0.5),
5
+ saw: (e) => 2 * e - 1
6
+ }, i = (e, a, n) => e > 0 && a > 0 ? e * Math.pow(a / e, n) : e + (a - e) * n;
7
+ function R(e) {
8
+ return 1 - Math.exp(-2 * Math.PI * Math.min(e, 22050 * 0.45) / 22050);
9
+ }
10
+ function _(e) {
11
+ const a = Math.max(...e.layers.map((t) => (t.d ?? 0) + t.t)), n = new Float32Array(Math.ceil(a * 22050) + 1);
12
+ let s = 2654435769;
13
+ const S = () => (s ^= s << 13, s ^= s >>> 17, s ^= s << 5, (s >>> 0) / 4294967295 * 2 - 1);
14
+ for (const t of e.layers) {
15
+ const u = Math.round((t.d ?? 0) * 22050), f = Math.round(t.t * 22050), l = Math.max(1, Math.round((t.at ?? 4e-3) * 22050));
16
+ let c = 0, A = 0, M = 0, T = 0;
17
+ for (let o = 0; o < f && u + o < n.length; o++) {
18
+ const p = o / f, d = t.f ? i(t.f[0], t.f[1], p) : 0;
19
+ c += d / 22050;
20
+ const E = c - Math.floor(c);
21
+ let h;
22
+ t.w === "noise" ? ((!t.f || E < d / 22050 || o === 0) && (A = S()), h = t.f ? A : S()) : h = N[t.w](E, t.duty ?? 0.5), t.lp && (M += (h - M) * R(i(t.lp[0], t.lp[1], p)), h = M), t.hp && (T += (h - T) * R(i(t.hp[0], t.hp[1], p)), h -= T);
23
+ const H = o < l ? o / l : Math.pow(1 - (o - l) / Math.max(1, f - l), t.c ?? 2);
24
+ n[u + o] += h * H * t.g;
25
+ }
26
+ }
27
+ let r = 0;
28
+ for (const t of n) r = Math.max(r, Math.abs(t));
29
+ if (r > 0.95) for (let t = 0; t < n.length; t++) n[t] *= 0.95 / r;
30
+ return n;
31
+ }
32
+ export {
33
+ Y as SYNTH_RATE,
34
+ _ as renderRecipe
35
+ };
36
+ //# sourceMappingURL=synth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synth.js","sources":["../../src/audio/synth.ts"],"sourcesContent":["/**\n * The combat sounds are written, not recorded: a few oscillator or noise layers rendered straight into a buffer\n * (`sounds.json` → `recipes`). Lo-fi on purpose — 22 kHz mono, short and soft — so they sit with the pixel art\n * instead of pretending to be a recording.\n */\nexport const SYNTH_RATE = 22050;\n\nexport interface SynthLayer {\n /** Waveform; `noise` is white noise, or sample-and-hold noise at `f` Hz when `f` is given (crunchier). */\n w: 'sine' | 'square' | 'tri' | 'saw' | 'noise';\n /** Pitch at the start and at the end of the layer (Hz), swept exponentially. */\n f?: [number, number];\n /** Length (s). */\n t: number;\n /** Delay before the layer starts (s). */\n d?: number;\n /** Attack (s). */\n at?: number;\n g: number;\n /** Decay curve exponent: 1 is linear, higher falls away faster. */\n c?: number;\n duty?: number;\n /** Low- and high-pass cutoff at the start and the end (Hz). */\n lp?: [number, number];\n hp?: [number, number];\n}\n\nexport interface SynthRecipe {\n layers: SynthLayer[];\n /** Random pitch spread per play (share of 1); the engine's default when absent. */\n jitter?: number;\n /** Level of the sound's recorded takes (`registerTakes`), which are normalised on decode; default 1. */\n fileGain?: number;\n}\n\nconst WAVES: Record<Exclude<SynthLayer['w'], 'noise'>, (p: number, duty: number) => number> = {\n sine: (p) => Math.sin(p * Math.PI * 2),\n square: (p, duty) => (p < duty ? 1 : -1),\n tri: (p) => 1 - 4 * Math.abs(p - 0.5),\n saw: (p) => 2 * p - 1,\n};\n\nconst sweep = (a: number, b: number, k: number): number => (a > 0 && b > 0 ? a * Math.pow(b / a, k) : a + (b - a) * k);\n\n/** A one-pole filter is enough for a stand-in, and it cannot ring or blow up the way a swept biquad can. */\nfunction onePole(cut: number): number {\n return 1 - Math.exp((-2 * Math.PI * Math.min(cut, SYNTH_RATE * 0.45)) / SYNTH_RATE);\n}\n\nexport function renderRecipe(recipe: SynthRecipe): Float32Array {\n const total = Math.max(...recipe.layers.map((l) => (l.d ?? 0) + l.t));\n const out = new Float32Array(Math.ceil(total * SYNTH_RATE) + 1);\n let seed = 0x9e3779b9;\n const rand = () => {\n seed ^= seed << 13;\n seed ^= seed >>> 17;\n seed ^= seed << 5;\n return ((seed >>> 0) / 0xffffffff) * 2 - 1;\n };\n for (const l of recipe.layers) {\n const start = Math.round((l.d ?? 0) * SYNTH_RATE);\n const n = Math.round(l.t * SYNTH_RATE);\n const at = Math.max(1, Math.round((l.at ?? 0.004) * SYNTH_RATE));\n let phase = 0;\n let held = 0;\n let lpState = 0;\n let hpState = 0;\n for (let i = 0; i < n && start + i < out.length; i++) {\n const k = i / n;\n const freq = l.f ? sweep(l.f[0], l.f[1], k) : 0;\n phase += freq / SYNTH_RATE;\n const p = phase - Math.floor(phase);\n let s: number;\n if (l.w === 'noise') {\n // sample-and-hold: a new value each time the phase wraps, which is what makes it crunch\n if (!l.f || p < freq / SYNTH_RATE || i === 0) held = rand();\n s = l.f ? held : rand();\n } else s = WAVES[l.w](p, l.duty ?? 0.5);\n if (l.lp) {\n lpState += (s - lpState) * onePole(sweep(l.lp[0], l.lp[1], k));\n s = lpState;\n }\n if (l.hp) {\n hpState += (s - hpState) * onePole(sweep(l.hp[0], l.hp[1], k));\n s -= hpState;\n }\n const env = i < at ? i / at : Math.pow(1 - (i - at) / Math.max(1, n - at), l.c ?? 2);\n out[start + i]! += s * env * l.g;\n }\n }\n // a stand-in never clips: peaks are brought back under full scale\n let peak = 0;\n for (const v of out) peak = Math.max(peak, Math.abs(v));\n if (peak > 0.95) for (let i = 0; i < out.length; i++) out[i]! *= 0.95 / peak;\n return out;\n}\n"],"names":["SYNTH_RATE","WAVES","p","duty","sweep","a","b","k","onePole","cut","renderRecipe","recipe","total","l","out","seed","rand","start","n","at","phase","held","lpState","hpState","i","freq","s","env","peak","v"],"mappings":"AAKO,MAAMA,IAAa,OA8BpBC,IAAwF;AAAA,EAC5F,MAAM,CAACC,MAAM,KAAK,IAAIA,IAAI,KAAK,KAAK,CAAC;AAAA,EACrC,QAAQ,CAACA,GAAGC,MAAUD,IAAIC,IAAO,IAAI;AAAA,EACrC,KAAK,CAACD,MAAM,IAAI,IAAI,KAAK,IAAIA,IAAI,GAAG;AAAA,EACpC,KAAK,CAACA,MAAM,IAAIA,IAAI;AACtB,GAEME,IAAQ,CAACC,GAAWC,GAAWC,MAAuBF,IAAI,KAAKC,IAAI,IAAID,IAAI,KAAK,IAAIC,IAAID,GAAGE,CAAC,IAAIF,KAAKC,IAAID,KAAKE;AAGpH,SAASC,EAAQC,GAAqB;AACpC,SAAO,IAAI,KAAK,IAAK,KAAK,KAAK,KAAK,KAAK,IAAIA,GAAK,QAAa,IAAI,IAAK,KAAU;AACpF;AAEO,SAASC,EAAaC,GAAmC;AAC9D,QAAMC,IAAQ,KAAK,IAAI,GAAGD,EAAO,OAAO,IAAI,CAACE,OAAOA,EAAE,KAAK,KAAKA,EAAE,CAAC,CAAC,GAC9DC,IAAM,IAAI,aAAa,KAAK,KAAKF,IAAQ,KAAU,IAAI,CAAC;AAC9D,MAAIG,IAAO;AACX,QAAMC,IAAO,OACXD,KAAQA,KAAQ,IAChBA,KAAQA,MAAS,IACjBA,KAAQA,KAAQ,IACPA,MAAS,KAAK,aAAc,IAAI;AAE3C,aAAWF,KAAKF,EAAO,QAAQ;AAC7B,UAAMM,IAAQ,KAAK,OAAOJ,EAAE,KAAK,KAAK,KAAU,GAC1CK,IAAI,KAAK,MAAML,EAAE,IAAI,KAAU,GAC/BM,IAAK,KAAK,IAAI,GAAG,KAAK,OAAON,EAAE,MAAM,QAAS,KAAU,CAAC;AAC/D,QAAIO,IAAQ,GACRC,IAAO,GACPC,IAAU,GACVC,IAAU;AACd,aAASC,IAAI,GAAGA,IAAIN,KAAKD,IAAQO,IAAIV,EAAI,QAAQU,KAAK;AACpD,YAAMjB,IAAIiB,IAAIN,GACRO,IAAOZ,EAAE,IAAIT,EAAMS,EAAE,EAAE,CAAC,GAAGA,EAAE,EAAE,CAAC,GAAGN,CAAC,IAAI;AAC9C,MAAAa,KAASK,IAAO;AAChB,YAAMvB,IAAIkB,IAAQ,KAAK,MAAMA,CAAK;AAClC,UAAIM;AACJ,MAAIb,EAAE,MAAM,YAEN,CAACA,EAAE,KAAKX,IAAIuB,IAAO,SAAcD,MAAM,OAAGH,IAAOL,EAAA,IACrDU,IAAIb,EAAE,IAAIQ,IAAOL,EAAA,SACRf,EAAMY,EAAE,CAAC,EAAEX,GAAGW,EAAE,QAAQ,GAAG,GAClCA,EAAE,OACJS,MAAYI,IAAIJ,KAAWd,EAAQJ,EAAMS,EAAE,GAAG,CAAC,GAAGA,EAAE,GAAG,CAAC,GAAGN,CAAC,CAAC,GAC7DmB,IAAIJ,IAEFT,EAAE,OACJU,MAAYG,IAAIH,KAAWf,EAAQJ,EAAMS,EAAE,GAAG,CAAC,GAAGA,EAAE,GAAG,CAAC,GAAGN,CAAC,CAAC,GAC7DmB,KAAKH;AAEP,YAAMI,IAAMH,IAAIL,IAAKK,IAAIL,IAAK,KAAK,IAAI,KAAKK,IAAIL,KAAM,KAAK,IAAI,GAAGD,IAAIC,CAAE,GAAGN,EAAE,KAAK,CAAC;AACnF,MAAAC,EAAIG,IAAQO,CAAC,KAAME,IAAIC,IAAMd,EAAE;AAAA,IACjC;AAAA,EACF;AAEA,MAAIe,IAAO;AACX,aAAWC,KAAKf,EAAK,CAAAc,IAAO,KAAK,IAAIA,GAAM,KAAK,IAAIC,CAAC,CAAC;AACtD,MAAID,IAAO,KAAM,UAASJ,IAAI,GAAGA,IAAIV,EAAI,QAAQU,IAAK,CAAAV,EAAIU,CAAC,KAAM,OAAOI;AACxE,SAAOd;AACT;"}
@@ -0,0 +1,49 @@
1
+ import { DynamicBitmapFont as S, BitmapFont as d, BitmapText as $ } from "pixi.js";
2
+ import { GameObject as h } from "./gameObject.js";
3
+ const m = /* @__PURE__ */ new Set(), u = [[" ", "~"]];
4
+ function w(s) {
5
+ u.push(s);
6
+ }
7
+ const x = 128;
8
+ function b(s, t, e, r, c, a, n = "") {
9
+ const i = `label|${s}|${t}|${e}|${r}|${c}|${a}${n ? `|${n}` : ""}`;
10
+ if (!m.has(i)) {
11
+ const o = S.defaultOptions, l = o.textureSize;
12
+ o.textureSize = x;
13
+ try {
14
+ d.install({
15
+ name: i,
16
+ chars: n ? [...u, n] : u,
17
+ resolution: a,
18
+ style: { fontFamily: s, fontSize: t, fill: e, stroke: { color: r, width: c, join: "round" } }
19
+ });
20
+ } finally {
21
+ o.textureSize = l;
22
+ }
23
+ m.add(i);
24
+ }
25
+ return i;
26
+ }
27
+ class y extends h($) {
28
+ /**
29
+ * `fontFamily` must already be loaded (`document.fonts.load`), or the glyphs bake in the fallback.
30
+ * Styled like `worldText`: the same font, size, colour and outline, rasterised at the same resolution. `glyphs`:
31
+ * letters beyond ASCII it prints (see `installLabelFont`).
32
+ */
33
+ constructor(t, e, r, c, a, n, i, o, l, f = "") {
34
+ const p = b(c, a, n, i, o, l, f);
35
+ super({ text: r, style: { fontFamily: p, fontSize: a } }), this.position.set(t, e);
36
+ }
37
+ setOrigin(t = 0.5, e = t) {
38
+ return this.anchor.set(t, e), this;
39
+ }
40
+ setText(t) {
41
+ return this.text = t, this;
42
+ }
43
+ }
44
+ export {
45
+ y as BitmapLabel,
46
+ w as addLabelGlyphs,
47
+ b as installLabelFont
48
+ };
49
+ //# sourceMappingURL=BitmapLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitmapLabel.js","sources":["../../src/core/BitmapLabel.ts"],"sourcesContent":["import { BitmapFont, BitmapText, DynamicBitmapFont } from 'pixi.js';\nimport { GameObject } from './gameObject';\n\nconst INSTALLED = new Set<string>();\n\n/**\n * The glyphs baked into every label font: printable ASCII (space to `~`) plus whatever a game adds (`addLabelGlyphs`)\n * for the words its labels print, so no glyph is baked mid-frame onto a fresh page (a new canvas a page, and iOS\n * hands out none once its canvas memory is spent).\n */\nconst CHARS: (string | [string, string])[] = [[' ', '~']];\n\n/**\n * Adds letters every label font made **after this call** bakes ahead — the accented letters of a language the labels\n * print (German's `'äöüß'`, say), an arrow, a star. A font already installed keeps the glyphs it was made with, so\n * call it once at start-up, before the first label or `FloatingText.warm`.\n *\n * Without it, a label font holds ASCII only: a letter outside it is still drawn (Pixi bakes it when first printed),\n * but on that frame, onto a new glyph page — the stall and the canvas memory this module exists to avoid. For one\n * font's own extra letters, pass them to `installLabelFont` (or `Label.bitmap`, `FloatingText`'s `glyphs`) instead.\n */\nexport function addLabelGlyphs(letters: string): void {\n CHARS.push(letters);\n}\n/**\n * The side of one glyph page in CSS pixels; a page's canvas is this × the resolution. Pixi's default, 512, made every\n * label font a 2048² canvas at resolution 4 (16 MB each, ten of them at boot); the numbers' glyphs fill a few pages of\n * this size instead.\n */\nconst PAGE_SIZE = 128;\n\n/**\n * Rasterises one label font once and returns its name. Called ahead of time for the damage numbers: baking a font on\n * its first number froze the first frame that printed one by ~60 ms. `glyphs` are letters this font bakes besides\n * ASCII and `addLabelGlyphs`' (a font with its own is a font of its own: pass the same `glyphs` wherever it is used).\n */\nexport function installLabelFont(fontFamily: string, size: number, color: string, stroke: string, strokeWidth: number, resolution: number, glyphs = ''): string {\n const name = `label|${fontFamily}|${size}|${color}|${stroke}|${strokeWidth}|${resolution}${glyphs ? `|${glyphs}` : ''}`;\n if (!INSTALLED.has(name)) {\n // `install` takes no page size of its own: it reads the dynamic font's default, set for this call only\n const defaults = DynamicBitmapFont.defaultOptions;\n const was = defaults.textureSize;\n defaults.textureSize = PAGE_SIZE;\n try {\n BitmapFont.install({\n name,\n chars: glyphs ? [...CHARS, glyphs] : CHARS,\n resolution,\n style: { fontFamily, fontSize: size, fill: color, stroke: { color: stroke, width: strokeWidth, join: 'round' } },\n });\n } finally {\n defaults.textureSize = was;\n }\n INSTALLED.add(name);\n }\n return name;\n}\n\n/**\n * Text drawn from a bitmap font: the glyphs are rasterised once per font, so changing the string costs no canvas\n * redraw and no texture upload, and every label of one font batches with the others. For the floating numbers, which\n * a crowded fight throws dozens of a second — a plain `Text` repaints its canvas at resolution 4 and uploads it on\n * every change.\n */\nexport class BitmapLabel extends GameObject(BitmapText) {\n /**\n * `fontFamily` must already be loaded (`document.fonts.load`), or the glyphs bake in the fallback.\n * Styled like `worldText`: the same font, size, colour and outline, rasterised at the same resolution. `glyphs`:\n * letters beyond ASCII it prints (see `installLabelFont`).\n */\n constructor(x: number, y: number, text: string, fontFamily: string, size: number, color: string, stroke: string, strokeWidth: number, resolution: number, glyphs = '') {\n const name = installLabelFont(fontFamily, size, color, stroke, strokeWidth, resolution, glyphs);\n super({ text, style: { fontFamily: name, fontSize: size } });\n this.position.set(x, y);\n }\n\n setOrigin(x = 0.5, y = x): this {\n this.anchor.set(x, y);\n return this;\n }\n\n setText(text: string): this {\n this.text = text;\n return this;\n }\n}\n"],"names":["INSTALLED","CHARS","addLabelGlyphs","letters","PAGE_SIZE","installLabelFont","fontFamily","size","color","stroke","strokeWidth","resolution","glyphs","name","defaults","DynamicBitmapFont","was","BitmapFont","BitmapLabel","GameObject","BitmapText","x","y","text"],"mappings":";;AAGA,MAAMA,wBAAgB,IAAA,GAOhBC,IAAuC,CAAC,CAAC,KAAK,GAAG,CAAC;AAWjD,SAASC,EAAeC,GAAuB;AACpD,EAAAF,EAAM,KAAKE,CAAO;AACpB;AAMA,MAAMC,IAAY;AAOX,SAASC,EAAiBC,GAAoBC,GAAcC,GAAeC,GAAgBC,GAAqBC,GAAoBC,IAAS,IAAY;AAC9J,QAAMC,IAAO,SAASP,CAAU,IAAIC,CAAI,IAAIC,CAAK,IAAIC,CAAM,IAAIC,CAAW,IAAIC,CAAU,GAAGC,IAAS,IAAIA,CAAM,KAAK,EAAE;AACrH,MAAI,CAACZ,EAAU,IAAIa,CAAI,GAAG;AAExB,UAAMC,IAAWC,EAAkB,gBAC7BC,IAAMF,EAAS;AACrB,IAAAA,EAAS,cAAcV;AACvB,QAAI;AACF,MAAAa,EAAW,QAAQ;AAAA,QACjB,MAAAJ;AAAA,QACA,OAAOD,IAAS,CAAC,GAAGX,GAAOW,CAAM,IAAIX;AAAA,QACrC,YAAAU;AAAA,QACA,OAAO,EAAE,YAAAL,GAAY,UAAUC,GAAM,MAAMC,GAAO,QAAQ,EAAE,OAAOC,GAAQ,OAAOC,GAAa,MAAM,UAAQ;AAAA,MAAE,CAChH;AAAA,IACH,UAAA;AACE,MAAAI,EAAS,cAAcE;AAAA,IACzB;AACA,IAAAhB,EAAU,IAAIa,CAAI;AAAA,EACpB;AACA,SAAOA;AACT;AAQO,MAAMK,UAAoBC,EAAWC,CAAU,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMtD,YAAYC,GAAWC,GAAWC,GAAcjB,GAAoBC,GAAcC,GAAeC,GAAgBC,GAAqBC,GAAoBC,IAAS,IAAI;AACrK,UAAMC,IAAOR,EAAiBC,GAAYC,GAAMC,GAAOC,GAAQC,GAAaC,GAAYC,CAAM;AAC9F,UAAM,EAAE,MAAAW,GAAM,OAAO,EAAE,YAAYV,GAAM,UAAUN,EAAA,GAAQ,GAC3D,KAAK,SAAS,IAAIc,GAAGC,CAAC;AAAA,EACxB;AAAA,EAEA,UAAUD,IAAI,KAAKC,IAAID,GAAS;AAC9B,gBAAK,OAAO,IAAIA,GAAGC,CAAC,GACb;AAAA,EACT;AAAA,EAEA,QAAQC,GAAoB;AAC1B,gBAAK,OAAOA,GACL;AAAA,EACT;AACF;"}