@driftengine/core 3.61.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +9 -0
- package/dist/behavior/behaviorTree.d.ts +140 -0
- package/dist/behavior/behaviorTree.js +289 -0
- package/dist/build/shaderComments.d.ts +64 -0
- package/dist/build/shaderComments.js +0 -0
- package/dist/cinematic/player.d.ts +80 -0
- package/dist/cinematic/player.js +184 -0
- package/dist/cinematic/script.d.ts +63 -0
- package/dist/cinematic/script.js +141 -0
- package/dist/core/bootGate.d.ts +37 -0
- package/dist/core/bootGate.js +47 -0
- package/dist/core/loadTracker.d.ts +78 -0
- package/dist/core/loadTracker.js +106 -0
- package/dist/core/loop.d.ts +118 -0
- package/dist/core/loop.js +84 -0
- package/dist/core/messageQueue.d.ts +61 -0
- package/dist/core/messageQueue.js +104 -0
- package/dist/core/onceSet.d.ts +27 -0
- package/dist/core/onceSet.js +62 -0
- package/dist/core/preferences.d.ts +47 -0
- package/dist/core/preferences.js +140 -0
- package/dist/core/remoteSave.d.ts +154 -0
- package/dist/core/remoteSave.js +249 -0
- package/dist/core/rng.d.ts +64 -0
- package/dist/core/rng.js +72 -0
- package/dist/core/stepBudget.d.ts +91 -0
- package/dist/core/stepBudget.js +105 -0
- package/dist/core/storage.d.ts +52 -0
- package/dist/core/storage.js +85 -0
- package/dist/core/tickTrace.d.ts +72 -0
- package/dist/core/tickTrace.js +102 -0
- package/dist/core/timeCurve.d.ts +83 -0
- package/dist/core/timeCurve.js +107 -0
- package/dist/core/withDefaults.d.ts +21 -0
- package/dist/core/withDefaults.js +29 -0
- package/dist/dev/contactProbe.d.ts +41 -0
- package/dist/dev/contactProbe.js +58 -0
- package/dist/dev/fpsMeter.d.ts +45 -0
- package/dist/dev/fpsMeter.js +86 -0
- package/dist/environment/celestialClock.d.ts +141 -0
- package/dist/environment/celestialClock.js +262 -0
- package/dist/geometry/decal.d.ts +61 -0
- package/dist/geometry/decal.js +178 -0
- package/dist/geometry/filmPatch.d.ts +35 -0
- package/dist/geometry/filmPatch.js +112 -0
- package/dist/geometry/growable.d.ts +70 -0
- package/dist/geometry/growable.js +167 -0
- package/dist/geometry/lightVolume.d.ts +76 -0
- package/dist/geometry/lightVolume.js +65 -0
- package/dist/geometry/meshBuilder.d.ts +426 -0
- package/dist/geometry/meshBuilder.js +1184 -0
- package/dist/geometry/pixelFont.d.ts +59 -0
- package/dist/geometry/pixelFont.js +179 -0
- package/dist/geometry/ribbon.d.ts +101 -0
- package/dist/geometry/ribbon.js +546 -0
- package/dist/geometry/shellFill.d.ts +101 -0
- package/dist/geometry/shellFill.js +203 -0
- package/dist/geometry/spline.d.ts +162 -0
- package/dist/geometry/spline.js +527 -0
- package/dist/geometry/tangents.d.ts +30 -0
- package/dist/geometry/tangents.js +142 -0
- package/dist/geometry/textMesh.d.ts +51 -0
- package/dist/geometry/textMesh.js +57 -0
- package/dist/geometry/treeBuilder.d.ts +37 -0
- package/dist/geometry/treeBuilder.js +56 -0
- package/dist/host/display.d.ts +135 -0
- package/dist/host/display.js +114 -0
- package/dist/host/files.d.ts +25 -0
- package/dist/host/files.js +44 -0
- package/dist/host/lifecycle.d.ts +45 -0
- package/dist/host/lifecycle.js +28 -0
- package/dist/host/platformServices.d.ts +23 -0
- package/dist/host/platformServices.js +1 -0
- package/dist/host/screen.d.ts +49 -0
- package/dist/host/screen.js +90 -0
- package/dist/index.d.ts +289 -0
- package/dist/index.js +320 -0
- package/dist/input/actionMap.d.ts +181 -0
- package/dist/input/actionMap.js +314 -0
- package/dist/input/activeDevice.d.ts +55 -0
- package/dist/input/activeDevice.js +83 -0
- package/dist/input/gamepadIdentity.d.ts +43 -0
- package/dist/input/gamepadIdentity.js +108 -0
- package/dist/input/gamepadMapping.d.ts +56 -0
- package/dist/input/gamepadMapping.js +91 -0
- package/dist/input/input.d.ts +281 -0
- package/dist/input/input.js +703 -0
- package/dist/input/inputHarness.d.ts +42 -0
- package/dist/input/inputHarness.js +193 -0
- package/dist/input/rightGesture.d.ts +57 -0
- package/dist/input/rightGesture.js +49 -0
- package/dist/input/rumble.d.ts +71 -0
- package/dist/input/rumble.js +119 -0
- package/dist/input/touchControls.d.ts +138 -0
- package/dist/input/touchControls.js +352 -0
- package/dist/input/typingTarget.d.ts +6 -0
- package/dist/input/typingTarget.js +27 -0
- package/dist/math/bounds.d.ts +61 -0
- package/dist/math/bounds.js +121 -0
- package/dist/math/color.d.ts +8 -0
- package/dist/math/color.js +35 -0
- package/dist/math/exact.d.ts +66 -0
- package/dist/math/exact.js +262 -0
- package/dist/math/frustum.d.ts +44 -0
- package/dist/math/frustum.js +90 -0
- package/dist/math/intersect.d.ts +76 -0
- package/dist/math/intersect.js +185 -0
- package/dist/math/scalar.d.ts +51 -0
- package/dist/math/scalar.js +99 -0
- package/dist/math/spring.d.ts +59 -0
- package/dist/math/spring.js +88 -0
- package/dist/nav/navGraph.d.ts +71 -0
- package/dist/nav/navGraph.js +111 -0
- package/dist/nav/navPath.d.ts +93 -0
- package/dist/nav/navPath.js +162 -0
- package/dist/nav/navSearch.d.ts +74 -0
- package/dist/nav/navSearch.js +198 -0
- package/dist/physics/boxSurface.d.ts +48 -0
- package/dist/physics/boxSurface.js +73 -0
- package/dist/physics/colliderSurface.d.ts +46 -0
- package/dist/physics/colliderSurface.js +146 -0
- package/dist/physics/compositeSurface.d.ts +33 -0
- package/dist/physics/compositeSurface.js +108 -0
- package/dist/physics/heightSurface.d.ts +103 -0
- package/dist/physics/heightSurface.js +153 -0
- package/dist/physics/ribbonSurface.d.ts +239 -0
- package/dist/physics/ribbonSurface.js +522 -0
- package/dist/render/ambientOcclusionPass.d.ts +53 -0
- package/dist/render/ambientOcclusionPass.js +179 -0
- package/dist/render/areaLights.d.ts +116 -0
- package/dist/render/areaLights.js +91 -0
- package/dist/render/areaShadowSet.d.ts +184 -0
- package/dist/render/areaShadowSet.js +277 -0
- package/dist/render/atmosphere.d.ts +94 -0
- package/dist/render/atmosphere.js +91 -0
- package/dist/render/backend/api.d.ts +496 -0
- package/dist/render/backend/api.js +1 -0
- package/dist/render/backend/budget.d.ts +82 -0
- package/dist/render/backend/budget.js +99 -0
- package/dist/render/backend/createRenderer.d.ts +135 -0
- package/dist/render/backend/createRenderer.js +201 -0
- package/dist/render/backend/deadline.d.ts +24 -0
- package/dist/render/backend/deadline.js +38 -0
- package/dist/render/backend/probe.d.ts +30 -0
- package/dist/render/backend/probe.js +129 -0
- package/dist/render/backend/select.d.ts +70 -0
- package/dist/render/backend/select.js +249 -0
- package/dist/render/backend/timer.d.ts +50 -0
- package/dist/render/backend/timer.js +1 -0
- package/dist/render/backend/webgl2/instanced.d.ts +21 -0
- package/dist/render/backend/webgl2/instanced.js +42 -0
- package/dist/render/backend/webgl2/morphTexture.d.ts +21 -0
- package/dist/render/backend/webgl2/morphTexture.js +55 -0
- package/dist/render/backend/webgl2/renderer.d.ts +3027 -0
- package/dist/render/backend/webgl2/renderer.js +6041 -0
- package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +32 -0
- package/dist/render/backend/webgl2/skinPaletteTexture.js +68 -0
- package/dist/render/backend/webgpu/boltPass.d.ts +42 -0
- package/dist/render/backend/webgpu/boltPass.js +160 -0
- package/dist/render/backend/webgpu/buffers.d.ts +159 -0
- package/dist/render/backend/webgpu/buffers.js +402 -0
- package/dist/render/backend/webgpu/causticsPass.d.ts +36 -0
- package/dist/render/backend/webgpu/causticsPass.js +138 -0
- package/dist/render/backend/webgpu/clusterBinner.d.ts +51 -0
- package/dist/render/backend/webgpu/clusterBinner.js +206 -0
- package/dist/render/backend/webgpu/depthPass.d.ts +114 -0
- package/dist/render/backend/webgpu/depthPass.js +228 -0
- package/dist/render/backend/webgpu/device.d.ts +52 -0
- package/dist/render/backend/webgpu/device.js +121 -0
- package/dist/render/backend/webgpu/drawCommand.d.ts +43 -0
- package/dist/render/backend/webgpu/drawCommand.js +54 -0
- package/dist/render/backend/webgpu/environmentTexels.d.ts +28 -0
- package/dist/render/backend/webgpu/environmentTexels.js +79 -0
- package/dist/render/backend/webgpu/filmPass.d.ts +29 -0
- package/dist/render/backend/webgpu/filmPass.js +97 -0
- package/dist/render/backend/webgpu/flatPass.d.ts +213 -0
- package/dist/render/backend/webgpu/flatPass.js +482 -0
- package/dist/render/backend/webgpu/flockPass.d.ts +34 -0
- package/dist/render/backend/webgpu/flockPass.js +129 -0
- package/dist/render/backend/webgpu/gpuTimestamps.d.ts +94 -0
- package/dist/render/backend/webgpu/gpuTimestamps.js +213 -0
- package/dist/render/backend/webgpu/insetPass.d.ts +19 -0
- package/dist/render/backend/webgpu/insetPass.js +108 -0
- package/dist/render/backend/webgpu/instanced.d.ts +27 -0
- package/dist/render/backend/webgpu/instanced.js +49 -0
- package/dist/render/backend/webgpu/lightVolumePass.d.ts +75 -0
- package/dist/render/backend/webgpu/lightVolumePass.js +154 -0
- package/dist/render/backend/webgpu/linePass.d.ts +90 -0
- package/dist/render/backend/webgpu/linePass.js +220 -0
- package/dist/render/backend/webgpu/morphTexture.d.ts +18 -0
- package/dist/render/backend/webgpu/morphTexture.js +51 -0
- package/dist/render/backend/webgpu/panelPass.d.ts +37 -0
- package/dist/render/backend/webgpu/panelPass.js +114 -0
- package/dist/render/backend/webgpu/particlePass.d.ts +89 -0
- package/dist/render/backend/webgpu/particlePass.js +280 -0
- package/dist/render/backend/webgpu/pipelineCache.d.ts +93 -0
- package/dist/render/backend/webgpu/pipelineCache.js +140 -0
- package/dist/render/backend/webgpu/plumePass.d.ts +69 -0
- package/dist/render/backend/webgpu/plumePass.js +213 -0
- package/dist/render/backend/webgpu/pointShadowPass.d.ts +88 -0
- package/dist/render/backend/webgpu/pointShadowPass.js +280 -0
- package/dist/render/backend/webgpu/postPass.d.ts +342 -0
- package/dist/render/backend/webgpu/postPass.js +366 -0
- package/dist/render/backend/webgpu/probePass.d.ts +108 -0
- package/dist/render/backend/webgpu/probePass.js +188 -0
- package/dist/render/backend/webgpu/reflectionPass.d.ts +29 -0
- package/dist/render/backend/webgpu/reflectionPass.js +87 -0
- package/dist/render/backend/webgpu/renderer.d.ts +3082 -0
- package/dist/render/backend/webgpu/renderer.js +10911 -0
- package/dist/render/backend/webgpu/scatterPass.d.ts +95 -0
- package/dist/render/backend/webgpu/scatterPass.js +266 -0
- package/dist/render/backend/webgpu/sdfTextPass.d.ts +86 -0
- package/dist/render/backend/webgpu/sdfTextPass.js +190 -0
- package/dist/render/backend/webgpu/shaderModules.d.ts +9 -0
- package/dist/render/backend/webgpu/shaderModules.js +45 -0
- package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +23 -0
- package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.js +208 -0
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +67 -0
- package/dist/render/backend/webgpu/skinPaletteRing.js +97 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +17 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.js +68 -0
- package/dist/render/backend/webgpu/skyPass.d.ts +102 -0
- package/dist/render/backend/webgpu/skyPass.js +70 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +41 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.js +228 -0
- package/dist/render/backend/webgpu/textPass.d.ts +73 -0
- package/dist/render/backend/webgpu/textPass.js +190 -0
- package/dist/render/backend/webgpu/uniformRing.d.ts +133 -0
- package/dist/render/backend/webgpu/uniformRing.js +208 -0
- package/dist/render/backend/webgpu/waterPass.d.ts +73 -0
- package/dist/render/backend/webgpu/waterPass.js +160 -0
- package/dist/render/backend/webgpu/windStreakPass.d.ts +46 -0
- package/dist/render/backend/webgpu/windStreakPass.js +153 -0
- package/dist/render/billboard.d.ts +27 -0
- package/dist/render/billboard.js +79 -0
- package/dist/render/bloomChain.d.ts +66 -0
- package/dist/render/bloomChain.js +83 -0
- package/dist/render/bloomPass.d.ts +54 -0
- package/dist/render/bloomPass.js +219 -0
- package/dist/render/boltBatch.d.ts +39 -0
- package/dist/render/boltBatch.js +121 -0
- package/dist/render/boltPool.d.ts +135 -0
- package/dist/render/boltPool.js +259 -0
- package/dist/render/boom.d.ts +46 -0
- package/dist/render/boom.js +81 -0
- package/dist/render/camera.d.ts +119 -0
- package/dist/render/camera.js +304 -0
- package/dist/render/causticsRenderer.d.ts +63 -0
- package/dist/render/causticsRenderer.js +119 -0
- package/dist/render/cinematicCamera.d.ts +102 -0
- package/dist/render/cinematicCamera.js +227 -0
- package/dist/render/clusteredLights.d.ts +260 -0
- package/dist/render/clusteredLights.js +479 -0
- package/dist/render/colourGrade.d.ts +62 -0
- package/dist/render/colourGrade.js +91 -0
- package/dist/render/compute.d.ts +74 -0
- package/dist/render/compute.js +8 -0
- package/dist/render/contextLoss.d.ts +32 -0
- package/dist/render/contextLoss.js +46 -0
- package/dist/render/debugLines.d.ts +75 -0
- package/dist/render/debugLines.js +281 -0
- package/dist/render/decalPass.d.ts +34 -0
- package/dist/render/decalPass.js +103 -0
- package/dist/render/decalProjector.d.ts +140 -0
- package/dist/render/decalProjector.js +282 -0
- package/dist/render/decalQueue.d.ts +53 -0
- package/dist/render/decalQueue.js +87 -0
- package/dist/render/depthConvention.d.ts +314 -0
- package/dist/render/depthConvention.js +346 -0
- package/dist/render/drawingBuffer.d.ts +52 -0
- package/dist/render/drawingBuffer.js +67 -0
- package/dist/render/emptyTexture.d.ts +60 -0
- package/dist/render/emptyTexture.js +103 -0
- package/dist/render/envProbeArray.d.ts +85 -0
- package/dist/render/envProbeArray.js +164 -0
- package/dist/render/equirectToCube.d.ts +54 -0
- package/dist/render/equirectToCube.js +123 -0
- package/dist/render/flockGeometry.d.ts +23 -0
- package/dist/render/flockGeometry.js +43 -0
- package/dist/render/flockRenderer.d.ts +37 -0
- package/dist/render/flockRenderer.js +70 -0
- package/dist/render/frame/arena.d.ts +32 -0
- package/dist/render/frame/arena.js +65 -0
- package/dist/render/frame/index.d.ts +18 -0
- package/dist/render/frame/index.js +4 -0
- package/dist/render/frame/replay.d.ts +34 -0
- package/dist/render/frame/replay.js +48 -0
- package/dist/render/frame/resources.d.ts +25 -0
- package/dist/render/frame/resources.js +55 -0
- package/dist/render/frame/schedule.d.ts +37 -0
- package/dist/render/frame/schedule.js +61 -0
- package/dist/render/frameView.d.ts +19 -0
- package/dist/render/frameView.js +1 -0
- package/dist/render/gizmo.d.ts +236 -0
- package/dist/render/gizmo.js +727 -0
- package/dist/render/globalMedium.d.ts +124 -0
- package/dist/render/globalMedium.js +100 -0
- package/dist/render/globalMediumPass.d.ts +101 -0
- package/dist/render/globalMediumPass.js +250 -0
- package/dist/render/gpuCapability.d.ts +111 -0
- package/dist/render/gpuCapability.js +194 -0
- package/dist/render/gpuTimer.d.ts +87 -0
- package/dist/render/gpuTimer.js +145 -0
- package/dist/render/halfFloat.d.ts +4 -0
- package/dist/render/halfFloat.js +38 -0
- package/dist/render/handleRegistry.d.ts +54 -0
- package/dist/render/handleRegistry.js +84 -0
- package/dist/render/iesProfile.d.ts +64 -0
- package/dist/render/iesProfile.js +179 -0
- package/dist/render/imageTexels.d.ts +50 -0
- package/dist/render/imageTexels.js +91 -0
- package/dist/render/instancedMesh.d.ts +48 -0
- package/dist/render/instancedMesh.js +127 -0
- package/dist/render/instances.d.ts +69 -0
- package/dist/render/instances.js +52 -0
- package/dist/render/lightBudget.d.ts +397 -0
- package/dist/render/lightBudget.js +524 -0
- package/dist/render/lightMatrix.d.ts +3 -0
- package/dist/render/lightMatrix.js +45 -0
- package/dist/render/lightVolumeDraw.d.ts +132 -0
- package/dist/render/lightVolumeDraw.js +181 -0
- package/dist/render/lineBatch.d.ts +60 -0
- package/dist/render/lineBatch.js +160 -0
- package/dist/render/linePoints.d.ts +33 -0
- package/dist/render/linePoints.js +46 -0
- package/dist/render/livePointShadowSet.d.ts +72 -0
- package/dist/render/livePointShadowSet.js +258 -0
- package/dist/render/lod.d.ts +35 -0
- package/dist/render/lod.js +65 -0
- package/dist/render/mesh.d.ts +177 -0
- package/dist/render/mesh.js +466 -0
- package/dist/render/occlusion.d.ts +81 -0
- package/dist/render/occlusion.js +378 -0
- package/dist/render/oitPass.d.ts +67 -0
- package/dist/render/oitPass.js +213 -0
- package/dist/render/orderIndependent.d.ts +92 -0
- package/dist/render/orderIndependent.js +108 -0
- package/dist/render/particleBatch.d.ts +140 -0
- package/dist/render/particleBatch.js +186 -0
- package/dist/render/particleMaterial.d.ts +54 -0
- package/dist/render/particleMaterial.js +42 -0
- package/dist/render/particlePool.d.ts +124 -0
- package/dist/render/particlePool.js +182 -0
- package/dist/render/pass.d.ts +195 -0
- package/dist/render/pass.js +9 -0
- package/dist/render/passTarget.d.ts +86 -0
- package/dist/render/passTarget.js +121 -0
- package/dist/render/pickable.d.ts +31 -0
- package/dist/render/pickable.js +172 -0
- package/dist/render/planarReflection.d.ts +59 -0
- package/dist/render/planarReflection.js +194 -0
- package/dist/render/planarReflectionDraw.d.ts +31 -0
- package/dist/render/planarReflectionDraw.js +65 -0
- package/dist/render/plumeGeometry.d.ts +25 -0
- package/dist/render/plumeGeometry.js +61 -0
- package/dist/render/plumeMaterial.d.ts +31 -0
- package/dist/render/plumeMaterial.js +64 -0
- package/dist/render/plumeRenderer.d.ts +96 -0
- package/dist/render/plumeRenderer.js +185 -0
- package/dist/render/pointLightSelection.d.ts +175 -0
- package/dist/render/pointLightSelection.js +301 -0
- package/dist/render/pointShadowArray.d.ts +95 -0
- package/dist/render/pointShadowArray.js +219 -0
- package/dist/render/pointShadowBudget.d.ts +118 -0
- package/dist/render/pointShadowBudget.js +221 -0
- package/dist/render/pointShadowImage.d.ts +265 -0
- package/dist/render/pointShadowImage.js +339 -0
- package/dist/render/pointShadowMap.d.ts +93 -0
- package/dist/render/pointShadowMap.js +167 -0
- package/dist/render/pointShadowSystem.d.ts +195 -0
- package/dist/render/pointShadowSystem.js +336 -0
- package/dist/render/prefilterEnvMap.d.ts +124 -0
- package/dist/render/prefilterEnvMap.js +146 -0
- package/dist/render/prefilterPass.d.ts +44 -0
- package/dist/render/prefilterPass.js +98 -0
- package/dist/render/probeGrid.d.ts +122 -0
- package/dist/render/probeGrid.js +174 -0
- package/dist/render/rainField.d.ts +99 -0
- package/dist/render/rainField.js +168 -0
- package/dist/render/reflectionProbe.d.ts +188 -0
- package/dist/render/reflectionProbe.js +437 -0
- package/dist/render/renderQuality.d.ts +699 -0
- package/dist/render/renderQuality.js +293 -0
- package/dist/render/rendererHarness.d.ts +39 -0
- package/dist/render/rendererHarness.js +185 -0
- package/dist/render/resolutionGovernor.d.ts +107 -0
- package/dist/render/resolutionGovernor.js +144 -0
- package/dist/render/scatterDeform.d.ts +17 -0
- package/dist/render/scatterDeform.js +46 -0
- package/dist/render/sceneTarget.d.ts +288 -0
- package/dist/render/sceneTarget.js +856 -0
- package/dist/render/screenSpaceReflection.d.ts +233 -0
- package/dist/render/screenSpaceReflection.js +415 -0
- package/dist/render/sdfFont.d.ts +77 -0
- package/dist/render/sdfFont.js +86 -0
- package/dist/render/sdfTextLayout.d.ts +46 -0
- package/dist/render/sdfTextLayout.js +145 -0
- package/dist/render/sdfTextRenderer.d.ts +75 -0
- package/dist/render/sdfTextRenderer.js +194 -0
- package/dist/render/seaState.d.ts +25 -0
- package/dist/render/seaState.js +34 -0
- package/dist/render/segmentQuads.d.ts +29 -0
- package/dist/render/segmentQuads.js +75 -0
- package/dist/render/shader.d.ts +5 -0
- package/dist/render/shader.js +172 -0
- package/dist/render/shaders/ambientOcclusion.d.ts +45 -0
- package/dist/render/shaders/ambientOcclusion.js +352 -0
- package/dist/render/shaders/arcane.d.ts +19 -0
- package/dist/render/shaders/arcane.js +102 -0
- package/dist/render/shaders/bloom.d.ts +70 -0
- package/dist/render/shaders/bloom.js +227 -0
- package/dist/render/shaders/bolt.d.ts +17 -0
- package/dist/render/shaders/bolt.js +161 -0
- package/dist/render/shaders/caustics.d.ts +38 -0
- package/dist/render/shaders/caustics.js +167 -0
- package/dist/render/shaders/conditionals.d.ts +21 -0
- package/dist/render/shaders/conditionals.js +55 -0
- package/dist/render/shaders/decalProject.d.ts +25 -0
- package/dist/render/shaders/decalProject.js +125 -0
- package/dist/render/shaders/depth.d.ts +14 -0
- package/dist/render/shaders/depth.js +114 -0
- package/dist/render/shaders/depthOfField.d.ts +41 -0
- package/dist/render/shaders/depthOfField.js +139 -0
- package/dist/render/shaders/film.d.ts +15 -0
- package/dist/render/shaders/film.js +283 -0
- package/dist/render/shaders/fire.d.ts +12 -0
- package/dist/render/shaders/fire.js +178 -0
- package/dist/render/shaders/flat/directionalShadow.d.ts +1 -0
- package/dist/render/shaders/flat/directionalShadow.js +195 -0
- package/dist/render/shaders/flat/index.d.ts +135 -0
- package/dist/render/shaders/flat/index.js +387 -0
- package/dist/render/shaders/flat/lobes.d.ts +1 -0
- package/dist/render/shaders/flat/lobes.js +398 -0
- package/dist/render/shaders/flat/main.d.ts +2 -0
- package/dist/render/shaders/flat/main.js +1630 -0
- package/dist/render/shaders/flat/pointShadow.d.ts +1 -0
- package/dist/render/shaders/flat/pointShadow.js +322 -0
- package/dist/render/shaders/flat/preamble.d.ts +15 -0
- package/dist/render/shaders/flat/preamble.js +864 -0
- package/dist/render/shaders/flat/probeGrid.d.ts +21 -0
- package/dist/render/shaders/flat/probeGrid.js +151 -0
- package/dist/render/shaders/flat/surface.d.ts +2 -0
- package/dist/render/shaders/flat/surface.js +40 -0
- package/dist/render/shaders/flock.d.ts +11 -0
- package/dist/render/shaders/flock.js +102 -0
- package/dist/render/shaders/fog.d.ts +37 -0
- package/dist/render/shaders/fog.js +98 -0
- package/dist/render/shaders/fullscreen.d.ts +16 -0
- package/dist/render/shaders/fullscreen.js +27 -0
- package/dist/render/shaders/generated/ambientOcclusion.wgsl.d.ts +65 -0
- package/dist/render/shaders/generated/ambientOcclusion.wgsl.js +71 -0
- package/dist/render/shaders/generated/arcane.wgsl.d.ts +90 -0
- package/dist/render/shaders/generated/arcane.wgsl.js +96 -0
- package/dist/render/shaders/generated/bloom.wgsl.d.ts +69 -0
- package/dist/render/shaders/generated/bloom.wgsl.js +75 -0
- package/dist/render/shaders/generated/bolt.wgsl.d.ts +118 -0
- package/dist/render/shaders/generated/bolt.wgsl.js +124 -0
- package/dist/render/shaders/generated/caustics.wgsl.d.ts +118 -0
- package/dist/render/shaders/generated/caustics.wgsl.js +124 -0
- package/dist/render/shaders/generated/decalProject.wgsl.d.ts +61 -0
- package/dist/render/shaders/generated/decalProject.wgsl.js +67 -0
- package/dist/render/shaders/generated/depth.wgsl.d.ts +131 -0
- package/dist/render/shaders/generated/depth.wgsl.js +137 -0
- package/dist/render/shaders/generated/film.wgsl.d.ts +134 -0
- package/dist/render/shaders/generated/film.wgsl.js +140 -0
- package/dist/render/shaders/generated/fire.wgsl.d.ts +128 -0
- package/dist/render/shaders/generated/fire.wgsl.js +134 -0
- package/dist/render/shaders/generated/flat.wgsl.d.ts +9163 -0
- package/dist/render/shaders/generated/flat.wgsl.js +9192 -0
- package/dist/render/shaders/generated/flock.wgsl.d.ts +73 -0
- package/dist/render/shaders/generated/flock.wgsl.js +79 -0
- package/dist/render/shaders/generated/fullscreen.wgsl.d.ts +12 -0
- package/dist/render/shaders/generated/fullscreen.wgsl.js +18 -0
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +130 -0
- package/dist/render/shaders/generated/globalMedium.wgsl.js +136 -0
- package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +230 -0
- package/dist/render/shaders/generated/lightVolume.wgsl.js +239 -0
- package/dist/render/shaders/generated/line.wgsl.d.ts +128 -0
- package/dist/render/shaders/generated/line.wgsl.js +134 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +51 -0
- package/dist/render/shaders/generated/octahedralResolve.wgsl.js +57 -0
- package/dist/render/shaders/generated/oitResolve.wgsl.d.ts +23 -0
- package/dist/render/shaders/generated/oitResolve.wgsl.js +29 -0
- package/dist/render/shaders/generated/panel.wgsl.d.ts +48 -0
- package/dist/render/shaders/generated/panel.wgsl.js +54 -0
- package/dist/render/shaders/generated/particle.wgsl.d.ts +332 -0
- package/dist/render/shaders/generated/particle.wgsl.js +338 -0
- package/dist/render/shaders/generated/prefilter.wgsl.d.ts +61 -0
- package/dist/render/shaders/generated/prefilter.wgsl.js +67 -0
- package/dist/render/shaders/generated/rush.wgsl.d.ts +131 -0
- package/dist/render/shaders/generated/rush.wgsl.js +137 -0
- package/dist/render/shaders/generated/scatter.wgsl.d.ts +195 -0
- package/dist/render/shaders/generated/scatter.wgsl.js +201 -0
- package/dist/render/shaders/generated/sdfText.wgsl.d.ts +69 -0
- package/dist/render/shaders/generated/sdfText.wgsl.js +75 -0
- package/dist/render/shaders/generated/sky.wgsl.d.ts +100 -0
- package/dist/render/shaders/generated/sky.wgsl.js +106 -0
- package/dist/render/shaders/generated/smoke.wgsl.d.ts +85 -0
- package/dist/render/shaders/generated/smoke.wgsl.js +91 -0
- package/dist/render/shaders/generated/ssrResolve.wgsl.d.ts +18 -0
- package/dist/render/shaders/generated/ssrResolve.wgsl.js +24 -0
- package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +86 -0
- package/dist/render/shaders/generated/ssrTrace.wgsl.js +92 -0
- package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +46 -0
- package/dist/render/shaders/generated/temporalResolve.wgsl.js +52 -0
- package/dist/render/shaders/generated/text.wgsl.d.ts +98 -0
- package/dist/render/shaders/generated/text.wgsl.js +104 -0
- package/dist/render/shaders/generated/water.wgsl.d.ts +247 -0
- package/dist/render/shaders/generated/water.wgsl.js +253 -0
- package/dist/render/shaders/generated/windStreaks.wgsl.d.ts +73 -0
- package/dist/render/shaders/generated/windStreaks.wgsl.js +79 -0
- package/dist/render/shaders/gerstner.d.ts +21 -0
- package/dist/render/shaders/gerstner.js +110 -0
- package/dist/render/shaders/globalMedium.d.ts +56 -0
- package/dist/render/shaders/globalMedium.js +393 -0
- package/dist/render/shaders/lightVolume.d.ts +61 -0
- package/dist/render/shaders/lightVolume.js +527 -0
- package/dist/render/shaders/line.d.ts +18 -0
- package/dist/render/shaders/line.js +122 -0
- package/dist/render/shaders/morph.d.ts +26 -0
- package/dist/render/shaders/morph.js +61 -0
- package/dist/render/shaders/octahedral.d.ts +76 -0
- package/dist/render/shaders/octahedral.js +161 -0
- package/dist/render/shaders/octahedralResolve.d.ts +25 -0
- package/dist/render/shaders/octahedralResolve.js +81 -0
- package/dist/render/shaders/oitResolve.d.ts +17 -0
- package/dist/render/shaders/oitResolve.js +42 -0
- package/dist/render/shaders/outputTransform.d.ts +37 -0
- package/dist/render/shaders/outputTransform.js +106 -0
- package/dist/render/shaders/panel.d.ts +17 -0
- package/dist/render/shaders/panel.js +50 -0
- package/dist/render/shaders/particle.d.ts +82 -0
- package/dist/render/shaders/particle.js +431 -0
- package/dist/render/shaders/prefilter.d.ts +37 -0
- package/dist/render/shaders/prefilter.js +276 -0
- package/dist/render/shaders/rush.d.ts +21 -0
- package/dist/render/shaders/rush.js +355 -0
- package/dist/render/shaders/scatter.d.ts +14 -0
- package/dist/render/shaders/scatter.js +206 -0
- package/dist/render/shaders/sdfText.d.ts +9 -0
- package/dist/render/shaders/sdfText.js +65 -0
- package/dist/render/shaders/skinning.d.ts +17 -0
- package/dist/render/shaders/skinning.js +59 -0
- package/dist/render/shaders/sky.d.ts +10 -0
- package/dist/render/shaders/sky.js +242 -0
- package/dist/render/shaders/smoke.d.ts +8 -0
- package/dist/render/shaders/smoke.js +88 -0
- package/dist/render/shaders/ssrResolve.d.ts +15 -0
- package/dist/render/shaders/ssrResolve.js +28 -0
- package/dist/render/shaders/ssrTrace.d.ts +22 -0
- package/dist/render/shaders/ssrTrace.js +230 -0
- package/dist/render/shaders/tangentFrame.d.ts +17 -0
- package/dist/render/shaders/tangentFrame.js +70 -0
- package/dist/render/shaders/temporalResolve.d.ts +1 -0
- package/dist/render/shaders/temporalResolve.js +150 -0
- package/dist/render/shaders/text.d.ts +17 -0
- package/dist/render/shaders/text.js +155 -0
- package/dist/render/shaders/vertexChannel.d.ts +39 -0
- package/dist/render/shaders/vertexChannel.js +69 -0
- package/dist/render/shaders/water.d.ts +18 -0
- package/dist/render/shaders/water.js +354 -0
- package/dist/render/shaders/windStreaks.d.ts +14 -0
- package/dist/render/shaders/windStreaks.js +129 -0
- package/dist/render/shadowCasters.d.ts +107 -0
- package/dist/render/shadowCasters.js +1 -0
- package/dist/render/shadowMap.d.ts +10 -0
- package/dist/render/shadowMap.js +80 -0
- package/dist/render/shotPlacement.d.ts +80 -0
- package/dist/render/shotPlacement.js +183 -0
- package/dist/render/skinPalette.d.ts +90 -0
- package/dist/render/skinPalette.js +136 -0
- package/dist/render/ssrPass.d.ts +59 -0
- package/dist/render/ssrPass.js +196 -0
- package/dist/render/surfaceSheet.d.ts +52 -0
- package/dist/render/surfaceSheet.js +99 -0
- package/dist/render/surfaceTexture.d.ts +197 -0
- package/dist/render/surfaceTexture.js +116 -0
- package/dist/render/temporalAa.d.ts +104 -0
- package/dist/render/temporalAa.js +194 -0
- package/dist/render/temporalPass.d.ts +54 -0
- package/dist/render/temporalPass.js +135 -0
- package/dist/render/textLayout.d.ts +88 -0
- package/dist/render/textLayout.js +201 -0
- package/dist/render/textRenderer.d.ts +32 -0
- package/dist/render/textRenderer.js +176 -0
- package/dist/render/thirdPersonCamera.d.ts +272 -0
- package/dist/render/thirdPersonCamera.js +479 -0
- package/dist/render/trample.d.ts +57 -0
- package/dist/render/trample.js +134 -0
- package/dist/render/translucentQueue.d.ts +76 -0
- package/dist/render/translucentQueue.js +90 -0
- package/dist/render/uniformVectorBudget.d.ts +105 -0
- package/dist/render/uniformVectorBudget.js +201 -0
- package/dist/render/uploadStep.d.ts +14 -0
- package/dist/render/uploadStep.js +14 -0
- package/dist/render/vertexDefaults.d.ts +48 -0
- package/dist/render/vertexDefaults.js +111 -0
- package/dist/render/visibility.d.ts +22 -0
- package/dist/render/visibility.js +47 -0
- package/dist/render/waterDraw.d.ts +57 -0
- package/dist/render/waterDraw.js +102 -0
- package/dist/render/waterGrid.d.ts +62 -0
- package/dist/render/waterGrid.js +151 -0
- package/dist/render/waterRenderer.d.ts +163 -0
- package/dist/render/waterRenderer.js +165 -0
- package/dist/render/wind.d.ts +45 -0
- package/dist/render/wind.js +32 -0
- package/dist/render/windField.d.ts +34 -0
- package/dist/render/windField.js +13 -0
- package/dist/render/windStreakDraw.d.ts +73 -0
- package/dist/render/windStreakDraw.js +86 -0
- package/dist/render/windStreakRenderer.d.ts +37 -0
- package/dist/render/windStreakRenderer.js +86 -0
- package/dist/scene/node.d.ts +128 -0
- package/dist/scene/node.js +319 -0
- package/dist/scene/visit.d.ts +38 -0
- package/dist/scene/visit.js +43 -0
- package/dist/ui/clipMime.d.ts +46 -0
- package/dist/ui/clipMime.js +88 -0
- package/dist/ui/exportTarget.d.ts +305 -0
- package/dist/ui/exportTarget.js +368 -0
- package/dist/ui/frameOverlay.d.ts +59 -0
- package/dist/ui/frameOverlay.js +76 -0
- package/dist/ui/framePacer.d.ts +142 -0
- package/dist/ui/framePacer.js +284 -0
- package/dist/ui/frameRecorder.d.ts +188 -0
- package/dist/ui/frameRecorder.js +221 -0
- package/dist/ui/fullscreen.d.ts +72 -0
- package/dist/ui/fullscreen.js +92 -0
- package/dist/ui/pixelCursor.d.ts +28 -0
- package/dist/ui/pixelCursor.js +66 -0
- package/dist/ui/splash.d.ts +86 -0
- package/dist/ui/splash.js +300 -0
- package/dist/ui/stillFrame.d.ts +22 -0
- package/dist/ui/stillFrame.js +40 -0
- package/package.json +60 -0
- package/src/behavior/behaviorTree.ts +346 -0
- package/src/build/shaderComments.ts +0 -0
- package/src/cinematic/player.ts +209 -0
- package/src/cinematic/script.ts +231 -0
- package/src/core/bootGate.ts +49 -0
- package/src/core/loadTracker.ts +144 -0
- package/src/core/loop.ts +211 -0
- package/src/core/messageQueue.ts +145 -0
- package/src/core/onceSet.ts +65 -0
- package/src/core/preferences.ts +177 -0
- package/src/core/remoteSave.ts +347 -0
- package/src/core/rng.ts +101 -0
- package/src/core/stepBudget.ts +136 -0
- package/src/core/storage.ts +114 -0
- package/src/core/tickTrace.ts +129 -0
- package/src/core/timeCurve.ts +175 -0
- package/src/core/withDefaults.ts +28 -0
- package/src/dev/contactProbe.ts +115 -0
- package/src/dev/fpsMeter.ts +101 -0
- package/src/environment/celestialClock.ts +385 -0
- package/src/geometry/decal.ts +260 -0
- package/src/geometry/filmPatch.ts +158 -0
- package/src/geometry/growable.ts +165 -0
- package/src/geometry/lightVolume.ts +161 -0
- package/src/geometry/meshBuilder.ts +1397 -0
- package/src/geometry/pixelFont.ts +189 -0
- package/src/geometry/ribbon.ts +790 -0
- package/src/geometry/shellFill.ts +265 -0
- package/src/geometry/spline.ts +659 -0
- package/src/geometry/tangents.ts +173 -0
- package/src/geometry/textMesh.ts +96 -0
- package/src/geometry/treeBuilder.ts +114 -0
- package/src/host/display.ts +180 -0
- package/src/host/files.ts +77 -0
- package/src/host/lifecycle.ts +63 -0
- package/src/host/platformServices.ts +23 -0
- package/src/host/screen.ts +134 -0
- package/src/index.ts +730 -0
- package/src/input/actionMap.ts +377 -0
- package/src/input/activeDevice.ts +86 -0
- package/src/input/gamepadIdentity.ts +131 -0
- package/src/input/gamepadMapping.ts +121 -0
- package/src/input/input.ts +872 -0
- package/src/input/inputHarness.ts +226 -0
- package/src/input/rightGesture.ts +76 -0
- package/src/input/rumble.ts +138 -0
- package/src/input/touchControls.ts +451 -0
- package/src/input/typingTarget.ts +26 -0
- package/src/math/bounds.ts +153 -0
- package/src/math/color.ts +37 -0
- package/src/math/exact.ts +274 -0
- package/src/math/frustum.ts +115 -0
- package/src/math/intersect.ts +228 -0
- package/src/math/scalar.ts +109 -0
- package/src/math/spring.ts +106 -0
- package/src/nav/navGraph.ts +168 -0
- package/src/nav/navPath.ts +217 -0
- package/src/nav/navSearch.ts +200 -0
- package/src/physics/boxSurface.ts +96 -0
- package/src/physics/colliderSurface.ts +213 -0
- package/src/physics/compositeSurface.ts +111 -0
- package/src/physics/heightSurface.ts +234 -0
- package/src/physics/ribbonSurface.ts +642 -0
- package/src/render/ambientOcclusionPass.ts +200 -0
- package/src/render/areaLights.ts +194 -0
- package/src/render/areaShadowSet.ts +405 -0
- package/src/render/atmosphere.ts +186 -0
- package/src/render/backend/api.ts +802 -0
- package/src/render/backend/budget.ts +139 -0
- package/src/render/backend/createRenderer.ts +343 -0
- package/src/render/backend/deadline.ts +37 -0
- package/src/render/backend/probe.ts +152 -0
- package/src/render/backend/select.ts +288 -0
- package/src/render/backend/timer.ts +59 -0
- package/src/render/backend/webgl2/instanced.ts +46 -0
- package/src/render/backend/webgl2/morphTexture.ts +58 -0
- package/src/render/backend/webgl2/renderer.ts +7484 -0
- package/src/render/backend/webgl2/skinPaletteTexture.ts +70 -0
- package/src/render/backend/webgpu/boltPass.ts +205 -0
- package/src/render/backend/webgpu/buffers.ts +553 -0
- package/src/render/backend/webgpu/causticsPass.ts +174 -0
- package/src/render/backend/webgpu/clusterBinner.ts +259 -0
- package/src/render/backend/webgpu/depthPass.ts +261 -0
- package/src/render/backend/webgpu/device.ts +148 -0
- package/src/render/backend/webgpu/drawCommand.ts +79 -0
- package/src/render/backend/webgpu/environmentTexels.ts +96 -0
- package/src/render/backend/webgpu/filmPass.ts +123 -0
- package/src/render/backend/webgpu/flatPass.ts +635 -0
- package/src/render/backend/webgpu/flockPass.ts +163 -0
- package/src/render/backend/webgpu/gpuTimestamps.ts +255 -0
- package/src/render/backend/webgpu/insetPass.ts +123 -0
- package/src/render/backend/webgpu/instanced.ts +55 -0
- package/src/render/backend/webgpu/lightVolumePass.ts +203 -0
- package/src/render/backend/webgpu/linePass.ts +270 -0
- package/src/render/backend/webgpu/morphTexture.ts +61 -0
- package/src/render/backend/webgpu/panelPass.ts +138 -0
- package/src/render/backend/webgpu/particlePass.ts +370 -0
- package/src/render/backend/webgpu/pipelineCache.ts +152 -0
- package/src/render/backend/webgpu/plumePass.ts +292 -0
- package/src/render/backend/webgpu/pointShadowPass.ts +368 -0
- package/src/render/backend/webgpu/postPass.ts +470 -0
- package/src/render/backend/webgpu/probePass.ts +218 -0
- package/src/render/backend/webgpu/reflectionPass.ts +137 -0
- package/src/render/backend/webgpu/renderer.ts +13004 -0
- package/src/render/backend/webgpu/scatterPass.ts +354 -0
- package/src/render/backend/webgpu/sdfTextPass.ts +220 -0
- package/src/render/backend/webgpu/shaderModules.ts +49 -0
- package/src/render/backend/webgpu/shaders/clusterBin.wgsl.ts +219 -0
- package/src/render/backend/webgpu/skinPaletteRing.ts +105 -0
- package/src/render/backend/webgpu/skinPaletteTexture.ts +79 -0
- package/src/render/backend/webgpu/skyPass.ts +85 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +257 -0
- package/src/render/backend/webgpu/textPass.ts +224 -0
- package/src/render/backend/webgpu/uniformRing.ts +228 -0
- package/src/render/backend/webgpu/waterPass.ts +211 -0
- package/src/render/backend/webgpu/windStreakPass.ts +196 -0
- package/src/render/billboard.ts +108 -0
- package/src/render/bloomChain.ts +101 -0
- package/src/render/bloomPass.ts +256 -0
- package/src/render/boltBatch.ts +141 -0
- package/src/render/boltPool.ts +360 -0
- package/src/render/boom.ts +123 -0
- package/src/render/camera.ts +348 -0
- package/src/render/causticsRenderer.ts +171 -0
- package/src/render/cinematicCamera.ts +278 -0
- package/src/render/clusteredLights.ts +598 -0
- package/src/render/colourGrade.ts +109 -0
- package/src/render/compute.ts +83 -0
- package/src/render/contextLoss.ts +50 -0
- package/src/render/debugLines.ts +411 -0
- package/src/render/decalPass.ts +124 -0
- package/src/render/decalProjector.ts +390 -0
- package/src/render/decalQueue.ts +110 -0
- package/src/render/depthConvention.ts +383 -0
- package/src/render/drawingBuffer.ts +89 -0
- package/src/render/emptyTexture.ts +130 -0
- package/src/render/envProbeArray.ts +201 -0
- package/src/render/equirectToCube.ts +160 -0
- package/src/render/flockGeometry.ts +53 -0
- package/src/render/flockRenderer.ts +111 -0
- package/src/render/frame/arena.ts +93 -0
- package/src/render/frame/index.ts +29 -0
- package/src/render/frame/replay.ts +50 -0
- package/src/render/frame/resources.ts +61 -0
- package/src/render/frame/schedule.ts +85 -0
- package/src/render/frameView.ts +20 -0
- package/src/render/gizmo.ts +923 -0
- package/src/render/globalMedium.ts +154 -0
- package/src/render/globalMediumPass.ts +323 -0
- package/src/render/gpuCapability.ts +244 -0
- package/src/render/gpuTimer.ts +182 -0
- package/src/render/halfFloat.ts +39 -0
- package/src/render/handleRegistry.ts +96 -0
- package/src/render/iesProfile.ts +215 -0
- package/src/render/imageTexels.ts +109 -0
- package/src/render/instancedMesh.ts +187 -0
- package/src/render/instances.ts +92 -0
- package/src/render/lightBudget.ts +655 -0
- package/src/render/lightMatrix.ts +69 -0
- package/src/render/lightVolumeDraw.ts +216 -0
- package/src/render/lineBatch.ts +180 -0
- package/src/render/linePoints.ts +61 -0
- package/src/render/livePointShadowSet.ts +285 -0
- package/src/render/lod.ts +86 -0
- package/src/render/mesh.ts +536 -0
- package/src/render/occlusion.ts +406 -0
- package/src/render/oitPass.ts +230 -0
- package/src/render/orderIndependent.ts +136 -0
- package/src/render/particleBatch.ts +299 -0
- package/src/render/particleMaterial.ts +84 -0
- package/src/render/particlePool.ts +291 -0
- package/src/render/pass.ts +203 -0
- package/src/render/passTarget.ts +225 -0
- package/src/render/pickable.ts +222 -0
- package/src/render/planarReflection.ts +233 -0
- package/src/render/planarReflectionDraw.ts +87 -0
- package/src/render/plumeGeometry.ts +75 -0
- package/src/render/plumeMaterial.ts +99 -0
- package/src/render/plumeRenderer.ts +272 -0
- package/src/render/pointLightSelection.ts +447 -0
- package/src/render/pointShadowArray.ts +276 -0
- package/src/render/pointShadowBudget.ts +305 -0
- package/src/render/pointShadowImage.ts +470 -0
- package/src/render/pointShadowMap.ts +228 -0
- package/src/render/pointShadowSystem.ts +408 -0
- package/src/render/prefilterEnvMap.ts +162 -0
- package/src/render/prefilterPass.ts +115 -0
- package/src/render/probeGrid.ts +248 -0
- package/src/render/rainField.ts +240 -0
- package/src/render/reflectionProbe.ts +530 -0
- package/src/render/renderQuality.ts +1054 -0
- package/src/render/rendererHarness.ts +214 -0
- package/src/render/resolutionGovernor.ts +189 -0
- package/src/render/scatterDeform.ts +72 -0
- package/src/render/sceneTarget.ts +1032 -0
- package/src/render/screenSpaceReflection.ts +524 -0
- package/src/render/sdfFont.ts +157 -0
- package/src/render/sdfTextLayout.ts +206 -0
- package/src/render/sdfTextRenderer.ts +233 -0
- package/src/render/seaState.ts +55 -0
- package/src/render/segmentQuads.ts +92 -0
- package/src/render/shader.ts +190 -0
- package/src/render/shaders/ambientOcclusion.ts +354 -0
- package/src/render/shaders/arcane.ts +103 -0
- package/src/render/shaders/bloom.ts +232 -0
- package/src/render/shaders/bolt.ts +164 -0
- package/src/render/shaders/caustics.ts +169 -0
- package/src/render/shaders/conditionals.ts +58 -0
- package/src/render/shaders/decalProject.ts +127 -0
- package/src/render/shaders/depth.ts +131 -0
- package/src/render/shaders/depthOfField.ts +141 -0
- package/src/render/shaders/film.ts +285 -0
- package/src/render/shaders/fire.ts +180 -0
- package/src/render/shaders/flat/directionalShadow.ts +196 -0
- package/src/render/shaders/flat/index.ts +502 -0
- package/src/render/shaders/flat/lobes.ts +399 -0
- package/src/render/shaders/flat/main.ts +1631 -0
- package/src/render/shaders/flat/pointShadow.ts +323 -0
- package/src/render/shaders/flat/preamble.ts +875 -0
- package/src/render/shaders/flat/probeGrid.ts +152 -0
- package/src/render/shaders/flat/surface.ts +41 -0
- package/src/render/shaders/flock.ts +103 -0
- package/src/render/shaders/fog.ts +99 -0
- package/src/render/shaders/fullscreen.ts +28 -0
- package/src/render/shaders/generated/ambientOcclusion.wgsl.ts +74 -0
- package/src/render/shaders/generated/arcane.wgsl.ts +98 -0
- package/src/render/shaders/generated/bloom.wgsl.ts +79 -0
- package/src/render/shaders/generated/bolt.wgsl.ts +127 -0
- package/src/render/shaders/generated/caustics.wgsl.ts +127 -0
- package/src/render/shaders/generated/decalProject.wgsl.ts +69 -0
- package/src/render/shaders/generated/depth.wgsl.ts +142 -0
- package/src/render/shaders/generated/film.wgsl.ts +143 -0
- package/src/render/shaders/generated/fire.wgsl.ts +137 -0
- package/src/render/shaders/generated/flat.wgsl.ts +9195 -0
- package/src/render/shaders/generated/flock.wgsl.ts +82 -0
- package/src/render/shaders/generated/fullscreen.wgsl.ts +20 -0
- package/src/render/shaders/generated/globalMedium.wgsl.ts +139 -0
- package/src/render/shaders/generated/lightVolume.wgsl.ts +242 -0
- package/src/render/shaders/generated/line.wgsl.ts +137 -0
- package/src/render/shaders/generated/octahedralResolve.wgsl.ts +60 -0
- package/src/render/shaders/generated/oitResolve.wgsl.ts +31 -0
- package/src/render/shaders/generated/panel.wgsl.ts +57 -0
- package/src/render/shaders/generated/particle.wgsl.ts +343 -0
- package/src/render/shaders/generated/prefilter.wgsl.ts +69 -0
- package/src/render/shaders/generated/rush.wgsl.ts +139 -0
- package/src/render/shaders/generated/scatter.wgsl.ts +205 -0
- package/src/render/shaders/generated/sdfText.wgsl.ts +78 -0
- package/src/render/shaders/generated/sky.wgsl.ts +109 -0
- package/src/render/shaders/generated/smoke.wgsl.ts +93 -0
- package/src/render/shaders/generated/ssrResolve.wgsl.ts +26 -0
- package/src/render/shaders/generated/ssrTrace.wgsl.ts +94 -0
- package/src/render/shaders/generated/temporalResolve.wgsl.ts +54 -0
- package/src/render/shaders/generated/text.wgsl.ts +107 -0
- package/src/render/shaders/generated/water.wgsl.ts +256 -0
- package/src/render/shaders/generated/windStreaks.wgsl.ts +82 -0
- package/src/render/shaders/gerstner.ts +110 -0
- package/src/render/shaders/globalMedium.ts +396 -0
- package/src/render/shaders/lightVolume.ts +546 -0
- package/src/render/shaders/line.ts +125 -0
- package/src/render/shaders/morph.ts +62 -0
- package/src/render/shaders/octahedral.ts +170 -0
- package/src/render/shaders/octahedralResolve.ts +83 -0
- package/src/render/shaders/oitResolve.ts +42 -0
- package/src/render/shaders/outputTransform.ts +107 -0
- package/src/render/shaders/panel.ts +51 -0
- package/src/render/shaders/particle.ts +438 -0
- package/src/render/shaders/prefilter.ts +278 -0
- package/src/render/shaders/rush.ts +357 -0
- package/src/render/shaders/scatter.ts +211 -0
- package/src/render/shaders/sdfText.ts +68 -0
- package/src/render/shaders/skinning.ts +59 -0
- package/src/render/shaders/sky.ts +243 -0
- package/src/render/shaders/smoke.ts +89 -0
- package/src/render/shaders/ssrResolve.ts +28 -0
- package/src/render/shaders/ssrTrace.ts +233 -0
- package/src/render/shaders/tangentFrame.ts +70 -0
- package/src/render/shaders/temporalResolve.ts +151 -0
- package/src/render/shaders/text.ts +156 -0
- package/src/render/shaders/vertexChannel.ts +71 -0
- package/src/render/shaders/water.ts +356 -0
- package/src/render/shaders/windStreaks.ts +130 -0
- package/src/render/shadowCasters.ts +124 -0
- package/src/render/shadowMap.ts +89 -0
- package/src/render/shotPlacement.ts +266 -0
- package/src/render/skinPalette.ts +157 -0
- package/src/render/ssrPass.ts +241 -0
- package/src/render/surfaceSheet.ts +158 -0
- package/src/render/surfaceTexture.ts +310 -0
- package/src/render/temporalAa.ts +221 -0
- package/src/render/temporalPass.ts +153 -0
- package/src/render/textLayout.ts +239 -0
- package/src/render/textRenderer.ts +201 -0
- package/src/render/thirdPersonCamera.ts +578 -0
- package/src/render/trample.ts +140 -0
- package/src/render/translucentQueue.ts +161 -0
- package/src/render/uniformVectorBudget.ts +246 -0
- package/src/render/uploadStep.ts +14 -0
- package/src/render/vertexDefaults.ts +115 -0
- package/src/render/visibility.ts +56 -0
- package/src/render/waterDraw.ts +167 -0
- package/src/render/waterGrid.ts +180 -0
- package/src/render/waterRenderer.ts +352 -0
- package/src/render/wind.ts +79 -0
- package/src/render/windField.ts +50 -0
- package/src/render/windStreakDraw.ts +131 -0
- package/src/render/windStreakRenderer.ts +130 -0
- package/src/scene/node.ts +336 -0
- package/src/scene/visit.ts +82 -0
- package/src/ui/clipMime.ts +109 -0
- package/src/ui/exportTarget.ts +491 -0
- package/src/ui/frameOverlay.ts +159 -0
- package/src/ui/framePacer.ts +351 -0
- package/src/ui/frameRecorder.ts +333 -0
- package/src/ui/fullscreen.ts +113 -0
- package/src/ui/pixelCursor.ts +99 -0
- package/src/ui/splash.ts +347 -0
- package/src/ui/stillFrame.ts +44 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { KeyValueStore } from './storage.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Persisted player preferences: a validated record in a `KeyValueStore`.
|
|
4
|
+
*
|
|
5
|
+
* Generic on purpose. A game declares *which* preferences exist and what their
|
|
6
|
+
* legal values are; everything below — reading, validating field by field,
|
|
7
|
+
* clamping, writing and announcing changes — is the same work in any game.
|
|
8
|
+
*
|
|
9
|
+
* Where the bytes actually live is the store's problem, not this module's, so a
|
|
10
|
+
* game can persist to the browser, a server or nothing at all without any of
|
|
11
|
+
* this changing. See `storage.ts` for why that seam is synchronous.
|
|
12
|
+
*/
|
|
13
|
+
export interface PreferenceSchema<T extends object> {
|
|
14
|
+
/** Storage key. Namespace it — the store is shared with everything else. */
|
|
15
|
+
readonly key: string;
|
|
16
|
+
/** The complete set of fields, and the value each falls back to. */
|
|
17
|
+
readonly defaults: T;
|
|
18
|
+
/** Inclusive `[min, max]` for numeric fields. Values outside are clamped. */
|
|
19
|
+
readonly ranges?: Partial<Record<keyof T, readonly [number, number]>>;
|
|
20
|
+
/** Legal values for string fields. Anything else falls back to the default. */
|
|
21
|
+
readonly options?: Partial<Record<keyof T, readonly string[]>>;
|
|
22
|
+
}
|
|
23
|
+
export declare function loadPreferences<T extends object>(schema: PreferenceSchema<T>, store?: KeyValueStore): T;
|
|
24
|
+
export declare function savePreferences<T extends object>(schema: PreferenceSchema<T>, value: T, store?: KeyValueStore): void;
|
|
25
|
+
/**
|
|
26
|
+
* A live preference record: the loaded value, validated updates, persistence
|
|
27
|
+
* and change notification for whatever applies them to running systems.
|
|
28
|
+
*/
|
|
29
|
+
export declare class PreferenceStore<T extends object> {
|
|
30
|
+
private readonly schema;
|
|
31
|
+
private readonly store;
|
|
32
|
+
private current;
|
|
33
|
+
private readonly listeners;
|
|
34
|
+
constructor(schema: PreferenceSchema<T>, store?: KeyValueStore);
|
|
35
|
+
get value(): Readonly<T>;
|
|
36
|
+
/**
|
|
37
|
+
* Apply a partial change. Every field goes through the same validation as a
|
|
38
|
+
* stored one — a control that can produce an illegal value would otherwise
|
|
39
|
+
* write it, leaving the read path as the only thing catching it, one boot too
|
|
40
|
+
* late.
|
|
41
|
+
*/
|
|
42
|
+
update(patch: Partial<T>): void;
|
|
43
|
+
/** Returns an unsubscribe function. */
|
|
44
|
+
subscribe(listener: (value: Readonly<T>) => void): () => void;
|
|
45
|
+
/** Back to the declared defaults, persisted and announced like any change. */
|
|
46
|
+
reset(): void;
|
|
47
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { defaultStore } from './storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* The field types a preference record can hold. A default of any other shape is refused.
|
|
4
|
+
*
|
|
5
|
+
* **Refused loudly, and that is the whole point of this function.** `validate` below answers
|
|
6
|
+
* `undefined` for anything that is not one of these, and `undefined` means "the stored value was
|
|
7
|
+
* unusable, keep the default" — which is exactly right for *data* and exactly wrong for a
|
|
8
|
+
* *schema*. A field the schema declares as an array took that path and cost a consumer a
|
|
9
|
+
* afternoon: `loadPreferences` handed back the default every time, and `update` skipped the field
|
|
10
|
+
* without ever setting `changed`, so writing one was a no-op that persisted nothing, notified
|
|
11
|
+
* nobody and reported no error. It was found by a failing test rather than by anything here.
|
|
12
|
+
*
|
|
13
|
+
* **The two paths are deliberately not symmetrical.** A stored record always lags the code that
|
|
14
|
+
* reads it, so one field of the wrong shape is the normal case and is tolerated field by field.
|
|
15
|
+
* A schema is written by a developer and is wrong at compile time or never, so it fails at init,
|
|
16
|
+
* where the engine's rule says a fault belongs.
|
|
17
|
+
*/
|
|
18
|
+
const SUPPORTED = ['number', 'boolean', 'string'];
|
|
19
|
+
function assertSupportedSchema(schema) {
|
|
20
|
+
for (const key of Object.keys(schema.defaults)) {
|
|
21
|
+
const fallback = schema.defaults[key];
|
|
22
|
+
if (SUPPORTED.includes(typeof fallback))
|
|
23
|
+
continue;
|
|
24
|
+
const shape = Array.isArray(fallback) ? 'an array' : `a ${typeof fallback}`;
|
|
25
|
+
throw new Error(`preferences: "${schema.key}.${String(key)}" defaults to ${shape}, and a preference field ` +
|
|
26
|
+
`may only be a number, a boolean or a string. Anything else is written to the store and ` +
|
|
27
|
+
`silently dropped on the way back, so it is refused here rather than at the next boot.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Coerce one field, returning undefined when the candidate is unusable. */
|
|
31
|
+
function validate(schema, key, value) {
|
|
32
|
+
const fallback = schema.defaults[key];
|
|
33
|
+
if (typeof fallback === 'number') {
|
|
34
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
35
|
+
return undefined;
|
|
36
|
+
const range = schema.ranges?.[key];
|
|
37
|
+
if (range === undefined)
|
|
38
|
+
return value;
|
|
39
|
+
return Math.min(Math.max(value, range[0]), range[1]);
|
|
40
|
+
}
|
|
41
|
+
if (typeof fallback === 'boolean') {
|
|
42
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
43
|
+
}
|
|
44
|
+
if (typeof fallback === 'string') {
|
|
45
|
+
if (typeof value !== 'string')
|
|
46
|
+
return undefined;
|
|
47
|
+
const allowed = schema.options?.[key];
|
|
48
|
+
if (allowed !== undefined && !allowed.includes(value))
|
|
49
|
+
return undefined;
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
export function loadPreferences(schema, store = defaultStore()) {
|
|
55
|
+
assertSupportedSchema(schema);
|
|
56
|
+
const result = { ...schema.defaults };
|
|
57
|
+
const raw = store.read(schema.key);
|
|
58
|
+
if (raw === null)
|
|
59
|
+
return result;
|
|
60
|
+
let stored;
|
|
61
|
+
try {
|
|
62
|
+
stored = JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
if (typeof stored !== 'object' || stored === null)
|
|
68
|
+
return result;
|
|
69
|
+
/*
|
|
70
|
+
* Field by field rather than all or nothing. A stored record always lags the
|
|
71
|
+
* code that reads it, so one field of the wrong shape is the normal case —
|
|
72
|
+
* and discarding the record over it would wipe every other preference the
|
|
73
|
+
* player had ever set.
|
|
74
|
+
*/
|
|
75
|
+
const source = stored;
|
|
76
|
+
for (const key of Object.keys(schema.defaults)) {
|
|
77
|
+
const value = validate(schema, key, source[key]);
|
|
78
|
+
if (value !== undefined)
|
|
79
|
+
result[key] = value;
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
export function savePreferences(schema, value, store = defaultStore()) {
|
|
84
|
+
/* Checked here too: a caller that only ever saves would otherwise write a record that
|
|
85
|
+
nothing can read back, and find out one boot later in somebody else's session. */
|
|
86
|
+
assertSupportedSchema(schema);
|
|
87
|
+
store.write(schema.key, JSON.stringify(value));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A live preference record: the loaded value, validated updates, persistence
|
|
91
|
+
* and change notification for whatever applies them to running systems.
|
|
92
|
+
*/
|
|
93
|
+
export class PreferenceStore {
|
|
94
|
+
schema;
|
|
95
|
+
store;
|
|
96
|
+
current;
|
|
97
|
+
listeners = new Set();
|
|
98
|
+
constructor(schema, store = defaultStore()) {
|
|
99
|
+
this.schema = schema;
|
|
100
|
+
this.store = store;
|
|
101
|
+
this.current = loadPreferences(schema, store);
|
|
102
|
+
}
|
|
103
|
+
get value() {
|
|
104
|
+
return this.current;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Apply a partial change. Every field goes through the same validation as a
|
|
108
|
+
* stored one — a control that can produce an illegal value would otherwise
|
|
109
|
+
* write it, leaving the read path as the only thing catching it, one boot too
|
|
110
|
+
* late.
|
|
111
|
+
*/
|
|
112
|
+
update(patch) {
|
|
113
|
+
let changed = false;
|
|
114
|
+
for (const key of Object.keys(patch)) {
|
|
115
|
+
if (!(key in this.schema.defaults))
|
|
116
|
+
continue;
|
|
117
|
+
const next = validate(this.schema, key, patch[key]);
|
|
118
|
+
if (next === undefined || next === this.current[key])
|
|
119
|
+
continue;
|
|
120
|
+
this.current[key] = next;
|
|
121
|
+
changed = true;
|
|
122
|
+
}
|
|
123
|
+
// Silent when nothing moved: subscribers apply settings to live systems and
|
|
124
|
+
// some of those write back, which without this is a loop.
|
|
125
|
+
if (!changed)
|
|
126
|
+
return;
|
|
127
|
+
savePreferences(this.schema, this.current, this.store);
|
|
128
|
+
for (const listener of this.listeners)
|
|
129
|
+
listener(this.current);
|
|
130
|
+
}
|
|
131
|
+
/** Returns an unsubscribe function. */
|
|
132
|
+
subscribe(listener) {
|
|
133
|
+
this.listeners.add(listener);
|
|
134
|
+
return () => this.listeners.delete(listener);
|
|
135
|
+
}
|
|
136
|
+
/** Back to the declared defaults, persisted and announced like any change. */
|
|
137
|
+
reset() {
|
|
138
|
+
this.update({ ...this.schema.defaults });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { KeyValueStore } from './storage.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A save that lives somewhere the engine cannot read synchronously — a server, a native shell, a
|
|
4
|
+
* sandbox — behind the synchronous seam every consumer already speaks.
|
|
5
|
+
*
|
|
6
|
+
* **A write-behind queue rather than a second interface, and that is the decision this module
|
|
7
|
+
* exists to record.** `KeyValueStore` is synchronous because preferences are read during *boot*,
|
|
8
|
+
* before the first frame: an await there means a frame drawn with the wrong settings and then
|
|
9
|
+
* corrected, which is a visible flicker on every load. So the choice was between widening the seam
|
|
10
|
+
* to an asynchronous twin, which every consumer and every store integration would then have to
|
|
11
|
+
* learn, or hydrating a cache once and draining writes behind it. Both shipped implementations of
|
|
12
|
+
* the seam that are already asynchronous underneath — a file the shell owns, and a cloud store —
|
|
13
|
+
* chose the second, independently, and neither needed the interface widened. This is that
|
|
14
|
+
* arrangement written once, with the three things a hand-rolled version leaves out.
|
|
15
|
+
*
|
|
16
|
+
* **The three:**
|
|
17
|
+
*
|
|
18
|
+
* 1. **Coalescing.** A settings slider writes on every drag frame. One request per write is sixty
|
|
19
|
+
* requests for one decision, and it is the reason a naive fire-and-forget backend gets rate
|
|
20
|
+
* limited. Writes accumulate into a batch, one entry per key, sent after a quiet period.
|
|
21
|
+
* 2. **Retry.** A save that cannot reach the server is a normal condition — a player on a train.
|
|
22
|
+
* The batch is retried with a growing delay, and giving up on the *attempt* is never giving up
|
|
23
|
+
* on the *data*: the changes stay queued and go out with the next batch.
|
|
24
|
+
* 3. **A status.** Failure surfaces as something the caller can read, never a throw. A game
|
|
25
|
+
* showing "saved" over a queue that has been failing for ten minutes is worse than either a
|
|
26
|
+
* crash or an honest indicator, and it is what fire-and-forget produces by construction.
|
|
27
|
+
*
|
|
28
|
+
* **What it costs.** A write is durable *later*, not now, and a player who closes the tab inside
|
|
29
|
+
* the flush delay loses it. `flush()` is the answer, called from whatever the consumer's platform
|
|
30
|
+
* gives it — `visibilitychange`, a shell's close hook, a menu's exit — and the engine does not
|
|
31
|
+
* register that listener itself, because a DOM listener is a decision about the page rather than
|
|
32
|
+
* about saving. **What would make this wrong** is a consumer needing a write acknowledged before
|
|
33
|
+
* it acts on it, and the honest answer then is `await flush()` at that one site rather than an
|
|
34
|
+
* asynchronous surface everywhere.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* The asynchronous side, which the consumer implements.
|
|
38
|
+
*
|
|
39
|
+
* **`save` takes a batch rather than one key**, because a network backend wants one round trip for
|
|
40
|
+
* a screen's worth of changes and a per-key interface makes that impossible to build on top. A
|
|
41
|
+
* consumer whose API is per-key loops inside `save`; a consumer whose API is a document writes one
|
|
42
|
+
* request. The reverse adaptation cannot be done at all.
|
|
43
|
+
*/
|
|
44
|
+
export interface SaveBackend {
|
|
45
|
+
/** Everything this backend holds, read once before the first frame. */
|
|
46
|
+
load(): Promise<Iterable<readonly [string, string]>>;
|
|
47
|
+
/**
|
|
48
|
+
* Apply a batch. A `null` value is a removal, so one call carries both kinds of change.
|
|
49
|
+
*
|
|
50
|
+
* Reject to have the batch retried. Resolving is a promise that it landed: a backend that
|
|
51
|
+
* resolves optimistically turns this store's status into a decoration.
|
|
52
|
+
*/
|
|
53
|
+
save(changes: ReadonlyMap<string, string | null>): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The delay, taken as a capability rather than reached for.
|
|
57
|
+
*
|
|
58
|
+
* The same rule `KeyValueStore` itself follows: nothing here may assume a browser origin, and a
|
|
59
|
+
* native shell or a test supplies its own. A platform with no timer at all still works — nothing
|
|
60
|
+
* is ever armed, and the consumer drives `flush()`.
|
|
61
|
+
*/
|
|
62
|
+
export interface SaveTimer {
|
|
63
|
+
schedule(callback: () => void, delayMs: number): number;
|
|
64
|
+
cancel(handle: number): void;
|
|
65
|
+
}
|
|
66
|
+
/** What the queue is doing, for an indicator a player can read. */
|
|
67
|
+
export type SaveStatus = 'idle' | 'pending' | 'saving' | 'failed';
|
|
68
|
+
export interface RemoteSaveOptions {
|
|
69
|
+
/** The quiet period a burst of writes is collected over, in milliseconds. Default 250. */
|
|
70
|
+
readonly flushDelayMs?: number;
|
|
71
|
+
/** How many times one batch is attempted before the status goes to `failed`. Default 3. */
|
|
72
|
+
readonly maxAttempts?: number;
|
|
73
|
+
/** The first retry delay, doubled at each further attempt. Default 500. */
|
|
74
|
+
readonly retryDelayMs?: number;
|
|
75
|
+
}
|
|
76
|
+
/** The global timer where there is one, and a timer that never fires where there is not. */
|
|
77
|
+
export declare function defaultSaveTimer(): SaveTimer;
|
|
78
|
+
export declare class RemoteSaveStore implements KeyValueStore {
|
|
79
|
+
private readonly backend;
|
|
80
|
+
private readonly timer;
|
|
81
|
+
/** Everything the backend held at boot, plus everything this session has written. */
|
|
82
|
+
private readonly cache;
|
|
83
|
+
/** Changes waiting to go out. Claimed once and swapped with `inFlight`, never rebuilt. */
|
|
84
|
+
private queued;
|
|
85
|
+
/** The batch currently being sent. Swapped rather than copied, so a flush allocates nothing. */
|
|
86
|
+
private inFlight;
|
|
87
|
+
private readonly listeners;
|
|
88
|
+
private loadedValue;
|
|
89
|
+
private warnedUnloaded;
|
|
90
|
+
private statusValue;
|
|
91
|
+
private lastErrorValue;
|
|
92
|
+
private handle;
|
|
93
|
+
private attempt;
|
|
94
|
+
private current;
|
|
95
|
+
private readonly flushDelayMs;
|
|
96
|
+
private readonly maxAttempts;
|
|
97
|
+
private readonly retryDelayMs;
|
|
98
|
+
constructor(backend: SaveBackend, timer?: SaveTimer, options?: RemoteSaveOptions);
|
|
99
|
+
/**
|
|
100
|
+
* Fill the cache from the backend. Await this **before the first frame**.
|
|
101
|
+
*
|
|
102
|
+
* Answers whether it worked rather than rejecting, because a rejected promise nobody caught is
|
|
103
|
+
* an unhandled rejection during boot and a store that cannot load is a store that still has to
|
|
104
|
+
* serve defaults. A failure also says so on the console once: a consumer that ignores both the
|
|
105
|
+
* answer and the status boots on defaults and overwrites the player's real settings with them on
|
|
106
|
+
* the first write, which is the one outcome worse than not loading.
|
|
107
|
+
*/
|
|
108
|
+
load(): Promise<boolean>;
|
|
109
|
+
/** Whether `load` has completed, either way. */
|
|
110
|
+
get loaded(): boolean;
|
|
111
|
+
get status(): SaveStatus;
|
|
112
|
+
/** How many keys are waiting to be sent, counting a batch that failed and came back. */
|
|
113
|
+
get pending(): number;
|
|
114
|
+
/** The last failure's message, cleared by the next batch that lands. */
|
|
115
|
+
get lastError(): string | null;
|
|
116
|
+
/** Told when the status changes, and only when it changes. Returns the unsubscribe. */
|
|
117
|
+
onStatusChange(listener: (status: SaveStatus) => void): () => void;
|
|
118
|
+
read(key: string): string | null;
|
|
119
|
+
write(key: string, value: string): void;
|
|
120
|
+
remove(key: string): void;
|
|
121
|
+
/**
|
|
122
|
+
* Send everything queued now, and resolve when that attempt has settled.
|
|
123
|
+
*
|
|
124
|
+
* For a consumer leaving the page. It never rejects: read `status` afterwards to find out
|
|
125
|
+
* whether it landed. A batch already in flight is awaited first, so two flushes cannot overlap.
|
|
126
|
+
*/
|
|
127
|
+
flush(): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Throw away everything waiting to be sent.
|
|
130
|
+
*
|
|
131
|
+
* The escape hatch that makes "a failed batch is kept forever" acceptable: a consumer that has
|
|
132
|
+
* decided the queue is stale — a player signing out, a save slot deleted — says so, rather than
|
|
133
|
+
* this store guessing after some number of failures. The cache is untouched, so reads still
|
|
134
|
+
* answer what the session wrote.
|
|
135
|
+
*/
|
|
136
|
+
discardPending(): void;
|
|
137
|
+
/**
|
|
138
|
+
* One attempt at the queued batch. **Never rejects**, because it is reachable from a timer and
|
|
139
|
+
* from a frame, and the house rule is that neither throws.
|
|
140
|
+
*/
|
|
141
|
+
private send;
|
|
142
|
+
private attemptSave;
|
|
143
|
+
/**
|
|
144
|
+
* Put a failed batch back **under** whatever arrived while it was away.
|
|
145
|
+
*
|
|
146
|
+
* The direction is the whole of it. A player dragging a slider writes 0.1, the batch leaves, they
|
|
147
|
+
* drag to 0.9, the batch fails — and a merge that overwrote would send 0.1 and silently undo the
|
|
148
|
+
* drag. Newer always wins, which is why this checks before it sets.
|
|
149
|
+
*/
|
|
150
|
+
private returnToQueue;
|
|
151
|
+
private arm;
|
|
152
|
+
private disarm;
|
|
153
|
+
private setStatus;
|
|
154
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/** The global timer where there is one, and a timer that never fires where there is not. */
|
|
2
|
+
export function defaultSaveTimer() {
|
|
3
|
+
const host = globalThis;
|
|
4
|
+
if (typeof host.setTimeout !== 'function') {
|
|
5
|
+
/* Not a silent no-op: `flush()` still sends, so a platform with no timer saves on demand and
|
|
6
|
+
never in the background. The alternative — throwing at construction — would refuse a store
|
|
7
|
+
that works, on a platform this engine has no business assuming anything about. */
|
|
8
|
+
return { schedule: () => 0, cancel: () => { } };
|
|
9
|
+
}
|
|
10
|
+
const set = host.setTimeout.bind(host);
|
|
11
|
+
const clear = host.clearTimeout?.bind(host);
|
|
12
|
+
let next = 1;
|
|
13
|
+
const handles = new Map();
|
|
14
|
+
return {
|
|
15
|
+
schedule(callback, delayMs) {
|
|
16
|
+
const id = next++;
|
|
17
|
+
handles.set(id, set(callback, delayMs));
|
|
18
|
+
return id;
|
|
19
|
+
},
|
|
20
|
+
cancel(handle) {
|
|
21
|
+
const native = handles.get(handle);
|
|
22
|
+
handles.delete(handle);
|
|
23
|
+
if (native !== undefined)
|
|
24
|
+
clear?.(native);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export class RemoteSaveStore {
|
|
29
|
+
backend;
|
|
30
|
+
timer;
|
|
31
|
+
/** Everything the backend held at boot, plus everything this session has written. */
|
|
32
|
+
cache = new Map();
|
|
33
|
+
/** Changes waiting to go out. Claimed once and swapped with `inFlight`, never rebuilt. */
|
|
34
|
+
queued = new Map();
|
|
35
|
+
/** The batch currently being sent. Swapped rather than copied, so a flush allocates nothing. */
|
|
36
|
+
inFlight = new Map();
|
|
37
|
+
listeners = [];
|
|
38
|
+
loadedValue = false;
|
|
39
|
+
warnedUnloaded = false;
|
|
40
|
+
statusValue = 'idle';
|
|
41
|
+
lastErrorValue = null;
|
|
42
|
+
handle = 0;
|
|
43
|
+
attempt = 0;
|
|
44
|
+
current = null;
|
|
45
|
+
flushDelayMs;
|
|
46
|
+
maxAttempts;
|
|
47
|
+
retryDelayMs;
|
|
48
|
+
constructor(backend, timer = defaultSaveTimer(), options = {}) {
|
|
49
|
+
this.backend = backend;
|
|
50
|
+
this.timer = timer;
|
|
51
|
+
this.flushDelayMs = options.flushDelayMs ?? 250;
|
|
52
|
+
this.maxAttempts = options.maxAttempts ?? 3;
|
|
53
|
+
this.retryDelayMs = options.retryDelayMs ?? 500;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Fill the cache from the backend. Await this **before the first frame**.
|
|
57
|
+
*
|
|
58
|
+
* Answers whether it worked rather than rejecting, because a rejected promise nobody caught is
|
|
59
|
+
* an unhandled rejection during boot and a store that cannot load is a store that still has to
|
|
60
|
+
* serve defaults. A failure also says so on the console once: a consumer that ignores both the
|
|
61
|
+
* answer and the status boots on defaults and overwrites the player's real settings with them on
|
|
62
|
+
* the first write, which is the one outcome worse than not loading.
|
|
63
|
+
*/
|
|
64
|
+
async load() {
|
|
65
|
+
try {
|
|
66
|
+
const entries = await this.backend.load();
|
|
67
|
+
for (const [key, value] of entries)
|
|
68
|
+
this.cache.set(key, value);
|
|
69
|
+
this.loadedValue = true;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.loadedValue = true;
|
|
74
|
+
this.lastErrorValue = messageOf(error);
|
|
75
|
+
this.setStatus('failed');
|
|
76
|
+
console.warn(`[driftengine] the save backend could not be read: ${this.lastErrorValue}. ` +
|
|
77
|
+
'The game will boot on defaults, and the first write will overwrite what is stored. ' +
|
|
78
|
+
'Read `status` before writing if that matters.');
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Whether `load` has completed, either way. */
|
|
83
|
+
get loaded() {
|
|
84
|
+
return this.loadedValue;
|
|
85
|
+
}
|
|
86
|
+
get status() {
|
|
87
|
+
return this.statusValue;
|
|
88
|
+
}
|
|
89
|
+
/** How many keys are waiting to be sent, counting a batch that failed and came back. */
|
|
90
|
+
get pending() {
|
|
91
|
+
return this.queued.size + this.inFlight.size;
|
|
92
|
+
}
|
|
93
|
+
/** The last failure's message, cleared by the next batch that lands. */
|
|
94
|
+
get lastError() {
|
|
95
|
+
return this.lastErrorValue;
|
|
96
|
+
}
|
|
97
|
+
/** Told when the status changes, and only when it changes. Returns the unsubscribe. */
|
|
98
|
+
onStatusChange(listener) {
|
|
99
|
+
this.listeners.push(listener);
|
|
100
|
+
return () => {
|
|
101
|
+
const at = this.listeners.indexOf(listener);
|
|
102
|
+
if (at >= 0)
|
|
103
|
+
this.listeners.splice(at, 1);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
read(key) {
|
|
107
|
+
if (!this.loadedValue && !this.warnedUnloaded) {
|
|
108
|
+
this.warnedUnloaded = true;
|
|
109
|
+
console.warn('[driftengine] a remote save store was read before `load()` resolved, so it answered null. ' +
|
|
110
|
+
'Await `load()` before the first frame, or the game boots on defaults it will then save.');
|
|
111
|
+
}
|
|
112
|
+
return this.cache.get(key) ?? null;
|
|
113
|
+
}
|
|
114
|
+
write(key, value) {
|
|
115
|
+
this.cache.set(key, value);
|
|
116
|
+
this.queued.set(key, value);
|
|
117
|
+
this.arm(this.flushDelayMs);
|
|
118
|
+
}
|
|
119
|
+
remove(key) {
|
|
120
|
+
this.cache.delete(key);
|
|
121
|
+
this.queued.set(key, null);
|
|
122
|
+
this.arm(this.flushDelayMs);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Send everything queued now, and resolve when that attempt has settled.
|
|
126
|
+
*
|
|
127
|
+
* For a consumer leaving the page. It never rejects: read `status` afterwards to find out
|
|
128
|
+
* whether it landed. A batch already in flight is awaited first, so two flushes cannot overlap.
|
|
129
|
+
*/
|
|
130
|
+
async flush() {
|
|
131
|
+
this.disarm();
|
|
132
|
+
if (this.current !== null)
|
|
133
|
+
await this.current;
|
|
134
|
+
if (this.queued.size === 0)
|
|
135
|
+
return;
|
|
136
|
+
/* A deliberate flush starts the attempt count over: the caller is asking now, and a previous
|
|
137
|
+
exhaustion should not make this call a no-op. */
|
|
138
|
+
this.attempt = 0;
|
|
139
|
+
await this.send();
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Throw away everything waiting to be sent.
|
|
143
|
+
*
|
|
144
|
+
* The escape hatch that makes "a failed batch is kept forever" acceptable: a consumer that has
|
|
145
|
+
* decided the queue is stale — a player signing out, a save slot deleted — says so, rather than
|
|
146
|
+
* this store guessing after some number of failures. The cache is untouched, so reads still
|
|
147
|
+
* answer what the session wrote.
|
|
148
|
+
*/
|
|
149
|
+
discardPending() {
|
|
150
|
+
this.disarm();
|
|
151
|
+
this.queued.clear();
|
|
152
|
+
this.inFlight.clear();
|
|
153
|
+
this.setStatus(this.statusValue === 'saving' ? 'saving' : 'idle');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* One attempt at the queued batch. **Never rejects**, because it is reachable from a timer and
|
|
157
|
+
* from a frame, and the house rule is that neither throws.
|
|
158
|
+
*/
|
|
159
|
+
async send() {
|
|
160
|
+
if (this.current !== null)
|
|
161
|
+
return this.current;
|
|
162
|
+
/* Swap rather than copy: the queue that was accumulating becomes the batch, and the empty one
|
|
163
|
+
that just went out becomes the queue. A write landing during the send goes into the new
|
|
164
|
+
queue and belongs to the next batch. */
|
|
165
|
+
const outgoing = this.queued;
|
|
166
|
+
this.queued = this.inFlight;
|
|
167
|
+
this.inFlight = outgoing;
|
|
168
|
+
this.attempt += 1;
|
|
169
|
+
this.setStatus('saving');
|
|
170
|
+
const run = this.attemptSave();
|
|
171
|
+
this.current = run;
|
|
172
|
+
try {
|
|
173
|
+
await run;
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
this.current = null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async attemptSave() {
|
|
180
|
+
try {
|
|
181
|
+
/* Awaited inside the `try` so a backend that throws synchronously reads the same as one that
|
|
182
|
+
rejects — they are the same condition to a caller, and only one of them is catchable by a
|
|
183
|
+
plain `.catch`. */
|
|
184
|
+
await this.backend.save(this.inFlight);
|
|
185
|
+
this.inFlight.clear();
|
|
186
|
+
this.attempt = 0;
|
|
187
|
+
this.lastErrorValue = null;
|
|
188
|
+
if (this.queued.size > 0) {
|
|
189
|
+
this.setStatus('pending');
|
|
190
|
+
this.arm(this.flushDelayMs);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.setStatus('idle');
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.lastErrorValue = messageOf(error);
|
|
197
|
+
this.returnToQueue();
|
|
198
|
+
if (this.attempt >= this.maxAttempts) {
|
|
199
|
+
/* Reset, so a later write or an explicit flush starts a fresh run of attempts rather than
|
|
200
|
+
being refused by a counter left at the ceiling. */
|
|
201
|
+
this.attempt = 0;
|
|
202
|
+
this.setStatus('failed');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this.setStatus('pending');
|
|
206
|
+
// determinism: build-time — a network retry backoff, which is wall-clock and not simulation
|
|
207
|
+
this.arm(this.retryDelayMs * 2 ** (this.attempt - 1));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Put a failed batch back **under** whatever arrived while it was away.
|
|
212
|
+
*
|
|
213
|
+
* The direction is the whole of it. A player dragging a slider writes 0.1, the batch leaves, they
|
|
214
|
+
* drag to 0.9, the batch fails — and a merge that overwrote would send 0.1 and silently undo the
|
|
215
|
+
* drag. Newer always wins, which is why this checks before it sets.
|
|
216
|
+
*/
|
|
217
|
+
returnToQueue() {
|
|
218
|
+
for (const [key, value] of this.inFlight) {
|
|
219
|
+
if (!this.queued.has(key))
|
|
220
|
+
this.queued.set(key, value);
|
|
221
|
+
}
|
|
222
|
+
this.inFlight.clear();
|
|
223
|
+
}
|
|
224
|
+
arm(delayMs) {
|
|
225
|
+
if (this.statusValue !== 'saving')
|
|
226
|
+
this.setStatus('pending');
|
|
227
|
+
this.disarm();
|
|
228
|
+
this.handle = this.timer.schedule(() => {
|
|
229
|
+
this.handle = 0;
|
|
230
|
+
void this.send();
|
|
231
|
+
}, delayMs);
|
|
232
|
+
}
|
|
233
|
+
disarm() {
|
|
234
|
+
if (this.handle === 0)
|
|
235
|
+
return;
|
|
236
|
+
this.timer.cancel(this.handle);
|
|
237
|
+
this.handle = 0;
|
|
238
|
+
}
|
|
239
|
+
setStatus(status) {
|
|
240
|
+
if (status === this.statusValue)
|
|
241
|
+
return;
|
|
242
|
+
this.statusValue = status;
|
|
243
|
+
for (let i = 0; i < this.listeners.length; i++)
|
|
244
|
+
this.listeners[i]?.(status);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function messageOf(error) {
|
|
248
|
+
return error instanceof Error ? error.message : String(error);
|
|
249
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded PRNG (mulberry32). The only randomness source allowed in simulation
|
|
3
|
+
* and world generation — `Math.random()` is banned there (see AGENTS.md).
|
|
4
|
+
* Same seed ⇒ same sequence on every platform.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Deterministically choose one item from a list.
|
|
8
|
+
*
|
|
9
|
+
* The seed is hashed before the modulo rather than used raw. `seed % length`
|
|
10
|
+
* walks the list in order, so consecutive seeds — day numbers, level indices —
|
|
11
|
+
* produce a visible cycle; multiplying by the golden-ratio constant first
|
|
12
|
+
* scatters them, which is the difference between "today's track" feeling picked
|
|
13
|
+
* and feeling like a rota.
|
|
14
|
+
*/
|
|
15
|
+
export declare function pickBySeed<T>(seed: number, items: readonly T[]): T | null;
|
|
16
|
+
/**
|
|
17
|
+
* A single well-mixed value in `[0, 1)` from one integer seed.
|
|
18
|
+
*
|
|
19
|
+
* `mulberry32`'s mixer without the stream: the same avalanche, applied once, for the
|
|
20
|
+
* very common case of "one deterministic value per index" — a per-particle jitter, a
|
|
21
|
+
* per-node displacement — where allocating a generator per lookup is absurd.
|
|
22
|
+
*
|
|
23
|
+
* It exists because the obvious alternative is wrong in a way that is hard to see.
|
|
24
|
+
* `fract(sin(x) * 43758.5453)` is the reflex GPU hash and it degrades badly on the CPU
|
|
25
|
+
* for large `x`: `sin` of a number in the millions has lost most of its precision to
|
|
26
|
+
* argument reduction, so nearby seeds correlate and *whole families of values collapse
|
|
27
|
+
* onto each other*. That is what an effect seeded from a tick count hands it. Measured
|
|
28
|
+
* as lightning whose every bolt came out the same shape however much variation the
|
|
29
|
+
* caller thought it was asking for: still visibly deterministic where the caller
|
|
30
|
+
* expected a fresh shape on every strike.
|
|
31
|
+
*
|
|
32
|
+
* Integer mixing has no such failure: every bit of the input reaches every bit of the
|
|
33
|
+
* output, at any magnitude, and it is bit-identical on every platform, which the
|
|
34
|
+
* replay contract requires.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hashToUnit(seed: number): number;
|
|
37
|
+
export declare function mulberry32(seed: number): () => number;
|
|
38
|
+
/**
|
|
39
|
+
* A generator whose position can be read and written.
|
|
40
|
+
*
|
|
41
|
+
* **The closure above cannot be rewound, and a resimulation has to be.** A rollback loop restores
|
|
42
|
+
* a past tick and steps forward again; anything the replayed ticks draw from a generator must draw
|
|
43
|
+
* the same numbers they drew the first time, or the replay produces a different world from the run
|
|
44
|
+
* it is replaying. `mulberry32` keeps its position in a closed-over variable, which is the right
|
|
45
|
+
* shape for every other caller and unreachable for this one.
|
|
46
|
+
*
|
|
47
|
+
* **The whole position is one int32**, which is why this is an interface over a number and not a
|
|
48
|
+
* buffer: mulberry32 mixes a counter and holds nothing else. A `save()` is a number a caller can
|
|
49
|
+
* put in a snapshot beside the rest of a tick's state, and comparing two of them is `===`.
|
|
50
|
+
*
|
|
51
|
+
* The sequence is `mulberry32`'s, unchanged and asserted against it. **That is the promise, not an
|
|
52
|
+
* implementation note**: `AGENTS.md` makes the seeded sequence a contract about stored replays and
|
|
53
|
+
* ghosts, so a second generator that drifted from the first by an increment would invalidate every
|
|
54
|
+
* one of them while passing every test that only read this file.
|
|
55
|
+
*/
|
|
56
|
+
export interface SavableRandom {
|
|
57
|
+
/** The next value in `[0, 1)`. */
|
|
58
|
+
next(): number;
|
|
59
|
+
/** The position, as one integer. */
|
|
60
|
+
save(): number;
|
|
61
|
+
/** Resume from a position `save` returned. */
|
|
62
|
+
restore(state: number): void;
|
|
63
|
+
}
|
|
64
|
+
export declare function savableMulberry32(seed: number): SavableRandom;
|