@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,502 @@
1
+ /**
2
+ * The module→Object3D step, shared by every tool that turns a project TS
3
+ * module's exported builder into a live `THREE.Object3D`.
4
+ *
5
+ * EXTRACTED VERBATIM from `src/tools/bake-module.tool.ts` (the typed error
6
+ * definitions, `resolveProjectModule`, `buildFromModule` and
7
+ * `computeMeshStats` were private there) when `project.bake.preview` needed
8
+ * the identical front half without the bake. Nothing about the behavior
9
+ * changed: the same path-escape guard, the same import, the same typed error
10
+ * codes. One copy, because "the same module, refused for a different reason
11
+ * depending on which verb you called" is the failure this prevents.
12
+ *
13
+ * It lives beside the tools rather than under `src/lib/bake/` because it is
14
+ * NODE-ONLY (`node:fs/promises`, `node:url`, a dynamic `import()` of project
15
+ * source). A project's own `tsconfig.json` compiles `src` for the browser and
16
+ * excludes `src/tools` precisely so tool code can reach for Node; a helper
17
+ * this shape under `src/lib/` reds every shipped project's typecheck.
18
+ */
19
+
20
+ import { realpath } from 'node:fs/promises';
21
+ import { resolve, sep } from 'node:path';
22
+ import { pathToFileURL } from 'node:url';
23
+ import { ToolError } from '@volter/editor-sdk/tools/errors';
24
+ import type { ToolErrorDefinition } from '@volter/editor-sdk/tools/registry';
25
+ import * as THREE from 'three';
26
+ import { z } from 'zod';
27
+
28
+ // ---------------------------------------------------------------------------
29
+ // Typed error codes — every real failure mode of `buildFromModule` /
30
+ // `resolveProjectModule`, mirroring the `ToolErrorDefinition` + `ToolError`
31
+ // pattern the SDK's own `project.*` operations use (e.g.
32
+ // `PATH_OUTSIDE_PROJECT_ERROR` in `@volter/editor-sdk`'s `project/shared.ts`).
33
+ // ---------------------------------------------------------------------------
34
+
35
+ export const MODULE_NOT_FOUND_ERROR: ToolErrorDefinition = {
36
+ code: 'MODULE_NOT_FOUND',
37
+ summary: 'The TypeScript module at modulePath does not exist, or failed to import.',
38
+ data: z.object({ modulePath: z.string(), reason: z.string() }),
39
+ };
40
+
41
+ export const EXPORT_NOT_CALLABLE_ERROR: ToolErrorDefinition = {
42
+ code: 'EXPORT_NOT_CALLABLE',
43
+ summary: "The named export is missing from the module, or isn't a function.",
44
+ data: z.object({
45
+ modulePath: z.string(),
46
+ exportName: z.string(),
47
+ available: z.array(z.string()),
48
+ }),
49
+ };
50
+
51
+ export const NOT_AN_OBJECT3D_ERROR: ToolErrorDefinition = {
52
+ code: 'NOT_AN_OBJECT3D',
53
+ summary: 'The export ran but did not return a THREE.Object3D or a THREE.BufferGeometry.',
54
+ data: z.object({ modulePath: z.string(), exportName: z.string(), returnedType: z.string() }),
55
+ };
56
+
57
+ export const EMPTY_GEOMETRY_ERROR: ToolErrorDefinition = {
58
+ code: 'EMPTY_GEOMETRY',
59
+ summary: 'The built Object3D has zero vertices or triangles — nothing renderable to bake.',
60
+ data: z.object({ modulePath: z.string(), exportName: z.string() }),
61
+ };
62
+
63
+ export const PATH_ESCAPES_PROJECT_ERROR: ToolErrorDefinition = {
64
+ code: 'PATH_ESCAPES_PROJECT',
65
+ summary: 'modulePath resolves outside the project root (e.g. via "..").',
66
+ data: z.object({ projectRoot: z.string(), modulePath: z.string() }),
67
+ };
68
+
69
+ /** Resolve `modulePath` to an absolute path that stays inside the project root (no `..` escape). */
70
+ export async function resolveProjectModule(
71
+ projectRoot: string,
72
+ modulePath: string,
73
+ ): Promise<string> {
74
+ const relativePath = modulePath.replace(/^\//, '');
75
+ const projectRootReal = await realpath(projectRoot);
76
+ const lexicalCandidate = resolve(projectRootReal, relativePath);
77
+ if (
78
+ lexicalCandidate !== projectRootReal &&
79
+ !lexicalCandidate.startsWith(`${projectRootReal}${sep}`)
80
+ ) {
81
+ throw new ToolError(
82
+ PATH_ESCAPES_PROJECT_ERROR.code,
83
+ `modulePath must resolve inside the project: ${modulePath}`,
84
+ { projectRoot: projectRootReal, modulePath },
85
+ );
86
+ }
87
+ let candidate: string;
88
+ try {
89
+ candidate = await realpath(lexicalCandidate);
90
+ } catch (error) {
91
+ throw new ToolError(
92
+ MODULE_NOT_FOUND_ERROR.code,
93
+ `module '${modulePath}' does not exist in the project.`,
94
+ { modulePath, reason: error instanceof Error ? error.message : String(error) },
95
+ );
96
+ }
97
+ if (candidate !== projectRootReal && !candidate.startsWith(`${projectRootReal}${sep}`)) {
98
+ throw new ToolError(
99
+ PATH_ESCAPES_PROJECT_ERROR.code,
100
+ `modulePath must resolve inside the project: ${modulePath}`,
101
+ { projectRoot: projectRootReal, modulePath },
102
+ );
103
+ }
104
+ return candidate;
105
+ }
106
+
107
+ /**
108
+ * THE TWO SHAPES A MODULE EXPORT MAY RETURN, normalized to one.
109
+ *
110
+ * 1. A bare `THREE.Object3D` — the original contract, and still the whole of
111
+ * it for a builder with nothing to tear down.
112
+ * 2. A BUILD RESULT `{ root, animations?, dispose? }` — the shape every
113
+ * parametric lib in the kit already returns (`createBird`'s `BirdBuild`,
114
+ * `createHumanoid`'s, and the fox/cub/winter generators a cold agent wrote
115
+ * from them). It is not a new convention invented here: `bakeObject3DSource`
116
+ * has always taken exactly `{ root, animations, dispose }` from its `build`
117
+ * callback, so the bake lane consumed this shape while the MODULE lane —
118
+ * `project.bake.module`, `project.bake.preview`, `vgai screenshot <module>`
119
+ * — refused it. Measured (cold fox, 2026-08-29): `vgai screenshot
120
+ * src/lib/fox/generate.ts` died with "export 'createFox' must return a
121
+ * THREE.Object3D, got object", closing the fast look door to every
122
+ * parametric lib including the kit's own worked examples.
123
+ *
124
+ * ANIMATIONS RIDE ON `root.animations`, always. That is three's own carrier —
125
+ * where `GLTFLoader` puts clips, what `Object3D.copy` carries across a clone,
126
+ * what `useAnimations(scene.animations)` reads — so a build result's separate
127
+ * `animations` list is written onto the root here and every downstream reader
128
+ * (the GLB writer, the preview exporter, the Asset Lab's transport) keeps
129
+ * working unchanged. A root that already carries clips is left alone.
130
+ */
131
+ export interface ModuleBuild {
132
+ readonly root: THREE.Object3D;
133
+ /** The builder's OWN teardown, when it returned one. The caller runs it
134
+ * instead of a generic graph dispose: a rig holds mixers, actions and
135
+ * materials a `traverse` walk does not know about. */
136
+ readonly dispose?: () => void;
137
+ }
138
+
139
+ /** Normalize any accepted shape, or `undefined` when it is none of them. */
140
+ function asModuleBuild(built: unknown): ModuleBuild | undefined {
141
+ if (!built || typeof built !== 'object') return undefined;
142
+ if ((built as THREE.Object3D).isObject3D === true) return { root: built as THREE.Object3D };
143
+ // 3. A MODEL MODULE — `build(): THREE.BufferGeometry` (`lib/mesh/geometry`).
144
+ // Geometry has no material; the lane photographs and bakes it under a
145
+ // neutral standard material, named for the export.
146
+ if ((built as THREE.BufferGeometry).isBufferGeometry === true) {
147
+ return {
148
+ root: new THREE.Mesh(built as THREE.BufferGeometry, new THREE.MeshStandardMaterial()),
149
+ };
150
+ }
151
+ const result = built as { root?: unknown; animations?: unknown; dispose?: unknown };
152
+ const root = result.root as THREE.Object3D | undefined;
153
+ if (!root || typeof root !== 'object' || root.isObject3D !== true) return undefined;
154
+ if (Array.isArray(result.animations) && root.animations.length === 0) {
155
+ root.animations = result.animations as THREE.AnimationClip[];
156
+ }
157
+ return {
158
+ root,
159
+ ...(typeof result.dispose === 'function'
160
+ ? { dispose: () => (result.dispose as () => void).call(built) }
161
+ : {}),
162
+ };
163
+ }
164
+
165
+ /**
166
+ * Import the project module and call its named export, matching the turntable `?module=&export=` contract.
167
+ *
168
+ * `loadModule` is the HOST's loader (`ctx.loadProjectModule`: the editor
169
+ * server's Vite SSR loader, which re-transforms a module — and everything it
170
+ * imports — when any file in that graph changes). Prefer it whenever the
171
+ * caller has one. The raw `import()` fallback is for a tool running outside an
172
+ * editor server, and it is a ONE-SHOT door: Node's ESM cache keys on the URL
173
+ * and never invalidates, so inside a long-lived server it returned the first
174
+ * version of `src/models/barrel.ts` for every later look until the server was
175
+ * restarted (the blind modeling bench measured three `vgai restart`s in one
176
+ * barrel, 2026-09-05).
177
+ */
178
+ export async function buildFromModule(
179
+ projectRoot: string,
180
+ modulePath: string,
181
+ exportName: string,
182
+ loadModule?: (absolutePath: string) => Promise<unknown>,
183
+ ): Promise<ModuleBuild> {
184
+ const absolute = await resolveProjectModule(projectRoot, modulePath);
185
+ let mod: Record<string, unknown>;
186
+ try {
187
+ mod = (
188
+ loadModule
189
+ ? await loadModule(absolute)
190
+ : await import(/* @vite-ignore */ pathToFileURL(absolute).href)
191
+ ) as Record<string, unknown>;
192
+ } catch (error) {
193
+ throw new ToolError(
194
+ MODULE_NOT_FOUND_ERROR.code,
195
+ `module '${modulePath}' failed to import: ${error instanceof Error ? error.message : String(error)}`,
196
+ { modulePath, reason: error instanceof Error ? error.message : String(error) },
197
+ );
198
+ }
199
+ // A MODEL MODULE's builder is `build` (`lib/mesh/geometry`'s contract), so a
200
+ // caller asking for the default export of a module that has none but has
201
+ // `build` gets the model — `vgai screenshot src/models/cube.ts` needs no flag.
202
+ const exp = mod[exportName] ?? (exportName === 'default' ? mod['build'] : undefined);
203
+ if (exp === undefined) {
204
+ throw new ToolError(
205
+ EXPORT_NOT_CALLABLE_ERROR.code,
206
+ `module '${modulePath}' has no export '${exportName}' (exports: ${Object.keys(mod).join(', ')})`,
207
+ { modulePath, exportName, available: Object.keys(mod) },
208
+ );
209
+ }
210
+ if (typeof exp !== 'function') {
211
+ throw new ToolError(
212
+ EXPORT_NOT_CALLABLE_ERROR.code,
213
+ `module '${modulePath}' export '${exportName}' must be a function returning a THREE.Object3D or THREE.BufferGeometry.`,
214
+ { modulePath, exportName, available: Object.keys(mod) },
215
+ );
216
+ }
217
+ const built = (await exp()) as unknown;
218
+ const build = asModuleBuild(built);
219
+ if (!build) {
220
+ throw new ToolError(
221
+ NOT_AN_OBJECT3D_ERROR.code,
222
+ `module '${modulePath}' export '${exportName}' must return a THREE.BufferGeometry (a model ` +
223
+ 'module), a THREE.Object3D, or a build result `{ root, animations?, dispose? }` whose ' +
224
+ "`root` is one (the kit's parametric libs — createBird, createHumanoid — return that " +
225
+ `shape). Got ${describeReturn(built)}.`,
226
+ { modulePath, exportName, returnedType: typeof built },
227
+ );
228
+ }
229
+ return build;
230
+ }
231
+
232
+ /** What the export actually returned, for the refusal above — `object` alone
233
+ * cannot tell a build result with a mistyped key from an unrelated value. */
234
+ function describeReturn(built: unknown): string {
235
+ if (built === null) return 'null';
236
+ if (typeof built !== 'object') return typeof built;
237
+ if (Array.isArray(built)) return 'an array';
238
+ const keys = Object.keys(built);
239
+ return keys.length > 0
240
+ ? `an object with keys ${keys.slice(0, 8).join(', ')}`
241
+ : 'an object with no own keys';
242
+ }
243
+
244
+ export function computeMeshStats(root: THREE.Object3D): {
245
+ vertexCount: number;
246
+ triangleCount: number;
247
+ /** See {@link countInvertedTriangles}. */
248
+ invertedTriangleCount: number;
249
+ /** Edges with exactly one triangle on them after welding by position —
250
+ * a hole, an unclosed cap, or a part that was never joined. See
251
+ * {@link countInvertedTriangles}, which measures both in one pass. */
252
+ boundaryEdgeCount: number;
253
+ /** World-space midpoints of up to six of those edges. */
254
+ boundaryEdgeSamples: [number, number, number][];
255
+ /** Vertices whose position is NaN or infinite. Three.js reports these as
256
+ * "computeBoundingBox(): Computed min/max have NaN values" on the console,
257
+ * naming no op and no line — a blind session spent five minutes with its
258
+ * own probe script finding where (2026-09-06). The look names the count. */
259
+ nonFiniteVertexCount: number;
260
+ } {
261
+ let vertexCount = 0;
262
+ let triangleCount = 0;
263
+ let invertedTriangleCount = 0;
264
+ let boundaryEdgeCount = 0;
265
+ let nonFiniteVertexCount = 0;
266
+ const boundaryEdgeSamples: [number, number, number][] = [];
267
+ root.traverse((object) => {
268
+ const mesh = object as THREE.Mesh;
269
+ if (!mesh.isMesh) return;
270
+ const position = mesh.geometry.getAttribute('position');
271
+ const index = mesh.geometry.getIndex();
272
+ vertexCount += position?.count ?? 0;
273
+ if (position) {
274
+ for (let i = 0; i < position.count; i += 1) {
275
+ if (
276
+ !Number.isFinite(position.getX(i)) ||
277
+ !Number.isFinite(position.getY(i)) ||
278
+ !Number.isFinite(position.getZ(i))
279
+ ) {
280
+ nonFiniteVertexCount += 1;
281
+ }
282
+ }
283
+ }
284
+ triangleCount += index ? index.count / 3 : (position?.count ?? 0) / 3;
285
+ const winding = countInvertedTriangles(mesh.geometry);
286
+ invertedTriangleCount += winding.inverted;
287
+ boundaryEdgeCount += winding.boundaryEdges;
288
+ // World space, as the brief's numbers are: the mesh's own transform applied.
289
+ mesh.updateWorldMatrix(true, false);
290
+ for (const [x, y, z] of winding.boundaryEdgeSamples) {
291
+ if (boundaryEdgeSamples.length >= 6) break;
292
+ const p = new THREE.Vector3(x, y, z).applyMatrix4(mesh.matrixWorld);
293
+ boundaryEdgeSamples.push([p.x, p.y, p.z]);
294
+ }
295
+ });
296
+ return {
297
+ vertexCount,
298
+ triangleCount,
299
+ invertedTriangleCount,
300
+ boundaryEdgeCount,
301
+ boundaryEdgeSamples,
302
+ nonFiniteVertexCount,
303
+ };
304
+ }
305
+
306
+ /**
307
+ * Triangles that FACE INWARD — the two ways a mesh gets there, counted the way
308
+ * Blender's Face Orientation overlay would paint them red:
309
+ *
310
+ * 1. an inside-out CLOSED SHELL (every edge shared by exactly two triangles)
311
+ * — its signed volume is negative, so every triangle in it is inverted.
312
+ * A shell that is consistently wound the wrong way has no local tell at
313
+ * all: every neighbour agrees with it, and only its volume says which side
314
+ * is out (`bmesh.ops.recalc_face_normals` decides the same way);
315
+ * 2. NON-CONTIGUOUS pairs — two triangles traversing a shared edge in the
316
+ * same direction, so their normals disagree (what the kit's `validate()`
317
+ * reports as `inconsistentWinding`). Both are counted; the count is a
318
+ * "how much is wrong" number, not a repair plan.
319
+ *
320
+ * Why the look verb needs this: the editor's model stage lights both sides,
321
+ * so a shell that is 60 % inverted photographs as a clean solid — the blind
322
+ * modeling bench shipped exactly that (a barrel whose 12 staves were built
323
+ * inside out, 432 of 720 triangles, reported "all features verified") while
324
+ * Blender rendered the same GLB dark. A picture that cannot show the defect
325
+ * has to SAY it.
326
+ *
327
+ * Vertices are welded by position (1e-5) first, so the flat-shaded, per-face
328
+ * vertex layout the mesh kit exports still resolves to shared edges.
329
+ */
330
+ export function countInvertedTriangles(geometry: THREE.BufferGeometry): {
331
+ inverted: number;
332
+ boundaryEdges: number;
333
+ /** Midpoints of the first few open edges, so a count becomes a place —
334
+ * four blind sessions accepted "2 open edges" because nothing said where. */
335
+ boundaryEdgeSamples: [number, number, number][];
336
+ } {
337
+ const position = geometry.getAttribute('position');
338
+ if (!position) return { inverted: 0, boundaryEdges: 0, boundaryEdgeSamples: [] };
339
+ const index = geometry.getIndex();
340
+ const triCount = index ? Math.floor(index.count / 3) : Math.floor(position.count / 3);
341
+ if (triCount === 0) return { inverted: 0, boundaryEdges: 0, boundaryEdgeSamples: [] };
342
+ const keyOf = new Map<string, number>();
343
+ const welded = new Int32Array(position.count);
344
+ for (let i = 0; i < position.count; i += 1) {
345
+ // Integer keys: `(-0).toFixed(5)` is "-0.00000" and never welds with
346
+ // "0.00000", which split every seam that landed on an axis and reported
347
+ // it as open edges (a barrel's head cylinders, blind bench 2026-09-06).
348
+ const key = `${Math.round(position.getX(i) * 1e5) || 0},${Math.round(position.getY(i) * 1e5) || 0},${Math.round(position.getZ(i) * 1e5) || 0}`;
349
+ let id = keyOf.get(key);
350
+ if (id === undefined) {
351
+ id = keyOf.size;
352
+ keyOf.set(key, id);
353
+ }
354
+ welded[i] = id;
355
+ }
356
+ const corner = (tri: number, k: number): number => {
357
+ const raw = index ? index.getX(tri * 3 + k) : tri * 3 + k;
358
+ return welded[raw] ?? 0;
359
+ };
360
+ // Union-find over welded vertices → connected shells.
361
+ const parent = new Int32Array(keyOf.size);
362
+ for (let i = 0; i < parent.length; i += 1) parent[i] = i;
363
+ const find = (a: number): number => {
364
+ let r = a;
365
+ while (parent[r] !== r) r = parent[r] as number;
366
+ while (parent[a] !== r) {
367
+ const next = parent[a] as number;
368
+ parent[a] = r;
369
+ a = next;
370
+ }
371
+ return r;
372
+ };
373
+ const union = (a: number, b: number) => {
374
+ const ra = find(a);
375
+ const rb = find(b);
376
+ if (ra !== rb) parent[ra] = rb;
377
+ };
378
+ const directed = new Map<string, number>();
379
+ const undirected = new Map<string, number>();
380
+ const tris: Array<[number, number, number]> = [];
381
+ for (let t = 0; t < triCount; t += 1) {
382
+ const a = corner(t, 0);
383
+ const b = corner(t, 1);
384
+ const c = corner(t, 2);
385
+ if (a === b || b === c || c === a) continue; // degenerate: no edge to disagree over
386
+ tris.push([a, b, c]);
387
+ union(a, b);
388
+ union(b, c);
389
+ for (const [u, v] of [
390
+ [a, b],
391
+ [b, c],
392
+ [c, a],
393
+ ] as const) {
394
+ const d = `${u}>${v}`;
395
+ directed.set(d, (directed.get(d) ?? 0) + 1);
396
+ const un = u < v ? `${u}-${v}` : `${v}-${u}`;
397
+ undirected.set(un, (undirected.get(un) ?? 0) + 1);
398
+ }
399
+ }
400
+ // Per shell: closed? signed volume.
401
+ const closed = new Map<number, boolean>();
402
+ const volume = new Map<number, number>();
403
+ for (const [a, b, c] of tris) {
404
+ const shell = find(a);
405
+ if (!closed.has(shell)) closed.set(shell, true);
406
+ for (const [u, v] of [
407
+ [a, b],
408
+ [b, c],
409
+ [c, a],
410
+ ] as const) {
411
+ const un = u < v ? `${u}-${v}` : `${v}-${u}`;
412
+ if (undirected.get(un) !== 2) closed.set(shell, false);
413
+ }
414
+ }
415
+ // Signed volume needs coordinates: read one representative position per welded id.
416
+ const rep = new Float64Array(keyOf.size * 3);
417
+ const seen = new Uint8Array(keyOf.size);
418
+ for (let i = 0; i < position.count; i += 1) {
419
+ const id = welded[i] as number;
420
+ if (seen[id]) continue;
421
+ seen[id] = 1;
422
+ rep[id * 3] = position.getX(i);
423
+ rep[id * 3 + 1] = position.getY(i);
424
+ rep[id * 3 + 2] = position.getZ(i);
425
+ }
426
+ for (const [a, b, c] of tris) {
427
+ const shell = find(a);
428
+ const ax = rep[a * 3] as number;
429
+ const ay = rep[a * 3 + 1] as number;
430
+ const az = rep[a * 3 + 2] as number;
431
+ const bx = rep[b * 3] as number;
432
+ const by = rep[b * 3 + 1] as number;
433
+ const bz = rep[b * 3 + 2] as number;
434
+ const cx = rep[c * 3] as number;
435
+ const cy = rep[c * 3 + 1] as number;
436
+ const cz = rep[c * 3 + 2] as number;
437
+ // a · (b × c) / 6
438
+ const v = (ax * (by * cz - bz * cy) - ay * (bx * cz - bz * cx) + az * (bx * cy - by * cx)) / 6;
439
+ volume.set(shell, (volume.get(shell) ?? 0) + v);
440
+ }
441
+ let boundaryEdges = 0;
442
+ const boundaryEdgeSamples: [number, number, number][] = [];
443
+ for (const [edge, count] of undirected) {
444
+ if (count !== 1) continue;
445
+ boundaryEdges += 1;
446
+ if (boundaryEdgeSamples.length >= 6) continue;
447
+ const [u, v] = edge.split('-').map(Number) as [number, number];
448
+ boundaryEdgeSamples.push([
449
+ ((rep[u * 3] as number) + (rep[v * 3] as number)) / 2,
450
+ ((rep[u * 3 + 1] as number) + (rep[v * 3 + 1] as number)) / 2,
451
+ ((rep[u * 3 + 2] as number) + (rep[v * 3 + 2] as number)) / 2,
452
+ ]);
453
+ }
454
+ let inverted = 0;
455
+ for (const [a, b, c] of tris) {
456
+ const shell = find(a);
457
+ if (closed.get(shell) && (volume.get(shell) ?? 0) < 0) {
458
+ inverted += 1;
459
+ continue;
460
+ }
461
+ // Non-contiguous only means something on a MANIFOLD edge (exactly two
462
+ // triangles). Two separate closed solids that touch along a knife edge
463
+ // — a barrel's staves at the groove apex, a lantern's collar on its roof
464
+ // — share that edge four ways after welding, every direction twice, and
465
+ // both solids are wound perfectly well. Two blind-bench sessions each
466
+ // spent several looks chasing that report before this line existed.
467
+ const manifold = (u: number, v: number) =>
468
+ undirected.get(u < v ? `${u}-${v}` : `${v}-${u}`) === 2;
469
+ if (
470
+ (manifold(a, b) && (directed.get(`${a}>${b}`) ?? 0) > 1) ||
471
+ (manifold(b, c) && (directed.get(`${b}>${c}`) ?? 0) > 1) ||
472
+ (manifold(c, a) && (directed.get(`${c}>${a}`) ?? 0) > 1)
473
+ ) {
474
+ inverted += 1;
475
+ }
476
+ }
477
+ return { inverted, boundaryEdges, boundaryEdgeSamples };
478
+ }
479
+
480
+ /** Every mesh in the built graph, for the mesh-count facts both verbs report. */
481
+ export function countMeshes(root: THREE.Object3D): number {
482
+ let meshCount = 0;
483
+ root.traverse((object) => {
484
+ if ((object as THREE.Mesh).isMesh) meshCount += 1;
485
+ });
486
+ return meshCount;
487
+ }
488
+
489
+ /** The shared "did the builder produce anything renderable?" gate. */
490
+ export function assertRenderableGeometry(
491
+ stats: { vertexCount: number; triangleCount: number },
492
+ modulePath: string,
493
+ exportName: string,
494
+ ): void {
495
+ if (stats.vertexCount > 0 && stats.triangleCount > 0) return;
496
+ throw new ToolError(
497
+ EMPTY_GEOMETRY_ERROR.code,
498
+ `module '${modulePath}' export '${exportName}' produced an Object3D with no ` +
499
+ 'renderable geometry.',
500
+ { modulePath, exportName },
501
+ );
502
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The `pagesFromUiModules` FINDER (ARCHITECTURE-CORE §The project model,
3
+ * "Documents, not scenes"): every project module under the selection's
4
+ * `include` globs that exports a React component is a `page` document —
5
+ * what a website is made of, the way a game is made of scenes. Select it
6
+ * in `vgai.adapter.ts`:
7
+ *
8
+ * documents: { find: [{ finder: 'pagesFromUiModules', include: ['src/ui/**\/*page.tsx'] }] }
9
+ *
10
+ * The glob IS the page rule: a project names its pages by where it keeps
11
+ * them. This module is a plain object the HOST registers; it mounts no UI
12
+ * and reads the project only through `input.sources`.
13
+ */
14
+ import { z } from 'zod';
15
+
16
+ const COMPONENT_EXPORT =
17
+ /export\s+(?:default\s+)?(?:function\s+[A-Z]\w*\s*\(|const\s+[A-Z]\w*\s*[:=])/;
18
+
19
+ export const finder = {
20
+ name: 'pagesFromUiModules',
21
+ schema: z
22
+ .object({
23
+ finder: z.literal('pagesFromUiModules'),
24
+ include: z
25
+ .array(z.string().min(1))
26
+ .min(1)
27
+ .describe('Project-relative globs of the page modules (`src/ui/**/*page.tsx`)'),
28
+ })
29
+ .strict(),
30
+ run(
31
+ _selection: { finder: 'pagesFromUiModules'; include: readonly string[] },
32
+ input: { sources?: readonly { path: string; source: string }[] },
33
+ ) {
34
+ const entries = [];
35
+ const notes: string[] = [];
36
+ for (const file of input.sources ?? []) {
37
+ if (!COMPONENT_EXPORT.test(file.source)) {
38
+ notes.push(`${file.path}: exports no component — not a page`);
39
+ continue;
40
+ }
41
+ const name = (file.path.split('/').pop() ?? file.path)
42
+ .replace(/\.[cm]?[jt]sx?$/, '')
43
+ .replace(/[-_.]?page$/i, '');
44
+ entries.push({
45
+ id: `page:${file.path}`,
46
+ label: name || 'page',
47
+ kind: 'page',
48
+ region: null,
49
+ authorable: true,
50
+ reach: { kind: 'root-mount' as const },
51
+ source: { path: file.path },
52
+ });
53
+ }
54
+ return {
55
+ entries,
56
+ notes,
57
+ // One page is the page; two is a choice the site's author states.
58
+ ...(entries.length === 1 ? { default: entries[0]!.id } : {}),
59
+ };
60
+ },
61
+ } as const;