@volter/game-editor 0.5.65

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 (653) hide show
  1. package/BUNDLED_NOTICES +11228 -0
  2. package/LICENSE +686 -0
  3. package/LICENSE-BLENDER +1409 -0
  4. package/LICENSE-MCP +21 -0
  5. package/NOTICE +21 -0
  6. package/catalog/entries/audio.json +14 -0
  7. package/catalog/entries/bake.json +36 -0
  8. package/catalog/entries/blender.json +17 -0
  9. package/catalog/entries/react-root.json +24 -0
  10. package/catalog/entries/reflections.json +29 -0
  11. package/catalog/entries/static-batch.json +25 -0
  12. package/catalog/project-source/LICENSE +37 -0
  13. package/catalog/project-source/src/contributions/bake.kind.ts +40 -0
  14. package/catalog/project-source/src/contributions/builder-document.tsx +65 -0
  15. package/catalog/project-source/src/contributions/builder-state.ts +27 -0
  16. package/catalog/project-source/src/contributions/builder-ui.tsx +61 -0
  17. package/catalog/project-source/src/contributions/module-source.ts +502 -0
  18. package/catalog/project-source/src/contributions/pages.finder.ts +61 -0
  19. package/catalog/project-source/src/lib/audio/sfx.ts +255 -0
  20. package/catalog/project-source/src/lib/bake/asset-seed.ts +128 -0
  21. package/catalog/project-source/src/lib/bake/bake-schema.ts +65 -0
  22. package/catalog/project-source/src/lib/bake/clip-layering.ts +203 -0
  23. package/catalog/project-source/src/lib/bake/gltf-bake.ts +657 -0
  24. package/catalog/project-source/src/lib/bake/mesh-slice.ts +157 -0
  25. package/catalog/project-source/src/lib/bake/node-image.ts +463 -0
  26. package/catalog/project-source/src/lib/bake/object3d-bake.ts +121 -0
  27. package/catalog/project-source/src/lib/bake/object3d-lifecycle.ts +15 -0
  28. package/catalog/project-source/src/lib/bake/object3d-source.ts +8 -0
  29. package/catalog/project-source/src/lib/bake/params.ts +75 -0
  30. package/catalog/project-source/src/lib/bake/rest-relative-animation.ts +217 -0
  31. package/catalog/project-source/src/lib/bake/use-model.ts +95 -0
  32. package/catalog/project-source/src/lib/react-root/index.ts +20 -0
  33. package/catalog/project-source/src/lib/react-root/react-root-adapter.tsx +57 -0
  34. package/catalog/project-source/src/lib/reflections/ReflectionProbe.tsx +201 -0
  35. package/catalog/project-source/src/lib/reflections/index.ts +19 -0
  36. package/catalog/project-source/src/lib/reflections/probe-controller.ts +75 -0
  37. package/catalog/project-source/src/lib/reflections/reflection-probe-registry.ts +402 -0
  38. package/catalog/project-source/src/lib/reflections/volume-reflection-material.ts +416 -0
  39. package/catalog/project-source/src/lib/static-batch/Frozen.tsx +91 -0
  40. package/catalog/project-source/src/lib/static-batch/freeze.ts +579 -0
  41. package/catalog/project-source/src/lib/static-batch/index.ts +44 -0
  42. package/catalog/project-source/src/lib/static-batch/mutation-watch.ts +149 -0
  43. package/catalog/project-source/src/lib/static-batch/shadow-cache.ts +171 -0
  44. package/catalog/project-source/src/tools/bake-module.tool.ts +139 -0
  45. package/catalog/project-source/src/tools/bake-preview.tool.ts +475 -0
  46. package/dist/.vite/manifest.json +8304 -0
  47. package/dist/assets/AssetBudgetPanel-J9--TZPU.js +23 -0
  48. package/dist/assets/AudioViewer-CR7333fe.js +1 -0
  49. package/dist/assets/BVHLoader-6bQIXhMX.js +1 -0
  50. package/dist/assets/BufferGeometryUtils-Nz37EVXf.js +1 -0
  51. package/dist/assets/CCDIKSolver-CD7vLpsK.js +1 -0
  52. package/dist/assets/CSS3DRenderer-CL7ABLVK.js +1 -0
  53. package/dist/assets/CanvasSceneViewport-Bpi6gVTC.js +1 -0
  54. package/dist/assets/ColladaLoader-aVOPIsCh.js +3 -0
  55. package/dist/assets/ColorInput-DQBNrW-K.js +1 -0
  56. package/dist/assets/ConvexGeometry-CAzXlPVG.js +1 -0
  57. package/dist/assets/ConvexHull-BINCESFp.js +1 -0
  58. package/dist/assets/CopyShader-BzTUYzf6.js +24 -0
  59. package/dist/assets/DecalGeometry-160KRdfg.js +1 -0
  60. package/dist/assets/EXRLoader-Cdans_oJ.js +1 -0
  61. package/dist/assets/EffectComposer-DQxfsXBZ.js +1 -0
  62. package/dist/assets/EntityModelDocument-Ccvw66N9.js +1 -0
  63. package/dist/assets/EnvironmentAssetDocument-Dg-Qq6O6.js +1 -0
  64. package/dist/assets/FBXLoader-B4MoUtAn.js +1 -0
  65. package/dist/assets/Fbo-Dz-Soul3.js +1 -0
  66. package/dist/assets/FontLoader-CvGoVI5a.js +2 -0
  67. package/dist/assets/GLTFExporter-HgrCle4L.js +1 -0
  68. package/dist/assets/GameplaySessionTimeline-B52W3FVZ.js +1 -0
  69. package/dist/assets/Gltf-UHVWKz65.js +2 -0
  70. package/dist/assets/HDRLoader-THU88oVD.js +5 -0
  71. package/dist/assets/ImageViewer-Tn7s_MnW.js +1 -0
  72. package/dist/assets/InspectorCanvasPreview-CEr_Kxna.js +1 -0
  73. package/dist/assets/InspectorObjectPreview-CVejvLRg.js +1 -0
  74. package/dist/assets/JsonAssetDocument-C7VGcLhu.js +3 -0
  75. package/dist/assets/LineSegments2-CsOpKSiM.js +370 -0
  76. package/dist/assets/MTLLoader-_Xzd4_0p.js +2 -0
  77. package/dist/assets/MarchingCubes-Bsp4wrzd.js +1 -0
  78. package/dist/assets/MeshBVH-BiDHDcu-.js +1 -0
  79. package/dist/assets/ModelAssetDocument-F5GACirk.js +1 -0
  80. package/dist/assets/NonThreeAuthoringBootstrap-C3woOMxX.js +1 -0
  81. package/dist/assets/OBJLoader-BhIC6Hwo.js +5 -0
  82. package/dist/assets/Object3DDocumentViewport-DB7T0NTl.js +2 -0
  83. package/dist/assets/Object3DPreview-DL8oi7Xs.js +2 -0
  84. package/dist/assets/OnlineAssetDetail-C6z9RvYK.js +2 -0
  85. package/dist/assets/OrbitControls-CM3bPray.js +1 -0
  86. package/dist/assets/OrbitControls-DLpayAaK.js +1 -0
  87. package/dist/assets/OrthographicCamera-bQozawrh.js +1 -0
  88. package/dist/assets/PLYLoader-DYQqs5Ik.js +2 -0
  89. package/dist/assets/PerspectiveCamera-CQ2lh01o.js +1 -0
  90. package/dist/assets/PlayBar-BR-Vg3Jb.js +2 -0
  91. package/dist/assets/RGBELoader-BgBcQv8j.js +1 -0
  92. package/dist/assets/RectAreaLightUniformsLib-CMMoWfll.js +1 -0
  93. package/dist/assets/RenderPass-DPrn-Uky.js +1 -0
  94. package/dist/assets/ResolutionPicker-C67vs1F3.js +1 -0
  95. package/dist/assets/RootSelectionOverlay-BZPlxmXU.js +1 -0
  96. package/dist/assets/RoundedBox-BDGBg6QZ.js +1 -0
  97. package/dist/assets/RoundedBoxGeometry-CyUuYPfW.js +1 -0
  98. package/dist/assets/STLLoader-Dyv3lsxY.js +1 -0
  99. package/dist/assets/SelectionBox-D_75KrNW.js +1 -0
  100. package/dist/assets/ShaderPass-QYRpPuFJ.js +1 -0
  101. package/dist/assets/ShadowEditor-DkImwu1Y.js +1 -0
  102. package/dist/assets/SimplifyModifier-C8ayvRzd.js +1 -0
  103. package/dist/assets/SkeletonUtils-Cps8GOC6.js +1 -0
  104. package/dist/assets/Sky-CQKCgYDs.js +154 -0
  105. package/dist/assets/SourceAssetViewer-2SWQoUut.js +12 -0
  106. package/dist/assets/StageHost-BN-IoTef.js +2 -0
  107. package/dist/assets/StoryPreviewMount-DjyxRCXu.js +1 -0
  108. package/dist/assets/TDSLoader-D_T8XJ81.js +1 -0
  109. package/dist/assets/TextGeometry-DOWAEUV0.js +1 -0
  110. package/dist/assets/ThreeBoardDocument-CVncZyIq.js +2 -0
  111. package/dist/assets/ThreeIsolationSceneContent-C8C8whSF.js +1 -0
  112. package/dist/assets/ToolObject3DPreview-BRoDWe4Q.js +1 -0
  113. package/dist/assets/TrackballControls-DfznuQTh.js +1 -0
  114. package/dist/assets/TransientHint-BB1fwrvK.js +1 -0
  115. package/dist/assets/UnrealBloomPass-CR-cS_K5.js +83 -0
  116. package/dist/assets/VideoViewer-C6kocgIU.js +1 -0
  117. package/dist/assets/_commonjsHelpers-D6-XlEtG.js +1 -0
  118. package/dist/assets/active-ingest-CT6jSGhr.js +3 -0
  119. package/dist/assets/adapter-surface-Y37Nzcyw.js +1 -0
  120. package/dist/assets/after-paint-CB4bz1-e.js +1 -0
  121. package/dist/assets/agx-base-srgb-BjWZJgrZ.lut +0 -0
  122. package/dist/assets/agx-look-medium-high-contrast-D5F_ob1L.lut +0 -0
  123. package/dist/assets/agx-look-punchy-dxsnycNs.lut +0 -0
  124. package/dist/assets/animation-clock-CnjZqfJp.js +1 -0
  125. package/dist/assets/asset-budget-asset.menu-Di3KiQCd.js +1 -0
  126. package/dist/assets/asset-budget.action-DCzzcuTh.js +1 -0
  127. package/dist/assets/asset-budget.document-BWU8wnVW.js +1 -0
  128. package/dist/assets/asset-budget.menu-BGZpT_31.js +1 -0
  129. package/dist/assets/asset-editor-persistence-BBaONOJt.js +1 -0
  130. package/dist/assets/asset-loaders-BOy5Ss8k.js +2 -0
  131. package/dist/assets/asset-parse-error-BHMwBRU3.js +3 -0
  132. package/dist/assets/assets-BuSoGjBX.js +1 -0
  133. package/dist/assets/audio-meter-CyiToeUW.js +1 -0
  134. package/dist/assets/audio-unlock.service-CfUgUQVy.js +1 -0
  135. package/dist/assets/audio.utility-C6K6jem8.js +1 -0
  136. package/dist/assets/authoring-CgcOFhGS.js +1 -0
  137. package/dist/assets/autoplay.service-BZBGNSvt.js +1 -0
  138. package/dist/assets/axe-LkjAB6Lv.js +30 -0
  139. package/dist/assets/babylon-authoring-adapter-CL02gWDn.js +1 -0
  140. package/dist/assets/binding-Bmxqznjk.js +1 -0
  141. package/dist/assets/binding-identity-DcTpbvyg.js +1 -0
  142. package/dist/assets/binding-resolver-Dsh-6Vor.js +2 -0
  143. package/dist/assets/blender-emscripten-engine-9ZIRYNhe.js +2 -0
  144. package/dist/assets/blender-node-editor.document-iIDkB9sI.js +1 -0
  145. package/dist/assets/blender-properties-tab-C5CyPydi.js +3 -0
  146. package/dist/assets/blender-runtime-host-BpBwGv7r.js +4 -0
  147. package/dist/assets/blender-runtime-skin-DyQ9B6CR.js +7140 -0
  148. package/dist/assets/blender-runtime.document-lIYhhPtv.js +8 -0
  149. package/dist/assets/blender-timeline.document-77fx96N7.js +1 -0
  150. package/dist/assets/blender-uv-editor.document-fsT7B4gV.js +1 -0
  151. package/dist/assets/blender-version.status-o6dBm3n6.js +1 -0
  152. package/dist/assets/blender-wali-engine-wTOcrOMC.js +2 -0
  153. package/dist/assets/blender.command-BtJeWk-A.js +1 -0
  154. package/dist/assets/blender.keymap-GAQgeklK.js +1 -0
  155. package/dist/assets/blender.status-ujwGU6dU.js +1 -0
  156. package/dist/assets/blender.style-Dcem5f_T.js +1 -0
  157. package/dist/assets/board-guides-DziKSTss.js +1 -0
  158. package/dist/assets/body-marks-h_xDxiDE.js +1 -0
  159. package/dist/assets/bridge.command-o5gDNEwa.js +3 -0
  160. package/dist/assets/browserAll-DeWblVez.js +1 -0
  161. package/dist/assets/build-profiles.document-kW8iw8Xj.js +2 -0
  162. package/dist/assets/build-progress.status-BNRLytg2.js +1 -0
  163. package/dist/assets/build-session-C_sg3CEn.js +9 -0
  164. package/dist/assets/build.action-lYjTLb7K.js +1 -0
  165. package/dist/assets/build.command-DIGgUPU_.js +1 -0
  166. package/dist/assets/build.header-CKajx5U3.js +1 -0
  167. package/dist/assets/build.menu-BdU0QXny.js +1 -0
  168. package/dist/assets/build.service-CbBAyeu3.js +1 -0
  169. package/dist/assets/bus-mixer-CGfWDP3C.js +1 -0
  170. package/dist/assets/camera-KEsKvOL7.js +1 -0
  171. package/dist/assets/camera-runtime.inspector-B7unX4g1.js +1 -0
  172. package/dist/assets/canvas-entry-runtime-SfBxaR9M.js +2 -0
  173. package/dist/assets/capability-coverage-Czas4C18.js +7 -0
  174. package/dist/assets/chrome-trace-YZHMz60-.js +1 -0
  175. package/dist/assets/client-DNXj_opT.js +25 -0
  176. package/dist/assets/clip-planes-CnAI6DZn.js +1 -0
  177. package/dist/assets/collaboration-presence-DLoZ7EA3.js +1 -0
  178. package/dist/assets/collider-Bw0mXlsW.js +1 -0
  179. package/dist/assets/collider-dimensions-9xoFADXN.js +1 -0
  180. package/dist/assets/collision-system-DpNUJRJ3.js +1 -0
  181. package/dist/assets/command-results-CUQD49AB.js +1 -0
  182. package/dist/assets/component-board-registry-DrIa2csL.js +1 -0
  183. package/dist/assets/component-board.service-DCwcUssB.js +2 -0
  184. package/dist/assets/component-board.service-DidCyM4O.js +2 -0
  185. package/dist/assets/component-verbs.command-7xzfjGMZ.js +1 -0
  186. package/dist/assets/component-verbs.service-Bv9jId3q.js +1 -0
  187. package/dist/assets/config-CEZk921y.js +6 -0
  188. package/dist/assets/configurations-DTBMdaTL.js +1 -0
  189. package/dist/assets/connection.status-BifnQdOs.js +1 -0
  190. package/dist/assets/console-bridge-CHcb-xk5.js +1 -0
  191. package/dist/assets/constraint-De8f1Uiq.js +1 -0
  192. package/dist/assets/constraints.inspector-B9U9Yj-u.js +1 -0
  193. package/dist/assets/countdown-timer-CUm74dom.js +1 -0
  194. package/dist/assets/coverage.service-VTX5Mcsx.js +3 -0
  195. package/dist/assets/crash-null-boundary-v3a0uEgw.js +1 -0
  196. package/dist/assets/create-runtime-CVCc1BDx.js +1 -0
  197. package/dist/assets/curve-7Q79VgU4.js +1 -0
  198. package/dist/assets/data-asset-4hjS642k.js +5 -0
  199. package/dist/assets/data-check-core-CQEjuFyt.js +1 -0
  200. package/dist/assets/data-ref-CQI28C0D.js +1 -0
  201. package/dist/assets/debug-bridge-CCohG-d-.js +1 -0
  202. package/dist/assets/debug-registry-Dgvitx8M.js +1 -0
  203. package/dist/assets/defaults-DKiBJCPN.js +1 -0
  204. package/dist/assets/deferred-commands-CEMmvL47.js +1 -0
  205. package/dist/assets/deferred-ingest-play-DCJi_Pgu.js +2 -0
  206. package/dist/assets/design-time-layers-wYgOTgni.js +1 -0
  207. package/dist/assets/design-time-mount-registry-DUpXCg1U.js +1 -0
  208. package/dist/assets/design-time-mount.service-BzY21e1F.js +2 -0
  209. package/dist/assets/design-time-react-mount-DM9WLrF2.js +1 -0
  210. package/dist/assets/dev-build-gDYrq68M.js +1 -0
  211. package/dist/assets/directional-shadow-fit-BVkOKAv2.js +1 -0
  212. package/dist/assets/document-preview-three-Kbg2GCLm.js +1 -0
  213. package/dist/assets/dom-authoring-adapter-CY8C7f4T.js +1 -0
  214. package/dist/assets/draco3d-BBUTcNkz.js +1 -0
  215. package/dist/assets/draco_decoder-DsQ12WqX.wasm +0 -0
  216. package/dist/assets/draco_encoder-2Tcju8Ns.wasm +0 -0
  217. package/dist/assets/edit-mode-audio.service-Bzetwd5B.js +1 -0
  218. package/dist/assets/edit-mode-authoring-B47TfLqu.js +1 -0
  219. package/dist/assets/edit-mode-networking.service-YCX6RRb_.js +1 -0
  220. package/dist/assets/editor-api-BoJIcyZG.js +1 -0
  221. package/dist/assets/editor-port-C_FeBdeV.js +1 -0
  222. package/dist/assets/editor-presentation-activity-C7SNSmTd.js +1 -0
  223. package/dist/assets/entry-adjudication-Cq8Yeb74.js +1 -0
  224. package/dist/assets/environment-capture-7himRh2L.js +1 -0
  225. package/dist/assets/esbuild-BHljloGq.wasm +0 -0
  226. package/dist/assets/events-156d8d12.esm-ErOhDXXB.js +36 -0
  227. package/dist/assets/extend-B-eOccUm.js +36 -0
  228. package/dist/assets/extends-CF3RwP-h.js +1 -0
  229. package/dist/assets/eyedropper-session-bjPXnfeX.js +1 -0
  230. package/dist/assets/fflate.module-DPuTF8aG.js +6 -0
  231. package/dist/assets/filmic-srgb-Ct35FIH6.lut +0 -0
  232. package/dist/assets/first-party-audio-system-DxnGJOER.js +1 -0
  233. package/dist/assets/first-party-navigation-system-CL5Bquub.js +1 -0
  234. package/dist/assets/fork-menu-BoVyw2Wu.js +1 -0
  235. package/dist/assets/frame-debugger-store-D1Mf_5up.js +1 -0
  236. package/dist/assets/frame-delta-D2nsw_Ht.js +1 -0
  237. package/dist/assets/frame-pacing-D5acoOzO.js +1 -0
  238. package/dist/assets/frame-selector-cache-cCeUbcjG.js +1 -0
  239. package/dist/assets/game-DHOZVb-7.js +1 -0
  240. package/dist/assets/game-contract-seams-a5YXejOu.js +1 -0
  241. package/dist/assets/game-css-scope-transform-Eng4wS8E.js +33 -0
  242. package/dist/assets/game-document.service-DbRfx2V0.js +1 -0
  243. package/dist/assets/game-eval.command-D-7Dxbj_.js +2 -0
  244. package/dist/assets/game-input-seams-CIQdetRw.js +1 -0
  245. package/dist/assets/game-loop-CZvXlY00.js +1 -0
  246. package/dist/assets/game-module-access-B2mFxv-i.js +1 -0
  247. package/dist/assets/game.layout-CBASrvQu.js +1 -0
  248. package/dist/assets/gameplay-export-BoKXm51x.js +1 -0
  249. package/dist/assets/gameplay-replay-e5umMlXv.js +1 -0
  250. package/dist/assets/gameplay-rng-trap-CTNhm-UW.js +3 -0
  251. package/dist/assets/gameplay.command-DxcVYX6F.js +1 -0
  252. package/dist/assets/generation-DhwCUHPf.css +1 -0
  253. package/dist/assets/generation-jobs-BQrXbGp_.js +1 -0
  254. package/dist/assets/generation.service-CDIgObuw.js +1 -0
  255. package/dist/assets/generations-DzUogZsM.js +1 -0
  256. package/dist/assets/generations.status-CgOUBCum.js +1 -0
  257. package/dist/assets/hierarchy-marks-BLPfSIym.js +1 -0
  258. package/dist/assets/host-pointer-DbGSCjE9.js +1 -0
  259. package/dist/assets/hosted-asset-materialization-CiIvWkGU.js +2 -0
  260. package/dist/assets/ibl-override-material-BlmCxFKq.js +6 -0
  261. package/dist/assets/index-96FBF1Oj.js +1 -0
  262. package/dist/assets/index-BAWkB0dv.js +1 -0
  263. package/dist/assets/index-BDnS2b6S.js +1 -0
  264. package/dist/assets/index-BHp07vN0.js +2 -0
  265. package/dist/assets/index-BMxv2MNV.js +1 -0
  266. package/dist/assets/index-BP6wv2A0.js +5 -0
  267. package/dist/assets/index-BcCBqgM_.js +952 -0
  268. package/dist/assets/index-Bge9JUr6.js +1 -0
  269. package/dist/assets/index-BjTCPEQ7.js +134 -0
  270. package/dist/assets/index-BncK9THk.js +1 -0
  271. package/dist/assets/index-CJbYy-CF.js +3 -0
  272. package/dist/assets/index-CVCb_ImQ.js +1 -0
  273. package/dist/assets/index-CZd9o7Lu.js +1 -0
  274. package/dist/assets/index-CanA16PU.js +2 -0
  275. package/dist/assets/index-CinJrH5C.js +9 -0
  276. package/dist/assets/index-CtzuWnCS.js +1 -0
  277. package/dist/assets/index-D2fNXpHa.css +1 -0
  278. package/dist/assets/index-DUpHH6JR.js +3120 -0
  279. package/dist/assets/index-DUqP1RMl.js +1 -0
  280. package/dist/assets/index-D_NuPfjr.js +9 -0
  281. package/dist/assets/index-Da9JhEvW.js +25 -0
  282. package/dist/assets/index-DgapqSPi.js +7 -0
  283. package/dist/assets/index-FUuS4qwW.js +562 -0
  284. package/dist/assets/index-GIL7oGEO.js +4894 -0
  285. package/dist/assets/index-IEjydI9d.js +1 -0
  286. package/dist/assets/index-OrYXPk3Z.js +487 -0
  287. package/dist/assets/index-V1R-e5Bd.js +1 -0
  288. package/dist/assets/index-bQE2NA0D.js +1 -0
  289. package/dist/assets/index-gHZae-lw.js +13 -0
  290. package/dist/assets/index-mjWQmGhM.js +1 -0
  291. package/dist/assets/index-nmcBqr7Y.js +1 -0
  292. package/dist/assets/inference-diagnostics-Dhmtfbq_.js +1 -0
  293. package/dist/assets/ingest-BbYMC2vQ.js +1 -0
  294. package/dist/assets/ingest-boot-viewport-D5rI_Kk_.js +1 -0
  295. package/dist/assets/ingest-siblings-Bop2kqVl.js +1 -0
  296. package/dist/assets/ingest-source-persistence-C_6Hiyra.js +1 -0
  297. package/dist/assets/ingest.service-BTDnQfM1.js +1 -0
  298. package/dist/assets/input-manager-DH_hGW6d.js +1 -0
  299. package/dist/assets/input-router-BNQvtIqw.js +1 -0
  300. package/dist/assets/inspect-BZfi3mmo.js +1 -0
  301. package/dist/assets/inspection-CObLhnrs.js +1 -0
  302. package/dist/assets/instance-fork-actions-D3sRzS3K.js +1 -0
  303. package/dist/assets/instances.command-D6UkZNO8.js +1 -0
  304. package/dist/assets/instruments-CKR02Y8I.js +1 -0
  305. package/dist/assets/json-history-resource-BbxllWfV.js +1 -0
  306. package/dist/assets/jsx-runtime-DPjLkJKQ.js +9 -0
  307. package/dist/assets/light-D-_wsKTq.js +1 -0
  308. package/dist/assets/light-camera-factory-CWbbe9gI.js +1 -0
  309. package/dist/assets/lil-gui.module.min-BF55BEwA.js +10 -0
  310. package/dist/assets/live-behaviors-Bxq49Maz.js +1 -0
  311. package/dist/assets/live-gesture-lock-DJbrjOqf.js +1 -0
  312. package/dist/assets/loader-CaF_I7Yt.js +1 -0
  313. package/dist/assets/logger-Dqis-7W1.js +1 -0
  314. package/dist/assets/loop-gate-report-N52EWFGD.js +1 -0
  315. package/dist/assets/matcap-texture-CVfalpWT.js +1 -0
  316. package/dist/assets/material-CpAdjDxn.js +1 -0
  317. package/dist/assets/material-factory-Bz6h__6g.js +1 -0
  318. package/dist/assets/mesh-B3WPtNKO.js +1 -0
  319. package/dist/assets/mesh-shadow-CZnXrw_l.js +1 -0
  320. package/dist/assets/mikktspace.module-DO88SLib.js +1 -0
  321. package/dist/assets/model-asset-sections-CFvvihfx.css +1 -0
  322. package/dist/assets/model-asset-sections.service-CHhFS3ZX.js +1 -0
  323. package/dist/assets/model.layout-BJUEQYUI.js +1 -0
  324. package/dist/assets/models.finder-G2jQgIRu.js +1 -0
  325. package/dist/assets/module-mode-DVBLT9d-.js +2 -0
  326. package/dist/assets/mount-canvas-ingest-root-DDuAWf_C.js +2 -0
  327. package/dist/assets/mount-dom-ingest-root-D_EiBgpn.js +2 -0
  328. package/dist/assets/mount-game-6t9cKNo4.js +1 -0
  329. package/dist/assets/mount-ingest-root-glv2SSWf.js +2 -0
  330. package/dist/assets/mount-manifest-CGVxhmAw.js +1 -0
  331. package/dist/assets/mount-readiness-Ds0HvvLH.js +4 -0
  332. package/dist/assets/mount-three-ingest-root-hrUt9VVU.js +1 -0
  333. package/dist/assets/mounted-authoring-Dmg5xmhP.js +1 -0
  334. package/dist/assets/mounted-story-viewport-source-DjP6RA9U.js +1 -0
  335. package/dist/assets/native-debug-module-CWicoSGD.js +1 -0
  336. package/dist/assets/native-entry-surface-BE8LJNdu.js +1 -0
  337. package/dist/assets/navigation-CIiCx-SM.js +1 -0
  338. package/dist/assets/navmesh-workflow-store-Cmnm57TB.js +1 -0
  339. package/dist/assets/navmesh.menu-CAKiH8PW.js +1 -0
  340. package/dist/assets/navmesh.service-jgDWlgj1.js +1 -0
  341. package/dist/assets/network.utility-CEu5nHf7.js +1 -0
  342. package/dist/assets/object-marks-DwvIEBOK.js +1 -0
  343. package/dist/assets/object3d-authoring-subject-CH5sI2oP.js +1 -0
  344. package/dist/assets/output-DK8waum9.js +195 -0
  345. package/dist/assets/particles-Y626p22p.js +1 -0
  346. package/dist/assets/particles-factory-DnLOHXT8.js +1 -0
  347. package/dist/assets/pasteboard-materialize-BqSS4QzV.js +20 -0
  348. package/dist/assets/pasteboard.action-DU3UHtJG.js +2 -0
  349. package/dist/assets/performance-profiler-D_Jey87L.js +1 -0
  350. package/dist/assets/physics-registry-B2Jkp8e6.js +1 -0
  351. package/dist/assets/physics-registry-CUB9cT9p.js +1 -0
  352. package/dist/assets/pixi-authoring-adapter-CjibysC3.js +1 -0
  353. package/dist/assets/pixi-live-write-target-DuWydlWb.js +1 -0
  354. package/dist/assets/pixi-primitive-DlWbUPN9.js +1 -0
  355. package/dist/assets/pixi-react-root-factory-DYsznYRQ.js +1 -0
  356. package/dist/assets/pixi-story-model-DNkfnWUV.js +1 -0
  357. package/dist/assets/pixi-transform-channels-VjdohT11.js +1 -0
  358. package/dist/assets/play-mode-BFU2PCkG.js +22 -0
  359. package/dist/assets/play.command-BpqqLqkq.js +2 -0
  360. package/dist/assets/playtest-BXIL1JEF.js +1 -0
  361. package/dist/assets/pose-guard-6Osb2cFu.js +1 -0
  362. package/dist/assets/presentation-BPP5pXeQ.js +1 -0
  363. package/dist/assets/product-DFhyARJj.js +1 -0
  364. package/dist/assets/profiler.action-CaXJDp3t.js +1 -0
  365. package/dist/assets/profiler.menu-BIMF6Bi4.js +1 -0
  366. package/dist/assets/profiler.utility-BExw9wBO.js +1 -0
  367. package/dist/assets/project-authoring-session-Bnt6icLr.js +2 -0
  368. package/dist/assets/project-provenance-BoP3nrle.js +1 -0
  369. package/dist/assets/prompt-labels-DSMdM2_B.js +1 -0
  370. package/dist/assets/properties-bone-constraints.inspector-ByT6p7S-.js +1 -0
  371. package/dist/assets/properties-bone.inspector-z4qJwKO5.js +1 -0
  372. package/dist/assets/properties-collection.inspector-D0_3ijWU.js +1 -0
  373. package/dist/assets/properties-constraints.inspector-CESzjuls.js +1 -0
  374. package/dist/assets/properties-data.inspector-hG8Wgyzb.js +1 -0
  375. package/dist/assets/properties-material.inspector-CzY0JCQ6.js +1 -0
  376. package/dist/assets/properties-modifiers.inspector-3dDhwf7g.js +1 -0
  377. package/dist/assets/properties-object.inspector-CiarfxkT.js +1 -0
  378. package/dist/assets/properties-output.inspector-DKJxmKSD.js +1 -0
  379. package/dist/assets/properties-particles.inspector-CCEdYWGm.js +1 -0
  380. package/dist/assets/properties-physics.inspector-B2c0KUyA.js +1 -0
  381. package/dist/assets/properties-render.inspector-Bcm0HLRW.js +1 -0
  382. package/dist/assets/properties-scene.inspector-PIM_eTb_.js +1 -0
  383. package/dist/assets/properties-texture.inspector-CgFlnyr8.js +1 -0
  384. package/dist/assets/properties-view-layer.inspector-DGjF_Aqo.js +1 -0
  385. package/dist/assets/properties-world.inspector-CrMvaRvB.js +1 -0
  386. package/dist/assets/r3f-design-session-D-4yyDO9.js +2 -0
  387. package/dist/assets/r3f-physics-binding-BBo8oma9.js +1 -0
  388. package/dist/assets/r3f-root-factory-z9llD1OU.js +1 -0
  389. package/dist/assets/r3f-source-authoring-adapter-w6Bc60K-.js +13 -0
  390. package/dist/assets/rapier-physics-adapter-CaZqWLu0.js +1 -0
  391. package/dist/assets/rapier-physics-bridge-CMoeVo3Y.js +1 -0
  392. package/dist/assets/react-18-By2b4xR9.js +1 -0
  393. package/dist/assets/react-inspector.service-B_neRnSK.js +1 -0
  394. package/dist/assets/react-root-CEz5NTck.js +1 -0
  395. package/dist/assets/react-story-board-BDDwiE2H.js +1 -0
  396. package/dist/assets/react-three-fiber.esm-CycrbDlA.js +1 -0
  397. package/dist/assets/react-three-rapier.esm-CEfKpvxT.js +1 -0
  398. package/dist/assets/react-world-authoring-adapter-DmrwM3py.js +1 -0
  399. package/dist/assets/realm-services-CobQsq_X.js +1 -0
  400. package/dist/assets/rebind-controller-Dtq19Vb3.js +1 -0
  401. package/dist/assets/recast-navigation.wasm-compat-Dsoa_MD-.js +1 -0
  402. package/dist/assets/reflection-probe-Don-M3Fj.js +1 -0
  403. package/dist/assets/reflection-probe-capture.inspector-CmFUoJCx.js +1 -0
  404. package/dist/assets/register-render-vitals-BiZk29b2.js +1 -0
  405. package/dist/assets/registry-02YZjMNp.js +1 -0
  406. package/dist/assets/relative-path-guard-GiM7Lsz8.js +1 -0
  407. package/dist/assets/render-audio-control-vMRlePWb.js +1 -0
  408. package/dist/assets/render-batch-system-0vq7p0VC.js +1 -0
  409. package/dist/assets/render-census-BrQX_CXv.js +1 -0
  410. package/dist/assets/render-control-Df3yTiyr.js +1 -0
  411. package/dist/assets/render-env-D2IV2x5k.js +1 -0
  412. package/dist/assets/render-features-CPQ_e568.js +1 -0
  413. package/dist/assets/render-seed-DF4JHy7P.js +1 -0
  414. package/dist/assets/render-settings-Bw4W9SYF.js +1 -0
  415. package/dist/assets/render-vitals-BZ5HtvMi.js +1 -0
  416. package/dist/assets/renderer-config-BqG4O8i9.js +1 -0
  417. package/dist/assets/resolve-three-SZE_WWUM.js +702 -0
  418. package/dist/assets/root-seam-contract-Z0VWX3Bk.js +1 -0
  419. package/dist/assets/rrweb-Cd2ifIRP.js +142 -0
  420. package/dist/assets/run-ticks-settled-C4ksViyA.js +1 -0
  421. package/dist/assets/runtime-inspection-l2iFQSsg.js +1 -0
  422. package/dist/assets/scene-capture-BQKzU0NT.js +1 -0
  423. package/dist/assets/scene-capture-CGYF-Viw.js +1 -0
  424. package/dist/assets/scene-document.service-qkDjUrlP.js +2 -0
  425. package/dist/assets/scene-framing-Cat0GtyJ.js +1 -0
  426. package/dist/assets/scene-index-B6BZOHMk.js +1 -0
  427. package/dist/assets/scene-query-C7_N-TpI.js +1 -0
  428. package/dist/assets/schema-kl9-2B_J.js +1 -0
  429. package/dist/assets/sculpt.layout-zJF55yCR.js +1 -0
  430. package/dist/assets/seeded-random-i3mtgBKZ.js +1 -0
  431. package/dist/assets/session-CZ5JPg-z.js +4877 -0
  432. package/dist/assets/setup-audio-S8GQF91f.js +1 -0
  433. package/dist/assets/setup-particles-GCXlnkj_.js +1 -0
  434. package/dist/assets/setup-physics-BeZ7-LKD.js +1 -0
  435. package/dist/assets/setup-renderer-DVXaSGin.js +1587 -0
  436. package/dist/assets/shading.layout-DULYZV6M.js +1 -0
  437. package/dist/assets/sim-clock-CLflx7kg.js +1 -0
  438. package/dist/assets/sky-precompute-worker-ChN7J87v.js +1 -0
  439. package/dist/assets/soft-particle-depth-DGvfQDi1.js +1 -0
  440. package/dist/assets/source-object3d-authoring-adapter-B-L6Ha6f.js +1 -0
  441. package/dist/assets/source-persistence-backend-C-aR-B_Y.js +1 -0
  442. package/dist/assets/spark-renderer-lifecycle-ynWESJcv.js +1 -0
  443. package/dist/assets/spark.module-4pXQoz5d.js +12120 -0
  444. package/dist/assets/stage-invalidation-DBg3C3Ta.js +1 -0
  445. package/dist/assets/stage-keyboard-n-5kKH-m.js +1 -0
  446. package/dist/assets/stage-overlay-set-B9zp2sLB.js +1 -0
  447. package/dist/assets/stage-presence-markers-DiGI6A45.js +1 -0
  448. package/dist/assets/standard-viewport-dressing-CzjAe_0A.js +7 -0
  449. package/dist/assets/state-bridge-DLP1jLRW.js +1 -0
  450. package/dist/assets/state-watch.action-BOvQR2qt.js +1 -0
  451. package/dist/assets/state-watch.menu-CNLvDeeY.js +1 -0
  452. package/dist/assets/state-watch.utility-Bg1tTTQU.js +1 -0
  453. package/dist/assets/static-batch-advisor-B13QEH7d.js +1 -0
  454. package/dist/assets/stats.module-BL02l9NC.js +1 -0
  455. package/dist/assets/story-arg-descriptors-Ek86ExX7.js +1 -0
  456. package/dist/assets/story-capture-_gC8dXV-.js +1 -0
  457. package/dist/assets/story-documents--TDLaPeL.js +3 -0
  458. package/dist/assets/story-documents.service-BiS_YbNQ.js +1 -0
  459. package/dist/assets/story-documents.service-CxOPYJ2j.js +1 -0
  460. package/dist/assets/story-media-presence-BHzk2IV5.js +1 -0
  461. package/dist/assets/story-mount-turn-DFRTj5hi.js +1 -0
  462. package/dist/assets/story-pixi-preview-BUrOJZXS.js +1 -0
  463. package/dist/assets/story-presentation-j2AVN-mK.js +1 -0
  464. package/dist/assets/story-three-preview-BHEDZzcl.js +2 -0
  465. package/dist/assets/structural-ids-Dc-7rEwi.js +1 -0
  466. package/dist/assets/structural-signature-0w-i_ats.js +1 -0
  467. package/dist/assets/surface-content-Dg9Kkazf.js +1 -0
  468. package/dist/assets/surface-state-DaxyruCj.js +3 -0
  469. package/dist/assets/system-adapters-rIC8FSGP.js +1 -0
  470. package/dist/assets/system-runner-DkOjxEBt.js +1 -0
  471. package/dist/assets/system-slot-E2mEdiih.js +1 -0
  472. package/dist/assets/team-playtest.service-DqOinFVA.js +1 -0
  473. package/dist/assets/texture.layout-DASpHVht.js +1 -0
  474. package/dist/assets/three-CDSueJyJ.js +1 -0
  475. package/dist/assets/three-authoring-adapter-CmSQ3Vui.js +1 -0
  476. package/dist/assets/three-authoring.service-iuHLwtf1.js +2 -0
  477. package/dist/assets/three-ingest-runtime-QzDYk6tU.js +1 -0
  478. package/dist/assets/three-projection-core-BmKMZ-nf.js +1 -0
  479. package/dist/assets/three-viewport-presentation-QBQpSdMh.js +1 -0
  480. package/dist/assets/three.module-D396a9Mn.js +3840 -0
  481. package/dist/assets/three.quarks.esm-B1C61jGo.js +1039 -0
  482. package/dist/assets/tools-B_NJsk05.js +1 -0
  483. package/dist/assets/transform-writer-BhBBTx33.js +1 -0
  484. package/dist/assets/transport.header-B-6HQlU2.js +1 -0
  485. package/dist/assets/trigger-volume-BNK2XzPL.js +1 -0
  486. package/dist/assets/tuples-CIQ4Bn1U.js +1 -0
  487. package/dist/assets/tween.module-DciWpAG6.js +1 -0
  488. package/dist/assets/ui-board-document-Bwtt--xp.js +2 -0
  489. package/dist/assets/unexported-game-trap-Dm1JYKHy.js +2 -0
  490. package/dist/assets/unmanaged-root-detector-B8CpbkSN.js +2 -0
  491. package/dist/assets/upstream-pin-BdgRH6ID.js +1 -0
  492. package/dist/assets/use-data-Dzq-MytE.js +1 -0
  493. package/dist/assets/use-live-actor-state-DErbWQWF.js +1 -0
  494. package/dist/assets/use-selection-DbR73-xd.js +1 -0
  495. package/dist/assets/user-data-BB2Of6Ht.js +1 -0
  496. package/dist/assets/utility-view-state-BHypxA33.js +1 -0
  497. package/dist/assets/uv-editing.layout-BEKHxmHw.js +1 -0
  498. package/dist/assets/vgai-shared-fontawesome-CU65D4Ij.js +1 -0
  499. package/dist/assets/vgai-shared-jsx-dev-runtime-DFDKL7fx.js +1 -0
  500. package/dist/assets/vgai-shared-jsx-runtime-DIqBpTut.js +1 -0
  501. package/dist/assets/vgai-shared-react-BT7rMc2H.js +1 -0
  502. package/dist/assets/vgai-shared-react-dom-DFajMqMT.js +1 -0
  503. package/dist/assets/vgai-shared-react-dom-client-S0ozfl6_.js +1 -0
  504. package/dist/assets/vgai-shared-three-Bc5PvpLM.js +1 -0
  505. package/dist/assets/viewport-pick-context-DkawXbEi.js +1 -0
  506. package/dist/assets/viewport-root-presentation-CWsE56K6.js +1 -0
  507. package/dist/assets/viewport-shading-BuA88e_A.js +1 -0
  508. package/dist/assets/viewport-shading-boundary-B_-_gABg.js +82 -0
  509. package/dist/assets/viewport-surface-status-B3om4Kcf.js +1 -0
  510. package/dist/assets/vision_bundle-DX0dWqEa.js +15 -0
  511. package/dist/assets/voxel-surface-DtcsSWRL.js +1 -0
  512. package/dist/assets/wav-encode-D31zWF6O.js +1 -0
  513. package/dist/assets/webgl-frame-capture-FlF9zQmW.js +1 -0
  514. package/dist/assets/webgl-gpu-timer-D3YX7RaD.js +1 -0
  515. package/dist/assets/webworkerAll-CM2o_dnz.js +1 -0
  516. package/dist/assets/worker-UrMcrc5_.js +2 -0
  517. package/dist/assets/world-documents-147tiFZe.js +1 -0
  518. package/dist/assets/world-root-stage-binding-vwTrtBz6.js +1 -0
  519. package/dist/assets/world-state-BWG-IcOd.js +1 -0
  520. package/dist/assets/writer-B-KovzkA.js +5 -0
  521. package/dist/assets/xstate-animation-binding-Brd0NST6.js +1 -0
  522. package/dist/assets/xstate-animation-meta-Q3u9zh_m.js +1 -0
  523. package/dist/assets/xstate-behavior.action-B8UluFBK.js +1 -0
  524. package/dist/assets/xstate-behavior.document-CKAsE45I.js +1 -0
  525. package/dist/assets/xstate-behavior.inspector-vJJyuifc.js +1 -0
  526. package/dist/assets/xstate-behavior.menu-BXbPICIh.js +1 -0
  527. package/dist/assets/xstate-inspection-BsZv8LS9.js +1 -0
  528. package/dist/vgai-shared-react.json +10 -0
  529. package/dist/vgai-shared-three.json +3 -0
  530. package/dist-node/cli.js +9320 -0
  531. package/dist-node/create.js +3239 -0
  532. package/package.json +91 -0
  533. package/presets.mjs +2 -0
  534. package/src/contributions.d.ts +4 -0
  535. package/src/index.ts +38 -0
  536. package/starter/cube.blend +0 -0
  537. package/starter/cube.py +81 -0
  538. package/template/.agents/references/project-manual.md +341 -0
  539. package/template/.agents/skills/editor/SKILL.md +53 -0
  540. package/template/.agents/skills/editor/agents/openai.yaml +4 -0
  541. package/template/.agents/skills/editor/references/editor-control.md +363 -0
  542. package/template/.agents/skills/vgai-3d-models/SKILL.md +64 -0
  543. package/template/.agents/skills/vgai-ingest-existing-game/SKILL.md +112 -0
  544. package/template/.agents/skills/vgai-threejs-authoring/SKILL.md +347 -0
  545. package/template/.agents/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
  546. package/template/.agents/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
  547. package/template/.claude/skills/editor/SKILL.md +53 -0
  548. package/template/.claude/skills/editor/agents/openai.yaml +4 -0
  549. package/template/.claude/skills/editor/references/editor-control.md +363 -0
  550. package/template/.claude/skills/vgai-3d-models/SKILL.md +64 -0
  551. package/template/.claude/skills/vgai-ingest-existing-game/SKILL.md +112 -0
  552. package/template/.claude/skills/vgai-threejs-authoring/SKILL.md +347 -0
  553. package/template/.claude/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
  554. package/template/.claude/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
  555. package/template/.github/copilot-instructions.md +6 -0
  556. package/template/.github/skills/editor/SKILL.md +53 -0
  557. package/template/.github/skills/editor/agents/openai.yaml +4 -0
  558. package/template/.github/skills/editor/references/editor-control.md +363 -0
  559. package/template/.github/skills/vgai-3d-models/SKILL.md +64 -0
  560. package/template/.github/skills/vgai-ingest-existing-game/SKILL.md +112 -0
  561. package/template/.github/skills/vgai-threejs-authoring/SKILL.md +347 -0
  562. package/template/.github/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
  563. package/template/.github/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
  564. package/template/.mcp.json +12 -0
  565. package/template/.vgai/assets.json +1 -0
  566. package/template/.vgai/provenance.json +4 -0
  567. package/template/.volter/tracker/validation/.preset.base.mts +178 -0
  568. package/template/.volter/tracker/validation/preset.mts +186 -0
  569. package/template/.volter/tracker/visualizer/.extension.base.tsx +14 -0
  570. package/template/.volter/tracker/visualizer/extension.tsx +14 -0
  571. package/template/.volter/tracker-config.json +17 -0
  572. package/template/AGENTS.md +176 -0
  573. package/template/CLAUDE.md +1 -0
  574. package/template/DEVLOG.md +20 -0
  575. package/template/IDIOMS.md +118 -0
  576. package/template/LICENSE +30 -0
  577. package/template/README.md +83 -0
  578. package/template/ROADMAP.md +20 -0
  579. package/template/asset-manifest.json +3 -0
  580. package/template/check-idioms.ts +1533 -0
  581. package/template/index.html +18 -0
  582. package/template/manifest-entry-modules-plugin.ts +53 -0
  583. package/template/package.json +62 -0
  584. package/template/public/jsm/libs/basis/basis_transcoder.js +19 -0
  585. package/template/public/jsm/libs/basis/basis_transcoder.wasm +0 -0
  586. package/template/public/jsm/libs/draco/gltf/draco_decoder.js +33 -0
  587. package/template/public/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
  588. package/template/public/jsm/libs/draco/gltf/draco_encoder.js +33 -0
  589. package/template/public/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
  590. package/template/public/shaders/daylight-sky.frag.glsl +15 -0
  591. package/template/public/shaders/daylight-sky.vert.glsl +7 -0
  592. package/template/scripts/patch-drei-stats-gl.mjs +35 -0
  593. package/template/server/colyseus-setup.ts +111 -0
  594. package/template/server/loopback.ts +76 -0
  595. package/template/server/main.ts +78 -0
  596. package/template/server/rooms/arena-room.ts +488 -0
  597. package/template/server/rooms/game-room.ts +274 -0
  598. package/template/server/rooms.ts +15 -0
  599. package/template/server/tsconfig.json +19 -0
  600. package/template/src/bot/QaTester.tsx +35 -0
  601. package/template/src/bot/behaviors.ts +203 -0
  602. package/template/src/bot/bot-station.ts +192 -0
  603. package/template/src/bot/tester-run.ts +238 -0
  604. package/template/src/bot/tester-station.ts +193 -0
  605. package/template/src/components/environment/DaylightSky.tsx +54 -0
  606. package/template/src/components/environment/Ground.tsx +129 -0
  607. package/template/src/components/environment/SceneAtmosphere.tsx +14 -0
  608. package/template/src/components/environment/SoftGroundShadow.tsx +62 -0
  609. package/template/src/components/environment/SunShadowFit.tsx +141 -0
  610. package/template/src/contributions/README.md +98 -0
  611. package/template/src/contributions/analytics.analytics.tsx +26 -0
  612. package/template/src/contributions/data.document.tsx +35 -0
  613. package/template/src/contributions/pages.finder.ts +61 -0
  614. package/template/src/contributions/tester.inspector.tsx +64 -0
  615. package/template/src/contributions/use-game-modules.ts +80 -0
  616. package/template/src/data/README.md +17 -0
  617. package/template/src/input.ts +97 -0
  618. package/template/src/lib/audio/capability.json +4 -0
  619. package/template/src/lib/audio/sfx.ts +255 -0
  620. package/template/src/lib/react-root/capability.json +4 -0
  621. package/template/src/lib/react-root/index.ts +20 -0
  622. package/template/src/lib/react-root/react-root-adapter.tsx +57 -0
  623. package/template/src/lib/reflections/ReflectionProbe.tsx +201 -0
  624. package/template/src/lib/reflections/capability.json +4 -0
  625. package/template/src/lib/reflections/index.ts +19 -0
  626. package/template/src/lib/reflections/probe-controller.ts +75 -0
  627. package/template/src/lib/reflections/reflection-probe-registry.ts +402 -0
  628. package/template/src/lib/reflections/volume-reflection-material.ts +416 -0
  629. package/template/src/lib/static-batch/Frozen.tsx +91 -0
  630. package/template/src/lib/static-batch/capability.json +4 -0
  631. package/template/src/lib/static-batch/freeze.ts +579 -0
  632. package/template/src/lib/static-batch/index.ts +44 -0
  633. package/template/src/lib/static-batch/mutation-watch.ts +149 -0
  634. package/template/src/lib/static-batch/shadow-cache.ts +171 -0
  635. package/template/src/main.ts +63 -0
  636. package/template/src/manifest-entry-modules.d.ts +3 -0
  637. package/template/src/prefabs/HeroBox.stories.tsx +23 -0
  638. package/template/src/prefabs/HeroBox.tsx +35 -0
  639. package/template/src/scenes/MainScene.tsx +77 -0
  640. package/template/src/world.tsx +87 -0
  641. package/template/tsconfig.json +35 -0
  642. package/template/tsconfig.node.json +32 -0
  643. package/template/tsconfig.tools.json +22 -0
  644. package/template/validate-asset-content.ts +27 -0
  645. package/template/validate-assets.ts +60 -0
  646. package/template/validate-manifest.ts +55 -0
  647. package/template/vgai.adapter.ts +76 -0
  648. package/template/vgai.project.json +24 -0
  649. package/template/vite.config.ts +247 -0
  650. package/template-dotfiles/gitignore +63 -0
  651. package/workbench/src/media/game-cover.css +83 -0
  652. package/workbench/src/product.contribution.ts +188 -0
  653. package/workbench/src/vgaiGameSkew.ts +276 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * The bot run's ONE store — status, trace, seat, and the operator directive.
