@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,347 @@
|
|
|
1
|
+
import type { KeyValueStore } from './storage.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A save that lives somewhere the engine cannot read synchronously — a server, a native shell, a
|
|
5
|
+
* sandbox — behind the synchronous seam every consumer already speaks.
|
|
6
|
+
*
|
|
7
|
+
* **A write-behind queue rather than a second interface, and that is the decision this module
|
|
8
|
+
* exists to record.** `KeyValueStore` is synchronous because preferences are read during *boot*,
|
|
9
|
+
* before the first frame: an await there means a frame drawn with the wrong settings and then
|
|
10
|
+
* corrected, which is a visible flicker on every load. So the choice was between widening the seam
|
|
11
|
+
* to an asynchronous twin, which every consumer and every store integration would then have to
|
|
12
|
+
* learn, or hydrating a cache once and draining writes behind it. Both shipped implementations of
|
|
13
|
+
* the seam that are already asynchronous underneath — a file the shell owns, and a cloud store —
|
|
14
|
+
* chose the second, independently, and neither needed the interface widened. This is that
|
|
15
|
+
* arrangement written once, with the three things a hand-rolled version leaves out.
|
|
16
|
+
*
|
|
17
|
+
* **The three:**
|
|
18
|
+
*
|
|
19
|
+
* 1. **Coalescing.** A settings slider writes on every drag frame. One request per write is sixty
|
|
20
|
+
* requests for one decision, and it is the reason a naive fire-and-forget backend gets rate
|
|
21
|
+
* limited. Writes accumulate into a batch, one entry per key, sent after a quiet period.
|
|
22
|
+
* 2. **Retry.** A save that cannot reach the server is a normal condition — a player on a train.
|
|
23
|
+
* The batch is retried with a growing delay, and giving up on the *attempt* is never giving up
|
|
24
|
+
* on the *data*: the changes stay queued and go out with the next batch.
|
|
25
|
+
* 3. **A status.** Failure surfaces as something the caller can read, never a throw. A game
|
|
26
|
+
* showing "saved" over a queue that has been failing for ten minutes is worse than either a
|
|
27
|
+
* crash or an honest indicator, and it is what fire-and-forget produces by construction.
|
|
28
|
+
*
|
|
29
|
+
* **What it costs.** A write is durable *later*, not now, and a player who closes the tab inside
|
|
30
|
+
* the flush delay loses it. `flush()` is the answer, called from whatever the consumer's platform
|
|
31
|
+
* gives it — `visibilitychange`, a shell's close hook, a menu's exit — and the engine does not
|
|
32
|
+
* register that listener itself, because a DOM listener is a decision about the page rather than
|
|
33
|
+
* about saving. **What would make this wrong** is a consumer needing a write acknowledged before
|
|
34
|
+
* it acts on it, and the honest answer then is `await flush()` at that one site rather than an
|
|
35
|
+
* asynchronous surface everywhere.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The asynchronous side, which the consumer implements.
|
|
40
|
+
*
|
|
41
|
+
* **`save` takes a batch rather than one key**, because a network backend wants one round trip for
|
|
42
|
+
* a screen's worth of changes and a per-key interface makes that impossible to build on top. A
|
|
43
|
+
* consumer whose API is per-key loops inside `save`; a consumer whose API is a document writes one
|
|
44
|
+
* request. The reverse adaptation cannot be done at all.
|
|
45
|
+
*/
|
|
46
|
+
export interface SaveBackend {
|
|
47
|
+
/** Everything this backend holds, read once before the first frame. */
|
|
48
|
+
load(): Promise<Iterable<readonly [string, string]>>;
|
|
49
|
+
/**
|
|
50
|
+
* Apply a batch. A `null` value is a removal, so one call carries both kinds of change.
|
|
51
|
+
*
|
|
52
|
+
* Reject to have the batch retried. Resolving is a promise that it landed: a backend that
|
|
53
|
+
* resolves optimistically turns this store's status into a decoration.
|
|
54
|
+
*/
|
|
55
|
+
save(changes: ReadonlyMap<string, string | null>): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The delay, taken as a capability rather than reached for.
|
|
60
|
+
*
|
|
61
|
+
* The same rule `KeyValueStore` itself follows: nothing here may assume a browser origin, and a
|
|
62
|
+
* native shell or a test supplies its own. A platform with no timer at all still works — nothing
|
|
63
|
+
* is ever armed, and the consumer drives `flush()`.
|
|
64
|
+
*/
|
|
65
|
+
export interface SaveTimer {
|
|
66
|
+
schedule(callback: () => void, delayMs: number): number;
|
|
67
|
+
cancel(handle: number): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** What the queue is doing, for an indicator a player can read. */
|
|
71
|
+
export type SaveStatus = 'idle' | 'pending' | 'saving' | 'failed';
|
|
72
|
+
|
|
73
|
+
export interface RemoteSaveOptions {
|
|
74
|
+
/** The quiet period a burst of writes is collected over, in milliseconds. Default 250. */
|
|
75
|
+
readonly flushDelayMs?: number;
|
|
76
|
+
/** How many times one batch is attempted before the status goes to `failed`. Default 3. */
|
|
77
|
+
readonly maxAttempts?: number;
|
|
78
|
+
/** The first retry delay, doubled at each further attempt. Default 500. */
|
|
79
|
+
readonly retryDelayMs?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The global timer where there is one, and a timer that never fires where there is not. */
|
|
83
|
+
export function defaultSaveTimer(): SaveTimer {
|
|
84
|
+
const host = globalThis as {
|
|
85
|
+
setTimeout?: (fn: () => void, ms: number) => unknown;
|
|
86
|
+
clearTimeout?: (handle: unknown) => void;
|
|
87
|
+
};
|
|
88
|
+
if (typeof host.setTimeout !== 'function') {
|
|
89
|
+
/* Not a silent no-op: `flush()` still sends, so a platform with no timer saves on demand and
|
|
90
|
+
never in the background. The alternative — throwing at construction — would refuse a store
|
|
91
|
+
that works, on a platform this engine has no business assuming anything about. */
|
|
92
|
+
return { schedule: () => 0, cancel: () => {} };
|
|
93
|
+
}
|
|
94
|
+
const set = host.setTimeout.bind(host);
|
|
95
|
+
const clear = host.clearTimeout?.bind(host);
|
|
96
|
+
let next = 1;
|
|
97
|
+
const handles = new Map<number, unknown>();
|
|
98
|
+
return {
|
|
99
|
+
schedule(callback, delayMs) {
|
|
100
|
+
const id = next++;
|
|
101
|
+
handles.set(id, set(callback, delayMs));
|
|
102
|
+
return id;
|
|
103
|
+
},
|
|
104
|
+
cancel(handle) {
|
|
105
|
+
const native = handles.get(handle);
|
|
106
|
+
handles.delete(handle);
|
|
107
|
+
if (native !== undefined) clear?.(native);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class RemoteSaveStore implements KeyValueStore {
|
|
113
|
+
/** Everything the backend held at boot, plus everything this session has written. */
|
|
114
|
+
private readonly cache = new Map<string, string>();
|
|
115
|
+
/** Changes waiting to go out. Claimed once and swapped with `inFlight`, never rebuilt. */
|
|
116
|
+
private queued = new Map<string, string | null>();
|
|
117
|
+
/** The batch currently being sent. Swapped rather than copied, so a flush allocates nothing. */
|
|
118
|
+
private inFlight = new Map<string, string | null>();
|
|
119
|
+
private readonly listeners: ((status: SaveStatus) => void)[] = [];
|
|
120
|
+
|
|
121
|
+
private loadedValue = false;
|
|
122
|
+
private warnedUnloaded = false;
|
|
123
|
+
private statusValue: SaveStatus = 'idle';
|
|
124
|
+
private lastErrorValue: string | null = null;
|
|
125
|
+
private handle = 0;
|
|
126
|
+
private attempt = 0;
|
|
127
|
+
private current: Promise<void> | null = null;
|
|
128
|
+
|
|
129
|
+
private readonly flushDelayMs: number;
|
|
130
|
+
private readonly maxAttempts: number;
|
|
131
|
+
private readonly retryDelayMs: number;
|
|
132
|
+
|
|
133
|
+
constructor(
|
|
134
|
+
private readonly backend: SaveBackend,
|
|
135
|
+
private readonly timer: SaveTimer = defaultSaveTimer(),
|
|
136
|
+
options: RemoteSaveOptions = {},
|
|
137
|
+
) {
|
|
138
|
+
this.flushDelayMs = options.flushDelayMs ?? 250;
|
|
139
|
+
this.maxAttempts = options.maxAttempts ?? 3;
|
|
140
|
+
this.retryDelayMs = options.retryDelayMs ?? 500;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Fill the cache from the backend. Await this **before the first frame**.
|
|
145
|
+
*
|
|
146
|
+
* Answers whether it worked rather than rejecting, because a rejected promise nobody caught is
|
|
147
|
+
* an unhandled rejection during boot and a store that cannot load is a store that still has to
|
|
148
|
+
* serve defaults. A failure also says so on the console once: a consumer that ignores both the
|
|
149
|
+
* answer and the status boots on defaults and overwrites the player's real settings with them on
|
|
150
|
+
* the first write, which is the one outcome worse than not loading.
|
|
151
|
+
*/
|
|
152
|
+
async load(): Promise<boolean> {
|
|
153
|
+
try {
|
|
154
|
+
const entries = await this.backend.load();
|
|
155
|
+
for (const [key, value] of entries) this.cache.set(key, value);
|
|
156
|
+
this.loadedValue = true;
|
|
157
|
+
return true;
|
|
158
|
+
} catch (error) {
|
|
159
|
+
this.loadedValue = true;
|
|
160
|
+
this.lastErrorValue = messageOf(error);
|
|
161
|
+
this.setStatus('failed');
|
|
162
|
+
console.warn(
|
|
163
|
+
`[driftengine] the save backend could not be read: ${this.lastErrorValue}. ` +
|
|
164
|
+
'The game will boot on defaults, and the first write will overwrite what is stored. ' +
|
|
165
|
+
'Read `status` before writing if that matters.',
|
|
166
|
+
);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Whether `load` has completed, either way. */
|
|
172
|
+
get loaded(): boolean {
|
|
173
|
+
return this.loadedValue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
get status(): SaveStatus {
|
|
177
|
+
return this.statusValue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** How many keys are waiting to be sent, counting a batch that failed and came back. */
|
|
181
|
+
get pending(): number {
|
|
182
|
+
return this.queued.size + this.inFlight.size;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** The last failure's message, cleared by the next batch that lands. */
|
|
186
|
+
get lastError(): string | null {
|
|
187
|
+
return this.lastErrorValue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Told when the status changes, and only when it changes. Returns the unsubscribe. */
|
|
191
|
+
onStatusChange(listener: (status: SaveStatus) => void): () => void {
|
|
192
|
+
this.listeners.push(listener);
|
|
193
|
+
return () => {
|
|
194
|
+
const at = this.listeners.indexOf(listener);
|
|
195
|
+
if (at >= 0) this.listeners.splice(at, 1);
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
read(key: string): string | null {
|
|
200
|
+
if (!this.loadedValue && !this.warnedUnloaded) {
|
|
201
|
+
this.warnedUnloaded = true;
|
|
202
|
+
console.warn(
|
|
203
|
+
'[driftengine] a remote save store was read before `load()` resolved, so it answered null. ' +
|
|
204
|
+
'Await `load()` before the first frame, or the game boots on defaults it will then save.',
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return this.cache.get(key) ?? null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
write(key: string, value: string): void {
|
|
211
|
+
this.cache.set(key, value);
|
|
212
|
+
this.queued.set(key, value);
|
|
213
|
+
this.arm(this.flushDelayMs);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
remove(key: string): void {
|
|
217
|
+
this.cache.delete(key);
|
|
218
|
+
this.queued.set(key, null);
|
|
219
|
+
this.arm(this.flushDelayMs);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Send everything queued now, and resolve when that attempt has settled.
|
|
224
|
+
*
|
|
225
|
+
* For a consumer leaving the page. It never rejects: read `status` afterwards to find out
|
|
226
|
+
* whether it landed. A batch already in flight is awaited first, so two flushes cannot overlap.
|
|
227
|
+
*/
|
|
228
|
+
async flush(): Promise<void> {
|
|
229
|
+
this.disarm();
|
|
230
|
+
if (this.current !== null) await this.current;
|
|
231
|
+
if (this.queued.size === 0) return;
|
|
232
|
+
/* A deliberate flush starts the attempt count over: the caller is asking now, and a previous
|
|
233
|
+
exhaustion should not make this call a no-op. */
|
|
234
|
+
this.attempt = 0;
|
|
235
|
+
await this.send();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Throw away everything waiting to be sent.
|
|
240
|
+
*
|
|
241
|
+
* The escape hatch that makes "a failed batch is kept forever" acceptable: a consumer that has
|
|
242
|
+
* decided the queue is stale — a player signing out, a save slot deleted — says so, rather than
|
|
243
|
+
* this store guessing after some number of failures. The cache is untouched, so reads still
|
|
244
|
+
* answer what the session wrote.
|
|
245
|
+
*/
|
|
246
|
+
discardPending(): void {
|
|
247
|
+
this.disarm();
|
|
248
|
+
this.queued.clear();
|
|
249
|
+
this.inFlight.clear();
|
|
250
|
+
this.setStatus(this.statusValue === 'saving' ? 'saving' : 'idle');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* One attempt at the queued batch. **Never rejects**, because it is reachable from a timer and
|
|
255
|
+
* from a frame, and the house rule is that neither throws.
|
|
256
|
+
*/
|
|
257
|
+
private async send(): Promise<void> {
|
|
258
|
+
if (this.current !== null) return this.current;
|
|
259
|
+
|
|
260
|
+
/* Swap rather than copy: the queue that was accumulating becomes the batch, and the empty one
|
|
261
|
+
that just went out becomes the queue. A write landing during the send goes into the new
|
|
262
|
+
queue and belongs to the next batch. */
|
|
263
|
+
const outgoing = this.queued;
|
|
264
|
+
this.queued = this.inFlight;
|
|
265
|
+
this.inFlight = outgoing;
|
|
266
|
+
this.attempt += 1;
|
|
267
|
+
this.setStatus('saving');
|
|
268
|
+
|
|
269
|
+
const run = this.attemptSave();
|
|
270
|
+
this.current = run;
|
|
271
|
+
try {
|
|
272
|
+
await run;
|
|
273
|
+
} finally {
|
|
274
|
+
this.current = null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private async attemptSave(): Promise<void> {
|
|
279
|
+
try {
|
|
280
|
+
/* Awaited inside the `try` so a backend that throws synchronously reads the same as one that
|
|
281
|
+
rejects — they are the same condition to a caller, and only one of them is catchable by a
|
|
282
|
+
plain `.catch`. */
|
|
283
|
+
await this.backend.save(this.inFlight);
|
|
284
|
+
this.inFlight.clear();
|
|
285
|
+
this.attempt = 0;
|
|
286
|
+
this.lastErrorValue = null;
|
|
287
|
+
if (this.queued.size > 0) {
|
|
288
|
+
this.setStatus('pending');
|
|
289
|
+
this.arm(this.flushDelayMs);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this.setStatus('idle');
|
|
293
|
+
} catch (error) {
|
|
294
|
+
this.lastErrorValue = messageOf(error);
|
|
295
|
+
this.returnToQueue();
|
|
296
|
+
if (this.attempt >= this.maxAttempts) {
|
|
297
|
+
/* Reset, so a later write or an explicit flush starts a fresh run of attempts rather than
|
|
298
|
+
being refused by a counter left at the ceiling. */
|
|
299
|
+
this.attempt = 0;
|
|
300
|
+
this.setStatus('failed');
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.setStatus('pending');
|
|
304
|
+
// determinism: build-time — a network retry backoff, which is wall-clock and not simulation
|
|
305
|
+
this.arm(this.retryDelayMs * 2 ** (this.attempt - 1));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Put a failed batch back **under** whatever arrived while it was away.
|
|
311
|
+
*
|
|
312
|
+
* The direction is the whole of it. A player dragging a slider writes 0.1, the batch leaves, they
|
|
313
|
+
* drag to 0.9, the batch fails — and a merge that overwrote would send 0.1 and silently undo the
|
|
314
|
+
* drag. Newer always wins, which is why this checks before it sets.
|
|
315
|
+
*/
|
|
316
|
+
private returnToQueue(): void {
|
|
317
|
+
for (const [key, value] of this.inFlight) {
|
|
318
|
+
if (!this.queued.has(key)) this.queued.set(key, value);
|
|
319
|
+
}
|
|
320
|
+
this.inFlight.clear();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private arm(delayMs: number): void {
|
|
324
|
+
if (this.statusValue !== 'saving') this.setStatus('pending');
|
|
325
|
+
this.disarm();
|
|
326
|
+
this.handle = this.timer.schedule(() => {
|
|
327
|
+
this.handle = 0;
|
|
328
|
+
void this.send();
|
|
329
|
+
}, delayMs);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
private disarm(): void {
|
|
333
|
+
if (this.handle === 0) return;
|
|
334
|
+
this.timer.cancel(this.handle);
|
|
335
|
+
this.handle = 0;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
private setStatus(status: SaveStatus): void {
|
|
339
|
+
if (status === this.statusValue) return;
|
|
340
|
+
this.statusValue = status;
|
|
341
|
+
for (let i = 0; i < this.listeners.length; i++) this.listeners[i]?.(status);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function messageOf(error: unknown): string {
|
|
346
|
+
return error instanceof Error ? error.message : String(error);
|
|
347
|
+
}
|
package/src/core/rng.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
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 function pickBySeed<T>(seed: number, items: readonly T[]): T | null {
|
|
16
|
+
if (items.length === 0) return null;
|
|
17
|
+
const scrambled = Math.abs(Math.imul(seed | 0, 0x9e3779b1)) % items.length;
|
|
18
|
+
return items[scrambled] ?? null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A single well-mixed value in `[0, 1)` from one integer seed.
|
|
23
|
+
*
|
|
24
|
+
* `mulberry32`'s mixer without the stream: the same avalanche, applied once, for the
|
|
25
|
+
* very common case of "one deterministic value per index" — a per-particle jitter, a
|
|
26
|
+
* per-node displacement — where allocating a generator per lookup is absurd.
|
|
27
|
+
*
|
|
28
|
+
* It exists because the obvious alternative is wrong in a way that is hard to see.
|
|
29
|
+
* `fract(sin(x) * 43758.5453)` is the reflex GPU hash and it degrades badly on the CPU
|
|
30
|
+
* for large `x`: `sin` of a number in the millions has lost most of its precision to
|
|
31
|
+
* argument reduction, so nearby seeds correlate and *whole families of values collapse
|
|
32
|
+
* onto each other*. That is what an effect seeded from a tick count hands it. Measured
|
|
33
|
+
* as lightning whose every bolt came out the same shape however much variation the
|
|
34
|
+
* caller thought it was asking for: still visibly deterministic where the caller
|
|
35
|
+
* expected a fresh shape on every strike.
|
|
36
|
+
*
|
|
37
|
+
* Integer mixing has no such failure: every bit of the input reaches every bit of the
|
|
38
|
+
* output, at any magnitude, and it is bit-identical on every platform, which the
|
|
39
|
+
* replay contract requires.
|
|
40
|
+
*/
|
|
41
|
+
export function hashToUnit(seed: number): number {
|
|
42
|
+
let t = (seed | 0) + 0x6d2b79f5;
|
|
43
|
+
t = Math.imul(t ^ (t >>> 15), 1 | t);
|
|
44
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
45
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function mulberry32(seed: number): () => number {
|
|
49
|
+
let state = seed | 0;
|
|
50
|
+
return () => {
|
|
51
|
+
state = (state + 0x6d2b79f5) | 0;
|
|
52
|
+
let t = Math.imul(state ^ (state >>> 15), 1 | state);
|
|
53
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
54
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A generator whose position can be read and written.
|
|
60
|
+
*
|
|
61
|
+
* **The closure above cannot be rewound, and a resimulation has to be.** A rollback loop restores
|
|
62
|
+
* a past tick and steps forward again; anything the replayed ticks draw from a generator must draw
|
|
63
|
+
* the same numbers they drew the first time, or the replay produces a different world from the run
|
|
64
|
+
* it is replaying. `mulberry32` keeps its position in a closed-over variable, which is the right
|
|
65
|
+
* shape for every other caller and unreachable for this one.
|
|
66
|
+
*
|
|
67
|
+
* **The whole position is one int32**, which is why this is an interface over a number and not a
|
|
68
|
+
* buffer: mulberry32 mixes a counter and holds nothing else. A `save()` is a number a caller can
|
|
69
|
+
* put in a snapshot beside the rest of a tick's state, and comparing two of them is `===`.
|
|
70
|
+
*
|
|
71
|
+
* The sequence is `mulberry32`'s, unchanged and asserted against it. **That is the promise, not an
|
|
72
|
+
* implementation note**: `AGENTS.md` makes the seeded sequence a contract about stored replays and
|
|
73
|
+
* ghosts, so a second generator that drifted from the first by an increment would invalidate every
|
|
74
|
+
* one of them while passing every test that only read this file.
|
|
75
|
+
*/
|
|
76
|
+
export interface SavableRandom {
|
|
77
|
+
/** The next value in `[0, 1)`. */
|
|
78
|
+
next(): number;
|
|
79
|
+
/** The position, as one integer. */
|
|
80
|
+
save(): number;
|
|
81
|
+
/** Resume from a position `save` returned. */
|
|
82
|
+
restore(state: number): void;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function savableMulberry32(seed: number): SavableRandom {
|
|
86
|
+
let state = seed | 0;
|
|
87
|
+
return {
|
|
88
|
+
next(): number {
|
|
89
|
+
state = (state + 0x6d2b79f5) | 0;
|
|
90
|
+
let t = Math.imul(state ^ (state >>> 15), 1 | state);
|
|
91
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
92
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
93
|
+
},
|
|
94
|
+
save(): number {
|
|
95
|
+
return state;
|
|
96
|
+
},
|
|
97
|
+
restore(next: number): void {
|
|
98
|
+
state = next | 0;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spending a slice of a frame on work that can stop, without spending more than the slice.
|
|
3
|
+
*
|
|
4
|
+
* A **budgeted step pump**: the caller has some job — building a square of world, uploading a
|
|
5
|
+
* mesh, decoding a model — that can be broken into indivisible units, and wants to advance it
|
|
6
|
+
* a little every frame without the frame noticing. This holds the clock and the arithmetic;
|
|
7
|
+
* the caller holds the work and decides what to do next.
|
|
8
|
+
*
|
|
9
|
+
* **What it guarantees, in the honest words:** a call costs the larger of the budget and one
|
|
10
|
+
* uninterrupted stop. Not the budget. A stop cannot be interrupted from outside, so the only
|
|
11
|
+
* way to bound a call by the budget alone would be to bound every stop, which is the caller's
|
|
12
|
+
* job and not this one's — see `worstIn`, which exists to say which of the caller's units is
|
|
13
|
+
* the one over the line.
|
|
14
|
+
*
|
|
15
|
+
* **Why this rather than a count of units.** A count bounds the cheap term and leaves the
|
|
16
|
+
* expensive one free. `assets/uploadBudget.ts` records the measurement that established it:
|
|
17
|
+
* the parts of a model cost between 6 and 254 ms each, so three per frame was three of
|
|
18
|
+
* whatever they happened to be. The clock is exact, needs no per-asset tuning, and is as
|
|
19
|
+
* right on a phone as on a workstation.
|
|
20
|
+
*
|
|
21
|
+
* Nothing here touches a renderer or a device, on purpose: the property worth testing is a
|
|
22
|
+
* whole number of stops, and a test that needed a GPU could not assert it.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** A per-call decay of the guard: a half-life of sixty-nine calls, a little over a second at 60 Hz. */
|
|
26
|
+
const DEFAULT_FORGET = 0.99;
|
|
27
|
+
|
|
28
|
+
export interface StepBudgetOptions {
|
|
29
|
+
/**
|
|
30
|
+
* The clock, in milliseconds.
|
|
31
|
+
*
|
|
32
|
+
* Injected so a test can move time by hand. Every property this class has is a whole number
|
|
33
|
+
* of milliseconds and a whole number of stops; measuring them against a real clock would be
|
|
34
|
+
* measuring the machine the suite ran on.
|
|
35
|
+
*/
|
|
36
|
+
readonly now?: () => number;
|
|
37
|
+
/**
|
|
38
|
+
* How fast the worst-stop estimate forgets, as a factor applied once per call.
|
|
39
|
+
*
|
|
40
|
+
* One per cent by default, and the number is load-bearing. Five per cent was tried by a
|
|
41
|
+
* consumer and is wrong: the estimate falls below the real cost inside a single crossing of
|
|
42
|
+
* a town, the guard lets a second stop start with no room for it, and a call costs the
|
|
43
|
+
* budget *plus* a stop rather than the larger of the two — which is the whole thing the
|
|
44
|
+
* guard exists to prevent.
|
|
45
|
+
*/
|
|
46
|
+
readonly forget?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class StepBudget<Label = string> {
|
|
50
|
+
private readonly clock: () => number;
|
|
51
|
+
private readonly forget: number;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* What one more stop is assumed to cost, and therefore whether there is room for it.
|
|
55
|
+
*
|
|
56
|
+
* The largest stop seen so far, decayed a little each call. It starts at zero, which means
|
|
57
|
+
* the first call of a program's life overshoots by one stop and learns from it — the price
|
|
58
|
+
* of not asking a caller to declare a number it cannot know.
|
|
59
|
+
*/
|
|
60
|
+
private guard = 0;
|
|
61
|
+
|
|
62
|
+
private worstEver = 0;
|
|
63
|
+
private worstEverIn: Label | null = null;
|
|
64
|
+
|
|
65
|
+
constructor(options: StepBudgetOptions = {}) {
|
|
66
|
+
this.clock = options.now ?? ((): number => performance.now());
|
|
67
|
+
this.forget = options.forget ?? DEFAULT_FORGET;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** What one more stop is currently assumed to cost. Decays; see `StepBudgetOptions.forget`. */
|
|
71
|
+
get estimate(): number {
|
|
72
|
+
return this.guard;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The longest single stop ever taken. Does not decay: this is the report, not the guard. */
|
|
76
|
+
get worst(): number {
|
|
77
|
+
return this.worstEver;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The label the caller gave the longest stop.
|
|
82
|
+
*
|
|
83
|
+
* **A budget being blown is useless information without the name of the unit that blew it.**
|
|
84
|
+
* That is the whole reason `next` returns a label rather than a boolean: "the worst stop was
|
|
85
|
+
* 57 ms" sends a reader nowhere, and "the worst stop was 57 ms, in upload" sends them to one
|
|
86
|
+
* file.
|
|
87
|
+
*/
|
|
88
|
+
get worstIn(): Label | null {
|
|
89
|
+
return this.worstEverIn;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Advance the caller's work for up to `budgetMs`, and say how many stops that took.
|
|
94
|
+
*
|
|
95
|
+
* `next` performs exactly one indivisible unit and returns a label naming what it did, or
|
|
96
|
+
* `null` when there is nothing left to do — which ends the call without counting a stop.
|
|
97
|
+
*
|
|
98
|
+
* **Return the label of the work just done, not of the work about to be done.** The two are
|
|
99
|
+
* easy to confuse where a job names its own next phase, and the report that results sends a
|
|
100
|
+
* reader to the wrong builder every time the phase changes.
|
|
101
|
+
*
|
|
102
|
+
* The two rules the loop is made of, both arrived at by getting them wrong first:
|
|
103
|
+
*
|
|
104
|
+
* - *Do not start what you cannot finish.* A driver that keeps going while any budget
|
|
105
|
+
* remains overshoots by a whole stop. Measured by a consumer at 30 Hz: 8.3 ms of budget
|
|
106
|
+
* plus an 8.6 ms stop against a frame of 16.7.
|
|
107
|
+
* - *But always do one.* Without the unconditional first stop, a unit costing more than the
|
|
108
|
+
* whole budget means nothing ever advances at all, and a world that never loads is worse
|
|
109
|
+
* than a frame that runs long.
|
|
110
|
+
*/
|
|
111
|
+
spend(budgetMs: number, next: () => Label | null): number {
|
|
112
|
+
const started = this.clock();
|
|
113
|
+
let stops = 0;
|
|
114
|
+
|
|
115
|
+
for (;;) {
|
|
116
|
+
const elapsed = this.clock() - started;
|
|
117
|
+
if (stops > 0 && elapsed + this.guard > budgetMs) break;
|
|
118
|
+
|
|
119
|
+
const began = this.clock();
|
|
120
|
+
const did = next();
|
|
121
|
+
if (did === null) break;
|
|
122
|
+
const took = this.clock() - began;
|
|
123
|
+
|
|
124
|
+
if (took > this.guard) this.guard = took;
|
|
125
|
+
if (took > this.worstEver) {
|
|
126
|
+
this.worstEver = took;
|
|
127
|
+
this.worstEverIn = did;
|
|
128
|
+
}
|
|
129
|
+
stops += 1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* And the estimate forgets, or one bad stop holds the queue for ever. */
|
|
133
|
+
this.guard *= this.forget;
|
|
134
|
+
return stops;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where persisted state goes.
|
|
3
|
+
*
|
|
4
|
+
* The engine must not assume a browser origin. A game may want its saves on a
|
|
5
|
+
* server, in a native shell's own store, in an embedder-provided sandbox, or
|
|
6
|
+
* nowhere at all — so every engine system that persists takes a
|
|
7
|
+
* `KeyValueStore` and the browser is merely the default implementation.
|
|
8
|
+
*
|
|
9
|
+
* **Synchronous by design.** Preferences, one-time flags and a chosen character
|
|
10
|
+
* are all read during boot, before the first frame, and an await there means a
|
|
11
|
+
* frame rendered with the wrong settings and then corrected — a visible flicker
|
|
12
|
+
* on every load. An asynchronous backend (a server, IndexedDB) fits by
|
|
13
|
+
* hydrating a cache first and implementing `write` as fire-and-forget; that is
|
|
14
|
+
* what `MemoryStore.hydrate` exists for.
|
|
15
|
+
*
|
|
16
|
+
* No implementation here throws. Storage failure is a normal condition — Safari
|
|
17
|
+
* private mode and several embedded webviews throw on plain access — and a
|
|
18
|
+
* preference is never worth failing a boot for.
|
|
19
|
+
*/
|
|
20
|
+
export interface KeyValueStore {
|
|
21
|
+
read(key: string): string | null;
|
|
22
|
+
write(key: string, value: string): void;
|
|
23
|
+
remove(key: string): void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Volatile store: the test double, and the fallback when nothing persists. */
|
|
27
|
+
export class MemoryStore implements KeyValueStore {
|
|
28
|
+
private readonly entries = new Map<string, string>();
|
|
29
|
+
|
|
30
|
+
read(key: string): string | null {
|
|
31
|
+
return this.entries.get(key) ?? null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
write(key: string, value: string): void {
|
|
35
|
+
this.entries.set(key, value);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
remove(key: string): void {
|
|
39
|
+
this.entries.delete(key);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Seed from an asynchronous backend before anything reads. */
|
|
43
|
+
hydrate(entries: Iterable<readonly [string, string]>): void {
|
|
44
|
+
for (const [key, value] of entries) this.entries.set(key, value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* `localStorage`, with every access guarded.
|
|
50
|
+
*
|
|
51
|
+
* A blocked store degrades to memory rather than to nothing: settings then last
|
|
52
|
+
* the session instead of resetting between screens, and a first-run prompt
|
|
53
|
+
* fires once per visit instead of on every single load. Never showing it at all
|
|
54
|
+
* would be the worse failure — a player who arrived from a link would have no
|
|
55
|
+
* idea what the controls are.
|
|
56
|
+
*/
|
|
57
|
+
export class BrowserStore implements KeyValueStore {
|
|
58
|
+
private readonly fallback = new MemoryStore();
|
|
59
|
+
private readonly available: boolean;
|
|
60
|
+
|
|
61
|
+
constructor() {
|
|
62
|
+
this.available = probeLocalStorage();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
read(key: string): string | null {
|
|
66
|
+
if (!this.available) return this.fallback.read(key);
|
|
67
|
+
try {
|
|
68
|
+
return localStorage.getItem(key);
|
|
69
|
+
} catch {
|
|
70
|
+
return this.fallback.read(key);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
write(key: string, value: string): void {
|
|
75
|
+
this.fallback.write(key, value);
|
|
76
|
+
if (!this.available) return;
|
|
77
|
+
try {
|
|
78
|
+
localStorage.setItem(key, value);
|
|
79
|
+
} catch {
|
|
80
|
+
// Quota exceeded or blocked mid-session; the memory copy still stands.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
remove(key: string): void {
|
|
85
|
+
this.fallback.remove(key);
|
|
86
|
+
if (!this.available) return;
|
|
87
|
+
try {
|
|
88
|
+
localStorage.removeItem(key);
|
|
89
|
+
} catch {
|
|
90
|
+
// As above.
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function probeLocalStorage(): boolean {
|
|
96
|
+
try {
|
|
97
|
+
// Reading is not enough of a probe: some browsers allow the read and throw
|
|
98
|
+
// only on write, which would strand a store that reports itself healthy.
|
|
99
|
+
const probe = '__driftengine_probe__';
|
|
100
|
+
localStorage.setItem(probe, '1');
|
|
101
|
+
localStorage.removeItem(probe);
|
|
102
|
+
return true;
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let shared: KeyValueStore | null = null;
|
|
109
|
+
|
|
110
|
+
/** The default store: the browser's when it works, memory when it does not. */
|
|
111
|
+
export function defaultStore(): KeyValueStore {
|
|
112
|
+
shared ??= new BrowserStore();
|
|
113
|
+
return shared;
|
|
114
|
+
}
|