@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,121 @@
1
+ import type { ToolContext } from '@volter/editor-sdk/tools/registry';
2
+ import type * as THREE from 'three';
3
+ import type { Object3DSourceBuild } from '../bake/object3d-source';
4
+ import {
5
+ collectMorphTargets,
6
+ exportObject3DToGlb,
7
+ type GlbValidationOptions,
8
+ installNodeThreePolyfills,
9
+ validateExportedGlb,
10
+ } from './gltf-bake';
11
+
12
+ type SourceFacts = Record<string, unknown>;
13
+
14
+ type ToolOutcome<T> = { ok: true; value: T } | { ok: false; error: unknown };
15
+
16
+ async function captureOutcome<T>(operation: Promise<T>): Promise<ToolOutcome<T>> {
17
+ try {
18
+ return { ok: true, value: await operation };
19
+ } catch (error) {
20
+ return { ok: false, error };
21
+ }
22
+ }
23
+
24
+ export interface Object3DBakeOptions<
25
+ TBuild extends Object3DSourceBuild,
26
+ TFacts extends SourceFacts,
27
+ > {
28
+ ctx: ToolContext;
29
+ name: string;
30
+ dryRun: boolean;
31
+ build(): TBuild;
32
+ resolveAnimations?(
33
+ build: TBuild,
34
+ ): readonly THREE.AnimationClip[] | Promise<readonly THREE.AnimationClip[]>;
35
+ validateSource?(build: TBuild, animations: readonly THREE.AnimationClip[]): void | Promise<void>;
36
+ /** Round-trip validation thresholds. May be a function of the built source
37
+ * so source-derived facts (bone count, a sampled vertex color) can be
38
+ * asserted against the reimported GLB. `requiredClips` and
39
+ * `requiredMorphTargets` are NOT settable here: both are read off the built
40
+ * source below, so no lib can bake an asset that quietly asserts less than
41
+ * what it authored. */
42
+ validation:
43
+ | Omit<GlbValidationOptions, 'requiredClips' | 'requiredMorphTargets'>
44
+ | ((build: TBuild) => Omit<GlbValidationOptions, 'requiredClips' | 'requiredMorphTargets'>);
45
+ inspectSource(build: TBuild): TFacts;
46
+ }
47
+
48
+ /**
49
+ * Compile an ordinary Object3D factory into the runtime asset pair. This is a
50
+ * build helper, not a modeling abstraction: geometry, materials, hierarchy,
51
+ * rigging, and animation remain native Three.js in the caller.
52
+ */
53
+ export async function bakeObject3DSource<
54
+ TBuild extends Object3DSourceBuild,
55
+ TFacts extends SourceFacts,
56
+ >(options: Object3DBakeOptions<TBuild, TFacts>) {
57
+ const { ctx } = options;
58
+ const projectOutputs = ctx.projectOutputs;
59
+ if (!projectOutputs) throw new Error('Object3D baking requires a project output writer.');
60
+ if (ctx.signal?.aborted) throw new Error('Object3D baking was cancelled.');
61
+
62
+ const restoreGlobals = installNodeThreePolyfills();
63
+ let built: TBuild | undefined;
64
+ const runOperation = async () => {
65
+ const currentBuild = options.build();
66
+ built = currentBuild;
67
+ const animations = options.resolveAnimations
68
+ ? await options.resolveAnimations(currentBuild)
69
+ : (currentBuild.animations ?? []);
70
+ await options.validateSource?.(currentBuild, animations);
71
+
72
+ const requiredMorphTargets = collectMorphTargets(currentBuild.root);
73
+ const glb = await exportObject3DToGlb(currentBuild.root, animations);
74
+ const validationOptions =
75
+ typeof options.validation === 'function'
76
+ ? options.validation(currentBuild)
77
+ : options.validation;
78
+ const validation = await validateExportedGlb(glb, {
79
+ ...validationOptions,
80
+ requiredClips: animations.map((clip) => clip.name),
81
+ requiredMorphTargets,
82
+ });
83
+ const model = `public/models/generated/${options.name}.glb`;
84
+ const output = await projectOutputs.write(
85
+ [{ path: model, content: glb, mediaType: 'model/gltf-binary', role: 'asset' }],
86
+ { dryRun: options.dryRun },
87
+ );
88
+ return {
89
+ model,
90
+ ...options.inspectSource(currentBuild),
91
+ ...validation,
92
+ ...output,
93
+ };
94
+ };
95
+
96
+ const outcome = await captureOutcome(runOperation());
97
+ const operationError = outcome.ok ? undefined : outcome.error;
98
+
99
+ const cleanupErrors: unknown[] = [];
100
+ if (built) {
101
+ try {
102
+ built.dispose();
103
+ } catch (error) {
104
+ cleanupErrors.push(error);
105
+ }
106
+ }
107
+ try {
108
+ restoreGlobals();
109
+ } catch (error) {
110
+ cleanupErrors.push(error);
111
+ }
112
+ if (cleanupErrors.length > 0) {
113
+ throw new AggregateError(
114
+ operationError === undefined ? cleanupErrors : [operationError, ...cleanupErrors],
115
+ 'Object3D baking failed to clean up completely.',
116
+ );
117
+ }
118
+ if (operationError !== undefined) throw operationError;
119
+ if (!outcome.ok) throw outcome.error;
120
+ return outcome.value;
121
+ }
@@ -0,0 +1,15 @@
1
+ import type * as THREE from 'three';
2
+
3
+ export function disposeObject3D(root: THREE.Object3D): void {
4
+ root.traverse((object) => {
5
+ const mesh = object as THREE.Mesh;
6
+ mesh.geometry?.dispose();
7
+ for (const material of Array.isArray(mesh.material)
8
+ ? mesh.material
9
+ : mesh.material
10
+ ? [mesh.material]
11
+ : []) {
12
+ material.dispose();
13
+ }
14
+ });
15
+ }
@@ -0,0 +1,8 @@
1
+ import type * as THREE from 'three';
2
+
3
+ /** Project-local structural boundary between raw Three.js source and bake/preview helpers. */
4
+ export interface Object3DSourceBuild {
5
+ root: THREE.Object3D;
6
+ animations?: readonly THREE.AnimationClip[];
7
+ dispose(): void;
8
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Reading a declared params schema as tuning controls.
3
+ *
4
+ * The parameterization contract (the `vgai-3d-assets` skill,
5
+ * "Parametric asset libs") says a
6
+ * parametric asset lib exports a PAIR — a declared parameter object and the
7
+ * function that takes it — and that any tuning UI is DERIVED from that
8
+ * declaration, never hand-mirrored. A hand-kept control table is a second
9
+ * list of the same facts, and second lists rot: a knob added to the schema
10
+ * gets no control, and a bound changed there silently leaves a slider driving
11
+ * values the generator would reject at parse.
12
+ *
13
+ * `z.toJSONSchema` is zod's own public projection of exactly what was
14
+ * declared — bounds, defaults, and `.describe()` prose — so this file is the
15
+ * whole mechanism. Both shipped libs (`lib/humanoid`, `lib/castle`)
16
+ * bind their Builder controls to it; a lib of your own gets a tuning UI by
17
+ * declaring a schema and nothing else.
18
+ */
19
+
20
+ import type { z } from 'zod';
21
+ import * as zod from 'zod';
22
+
23
+ /** One numeric knob, read off a declared params schema. */
24
+ export interface NumericParamDescriptor {
25
+ readonly key: string;
26
+ readonly min: number;
27
+ readonly max: number;
28
+ /** The declared default; absent for an optional param that has none. */
29
+ readonly default?: number;
30
+ /** The field's `.describe()` prose — control hint / tooltip copy. */
31
+ readonly description: string;
32
+ /** True when the param may be omitted (it has no default). */
33
+ readonly optional: boolean;
34
+ }
35
+
36
+ /** Every bounded numeric field of a params schema, in declaration order.
37
+ * Fields without both bounds are skipped: an unbounded number has no slider
38
+ * range, so a UI must decide what to do with it explicitly. */
39
+ export function describeNumericParams(schema: z.ZodType): readonly NumericParamDescriptor[] {
40
+ const json = zod.toJSONSchema(schema) as {
41
+ properties?: Record<
42
+ string,
43
+ { type?: string; minimum?: number; maximum?: number; default?: unknown; description?: string }
44
+ >;
45
+ required?: string[];
46
+ };
47
+ const required = new Set(json.required ?? []);
48
+ return Object.entries(json.properties ?? {}).flatMap(([key, property]) => {
49
+ const { minimum, maximum } = property;
50
+ if (property.type !== 'number' || minimum === undefined || maximum === undefined) return [];
51
+ return [
52
+ {
53
+ key,
54
+ min: minimum,
55
+ max: maximum,
56
+ ...(typeof property.default === 'number' ? { default: property.default } : {}),
57
+ description: property.description ?? '',
58
+ optional: !required.has(key),
59
+ },
60
+ ];
61
+ });
62
+ }
63
+
64
+ /** Descriptor defaults as a plain params object — the initial state of a
65
+ * control set. Params with no declared default are omitted (the generator's
66
+ * own "natural" behavior stands until the user types a value). */
67
+ export function defaultParams(
68
+ descriptors: readonly NumericParamDescriptor[],
69
+ ): Record<string, number> {
70
+ return Object.fromEntries(
71
+ descriptors
72
+ .filter((descriptor) => descriptor.default !== undefined)
73
+ .map((descriptor) => [descriptor.key, descriptor.default as number]),
74
+ );
75
+ }
@@ -0,0 +1,217 @@
1
+ /**
2
+ * REST-RELATIVE CLIP AUTHORING + the clip self-checks, for any rigged asset:
3
+ * `assertClipRestBoundaries` (does it return to REST — what an additive layer
4
+ * needs) and `assertClipLoops` (does it return to WHERE IT STARTED — what a
5
+ * cyclic clip needs), plus `sampleAnimatedDeformedBounds`.
6
+ *
7
+ * Skeleton-agnostic by construction — it speaks `THREE.Bone`, `THREE.Object3D`
8
+ * and `THREE.AnimationClip` and knows nothing about humanoids — so it lives
9
+ * here in `lib/bake`, the procedural-asset family's shared home, beside
10
+ * `clip-layering.ts`. `lib/humanoid/rest-relative-animation.ts` re-exports it
11
+ * verbatim, so every import path that ever worked still does.
12
+ *
13
+ * REMOVAL LINE: delete this file and its humanoid re-export. You lose the
14
+ * ability to AUTHOR clips as pose deltas and the loud checks; retargeted
15
+ * clips and baking are unaffected.
16
+ */
17
+
18
+ import * as THREE from 'three';
19
+
20
+ export type EulerDelta = readonly [x: number, y: number, z: number];
21
+
22
+ function createTrackInterpolant(track: THREE.KeyframeTrack): {
23
+ evaluate(time: number): ArrayLike<number>;
24
+ } {
25
+ // Three assigns this native factory at runtime, but its r180 declarations
26
+ // omit the property. Keep the runtime factory so custom track interpolation
27
+ // remains intact.
28
+ const factory = (
29
+ track as THREE.KeyframeTrack & {
30
+ createInterpolant?: () => { evaluate(time: number): ArrayLike<number> };
31
+ }
32
+ ).createInterpolant;
33
+ if (!factory) throw new Error(`Animation track ${track.name} has no interpolant factory.`);
34
+ return factory.call(track);
35
+ }
36
+
37
+ /** Build an absolute quaternion track from local deltas without erasing rest orientation. */
38
+ export function createRestRelativeQuaternionTrack(
39
+ bone: THREE.Bone,
40
+ times: readonly number[],
41
+ deltas: readonly EulerDelta[],
42
+ ): THREE.QuaternionKeyframeTrack {
43
+ if (times.length !== deltas.length || times.length === 0) {
44
+ throw new Error(
45
+ `Rest-relative track for ${bone.name} needs one delta per time (${times.length} times, ${deltas.length} deltas).`,
46
+ );
47
+ }
48
+ const rest = bone.quaternion.clone().normalize();
49
+ const values: number[] = [];
50
+ let previous: THREE.Quaternion | undefined;
51
+ for (const [x, y, z] of deltas) {
52
+ const delta = new THREE.Quaternion().setFromEuler(new THREE.Euler(x, y, z));
53
+ const value = rest.clone().multiply(delta).normalize();
54
+ if (previous && previous.dot(value) < 0) value.set(-value.x, -value.y, -value.z, -value.w);
55
+ values.push(value.x, value.y, value.z, value.w);
56
+ previous = value;
57
+ }
58
+ return new THREE.QuaternionKeyframeTrack(`${bone.name}.quaternion`, [...times], values);
59
+ }
60
+
61
+ /** Assert that a clip intentionally authored to return to rest actually does so. */
62
+ export function assertClipRestBoundaries(
63
+ root: THREE.Object3D,
64
+ clip: THREE.AnimationClip,
65
+ sampleTimes: readonly number[] = [0, clip.duration],
66
+ toleranceRadians = 1e-4,
67
+ ): void {
68
+ for (const track of clip.tracks) {
69
+ if (!track.name.endsWith('.quaternion')) continue;
70
+ const nodeName = track.name.slice(0, -'.quaternion'.length);
71
+ const node = root.getObjectByName(nodeName);
72
+ if (!node) throw new Error(`Clip '${clip.name}' targets missing node '${nodeName}'.`);
73
+ const rest = node.quaternion.clone().normalize();
74
+ const interpolant = createTrackInterpolant(track);
75
+ for (const time of sampleTimes) {
76
+ const sample = interpolant.evaluate(time);
77
+ const value = new THREE.Quaternion(sample[0], sample[1], sample[2], sample[3]).normalize();
78
+ const angle = 2 * Math.acos(THREE.MathUtils.clamp(Math.abs(rest.dot(value)), -1, 1));
79
+ if (!Number.isFinite(angle) || angle > toleranceRadians) {
80
+ throw new Error(
81
+ `Clip '${clip.name}' erases the rest orientation of '${nodeName}' at t=${time.toFixed(3)} (error ${angle.toFixed(6)} rad).`,
82
+ );
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Assert that a clip authored to LOOP actually does: every track's first and
90
+ * last keyframe values agree within `tolerance`, over a positive duration.
91
+ *
92
+ * The cyclic sibling of {@link assertClipRestBoundaries}, and deliberately a
93
+ * different check. That one asks "does the clip return to REST" — the property
94
+ * an additive layer needs, measured against the skeleton. This one asks "does
95
+ * the clip return to WHERE IT STARTED", which is what a looping clip needs and
96
+ * is a strictly weaker, skeleton-free property: a walk cycle, a wingbeat or an
97
+ * idle breath holds a pose that is nowhere near rest and must still meet
98
+ * itself seamlessly. Reaching for the rest check on a cyclic clip fails every
99
+ * honest loop; reaching for neither is how a one-frame pop ships, because the
100
+ * seam is exactly the frame nobody scrubs to.
101
+ *
102
+ * Works on the raw track VALUES rather than an interpolant, so it is exact and
103
+ * says nothing about the interpolation between the ends: what it catches is
104
+ * the authoring mistake — a phase gradient that does not close, a sine sampled
105
+ * over an open interval, a keyed track whose last value was never brought back
106
+ * — not a curve's shape.
107
+ *
108
+ * Throws naming the failing track and its drift; returns nothing when clean.
109
+ */
110
+ export function assertClipLoops(clip: THREE.AnimationClip, tolerance = 1e-4): void {
111
+ if (!(clip.duration > 0)) {
112
+ throw new Error(
113
+ `Clip '${clip.name}' cannot loop: its duration is ${clip.duration} — a cycle with no length.`,
114
+ );
115
+ }
116
+ for (const track of clip.tracks) {
117
+ const stride = track.getValueSize();
118
+ const { values } = track;
119
+ if (values.length < stride) {
120
+ throw new Error(`Clip '${clip.name}' track '${track.name}' has no keyframe values.`);
121
+ }
122
+ let drift = 0;
123
+ for (let i = 0; i < stride; i += 1) {
124
+ drift = Math.max(
125
+ drift,
126
+ Math.abs((values[i] as number) - (values[values.length - stride + i] as number)),
127
+ );
128
+ }
129
+ if (!Number.isFinite(drift) || drift > tolerance) {
130
+ throw new Error(
131
+ `Clip '${clip.name}' does not loop: track '${track.name}' drifts by ${drift.toFixed(5)} ` +
132
+ `between t=0 and t=${clip.duration} (tolerance ${tolerance}).`,
133
+ );
134
+ }
135
+ }
136
+ }
137
+
138
+ export interface AnimatedBoundsSample {
139
+ bindDiagonal: number;
140
+ maximumDiagonal: number;
141
+ maximumExpansionRatio: number;
142
+ samples: number;
143
+ }
144
+
145
+ /** Sample precise SkinnedMesh bounds across a clip, restoring the source pose afterward. */
146
+ export function sampleAnimatedDeformedBounds(
147
+ root: THREE.Object3D,
148
+ clip: THREE.AnimationClip,
149
+ sampleCount = 20,
150
+ allowedExpansionRatio = 3,
151
+ ): AnimatedBoundsSample {
152
+ if (sampleCount < 1) throw new Error('Animated bounds sampling needs at least one interval.');
153
+ const saved = new Map<
154
+ THREE.Object3D,
155
+ { position: THREE.Vector3; quaternion: THREE.Quaternion; scale: THREE.Vector3 }
156
+ >();
157
+ root.traverse((object) => {
158
+ saved.set(object, {
159
+ position: object.position.clone(),
160
+ quaternion: object.quaternion.clone(),
161
+ scale: object.scale.clone(),
162
+ });
163
+ });
164
+ const preciseBounds = () => {
165
+ root.updateMatrixWorld(true);
166
+ const bounds = new THREE.Box3();
167
+ root.traverse((object) => {
168
+ const mesh = object as THREE.Mesh;
169
+ if (!mesh.isMesh || !mesh.geometry) return;
170
+ if ((mesh as THREE.SkinnedMesh).isSkinnedMesh) {
171
+ const skinned = mesh as THREE.SkinnedMesh;
172
+ skinned.computeBoundingBox();
173
+ if (skinned.boundingBox) {
174
+ bounds.union(skinned.boundingBox.clone().applyMatrix4(skinned.matrixWorld));
175
+ }
176
+ } else {
177
+ if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox();
178
+ if (mesh.geometry.boundingBox) {
179
+ bounds.union(mesh.geometry.boundingBox.clone().applyMatrix4(mesh.matrixWorld));
180
+ }
181
+ }
182
+ });
183
+ if (bounds.isEmpty()) throw new Error('Animated bounds sampling found no mesh bounds.');
184
+ const diagonal = bounds.getSize(new THREE.Vector3()).length();
185
+ if (!Number.isFinite(diagonal) || diagonal <= 0) {
186
+ throw new Error(`Animated bounds produced invalid diagonal ${diagonal}.`);
187
+ }
188
+ return diagonal;
189
+ };
190
+
191
+ const bindDiagonal = preciseBounds();
192
+ const mixer = new THREE.AnimationMixer(root);
193
+ mixer.clipAction(clip).play();
194
+ let maximumDiagonal = bindDiagonal;
195
+ try {
196
+ for (let index = 0; index <= sampleCount; index += 1) {
197
+ mixer.setTime((clip.duration * index) / sampleCount);
198
+ maximumDiagonal = Math.max(maximumDiagonal, preciseBounds());
199
+ }
200
+ } finally {
201
+ mixer.stopAllAction();
202
+ mixer.uncacheRoot(root);
203
+ for (const [object, transform] of saved) {
204
+ object.position.copy(transform.position);
205
+ object.quaternion.copy(transform.quaternion);
206
+ object.scale.copy(transform.scale);
207
+ }
208
+ root.updateMatrixWorld(true);
209
+ }
210
+ const maximumExpansionRatio = maximumDiagonal / bindDiagonal;
211
+ if (!Number.isFinite(maximumExpansionRatio) || maximumExpansionRatio > allowedExpansionRatio) {
212
+ throw new Error(
213
+ `Clip '${clip.name}' expands deformed bounds by ${maximumExpansionRatio.toFixed(3)}× (limit ${allowedExpansionRatio}×).`,
214
+ );
215
+ }
216
+ return { bindDiagonal, maximumDiagonal, maximumExpansionRatio, samples: sampleCount + 1 };
217
+ }
@@ -0,0 +1,95 @@
1
+ import { useMemo } from 'react';
2
+ import type * as THREE from 'three';
3
+ import { clone as cloneSkeleton } from 'three/addons/utils/SkeletonUtils.js';
4
+
5
+ /**
6
+ * THE SEAM BETWEEN A MODEL BUILDER AND A PREFAB.
7
+ *
8
+ * A game authors a 3D asset as a builder returning an Object3D — that is what
9
+ * `project.bake.preview` photographs in isolation and what `project.bake`
10
+ * bakes. To place one in a world it has to become an R3F component, and until
11
+ * this existed the engine offered no way across that gap, so every project
12
+ * hand-rolled the same three decisions: build once or per instance, clone or
13
+ * duplicate, and how to hold the result across renders.
14
+ *
15
+ * The obvious hand-rolled answer is wrong, and wrong SILENTLY:
16
+ *
17
+ * const model = useMemo(() => build(), []); // <- stale after any edit
18
+ *
19
+ * React Fast Refresh re-renders a mounted component rather than remounting it,
20
+ * and deliberately preserves hook state. An empty dep array therefore survives
21
+ * every hot update, so the component goes on handing out the Object3D built
22
+ * from the module version before the edit. The new geometry is built correctly
23
+ * and nothing ever asks for it. Nothing errors; the model simply stops
24
+ * changing, which reads as "HMR is broken" and sends people to restart the
25
+ * host — the failure that motivated this file.
26
+ *
27
+ * `useModel` keys its cache on the BUILDER ITSELF. A hot update re-executes the
28
+ * module that defines the builder, which mints a new function identity, so the
29
+ * dep changes exactly when the source changed and at no other time.
30
+ *
31
+ * Instances share buffers: the builder runs once per builder identity, and each
32
+ * caller gets a `clone()`, which copies the scene graph while sharing geometry
33
+ * and material by reference. A hall with ten of a machine pays for ten graph
34
+ * entries and one set of buffers.
35
+ *
36
+ * function Scanner(props: ThreeElements['group']) {
37
+ * const model = useModel(buildScanner);
38
+ * return <group {...props}><primitive object={model} /></group>;
39
+ * }
40
+ *
41
+ * Disposal is deliberately NOT done here. The shared source outlives any one
42
+ * component, and clones share its buffers, so disposing on unmount would free
43
+ * geometry still in use by every sibling. A project that spawns and destroys
44
+ * models at runtime owns that lifetime itself — `disposeObject3D` is next door.
45
+ */
46
+ const sources = new WeakMap<() => THREE.Object3D, THREE.Object3D>();
47
+
48
+ /** Build (or reuse) a model and return an instance of it, HMR-correct. */
49
+ export function useModel(build: () => THREE.Object3D): THREE.Object3D {
50
+ return useMemo(() => instantiate(build), [build]);
51
+ }
52
+
53
+ /**
54
+ * The same thing outside React, for callers placing models imperatively. Kept
55
+ * beside the hook rather than duplicated, so both share one cache.
56
+ */
57
+ export function instantiate(build: () => THREE.Object3D): THREE.Object3D {
58
+ let source = sources.get(build);
59
+ if (!source) {
60
+ source = build();
61
+ sources.set(build, source);
62
+ }
63
+ return cloneModel(source);
64
+ }
65
+
66
+ /**
67
+ * Clone a built model — and use `SkeletonUtils` when it is RIGGED.
68
+ *
69
+ * `Object3D.clone()` copies the meshes and the bones but NOT the bone↔skeleton
70
+ * wiring: the copied `SkinnedMesh` keeps a reference to the ORIGINAL's
71
+ * `THREE.Skeleton`, so it is driven by the original's bones and the clone's own
72
+ * bones drive nothing. One instance animates and every other stands frozen —
73
+ * with no error anywhere, because nothing is broken, only pointed elsewhere.
74
+ * This is the same trap the 3D-assets skill names for a baked GLB
75
+ * ("a SKINNED GLB must be cloned with `SkeletonUtils.clone`"); it applies to a
76
+ * model MODULE for exactly the same reason, and `useModel` is the seam every
77
+ * model module reaches a scene through.
78
+ *
79
+ * Measured by the adventurer driver: a story wound its clip onto the clone's
80
+ * bones and the character rendered its REST pose in every variant.
81
+ *
82
+ * `animations` is carried across too. Three's clone drops the field, and the
83
+ * model-file contract puts a model's clips on `root.animations` — a prefab
84
+ * that could not read them would have to rebuild them, which is a second
85
+ * implementation of the thing the module already shipped.
86
+ */
87
+ function cloneModel(source: THREE.Object3D): THREE.Object3D {
88
+ let rigged = false;
89
+ source.traverse((object) => {
90
+ if ((object as THREE.SkinnedMesh).isSkinnedMesh === true) rigged = true;
91
+ });
92
+ const copy = rigged ? cloneSkeleton(source) : source.clone();
93
+ if (source.animations.length > 0) copy.animations = source.animations;
94
+ return copy;
95
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * React as the implementer of this project's `dom` roots.
3
+ *
4
+ * A `dom` root is one of the three things the host can hand you: an
5
+ * `HTMLElement` (the others being a `<canvas>` and a shared `three`
6
+ * instance). What mounts into that element is entirely your choice — the
7
+ * engine has no opinion and ships no default, which is why this file lives in
8
+ * your project rather than in the engine.
9
+ *
10
+ * React is the shipped choice because the editor's JSX authoring
11
+ * (OID-addressed hierarchy, style/className write-back to source) is built on
12
+ * it. Nothing forces it: register your own factory for `'dom'` and the same
13
+ * root mounts Vue, Svelte, or plain DOM. You lose the JSX authoring panels
14
+ * until that stack supplies its own authoring adapter — the panel is the
15
+ * reward for implementing the adapter, and the game runs regardless.
16
+ *
17
+ * Thirty lines, and every one of them is React's own API — `createRoot`,
18
+ * `flushSync`, `unmount`. Copied in, yours to edit.
19
+ */
20
+ export { createReactRootAdapter, registerReactAdapter } from './react-root-adapter';
@@ -0,0 +1,57 @@
1
+ import { WorldProvider } from '@volter/game-runtime/react/world-state';
2
+ import type { GameDomHostContext } from '@volter/game-runtime/runtime/host-context';
3
+ import type { MountedReactGame, ReactRootAdapter } from '@volter/game-runtime/runtime/create-runtime';
4
+ import { isAdapterRegistered, registerAdapter } from '@volter/game-runtime/runtime/mount-game';
5
+ import { type ComponentType, createElement } from 'react';
6
+ import { flushSync } from 'react-dom';
7
+ import { createRoot } from 'react-dom/client';
8
+
9
+ interface ReactEntryModule {
10
+ readonly default?: ComponentType;
11
+ }
12
+
13
+ /** Construct one canonical React root adapter for direct host composition. */
14
+ export function createReactRootAdapter(id: string, Entry: ComponentType): ReactRootAdapter {
15
+ return {
16
+ id,
17
+ async mount(host: GameDomHostContext): Promise<MountedReactGame> {
18
+ if (!host.game) throw new Error(`React root "${id}" requires a Game host.`);
19
+ const reactRoot = createRoot(host.container);
20
+ flushSync(() => {
21
+ reactRoot.render(createElement(WorldProvider, { game: host.game! }, createElement(Entry)));
22
+ });
23
+ return {
24
+ kind: 'dom',
25
+ container: host.container,
26
+ drivesOwnLoop: false,
27
+ dispose: () => reactRoot.unmount(),
28
+ };
29
+ },
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Register React as the factory for this project's `dom` roots. Call once at
35
+ * module load, before mounting — ADD the call to your `src/main.ts` yourself:
36
+ * the scaffold's main.ts registers only `three`, and installing this
37
+ * capability does not edit it.
38
+ *
39
+ * Registration is what makes a `dom` root mount at all; the engine ships no
40
+ * default. Swap React out by not calling this and registering your own
41
+ * factory for `'dom'` instead — the host hands that factory an `HTMLElement`
42
+ * and asks for a dispose, which is all `createApp().mount(el)` or
43
+ * `new Svelte({ target })` needs.
44
+ */
45
+ export function registerReactAdapter(): void {
46
+ if (isAdapterRegistered('dom')) return;
47
+ registerAdapter('dom', (root, { entryModule }) => {
48
+ const Entry = (entryModule as ReactEntryModule | undefined)?.default;
49
+ if (!Entry) {
50
+ throw new Error(
51
+ `React root "${root.id}" entry "${root.entry ?? '(missing)'}" must default-export a component.`,
52
+ );
53
+ }
54
+
55
+ return { kind: 'dom', adapter: createReactRootAdapter(root.id, Entry) };
56
+ });
57
+ }