3
+ *
4
+ * The resident QA tester (`src/bot/tester-station.ts`) plays this game from
5
+ * INSIDE the page, directed live from the REPL through `hireTester`. This module
6
+ * holds what it is doing so the game's Tester surface and `vgai eval`
7
+ * both watch one run, and it implements the operator controls the tester
8
+ * honors between steps. This module is plain application state and imports no
9
+ * vgai API; its exports are the whole control surface.
10
+ *
11
+ * `getBotStatus()` reads `{active, seat, goal, step, phase, progress,
12
+ * waitingOn, note, seed, directive}`. `pauseBot()`, `resumeBot()`,
13
+ * `abortBot()`, and `handoffBot()` are the operator's controls. Abort and
14
+ * handoff also clear virtual input immediately, so a human taking the seat
15
+ * back never inherits a held key.
16
+ *
17
+ * Resource ownership: THIS MODULE owns bot run state; its ONE writer is the
18
+ * tester (in-process, through `reportTesterRun`). The operator commands own
19
+ * `directive` and the writer never overwrites it — except at a run BOUNDARY:
20
+ * a patch that sets `active` (start or end) resets the directive, so a run
21
+ * neither starts under nor hands on a stale stop. The terminal patch
22
+ * (`active: false`) is the one teardown path that clears the run.
23
+ *
24
+ * ── THE SEAT ────────────────────────────────────────────────────────────────
25
+ * `status.seat` is the CONTROLLER, and it has exactly ONE owner at a time —
26
+ * the tester, or you ({@link seatTester}, {@link releaseTester} — nobody
27
+ * else may reason about `seat`). `hireTester` while a run is active refuses
28
+ * (two hands on one controller); `bot.handoff` returns the seat to the
29
+ * human's keyboard mid-run.
30
+ *
31
+ * Cost when idle: none. No timers, no frame work — reads are pull-only.
32
+ */
33
+
34
+ import { clearVirtualActions } from '../input';
35
+
36
+ /** This module feeds the game's Tester surface and its operator controls. */
37
+ /** What the operator has asked the running bot to do. This module is the
38
+ * authority, because it is the side that VALIDATES. */
39
+ export type BotDirective = 'run' | 'pause' | 'abort' | 'handoff';
40
+
41
+ /** Who holds the controller — see this module's SEAT section. `null` while
42
+ * nothing is driving. */
43
+ export type BotSeat = 'tester' | null;
44
+
45
+ export interface BotStatus {
46
+ readonly active: boolean;
47
+ /** The controller's one owner right now. */
48
+ readonly seat: BotSeat;
49
+ /** The game-side tester's run: which behavior from its repertoire. */
50
+ readonly goal: string | null;
51
+ readonly step: string | null;
52
+ readonly phase: string | null;
53
+ /** Steps completed so far in this run. */
54
+ readonly progress: number;
55
+ /** What the tester is currently waiting on, when it is waiting. */
56
+ readonly waitingOn: string | null;
57
+ /** The tester's own live line — what it is doing, or why it stopped. */
58
+ readonly note: string | null;
59
+ readonly seed: number | null;
60
+ readonly directive: BotDirective;
61
+ }
62
+
63
+ const IDLE: BotStatus = {
64
+ active: false,
65
+ seat: null,
66
+ goal: null,
67
+ step: null,
68
+ phase: null,
69
+ progress: 0,
70
+ waitingOn: null,
71
+ note: null,
72
+ seed: null,
73
+ directive: 'run',
74
+ };
75
+
76
+ /** One patch, from either writer. Every field is optional: absent means
77
+ * unchanged. The wire schema above is the DRIVER's half of this shape. */
78
+ export interface BotPatch {
79
+ seat?: BotSeat | undefined;
80
+ goal?: string | null | undefined;
81
+ step?: string | null | undefined;
82
+ phase?: string | null | undefined;
83
+ progress?: number | undefined;
84
+ waitingOn?: string | null | undefined;
85
+ note?: string | null | undefined;
86
+ active?: boolean | undefined;
87
+ seed?: number | undefined;
88
+ }
89
+
90
+ let status: BotStatus = IDLE;
91
+
92
+ /** A field an absent patch leaves alone. */
93
+ function kept<T>(next: T | undefined, current: T): T {
94
+ return next === undefined ? current : next;
95
+ }
96
+
97
+ /** A field that also RESETS at a run boundary. Both writers omit each other's
98
+ * fields, so without this a new run would wear the last one's identity. */
99
+ function scoped<T>(next: T | undefined, current: T, boundary: boolean, empty: T): T {
100
+ if (next !== undefined) return next;
101
+ return boundary ? empty : current;
102
+ }
103
+
104
+ function applyPatch(patch: BotPatch): BotStatus {
105
+ // A run's own start and end are the only moments the operator's directive is
106
+ // reset — otherwise an abort would silently carry into the next run.
107
+ const boundary = patch.active !== undefined;
108
+ status = {
109
+ active: kept(patch.active, status.active),
110
+ // The tester names its seat on start; a run that ENDS empties the seat.
111
+ seat: patch.seat !== undefined ? patch.seat : boundary && !patch.active ? null : status.seat,
112
+ goal: scoped(patch.goal, status.goal, boundary, null),
113
+ step: kept(patch.step, status.step),
114
+ phase: kept(patch.phase, status.phase),
115
+ progress: scoped(patch.progress, status.progress, boundary, 0),
116
+ waitingOn: kept(patch.waitingOn, status.waitingOn),
117
+ note: scoped(patch.note, status.note, boundary, null),
118
+ seed: scoped(patch.seed, status.seed, boundary, null),
119
+ directive: boundary ? 'run' : status.directive,
120
+ };
121
+ return status;
122
+ }
123
+
124
+ /**
125
+ * The GAME-SIDE writer's door: the resident QA tester
126
+ * (`src/bot/tester-station.ts`) runs in this page, not over the wire, so it
127
+ * patches the store directly. Same store, same boundary rules — see the
128
+ * ownership note.
129
+ */
130
+ export function reportTesterRun(patch: BotPatch): BotStatus {
131
+ return applyPatch(patch);
132
+ }
133
+
134
+ /** Seat the tester for one goal — it starts the run and owns it. */
135
+ export function seatTester(goal: string): BotStatus {
136
+ return applyPatch({
137
+ goal,
138
+ step: null,
139
+ phase: 'drive',
140
+ note: null,
141
+ active: true,
142
+ seat: 'tester',
143
+ progress: 0,
144
+ });
145
+ }
146
+
147
+ /** The ONE teardown path for a tester run: ends it and empties the seat. */
148
+ export function releaseTester(note: string | null): BotStatus {
149
+ return applyPatch({ goal: null, step: null, phase: null, note, active: false, seat: null });
150
+ }
151
+
152
+ export function getBotStatus(): BotStatus {
153
+ return status;
154
+ }
155
+
156
+ function setDirective(directive: BotDirective): BotStatus {
157
+ status = { ...status, directive };
158
+ return status;
159
+ }
160
+
161
+ function requireActiveRun(verb: string): void {
162
+ if (!status.active) {
163
+ throw new Error(`${verb}: no bot run is active — nothing is holding the controller.`);
164
+ }
165
+ }
166
+
167
+ /** Pause the running bot at its next gate — a step boundary or a wait poll. */
168
+ export function pauseBot(): BotStatus {
169
+ requireActiveRun('bot.pause');
170
+ return setDirective('pause');
171
+ }
172
+
173
+ /** Resume a paused bot. */
174
+ export function resumeBot(): BotStatus {
175
+ requireActiveRun('bot.resume');
176
+ return setDirective('run');
177
+ }
178
+
179
+ /** Stop the running bot and release its virtual input. */
180
+ export function abortBot(): BotStatus {
181
+ requireActiveRun('bot.abort');
182
+ clearVirtualActions();
183
+ return setDirective('abort');
184
+ }
185
+
186
+ /** Stop the bot and give the seat back to the human immediately — the
187
+ * keyboard has to be free the moment a person asks for it. */
188
+ export function handoffBot(): BotStatus {
189
+ requireActiveRun('bot.handoff');
190
+ clearVirtualActions();
191
+ return setDirective('handoff');
192
+ }
@@ -0,0 +1,238 @@
1
+ /**
2
+ * ONE tester run: a goal, the hands it plays with, and the per-tick stepping
3
+ * that honors the operator's directive.
4
+ *
5
+ * Kept out of the React component on purpose — this is the part with rules
6
+ * (the tester only ever writes virtual input; pause takes its hands off the
7
+ * controller; abort/handoff end the run), and rules deserve to be provable
8
+ * without a browser. `src/bot/QaTester.tsx` is the thin half: hooks, the frame
9
+ * callback, and the bridge store.
10
+ *
11
+ * Resource ownership: a run owns the virtual actions IT set, and nothing else.
12
+ * It records every actuation it makes so it can let go of exactly those on
13
+ * pause, on abort, and at the end — which is what makes `bot.handoff` hand a
14
+ * clean keyboard to the human. The engine's `clearVirtualActions()` (the
15
+ * bridge's own abort path) is the bigger hammer; a run never needs it.
16
+ */
17
+
18
+ import type { TesterBehavior, TesterHands, TesterOutcome, TesterTick } from './behaviors';
19
+
20
+ /** What the operator has asked the running bot to do — the union
21
+ * `src/bot/bot-station.ts` validates and owns. */
22
+ export type TesterDirective = 'run' | 'pause' | 'abort' | 'handoff';
23
+
24
+ /** How a run ended. The behavior's own `done`/`failed`, plus `stopped` for the
25
+ * operator ending it — a stopped run is not a failed game. */
26
+ export type TesterRunStatus = 'running' | 'done' | 'failed' | 'stopped';
27
+
28
+ /**
29
+ * The three `InputManager` methods the tester's hands need — the game's REAL
30
+ * input store satisfies this structurally, and a disposable REPL probe may
31
+ * pass a recorder. Typed narrowly here so this module never imports the engine, and
32
+ * so the surface a tester can reach is visible in one glance: virtual input,
33
+ * and nothing else.
34
+ */
35
+ export interface TesterInputTarget {
36
+ actionNames(): string[];
37
+ setVirtualAction(
38
+ action: string,
39
+ value: boolean | number | { x: number; y: number },
40
+ ): { delivered: boolean; reason?: string };
41
+ tapVirtualAction(action: string): { delivered: boolean; reason?: string };
42
+ }
43
+
44
+ export interface TesterRunPatch {
45
+ readonly step?: string;
46
+ readonly progress?: number;
47
+ readonly note?: string;
48
+ }
49
+
50
+ export interface TesterRunOptions {
51
+ /** The behavior name from this game's repertoire, for reporting. */
52
+ readonly goal: string;
53
+ readonly behavior: TesterBehavior;
54
+ /** Already parsed against `behavior.params` by the caller. */
55
+ readonly params: unknown;
56
+ readonly input: TesterInputTarget;
57
+ /** Read fresh every tick, so pause/abort bite on the next tick. */
58
+ readonly directive: () => TesterDirective;
59
+ readonly report: (patch: TesterRunPatch) => void;
60
+ }
61
+
62
+ /** The "let go" value for whatever shape was last written. */
63
+ function releasedValue(
64
+ value: boolean | number | { x: number; y: number },
65
+ ): boolean | number | { x: number; y: number } {
66
+ if (typeof value === 'boolean') return false;
67
+ if (typeof value === 'number') return 0;
68
+ return { x: 0, y: 0 };
69
+ }
70
+
71
+ class Hands implements TesterHands {
72
+ readonly #input: TesterInputTarget;
73
+ /** Every action this run is currently actuating, with its last value — the
74
+ * ledger `release`/`suspend`/`resume` work from. */
75
+ readonly #held = new Map<string, boolean | number | { x: number; y: number }>();
76
+ #undelivered: string | null = null;
77
+
78
+ constructor(input: TesterInputTarget) {
79
+ this.#input = input;
80
+ }
81
+
82
+ actions(): readonly string[] {
83
+ return this.#input.actionNames();
84
+ }
85
+
86
+ set(action: string, value: boolean | number | { x: number; y: number }): void {
87
+ this.#note(this.#input.setVirtualAction(action, value));
88
+ this.#held.set(action, value);
89
+ }
90
+
91
+ tap(action: string): void {
92
+ this.#note(this.#input.tapVirtualAction(action));
93
+ }
94
+
95
+ release(): void {
96
+ this.#letGo();
97
+ this.#held.clear();
98
+ }
99
+
100
+ /** Pause: hands off the controller, ledger kept so `resume` can take it
101
+ * back exactly as it was. */
102
+ suspend(): void {
103
+ this.#letGo();
104
+ }
105
+
106
+ resume(): void {
107
+ for (const [action, value] of this.#held) {
108
+ this.#note(this.#input.setVirtualAction(action, value));
109
+ }
110
+ }
111
+
112
+ /** The last actuation the engine refused (input gated), consumed by the
113
+ * reader. A swallowed actuation must never look like a delivered one. */
114
+ takeUndelivered(): string | null {
115
+ const reason = this.#undelivered;
116
+ this.#undelivered = null;
117
+ return reason;
118
+ }
119
+
120
+ #letGo(): void {
121
+ for (const [action, value] of this.#held) {
122
+ this.#input.setVirtualAction(action, releasedValue(value));
123
+ }
124
+ }
125
+
126
+ #note(result: { delivered: boolean; reason?: string }): void {
127
+ if (!result.delivered) this.#undelivered = result.reason ?? 'actuation not delivered';
128
+ }
129
+ }
130
+
131
+ export class TesterRun {
132
+ readonly goal: string;
133
+ readonly #options: TesterRunOptions;
134
+ readonly #hands: Hands;
135
+ readonly #step: (tick: TesterTick) => TesterOutcome;
136
+ #status: TesterRunStatus = 'running';
137
+ #note: string | null = null;
138
+ #elapsed = 0;
139
+ #suspended = false;
140
+
141
+ constructor(options: TesterRunOptions) {
142
+ this.goal = options.goal;
143
+ this.#options = options;
144
+ this.#hands = new Hands(options.input);
145
+ this.#step = options.behavior.create(
146
+ {
147
+ hands: this.#hands,
148
+ report: (patch) => {
149
+ if (patch.note !== undefined) this.#note = patch.note;
150
+ options.report(patch);
151
+ },
152
+ },
153
+ options.params,
154
+ );
155
+ }
156
+
157
+ /** Sim seconds this run has been playing. */
158
+ get elapsed(): number {
159
+ return this.#elapsed;
160
+ }
161
+
162
+ /** The last thing the run said about itself — the terminal one is why it
163
+ * ended. */
164
+ get note(): string | null {
165
+ return this.#note;
166
+ }
167
+
168
+ get status(): TesterRunStatus {
169
+ return this.#status;
170
+ }
171
+
172
+ /**
173
+ * Advance the run by one sim tick. Returns the run's status: anything but
174
+ * `running` means it is over and the caller should retire it.
175
+ */
176
+ step(dt: number): TesterRunStatus {
177
+ if (this.#status !== 'running') return this.#status;
178
+
179
+ const directive = this.#options.directive();
180
+ if (directive === 'abort' || directive === 'handoff') {
181
+ // The bridge's own command already released virtual input for the
182
+ // human; this drops the run's ledger so nothing can re-assert it.
183
+ this.#hands.release();
184
+ return this.#end('stopped', `stopped by bot.${directive}`);
185
+ }
186
+
187
+ if (directive === 'pause') {
188
+ if (!this.#suspended) {
189
+ this.#suspended = true;
190
+ this.#hands.suspend();
191
+ this.#report('paused — hands off the controller');
192
+ }
193
+ // Paused holds POSITION: the behavior is not stepped and no sim budget
194
+ // is charged against it, so resuming continues the same play.
195
+ return 'running';
196
+ }
197
+
198
+ if (this.#suspended) {
199
+ this.#suspended = false;
200
+ this.#hands.resume();
201
+ this.#report('resumed');
202
+ }
203
+
204
+ this.#elapsed += dt;
205
+
206
+ let outcome: TesterOutcome;
207
+ try {
208
+ outcome = this.#step({ dt, elapsed: this.#elapsed });
209
+ } catch (error) {
210
+ this.#hands.release();
211
+ return this.#end('failed', String(error));
212
+ }
213
+
214
+ const undelivered = this.#hands.takeUndelivered();
215
+ if (undelivered !== null) this.#report(`input not delivered — ${undelivered}`);
216
+
217
+ if (outcome === 'running') return 'running';
218
+ this.#hands.release();
219
+ return this.#end(outcome, this.#note ?? `behavior reported ${outcome}`);
220
+ }
221
+
222
+ #report(note: string): void {
223
+ this.#note = note;
224
+ this.#options.report({ note });
225
+ }
226
+
227
+ #end(status: TesterRunStatus, note: string): TesterRunStatus {
228
+ this.#status = status;
229
+ this.#note = note;
230
+ return status;
231
+ }
232
+ }
233
+
234
+ /** Start a goal. The behavior is created here, so anything it wants to read at
235
+ * start (the declared action list, game state) is read before the first tick. */
236
+ export function startTesterRun(options: TesterRunOptions): TesterRun {
237
+ return new TesterRun(options);
238
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * The resident QA TESTER's run state and doors — the half of the live
3
+ * playtesting loop that actually plays the game.
4
+ *
5
+ * Two people build this game: the DEVELOPER (a coding agent at the REPL) and
6
+ * the TESTER. The developer arranges the situation with the game's own setup
7
+ * verbs and tunables, then says WHAT TO TEST in intent terms —
8
+ * `hireTester('sweep')` on this running module — and watches. The tester holds the
9
+ * controller from here on: it steps its goal once per sim tick
10
+ * (`src/bot/QaTester.tsx`'s frame hook calls {@link stepTester}), acting ONLY
11
+ * through this game's own input store, at the game's own timescale. A
12
+ * developer at conversation pace cannot honestly play a realtime game, which
13
+ * is exactly why the tester exists.
14
+ *
15
+ * Exported surface:
16
+ * - {@link hireTester} starts a named goal and is always callable;
17
+ * - {@link describeTester} returns the repertoire and the last run's outcome.
18
+ * The outcome lives here rather than in the run-scoped status because that
19
+ * status resets at exactly the moment the outcome exists.
20
+ *
21
+ * The SEAT — who may hold the controller — is `bot-station.ts`'s to define
22
+ * and enforce. This module takes
23
+ * (`seatTester`) and gives it back (`releaseTester`); it never reasons about
24
+ * the rule itself.
25
+ *
26
+ * No vgai import anywhere: the tester's hands are the project's own input
27
+ * store (`src/input.ts`), typed through `tester-run.ts`'s narrow
28
+ * `TesterInputTarget`.
29
+ */
30
+
31
+ import { clearVirtualActions, gameActions, setVirtualAction } from '../input';
32
+ import { describeTesterBehaviors, resolveTesterBehavior } from './behaviors';
33
+ import { getBotStatus, releaseTester, reportTesterRun, seatTester } from './bot-station';
34
+ import {
35
+ startTesterRun,
36
+ type TesterInputTarget,
37
+ type TesterRun,
38
+ type TesterRunStatus,
39
+ } from './tester-run';
40
+
41
+ /** How a finished job is remembered for the developer's next poll. */
42
+ interface TesterJobRecord {
43
+ readonly goal: string;
44
+ readonly outcome: TesterRunStatus;
45
+ readonly note: string | null;
46
+ readonly simSeconds: number;
47
+ }
48
+
49
+ let currentRun: TesterRun | null = null;
50
+ let lastJob: TesterJobRecord | null = null;
51
+ const pendingTapReleases = new Set<string>();
52
+
53
+ /** The tester's hands, over this game's OWN input store. `tap` is a set that
54
+ * the behavior itself releases — the store keeps no tick scheduler the
55
+ * neutral scaffold has no reader for. */
56
+ const hands: TesterInputTarget = {
57
+ actionNames: () => [...gameActions],
58
+ setVirtualAction(action, value) {
59
+ try {
60
+ setVirtualAction(action, value);
61
+ return { delivered: true };
62
+ } catch (error) {
63
+ return { delivered: false, reason: String(error) };
64
+ }
65
+ },
66
+ tapVirtualAction(action) {
67
+ try {
68
+ setVirtualAction(action, true);
69
+ pendingTapReleases.add(action);
70
+ return { delivered: true };
71
+ } catch (error) {
72
+ return { delivered: false, reason: String(error) };
73
+ }
74
+ },
75
+ };
76
+
77
+ /** Release taps from the previous tick before the next behavior step. A tap
78
+ * therefore stays asserted while every later gameplay callback reads this
79
+ * frame, instead of becoming an invisible true→false write in one call. */
80
+ function releasePendingTaps(): void {
81
+ for (const action of pendingTapReleases) setVirtualAction(action, false);
82
+ pendingTapReleases.clear();
83
+ }
84
+
85
+ /** The `paramsJson` argument, as typed at a REPL or into the Dev tab's field. */
86
+ function parseGoalParams(raw: string | undefined): unknown {
87
+ if (raw === undefined || raw.trim() === '') return {};
88
+ try {
89
+ return JSON.parse(raw);
90
+ } catch (error) {
91
+ throw new Error(
92
+ `hireTester: params are not valid JSON (${String(error)}). Pass an object literal, ` +
93
+ 'e.g. \'{"holdSimSeconds": 1.5}\'.',
94
+ );
95
+ }
96
+ }
97
+
98
+ /** The Tester contribution and live REPL's discovery/readout body. */
99
+ export function describeTester(): {
100
+ behaviors: ReturnType<typeof describeTesterBehaviors>;
101
+ running: string | null;
102
+ last: TesterJobRecord | null;
103
+ } {
104
+ return {
105
+ behaviors: describeTesterBehaviors(),
106
+ running: currentRun?.goal ?? null,
107
+ last: lastJob,
108
+ };
109
+ }
110
+
111
+ /** Hire the tester for one goal. */
112
+ export function hireTester(name: string, paramsJson?: string): { goal: string; summary: string } {
113
+ if (currentRun !== null) {
114
+ throw new Error(
115
+ `hireTester: the tester is already playing "${currentRun.goal}". ` +
116
+ 'Let it finish, or call `abortBot()` first.',
117
+ );
118
+ }
119
+ const behavior = resolveTesterBehavior(name);
120
+ const params = behavior.params
121
+ ? behavior.params.parse(parseGoalParams(paramsJson))
122
+ : parseGoalParams(paramsJson);
123
+
124
+ // Takes the seat, starting a run of its own. `drive` is the honest phase
125
+ // tag: everything a tester does is player input. A `setup` cheat is the
126
+ // developer's move, never the tester's.
127
+ seatTester(name);
128
+ try {
129
+ currentRun = startTesterRun({
130
+ goal: name,
131
+ behavior,
132
+ params,
133
+ input: hands,
134
+ directive: () => getBotStatus().directive,
135
+ report: (patch) => reportTesterRun(patch),
136
+ });
137
+ } catch (error) {
138
+ // `create()` is game code and may throw (it reads game state at start).
139
+ // The seating above is already published, so give the seat back —
140
+ // otherwise it strands with no run behind it and the guard refuses every
141
+ // future `hireTester` call.
142
+ lastJob = { goal: name, outcome: 'failed', note: String(error), simSeconds: 0 };
143
+ releaseTester(String(error));
144
+ throw error;
145
+ }
146
+ return { goal: name, summary: behavior.summary };
147
+ }
148
+
149
+ /** One sim tick of the tester's hands — called by `QaTester.tsx`'s frame hook,
150
+ * which runs before every game-logic hook so a virtual action is already
151
+ * written when the first mechanic reads it. */
152
+ export function stepTester(dt: number): void {
153
+ // Paused redraws must not consume a waypoint or release a pending tap.
154
+ if (dt <= 0) return;
155
+ releasePendingTaps();
156
+ const run = currentRun;
157
+ if (run === null) return;
158
+ const status = run.step(dt);
159
+ if (status === 'running') return;
160
+
161
+ currentRun = null;
162
+ lastJob = {
163
+ goal: run.goal,
164
+ outcome: status,
165
+ note: run.note,
166
+ simSeconds: Number(run.elapsed.toFixed(3)),
167
+ };
168
+ // The terminal patch: gives the seat back — to the human, or
169
+ // to nobody, ending the run this tester started.
170
+ releaseTester(run.note);
171
+ }
172
+
173
+ /**
174
+ * The world is unmounting (Play stopped): a run cannot outlive the frame that
175
+ * steps it. Ends the current run as `stopped`, releases the seat, and leaves
176
+ * the outcome on `last` — module state must never strand a dead run into the
177
+ * NEXT session, where `hireTester` would refuse every goal for a run nothing
178
+ * is stepping. `QaTester.tsx`'s unmount cleanup is the one caller.
179
+ */
180
+ export function stopTesterForUnmount(): void {
181
+ releasePendingTaps();
182
+ clearVirtualActions();
183
+ const run = currentRun;
184
+ if (run === null) return;
185
+ currentRun = null;
186
+ lastJob = {
187
+ goal: run.goal,
188
+ outcome: 'stopped',
189
+ note: 'the world unmounted mid-run',
190
+ simSeconds: Number(run.elapsed.toFixed(3)),
191
+ };
192
+ releaseTester('the world unmounted mid-run');
193
+ }
@@ -0,0 +1,54 @@
1
+ import type { ThreeElements } from '@react-three/fiber';
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import * as THREE from 'three';
4
+
5
+ interface DaylightShaderPair {
6
+ readonly vertex: string;
7
+ readonly fragment: string;
8
+ }
9
+
10
+ async function readShader(path: string, signal: AbortSignal): Promise<string> {
11
+ const response = await fetch(path, { signal });
12
+ if (!response.ok) throw new Error(`DaylightSky could not load ${path}: HTTP ${response.status}`);
13
+ return response.text();
14
+ }
15
+
16
+ /** Procedural daylight sky supporting the starter scene. */
17
+ export function DaylightSky({ name = 'Daylight Sky', ...props }: ThreeElements['mesh']) {
18
+ const [shaders, setShaders] = useState<DaylightShaderPair | null>(null);
19
+ const uniforms = useMemo(
20
+ () => ({
21
+ uHorizonColor: { value: new THREE.Color('#badbe9') },
22
+ uZenithColor: { value: new THREE.Color('#297aba') },
23
+ uSunColor: { value: new THREE.Color('#fff0c2') },
24
+ }),
25
+ [],
26
+ );
27
+ useEffect(() => {
28
+ const controller = new AbortController();
29
+ void Promise.all([
30
+ readShader('/shaders/daylight-sky.vert.glsl', controller.signal),
31
+ readShader('/shaders/daylight-sky.frag.glsl', controller.signal),
32
+ ]).then(
33
+ ([vertex, fragment]) => setShaders({ vertex, fragment }),
34
+ (cause) => {
35
+ // biome-ignore lint/suspicious/noConsole: failed project assets must surface in the editor console.
36
+ if (!controller.signal.aborted) console.error(cause);
37
+ },
38
+ );
39
+ return () => controller.abort();
40
+ }, []);
41
+ if (!shaders) return null;
42
+ return (
43
+ <mesh name={name} scale={150} {...props}>
44
+ <sphereGeometry args={[1, 64, 32]} />
45
+ <shaderMaterial
46
+ side={THREE.BackSide}
47
+ depthWrite={false}
48
+ uniforms={uniforms}
49
+ vertexShader={shaders.vertex}
50
+ fragmentShader={shaders.fragment}
51
+ />
52
+ </mesh>
53
+ );
54
+ }