@thunderclap-engine/engine 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
import { type OccludableVoice, type OcclusionOptions } from './occlusion.js';
|
|
2
|
+
import type { Send } from './send.js';
|
|
3
|
+
import { type SpriteSchedule, type SpriteSheet } from './sprites.js';
|
|
4
|
+
import { type OfflineContextFactory, type SoundSpec } from './synth.js';
|
|
5
|
+
import { AudioZones } from './zones.js';
|
|
6
|
+
export declare const BUS_NAMES: readonly ['master', 'music', 'sfx', 'ui'];
|
|
7
|
+
export type BusName = (typeof BUS_NAMES)[number];
|
|
8
|
+
/** Buses a sound can play on (everything feeds master). */
|
|
9
|
+
export type OutputBus = Exclude<BusName, 'master'>;
|
|
10
|
+
export interface BusSettings {
|
|
11
|
+
/** Slider position 0..1 (mapped to gain with a squared curve). */
|
|
12
|
+
volume: number;
|
|
13
|
+
muted: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type MixerSettings = Record<BusName, BusSettings>;
|
|
16
|
+
export declare const DEFAULT_MIXER: Readonly<MixerSettings>;
|
|
17
|
+
/** Clamp and fill gaps so any (possibly hand-edited) object becomes valid settings. */
|
|
18
|
+
export declare function sanitizeMixer(input: unknown): MixerSettings;
|
|
19
|
+
/** Effective linear gain for a bus. */
|
|
20
|
+
export declare function busGain(s: BusSettings): number;
|
|
21
|
+
/**
|
|
22
|
+
* - `locked`: waiting for a user gesture (or no context yet).
|
|
23
|
+
* - `running`: playing.
|
|
24
|
+
* - `suspended`: unlocked but paused (tab hidden or `suspend()`).
|
|
25
|
+
* - `unavailable`: no WebAudio in this browser; everything is a silent no-op.
|
|
26
|
+
*/
|
|
27
|
+
export type AudioState = 'locked' | 'running' | 'suspended' | 'unavailable';
|
|
28
|
+
export interface AudioPlayOptions {
|
|
29
|
+
/** Default `sfx` for `play`, `music` for `loop`. */
|
|
30
|
+
bus?: OutputBus;
|
|
31
|
+
/** Linear gain on top of the bus. Default 1. */
|
|
32
|
+
gain?: number;
|
|
33
|
+
/** Playback rate (1 = original, 2 = octave up). Default 1. */
|
|
34
|
+
rate?: number;
|
|
35
|
+
/** Cents. */
|
|
36
|
+
detune?: number;
|
|
37
|
+
/**
|
|
38
|
+
* 2D stereo position, -1 (left) .. 1 (right), through a `StereoPannerNode`. The shorthand
|
|
39
|
+
* for a flat game (a sound from the left of the board). Ignored when `at` is set.
|
|
40
|
+
*/
|
|
41
|
+
pan?: number;
|
|
42
|
+
/**
|
|
43
|
+
* World position `[x, y, z]` of the emitter. Routes the voice through a pooled `PannerNode`
|
|
44
|
+
* (distance and direction relative to `audio.listener`); move it with `Voice.setPosition`.
|
|
45
|
+
* Read once at play time (the array is not kept). Takes precedence over `pan`.
|
|
46
|
+
*/
|
|
47
|
+
at?: ArrayLike<number>;
|
|
48
|
+
/** How a voice with `at` attenuates and pans. Ignored without `at`. */
|
|
49
|
+
spatial?: SpatialOptions;
|
|
50
|
+
/** Seconds from now. */
|
|
51
|
+
delay?: number;
|
|
52
|
+
/** Seconds to fade in. Default 0 for one-shots, 0.5 for loops. */
|
|
53
|
+
fadeIn?: number;
|
|
54
|
+
}
|
|
55
|
+
/** A playing (or pending) sound. Every method is safe to call at any time. */
|
|
56
|
+
export interface Voice {
|
|
57
|
+
/** Stop, optionally fading out over `fade` seconds. */
|
|
58
|
+
stop(fade?: number): void;
|
|
59
|
+
setGain(gain: number, ramp?: number): void;
|
|
60
|
+
setRate(rate: number, ramp?: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Move a spatial voice (one played with `at`) to world `(x, y, z)`. Writes the voice's own
|
|
63
|
+
* `PannerNode` in place, so it is safe to call every frame. No-op on a non-spatial voice;
|
|
64
|
+
* on a voice still waiting to start, the position is kept and applied at start.
|
|
65
|
+
*/
|
|
66
|
+
setPosition(x: number, y: number, z: number): void;
|
|
67
|
+
/** Point a spatial voice's cone (`spatial.cone`) along `(x, y, z)`. Same rules as `setPosition`. */
|
|
68
|
+
setDirection(x: number, y: number, z: number): void;
|
|
69
|
+
/**
|
|
70
|
+
* Make a spatial voice read its position from `target.world` (a 3×4 row-major world matrix,
|
|
71
|
+
* translation at floats 3, 7 and 11, such as a `Transform`'s) on every `audio.update(dt)`,
|
|
72
|
+
* so the game stops copying positions. `null` stops following. No-op on a non-spatial voice.
|
|
73
|
+
*/
|
|
74
|
+
follow(target: {
|
|
75
|
+
readonly world: ArrayLike<number>;
|
|
76
|
+
} | null): void;
|
|
77
|
+
/**
|
|
78
|
+
* Route a copy of this voice into an effect: a parallel path from the voice's output (after
|
|
79
|
+
* its gain and panner) through a send gain of `amount` into `input`, a `Send` (its `input`)
|
|
80
|
+
* or any `AudioNode`. The dry path to the bus is untouched. Calling again with the same
|
|
81
|
+
* `input` ramps the amount over `ramp` seconds (default 0.05); `amount` 0 disconnects it and
|
|
82
|
+
* frees the gain. At most `MAX_VOICE_SENDS` (4) inputs per voice; the fifth throws a
|
|
83
|
+
* `RangeError`. Torn down with the voice. No-op on an inert voice.
|
|
84
|
+
*/
|
|
85
|
+
sendTo(input: AudioNode | Send, amount: number, ramp?: number): void;
|
|
86
|
+
/**
|
|
87
|
+
* Insert one pooled `BiquadFilterNode` of `kind` between the voice's gain and its panner or
|
|
88
|
+
* bus (ws/audio-4), ramping `cutoff` (Hz) and `q` over `ramp` seconds (default 0.05); calling
|
|
89
|
+
* again retunes it, `null` removes it and returns the node to the pool. Independent of the
|
|
90
|
+
* occlusion lowpass: an occluded voice with a filter has two biquads in series. No-op on an
|
|
91
|
+
* inert voice; set before start, it is applied at start.
|
|
92
|
+
*/
|
|
93
|
+
filter(kind: VoiceFilterKind | null, opts?: VoiceFilterOptions): void;
|
|
94
|
+
/** World position of a spatial voice as last set or followed (zeros on a non-spatial voice). */
|
|
95
|
+
readonly position: ArrayLike<number>;
|
|
96
|
+
readonly playing: boolean;
|
|
97
|
+
/** Live sends (`sendTo` inputs with a non-zero amount). */
|
|
98
|
+
readonly sendCount: number;
|
|
99
|
+
/** The last answer of `audio.occlusion.probe` for this voice, 0 clear .. 1 occluded (0 when unprobed). */
|
|
100
|
+
readonly occlusion: number;
|
|
101
|
+
/**
|
|
102
|
+
* The Doppler multiplier on the playback rate as of the last `audio.update` (1 without
|
|
103
|
+
* `spatial.doppler`, and on every voice the mixer did not start; diagnostics).
|
|
104
|
+
*/
|
|
105
|
+
readonly doppler: number;
|
|
106
|
+
}
|
|
107
|
+
/** `Voice.filter` kinds (the `BiquadFilterNode` types a voice offers). */
|
|
108
|
+
export type VoiceFilterKind = 'lowpass' | 'highpass' | 'bandpass';
|
|
109
|
+
export interface VoiceFilterOptions {
|
|
110
|
+
/** Hz. Default 1000. */
|
|
111
|
+
cutoff?: number;
|
|
112
|
+
/** Resonance. Default 1. */
|
|
113
|
+
q?: number;
|
|
114
|
+
/** Seconds the cutoff and Q ramp over. Default 0.05. */
|
|
115
|
+
ramp?: number;
|
|
116
|
+
}
|
|
117
|
+
/** m/s, the Doppler reference (`SpatialOptions.doppler`). */
|
|
118
|
+
export declare const SPEED_OF_SOUND = 343;
|
|
119
|
+
/** m/s: a move faster than this between two `update`s is a teleport, not a velocity. */
|
|
120
|
+
export declare const DEFAULT_MAX_DOPPLER_SPEED = 100;
|
|
121
|
+
/** Sends one voice can hold at once (`Voice.sendTo`). */
|
|
122
|
+
export declare const MAX_VOICE_SENDS = 4;
|
|
123
|
+
/** `stopAll` as an options object (the positional `stopAll(fade?, bus?)` form still works). */
|
|
124
|
+
export interface StopAllOptions {
|
|
125
|
+
/** Seconds to fade out. Default 0. */
|
|
126
|
+
fade?: number;
|
|
127
|
+
/** Only this bus. */
|
|
128
|
+
bus?: OutputBus;
|
|
129
|
+
/** Buses left playing, e.g. `['music']` to keep the score through a scene change. */
|
|
130
|
+
except?: readonly BusName[];
|
|
131
|
+
}
|
|
132
|
+
/** `audio.pause` options. */
|
|
133
|
+
export interface PauseOptions {
|
|
134
|
+
/** Buses that keep playing. Default `['ui']` (menu clicks stay audible). `master` never ramps. */
|
|
135
|
+
keep?: readonly OutputBus[];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Internal: write `value` to an AudioParam as a linear ramp over `ramp` seconds from `t`,
|
|
139
|
+
* cancelling what was scheduled (a step when `ramp` is 0).
|
|
140
|
+
*/
|
|
141
|
+
export declare function rampParamTo(param: AudioParam, value: number, t: number, ramp: number): void;
|
|
142
|
+
/**
|
|
143
|
+
* Internal: the parallel sends behind `Voice.sendTo`, one per voice, shared by the mixer's own
|
|
144
|
+
* voices and music stems. `attach` names the node to tap once it exists; sends set before that
|
|
145
|
+
* are built then. Each live send is one `GainNode`: tap → gain → input.
|
|
146
|
+
*/
|
|
147
|
+
export declare class VoiceSends {
|
|
148
|
+
private readonly taps;
|
|
149
|
+
private from;
|
|
150
|
+
private ctx;
|
|
151
|
+
/** True once `attach` ran (the sends are in the graph). */
|
|
152
|
+
get attached(): boolean;
|
|
153
|
+
/** Live sends. */
|
|
154
|
+
get count(): number;
|
|
155
|
+
/** The voice's output node is known: build the sends set so far. */
|
|
156
|
+
attach(ctx: AudioContext, from: AudioNode): void;
|
|
157
|
+
/** The voice's output node changed (a filter went in or out): move the taps to `from`. */
|
|
158
|
+
retarget(from: AudioNode): void;
|
|
159
|
+
set(target: AudioNode | Send, amount: number, ramp: number): void;
|
|
160
|
+
private build;
|
|
161
|
+
private remove;
|
|
162
|
+
/** Disconnect and drop every send (the voice ended). */
|
|
163
|
+
dispose(): void;
|
|
164
|
+
}
|
|
165
|
+
/** Anything with a 3×4 world matrix a voice can follow (`Voice.follow`). */
|
|
166
|
+
export interface AudioFollowTarget {
|
|
167
|
+
readonly world: ArrayLike<number>;
|
|
168
|
+
/** A counter that moves whenever `world` may have (a `Transform.changed`); lets the follower skip the read. */
|
|
169
|
+
readonly changed?: number;
|
|
170
|
+
}
|
|
171
|
+
/** Distance model of a spatial voice (`PannerNode.distanceModel`). */
|
|
172
|
+
export type Rolloff = 'linear' | 'inverse' | 'exponential';
|
|
173
|
+
/** Directional emitter: full gain inside `inner`, `outerGain` beyond `outer` (degrees, whole angle). */
|
|
174
|
+
export interface ConeOptions {
|
|
175
|
+
/** Degrees. Default 360. */
|
|
176
|
+
inner?: number;
|
|
177
|
+
/** Degrees. Default 360. */
|
|
178
|
+
outer?: number;
|
|
179
|
+
/** Linear gain outside the outer cone. Default 0. */
|
|
180
|
+
outerGain?: number;
|
|
181
|
+
}
|
|
182
|
+
/** Attenuation and panning of a voice played with `AudioPlayOptions.at`. */
|
|
183
|
+
export interface SpatialOptions {
|
|
184
|
+
/** Distance (world units) at which attenuation starts. Default 1. */
|
|
185
|
+
refDistance?: number;
|
|
186
|
+
/** Distance beyond which the voice gets no quieter. Default 10000. */
|
|
187
|
+
maxDistance?: number;
|
|
188
|
+
/** Distance model. Default `'inverse'`. */
|
|
189
|
+
rolloff?: Rolloff;
|
|
190
|
+
/** How fast the model attenuates. Default 1 (WebAudio clamps it to 0..1 for `linear`). */
|
|
191
|
+
rolloffFactor?: number;
|
|
192
|
+
/** `'equalpower'` (default, cheap) or `'HRTF'` (binaural, for headphones and headsets). */
|
|
193
|
+
panningModel?: PanningModelType;
|
|
194
|
+
/** Directional emitter. Omit for an omnidirectional one. */
|
|
195
|
+
cone?: ConeOptions;
|
|
196
|
+
/** Cone direction `[x, y, z]`. Default `[1, 0, 0]` (the WebAudio default). */
|
|
197
|
+
direction?: ArrayLike<number>;
|
|
198
|
+
/**
|
|
199
|
+
* Doppler factor (ws/audio-4): 0 (default) off; 1 the textbook shift
|
|
200
|
+
* `(c - v_listener·n) / (c - v_emitter·n)` with `c = SPEED_OF_SOUND`, applied as a
|
|
201
|
+
* `playbackRate` multiplier on top of `setRate`. Velocities come from successive
|
|
202
|
+
* `setPosition` / `follow` and `listener.set` / `fromCamera` calls per `audio.update(dt)`.
|
|
203
|
+
*/
|
|
204
|
+
doppler?: number;
|
|
205
|
+
/**
|
|
206
|
+
* m/s above which a move between two updates counts as a teleport and resets the velocity
|
|
207
|
+
* instead of chirping. Default `DEFAULT_MAX_DOPPLER_SPEED` (100).
|
|
208
|
+
*/
|
|
209
|
+
maxDopplerSpeed?: number;
|
|
210
|
+
/** Probe this voice through `audio.occlusion` (ws/audio-4). Default true when a probe is set. */
|
|
211
|
+
occlude?: boolean;
|
|
212
|
+
}
|
|
213
|
+
/** Anything with a world→view matrix and an eye position, such as the renderer's `Camera`. */
|
|
214
|
+
export interface CameraLike {
|
|
215
|
+
/** Column-major world→view matrix (16 numbers). */
|
|
216
|
+
readonly view: ArrayLike<number>;
|
|
217
|
+
/** Eye position in world space. */
|
|
218
|
+
readonly position: ArrayLike<number>;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Where the ears are: one per `AudioEngine` (`audio.listener`), written to the context's
|
|
222
|
+
* `AudioListener`. Safe before unlock: the pose is kept and applied when the context exists.
|
|
223
|
+
* Every method writes in place and allocates nothing, so call `fromCamera` every frame.
|
|
224
|
+
*/
|
|
225
|
+
export declare class SpatialListener {
|
|
226
|
+
private readonly engine;
|
|
227
|
+
/** px, py, pz, fx, fy, fz, ux, uy, uz. */
|
|
228
|
+
private readonly pose;
|
|
229
|
+
/** Current pose, read-only (change it with `set` or `fromCamera`). */
|
|
230
|
+
readonly position: ArrayLike<number>;
|
|
231
|
+
readonly forward: ArrayLike<number>;
|
|
232
|
+
readonly up: ArrayLike<number>;
|
|
233
|
+
/** Position at the previous `audio.update`, and the velocity derived from it (m/s). */
|
|
234
|
+
private readonly prev;
|
|
235
|
+
private hasPrev;
|
|
236
|
+
private readonly vel;
|
|
237
|
+
/** Velocity over the last `audio.update(dt)` (ws/audio-4), read-only; zeros after a teleport. */
|
|
238
|
+
readonly velocity: ArrayLike<number>;
|
|
239
|
+
/** m/s above which a move between updates resets the velocity (a teleport). Default 100. */
|
|
240
|
+
maxSpeed: number;
|
|
241
|
+
/** Built by `AudioEngine`; reach it as `audio.listener`. */
|
|
242
|
+
constructor(engine: AudioEngine);
|
|
243
|
+
/** Place the listener at `position`, facing `forward`, with `up` (default `[0, 1, 0]`). */
|
|
244
|
+
set(position: ArrayLike<number>, forward: ArrayLike<number>, up?: ArrayLike<number>): void;
|
|
245
|
+
/**
|
|
246
|
+
* Follow a camera: position from `camera.position`, forward and up from the view matrix
|
|
247
|
+
* (forward is minus its third row, up its second; the view looks down -z).
|
|
248
|
+
*/
|
|
249
|
+
fromCamera(camera: CameraLike): void;
|
|
250
|
+
/** Internal (`audio.update`): derive the velocity from the move since the last call. */
|
|
251
|
+
tick(dt: number): void;
|
|
252
|
+
/** Write the pose to the context's listener (on every change, and when the context is built). */
|
|
253
|
+
apply(): void;
|
|
254
|
+
}
|
|
255
|
+
type SoundSource = SoundSpec | (() => Promise<AudioBuffer>);
|
|
256
|
+
declare class VoiceImpl implements Voice, OccludableVoice {
|
|
257
|
+
private readonly engine;
|
|
258
|
+
readonly loop: boolean;
|
|
259
|
+
private readonly opts;
|
|
260
|
+
private readonly onEnd;
|
|
261
|
+
/** A sprite clip's range, or null for the whole buffer. */
|
|
262
|
+
private readonly schedule;
|
|
263
|
+
private src;
|
|
264
|
+
private gainNode;
|
|
265
|
+
private stopped;
|
|
266
|
+
private targetGain;
|
|
267
|
+
private rate;
|
|
268
|
+
private ended;
|
|
269
|
+
private panner;
|
|
270
|
+
/** The node after the filters (panner or stereo panner), or null when the chain ends at the bus. */
|
|
271
|
+
private out;
|
|
272
|
+
/** `out` is connected to the bus (done once; `relink` never breaks that link). */
|
|
273
|
+
private outWired;
|
|
274
|
+
private bus_;
|
|
275
|
+
/** The last node before the bus (gain, filter, panner or stereo panner): what the sends tap. */
|
|
276
|
+
private tail;
|
|
277
|
+
private sends;
|
|
278
|
+
/** `audio.pause` set the playback rate to 0; `rate` keeps the value to restore. */
|
|
279
|
+
private frozen;
|
|
280
|
+
/** Emitter position and cone direction (kept for a voice that has not started yet). */
|
|
281
|
+
private readonly spatial;
|
|
282
|
+
private readonly pos;
|
|
283
|
+
private target;
|
|
284
|
+
/** `target.changed` at the last `syncFollow`; a target without one is read every update. */
|
|
285
|
+
private followSeen;
|
|
286
|
+
private dx;
|
|
287
|
+
private dy;
|
|
288
|
+
private dz;
|
|
289
|
+
/** `Voice.filter`: the pooled biquad and what it was last asked for (applied at start). */
|
|
290
|
+
private userFilter;
|
|
291
|
+
private userKind;
|
|
292
|
+
private userCutoff;
|
|
293
|
+
private userQ;
|
|
294
|
+
/** Occlusion: the pooled lowpass and the last probe (ws/audio-4). */
|
|
295
|
+
private occFilter;
|
|
296
|
+
private occAmount;
|
|
297
|
+
private occGain;
|
|
298
|
+
private occApplied;
|
|
299
|
+
occlusionProbedAt: number;
|
|
300
|
+
/** Doppler: the previous position per update, and the multiplier on `rate`. */
|
|
301
|
+
private readonly prevPos;
|
|
302
|
+
private hasPrev;
|
|
303
|
+
private dopplerRate;
|
|
304
|
+
constructor(engine: AudioEngine, loop: boolean, opts: AudioPlayOptions, onEnd: (v: VoiceImpl) => void,
|
|
305
|
+
/** A sprite clip's range, or null for the whole buffer. */
|
|
306
|
+
schedule?: SpriteSchedule | null);
|
|
307
|
+
get playing(): boolean;
|
|
308
|
+
get position(): ArrayLike<number>;
|
|
309
|
+
get started(): boolean;
|
|
310
|
+
get bus(): OutputBus;
|
|
311
|
+
get occlusion(): number;
|
|
312
|
+
/** Internal: a spatial voice `audio.occlusion` may probe (`spatial.occlude` not false). */
|
|
313
|
+
get occludable(): boolean;
|
|
314
|
+
/** The Doppler multiplier on `rate` as of the last `audio.update` (1 without `spatial.doppler`; diagnostics). */
|
|
315
|
+
get doppler(): number;
|
|
316
|
+
/** Internal: `spatial.doppler` above 0. */
|
|
317
|
+
get dopplerFactor(): number;
|
|
318
|
+
/** Create nodes and start. Returns false if it can't (no context). */
|
|
319
|
+
start(buffer: AudioBuffer): boolean;
|
|
320
|
+
/**
|
|
321
|
+
* (Re)wire gain → [user filter] → [occlusion lowpass] → [panner | stereo panner] → bus and
|
|
322
|
+
* point the sends at the new tail. Only the links that can change are touched.
|
|
323
|
+
*/
|
|
324
|
+
private relink;
|
|
325
|
+
filter(kind: VoiceFilterKind | null, o?: VoiceFilterOptions): void;
|
|
326
|
+
/** Internal (`OcclusionScheduler`): ramp the lowpass and the voice gain to the probe's answer. */
|
|
327
|
+
applyOcclusion(amount: number, cutoff: number, gain: number, ramp: number): void;
|
|
328
|
+
/**
|
|
329
|
+
* Internal (`audio.update`): the emitter's velocity from its move since the last update, and
|
|
330
|
+
* the Doppler ratio against the listener's, written to `playbackRate` when it changed.
|
|
331
|
+
*/
|
|
332
|
+
syncDoppler(dt: number, listener: SpatialListener): void;
|
|
333
|
+
stop(fade?: number): void;
|
|
334
|
+
sendTo(input: AudioNode | Send, amount: number, ramp?: number): void;
|
|
335
|
+
/** Live sends (tests, diagnostics). */
|
|
336
|
+
get sendCount(): number;
|
|
337
|
+
/** Internal: whether this voice's `playbackRate` accepts 0 (null before it has a source). */
|
|
338
|
+
rateZeroAllowed(): boolean | null;
|
|
339
|
+
/** Internal (`audio.pause`): hold the source at rate 0, keeping `rate` for `thawRate`. */
|
|
340
|
+
freezeRate(ramp: number): void;
|
|
341
|
+
/** Internal (`audio.unpause`): back to the rate the game set. */
|
|
342
|
+
thawRate(ramp: number): void;
|
|
343
|
+
setGain(gain: number, ramp?: number): void;
|
|
344
|
+
setRate(rate: number, ramp?: number): void;
|
|
345
|
+
setPosition(x: number, y: number, z: number): void;
|
|
346
|
+
follow(target: AudioFollowTarget | null): void;
|
|
347
|
+
/**
|
|
348
|
+
* Internal: copy the followed matrix's translation into the panner. A target with a
|
|
349
|
+
* `changed` counter (a `Transform`) is read only when it moved since the last sync.
|
|
350
|
+
*/
|
|
351
|
+
syncFollow(): void;
|
|
352
|
+
setDirection(x: number, y: number, z: number): void;
|
|
353
|
+
}
|
|
354
|
+
/** Master limiter (a `DynamicsCompressorNode` between master and the output). */
|
|
355
|
+
export interface LimiterOptions {
|
|
356
|
+
/** dB. Default -1. */
|
|
357
|
+
threshold?: number;
|
|
358
|
+
/** dB. Default 0 (hard knee). */
|
|
359
|
+
knee?: number;
|
|
360
|
+
/** Default 20. */
|
|
361
|
+
ratio?: number;
|
|
362
|
+
/** Seconds. Default 0.003. */
|
|
363
|
+
attack?: number;
|
|
364
|
+
/** Seconds. Default 0.25. */
|
|
365
|
+
release?: number;
|
|
366
|
+
}
|
|
367
|
+
export declare const DEFAULT_LIMITER: Readonly<Required<LimiterOptions>>;
|
|
368
|
+
/** Shared convolution reverb: per-bus sends into one procedural room, returned to master. */
|
|
369
|
+
export interface ReverbOptions {
|
|
370
|
+
/** Impulse length in seconds. Default 2. */
|
|
371
|
+
seconds?: number;
|
|
372
|
+
/** Tail shape: `(1 - t)^decay`. Higher = shorter, drier. Default 3. */
|
|
373
|
+
decay?: number;
|
|
374
|
+
/** Impulse noise seed. Default 1. */
|
|
375
|
+
seed?: number;
|
|
376
|
+
/** Wet return level into master (linear). Default 1. */
|
|
377
|
+
wet?: number;
|
|
378
|
+
/** Send level per bus (linear, 0 = dry). Default music 0.2, sfx 0.25, ui 0. */
|
|
379
|
+
sends?: Partial<Record<OutputBus, number>>;
|
|
380
|
+
}
|
|
381
|
+
export declare const DEFAULT_REVERB_SENDS: Readonly<Record<OutputBus, number>>;
|
|
382
|
+
export interface AudioEngineOptions {
|
|
383
|
+
/** Create the realtime context. Called lazily, inside a user gesture. */
|
|
384
|
+
createContext?: () => AudioContext;
|
|
385
|
+
/** Offline renderer factory (tests). */
|
|
386
|
+
createOffline?: OfflineContextFactory;
|
|
387
|
+
/** Initial mixer settings (e.g. from a save). */
|
|
388
|
+
settings?: unknown;
|
|
389
|
+
/**
|
|
390
|
+
* Master limiter that catches stacked one-shots before they clip. Default on
|
|
391
|
+
* (`DEFAULT_LIMITER`); `false` connects master straight to the output.
|
|
392
|
+
*/
|
|
393
|
+
limiter?: boolean | LimiterOptions;
|
|
394
|
+
/** Optional shared reverb (off by default). Change later with `setReverb`. */
|
|
395
|
+
reverb?: ReverbOptions | null;
|
|
396
|
+
}
|
|
397
|
+
export interface AttachAudioOptions {
|
|
398
|
+
/** Where to listen for the unlocking gesture. Default `window`. */
|
|
399
|
+
target?: EventTarget;
|
|
400
|
+
/** Suspend while the tab is hidden. Default true. */
|
|
401
|
+
pauseWhenHidden?: boolean;
|
|
402
|
+
}
|
|
403
|
+
export declare class AudioEngine {
|
|
404
|
+
private ctx;
|
|
405
|
+
private _state;
|
|
406
|
+
private buses;
|
|
407
|
+
private _settings;
|
|
408
|
+
private readonly sounds;
|
|
409
|
+
private readonly deferred;
|
|
410
|
+
private readonly active;
|
|
411
|
+
private readonly stateListeners;
|
|
412
|
+
private readonly settingsListeners;
|
|
413
|
+
private readonly createContext;
|
|
414
|
+
private readonly createOffline;
|
|
415
|
+
private detachFns;
|
|
416
|
+
/** Gesture listeners: armed while audio should run but the browser won't let it. */
|
|
417
|
+
private gestureTarget;
|
|
418
|
+
private gesturesArmed;
|
|
419
|
+
private userSuspended;
|
|
420
|
+
private hidden;
|
|
421
|
+
private _halted;
|
|
422
|
+
private readonly limiterOpts;
|
|
423
|
+
private limiterNode;
|
|
424
|
+
private reverbOpts;
|
|
425
|
+
/** The base sends (what the game set); the zones add `zoneSends` on top (`max`). */
|
|
426
|
+
private reverbSends;
|
|
427
|
+
private readonly zoneSends;
|
|
428
|
+
private readonly effectiveSends;
|
|
429
|
+
private readonly appliedSends;
|
|
430
|
+
private reverbNodes;
|
|
431
|
+
private _zones;
|
|
432
|
+
/** Spatial voices following a matrix (`Voice.follow`), synced in `update`. */
|
|
433
|
+
private readonly followers;
|
|
434
|
+
/** Panners of ended spatial voices, reused by the next ones (cleared with the context). */
|
|
435
|
+
private readonly pannerPool;
|
|
436
|
+
/** Biquads of ended voices' filters and occlusion lowpasses, reused the same way. */
|
|
437
|
+
private readonly biquadPool;
|
|
438
|
+
/**
|
|
439
|
+
* The game's occlusion probe (ws/audio-4), or null for none. Set it once; every spatial voice
|
|
440
|
+
* (unless `spatial.occlude` is false) is then probed round-robin from `update`.
|
|
441
|
+
*/
|
|
442
|
+
occlusion: OcclusionOptions | null;
|
|
443
|
+
private readonly occluder;
|
|
444
|
+
/** Started spatial voices the probe may ask about, in start order. */
|
|
445
|
+
private readonly occludable;
|
|
446
|
+
/** Started voices with a Doppler factor. */
|
|
447
|
+
private readonly dopplers;
|
|
448
|
+
/** Sprite sheets by name (`defineSprites`); the buffer itself is a sound of the same name. */
|
|
449
|
+
private readonly spriteSheets;
|
|
450
|
+
private readonly scratchSchedule;
|
|
451
|
+
private _listener;
|
|
452
|
+
/** Externally owned voices (`register`): music stems, a game's own players. */
|
|
453
|
+
private readonly registered;
|
|
454
|
+
private _paused;
|
|
455
|
+
private readonly pausedList;
|
|
456
|
+
private _pausedRate;
|
|
457
|
+
/** Whether this context's `playbackRate` accepts 0, once a voice told us. */
|
|
458
|
+
private rateZeroOk;
|
|
459
|
+
/** Registered voices frozen by `pause`, with the rate to restore. */
|
|
460
|
+
private readonly frozenExternal;
|
|
461
|
+
/**
|
|
462
|
+
* Per-bus keyed multipliers on the settings gain (`setBusScale`: the duckers). Parallel
|
|
463
|
+
* key/value arrays, searched linearly (a bus has a handful of keys), so a per-frame
|
|
464
|
+
* `setBusScale` on an existing key allocates nothing. `scales` caches each bus's product.
|
|
465
|
+
*/
|
|
466
|
+
private readonly scaleKeys;
|
|
467
|
+
private readonly scaleValues;
|
|
468
|
+
private readonly scales;
|
|
469
|
+
constructor(opts?: AudioEngineOptions);
|
|
470
|
+
get state(): AudioState;
|
|
471
|
+
/** The realtime context, once created (after the first gesture). */
|
|
472
|
+
get context(): AudioContext | null;
|
|
473
|
+
get settings(): Readonly<MixerSettings>;
|
|
474
|
+
/** Where spatial voices are heard from. A 3D game calls `audio.listener.fromCamera(camera)` each frame. */
|
|
475
|
+
get listener(): SpatialListener;
|
|
476
|
+
/**
|
|
477
|
+
* Regions that drive ambient loops and reverb sends by listener position. Built on first use;
|
|
478
|
+
* advanced by `update(dt)`.
|
|
479
|
+
*/
|
|
480
|
+
get zones(): AudioZones;
|
|
481
|
+
/**
|
|
482
|
+
* Per-frame bookkeeping: the zones (weights, ambient gains, reverb sends) and the followers
|
|
483
|
+
* (`Voice.follow`). `createGame`'s loop calls it after input, before the scenes. Safe before
|
|
484
|
+
* unlock and when audio is unavailable: the numbers still move, nothing plays.
|
|
485
|
+
*/
|
|
486
|
+
update(dt: number): void;
|
|
487
|
+
/** Internal: a voice starts or stops following a matrix. */
|
|
488
|
+
trackFollower(v: VoiceImpl, on: boolean): void;
|
|
489
|
+
/** Internal: a spatial voice started; it joins the occlusion and Doppler rounds it asks for. */
|
|
490
|
+
trackSpatial(v: VoiceImpl): void;
|
|
491
|
+
private untrackSpatial;
|
|
492
|
+
/** Idle panners waiting for the next spatial voice (tests, diagnostics). */
|
|
493
|
+
get pooledPanners(): number;
|
|
494
|
+
/** Idle biquads waiting for the next `Voice.filter` or occluded voice (tests, diagnostics). */
|
|
495
|
+
get pooledFilters(): number;
|
|
496
|
+
/** Voices `occlusion.probe` may be asked about (tests, diagnostics). */
|
|
497
|
+
get occludedVoiceCount(): number;
|
|
498
|
+
/**
|
|
499
|
+
* The page lifecycle's flag (ws/audio-4): `true` suspends the context while the app is hidden
|
|
500
|
+
* or backgrounded, `false` brings back whatever the user state is (`suspend()` still holds it
|
|
501
|
+
* suspended; otherwise it resumes). `attach({ pauseWhenHidden })` and `createGame`'s host
|
|
502
|
+
* lifecycle call this; a game with its own lifecycle source can too. Independent of `pause()`.
|
|
503
|
+
*/
|
|
504
|
+
background(hidden: boolean): void;
|
|
505
|
+
/** True while `background(true)` holds (the document hidden or the app in the background). */
|
|
506
|
+
get inBackground(): boolean;
|
|
507
|
+
/** True after `halt()`: silent for good. */
|
|
508
|
+
get halted(): boolean;
|
|
509
|
+
onStateChange(fn: (s: AudioState) => void): () => void;
|
|
510
|
+
onSettingsChange(fn: (s: Readonly<MixerSettings>) => void): () => void;
|
|
511
|
+
private setState;
|
|
512
|
+
/**
|
|
513
|
+
* Listen for the first user gesture to unlock audio, and pause while hidden. Returns detach.
|
|
514
|
+
*
|
|
515
|
+
* Phones take audio away again after unlock: iOS interrupts the context for a call, Siri or
|
|
516
|
+
* an alarm (state `interrupted`) and may leave it suspended after an app switch; Android
|
|
517
|
+
* suspends it in the background. Whenever the context is not running but should be, the
|
|
518
|
+
* gesture listeners are re-armed so the next tap brings sound back, and `pageshow` / `focus`
|
|
519
|
+
* try a resume without one.
|
|
520
|
+
*/
|
|
521
|
+
attach(opts?: AttachAudioOptions): () => void;
|
|
522
|
+
detach(): void;
|
|
523
|
+
private readonly onGesture;
|
|
524
|
+
private armGestures;
|
|
525
|
+
private disarmGestures;
|
|
526
|
+
/**
|
|
527
|
+
* Create/resume the context. Must run inside a user-gesture handler the first time
|
|
528
|
+
* (`attach` does this for you). Resolves true once audio is running.
|
|
529
|
+
*/
|
|
530
|
+
unlock(): Promise<boolean>;
|
|
531
|
+
private isPaused;
|
|
532
|
+
private onContextState;
|
|
533
|
+
/** Pause all audio (e.g. game paused). Pair with `resume()`. */
|
|
534
|
+
suspend(): Promise<void>;
|
|
535
|
+
resume(): Promise<void>;
|
|
536
|
+
private syncSuspension;
|
|
537
|
+
/**
|
|
538
|
+
* Fall silent for good, e.g. when the page can no longer run (GPU device lost) and only a
|
|
539
|
+
* reload helps. Stops every voice, drops loops waiting for unlock, removes the gesture and
|
|
540
|
+
* visibility listeners and suspends the context. After this, `unlock`, `resume`, `play`,
|
|
541
|
+
* `loop` and `prepare` do nothing, so no timer or tab switch can bring sound back.
|
|
542
|
+
*/
|
|
543
|
+
halt(): Promise<void>;
|
|
544
|
+
/** Close the context and drop everything. */
|
|
545
|
+
dispose(): Promise<void>;
|
|
546
|
+
private buildBuses;
|
|
547
|
+
/**
|
|
548
|
+
* Internal: a `PannerNode` set up from `opts`, from the pool when one is idle. Null where the
|
|
549
|
+
* context has no panner (the voice then plays unspatialised, straight into its bus).
|
|
550
|
+
*/
|
|
551
|
+
acquirePanner(opts: SpatialOptions | undefined): PannerNode | null;
|
|
552
|
+
/** Internal: take back an ended voice's (disconnected) panner. Dropped if its context is gone. */
|
|
553
|
+
releasePanner(p: PannerNode): void;
|
|
554
|
+
/** Internal: a `BiquadFilterNode` from the pool, or a new one. Null where the context has none. */
|
|
555
|
+
acquireBiquad(): BiquadFilterNode | null;
|
|
556
|
+
/** Internal: take back a (disconnected) biquad. Dropped if its context is gone. */
|
|
557
|
+
releaseBiquad(f: BiquadFilterNode): void;
|
|
558
|
+
/** The master limiter node, once the context exists (null when disabled or unsupported). */
|
|
559
|
+
get limiter(): DynamicsCompressorNode | null;
|
|
560
|
+
/** Current reverb settings (`null` = off). */
|
|
561
|
+
get reverb(): Readonly<ReverbOptions> | null;
|
|
562
|
+
/**
|
|
563
|
+
* Turn the shared reverb on (or rebuild it with a new room), or off with `null`. Safe before
|
|
564
|
+
* unlock: it is built with the buses. Rebuilding renders a new impulse, so do it rarely
|
|
565
|
+
* (scene changes), not per frame. Sends given here replace the matching current sends.
|
|
566
|
+
*/
|
|
567
|
+
setReverb(opts: ReverbOptions | null): void;
|
|
568
|
+
/**
|
|
569
|
+
* Change one bus's base reverb send (linear, ramped). Remembered while reverb is off. The
|
|
570
|
+
* zones (`audio.zones`) raise the effective send above it, never below.
|
|
571
|
+
*/
|
|
572
|
+
setReverbSend(bus: OutputBus, level: number): void;
|
|
573
|
+
/** Internal: the zones' contribution to one bus's send; `max(base, zone)` reaches the graph. */
|
|
574
|
+
setZoneReverbSend(bus: OutputBus, level: number): void;
|
|
575
|
+
/** Write `max(base, zone)` to the send node when it moved by more than 1e-3 (or `force`). */
|
|
576
|
+
private applySend;
|
|
577
|
+
/** Base send levels per bus (what `setReverbSend` and the reverb options set). */
|
|
578
|
+
get reverbSendLevels(): Readonly<Record<OutputBus, number>>;
|
|
579
|
+
/** What reaches the reverb per bus: `max(base, zones)`. The same object every call. */
|
|
580
|
+
get effectiveReverbSendLevels(): Readonly<Record<OutputBus, number>>;
|
|
581
|
+
private buildReverb;
|
|
582
|
+
private teardownReverb;
|
|
583
|
+
/** Internal: the GainNode for a bus, once the context exists. */
|
|
584
|
+
busNode(name: BusName): GainNode | null;
|
|
585
|
+
/** What a bus gain should be when nothing holds it: the settings gain times its scale. */
|
|
586
|
+
private busTarget;
|
|
587
|
+
private applyBus;
|
|
588
|
+
/**
|
|
589
|
+
* Multiply a bus's settings gain by `scale` (0..1) under `key` (default `'default'`),
|
|
590
|
+
* approached with time constant `timeConstant` seconds (default 0.015). A bus keeps one scale
|
|
591
|
+
* per key and its effective scale is the product of them all, so two duckers on one bus
|
|
592
|
+
* combine instead of fighting. The bus gain is always `busGain(settings[bus]) × product`, so
|
|
593
|
+
* `setVolume` and `setMuted` keep composing with it. The engine owns the write: while `pause`
|
|
594
|
+
* holds the bus or `inBackground` is true the scale is only stored, and `unpause` /
|
|
595
|
+
* `background(false)` ramp to the scaled gain; set before the context exists, the bus is
|
|
596
|
+
* built at it. `createDucker` drives this with a key of its own.
|
|
597
|
+
*/
|
|
598
|
+
setBusScale(bus: BusName, scale: number, timeConstant?: number, key?: string): void;
|
|
599
|
+
/**
|
|
600
|
+
* Remove `key`'s scale from `bus` (a no-op for a key never set), ramping to the product of
|
|
601
|
+
* the keys left with time constant `timeConstant` (default 0.015). `Ducker.dispose` calls it.
|
|
602
|
+
*/
|
|
603
|
+
clearBusScale(bus: BusName, key: string, timeConstant?: number): void;
|
|
604
|
+
/**
|
|
605
|
+
* `key`'s `setBusScale` multiplier on `bus` (1 for a key never set or cleared), or, with
|
|
606
|
+
* `key` omitted, the bus's effective scale: the product of all its keys (1 by default).
|
|
607
|
+
*/
|
|
608
|
+
busScale(bus: BusName, key?: string): number;
|
|
609
|
+
/** Recompute a bus's product of keyed scales and write the bus if it changed. */
|
|
610
|
+
private updateBusScale;
|
|
611
|
+
/**
|
|
612
|
+
* The pause-menu recipe: ramp every output bus except `keep` (default `['ui']`, so menu
|
|
613
|
+
* clicks stay audible) to silence over 50 ms and hold the voices on those buses still by
|
|
614
|
+
* setting their playback rate to 0, where the context's `playbackRate` allows it (every
|
|
615
|
+
* current browser; elsewhere the voices keep running under the muted bus). `unpause` ramps
|
|
616
|
+
* the bus gains back to the mixer settings and the rates back to what the game set. Music
|
|
617
|
+
* stems pause the same way through their registered voices. The context keeps running
|
|
618
|
+
* (`suspend()` is the other tool); `master` never ramps. Idempotent.
|
|
619
|
+
*/
|
|
620
|
+
pause(opts?: PauseOptions): void;
|
|
621
|
+
/** Undo `pause`: bus gains back to the settings (times any `setBusScale`), voice rates back to the game's. */
|
|
622
|
+
unpause(): void;
|
|
623
|
+
/** True between `pause` and `unpause`. */
|
|
624
|
+
get paused(): boolean;
|
|
625
|
+
/** The buses `pause` silenced (empty while not paused). The same array every call. */
|
|
626
|
+
get pausedBuses(): readonly OutputBus[];
|
|
627
|
+
/**
|
|
628
|
+
* Which pause path ran: true when the paused voices' playback rates were set to 0 as well
|
|
629
|
+
* (they resume where they stopped), false when the context refuses rate 0 and the buses were
|
|
630
|
+
* only muted (the voices keep running). False while not paused.
|
|
631
|
+
*/
|
|
632
|
+
get pausedRate(): boolean;
|
|
633
|
+
/** Internal: whether `pause` silenced this bus. */
|
|
634
|
+
isBusPaused(bus: BusName): boolean;
|
|
635
|
+
private emitSettings;
|
|
636
|
+
setVolume(bus: BusName, volume: number): void;
|
|
637
|
+
setMuted(bus: BusName, muted: boolean): void;
|
|
638
|
+
toggleMuted(bus: BusName): boolean;
|
|
639
|
+
/** Replace all settings (sanitized), e.g. after loading a save. */
|
|
640
|
+
applySettings(settings: unknown): void;
|
|
641
|
+
/**
|
|
642
|
+
* Register a named sound from a spec (rendered lazily or via `prepare`) or an async buffer
|
|
643
|
+
* factory. `maxVoices` caps simultaneous plays of this sound (oldest is stolen). Default 8.
|
|
644
|
+
*/
|
|
645
|
+
define(name: string, source: SoundSource, opts?: {
|
|
646
|
+
maxVoices?: number;
|
|
647
|
+
}): void;
|
|
648
|
+
has(name: string): boolean;
|
|
649
|
+
/**
|
|
650
|
+
* Register a sprite sheet (ws/audio-4): one buffer (or a factory for it) and named
|
|
651
|
+
* `[startMs, lengthMs]` ranges. `play('name#clip')` and `loop('name#clip')` then play one range
|
|
652
|
+
* (a loop repeats between the clip's `loopPoints`, or its whole range); `play('name')` still
|
|
653
|
+
* plays the whole buffer. `maxVoices` caps the sheet's simultaneous plays, every clip counted.
|
|
654
|
+
*/
|
|
655
|
+
defineSprites(name: string, sheet: SpriteSheet, opts?: {
|
|
656
|
+
maxVoices?: number;
|
|
657
|
+
}): void;
|
|
658
|
+
/** The sprite sheet registered under `name`, if any. */
|
|
659
|
+
spriteSheet(name: string): SpriteSheet | null;
|
|
660
|
+
/** Render (or fetch) the buffer for a sound. Needs no gesture. Cached. */
|
|
661
|
+
load(name: string): Promise<AudioBuffer>;
|
|
662
|
+
/** Render several (default: all) defined sounds up front. Call at boot or behind a loading screen. */
|
|
663
|
+
prepare(names?: readonly string[]): Promise<void>;
|
|
664
|
+
/** Rendered buffer if ready. */
|
|
665
|
+
buffer(name: string): AudioBuffer | null;
|
|
666
|
+
/**
|
|
667
|
+
* Fire a one-shot. Dropped (returns an inert voice) while audio is locked, suspended or
|
|
668
|
+
* unavailable: a click sound arriving seconds late after unlock would be wrong.
|
|
669
|
+
*/
|
|
670
|
+
play(sound: string | AudioBuffer, opts?: AudioPlayOptions): Voice;
|
|
671
|
+
/**
|
|
672
|
+
* Start a loop (music, ambience). If audio is still locked, it starts as soon as it unlocks.
|
|
673
|
+
* Stop it with `voice.stop(fade)`.
|
|
674
|
+
*/
|
|
675
|
+
loop(sound: string | AudioBuffer, opts?: AudioPlayOptions): Voice;
|
|
676
|
+
private startVoice;
|
|
677
|
+
private startDeferred;
|
|
678
|
+
/**
|
|
679
|
+
* Stop every voice the mixer knows (its own and the registered ones, so music stems too),
|
|
680
|
+
* with an optional fade, or only those on `bus`. The options form adds `except`:
|
|
681
|
+
* `stopAll({ except: ['music'] })` clears the effects and keeps the score.
|
|
682
|
+
*/
|
|
683
|
+
stopAll(fade?: number | StopAllOptions, bus?: OutputBus): void;
|
|
684
|
+
/**
|
|
685
|
+
* The live voices (playing or waiting to start, not yet stopped or ended) on `bus`, or on
|
|
686
|
+
* every bus when `bus` is omitted or `master`. A voice leaves the list the moment `stop` is
|
|
687
|
+
* called or its source ends. Allocates one array per call; `forEachVoice` allocates nothing.
|
|
688
|
+
*/
|
|
689
|
+
voices(bus?: BusName): readonly Voice[];
|
|
690
|
+
/** `voices(bus)` without the array: `fn(voice, bus)` for each live voice. */
|
|
691
|
+
forEachVoice(bus: BusName | undefined, fn: (voice: Voice, bus: BusName) => void): void;
|
|
692
|
+
/**
|
|
693
|
+
* Put an externally owned voice (anything implementing `Voice`) on the mixer's books, so
|
|
694
|
+
* `voices`, `voiceCount`, `stopAll` and `pause` see it; `createMusic` does this for each
|
|
695
|
+
* playing stem. A registered voice with a numeric `rate` property has its rate frozen by
|
|
696
|
+
* `pause` and restored by `unpause`. Returns the unregister; a voice whose `playing` is false
|
|
697
|
+
* is skipped meanwhile.
|
|
698
|
+
*/
|
|
699
|
+
register(voice: Voice, bus: BusName): () => void;
|
|
700
|
+
/** Number of live voices: `voices().length` without the array. */
|
|
701
|
+
get voiceCount(): number;
|
|
702
|
+
}
|
|
703
|
+
/** `createVoiceAdapter` options. */
|
|
704
|
+
export interface VoiceAdapterOptions {
|
|
705
|
+
/** The raw source: a buffer or oscillator source, a media element source, a worklet. */
|
|
706
|
+
source: AudioNode;
|
|
707
|
+
/** Bus the adapter's gain feeds. Default `sfx`. */
|
|
708
|
+
bus?: OutputBus;
|
|
709
|
+
/** Linear gain to start at. Default 1. */
|
|
710
|
+
gain?: number;
|
|
711
|
+
/** Called once the voice is stopped (after its fade) or `end()` ran. */
|
|
712
|
+
onEnd?: () => void;
|
|
713
|
+
/** Put the voice on the mixer's books (`audio.register`). Default true. */
|
|
714
|
+
register?: boolean;
|
|
715
|
+
}
|
|
716
|
+
/** The `Voice` `createVoiceAdapter` returns; `rate` lets `audio.pause` freeze and restore it. */
|
|
717
|
+
export interface VoiceAdapter extends Voice {
|
|
718
|
+
rate: number;
|
|
719
|
+
/** The gain node between the source and the bus. */
|
|
720
|
+
readonly gainNode: GainNode | null;
|
|
721
|
+
/** Internal to the owner: the source ended on its own; tear down without a fade. */
|
|
722
|
+
end(): void;
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* A `Voice` over a raw `AudioNode` another owner runs (ws/audio-4): source → gain → bus, with
|
|
726
|
+
* `setGain`, `stop(fade)` (ramps the gain, stops a scheduled source at the fade's end, else
|
|
727
|
+
* disconnects it then), `setRate` (writes the source's `playbackRate` when it has one, so
|
|
728
|
+
* `audio.pause` freezes it), `sendTo` and `filter` on the same pool as the mixer's voices. Not
|
|
729
|
+
* spatial: `setPosition`, `follow` and `occlusion` are inert. Registered with the mixer unless
|
|
730
|
+
* `register` is false, so `voices`, `stopAll` and `pause` see it. Null context: an inert voice.
|
|
731
|
+
*/
|
|
732
|
+
export declare function createVoiceAdapter(audio: AudioEngine, opts: VoiceAdapterOptions): VoiceAdapter;
|
|
733
|
+
export {};
|