@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.
Files changed (955) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/README.md +9 -0
  4. package/dist/behavior/behaviorTree.d.ts +140 -0
  5. package/dist/behavior/behaviorTree.js +289 -0
  6. package/dist/build/shaderComments.d.ts +64 -0
  7. package/dist/build/shaderComments.js +0 -0
  8. package/dist/cinematic/player.d.ts +80 -0
  9. package/dist/cinematic/player.js +184 -0
  10. package/dist/cinematic/script.d.ts +63 -0
  11. package/dist/cinematic/script.js +141 -0
  12. package/dist/core/bootGate.d.ts +37 -0
  13. package/dist/core/bootGate.js +47 -0
  14. package/dist/core/loadTracker.d.ts +78 -0
  15. package/dist/core/loadTracker.js +106 -0
  16. package/dist/core/loop.d.ts +118 -0
  17. package/dist/core/loop.js +84 -0
  18. package/dist/core/messageQueue.d.ts +61 -0
  19. package/dist/core/messageQueue.js +104 -0
  20. package/dist/core/onceSet.d.ts +27 -0
  21. package/dist/core/onceSet.js +62 -0
  22. package/dist/core/preferences.d.ts +47 -0
  23. package/dist/core/preferences.js +140 -0
  24. package/dist/core/remoteSave.d.ts +154 -0
  25. package/dist/core/remoteSave.js +249 -0
  26. package/dist/core/rng.d.ts +64 -0
  27. package/dist/core/rng.js +72 -0
  28. package/dist/core/stepBudget.d.ts +91 -0
  29. package/dist/core/stepBudget.js +105 -0
  30. package/dist/core/storage.d.ts +52 -0
  31. package/dist/core/storage.js +85 -0
  32. package/dist/core/tickTrace.d.ts +72 -0
  33. package/dist/core/tickTrace.js +102 -0
  34. package/dist/core/timeCurve.d.ts +83 -0
  35. package/dist/core/timeCurve.js +107 -0
  36. package/dist/core/withDefaults.d.ts +21 -0
  37. package/dist/core/withDefaults.js +29 -0
  38. package/dist/dev/contactProbe.d.ts +41 -0
  39. package/dist/dev/contactProbe.js +58 -0
  40. package/dist/dev/fpsMeter.d.ts +45 -0
  41. package/dist/dev/fpsMeter.js +86 -0
  42. package/dist/environment/celestialClock.d.ts +141 -0
  43. package/dist/environment/celestialClock.js +262 -0
  44. package/dist/geometry/decal.d.ts +61 -0
  45. package/dist/geometry/decal.js +178 -0
  46. package/dist/geometry/filmPatch.d.ts +35 -0
  47. package/dist/geometry/filmPatch.js +112 -0
  48. package/dist/geometry/growable.d.ts +70 -0
  49. package/dist/geometry/growable.js +167 -0
  50. package/dist/geometry/lightVolume.d.ts +76 -0
  51. package/dist/geometry/lightVolume.js +65 -0
  52. package/dist/geometry/meshBuilder.d.ts +426 -0
  53. package/dist/geometry/meshBuilder.js +1184 -0
  54. package/dist/geometry/pixelFont.d.ts +59 -0
  55. package/dist/geometry/pixelFont.js +179 -0
  56. package/dist/geometry/ribbon.d.ts +101 -0
  57. package/dist/geometry/ribbon.js +546 -0
  58. package/dist/geometry/shellFill.d.ts +101 -0
  59. package/dist/geometry/shellFill.js +203 -0
  60. package/dist/geometry/spline.d.ts +162 -0
  61. package/dist/geometry/spline.js +527 -0
  62. package/dist/geometry/tangents.d.ts +30 -0
  63. package/dist/geometry/tangents.js +142 -0
  64. package/dist/geometry/textMesh.d.ts +51 -0
  65. package/dist/geometry/textMesh.js +57 -0
  66. package/dist/geometry/treeBuilder.d.ts +37 -0
  67. package/dist/geometry/treeBuilder.js +56 -0
  68. package/dist/host/display.d.ts +135 -0
  69. package/dist/host/display.js +114 -0
  70. package/dist/host/files.d.ts +25 -0
  71. package/dist/host/files.js +44 -0
  72. package/dist/host/lifecycle.d.ts +45 -0
  73. package/dist/host/lifecycle.js +28 -0
  74. package/dist/host/platformServices.d.ts +23 -0
  75. package/dist/host/platformServices.js +1 -0
  76. package/dist/host/screen.d.ts +49 -0
  77. package/dist/host/screen.js +90 -0
  78. package/dist/index.d.ts +289 -0
  79. package/dist/index.js +320 -0
  80. package/dist/input/actionMap.d.ts +181 -0
  81. package/dist/input/actionMap.js +314 -0
  82. package/dist/input/activeDevice.d.ts +55 -0
  83. package/dist/input/activeDevice.js +83 -0
  84. package/dist/input/gamepadIdentity.d.ts +43 -0
  85. package/dist/input/gamepadIdentity.js +108 -0
  86. package/dist/input/gamepadMapping.d.ts +56 -0
  87. package/dist/input/gamepadMapping.js +91 -0
  88. package/dist/input/input.d.ts +281 -0
  89. package/dist/input/input.js +703 -0
  90. package/dist/input/inputHarness.d.ts +42 -0
  91. package/dist/input/inputHarness.js +193 -0
  92. package/dist/input/rightGesture.d.ts +57 -0
  93. package/dist/input/rightGesture.js +49 -0
  94. package/dist/input/rumble.d.ts +71 -0
  95. package/dist/input/rumble.js +119 -0
  96. package/dist/input/touchControls.d.ts +138 -0
  97. package/dist/input/touchControls.js +352 -0
  98. package/dist/input/typingTarget.d.ts +6 -0
  99. package/dist/input/typingTarget.js +27 -0
  100. package/dist/math/bounds.d.ts +61 -0
  101. package/dist/math/bounds.js +121 -0
  102. package/dist/math/color.d.ts +8 -0
  103. package/dist/math/color.js +35 -0
  104. package/dist/math/exact.d.ts +66 -0
  105. package/dist/math/exact.js +262 -0
  106. package/dist/math/frustum.d.ts +44 -0
  107. package/dist/math/frustum.js +90 -0
  108. package/dist/math/intersect.d.ts +76 -0
  109. package/dist/math/intersect.js +185 -0
  110. package/dist/math/scalar.d.ts +51 -0
  111. package/dist/math/scalar.js +99 -0
  112. package/dist/math/spring.d.ts +59 -0
  113. package/dist/math/spring.js +88 -0
  114. package/dist/nav/navGraph.d.ts +71 -0
  115. package/dist/nav/navGraph.js +111 -0
  116. package/dist/nav/navPath.d.ts +93 -0
  117. package/dist/nav/navPath.js +162 -0
  118. package/dist/nav/navSearch.d.ts +74 -0
  119. package/dist/nav/navSearch.js +198 -0
  120. package/dist/physics/boxSurface.d.ts +48 -0
  121. package/dist/physics/boxSurface.js +73 -0
  122. package/dist/physics/colliderSurface.d.ts +46 -0
  123. package/dist/physics/colliderSurface.js +146 -0
  124. package/dist/physics/compositeSurface.d.ts +33 -0
  125. package/dist/physics/compositeSurface.js +108 -0
  126. package/dist/physics/heightSurface.d.ts +103 -0
  127. package/dist/physics/heightSurface.js +153 -0
  128. package/dist/physics/ribbonSurface.d.ts +239 -0
  129. package/dist/physics/ribbonSurface.js +522 -0
  130. package/dist/render/ambientOcclusionPass.d.ts +53 -0
  131. package/dist/render/ambientOcclusionPass.js +179 -0
  132. package/dist/render/areaLights.d.ts +116 -0
  133. package/dist/render/areaLights.js +91 -0
  134. package/dist/render/areaShadowSet.d.ts +184 -0
  135. package/dist/render/areaShadowSet.js +277 -0
  136. package/dist/render/atmosphere.d.ts +94 -0
  137. package/dist/render/atmosphere.js +91 -0
  138. package/dist/render/backend/api.d.ts +496 -0
  139. package/dist/render/backend/api.js +1 -0
  140. package/dist/render/backend/budget.d.ts +82 -0
  141. package/dist/render/backend/budget.js +99 -0
  142. package/dist/render/backend/createRenderer.d.ts +135 -0
  143. package/dist/render/backend/createRenderer.js +201 -0
  144. package/dist/render/backend/deadline.d.ts +24 -0
  145. package/dist/render/backend/deadline.js +38 -0
  146. package/dist/render/backend/probe.d.ts +30 -0
  147. package/dist/render/backend/probe.js +129 -0
  148. package/dist/render/backend/select.d.ts +70 -0
  149. package/dist/render/backend/select.js +249 -0
  150. package/dist/render/backend/timer.d.ts +50 -0
  151. package/dist/render/backend/timer.js +1 -0
  152. package/dist/render/backend/webgl2/instanced.d.ts +21 -0
  153. package/dist/render/backend/webgl2/instanced.js +42 -0
  154. package/dist/render/backend/webgl2/morphTexture.d.ts +21 -0
  155. package/dist/render/backend/webgl2/morphTexture.js +55 -0
  156. package/dist/render/backend/webgl2/renderer.d.ts +3027 -0
  157. package/dist/render/backend/webgl2/renderer.js +6041 -0
  158. package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +32 -0
  159. package/dist/render/backend/webgl2/skinPaletteTexture.js +68 -0
  160. package/dist/render/backend/webgpu/boltPass.d.ts +42 -0
  161. package/dist/render/backend/webgpu/boltPass.js +160 -0
  162. package/dist/render/backend/webgpu/buffers.d.ts +159 -0
  163. package/dist/render/backend/webgpu/buffers.js +402 -0
  164. package/dist/render/backend/webgpu/causticsPass.d.ts +36 -0
  165. package/dist/render/backend/webgpu/causticsPass.js +138 -0
  166. package/dist/render/backend/webgpu/clusterBinner.d.ts +51 -0
  167. package/dist/render/backend/webgpu/clusterBinner.js +206 -0
  168. package/dist/render/backend/webgpu/depthPass.d.ts +114 -0
  169. package/dist/render/backend/webgpu/depthPass.js +228 -0
  170. package/dist/render/backend/webgpu/device.d.ts +52 -0
  171. package/dist/render/backend/webgpu/device.js +121 -0
  172. package/dist/render/backend/webgpu/drawCommand.d.ts +43 -0
  173. package/dist/render/backend/webgpu/drawCommand.js +54 -0
  174. package/dist/render/backend/webgpu/environmentTexels.d.ts +28 -0
  175. package/dist/render/backend/webgpu/environmentTexels.js +79 -0
  176. package/dist/render/backend/webgpu/filmPass.d.ts +29 -0
  177. package/dist/render/backend/webgpu/filmPass.js +97 -0
  178. package/dist/render/backend/webgpu/flatPass.d.ts +213 -0
  179. package/dist/render/backend/webgpu/flatPass.js +482 -0
  180. package/dist/render/backend/webgpu/flockPass.d.ts +34 -0
  181. package/dist/render/backend/webgpu/flockPass.js +129 -0
  182. package/dist/render/backend/webgpu/gpuTimestamps.d.ts +94 -0
  183. package/dist/render/backend/webgpu/gpuTimestamps.js +213 -0
  184. package/dist/render/backend/webgpu/insetPass.d.ts +19 -0
  185. package/dist/render/backend/webgpu/insetPass.js +108 -0
  186. package/dist/render/backend/webgpu/instanced.d.ts +27 -0
  187. package/dist/render/backend/webgpu/instanced.js +49 -0
  188. package/dist/render/backend/webgpu/lightVolumePass.d.ts +75 -0
  189. package/dist/render/backend/webgpu/lightVolumePass.js +154 -0
  190. package/dist/render/backend/webgpu/linePass.d.ts +90 -0
  191. package/dist/render/backend/webgpu/linePass.js +220 -0
  192. package/dist/render/backend/webgpu/morphTexture.d.ts +18 -0
  193. package/dist/render/backend/webgpu/morphTexture.js +51 -0
  194. package/dist/render/backend/webgpu/panelPass.d.ts +37 -0
  195. package/dist/render/backend/webgpu/panelPass.js +114 -0
  196. package/dist/render/backend/webgpu/particlePass.d.ts +89 -0
  197. package/dist/render/backend/webgpu/particlePass.js +280 -0
  198. package/dist/render/backend/webgpu/pipelineCache.d.ts +93 -0
  199. package/dist/render/backend/webgpu/pipelineCache.js +140 -0
  200. package/dist/render/backend/webgpu/plumePass.d.ts +69 -0
  201. package/dist/render/backend/webgpu/plumePass.js +213 -0
  202. package/dist/render/backend/webgpu/pointShadowPass.d.ts +88 -0
  203. package/dist/render/backend/webgpu/pointShadowPass.js +280 -0
  204. package/dist/render/backend/webgpu/postPass.d.ts +342 -0
  205. package/dist/render/backend/webgpu/postPass.js +366 -0
  206. package/dist/render/backend/webgpu/probePass.d.ts +108 -0
  207. package/dist/render/backend/webgpu/probePass.js +188 -0
  208. package/dist/render/backend/webgpu/reflectionPass.d.ts +29 -0
  209. package/dist/render/backend/webgpu/reflectionPass.js +87 -0
  210. package/dist/render/backend/webgpu/renderer.d.ts +3082 -0
  211. package/dist/render/backend/webgpu/renderer.js +10911 -0
  212. package/dist/render/backend/webgpu/scatterPass.d.ts +95 -0
  213. package/dist/render/backend/webgpu/scatterPass.js +266 -0
  214. package/dist/render/backend/webgpu/sdfTextPass.d.ts +86 -0
  215. package/dist/render/backend/webgpu/sdfTextPass.js +190 -0
  216. package/dist/render/backend/webgpu/shaderModules.d.ts +9 -0
  217. package/dist/render/backend/webgpu/shaderModules.js +45 -0
  218. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +23 -0
  219. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.js +208 -0
  220. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +67 -0
  221. package/dist/render/backend/webgpu/skinPaletteRing.js +97 -0
  222. package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +17 -0
  223. package/dist/render/backend/webgpu/skinPaletteTexture.js +68 -0
  224. package/dist/render/backend/webgpu/skyPass.d.ts +102 -0
  225. package/dist/render/backend/webgpu/skyPass.js +70 -0
  226. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +41 -0
  227. package/dist/render/backend/webgpu/surfaceTexturePass.js +228 -0
  228. package/dist/render/backend/webgpu/textPass.d.ts +73 -0
  229. package/dist/render/backend/webgpu/textPass.js +190 -0
  230. package/dist/render/backend/webgpu/uniformRing.d.ts +133 -0
  231. package/dist/render/backend/webgpu/uniformRing.js +208 -0
  232. package/dist/render/backend/webgpu/waterPass.d.ts +73 -0
  233. package/dist/render/backend/webgpu/waterPass.js +160 -0
  234. package/dist/render/backend/webgpu/windStreakPass.d.ts +46 -0
  235. package/dist/render/backend/webgpu/windStreakPass.js +153 -0
  236. package/dist/render/billboard.d.ts +27 -0
  237. package/dist/render/billboard.js +79 -0
  238. package/dist/render/bloomChain.d.ts +66 -0
  239. package/dist/render/bloomChain.js +83 -0
  240. package/dist/render/bloomPass.d.ts +54 -0
  241. package/dist/render/bloomPass.js +219 -0
  242. package/dist/render/boltBatch.d.ts +39 -0
  243. package/dist/render/boltBatch.js +121 -0
  244. package/dist/render/boltPool.d.ts +135 -0
  245. package/dist/render/boltPool.js +259 -0
  246. package/dist/render/boom.d.ts +46 -0
  247. package/dist/render/boom.js +81 -0
  248. package/dist/render/camera.d.ts +119 -0
  249. package/dist/render/camera.js +304 -0
  250. package/dist/render/causticsRenderer.d.ts +63 -0
  251. package/dist/render/causticsRenderer.js +119 -0
  252. package/dist/render/cinematicCamera.d.ts +102 -0
  253. package/dist/render/cinematicCamera.js +227 -0
  254. package/dist/render/clusteredLights.d.ts +260 -0
  255. package/dist/render/clusteredLights.js +479 -0
  256. package/dist/render/colourGrade.d.ts +62 -0
  257. package/dist/render/colourGrade.js +91 -0
  258. package/dist/render/compute.d.ts +74 -0
  259. package/dist/render/compute.js +8 -0
  260. package/dist/render/contextLoss.d.ts +32 -0
  261. package/dist/render/contextLoss.js +46 -0
  262. package/dist/render/debugLines.d.ts +75 -0
  263. package/dist/render/debugLines.js +281 -0
  264. package/dist/render/decalPass.d.ts +34 -0
  265. package/dist/render/decalPass.js +103 -0
  266. package/dist/render/decalProjector.d.ts +140 -0
  267. package/dist/render/decalProjector.js +282 -0
  268. package/dist/render/decalQueue.d.ts +53 -0
  269. package/dist/render/decalQueue.js +87 -0
  270. package/dist/render/depthConvention.d.ts +314 -0
  271. package/dist/render/depthConvention.js +346 -0
  272. package/dist/render/drawingBuffer.d.ts +52 -0
  273. package/dist/render/drawingBuffer.js +67 -0
  274. package/dist/render/emptyTexture.d.ts +60 -0
  275. package/dist/render/emptyTexture.js +103 -0
  276. package/dist/render/envProbeArray.d.ts +85 -0
  277. package/dist/render/envProbeArray.js +164 -0
  278. package/dist/render/equirectToCube.d.ts +54 -0
  279. package/dist/render/equirectToCube.js +123 -0
  280. package/dist/render/flockGeometry.d.ts +23 -0
  281. package/dist/render/flockGeometry.js +43 -0
  282. package/dist/render/flockRenderer.d.ts +37 -0
  283. package/dist/render/flockRenderer.js +70 -0
  284. package/dist/render/frame/arena.d.ts +32 -0
  285. package/dist/render/frame/arena.js +65 -0
  286. package/dist/render/frame/index.d.ts +18 -0
  287. package/dist/render/frame/index.js +4 -0
  288. package/dist/render/frame/replay.d.ts +34 -0
  289. package/dist/render/frame/replay.js +48 -0
  290. package/dist/render/frame/resources.d.ts +25 -0
  291. package/dist/render/frame/resources.js +55 -0
  292. package/dist/render/frame/schedule.d.ts +37 -0
  293. package/dist/render/frame/schedule.js +61 -0
  294. package/dist/render/frameView.d.ts +19 -0
  295. package/dist/render/frameView.js +1 -0
  296. package/dist/render/gizmo.d.ts +236 -0
  297. package/dist/render/gizmo.js +727 -0
  298. package/dist/render/globalMedium.d.ts +124 -0
  299. package/dist/render/globalMedium.js +100 -0
  300. package/dist/render/globalMediumPass.d.ts +101 -0
  301. package/dist/render/globalMediumPass.js +250 -0
  302. package/dist/render/gpuCapability.d.ts +111 -0
  303. package/dist/render/gpuCapability.js +194 -0
  304. package/dist/render/gpuTimer.d.ts +87 -0
  305. package/dist/render/gpuTimer.js +145 -0
  306. package/dist/render/halfFloat.d.ts +4 -0
  307. package/dist/render/halfFloat.js +38 -0
  308. package/dist/render/handleRegistry.d.ts +54 -0
  309. package/dist/render/handleRegistry.js +84 -0
  310. package/dist/render/iesProfile.d.ts +64 -0
  311. package/dist/render/iesProfile.js +179 -0
  312. package/dist/render/imageTexels.d.ts +50 -0
  313. package/dist/render/imageTexels.js +91 -0
  314. package/dist/render/instancedMesh.d.ts +48 -0
  315. package/dist/render/instancedMesh.js +127 -0
  316. package/dist/render/instances.d.ts +69 -0
  317. package/dist/render/instances.js +52 -0
  318. package/dist/render/lightBudget.d.ts +397 -0
  319. package/dist/render/lightBudget.js +524 -0
  320. package/dist/render/lightMatrix.d.ts +3 -0
  321. package/dist/render/lightMatrix.js +45 -0
  322. package/dist/render/lightVolumeDraw.d.ts +132 -0
  323. package/dist/render/lightVolumeDraw.js +181 -0
  324. package/dist/render/lineBatch.d.ts +60 -0
  325. package/dist/render/lineBatch.js +160 -0
  326. package/dist/render/linePoints.d.ts +33 -0
  327. package/dist/render/linePoints.js +46 -0
  328. package/dist/render/livePointShadowSet.d.ts +72 -0
  329. package/dist/render/livePointShadowSet.js +258 -0
  330. package/dist/render/lod.d.ts +35 -0
  331. package/dist/render/lod.js +65 -0
  332. package/dist/render/mesh.d.ts +177 -0
  333. package/dist/render/mesh.js +466 -0
  334. package/dist/render/occlusion.d.ts +81 -0
  335. package/dist/render/occlusion.js +378 -0
  336. package/dist/render/oitPass.d.ts +67 -0
  337. package/dist/render/oitPass.js +213 -0
  338. package/dist/render/orderIndependent.d.ts +92 -0
  339. package/dist/render/orderIndependent.js +108 -0
  340. package/dist/render/particleBatch.d.ts +140 -0
  341. package/dist/render/particleBatch.js +186 -0
  342. package/dist/render/particleMaterial.d.ts +54 -0
  343. package/dist/render/particleMaterial.js +42 -0
  344. package/dist/render/particlePool.d.ts +124 -0
  345. package/dist/render/particlePool.js +182 -0
  346. package/dist/render/pass.d.ts +195 -0
  347. package/dist/render/pass.js +9 -0
  348. package/dist/render/passTarget.d.ts +86 -0
  349. package/dist/render/passTarget.js +121 -0
  350. package/dist/render/pickable.d.ts +31 -0
  351. package/dist/render/pickable.js +172 -0
  352. package/dist/render/planarReflection.d.ts +59 -0
  353. package/dist/render/planarReflection.js +194 -0
  354. package/dist/render/planarReflectionDraw.d.ts +31 -0
  355. package/dist/render/planarReflectionDraw.js +65 -0
  356. package/dist/render/plumeGeometry.d.ts +25 -0
  357. package/dist/render/plumeGeometry.js +61 -0
  358. package/dist/render/plumeMaterial.d.ts +31 -0
  359. package/dist/render/plumeMaterial.js +64 -0
  360. package/dist/render/plumeRenderer.d.ts +96 -0
  361. package/dist/render/plumeRenderer.js +185 -0
  362. package/dist/render/pointLightSelection.d.ts +175 -0
  363. package/dist/render/pointLightSelection.js +301 -0
  364. package/dist/render/pointShadowArray.d.ts +95 -0
  365. package/dist/render/pointShadowArray.js +219 -0
  366. package/dist/render/pointShadowBudget.d.ts +118 -0
  367. package/dist/render/pointShadowBudget.js +221 -0
  368. package/dist/render/pointShadowImage.d.ts +265 -0
  369. package/dist/render/pointShadowImage.js +339 -0
  370. package/dist/render/pointShadowMap.d.ts +93 -0
  371. package/dist/render/pointShadowMap.js +167 -0
  372. package/dist/render/pointShadowSystem.d.ts +195 -0
  373. package/dist/render/pointShadowSystem.js +336 -0
  374. package/dist/render/prefilterEnvMap.d.ts +124 -0
  375. package/dist/render/prefilterEnvMap.js +146 -0
  376. package/dist/render/prefilterPass.d.ts +44 -0
  377. package/dist/render/prefilterPass.js +98 -0
  378. package/dist/render/probeGrid.d.ts +122 -0
  379. package/dist/render/probeGrid.js +174 -0
  380. package/dist/render/rainField.d.ts +99 -0
  381. package/dist/render/rainField.js +168 -0
  382. package/dist/render/reflectionProbe.d.ts +188 -0
  383. package/dist/render/reflectionProbe.js +437 -0
  384. package/dist/render/renderQuality.d.ts +699 -0
  385. package/dist/render/renderQuality.js +293 -0
  386. package/dist/render/rendererHarness.d.ts +39 -0
  387. package/dist/render/rendererHarness.js +185 -0
  388. package/dist/render/resolutionGovernor.d.ts +107 -0
  389. package/dist/render/resolutionGovernor.js +144 -0
  390. package/dist/render/scatterDeform.d.ts +17 -0
  391. package/dist/render/scatterDeform.js +46 -0
  392. package/dist/render/sceneTarget.d.ts +288 -0
  393. package/dist/render/sceneTarget.js +856 -0
  394. package/dist/render/screenSpaceReflection.d.ts +233 -0
  395. package/dist/render/screenSpaceReflection.js +415 -0
  396. package/dist/render/sdfFont.d.ts +77 -0
  397. package/dist/render/sdfFont.js +86 -0
  398. package/dist/render/sdfTextLayout.d.ts +46 -0
  399. package/dist/render/sdfTextLayout.js +145 -0
  400. package/dist/render/sdfTextRenderer.d.ts +75 -0
  401. package/dist/render/sdfTextRenderer.js +194 -0
  402. package/dist/render/seaState.d.ts +25 -0
  403. package/dist/render/seaState.js +34 -0
  404. package/dist/render/segmentQuads.d.ts +29 -0
  405. package/dist/render/segmentQuads.js +75 -0
  406. package/dist/render/shader.d.ts +5 -0
  407. package/dist/render/shader.js +172 -0
  408. package/dist/render/shaders/ambientOcclusion.d.ts +45 -0
  409. package/dist/render/shaders/ambientOcclusion.js +352 -0
  410. package/dist/render/shaders/arcane.d.ts +19 -0
  411. package/dist/render/shaders/arcane.js +102 -0
  412. package/dist/render/shaders/bloom.d.ts +70 -0
  413. package/dist/render/shaders/bloom.js +227 -0
  414. package/dist/render/shaders/bolt.d.ts +17 -0
  415. package/dist/render/shaders/bolt.js +161 -0
  416. package/dist/render/shaders/caustics.d.ts +38 -0
  417. package/dist/render/shaders/caustics.js +167 -0
  418. package/dist/render/shaders/conditionals.d.ts +21 -0
  419. package/dist/render/shaders/conditionals.js +55 -0
  420. package/dist/render/shaders/decalProject.d.ts +25 -0
  421. package/dist/render/shaders/decalProject.js +125 -0
  422. package/dist/render/shaders/depth.d.ts +14 -0
  423. package/dist/render/shaders/depth.js +114 -0
  424. package/dist/render/shaders/depthOfField.d.ts +41 -0
  425. package/dist/render/shaders/depthOfField.js +139 -0
  426. package/dist/render/shaders/film.d.ts +15 -0
  427. package/dist/render/shaders/film.js +283 -0
  428. package/dist/render/shaders/fire.d.ts +12 -0
  429. package/dist/render/shaders/fire.js +178 -0
  430. package/dist/render/shaders/flat/directionalShadow.d.ts +1 -0
  431. package/dist/render/shaders/flat/directionalShadow.js +195 -0
  432. package/dist/render/shaders/flat/index.d.ts +135 -0
  433. package/dist/render/shaders/flat/index.js +387 -0
  434. package/dist/render/shaders/flat/lobes.d.ts +1 -0
  435. package/dist/render/shaders/flat/lobes.js +398 -0
  436. package/dist/render/shaders/flat/main.d.ts +2 -0
  437. package/dist/render/shaders/flat/main.js +1630 -0
  438. package/dist/render/shaders/flat/pointShadow.d.ts +1 -0
  439. package/dist/render/shaders/flat/pointShadow.js +322 -0
  440. package/dist/render/shaders/flat/preamble.d.ts +15 -0
  441. package/dist/render/shaders/flat/preamble.js +864 -0
  442. package/dist/render/shaders/flat/probeGrid.d.ts +21 -0
  443. package/dist/render/shaders/flat/probeGrid.js +151 -0
  444. package/dist/render/shaders/flat/surface.d.ts +2 -0
  445. package/dist/render/shaders/flat/surface.js +40 -0
  446. package/dist/render/shaders/flock.d.ts +11 -0
  447. package/dist/render/shaders/flock.js +102 -0
  448. package/dist/render/shaders/fog.d.ts +37 -0
  449. package/dist/render/shaders/fog.js +98 -0
  450. package/dist/render/shaders/fullscreen.d.ts +16 -0
  451. package/dist/render/shaders/fullscreen.js +27 -0
  452. package/dist/render/shaders/generated/ambientOcclusion.wgsl.d.ts +65 -0
  453. package/dist/render/shaders/generated/ambientOcclusion.wgsl.js +71 -0
  454. package/dist/render/shaders/generated/arcane.wgsl.d.ts +90 -0
  455. package/dist/render/shaders/generated/arcane.wgsl.js +96 -0
  456. package/dist/render/shaders/generated/bloom.wgsl.d.ts +69 -0
  457. package/dist/render/shaders/generated/bloom.wgsl.js +75 -0
  458. package/dist/render/shaders/generated/bolt.wgsl.d.ts +118 -0
  459. package/dist/render/shaders/generated/bolt.wgsl.js +124 -0
  460. package/dist/render/shaders/generated/caustics.wgsl.d.ts +118 -0
  461. package/dist/render/shaders/generated/caustics.wgsl.js +124 -0
  462. package/dist/render/shaders/generated/decalProject.wgsl.d.ts +61 -0
  463. package/dist/render/shaders/generated/decalProject.wgsl.js +67 -0
  464. package/dist/render/shaders/generated/depth.wgsl.d.ts +131 -0
  465. package/dist/render/shaders/generated/depth.wgsl.js +137 -0
  466. package/dist/render/shaders/generated/film.wgsl.d.ts +134 -0
  467. package/dist/render/shaders/generated/film.wgsl.js +140 -0
  468. package/dist/render/shaders/generated/fire.wgsl.d.ts +128 -0
  469. package/dist/render/shaders/generated/fire.wgsl.js +134 -0
  470. package/dist/render/shaders/generated/flat.wgsl.d.ts +9163 -0
  471. package/dist/render/shaders/generated/flat.wgsl.js +9192 -0
  472. package/dist/render/shaders/generated/flock.wgsl.d.ts +73 -0
  473. package/dist/render/shaders/generated/flock.wgsl.js +79 -0
  474. package/dist/render/shaders/generated/fullscreen.wgsl.d.ts +12 -0
  475. package/dist/render/shaders/generated/fullscreen.wgsl.js +18 -0
  476. package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +130 -0
  477. package/dist/render/shaders/generated/globalMedium.wgsl.js +136 -0
  478. package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +230 -0
  479. package/dist/render/shaders/generated/lightVolume.wgsl.js +239 -0
  480. package/dist/render/shaders/generated/line.wgsl.d.ts +128 -0
  481. package/dist/render/shaders/generated/line.wgsl.js +134 -0
  482. package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +51 -0
  483. package/dist/render/shaders/generated/octahedralResolve.wgsl.js +57 -0
  484. package/dist/render/shaders/generated/oitResolve.wgsl.d.ts +23 -0
  485. package/dist/render/shaders/generated/oitResolve.wgsl.js +29 -0
  486. package/dist/render/shaders/generated/panel.wgsl.d.ts +48 -0
  487. package/dist/render/shaders/generated/panel.wgsl.js +54 -0
  488. package/dist/render/shaders/generated/particle.wgsl.d.ts +332 -0
  489. package/dist/render/shaders/generated/particle.wgsl.js +338 -0
  490. package/dist/render/shaders/generated/prefilter.wgsl.d.ts +61 -0
  491. package/dist/render/shaders/generated/prefilter.wgsl.js +67 -0
  492. package/dist/render/shaders/generated/rush.wgsl.d.ts +131 -0
  493. package/dist/render/shaders/generated/rush.wgsl.js +137 -0
  494. package/dist/render/shaders/generated/scatter.wgsl.d.ts +195 -0
  495. package/dist/render/shaders/generated/scatter.wgsl.js +201 -0
  496. package/dist/render/shaders/generated/sdfText.wgsl.d.ts +69 -0
  497. package/dist/render/shaders/generated/sdfText.wgsl.js +75 -0
  498. package/dist/render/shaders/generated/sky.wgsl.d.ts +100 -0
  499. package/dist/render/shaders/generated/sky.wgsl.js +106 -0
  500. package/dist/render/shaders/generated/smoke.wgsl.d.ts +85 -0
  501. package/dist/render/shaders/generated/smoke.wgsl.js +91 -0
  502. package/dist/render/shaders/generated/ssrResolve.wgsl.d.ts +18 -0
  503. package/dist/render/shaders/generated/ssrResolve.wgsl.js +24 -0
  504. package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +86 -0
  505. package/dist/render/shaders/generated/ssrTrace.wgsl.js +92 -0
  506. package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +46 -0
  507. package/dist/render/shaders/generated/temporalResolve.wgsl.js +52 -0
  508. package/dist/render/shaders/generated/text.wgsl.d.ts +98 -0
  509. package/dist/render/shaders/generated/text.wgsl.js +104 -0
  510. package/dist/render/shaders/generated/water.wgsl.d.ts +247 -0
  511. package/dist/render/shaders/generated/water.wgsl.js +253 -0
  512. package/dist/render/shaders/generated/windStreaks.wgsl.d.ts +73 -0
  513. package/dist/render/shaders/generated/windStreaks.wgsl.js +79 -0
  514. package/dist/render/shaders/gerstner.d.ts +21 -0
  515. package/dist/render/shaders/gerstner.js +110 -0
  516. package/dist/render/shaders/globalMedium.d.ts +56 -0
  517. package/dist/render/shaders/globalMedium.js +393 -0
  518. package/dist/render/shaders/lightVolume.d.ts +61 -0
  519. package/dist/render/shaders/lightVolume.js +527 -0
  520. package/dist/render/shaders/line.d.ts +18 -0
  521. package/dist/render/shaders/line.js +122 -0
  522. package/dist/render/shaders/morph.d.ts +26 -0
  523. package/dist/render/shaders/morph.js +61 -0
  524. package/dist/render/shaders/octahedral.d.ts +76 -0
  525. package/dist/render/shaders/octahedral.js +161 -0
  526. package/dist/render/shaders/octahedralResolve.d.ts +25 -0
  527. package/dist/render/shaders/octahedralResolve.js +81 -0
  528. package/dist/render/shaders/oitResolve.d.ts +17 -0
  529. package/dist/render/shaders/oitResolve.js +42 -0
  530. package/dist/render/shaders/outputTransform.d.ts +37 -0
  531. package/dist/render/shaders/outputTransform.js +106 -0
  532. package/dist/render/shaders/panel.d.ts +17 -0
  533. package/dist/render/shaders/panel.js +50 -0
  534. package/dist/render/shaders/particle.d.ts +82 -0
  535. package/dist/render/shaders/particle.js +431 -0
  536. package/dist/render/shaders/prefilter.d.ts +37 -0
  537. package/dist/render/shaders/prefilter.js +276 -0
  538. package/dist/render/shaders/rush.d.ts +21 -0
  539. package/dist/render/shaders/rush.js +355 -0
  540. package/dist/render/shaders/scatter.d.ts +14 -0
  541. package/dist/render/shaders/scatter.js +206 -0
  542. package/dist/render/shaders/sdfText.d.ts +9 -0
  543. package/dist/render/shaders/sdfText.js +65 -0
  544. package/dist/render/shaders/skinning.d.ts +17 -0
  545. package/dist/render/shaders/skinning.js +59 -0
  546. package/dist/render/shaders/sky.d.ts +10 -0
  547. package/dist/render/shaders/sky.js +242 -0
  548. package/dist/render/shaders/smoke.d.ts +8 -0
  549. package/dist/render/shaders/smoke.js +88 -0
  550. package/dist/render/shaders/ssrResolve.d.ts +15 -0
  551. package/dist/render/shaders/ssrResolve.js +28 -0
  552. package/dist/render/shaders/ssrTrace.d.ts +22 -0
  553. package/dist/render/shaders/ssrTrace.js +230 -0
  554. package/dist/render/shaders/tangentFrame.d.ts +17 -0
  555. package/dist/render/shaders/tangentFrame.js +70 -0
  556. package/dist/render/shaders/temporalResolve.d.ts +1 -0
  557. package/dist/render/shaders/temporalResolve.js +150 -0
  558. package/dist/render/shaders/text.d.ts +17 -0
  559. package/dist/render/shaders/text.js +155 -0
  560. package/dist/render/shaders/vertexChannel.d.ts +39 -0
  561. package/dist/render/shaders/vertexChannel.js +69 -0
  562. package/dist/render/shaders/water.d.ts +18 -0
  563. package/dist/render/shaders/water.js +354 -0
  564. package/dist/render/shaders/windStreaks.d.ts +14 -0
  565. package/dist/render/shaders/windStreaks.js +129 -0
  566. package/dist/render/shadowCasters.d.ts +107 -0
  567. package/dist/render/shadowCasters.js +1 -0
  568. package/dist/render/shadowMap.d.ts +10 -0
  569. package/dist/render/shadowMap.js +80 -0
  570. package/dist/render/shotPlacement.d.ts +80 -0
  571. package/dist/render/shotPlacement.js +183 -0
  572. package/dist/render/skinPalette.d.ts +90 -0
  573. package/dist/render/skinPalette.js +136 -0
  574. package/dist/render/ssrPass.d.ts +59 -0
  575. package/dist/render/ssrPass.js +196 -0
  576. package/dist/render/surfaceSheet.d.ts +52 -0
  577. package/dist/render/surfaceSheet.js +99 -0
  578. package/dist/render/surfaceTexture.d.ts +197 -0
  579. package/dist/render/surfaceTexture.js +116 -0
  580. package/dist/render/temporalAa.d.ts +104 -0
  581. package/dist/render/temporalAa.js +194 -0
  582. package/dist/render/temporalPass.d.ts +54 -0
  583. package/dist/render/temporalPass.js +135 -0
  584. package/dist/render/textLayout.d.ts +88 -0
  585. package/dist/render/textLayout.js +201 -0
  586. package/dist/render/textRenderer.d.ts +32 -0
  587. package/dist/render/textRenderer.js +176 -0
  588. package/dist/render/thirdPersonCamera.d.ts +272 -0
  589. package/dist/render/thirdPersonCamera.js +479 -0
  590. package/dist/render/trample.d.ts +57 -0
  591. package/dist/render/trample.js +134 -0
  592. package/dist/render/translucentQueue.d.ts +76 -0
  593. package/dist/render/translucentQueue.js +90 -0
  594. package/dist/render/uniformVectorBudget.d.ts +105 -0
  595. package/dist/render/uniformVectorBudget.js +201 -0
  596. package/dist/render/uploadStep.d.ts +14 -0
  597. package/dist/render/uploadStep.js +14 -0
  598. package/dist/render/vertexDefaults.d.ts +48 -0
  599. package/dist/render/vertexDefaults.js +111 -0
  600. package/dist/render/visibility.d.ts +22 -0
  601. package/dist/render/visibility.js +47 -0
  602. package/dist/render/waterDraw.d.ts +57 -0
  603. package/dist/render/waterDraw.js +102 -0
  604. package/dist/render/waterGrid.d.ts +62 -0
  605. package/dist/render/waterGrid.js +151 -0
  606. package/dist/render/waterRenderer.d.ts +163 -0
  607. package/dist/render/waterRenderer.js +165 -0
  608. package/dist/render/wind.d.ts +45 -0
  609. package/dist/render/wind.js +32 -0
  610. package/dist/render/windField.d.ts +34 -0
  611. package/dist/render/windField.js +13 -0
  612. package/dist/render/windStreakDraw.d.ts +73 -0
  613. package/dist/render/windStreakDraw.js +86 -0
  614. package/dist/render/windStreakRenderer.d.ts +37 -0
  615. package/dist/render/windStreakRenderer.js +86 -0
  616. package/dist/scene/node.d.ts +128 -0
  617. package/dist/scene/node.js +319 -0
  618. package/dist/scene/visit.d.ts +38 -0
  619. package/dist/scene/visit.js +43 -0
  620. package/dist/ui/clipMime.d.ts +46 -0
  621. package/dist/ui/clipMime.js +88 -0
  622. package/dist/ui/exportTarget.d.ts +305 -0
  623. package/dist/ui/exportTarget.js +368 -0
  624. package/dist/ui/frameOverlay.d.ts +59 -0
  625. package/dist/ui/frameOverlay.js +76 -0
  626. package/dist/ui/framePacer.d.ts +142 -0
  627. package/dist/ui/framePacer.js +284 -0
  628. package/dist/ui/frameRecorder.d.ts +188 -0
  629. package/dist/ui/frameRecorder.js +221 -0
  630. package/dist/ui/fullscreen.d.ts +72 -0
  631. package/dist/ui/fullscreen.js +92 -0
  632. package/dist/ui/pixelCursor.d.ts +28 -0
  633. package/dist/ui/pixelCursor.js +66 -0
  634. package/dist/ui/splash.d.ts +86 -0
  635. package/dist/ui/splash.js +300 -0
  636. package/dist/ui/stillFrame.d.ts +22 -0
  637. package/dist/ui/stillFrame.js +40 -0
  638. package/package.json +60 -0
  639. package/src/behavior/behaviorTree.ts +346 -0
  640. package/src/build/shaderComments.ts +0 -0
  641. package/src/cinematic/player.ts +209 -0
  642. package/src/cinematic/script.ts +231 -0
  643. package/src/core/bootGate.ts +49 -0
  644. package/src/core/loadTracker.ts +144 -0
  645. package/src/core/loop.ts +211 -0
  646. package/src/core/messageQueue.ts +145 -0
  647. package/src/core/onceSet.ts +65 -0
  648. package/src/core/preferences.ts +177 -0
  649. package/src/core/remoteSave.ts +347 -0
  650. package/src/core/rng.ts +101 -0
  651. package/src/core/stepBudget.ts +136 -0
  652. package/src/core/storage.ts +114 -0
  653. package/src/core/tickTrace.ts +129 -0
  654. package/src/core/timeCurve.ts +175 -0
  655. package/src/core/withDefaults.ts +28 -0
  656. package/src/dev/contactProbe.ts +115 -0
  657. package/src/dev/fpsMeter.ts +101 -0
  658. package/src/environment/celestialClock.ts +385 -0
  659. package/src/geometry/decal.ts +260 -0
  660. package/src/geometry/filmPatch.ts +158 -0
  661. package/src/geometry/growable.ts +165 -0
  662. package/src/geometry/lightVolume.ts +161 -0
  663. package/src/geometry/meshBuilder.ts +1397 -0
  664. package/src/geometry/pixelFont.ts +189 -0
  665. package/src/geometry/ribbon.ts +790 -0
  666. package/src/geometry/shellFill.ts +265 -0
  667. package/src/geometry/spline.ts +659 -0
  668. package/src/geometry/tangents.ts +173 -0
  669. package/src/geometry/textMesh.ts +96 -0
  670. package/src/geometry/treeBuilder.ts +114 -0
  671. package/src/host/display.ts +180 -0
  672. package/src/host/files.ts +77 -0
  673. package/src/host/lifecycle.ts +63 -0
  674. package/src/host/platformServices.ts +23 -0
  675. package/src/host/screen.ts +134 -0
  676. package/src/index.ts +730 -0
  677. package/src/input/actionMap.ts +377 -0
  678. package/src/input/activeDevice.ts +86 -0
  679. package/src/input/gamepadIdentity.ts +131 -0
  680. package/src/input/gamepadMapping.ts +121 -0
  681. package/src/input/input.ts +872 -0
  682. package/src/input/inputHarness.ts +226 -0
  683. package/src/input/rightGesture.ts +76 -0
  684. package/src/input/rumble.ts +138 -0
  685. package/src/input/touchControls.ts +451 -0
  686. package/src/input/typingTarget.ts +26 -0
  687. package/src/math/bounds.ts +153 -0
  688. package/src/math/color.ts +37 -0
  689. package/src/math/exact.ts +274 -0
  690. package/src/math/frustum.ts +115 -0
  691. package/src/math/intersect.ts +228 -0
  692. package/src/math/scalar.ts +109 -0
  693. package/src/math/spring.ts +106 -0
  694. package/src/nav/navGraph.ts +168 -0
  695. package/src/nav/navPath.ts +217 -0
  696. package/src/nav/navSearch.ts +200 -0
  697. package/src/physics/boxSurface.ts +96 -0
  698. package/src/physics/colliderSurface.ts +213 -0
  699. package/src/physics/compositeSurface.ts +111 -0
  700. package/src/physics/heightSurface.ts +234 -0
  701. package/src/physics/ribbonSurface.ts +642 -0
  702. package/src/render/ambientOcclusionPass.ts +200 -0
  703. package/src/render/areaLights.ts +194 -0
  704. package/src/render/areaShadowSet.ts +405 -0
  705. package/src/render/atmosphere.ts +186 -0
  706. package/src/render/backend/api.ts +802 -0
  707. package/src/render/backend/budget.ts +139 -0
  708. package/src/render/backend/createRenderer.ts +343 -0
  709. package/src/render/backend/deadline.ts +37 -0
  710. package/src/render/backend/probe.ts +152 -0
  711. package/src/render/backend/select.ts +288 -0
  712. package/src/render/backend/timer.ts +59 -0
  713. package/src/render/backend/webgl2/instanced.ts +46 -0
  714. package/src/render/backend/webgl2/morphTexture.ts +58 -0
  715. package/src/render/backend/webgl2/renderer.ts +7484 -0
  716. package/src/render/backend/webgl2/skinPaletteTexture.ts +70 -0
  717. package/src/render/backend/webgpu/boltPass.ts +205 -0
  718. package/src/render/backend/webgpu/buffers.ts +553 -0
  719. package/src/render/backend/webgpu/causticsPass.ts +174 -0
  720. package/src/render/backend/webgpu/clusterBinner.ts +259 -0
  721. package/src/render/backend/webgpu/depthPass.ts +261 -0
  722. package/src/render/backend/webgpu/device.ts +148 -0
  723. package/src/render/backend/webgpu/drawCommand.ts +79 -0
  724. package/src/render/backend/webgpu/environmentTexels.ts +96 -0
  725. package/src/render/backend/webgpu/filmPass.ts +123 -0
  726. package/src/render/backend/webgpu/flatPass.ts +635 -0
  727. package/src/render/backend/webgpu/flockPass.ts +163 -0
  728. package/src/render/backend/webgpu/gpuTimestamps.ts +255 -0
  729. package/src/render/backend/webgpu/insetPass.ts +123 -0
  730. package/src/render/backend/webgpu/instanced.ts +55 -0
  731. package/src/render/backend/webgpu/lightVolumePass.ts +203 -0
  732. package/src/render/backend/webgpu/linePass.ts +270 -0
  733. package/src/render/backend/webgpu/morphTexture.ts +61 -0
  734. package/src/render/backend/webgpu/panelPass.ts +138 -0
  735. package/src/render/backend/webgpu/particlePass.ts +370 -0
  736. package/src/render/backend/webgpu/pipelineCache.ts +152 -0
  737. package/src/render/backend/webgpu/plumePass.ts +292 -0
  738. package/src/render/backend/webgpu/pointShadowPass.ts +368 -0
  739. package/src/render/backend/webgpu/postPass.ts +470 -0
  740. package/src/render/backend/webgpu/probePass.ts +218 -0
  741. package/src/render/backend/webgpu/reflectionPass.ts +137 -0
  742. package/src/render/backend/webgpu/renderer.ts +13004 -0
  743. package/src/render/backend/webgpu/scatterPass.ts +354 -0
  744. package/src/render/backend/webgpu/sdfTextPass.ts +220 -0
  745. package/src/render/backend/webgpu/shaderModules.ts +49 -0
  746. package/src/render/backend/webgpu/shaders/clusterBin.wgsl.ts +219 -0
  747. package/src/render/backend/webgpu/skinPaletteRing.ts +105 -0
  748. package/src/render/backend/webgpu/skinPaletteTexture.ts +79 -0
  749. package/src/render/backend/webgpu/skyPass.ts +85 -0
  750. package/src/render/backend/webgpu/surfaceTexturePass.ts +257 -0
  751. package/src/render/backend/webgpu/textPass.ts +224 -0
  752. package/src/render/backend/webgpu/uniformRing.ts +228 -0
  753. package/src/render/backend/webgpu/waterPass.ts +211 -0
  754. package/src/render/backend/webgpu/windStreakPass.ts +196 -0
  755. package/src/render/billboard.ts +108 -0
  756. package/src/render/bloomChain.ts +101 -0
  757. package/src/render/bloomPass.ts +256 -0
  758. package/src/render/boltBatch.ts +141 -0
  759. package/src/render/boltPool.ts +360 -0
  760. package/src/render/boom.ts +123 -0
  761. package/src/render/camera.ts +348 -0
  762. package/src/render/causticsRenderer.ts +171 -0
  763. package/src/render/cinematicCamera.ts +278 -0
  764. package/src/render/clusteredLights.ts +598 -0
  765. package/src/render/colourGrade.ts +109 -0
  766. package/src/render/compute.ts +83 -0
  767. package/src/render/contextLoss.ts +50 -0
  768. package/src/render/debugLines.ts +411 -0
  769. package/src/render/decalPass.ts +124 -0
  770. package/src/render/decalProjector.ts +390 -0
  771. package/src/render/decalQueue.ts +110 -0
  772. package/src/render/depthConvention.ts +383 -0
  773. package/src/render/drawingBuffer.ts +89 -0
  774. package/src/render/emptyTexture.ts +130 -0
  775. package/src/render/envProbeArray.ts +201 -0
  776. package/src/render/equirectToCube.ts +160 -0
  777. package/src/render/flockGeometry.ts +53 -0
  778. package/src/render/flockRenderer.ts +111 -0
  779. package/src/render/frame/arena.ts +93 -0
  780. package/src/render/frame/index.ts +29 -0
  781. package/src/render/frame/replay.ts +50 -0
  782. package/src/render/frame/resources.ts +61 -0
  783. package/src/render/frame/schedule.ts +85 -0
  784. package/src/render/frameView.ts +20 -0
  785. package/src/render/gizmo.ts +923 -0
  786. package/src/render/globalMedium.ts +154 -0
  787. package/src/render/globalMediumPass.ts +323 -0
  788. package/src/render/gpuCapability.ts +244 -0
  789. package/src/render/gpuTimer.ts +182 -0
  790. package/src/render/halfFloat.ts +39 -0
  791. package/src/render/handleRegistry.ts +96 -0
  792. package/src/render/iesProfile.ts +215 -0
  793. package/src/render/imageTexels.ts +109 -0
  794. package/src/render/instancedMesh.ts +187 -0
  795. package/src/render/instances.ts +92 -0
  796. package/src/render/lightBudget.ts +655 -0
  797. package/src/render/lightMatrix.ts +69 -0
  798. package/src/render/lightVolumeDraw.ts +216 -0
  799. package/src/render/lineBatch.ts +180 -0
  800. package/src/render/linePoints.ts +61 -0
  801. package/src/render/livePointShadowSet.ts +285 -0
  802. package/src/render/lod.ts +86 -0
  803. package/src/render/mesh.ts +536 -0
  804. package/src/render/occlusion.ts +406 -0
  805. package/src/render/oitPass.ts +230 -0
  806. package/src/render/orderIndependent.ts +136 -0
  807. package/src/render/particleBatch.ts +299 -0
  808. package/src/render/particleMaterial.ts +84 -0
  809. package/src/render/particlePool.ts +291 -0
  810. package/src/render/pass.ts +203 -0
  811. package/src/render/passTarget.ts +225 -0
  812. package/src/render/pickable.ts +222 -0
  813. package/src/render/planarReflection.ts +233 -0
  814. package/src/render/planarReflectionDraw.ts +87 -0
  815. package/src/render/plumeGeometry.ts +75 -0
  816. package/src/render/plumeMaterial.ts +99 -0
  817. package/src/render/plumeRenderer.ts +272 -0
  818. package/src/render/pointLightSelection.ts +447 -0
  819. package/src/render/pointShadowArray.ts +276 -0
  820. package/src/render/pointShadowBudget.ts +305 -0
  821. package/src/render/pointShadowImage.ts +470 -0
  822. package/src/render/pointShadowMap.ts +228 -0
  823. package/src/render/pointShadowSystem.ts +408 -0
  824. package/src/render/prefilterEnvMap.ts +162 -0
  825. package/src/render/prefilterPass.ts +115 -0
  826. package/src/render/probeGrid.ts +248 -0
  827. package/src/render/rainField.ts +240 -0
  828. package/src/render/reflectionProbe.ts +530 -0
  829. package/src/render/renderQuality.ts +1054 -0
  830. package/src/render/rendererHarness.ts +214 -0
  831. package/src/render/resolutionGovernor.ts +189 -0
  832. package/src/render/scatterDeform.ts +72 -0
  833. package/src/render/sceneTarget.ts +1032 -0
  834. package/src/render/screenSpaceReflection.ts +524 -0
  835. package/src/render/sdfFont.ts +157 -0
  836. package/src/render/sdfTextLayout.ts +206 -0
  837. package/src/render/sdfTextRenderer.ts +233 -0
  838. package/src/render/seaState.ts +55 -0
  839. package/src/render/segmentQuads.ts +92 -0
  840. package/src/render/shader.ts +190 -0
  841. package/src/render/shaders/ambientOcclusion.ts +354 -0
  842. package/src/render/shaders/arcane.ts +103 -0
  843. package/src/render/shaders/bloom.ts +232 -0
  844. package/src/render/shaders/bolt.ts +164 -0
  845. package/src/render/shaders/caustics.ts +169 -0
  846. package/src/render/shaders/conditionals.ts +58 -0
  847. package/src/render/shaders/decalProject.ts +127 -0
  848. package/src/render/shaders/depth.ts +131 -0
  849. package/src/render/shaders/depthOfField.ts +141 -0
  850. package/src/render/shaders/film.ts +285 -0
  851. package/src/render/shaders/fire.ts +180 -0
  852. package/src/render/shaders/flat/directionalShadow.ts +196 -0
  853. package/src/render/shaders/flat/index.ts +502 -0
  854. package/src/render/shaders/flat/lobes.ts +399 -0
  855. package/src/render/shaders/flat/main.ts +1631 -0
  856. package/src/render/shaders/flat/pointShadow.ts +323 -0
  857. package/src/render/shaders/flat/preamble.ts +875 -0
  858. package/src/render/shaders/flat/probeGrid.ts +152 -0
  859. package/src/render/shaders/flat/surface.ts +41 -0
  860. package/src/render/shaders/flock.ts +103 -0
  861. package/src/render/shaders/fog.ts +99 -0
  862. package/src/render/shaders/fullscreen.ts +28 -0
  863. package/src/render/shaders/generated/ambientOcclusion.wgsl.ts +74 -0
  864. package/src/render/shaders/generated/arcane.wgsl.ts +98 -0
  865. package/src/render/shaders/generated/bloom.wgsl.ts +79 -0
  866. package/src/render/shaders/generated/bolt.wgsl.ts +127 -0
  867. package/src/render/shaders/generated/caustics.wgsl.ts +127 -0
  868. package/src/render/shaders/generated/decalProject.wgsl.ts +69 -0
  869. package/src/render/shaders/generated/depth.wgsl.ts +142 -0
  870. package/src/render/shaders/generated/film.wgsl.ts +143 -0
  871. package/src/render/shaders/generated/fire.wgsl.ts +137 -0
  872. package/src/render/shaders/generated/flat.wgsl.ts +9195 -0
  873. package/src/render/shaders/generated/flock.wgsl.ts +82 -0
  874. package/src/render/shaders/generated/fullscreen.wgsl.ts +20 -0
  875. package/src/render/shaders/generated/globalMedium.wgsl.ts +139 -0
  876. package/src/render/shaders/generated/lightVolume.wgsl.ts +242 -0
  877. package/src/render/shaders/generated/line.wgsl.ts +137 -0
  878. package/src/render/shaders/generated/octahedralResolve.wgsl.ts +60 -0
  879. package/src/render/shaders/generated/oitResolve.wgsl.ts +31 -0
  880. package/src/render/shaders/generated/panel.wgsl.ts +57 -0
  881. package/src/render/shaders/generated/particle.wgsl.ts +343 -0
  882. package/src/render/shaders/generated/prefilter.wgsl.ts +69 -0
  883. package/src/render/shaders/generated/rush.wgsl.ts +139 -0
  884. package/src/render/shaders/generated/scatter.wgsl.ts +205 -0
  885. package/src/render/shaders/generated/sdfText.wgsl.ts +78 -0
  886. package/src/render/shaders/generated/sky.wgsl.ts +109 -0
  887. package/src/render/shaders/generated/smoke.wgsl.ts +93 -0
  888. package/src/render/shaders/generated/ssrResolve.wgsl.ts +26 -0
  889. package/src/render/shaders/generated/ssrTrace.wgsl.ts +94 -0
  890. package/src/render/shaders/generated/temporalResolve.wgsl.ts +54 -0
  891. package/src/render/shaders/generated/text.wgsl.ts +107 -0
  892. package/src/render/shaders/generated/water.wgsl.ts +256 -0
  893. package/src/render/shaders/generated/windStreaks.wgsl.ts +82 -0
  894. package/src/render/shaders/gerstner.ts +110 -0
  895. package/src/render/shaders/globalMedium.ts +396 -0
  896. package/src/render/shaders/lightVolume.ts +546 -0
  897. package/src/render/shaders/line.ts +125 -0
  898. package/src/render/shaders/morph.ts +62 -0
  899. package/src/render/shaders/octahedral.ts +170 -0
  900. package/src/render/shaders/octahedralResolve.ts +83 -0
  901. package/src/render/shaders/oitResolve.ts +42 -0
  902. package/src/render/shaders/outputTransform.ts +107 -0
  903. package/src/render/shaders/panel.ts +51 -0
  904. package/src/render/shaders/particle.ts +438 -0
  905. package/src/render/shaders/prefilter.ts +278 -0
  906. package/src/render/shaders/rush.ts +357 -0
  907. package/src/render/shaders/scatter.ts +211 -0
  908. package/src/render/shaders/sdfText.ts +68 -0
  909. package/src/render/shaders/skinning.ts +59 -0
  910. package/src/render/shaders/sky.ts +243 -0
  911. package/src/render/shaders/smoke.ts +89 -0
  912. package/src/render/shaders/ssrResolve.ts +28 -0
  913. package/src/render/shaders/ssrTrace.ts +233 -0
  914. package/src/render/shaders/tangentFrame.ts +70 -0
  915. package/src/render/shaders/temporalResolve.ts +151 -0
  916. package/src/render/shaders/text.ts +156 -0
  917. package/src/render/shaders/vertexChannel.ts +71 -0
  918. package/src/render/shaders/water.ts +356 -0
  919. package/src/render/shaders/windStreaks.ts +130 -0
  920. package/src/render/shadowCasters.ts +124 -0
  921. package/src/render/shadowMap.ts +89 -0
  922. package/src/render/shotPlacement.ts +266 -0
  923. package/src/render/skinPalette.ts +157 -0
  924. package/src/render/ssrPass.ts +241 -0
  925. package/src/render/surfaceSheet.ts +158 -0
  926. package/src/render/surfaceTexture.ts +310 -0
  927. package/src/render/temporalAa.ts +221 -0
  928. package/src/render/temporalPass.ts +153 -0
  929. package/src/render/textLayout.ts +239 -0
  930. package/src/render/textRenderer.ts +201 -0
  931. package/src/render/thirdPersonCamera.ts +578 -0
  932. package/src/render/trample.ts +140 -0
  933. package/src/render/translucentQueue.ts +161 -0
  934. package/src/render/uniformVectorBudget.ts +246 -0
  935. package/src/render/uploadStep.ts +14 -0
  936. package/src/render/vertexDefaults.ts +115 -0
  937. package/src/render/visibility.ts +56 -0
  938. package/src/render/waterDraw.ts +167 -0
  939. package/src/render/waterGrid.ts +180 -0
  940. package/src/render/waterRenderer.ts +352 -0
  941. package/src/render/wind.ts +79 -0
  942. package/src/render/windField.ts +50 -0
  943. package/src/render/windStreakDraw.ts +131 -0
  944. package/src/render/windStreakRenderer.ts +130 -0
  945. package/src/scene/node.ts +336 -0
  946. package/src/scene/visit.ts +82 -0
  947. package/src/ui/clipMime.ts +109 -0
  948. package/src/ui/exportTarget.ts +491 -0
  949. package/src/ui/frameOverlay.ts +159 -0
  950. package/src/ui/framePacer.ts +351 -0
  951. package/src/ui/frameRecorder.ts +333 -0
  952. package/src/ui/fullscreen.ts +113 -0
  953. package/src/ui/pixelCursor.ts +99 -0
  954. package/src/ui/splash.ts +347 -0
  955. 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
+ }
@@ -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
+ }