@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,255 @@
1
+ /**
2
+ * The game's own SFX voice: a small Web Audio graph this project owns, and the
3
+ * `SystemAdapters.audio` registration that lets the host silence it.
4
+ *
5
+ * ## Why the game owns the context
6
+ *
7
+ * This world is an R3F root. An R3F root renders through react-three-fiber
8
+ * against the HOST's renderer, and the host supplies no mixer of its own —
9
+ * audio is the game's, built with Web Audio directly inside the tree. That is
10
+ * the seam doctrine working as designed: an absent capability is absent, not
11
+ * faked by the host.
12
+ *
13
+ * ## Why it is still mutable from the editor
14
+ *
15
+ * A game-owned context is only orphaned if nothing can see it. `SystemAdapters`
16
+ * is the seam for exactly this: the game DECLARES what it implements through
17
+ * its entry's `systems` export (`export const systems = { audio:
18
+ * sfxAudioSystem() }` in `src/systems.ts`), and from the moment the host
19
+ * installs it the editor's mute button, the Audio debugger tab and
20
+ * `Game.play.pause()`'s silence-on-pause all reach this graph — without the
21
+ * host fabricating a mixer it does not have, and without a component calling
22
+ * a host registration.
23
+ *
24
+ * The graph is deliberately tiny: one gain node (the game's whole "sfx bus")
25
+ * into the destination. Mute rides that node, so muting composes with the
26
+ * per-voice envelopes below instead of fighting them.
27
+ */
28
+
29
+ import type { AudioAdapter, AudioGraphNode } from '@volter/editor-project/adapter';
30
+
31
+ /** A one-shot blip: a falling/rising saw with an exponential decay. Frequencies
32
+ * in Hz, `duration` in seconds, `volume` linear (0–1), `end` the frequency to
33
+ * glide to (defaults to a steady tone). A no-op when this environment has no
34
+ * Web Audio at all — headless CI, an SSR pass — which is why callers never
35
+ * guard. */
36
+ export type PlayTone = (frequency: number, duration: number, volume: number, end?: number) => void;
37
+
38
+ export interface GainDuckOptions {
39
+ /** Gain while ducked, in linear amplitude. */
40
+ duckGain?: number;
41
+ /** Seconds to reach the ducked level. */
42
+ attack?: number;
43
+ /** Seconds to remain ducked before restoring. */
44
+ hold?: number;
45
+ /** Seconds to restore the resting gain. */
46
+ release?: number;
47
+ }
48
+
49
+ /**
50
+ * Coordinate ducking on an ordinary Web Audio gain parameter. The project
51
+ * keeps the native AudioParam — this helper only owns the easy-to-get-wrong
52
+ * cancel/hold/restore automation for repeated triggers.
53
+ */
54
+ export function createGainDucker(
55
+ context: BaseAudioContext,
56
+ gain: AudioParam,
57
+ options: GainDuckOptions = {},
58
+ ): { trigger(): void; dispose(): void } {
59
+ const restingGain = gain.value;
60
+ const duckGain = Math.max(0, options.duckGain ?? 0.35);
61
+ const attack = Math.max(0, options.attack ?? 0.02);
62
+ const hold = Math.max(0, options.hold ?? 0.12);
63
+ const release = Math.max(0, options.release ?? 0.25);
64
+
65
+ return {
66
+ trigger(): void {
67
+ const now = context.currentTime;
68
+ gain.cancelAndHoldAtTime(now);
69
+ gain.linearRampToValueAtTime(duckGain, now + attack);
70
+ gain.setValueAtTime(duckGain, now + attack + hold);
71
+ gain.linearRampToValueAtTime(restingGain, now + attack + hold + release);
72
+ },
73
+ dispose(): void {
74
+ const now = context.currentTime;
75
+ gain.cancelScheduledValues(now);
76
+ gain.setValueAtTime(restingGain, now);
77
+ },
78
+ };
79
+ }
80
+
81
+ /** What {@link createGameSfx} hands back: the voice, the adapter to register,
82
+ * and the teardown the mounting component owns. */
83
+ export interface GameSfx {
84
+ readonly tone: PlayTone;
85
+ /** Expose this through the root entry's `systems.audio` so
86
+ * host mute/pause reach the graph. `null` when there is no real context to
87
+ * silence — registering a no-op adapter would tell the host this world's
88
+ * audio is under control when there is no audio at all. */
89
+ readonly adapter: AudioAdapter | null;
90
+ /** Close the context. Nothing else owns it. */
91
+ dispose(): void;
92
+ }
93
+
94
+ /** The silent stand-in for an environment with no Web Audio (jsdom, a headless
95
+ * bot run). It reports no adapter, so `Game.play.pause()` says out loud that
96
+ * this world has no audio seam rather than pretending it silenced one. */
97
+ const SILENT: GameSfx = {
98
+ tone: () => {},
99
+ adapter: null,
100
+ dispose: () => {},
101
+ };
102
+
103
+ export function createGameSfx({ maxVoices = 24 }: { maxVoices?: number } = {}): GameSfx {
104
+ const Ctor: typeof AudioContext | undefined =
105
+ typeof AudioContext !== 'undefined' ? AudioContext : undefined;
106
+ if (!Ctor) return SILENT;
107
+
108
+ const context = new Ctor();
109
+ const bus = context.createGain();
110
+ bus.gain.value = 1;
111
+ bus.connect(context.destination);
112
+
113
+ let muted = false;
114
+ let priorGain = bus.gain.value;
115
+ let voiceSequence = 0;
116
+ const voiceLimit = Math.max(1, Math.floor(maxVoices));
117
+ const voices: Array<{
118
+ id: number;
119
+ oscillator: OscillatorNode;
120
+ gain: GainNode;
121
+ }> = [];
122
+
123
+ const releaseVoice = (voice: (typeof voices)[number]): void => {
124
+ const index = voices.indexOf(voice);
125
+ if (index >= 0) voices.splice(index, 1);
126
+ voice.oscillator.disconnect();
127
+ voice.gain.disconnect();
128
+ };
129
+
130
+ const stopVoice = (voice: (typeof voices)[number]): void => {
131
+ voice.oscillator.onended = null;
132
+ try {
133
+ voice.oscillator.stop();
134
+ } catch {
135
+ // It ended between the pool check and the stop call.
136
+ }
137
+ releaseVoice(voice);
138
+ };
139
+
140
+ const adapter: AudioAdapter = {
141
+ resume: () => {
142
+ if (context.state === 'suspended') void context.resume();
143
+ },
144
+ setMuted(next: boolean): void {
145
+ if (next === muted) return;
146
+ muted = next;
147
+ // Restore to whatever the bus held before muting, never a hardcoded 1 —
148
+ // so a pause taken while already user-muted resumes muted.
149
+ if (next) {
150
+ priorGain = bus.gain.value;
151
+ bus.gain.value = 0;
152
+ } else {
153
+ bus.gain.value = priorGain;
154
+ }
155
+ },
156
+ isMuted: () => muted,
157
+ graphSnapshot(): AudioGraphNode[] {
158
+ return [
159
+ {
160
+ id: 'destination',
161
+ type: 'AudioDestinationNode',
162
+ label: 'Output',
163
+ outputs: [],
164
+ state: context.state,
165
+ },
166
+ { id: 'sfx', type: 'GainNode', label: 'Game SFX', outputs: ['destination'] },
167
+ ...voices.map((voice) => ({
168
+ id: `voice-${voice.id}`,
169
+ type: 'OscillatorNode',
170
+ label: `One-shot voice ${voice.id} (${voices.length}/${voiceLimit})`,
171
+ outputs: ['sfx'],
172
+ state: 'started',
173
+ })),
174
+ ];
175
+ },
176
+ };
177
+
178
+ return {
179
+ tone(frequency, duration, volume, end = frequency): void {
180
+ // Autoplay policy starts every context suspended; the page has had user
181
+ // activation long before a shot is fired, so this is the cheap unlock.
182
+ if (context.state === 'suspended') void context.resume();
183
+ while (voices.length >= voiceLimit) stopVoice(voices[0]!);
184
+ const now = context.currentTime;
185
+ const oscillator = context.createOscillator();
186
+ const gain = context.createGain();
187
+ const voice = { id: ++voiceSequence, oscillator, gain };
188
+ voices.push(voice);
189
+ oscillator.onended = () => releaseVoice(voice);
190
+ oscillator.type = 'sawtooth';
191
+ oscillator.frequency.setValueAtTime(frequency, now);
192
+ oscillator.frequency.exponentialRampToValueAtTime(Math.max(20, end), now + duration);
193
+ gain.gain.setValueAtTime(volume, now);
194
+ gain.gain.exponentialRampToValueAtTime(0.0001, now + duration);
195
+ oscillator.connect(gain).connect(bus);
196
+ oscillator.start(now);
197
+ oscillator.stop(now + duration);
198
+ },
199
+ adapter,
200
+ dispose(): void {
201
+ for (const voice of [...voices]) stopVoice(voice);
202
+ bus.disconnect();
203
+ void context.close();
204
+ },
205
+ };
206
+ }
207
+
208
+ // --- The one voice, module-owned ---------------------------------------------
209
+ //
210
+ // Created on first use, kept for the page's lifetime: browsers cap live
211
+ // AudioContexts, an Edit→Play remount reuses the same graph, and the entry's
212
+ // `systems` export needs the adapter to exist when the host installs it —
213
+ // which is right after mount, long before the first gunshot.
214
+
215
+ let active: GameSfx | null = null;
216
+
217
+ /** The game's one voice. */
218
+ export function gameSfx(): GameSfx {
219
+ active ??= createGameSfx();
220
+ return active;
221
+ }
222
+
223
+ /** Play one tone through the game's voice — the call every mechanic makes. */
224
+ export const gameTone: PlayTone = (frequency, duration, volume, end) => {
225
+ gameSfx().tone(frequency, duration, volume, end);
226
+ };
227
+
228
+ /**
229
+ * The entry `systems` export's audio slot: a LAZY forwarding adapter over the
230
+ * voice (constructed on first actual call, so importing the entry in Edit
231
+ * mode builds no AudioContext), or the positive absence for an environment
232
+ * with no Web Audio at all (jsdom, a headless bot run) — decided without
233
+ * constructing anything, stated, never simulated.
234
+ */
235
+ export function sfxAudioSystem(): AudioAdapter | { present: false; evidence: string } {
236
+ if (typeof AudioContext === 'undefined') {
237
+ return {
238
+ present: false,
239
+ evidence:
240
+ 'no Web Audio in this environment — `typeof AudioContext === "undefined"` ' +
241
+ '(src/lib/audio/sfx.ts)',
242
+ };
243
+ }
244
+ const live = (): AudioAdapter => {
245
+ const adapter = gameSfx().adapter;
246
+ if (!adapter) throw new Error('sfx: the Web Audio voice failed to construct.');
247
+ return adapter;
248
+ };
249
+ return {
250
+ resume: () => live().resume?.(),
251
+ setMuted: (next) => live().setMuted(next),
252
+ isMuted: () => live().isMuted(),
253
+ graphSnapshot: () => live().graphSnapshot?.() ?? [],
254
+ };
255
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * The ASSET SEED — the procedural-asset family's serializable "what to build".
3
+ *
4
+ * Every parametric asset lib in this family (the humanoid, the walking
5
+ * castle, whatever you add next) exports the same PAIR: a declared params
6
+ * schema and the synchronous function that takes it (see `params.ts`'s
7
+ * `describeNumericParams`, which reads the tuning controls off that
8
+ * declaration). A seed is the JSON-able record of one call to that pair:
9
+ *
10
+ * { generator, variant?, params?, palette? }
11
+ *
12
+ * That is deliberately the smallest thing that can round-trip through a save
13
+ * file, a network spawn packet, a URL, or a character creator's state.
14
+ * Because generation is synchronous and loads no assets, a seed is enough to
15
+ * REBUILD the asset anywhere — no baked GLB has to travel with it.
16
+ *
17
+ * FAMILY-LEVEL ON PURPOSE, and it lives HERE rather than in any one lib
18
+ * because `lib/bake` is already where the family's cross-member contracts
19
+ * live: `params.ts` (the schema-pair parameterization both Builders derive
20
+ * their controls from) and the bake host itself. `bake` is a `requires` of
21
+ * both `humanoid` and `castle`, so a seed is reachable from either without
22
+ * one lib depending on the other.
23
+ *
24
+ * The shape knows NOTHING about humanoids: a walking castle seed is
25
+ * `{ generator: 'castle', variant: 'keep', params: { towers: 4 },
26
+ * palette: { stone: 0x8a8a92 } }` and fits it exactly. Each lib supplies its
27
+ * own thin instance — the pair of functions that turn a seed into a built
28
+ * asset and a built asset's inputs back into a seed (the humanoid's is
29
+ * `src/lib/humanoid/seed.ts`). There is deliberately no registry, no
30
+ * dispatcher and no "seed system": resolving `generator` to a builder is one
31
+ * `switch` in your game, written where your game knows which libs it has.
32
+ *
33
+ * REMOVAL LINE: nothing in any render or bake path reads a seed. Delete this
34
+ * file and each lib's `seed.ts` and every generator still builds from its
35
+ * params exactly as before; you lose serialization, not generation.
36
+ */
37
+
38
+ import { z } from 'zod';
39
+
40
+ export const AssetSeedSchema = z
41
+ .object({
42
+ generator: z
43
+ .string()
44
+ .min(1)
45
+ .describe(
46
+ 'Which parametric asset lib builds this — the lib id, e.g. "humanoid" or "castle". ' +
47
+ 'Your game maps it to a builder; nothing here resolves it.',
48
+ ),
49
+ variant: z
50
+ .string()
51
+ .min(1)
52
+ .optional()
53
+ .describe(
54
+ 'The generator’s own named starting point — a key of its character/preset index ' +
55
+ '(the humanoid’s CHARACTERS, the castle’s presets). Omitted = that lib’s default.',
56
+ ),
57
+ params: z
58
+ .record(z.string(), z.number())
59
+ .optional()
60
+ .describe(
61
+ 'Numeric tuning params, validated by the generator’s OWN params schema (the same ' +
62
+ 'declaration `describeNumericParams` reads its controls from). Merged OVER the ' +
63
+ 'variant’s own params — an explicit value always wins.',
64
+ ),
65
+ palette: z
66
+ .record(z.string(), z.number())
67
+ .optional()
68
+ .describe(
69
+ 'Material-slot colour overrides: slot name → 0xRRGGBB, merged over the variant’s ' +
70
+ 'palette. Slot names are the generator’s own vocabulary; an unknown slot is inert ' +
71
+ 'here and is reported by the generator if it validates its spec.',
72
+ ),
73
+ })
74
+ .strict();
75
+
76
+ /** One serializable "what to build" — see the module header. */
77
+ export type AssetSeed = z.infer<typeof AssetSeedSchema>;
78
+
79
+ /** Thrown by `parseAssetSeed`. */
80
+ export class AssetSeedError extends Error {
81
+ constructor(message: string) {
82
+ super(`asset seed: ${message}`);
83
+ this.name = 'AssetSeedError';
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Validate an untrusted seed (save file, network packet, URL fragment) and
89
+ * return it typed. Loud and named on failure — a malformed seed must never
90
+ * quietly become "the default character".
91
+ */
92
+ export function parseAssetSeed(value: unknown): AssetSeed {
93
+ const result = AssetSeedSchema.safeParse(value);
94
+ if (!result.success) {
95
+ throw new AssetSeedError(
96
+ result.error.issues
97
+ .slice(0, 6)
98
+ .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)
99
+ .join('; '),
100
+ );
101
+ }
102
+ return result.data;
103
+ }
104
+
105
+ /**
106
+ * Build a seed from a generator id plus optional parts, DROPPING empty ones —
107
+ * so a seed is stable to compare and cheap to store: `{ generator: 'humanoid' }`
108
+ * and `{ generator: 'humanoid', params: {}, palette: {} }` serialize the same.
109
+ */
110
+ export function assetSeed(
111
+ generator: string,
112
+ parts: {
113
+ variant?: string | undefined;
114
+ params?: Readonly<Record<string, number>> | undefined;
115
+ palette?: Readonly<Record<string, number>> | undefined;
116
+ } = {},
117
+ ): AssetSeed {
118
+ const params =
119
+ parts.params && Object.keys(parts.params).length > 0 ? { ...parts.params } : undefined;
120
+ const palette =
121
+ parts.palette && Object.keys(parts.palette).length > 0 ? { ...parts.palette } : undefined;
122
+ return {
123
+ generator,
124
+ ...(parts.variant ? { variant: parts.variant } : {}),
125
+ ...(params ? { params } : {}),
126
+ ...(palette ? { palette } : {}),
127
+ };
128
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The schema fragments every parametric-asset bake tool repeats.
3
+ *
4
+ * A bake tool's genuinely own facts are its name, its prose, its build closure,
5
+ * and its validation thresholds — not the shape of an output file record or the
6
+ * dozen counters `bakeObject3DSource` returns. Those were copied verbatim into
7
+ * each tool, so a new field meant editing every lib. Libs `.extend()` these with
8
+ * whatever they additionally report.
9
+ *
10
+ * Plain data with explicit inputs and outputs; no registry and no tool factory.
11
+ * `defineTool` stays in each lib's own file, where its summary, permission, and
12
+ * impl belong.
13
+ */
14
+
15
+ import { z } from 'zod';
16
+
17
+ /** One file written by a bake. */
18
+ export const BakeOutputFileSchema = z.object({
19
+ bytes: z.number(),
20
+ mediaType: z.string().optional(),
21
+ path: z.string(),
22
+ role: z.enum(['asset', 'provenance', 'other']).optional(),
23
+ });
24
+
25
+ /** What every Object3D bake reports. Extend for lib-specific counters. */
26
+ export const BakeResultSchema = z.object({
27
+ animatedNodeCount: z.number(),
28
+ boneCount: z.number(),
29
+ clips: z.array(z.string()),
30
+ dryRun: z.boolean(),
31
+ files: z.array(BakeOutputFileSchema),
32
+ meshCount: z.number(),
33
+ model: z.string(),
34
+ provenanceOperationId: z.string().optional(),
35
+ skinnedMeshCount: z.number(),
36
+ totalBytes: z.number(),
37
+ });
38
+
39
+ /** Stable lowercase asset name for the generated GLB. */
40
+ export const BakeAssetNameSchema = z
41
+ .string()
42
+ .regex(/^[a-z0-9][a-z0-9-_]{0,63}$/)
43
+ .describe('Stable lowercase asset name used for the generated GLB file.');
44
+
45
+ export const BakeDryRunSchema = z
46
+ .boolean()
47
+ .default(false)
48
+ .describe('Generate and validate the complete batch without writing project files.');
49
+
50
+ /**
51
+ * The `{ dryRun, name, params }` base every bake tool accepts. Pass the lib's
52
+ * own params schema already made partial and defaulted — that stays at the call
53
+ * site so `input.params` keeps the lib's exact type, which the build closure
54
+ * needs. This helper owns only the two fields that are identical everywhere.
55
+ */
56
+ export function bakeInputSchema<P extends z.ZodTypeAny>(
57
+ params: P,
58
+ options: { defaultName: string },
59
+ ) {
60
+ return z.object({
61
+ dryRun: BakeDryRunSchema,
62
+ name: BakeAssetNameSchema.default(options.defaultName),
63
+ params,
64
+ });
65
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * CLIP LAYERING — additive clips and per-bone masks, for any rigged asset.
3
+ *
4
+ * This is the family-level animation floor: a humanoid layers an expression or
5
+ * an aim pose over a walk, and a walking castle layers a drawbridge over its
6
+ * gait, by the same mechanism. It lives here in `lib/bake` — the
7
+ * procedural-asset family's shared home, required by `humanoid` and `castle`
8
+ * alike — precisely so the castle never has to import humanoid code to get it.
9
+ * Nothing in this file knows what a spine is.
10
+ *
11
+ * HELPERS, NOT A SYSTEM. Every function returns a real `THREE.AnimationClip`
12
+ * you then hand to a real `THREE.AnimationMixer` and drive with three's own
13
+ * API (`action.blendMode`, `.weight`, `.play()`). There is no layer manager,
14
+ * no rig-agnostic state machine, no registry — three already has the runtime
15
+ * (`AdditiveAnimationBlendMode` and one action per layer). What was missing was
16
+ * the two PREPARATION steps three makes you write by hand each time, and both
17
+ * are traps:
18
+ *
19
+ * - `AnimationUtils.makeClipAdditive` MUTATES the clip you pass it, so
20
+ * calling it on a clip that is also playing as a base layer silently turns
21
+ * that layer into deltas about a reference pose. {@link additiveClip}
22
+ * clones first.
23
+ * - masking means filtering `clip.tracks` by node name, and a typo'd bone
24
+ * name filters to nothing and animates nothing, silently.
25
+ * {@link maskClip} throws instead.
26
+ *
27
+ * TYPICAL USE — an upper-body additive layer over a full-body base:
28
+ *
29
+ * const base = mixer.clipAction(walk);
30
+ * const layer = mixer.clipAction(
31
+ * additiveClip(maskClip(aim, boneSubtreeNames(root, ['chest'], { animatedIn: aim }))),
32
+ * );
33
+ * layer.blendMode = THREE.AdditiveAnimationBlendMode;
34
+ * base.play();
35
+ * layer.setEffectiveWeight(0.8).play();
36
+ *
37
+ * REMOVAL LINE: delete this file. Nothing else in the family imports it — a
38
+ * game that does not layer clips loses nothing, and a game that does can write
39
+ * the four lines each helper wraps.
40
+ */
41
+
42
+ import * as THREE from 'three';
43
+
44
+ /** Every node name the clip animates, in first-appearance order. */
45
+ export function clipAnimatedNodes(clip: THREE.AnimationClip): string[] {
46
+ const seen = new Set<string>();
47
+ const out: string[] = [];
48
+ for (const track of clip.tracks) {
49
+ const { nodeName } = THREE.PropertyBinding.parseTrackName(track.name);
50
+ if (!nodeName || seen.has(nodeName)) continue;
51
+ seen.add(nodeName);
52
+ out.push(nodeName);
53
+ }
54
+ return out;
55
+ }
56
+
57
+ export interface AdditiveClipOptions {
58
+ /** Name for the returned clip (default: `${clip.name}_Additive`). */
59
+ name?: string;
60
+ /** Frame of `reference` to subtract — the pose the layer is a DELTA FROM.
61
+ * Default 0. */
62
+ referenceFrame?: number;
63
+ /** Clip the reference pose is sampled from (default: `clip` itself, i.e. the
64
+ * layer is a delta from its own first frame). Pass the BASE clip's rest
65
+ * frame when the layer was authored against a different neutral pose. */
66
+ reference?: THREE.AnimationClip;
67
+ /** Frames per second used to turn `referenceFrame` into a time. Default 30. */
68
+ fps?: number;
69
+ }
70
+
71
+ /**
72
+ * `THREE.AnimationUtils.makeClipAdditive`, on a CLONE.
73
+ *
74
+ * Three's own function converts in place and returns the same object, which is
75
+ * the sharp edge: the clip you passed is now deltas, and any action already
76
+ * playing it as a normal (base) layer is now playing a broken pose. This
77
+ * returns a new clip and leaves the input untouched, so the same source clip
78
+ * can be both a base layer and the source of an additive one.
79
+ *
80
+ * The returned clip is only meaningful on an action whose `blendMode` is
81
+ * `THREE.AdditiveAnimationBlendMode` — that is three's contract, not this
82
+ * helper's, and this helper deliberately does not create the action for you.
83
+ */
84
+ export function additiveClip(
85
+ clip: THREE.AnimationClip,
86
+ options: AdditiveClipOptions = {},
87
+ ): THREE.AnimationClip {
88
+ const additive = clip.clone();
89
+ additive.name = options.name ?? `${clip.name}_Additive`;
90
+ THREE.AnimationUtils.makeClipAdditive(
91
+ additive,
92
+ options.referenceFrame ?? 0,
93
+ options.reference ?? additive,
94
+ options.fps ?? 30,
95
+ );
96
+ return additive;
97
+ }
98
+
99
+ export interface MaskClipOptions {
100
+ /** Name for the returned clip (default: `${clip.name}_Masked`). */
101
+ name?: string;
102
+ /** Keep the tracks that do NOT target the named nodes instead — the
103
+ * complementary half of the same split. Default false. */
104
+ invert?: boolean;
105
+ }
106
+
107
+ /**
108
+ * A copy of `clip` carrying only the tracks that target the named nodes (or,
109
+ * with `invert`, only the tracks that do not).
110
+ *
111
+ * BOUNDARY SEMANTICS — the part that decides what a "split" actually means:
112
+ * a mask is a FLAT SET OF NODE NAMES, never a subtree. Naming a node puts THAT
113
+ * node on the mask's side and says nothing about its children, its parent, or
114
+ * its siblings. Use {@link boneSubtreeNames} to turn a split node into its
115
+ * subtree when that is what you want — and note what that does NOT include:
116
+ * a chain that hangs off an ANCESTOR of your split node is on the other side,
117
+ * even if it is anatomically "above" it. (Concretely for a humanoid rig: the
118
+ * clavicles hang off the chest vertebra, so an upper-body mask rooted at the
119
+ * ARM bones leaves clavicle motion on the TORSO side. That is usually right —
120
+ * see this lib's humanoid notes on the retargeter's clavicle pass-through —
121
+ * but it is a decision, so it is spelled out rather than implied.)
122
+ *
123
+ * Loud on a name the clip does not animate: a mask is written by hand against
124
+ * a rig, so a typo or a mask copied from a different skeleton is the expected
125
+ * failure, and silently filtering to nothing is the expected symptom.
126
+ */
127
+ export function maskClip(
128
+ clip: THREE.AnimationClip,
129
+ nodes: Iterable<string>,
130
+ options: MaskClipOptions = {},
131
+ ): THREE.AnimationClip {
132
+ const wanted = new Set(nodes);
133
+ if (wanted.size === 0) {
134
+ throw new Error(`clip-layering: maskClip('${clip.name}') was given no node names`);
135
+ }
136
+ const animated = new Set(clipAnimatedNodes(clip));
137
+ const unknown = [...wanted].filter((name) => !animated.has(name));
138
+ if (unknown.length > 0) {
139
+ throw new Error(
140
+ `clip-layering: maskClip('${clip.name}') names ${unknown.length} node(s) the clip does ` +
141
+ `not animate: ${unknown.slice(0, 12).join(', ')} (it animates: ` +
142
+ `${[...animated].slice(0, 12).join(', ')}${animated.size > 12 ? ', …' : ''})`,
143
+ );
144
+ }
145
+ const invert = options.invert ?? false;
146
+ const tracks = clip.tracks.filter((track) => {
147
+ const { nodeName } = THREE.PropertyBinding.parseTrackName(track.name);
148
+ return wanted.has(nodeName) !== invert;
149
+ });
150
+ if (tracks.length === 0) {
151
+ throw new Error(
152
+ `clip-layering: maskClip('${clip.name}') kept no tracks — the mask covers ` +
153
+ `${invert ? 'every' : 'no'} animated node`,
154
+ );
155
+ }
156
+ return new THREE.AnimationClip(
157
+ options.name ?? `${clip.name}_Masked`,
158
+ clip.duration,
159
+ tracks.map((track) => track.clone()),
160
+ clip.blendMode,
161
+ );
162
+ }
163
+
164
+ export interface BoneSubtreeOptions {
165
+ /** Keep only the names this clip actually animates. Without it the result is
166
+ * the full subtree, which {@link maskClip} will reject if the clip animates
167
+ * only part of it — so pass the clip you are about to mask. */
168
+ animatedIn?: THREE.AnimationClip;
169
+ }
170
+
171
+ /**
172
+ * Every node name at or under each named split node, found by traversing
173
+ * `root`. The ergonomic way to build a mask from a handful of split points
174
+ * ("everything from the chest up") instead of listing forty bones.
175
+ *
176
+ * Loud on a split node that is not in `root`: naming a bone the rig does not
177
+ * have is the same authoring mistake {@link maskClip} guards, one step earlier.
178
+ */
179
+ export function boneSubtreeNames(
180
+ root: THREE.Object3D,
181
+ splitNodes: Iterable<string>,
182
+ options: BoneSubtreeOptions = {},
183
+ ): string[] {
184
+ const requested = [...splitNodes];
185
+ if (requested.length === 0) {
186
+ throw new Error('clip-layering: boneSubtreeNames was given no split nodes');
187
+ }
188
+ const missing = requested.filter((name) => !root.getObjectByName(name));
189
+ if (missing.length > 0) {
190
+ throw new Error(
191
+ `clip-layering: boneSubtreeNames: '${root.name || 'root'}' has no node(s) ` +
192
+ `${missing.slice(0, 12).join(', ')}`,
193
+ );
194
+ }
195
+ const keep = options.animatedIn ? new Set(clipAnimatedNodes(options.animatedIn)) : null;
196
+ const out = new Set<string>();
197
+ for (const name of requested) {
198
+ root.getObjectByName(name)?.traverse((node) => {
199
+ if (node.name && (!keep || keep.has(node.name))) out.add(node.name);
200
+ });
201
+ }
202
+ return [...out];
203
+ }