@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.
- package/BUNDLED_NOTICES +11228 -0
- package/LICENSE +686 -0
- package/LICENSE-BLENDER +1409 -0
- package/LICENSE-MCP +21 -0
- package/NOTICE +21 -0
- package/catalog/entries/audio.json +14 -0
- package/catalog/entries/bake.json +36 -0
- package/catalog/entries/blender.json +17 -0
- package/catalog/entries/react-root.json +24 -0
- package/catalog/entries/reflections.json +29 -0
- package/catalog/entries/static-batch.json +25 -0
- package/catalog/project-source/LICENSE +37 -0
- package/catalog/project-source/src/contributions/bake.kind.ts +40 -0
- package/catalog/project-source/src/contributions/builder-document.tsx +65 -0
- package/catalog/project-source/src/contributions/builder-state.ts +27 -0
- package/catalog/project-source/src/contributions/builder-ui.tsx +61 -0
- package/catalog/project-source/src/contributions/module-source.ts +502 -0
- package/catalog/project-source/src/contributions/pages.finder.ts +61 -0
- package/catalog/project-source/src/lib/audio/sfx.ts +255 -0
- package/catalog/project-source/src/lib/bake/asset-seed.ts +128 -0
- package/catalog/project-source/src/lib/bake/bake-schema.ts +65 -0
- package/catalog/project-source/src/lib/bake/clip-layering.ts +203 -0
- package/catalog/project-source/src/lib/bake/gltf-bake.ts +657 -0
- package/catalog/project-source/src/lib/bake/mesh-slice.ts +157 -0
- package/catalog/project-source/src/lib/bake/node-image.ts +463 -0
- package/catalog/project-source/src/lib/bake/object3d-bake.ts +121 -0
- package/catalog/project-source/src/lib/bake/object3d-lifecycle.ts +15 -0
- package/catalog/project-source/src/lib/bake/object3d-source.ts +8 -0
- package/catalog/project-source/src/lib/bake/params.ts +75 -0
- package/catalog/project-source/src/lib/bake/rest-relative-animation.ts +217 -0
- package/catalog/project-source/src/lib/bake/use-model.ts +95 -0
- package/catalog/project-source/src/lib/react-root/index.ts +20 -0
- package/catalog/project-source/src/lib/react-root/react-root-adapter.tsx +57 -0
- package/catalog/project-source/src/lib/reflections/ReflectionProbe.tsx +201 -0
- package/catalog/project-source/src/lib/reflections/index.ts +19 -0
- package/catalog/project-source/src/lib/reflections/probe-controller.ts +75 -0
- package/catalog/project-source/src/lib/reflections/reflection-probe-registry.ts +402 -0
- package/catalog/project-source/src/lib/reflections/volume-reflection-material.ts +416 -0
- package/catalog/project-source/src/lib/static-batch/Frozen.tsx +91 -0
- package/catalog/project-source/src/lib/static-batch/freeze.ts +579 -0
- package/catalog/project-source/src/lib/static-batch/index.ts +44 -0
- package/catalog/project-source/src/lib/static-batch/mutation-watch.ts +149 -0
- package/catalog/project-source/src/lib/static-batch/shadow-cache.ts +171 -0
- package/catalog/project-source/src/tools/bake-module.tool.ts +139 -0
- package/catalog/project-source/src/tools/bake-preview.tool.ts +475 -0
- package/dist/.vite/manifest.json +8304 -0
- package/dist/assets/AssetBudgetPanel-J9--TZPU.js +23 -0
- package/dist/assets/AudioViewer-CR7333fe.js +1 -0
- package/dist/assets/BVHLoader-6bQIXhMX.js +1 -0
- package/dist/assets/BufferGeometryUtils-Nz37EVXf.js +1 -0
- package/dist/assets/CCDIKSolver-CD7vLpsK.js +1 -0
- package/dist/assets/CSS3DRenderer-CL7ABLVK.js +1 -0
- package/dist/assets/CanvasSceneViewport-Bpi6gVTC.js +1 -0
- package/dist/assets/ColladaLoader-aVOPIsCh.js +3 -0
- package/dist/assets/ColorInput-DQBNrW-K.js +1 -0
- package/dist/assets/ConvexGeometry-CAzXlPVG.js +1 -0
- package/dist/assets/ConvexHull-BINCESFp.js +1 -0
- package/dist/assets/CopyShader-BzTUYzf6.js +24 -0
- package/dist/assets/DecalGeometry-160KRdfg.js +1 -0
- package/dist/assets/EXRLoader-Cdans_oJ.js +1 -0
- package/dist/assets/EffectComposer-DQxfsXBZ.js +1 -0
- package/dist/assets/EntityModelDocument-Ccvw66N9.js +1 -0
- package/dist/assets/EnvironmentAssetDocument-Dg-Qq6O6.js +1 -0
- package/dist/assets/FBXLoader-B4MoUtAn.js +1 -0
- package/dist/assets/Fbo-Dz-Soul3.js +1 -0
- package/dist/assets/FontLoader-CvGoVI5a.js +2 -0
- package/dist/assets/GLTFExporter-HgrCle4L.js +1 -0
- package/dist/assets/GameplaySessionTimeline-B52W3FVZ.js +1 -0
- package/dist/assets/Gltf-UHVWKz65.js +2 -0
- package/dist/assets/HDRLoader-THU88oVD.js +5 -0
- package/dist/assets/ImageViewer-Tn7s_MnW.js +1 -0
- package/dist/assets/InspectorCanvasPreview-CEr_Kxna.js +1 -0
- package/dist/assets/InspectorObjectPreview-CVejvLRg.js +1 -0
- package/dist/assets/JsonAssetDocument-C7VGcLhu.js +3 -0
- package/dist/assets/LineSegments2-CsOpKSiM.js +370 -0
- package/dist/assets/MTLLoader-_Xzd4_0p.js +2 -0
- package/dist/assets/MarchingCubes-Bsp4wrzd.js +1 -0
- package/dist/assets/MeshBVH-BiDHDcu-.js +1 -0
- package/dist/assets/ModelAssetDocument-F5GACirk.js +1 -0
- package/dist/assets/NonThreeAuthoringBootstrap-C3woOMxX.js +1 -0
- package/dist/assets/OBJLoader-BhIC6Hwo.js +5 -0
- package/dist/assets/Object3DDocumentViewport-DB7T0NTl.js +2 -0
- package/dist/assets/Object3DPreview-DL8oi7Xs.js +2 -0
- package/dist/assets/OnlineAssetDetail-C6z9RvYK.js +2 -0
- package/dist/assets/OrbitControls-CM3bPray.js +1 -0
- package/dist/assets/OrbitControls-DLpayAaK.js +1 -0
- package/dist/assets/OrthographicCamera-bQozawrh.js +1 -0
- package/dist/assets/PLYLoader-DYQqs5Ik.js +2 -0
- package/dist/assets/PerspectiveCamera-CQ2lh01o.js +1 -0
- package/dist/assets/PlayBar-BR-Vg3Jb.js +2 -0
- package/dist/assets/RGBELoader-BgBcQv8j.js +1 -0
- package/dist/assets/RectAreaLightUniformsLib-CMMoWfll.js +1 -0
- package/dist/assets/RenderPass-DPrn-Uky.js +1 -0
- package/dist/assets/ResolutionPicker-C67vs1F3.js +1 -0
- package/dist/assets/RootSelectionOverlay-BZPlxmXU.js +1 -0
- package/dist/assets/RoundedBox-BDGBg6QZ.js +1 -0
- package/dist/assets/RoundedBoxGeometry-CyUuYPfW.js +1 -0
- package/dist/assets/STLLoader-Dyv3lsxY.js +1 -0
- package/dist/assets/SelectionBox-D_75KrNW.js +1 -0
- package/dist/assets/ShaderPass-QYRpPuFJ.js +1 -0
- package/dist/assets/ShadowEditor-DkImwu1Y.js +1 -0
- package/dist/assets/SimplifyModifier-C8ayvRzd.js +1 -0
- package/dist/assets/SkeletonUtils-Cps8GOC6.js +1 -0
- package/dist/assets/Sky-CQKCgYDs.js +154 -0
- package/dist/assets/SourceAssetViewer-2SWQoUut.js +12 -0
- package/dist/assets/StageHost-BN-IoTef.js +2 -0
- package/dist/assets/StoryPreviewMount-DjyxRCXu.js +1 -0
- package/dist/assets/TDSLoader-D_T8XJ81.js +1 -0
- package/dist/assets/TextGeometry-DOWAEUV0.js +1 -0
- package/dist/assets/ThreeBoardDocument-CVncZyIq.js +2 -0
- package/dist/assets/ThreeIsolationSceneContent-C8C8whSF.js +1 -0
- package/dist/assets/ToolObject3DPreview-BRoDWe4Q.js +1 -0
- package/dist/assets/TrackballControls-DfznuQTh.js +1 -0
- package/dist/assets/TransientHint-BB1fwrvK.js +1 -0
- package/dist/assets/UnrealBloomPass-CR-cS_K5.js +83 -0
- package/dist/assets/VideoViewer-C6kocgIU.js +1 -0
- package/dist/assets/_commonjsHelpers-D6-XlEtG.js +1 -0
- package/dist/assets/active-ingest-CT6jSGhr.js +3 -0
- package/dist/assets/adapter-surface-Y37Nzcyw.js +1 -0
- package/dist/assets/after-paint-CB4bz1-e.js +1 -0
- package/dist/assets/agx-base-srgb-BjWZJgrZ.lut +0 -0
- package/dist/assets/agx-look-medium-high-contrast-D5F_ob1L.lut +0 -0
- package/dist/assets/agx-look-punchy-dxsnycNs.lut +0 -0
- package/dist/assets/animation-clock-CnjZqfJp.js +1 -0
- package/dist/assets/asset-budget-asset.menu-Di3KiQCd.js +1 -0
- package/dist/assets/asset-budget.action-DCzzcuTh.js +1 -0
- package/dist/assets/asset-budget.document-BWU8wnVW.js +1 -0
- package/dist/assets/asset-budget.menu-BGZpT_31.js +1 -0
- package/dist/assets/asset-editor-persistence-BBaONOJt.js +1 -0
- package/dist/assets/asset-loaders-BOy5Ss8k.js +2 -0
- package/dist/assets/asset-parse-error-BHMwBRU3.js +3 -0
- package/dist/assets/assets-BuSoGjBX.js +1 -0
- package/dist/assets/audio-meter-CyiToeUW.js +1 -0
- package/dist/assets/audio-unlock.service-CfUgUQVy.js +1 -0
- package/dist/assets/audio.utility-C6K6jem8.js +1 -0
- package/dist/assets/authoring-CgcOFhGS.js +1 -0
- package/dist/assets/autoplay.service-BZBGNSvt.js +1 -0
- package/dist/assets/axe-LkjAB6Lv.js +30 -0
- package/dist/assets/babylon-authoring-adapter-CL02gWDn.js +1 -0
- package/dist/assets/binding-Bmxqznjk.js +1 -0
- package/dist/assets/binding-identity-DcTpbvyg.js +1 -0
- package/dist/assets/binding-resolver-Dsh-6Vor.js +2 -0
- package/dist/assets/blender-emscripten-engine-9ZIRYNhe.js +2 -0
- package/dist/assets/blender-node-editor.document-iIDkB9sI.js +1 -0
- package/dist/assets/blender-properties-tab-C5CyPydi.js +3 -0
- package/dist/assets/blender-runtime-host-BpBwGv7r.js +4 -0
- package/dist/assets/blender-runtime-skin-DyQ9B6CR.js +7140 -0
- package/dist/assets/blender-runtime.document-lIYhhPtv.js +8 -0
- package/dist/assets/blender-timeline.document-77fx96N7.js +1 -0
- package/dist/assets/blender-uv-editor.document-fsT7B4gV.js +1 -0
- package/dist/assets/blender-version.status-o6dBm3n6.js +1 -0
- package/dist/assets/blender-wali-engine-wTOcrOMC.js +2 -0
- package/dist/assets/blender.command-BtJeWk-A.js +1 -0
- package/dist/assets/blender.keymap-GAQgeklK.js +1 -0
- package/dist/assets/blender.status-ujwGU6dU.js +1 -0
- package/dist/assets/blender.style-Dcem5f_T.js +1 -0
- package/dist/assets/board-guides-DziKSTss.js +1 -0
- package/dist/assets/body-marks-h_xDxiDE.js +1 -0
- package/dist/assets/bridge.command-o5gDNEwa.js +3 -0
- package/dist/assets/browserAll-DeWblVez.js +1 -0
- package/dist/assets/build-profiles.document-kW8iw8Xj.js +2 -0
- package/dist/assets/build-progress.status-BNRLytg2.js +1 -0
- package/dist/assets/build-session-C_sg3CEn.js +9 -0
- package/dist/assets/build.action-lYjTLb7K.js +1 -0
- package/dist/assets/build.command-DIGgUPU_.js +1 -0
- package/dist/assets/build.header-CKajx5U3.js +1 -0
- package/dist/assets/build.menu-BdU0QXny.js +1 -0
- package/dist/assets/build.service-CbBAyeu3.js +1 -0
- package/dist/assets/bus-mixer-CGfWDP3C.js +1 -0
- package/dist/assets/camera-KEsKvOL7.js +1 -0
- package/dist/assets/camera-runtime.inspector-B7unX4g1.js +1 -0
- package/dist/assets/canvas-entry-runtime-SfBxaR9M.js +2 -0
- package/dist/assets/capability-coverage-Czas4C18.js +7 -0
- package/dist/assets/chrome-trace-YZHMz60-.js +1 -0
- package/dist/assets/client-DNXj_opT.js +25 -0
- package/dist/assets/clip-planes-CnAI6DZn.js +1 -0
- package/dist/assets/collaboration-presence-DLoZ7EA3.js +1 -0
- package/dist/assets/collider-Bw0mXlsW.js +1 -0
- package/dist/assets/collider-dimensions-9xoFADXN.js +1 -0
- package/dist/assets/collision-system-DpNUJRJ3.js +1 -0
- package/dist/assets/command-results-CUQD49AB.js +1 -0
- package/dist/assets/component-board-registry-DrIa2csL.js +1 -0
- package/dist/assets/component-board.service-DCwcUssB.js +2 -0
- package/dist/assets/component-board.service-DidCyM4O.js +2 -0
- package/dist/assets/component-verbs.command-7xzfjGMZ.js +1 -0
- package/dist/assets/component-verbs.service-Bv9jId3q.js +1 -0
- package/dist/assets/config-CEZk921y.js +6 -0
- package/dist/assets/configurations-DTBMdaTL.js +1 -0
- package/dist/assets/connection.status-BifnQdOs.js +1 -0
- package/dist/assets/console-bridge-CHcb-xk5.js +1 -0
- package/dist/assets/constraint-De8f1Uiq.js +1 -0
- package/dist/assets/constraints.inspector-B9U9Yj-u.js +1 -0
- package/dist/assets/countdown-timer-CUm74dom.js +1 -0
- package/dist/assets/coverage.service-VTX5Mcsx.js +3 -0
- package/dist/assets/crash-null-boundary-v3a0uEgw.js +1 -0
- package/dist/assets/create-runtime-CVCc1BDx.js +1 -0
- package/dist/assets/curve-7Q79VgU4.js +1 -0
- package/dist/assets/data-asset-4hjS642k.js +5 -0
- package/dist/assets/data-check-core-CQEjuFyt.js +1 -0
- package/dist/assets/data-ref-CQI28C0D.js +1 -0
- package/dist/assets/debug-bridge-CCohG-d-.js +1 -0
- package/dist/assets/debug-registry-Dgvitx8M.js +1 -0
- package/dist/assets/defaults-DKiBJCPN.js +1 -0
- package/dist/assets/deferred-commands-CEMmvL47.js +1 -0
- package/dist/assets/deferred-ingest-play-DCJi_Pgu.js +2 -0
- package/dist/assets/design-time-layers-wYgOTgni.js +1 -0
- package/dist/assets/design-time-mount-registry-DUpXCg1U.js +1 -0
- package/dist/assets/design-time-mount.service-BzY21e1F.js +2 -0
- package/dist/assets/design-time-react-mount-DM9WLrF2.js +1 -0
- package/dist/assets/dev-build-gDYrq68M.js +1 -0
- package/dist/assets/directional-shadow-fit-BVkOKAv2.js +1 -0
- package/dist/assets/document-preview-three-Kbg2GCLm.js +1 -0
- package/dist/assets/dom-authoring-adapter-CY8C7f4T.js +1 -0
- package/dist/assets/draco3d-BBUTcNkz.js +1 -0
- package/dist/assets/draco_decoder-DsQ12WqX.wasm +0 -0
- package/dist/assets/draco_encoder-2Tcju8Ns.wasm +0 -0
- package/dist/assets/edit-mode-audio.service-Bzetwd5B.js +1 -0
- package/dist/assets/edit-mode-authoring-B47TfLqu.js +1 -0
- package/dist/assets/edit-mode-networking.service-YCX6RRb_.js +1 -0
- package/dist/assets/editor-api-BoJIcyZG.js +1 -0
- package/dist/assets/editor-port-C_FeBdeV.js +1 -0
- package/dist/assets/editor-presentation-activity-C7SNSmTd.js +1 -0
- package/dist/assets/entry-adjudication-Cq8Yeb74.js +1 -0
- package/dist/assets/environment-capture-7himRh2L.js +1 -0
- package/dist/assets/esbuild-BHljloGq.wasm +0 -0
- package/dist/assets/events-156d8d12.esm-ErOhDXXB.js +36 -0
- package/dist/assets/extend-B-eOccUm.js +36 -0
- package/dist/assets/extends-CF3RwP-h.js +1 -0
- package/dist/assets/eyedropper-session-bjPXnfeX.js +1 -0
- package/dist/assets/fflate.module-DPuTF8aG.js +6 -0
- package/dist/assets/filmic-srgb-Ct35FIH6.lut +0 -0
- package/dist/assets/first-party-audio-system-DxnGJOER.js +1 -0
- package/dist/assets/first-party-navigation-system-CL5Bquub.js +1 -0
- package/dist/assets/fork-menu-BoVyw2Wu.js +1 -0
- package/dist/assets/frame-debugger-store-D1Mf_5up.js +1 -0
- package/dist/assets/frame-delta-D2nsw_Ht.js +1 -0
- package/dist/assets/frame-pacing-D5acoOzO.js +1 -0
- package/dist/assets/frame-selector-cache-cCeUbcjG.js +1 -0
- package/dist/assets/game-DHOZVb-7.js +1 -0
- package/dist/assets/game-contract-seams-a5YXejOu.js +1 -0
- package/dist/assets/game-css-scope-transform-Eng4wS8E.js +33 -0
- package/dist/assets/game-document.service-DbRfx2V0.js +1 -0
- package/dist/assets/game-eval.command-D-7Dxbj_.js +2 -0
- package/dist/assets/game-input-seams-CIQdetRw.js +1 -0
- package/dist/assets/game-loop-CZvXlY00.js +1 -0
- package/dist/assets/game-module-access-B2mFxv-i.js +1 -0
- package/dist/assets/game.layout-CBASrvQu.js +1 -0
- package/dist/assets/gameplay-export-BoKXm51x.js +1 -0
- package/dist/assets/gameplay-replay-e5umMlXv.js +1 -0
- package/dist/assets/gameplay-rng-trap-CTNhm-UW.js +3 -0
- package/dist/assets/gameplay.command-DxcVYX6F.js +1 -0
- package/dist/assets/generation-DhwCUHPf.css +1 -0
- package/dist/assets/generation-jobs-BQrXbGp_.js +1 -0
- package/dist/assets/generation.service-CDIgObuw.js +1 -0
- package/dist/assets/generations-DzUogZsM.js +1 -0
- package/dist/assets/generations.status-CgOUBCum.js +1 -0
- package/dist/assets/hierarchy-marks-BLPfSIym.js +1 -0
- package/dist/assets/host-pointer-DbGSCjE9.js +1 -0
- package/dist/assets/hosted-asset-materialization-CiIvWkGU.js +2 -0
- package/dist/assets/ibl-override-material-BlmCxFKq.js +6 -0
- package/dist/assets/index-96FBF1Oj.js +1 -0
- package/dist/assets/index-BAWkB0dv.js +1 -0
- package/dist/assets/index-BDnS2b6S.js +1 -0
- package/dist/assets/index-BHp07vN0.js +2 -0
- package/dist/assets/index-BMxv2MNV.js +1 -0
- package/dist/assets/index-BP6wv2A0.js +5 -0
- package/dist/assets/index-BcCBqgM_.js +952 -0
- package/dist/assets/index-Bge9JUr6.js +1 -0
- package/dist/assets/index-BjTCPEQ7.js +134 -0
- package/dist/assets/index-BncK9THk.js +1 -0
- package/dist/assets/index-CJbYy-CF.js +3 -0
- package/dist/assets/index-CVCb_ImQ.js +1 -0
- package/dist/assets/index-CZd9o7Lu.js +1 -0
- package/dist/assets/index-CanA16PU.js +2 -0
- package/dist/assets/index-CinJrH5C.js +9 -0
- package/dist/assets/index-CtzuWnCS.js +1 -0
- package/dist/assets/index-D2fNXpHa.css +1 -0
- package/dist/assets/index-DUpHH6JR.js +3120 -0
- package/dist/assets/index-DUqP1RMl.js +1 -0
- package/dist/assets/index-D_NuPfjr.js +9 -0
- package/dist/assets/index-Da9JhEvW.js +25 -0
- package/dist/assets/index-DgapqSPi.js +7 -0
- package/dist/assets/index-FUuS4qwW.js +562 -0
- package/dist/assets/index-GIL7oGEO.js +4894 -0
- package/dist/assets/index-IEjydI9d.js +1 -0
- package/dist/assets/index-OrYXPk3Z.js +487 -0
- package/dist/assets/index-V1R-e5Bd.js +1 -0
- package/dist/assets/index-bQE2NA0D.js +1 -0
- package/dist/assets/index-gHZae-lw.js +13 -0
- package/dist/assets/index-mjWQmGhM.js +1 -0
- package/dist/assets/index-nmcBqr7Y.js +1 -0
- package/dist/assets/inference-diagnostics-Dhmtfbq_.js +1 -0
- package/dist/assets/ingest-BbYMC2vQ.js +1 -0
- package/dist/assets/ingest-boot-viewport-D5rI_Kk_.js +1 -0
- package/dist/assets/ingest-siblings-Bop2kqVl.js +1 -0
- package/dist/assets/ingest-source-persistence-C_6Hiyra.js +1 -0
- package/dist/assets/ingest.service-BTDnQfM1.js +1 -0
- package/dist/assets/input-manager-DH_hGW6d.js +1 -0
- package/dist/assets/input-router-BNQvtIqw.js +1 -0
- package/dist/assets/inspect-BZfi3mmo.js +1 -0
- package/dist/assets/inspection-CObLhnrs.js +1 -0
- package/dist/assets/instance-fork-actions-D3sRzS3K.js +1 -0
- package/dist/assets/instances.command-D6UkZNO8.js +1 -0
- package/dist/assets/instruments-CKR02Y8I.js +1 -0
- package/dist/assets/json-history-resource-BbxllWfV.js +1 -0
- package/dist/assets/jsx-runtime-DPjLkJKQ.js +9 -0
- package/dist/assets/light-D-_wsKTq.js +1 -0
- package/dist/assets/light-camera-factory-CWbbe9gI.js +1 -0
- package/dist/assets/lil-gui.module.min-BF55BEwA.js +10 -0
- package/dist/assets/live-behaviors-Bxq49Maz.js +1 -0
- package/dist/assets/live-gesture-lock-DJbrjOqf.js +1 -0
- package/dist/assets/loader-CaF_I7Yt.js +1 -0
- package/dist/assets/logger-Dqis-7W1.js +1 -0
- package/dist/assets/loop-gate-report-N52EWFGD.js +1 -0
- package/dist/assets/matcap-texture-CVfalpWT.js +1 -0
- package/dist/assets/material-CpAdjDxn.js +1 -0
- package/dist/assets/material-factory-Bz6h__6g.js +1 -0
- package/dist/assets/mesh-B3WPtNKO.js +1 -0
- package/dist/assets/mesh-shadow-CZnXrw_l.js +1 -0
- package/dist/assets/mikktspace.module-DO88SLib.js +1 -0
- package/dist/assets/model-asset-sections-CFvvihfx.css +1 -0
- package/dist/assets/model-asset-sections.service-CHhFS3ZX.js +1 -0
- package/dist/assets/model.layout-BJUEQYUI.js +1 -0
- package/dist/assets/models.finder-G2jQgIRu.js +1 -0
- package/dist/assets/module-mode-DVBLT9d-.js +2 -0
- package/dist/assets/mount-canvas-ingest-root-DDuAWf_C.js +2 -0
- package/dist/assets/mount-dom-ingest-root-D_EiBgpn.js +2 -0
- package/dist/assets/mount-game-6t9cKNo4.js +1 -0
- package/dist/assets/mount-ingest-root-glv2SSWf.js +2 -0
- package/dist/assets/mount-manifest-CGVxhmAw.js +1 -0
- package/dist/assets/mount-readiness-Ds0HvvLH.js +4 -0
- package/dist/assets/mount-three-ingest-root-hrUt9VVU.js +1 -0
- package/dist/assets/mounted-authoring-Dmg5xmhP.js +1 -0
- package/dist/assets/mounted-story-viewport-source-DjP6RA9U.js +1 -0
- package/dist/assets/native-debug-module-CWicoSGD.js +1 -0
- package/dist/assets/native-entry-surface-BE8LJNdu.js +1 -0
- package/dist/assets/navigation-CIiCx-SM.js +1 -0
- package/dist/assets/navmesh-workflow-store-Cmnm57TB.js +1 -0
- package/dist/assets/navmesh.menu-CAKiH8PW.js +1 -0
- package/dist/assets/navmesh.service-jgDWlgj1.js +1 -0
- package/dist/assets/network.utility-CEu5nHf7.js +1 -0
- package/dist/assets/object-marks-DwvIEBOK.js +1 -0
- package/dist/assets/object3d-authoring-subject-CH5sI2oP.js +1 -0
- package/dist/assets/output-DK8waum9.js +195 -0
- package/dist/assets/particles-Y626p22p.js +1 -0
- package/dist/assets/particles-factory-DnLOHXT8.js +1 -0
- package/dist/assets/pasteboard-materialize-BqSS4QzV.js +20 -0
- package/dist/assets/pasteboard.action-DU3UHtJG.js +2 -0
- package/dist/assets/performance-profiler-D_Jey87L.js +1 -0
- package/dist/assets/physics-registry-B2Jkp8e6.js +1 -0
- package/dist/assets/physics-registry-CUB9cT9p.js +1 -0
- package/dist/assets/pixi-authoring-adapter-CjibysC3.js +1 -0
- package/dist/assets/pixi-live-write-target-DuWydlWb.js +1 -0
- package/dist/assets/pixi-primitive-DlWbUPN9.js +1 -0
- package/dist/assets/pixi-react-root-factory-DYsznYRQ.js +1 -0
- package/dist/assets/pixi-story-model-DNkfnWUV.js +1 -0
- package/dist/assets/pixi-transform-channels-VjdohT11.js +1 -0
- package/dist/assets/play-mode-BFU2PCkG.js +22 -0
- package/dist/assets/play.command-BpqqLqkq.js +2 -0
- package/dist/assets/playtest-BXIL1JEF.js +1 -0
- package/dist/assets/pose-guard-6Osb2cFu.js +1 -0
- package/dist/assets/presentation-BPP5pXeQ.js +1 -0
- package/dist/assets/product-DFhyARJj.js +1 -0
- package/dist/assets/profiler.action-CaXJDp3t.js +1 -0
- package/dist/assets/profiler.menu-BIMF6Bi4.js +1 -0
- package/dist/assets/profiler.utility-BExw9wBO.js +1 -0
- package/dist/assets/project-authoring-session-Bnt6icLr.js +2 -0
- package/dist/assets/project-provenance-BoP3nrle.js +1 -0
- package/dist/assets/prompt-labels-DSMdM2_B.js +1 -0
- package/dist/assets/properties-bone-constraints.inspector-ByT6p7S-.js +1 -0
- package/dist/assets/properties-bone.inspector-z4qJwKO5.js +1 -0
- package/dist/assets/properties-collection.inspector-D0_3ijWU.js +1 -0
- package/dist/assets/properties-constraints.inspector-CESzjuls.js +1 -0
- package/dist/assets/properties-data.inspector-hG8Wgyzb.js +1 -0
- package/dist/assets/properties-material.inspector-CzY0JCQ6.js +1 -0
- package/dist/assets/properties-modifiers.inspector-3dDhwf7g.js +1 -0
- package/dist/assets/properties-object.inspector-CiarfxkT.js +1 -0
- package/dist/assets/properties-output.inspector-DKJxmKSD.js +1 -0
- package/dist/assets/properties-particles.inspector-CCEdYWGm.js +1 -0
- package/dist/assets/properties-physics.inspector-B2c0KUyA.js +1 -0
- package/dist/assets/properties-render.inspector-Bcm0HLRW.js +1 -0
- package/dist/assets/properties-scene.inspector-PIM_eTb_.js +1 -0
- package/dist/assets/properties-texture.inspector-CgFlnyr8.js +1 -0
- package/dist/assets/properties-view-layer.inspector-DGjF_Aqo.js +1 -0
- package/dist/assets/properties-world.inspector-CrMvaRvB.js +1 -0
- package/dist/assets/r3f-design-session-D-4yyDO9.js +2 -0
- package/dist/assets/r3f-physics-binding-BBo8oma9.js +1 -0
- package/dist/assets/r3f-root-factory-z9llD1OU.js +1 -0
- package/dist/assets/r3f-source-authoring-adapter-w6Bc60K-.js +13 -0
- package/dist/assets/rapier-physics-adapter-CaZqWLu0.js +1 -0
- package/dist/assets/rapier-physics-bridge-CMoeVo3Y.js +1 -0
- package/dist/assets/react-18-By2b4xR9.js +1 -0
- package/dist/assets/react-inspector.service-B_neRnSK.js +1 -0
- package/dist/assets/react-root-CEz5NTck.js +1 -0
- package/dist/assets/react-story-board-BDDwiE2H.js +1 -0
- package/dist/assets/react-three-fiber.esm-CycrbDlA.js +1 -0
- package/dist/assets/react-three-rapier.esm-CEfKpvxT.js +1 -0
- package/dist/assets/react-world-authoring-adapter-DmrwM3py.js +1 -0
- package/dist/assets/realm-services-CobQsq_X.js +1 -0
- package/dist/assets/rebind-controller-Dtq19Vb3.js +1 -0
- package/dist/assets/recast-navigation.wasm-compat-Dsoa_MD-.js +1 -0
- package/dist/assets/reflection-probe-Don-M3Fj.js +1 -0
- package/dist/assets/reflection-probe-capture.inspector-CmFUoJCx.js +1 -0
- package/dist/assets/register-render-vitals-BiZk29b2.js +1 -0
- package/dist/assets/registry-02YZjMNp.js +1 -0
- package/dist/assets/relative-path-guard-GiM7Lsz8.js +1 -0
- package/dist/assets/render-audio-control-vMRlePWb.js +1 -0
- package/dist/assets/render-batch-system-0vq7p0VC.js +1 -0
- package/dist/assets/render-census-BrQX_CXv.js +1 -0
- package/dist/assets/render-control-Df3yTiyr.js +1 -0
- package/dist/assets/render-env-D2IV2x5k.js +1 -0
- package/dist/assets/render-features-CPQ_e568.js +1 -0
- package/dist/assets/render-seed-DF4JHy7P.js +1 -0
- package/dist/assets/render-settings-Bw4W9SYF.js +1 -0
- package/dist/assets/render-vitals-BZ5HtvMi.js +1 -0
- package/dist/assets/renderer-config-BqG4O8i9.js +1 -0
- package/dist/assets/resolve-three-SZE_WWUM.js +702 -0
- package/dist/assets/root-seam-contract-Z0VWX3Bk.js +1 -0
- package/dist/assets/rrweb-Cd2ifIRP.js +142 -0
- package/dist/assets/run-ticks-settled-C4ksViyA.js +1 -0
- package/dist/assets/runtime-inspection-l2iFQSsg.js +1 -0
- package/dist/assets/scene-capture-BQKzU0NT.js +1 -0
- package/dist/assets/scene-capture-CGYF-Viw.js +1 -0
- package/dist/assets/scene-document.service-qkDjUrlP.js +2 -0
- package/dist/assets/scene-framing-Cat0GtyJ.js +1 -0
- package/dist/assets/scene-index-B6BZOHMk.js +1 -0
- package/dist/assets/scene-query-C7_N-TpI.js +1 -0
- package/dist/assets/schema-kl9-2B_J.js +1 -0
- package/dist/assets/sculpt.layout-zJF55yCR.js +1 -0
- package/dist/assets/seeded-random-i3mtgBKZ.js +1 -0
- package/dist/assets/session-CZ5JPg-z.js +4877 -0
- package/dist/assets/setup-audio-S8GQF91f.js +1 -0
- package/dist/assets/setup-particles-GCXlnkj_.js +1 -0
- package/dist/assets/setup-physics-BeZ7-LKD.js +1 -0
- package/dist/assets/setup-renderer-DVXaSGin.js +1587 -0
- package/dist/assets/shading.layout-DULYZV6M.js +1 -0
- package/dist/assets/sim-clock-CLflx7kg.js +1 -0
- package/dist/assets/sky-precompute-worker-ChN7J87v.js +1 -0
- package/dist/assets/soft-particle-depth-DGvfQDi1.js +1 -0
- package/dist/assets/source-object3d-authoring-adapter-B-L6Ha6f.js +1 -0
- package/dist/assets/source-persistence-backend-C-aR-B_Y.js +1 -0
- package/dist/assets/spark-renderer-lifecycle-ynWESJcv.js +1 -0
- package/dist/assets/spark.module-4pXQoz5d.js +12120 -0
- package/dist/assets/stage-invalidation-DBg3C3Ta.js +1 -0
- package/dist/assets/stage-keyboard-n-5kKH-m.js +1 -0
- package/dist/assets/stage-overlay-set-B9zp2sLB.js +1 -0
- package/dist/assets/stage-presence-markers-DiGI6A45.js +1 -0
- package/dist/assets/standard-viewport-dressing-CzjAe_0A.js +7 -0
- package/dist/assets/state-bridge-DLP1jLRW.js +1 -0
- package/dist/assets/state-watch.action-BOvQR2qt.js +1 -0
- package/dist/assets/state-watch.menu-CNLvDeeY.js +1 -0
- package/dist/assets/state-watch.utility-Bg1tTTQU.js +1 -0
- package/dist/assets/static-batch-advisor-B13QEH7d.js +1 -0
- package/dist/assets/stats.module-BL02l9NC.js +1 -0
- package/dist/assets/story-arg-descriptors-Ek86ExX7.js +1 -0
- package/dist/assets/story-capture-_gC8dXV-.js +1 -0
- package/dist/assets/story-documents--TDLaPeL.js +3 -0
- package/dist/assets/story-documents.service-BiS_YbNQ.js +1 -0
- package/dist/assets/story-documents.service-CxOPYJ2j.js +1 -0
- package/dist/assets/story-media-presence-BHzk2IV5.js +1 -0
- package/dist/assets/story-mount-turn-DFRTj5hi.js +1 -0
- package/dist/assets/story-pixi-preview-BUrOJZXS.js +1 -0
- package/dist/assets/story-presentation-j2AVN-mK.js +1 -0
- package/dist/assets/story-three-preview-BHEDZzcl.js +2 -0
- package/dist/assets/structural-ids-Dc-7rEwi.js +1 -0
- package/dist/assets/structural-signature-0w-i_ats.js +1 -0
- package/dist/assets/surface-content-Dg9Kkazf.js +1 -0
- package/dist/assets/surface-state-DaxyruCj.js +3 -0
- package/dist/assets/system-adapters-rIC8FSGP.js +1 -0
- package/dist/assets/system-runner-DkOjxEBt.js +1 -0
- package/dist/assets/system-slot-E2mEdiih.js +1 -0
- package/dist/assets/team-playtest.service-DqOinFVA.js +1 -0
- package/dist/assets/texture.layout-DASpHVht.js +1 -0
- package/dist/assets/three-CDSueJyJ.js +1 -0
- package/dist/assets/three-authoring-adapter-CmSQ3Vui.js +1 -0
- package/dist/assets/three-authoring.service-iuHLwtf1.js +2 -0
- package/dist/assets/three-ingest-runtime-QzDYk6tU.js +1 -0
- package/dist/assets/three-projection-core-BmKMZ-nf.js +1 -0
- package/dist/assets/three-viewport-presentation-QBQpSdMh.js +1 -0
- package/dist/assets/three.module-D396a9Mn.js +3840 -0
- package/dist/assets/three.quarks.esm-B1C61jGo.js +1039 -0
- package/dist/assets/tools-B_NJsk05.js +1 -0
- package/dist/assets/transform-writer-BhBBTx33.js +1 -0
- package/dist/assets/transport.header-B-6HQlU2.js +1 -0
- package/dist/assets/trigger-volume-BNK2XzPL.js +1 -0
- package/dist/assets/tuples-CIQ4Bn1U.js +1 -0
- package/dist/assets/tween.module-DciWpAG6.js +1 -0
- package/dist/assets/ui-board-document-Bwtt--xp.js +2 -0
- package/dist/assets/unexported-game-trap-Dm1JYKHy.js +2 -0
- package/dist/assets/unmanaged-root-detector-B8CpbkSN.js +2 -0
- package/dist/assets/upstream-pin-BdgRH6ID.js +1 -0
- package/dist/assets/use-data-Dzq-MytE.js +1 -0
- package/dist/assets/use-live-actor-state-DErbWQWF.js +1 -0
- package/dist/assets/use-selection-DbR73-xd.js +1 -0
- package/dist/assets/user-data-BB2Of6Ht.js +1 -0
- package/dist/assets/utility-view-state-BHypxA33.js +1 -0
- package/dist/assets/uv-editing.layout-BEKHxmHw.js +1 -0
- package/dist/assets/vgai-shared-fontawesome-CU65D4Ij.js +1 -0
- package/dist/assets/vgai-shared-jsx-dev-runtime-DFDKL7fx.js +1 -0
- package/dist/assets/vgai-shared-jsx-runtime-DIqBpTut.js +1 -0
- package/dist/assets/vgai-shared-react-BT7rMc2H.js +1 -0
- package/dist/assets/vgai-shared-react-dom-DFajMqMT.js +1 -0
- package/dist/assets/vgai-shared-react-dom-client-S0ozfl6_.js +1 -0
- package/dist/assets/vgai-shared-three-Bc5PvpLM.js +1 -0
- package/dist/assets/viewport-pick-context-DkawXbEi.js +1 -0
- package/dist/assets/viewport-root-presentation-CWsE56K6.js +1 -0
- package/dist/assets/viewport-shading-BuA88e_A.js +1 -0
- package/dist/assets/viewport-shading-boundary-B_-_gABg.js +82 -0
- package/dist/assets/viewport-surface-status-B3om4Kcf.js +1 -0
- package/dist/assets/vision_bundle-DX0dWqEa.js +15 -0
- package/dist/assets/voxel-surface-DtcsSWRL.js +1 -0
- package/dist/assets/wav-encode-D31zWF6O.js +1 -0
- package/dist/assets/webgl-frame-capture-FlF9zQmW.js +1 -0
- package/dist/assets/webgl-gpu-timer-D3YX7RaD.js +1 -0
- package/dist/assets/webworkerAll-CM2o_dnz.js +1 -0
- package/dist/assets/worker-UrMcrc5_.js +2 -0
- package/dist/assets/world-documents-147tiFZe.js +1 -0
- package/dist/assets/world-root-stage-binding-vwTrtBz6.js +1 -0
- package/dist/assets/world-state-BWG-IcOd.js +1 -0
- package/dist/assets/writer-B-KovzkA.js +5 -0
- package/dist/assets/xstate-animation-binding-Brd0NST6.js +1 -0
- package/dist/assets/xstate-animation-meta-Q3u9zh_m.js +1 -0
- package/dist/assets/xstate-behavior.action-B8UluFBK.js +1 -0
- package/dist/assets/xstate-behavior.document-CKAsE45I.js +1 -0
- package/dist/assets/xstate-behavior.inspector-vJJyuifc.js +1 -0
- package/dist/assets/xstate-behavior.menu-BXbPICIh.js +1 -0
- package/dist/assets/xstate-inspection-BsZv8LS9.js +1 -0
- package/dist/vgai-shared-react.json +10 -0
- package/dist/vgai-shared-three.json +3 -0
- package/dist-node/cli.js +9320 -0
- package/dist-node/create.js +3239 -0
- package/package.json +91 -0
- package/presets.mjs +2 -0
- package/src/contributions.d.ts +4 -0
- package/src/index.ts +38 -0
- package/starter/cube.blend +0 -0
- package/starter/cube.py +81 -0
- package/template/.agents/references/project-manual.md +341 -0
- package/template/.agents/skills/editor/SKILL.md +53 -0
- package/template/.agents/skills/editor/agents/openai.yaml +4 -0
- package/template/.agents/skills/editor/references/editor-control.md +363 -0
- package/template/.agents/skills/vgai-3d-models/SKILL.md +64 -0
- package/template/.agents/skills/vgai-ingest-existing-game/SKILL.md +112 -0
- package/template/.agents/skills/vgai-threejs-authoring/SKILL.md +347 -0
- package/template/.agents/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
- package/template/.agents/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
- package/template/.claude/skills/editor/SKILL.md +53 -0
- package/template/.claude/skills/editor/agents/openai.yaml +4 -0
- package/template/.claude/skills/editor/references/editor-control.md +363 -0
- package/template/.claude/skills/vgai-3d-models/SKILL.md +64 -0
- package/template/.claude/skills/vgai-ingest-existing-game/SKILL.md +112 -0
- package/template/.claude/skills/vgai-threejs-authoring/SKILL.md +347 -0
- package/template/.claude/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
- package/template/.claude/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
- package/template/.github/copilot-instructions.md +6 -0
- package/template/.github/skills/editor/SKILL.md +53 -0
- package/template/.github/skills/editor/agents/openai.yaml +4 -0
- package/template/.github/skills/editor/references/editor-control.md +363 -0
- package/template/.github/skills/vgai-3d-models/SKILL.md +64 -0
- package/template/.github/skills/vgai-ingest-existing-game/SKILL.md +112 -0
- package/template/.github/skills/vgai-threejs-authoring/SKILL.md +347 -0
- package/template/.github/skills/vgai-threejs-authoring/agents/openai.yaml +4 -0
- package/template/.github/skills/vgai-threejs-authoring/references/helper-catalog.md +65 -0
- package/template/.mcp.json +12 -0
- package/template/.vgai/assets.json +1 -0
- package/template/.vgai/provenance.json +4 -0
- package/template/.volter/tracker/validation/.preset.base.mts +178 -0
- package/template/.volter/tracker/validation/preset.mts +186 -0
- package/template/.volter/tracker/visualizer/.extension.base.tsx +14 -0
- package/template/.volter/tracker/visualizer/extension.tsx +14 -0
- package/template/.volter/tracker-config.json +17 -0
- package/template/AGENTS.md +176 -0
- package/template/CLAUDE.md +1 -0
- package/template/DEVLOG.md +20 -0
- package/template/IDIOMS.md +118 -0
- package/template/LICENSE +30 -0
- package/template/README.md +83 -0
- package/template/ROADMAP.md +20 -0
- package/template/asset-manifest.json +3 -0
- package/template/check-idioms.ts +1533 -0
- package/template/index.html +18 -0
- package/template/manifest-entry-modules-plugin.ts +53 -0
- package/template/package.json +62 -0
- package/template/public/jsm/libs/basis/basis_transcoder.js +19 -0
- package/template/public/jsm/libs/basis/basis_transcoder.wasm +0 -0
- package/template/public/jsm/libs/draco/gltf/draco_decoder.js +33 -0
- package/template/public/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/template/public/jsm/libs/draco/gltf/draco_encoder.js +33 -0
- package/template/public/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/template/public/shaders/daylight-sky.frag.glsl +15 -0
- package/template/public/shaders/daylight-sky.vert.glsl +7 -0
- package/template/scripts/patch-drei-stats-gl.mjs +35 -0
- package/template/server/colyseus-setup.ts +111 -0
- package/template/server/loopback.ts +76 -0
- package/template/server/main.ts +78 -0
- package/template/server/rooms/arena-room.ts +488 -0
- package/template/server/rooms/game-room.ts +274 -0
- package/template/server/rooms.ts +15 -0
- package/template/server/tsconfig.json +19 -0
- package/template/src/bot/QaTester.tsx +35 -0
- package/template/src/bot/behaviors.ts +203 -0
- package/template/src/bot/bot-station.ts +192 -0
- package/template/src/bot/tester-run.ts +238 -0
- package/template/src/bot/tester-station.ts +193 -0
- package/template/src/components/environment/DaylightSky.tsx +54 -0
- package/template/src/components/environment/Ground.tsx +129 -0
- package/template/src/components/environment/SceneAtmosphere.tsx +14 -0
- package/template/src/components/environment/SoftGroundShadow.tsx +62 -0
- package/template/src/components/environment/SunShadowFit.tsx +141 -0
- package/template/src/contributions/README.md +98 -0
- package/template/src/contributions/analytics.analytics.tsx +26 -0
- package/template/src/contributions/data.document.tsx +35 -0
- package/template/src/contributions/pages.finder.ts +61 -0
- package/template/src/contributions/tester.inspector.tsx +64 -0
- package/template/src/contributions/use-game-modules.ts +80 -0
- package/template/src/data/README.md +17 -0
- package/template/src/input.ts +97 -0
- package/template/src/lib/audio/capability.json +4 -0
- package/template/src/lib/audio/sfx.ts +255 -0
- package/template/src/lib/react-root/capability.json +4 -0
- package/template/src/lib/react-root/index.ts +20 -0
- package/template/src/lib/react-root/react-root-adapter.tsx +57 -0
- package/template/src/lib/reflections/ReflectionProbe.tsx +201 -0
- package/template/src/lib/reflections/capability.json +4 -0
- package/template/src/lib/reflections/index.ts +19 -0
- package/template/src/lib/reflections/probe-controller.ts +75 -0
- package/template/src/lib/reflections/reflection-probe-registry.ts +402 -0
- package/template/src/lib/reflections/volume-reflection-material.ts +416 -0
- package/template/src/lib/static-batch/Frozen.tsx +91 -0
- package/template/src/lib/static-batch/capability.json +4 -0
- package/template/src/lib/static-batch/freeze.ts +579 -0
- package/template/src/lib/static-batch/index.ts +44 -0
- package/template/src/lib/static-batch/mutation-watch.ts +149 -0
- package/template/src/lib/static-batch/shadow-cache.ts +171 -0
- package/template/src/main.ts +63 -0
- package/template/src/manifest-entry-modules.d.ts +3 -0
- package/template/src/prefabs/HeroBox.stories.tsx +23 -0
- package/template/src/prefabs/HeroBox.tsx +35 -0
- package/template/src/scenes/MainScene.tsx +77 -0
- package/template/src/world.tsx +87 -0
- package/template/tsconfig.json +35 -0
- package/template/tsconfig.node.json +32 -0
- package/template/tsconfig.tools.json +22 -0
- package/template/validate-asset-content.ts +27 -0
- package/template/validate-assets.ts +60 -0
- package/template/validate-manifest.ts +55 -0
- package/template/vgai.adapter.ts +76 -0
- package/template/vgai.project.json +24 -0
- package/template/vite.config.ts +247 -0
- package/template-dotfiles/gitignore +63 -0
- package/workbench/src/media/game-cover.css +83 -0
- package/workbench/src/product.contribution.ts +188 -0
- package/workbench/src/vgaiGameSkew.ts +276 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE TRIPWIRE for the one rule `<Frozen>` cannot enforce: its children must
|
|
3
|
+
* be MOUNT-STATIC.
|
|
4
|
+
*
|
|
5
|
+
* A freeze draws the batched products and hides the originals. React still
|
|
6
|
+
* owns those originals, so nothing stops a game from moving one, re-colouring
|
|
7
|
+
* it, or un-hiding it — and nothing HAPPENS when it does. The mesh is
|
|
8
|
+
* invisible; the picture comes from the product; the edit is simply lost. That
|
|
9
|
+
* is the worst possible failure shape: silent, and indistinguishable from the
|
|
10
|
+
* mechanic being wrong. An author who animates a door under a `<Frozen>` will
|
|
11
|
+
* spend an afternoon in the wrong file.
|
|
12
|
+
*
|
|
13
|
+
* The contract used to live in a docblock. A docblock describes intent; only a
|
|
14
|
+
* measurement describes status. So the hidden originals are SAMPLED — the
|
|
15
|
+
* cheapest reading that catches all three drifts:
|
|
16
|
+
* - `matrixWorld`, hashed: it moved, was scaled, or was re-parented;
|
|
17
|
+
* - `material.version`, which three bumps on `needsUpdate`: it was re-styled;
|
|
18
|
+
* - `visible`, restored to `true` by the game: it thinks it is showing.
|
|
19
|
+
*
|
|
20
|
+
* ── COST, AND WHY IT IS A TIMER ─────────────────────────────────────────────
|
|
21
|
+
* ~1 Hz, and only under {@link devBuildEnabled}. A per-frame check would be a
|
|
22
|
+
* real cost added by a feature whose entire job is removing cost; a `Proxy` or
|
|
23
|
+
* accessor trap over every node would change the objects the game is holding.
|
|
24
|
+
* A second of latency on a diagnostic nobody is waiting for is free, and 4,000
|
|
25
|
+
* hashes once a second is a rounding error against one frame of the draw calls
|
|
26
|
+
* this replaced.
|
|
27
|
+
*
|
|
28
|
+
* It fires ONCE. The first drift is the finding; a mechanic that runs every
|
|
29
|
+
* frame would otherwise fill the console with the same line, and the watch
|
|
30
|
+
* stops itself rather than becoming the noise it exists to prevent.
|
|
31
|
+
*
|
|
32
|
+
* ── RESOURCE OWNERSHIP, STATED ONCE ─────────────────────────────────────────
|
|
33
|
+
* OWNER: the handle {@link watchFrozenMutations} returns, which owns exactly
|
|
34
|
+
* one interval. SHARERS: none — `Frozen.tsx` holds it and nothing else sees
|
|
35
|
+
* it. TEARDOWN: that handle's `stop()`, the ONE path that clears the interval,
|
|
36
|
+
* called from the wrapper's own effect cleanup and by the watch itself after
|
|
37
|
+
* it warns. Idempotent.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { devBuildEnabled } from '@volter/game-runtime/runtime/dev-build';
|
|
41
|
+
import type * as THREE from 'three';
|
|
42
|
+
import type { FrozenBatch } from './freeze';
|
|
43
|
+
|
|
44
|
+
/** Samples per second. See the module note for why this is a timer at all. */
|
|
45
|
+
export const MUTATION_SAMPLE_MS = 1000;
|
|
46
|
+
|
|
47
|
+
interface Sample {
|
|
48
|
+
matrix: number;
|
|
49
|
+
materialVersions: string;
|
|
50
|
+
visible: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A cheap order-sensitive fold of the 16 world-matrix elements. Collisions
|
|
54
|
+
* are possible in principle and irrelevant in practice: this compares a value
|
|
55
|
+
* against ITS OWN previous value, not against another node's. */
|
|
56
|
+
function hashMatrix(mesh: THREE.Object3D): number {
|
|
57
|
+
const elements = mesh.matrixWorld.elements;
|
|
58
|
+
let hash = 0;
|
|
59
|
+
for (let i = 0; i < 16; i++) hash = (hash * 31 + (elements[i] ?? 0)) % 1e12;
|
|
60
|
+
return hash;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function sample(mesh: THREE.Mesh): Sample {
|
|
64
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
65
|
+
return {
|
|
66
|
+
matrix: hashMatrix(mesh),
|
|
67
|
+
materialVersions: materials.map((material) => material?.version ?? -1).join(','),
|
|
68
|
+
visible: mesh.visible,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** What changed, in the words of the thing that changed it. */
|
|
73
|
+
function drift(before: Sample, after: Sample): string | null {
|
|
74
|
+
if (after.visible !== before.visible) return 'was made visible again';
|
|
75
|
+
if (after.matrix !== before.matrix) return 'moved (its world matrix changed)';
|
|
76
|
+
if (after.materialVersions !== before.materialVersions) return 'had its material changed';
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface FrozenMutationWatch {
|
|
81
|
+
/** See the ownership note — the ONE path that ends the watch. Idempotent. */
|
|
82
|
+
stop(): void;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function warnOnConsole(message: string): void {
|
|
86
|
+
// biome-ignore lint/suspicious/noConsole: console is this tripwire's vgai-status channel.
|
|
87
|
+
console.warn(message);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Watch a freeze's hidden originals for the mutations the contract forbids,
|
|
92
|
+
* and say so once. A no-op outside a dev context, and a no-op when the freeze
|
|
93
|
+
* hid nothing.
|
|
94
|
+
*/
|
|
95
|
+
export function watchFrozenMutations(
|
|
96
|
+
batch: FrozenBatch,
|
|
97
|
+
options: {
|
|
98
|
+
/** Injectable so the tripwire is provable without a console. */
|
|
99
|
+
readonly warn?: (message: string) => void;
|
|
100
|
+
/** Injectable so a test can step time instead of waiting a second. */
|
|
101
|
+
readonly schedule?: (tick: () => void) => () => void;
|
|
102
|
+
/** Overrides the dev gate — a headless test passes `true`. */
|
|
103
|
+
readonly dev?: boolean;
|
|
104
|
+
} = {},
|
|
105
|
+
): FrozenMutationWatch {
|
|
106
|
+
const warn = options.warn ?? warnOnConsole;
|
|
107
|
+
if (!devBuildEnabled(options.dev) || batch.sources.length === 0) {
|
|
108
|
+
return { stop: () => {} };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const baseline = batch.sources.map((source) => sample(source.mesh));
|
|
112
|
+
let stopped = false;
|
|
113
|
+
let release: (() => void) | null = null;
|
|
114
|
+
|
|
115
|
+
const stop = (): void => {
|
|
116
|
+
if (stopped) return;
|
|
117
|
+
stopped = true;
|
|
118
|
+
release?.();
|
|
119
|
+
release = null;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const tick = (): void => {
|
|
123
|
+
if (stopped) return;
|
|
124
|
+
for (let i = 0; i < batch.sources.length; i++) {
|
|
125
|
+
const source = batch.sources[i];
|
|
126
|
+
const before = baseline[i];
|
|
127
|
+
if (!source || !before) continue;
|
|
128
|
+
const change = drift(before, sample(source.mesh));
|
|
129
|
+
if (!change) continue;
|
|
130
|
+
const node = source.mesh.name || '(unnamed)';
|
|
131
|
+
warn(
|
|
132
|
+
`[static-batch] "${node}" ${change} while frozen under <Frozen name="${batch.name}"> — ` +
|
|
133
|
+
'the change will never be visible, because the picture comes from the batched copy ' +
|
|
134
|
+
'and the original is hidden. Everything under a <Frozen> must be mount-static: move ' +
|
|
135
|
+
'this node OUT of the wrapper, or mark its subtree userData={{ staticBatch: false }}.',
|
|
136
|
+
);
|
|
137
|
+
stop();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
if (options.schedule) {
|
|
143
|
+
release = options.schedule(tick);
|
|
144
|
+
} else {
|
|
145
|
+
const timer = setInterval(tick, MUTATION_SAMPLE_MS);
|
|
146
|
+
release = () => clearInterval(timer);
|
|
147
|
+
}
|
|
148
|
+
return { stop };
|
|
149
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/** Reuse directional shadow maps only while every caster is declared mount-static. */
|
|
2
|
+
|
|
3
|
+
import type * as THREE from 'three';
|
|
4
|
+
import { activeFrozenBatches, type FrozenBatch } from './freeze';
|
|
5
|
+
|
|
6
|
+
export interface FrozenDirectionalShadowController {
|
|
7
|
+
update(): void;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function belongsTo(node: THREE.Object3D, ancestor: THREE.Object3D): boolean {
|
|
12
|
+
for (let cursor: THREE.Object3D | null = node; cursor !== null; cursor = cursor.parent) {
|
|
13
|
+
if (cursor === ancestor) return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function matrixChanged(
|
|
19
|
+
node: THREE.Object3D,
|
|
20
|
+
snapshots: Map<THREE.Object3D, THREE.Matrix4>,
|
|
21
|
+
): boolean {
|
|
22
|
+
node.updateWorldMatrix(true, false);
|
|
23
|
+
const previous = snapshots.get(node);
|
|
24
|
+
if (previous?.equals(node.matrixWorld)) return false;
|
|
25
|
+
if (previous === undefined) snapshots.set(node, node.matrixWorld.clone());
|
|
26
|
+
else previous.copy(node.matrixWorld);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function projectionChanged(
|
|
31
|
+
camera: THREE.Camera,
|
|
32
|
+
snapshots: Map<THREE.Camera, THREE.Matrix4>,
|
|
33
|
+
): boolean {
|
|
34
|
+
const projectable = camera as THREE.Camera & { updateProjectionMatrix?: () => void };
|
|
35
|
+
projectable.updateProjectionMatrix?.();
|
|
36
|
+
const previous = snapshots.get(camera);
|
|
37
|
+
if (previous?.equals(camera.projectionMatrix)) return false;
|
|
38
|
+
if (previous === undefined) snapshots.set(camera, camera.projectionMatrix.clone());
|
|
39
|
+
else previous.copy(camera.projectionMatrix);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function collectDirectionalShadowLights(
|
|
44
|
+
root: THREE.Object3D,
|
|
45
|
+
lights: Set<THREE.DirectionalLight>,
|
|
46
|
+
): void {
|
|
47
|
+
root.traverseVisible((node) => {
|
|
48
|
+
const light = node as THREE.DirectionalLight;
|
|
49
|
+
if (light.isDirectionalLight && light.castShadow) lights.add(light);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function inspectOutsideFrozen(
|
|
54
|
+
node: THREE.Object3D,
|
|
55
|
+
frozenRoots: ReadonlySet<THREE.Object3D>,
|
|
56
|
+
lights: Set<THREE.DirectionalLight>,
|
|
57
|
+
): boolean {
|
|
58
|
+
if (!node.visible || frozenRoots.has(node)) return false;
|
|
59
|
+
const light = node as THREE.DirectionalLight;
|
|
60
|
+
if (light.isDirectionalLight && light.castShadow) lights.add(light);
|
|
61
|
+
let caster = (node as THREE.Mesh).isMesh === true && (node as THREE.Mesh).castShadow;
|
|
62
|
+
for (const child of node.children) {
|
|
63
|
+
caster = inspectOutsideFrozen(child, frozenRoots, lights) || caster;
|
|
64
|
+
}
|
|
65
|
+
return caster;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function sceneBatches(scene: THREE.Object3D): readonly FrozenBatch[] {
|
|
69
|
+
return activeFrozenBatches().filter((batch) => belongsTo(batch.root, scene));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface ShadowControllerState {
|
|
73
|
+
readonly objectMatrices: Map<THREE.Object3D, THREE.Matrix4>;
|
|
74
|
+
readonly cameraProjections: Map<THREE.Camera, THREE.Matrix4>;
|
|
75
|
+
readonly controlledLights: Set<THREE.DirectionalLight>;
|
|
76
|
+
readonly frozenLights: Set<THREE.DirectionalLight>;
|
|
77
|
+
previousBatches: Set<FrozenBatch>;
|
|
78
|
+
hadOutsideCaster: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function batchesChanged(batches: readonly FrozenBatch[], previous: ReadonlySet<FrozenBatch>) {
|
|
82
|
+
return batches.length !== previous.size || batches.some((batch) => !previous.has(batch));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function updateLight(
|
|
86
|
+
light: THREE.DirectionalLight,
|
|
87
|
+
external: boolean,
|
|
88
|
+
staticInputChanged: boolean,
|
|
89
|
+
state: ShadowControllerState,
|
|
90
|
+
): void {
|
|
91
|
+
state.controlledLights.add(light);
|
|
92
|
+
if (external) {
|
|
93
|
+
light.shadow.autoUpdate = true;
|
|
94
|
+
light.shadow.needsUpdate = true;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Snapshot every input on the first invalidation. A short-circuit expression here would
|
|
98
|
+
// discover one previously unseen input per frame and redraw the same initial map four times.
|
|
99
|
+
const lightMoved = matrixChanged(light, state.objectMatrices);
|
|
100
|
+
const targetMoved = matrixChanged(light.target, state.objectMatrices);
|
|
101
|
+
const projectionMoved = projectionChanged(light.shadow.camera, state.cameraProjections);
|
|
102
|
+
light.shadow.autoUpdate = false;
|
|
103
|
+
if (staticInputChanged || lightMoved || targetMoved || projectionMoved) {
|
|
104
|
+
light.shadow.needsUpdate = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function updateController(scene: THREE.Object3D, state: ShadowControllerState): void {
|
|
109
|
+
const batches = sceneBatches(scene);
|
|
110
|
+
const roots = new Set(batches.map((batch) => batch.root));
|
|
111
|
+
const batchSetChanged = batchesChanged(batches, state.previousBatches);
|
|
112
|
+
state.previousBatches = new Set(batches);
|
|
113
|
+
|
|
114
|
+
if (batchSetChanged) {
|
|
115
|
+
state.frozenLights.clear();
|
|
116
|
+
for (const root of roots) collectDirectionalShadowLights(root, state.frozenLights);
|
|
117
|
+
}
|
|
118
|
+
const nextLights = new Set(state.frozenLights);
|
|
119
|
+
const outsideCaster = inspectOutsideFrozen(scene, roots, nextLights);
|
|
120
|
+
const external = batches.length === 0 || outsideCaster;
|
|
121
|
+
let staticInputChanged = batchSetChanged || external !== state.hadOutsideCaster;
|
|
122
|
+
state.hadOutsideCaster = external;
|
|
123
|
+
for (const root of roots) {
|
|
124
|
+
staticInputChanged = matrixChanged(root, state.objectMatrices) || staticInputChanged;
|
|
125
|
+
}
|
|
126
|
+
for (const light of nextLights) updateLight(light, external, staticInputChanged, state);
|
|
127
|
+
|
|
128
|
+
for (const light of state.controlledLights) {
|
|
129
|
+
if (nextLights.has(light)) continue;
|
|
130
|
+
light.shadow.autoUpdate = true;
|
|
131
|
+
light.shadow.needsUpdate = true;
|
|
132
|
+
state.controlledLights.delete(light);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Three redraws every directional shadow map every frame by default. A mounted `Frozen` subtree
|
|
138
|
+
* promises that its descendants do not change, so a scene whose ENTIRE caster set is covered by
|
|
139
|
+
* those declarations can reuse its depth map until a wrapper, light, target, or shadow camera
|
|
140
|
+
* changes. A caster anywhere outside a Frozen root immediately restores Three's ordinary
|
|
141
|
+
* per-frame path; reactive content is never guessed to be static.
|
|
142
|
+
*/
|
|
143
|
+
export function createFrozenDirectionalShadowController(
|
|
144
|
+
scene: THREE.Object3D,
|
|
145
|
+
): FrozenDirectionalShadowController {
|
|
146
|
+
const state: ShadowControllerState = {
|
|
147
|
+
objectMatrices: new Map(),
|
|
148
|
+
cameraProjections: new Map(),
|
|
149
|
+
controlledLights: new Set(),
|
|
150
|
+
frozenLights: new Set(),
|
|
151
|
+
previousBatches: new Set(),
|
|
152
|
+
hadOutsideCaster: true,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
update(): void {
|
|
157
|
+
updateController(scene, state);
|
|
158
|
+
},
|
|
159
|
+
dispose(): void {
|
|
160
|
+
for (const light of state.controlledLights) {
|
|
161
|
+
light.shadow.autoUpdate = true;
|
|
162
|
+
light.shadow.needsUpdate = true;
|
|
163
|
+
}
|
|
164
|
+
state.controlledLights.clear();
|
|
165
|
+
state.frozenLights.clear();
|
|
166
|
+
state.objectMatrices.clear();
|
|
167
|
+
state.cameraProjections.clear();
|
|
168
|
+
state.previousBatches.clear();
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone entry point.
|
|
3
|
+
*
|
|
4
|
+
* One `mountGameFromManifest` call mounts every explicit adapter root in the
|
|
5
|
+
* v2 `vgai.project.json`. Roots are required; the default scaffold declares
|
|
6
|
+
* one Three.js world, while composition templates may rewrite that list.
|
|
7
|
+
* The selected built-in adapter owns each root's document and lifecycle.
|
|
8
|
+
*
|
|
9
|
+
* `host.loadEntryModule` resolves an explicitly declared `entry` through a
|
|
10
|
+
* Vite-generated virtual module containing exactly the manifest's entry
|
|
11
|
+
* paths. The manifest remains the sole source of truth—filenames are
|
|
12
|
+
* arbitrary, while the bundler still sees static imports.
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { manifestEntryModules } from 'virtual:vgai-manifest-entries';
|
|
17
|
+
import type { ManifestHost } from '@volter/game-runtime/runtime/mount-game';
|
|
18
|
+
import {
|
|
19
|
+
isAdapterRegistered,
|
|
20
|
+
mountGameFromManifest,
|
|
21
|
+
registerAdapter,
|
|
22
|
+
} from '@volter/game-runtime/runtime/mount-game';
|
|
23
|
+
import { r3fRootFactory } from '@volter/game-runtime/world3d-react';
|
|
24
|
+
import manifest from '../vgai.project.json';
|
|
25
|
+
import { registerReactAdapter } from './lib/react-root';
|
|
26
|
+
|
|
27
|
+
// Three roots resolve through `r3fRootFactory`: the world entry module
|
|
28
|
+
// DEFAULT-EXPORTS its React component (src/world.tsx), the same contract dom
|
|
29
|
+
// roots already use. An `adapter` export still wins if a world needs full
|
|
30
|
+
// control over its own RootAdapter.
|
|
31
|
+
if (!isAdapterRegistered('three')) {
|
|
32
|
+
registerAdapter('three', r3fRootFactory);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Keep the optional DOM adapter available for a project that later adds a UI
|
|
36
|
+
// root; the neutral scaffold itself declares only the Three world.
|
|
37
|
+
registerReactAdapter();
|
|
38
|
+
|
|
39
|
+
async function main() {
|
|
40
|
+
document.title = manifest.name;
|
|
41
|
+
|
|
42
|
+
const container = document.getElementById('game-canvas') as HTMLElement;
|
|
43
|
+
const host: ManifestHost = {
|
|
44
|
+
container,
|
|
45
|
+
async loadEntryModule(path) {
|
|
46
|
+
const entryModule = manifestEntryModules[path];
|
|
47
|
+
if (!entryModule) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`main.ts: entry module "${path}" was not generated from vgai.project.json.`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return entryModule;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
const session = await mountGameFromManifest(manifest, host);
|
|
56
|
+
session.resize(window.innerWidth, window.innerHeight);
|
|
57
|
+
|
|
58
|
+
window.addEventListener('resize', () => {
|
|
59
|
+
session.resize(window.innerWidth, window.innerHeight);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { HeroBox } from './HeroBox';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Starter/Hero Box',
|
|
6
|
+
component: HeroBox,
|
|
7
|
+
// `color` is deliberately NOT pinned here: the story exhibits the
|
|
8
|
+
// component's own default, so Apply-to-Component changes what the board
|
|
9
|
+
// shows. A pinned copy of the default masked every applied change (two
|
|
10
|
+
// humans read the stale exhibit as breakage — runhuman passes 43/44).
|
|
11
|
+
args: {
|
|
12
|
+
name: 'Hero Box',
|
|
13
|
+
rotation: [0, -0.28, 0],
|
|
14
|
+
},
|
|
15
|
+
} satisfies Meta<typeof HeroBox>;
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
parameters: { vgai: { default: true } },
|
|
23
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RoundedBoxGeometry } from '@react-three/drei/core/RoundedBox';
|
|
2
|
+
import type { ThreeElements } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
export type HeroBoxProps = Omit<ThreeElements['mesh'], 'args' | 'children' | 'ref'> & {
|
|
5
|
+
color?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The neutral focal-object prefab: one independently placeable thing a
|
|
10
|
+
* designer can find in Content, duplicate, and reuse. Its colocated story is
|
|
11
|
+
* the registration. Keep construction pieces that only make sense as part of
|
|
12
|
+
* this object inside this owner; do not promote its geometry or material into
|
|
13
|
+
* primitive-sized prefabs. Replace the subject, not this distinction.
|
|
14
|
+
*/
|
|
15
|
+
export function HeroBox({ color = '#c8dce1', name = 'Hero Box', ...props }: HeroBoxProps) {
|
|
16
|
+
return (
|
|
17
|
+
<mesh name={name} castShadow receiveShadow {...props}>
|
|
18
|
+
<RoundedBoxGeometry
|
|
19
|
+
args={[2.55, 2.55, 2.55]}
|
|
20
|
+
radius={0.14}
|
|
21
|
+
smoothness={8}
|
|
22
|
+
bevelSegments={8}
|
|
23
|
+
/>
|
|
24
|
+
<meshPhysicalMaterial
|
|
25
|
+
color={color}
|
|
26
|
+
roughness={0.24}
|
|
27
|
+
metalness={0.06}
|
|
28
|
+
clearcoat={0.36}
|
|
29
|
+
clearcoatRoughness={0.2}
|
|
30
|
+
sheen={0.18}
|
|
31
|
+
sheenColor="#d9f2ff"
|
|
32
|
+
/>
|
|
33
|
+
</mesh>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { OrbitControls } from '@react-three/drei/core/OrbitControls';
|
|
2
|
+
import { PerspectiveCamera } from '@react-three/drei/core/PerspectiveCamera';
|
|
3
|
+
import type { ThreeElements } from '@react-three/fiber';
|
|
4
|
+
import { useRef } from 'react';
|
|
5
|
+
import type * as THREE from 'three';
|
|
6
|
+
import { DaylightSky } from '../components/environment/DaylightSky';
|
|
7
|
+
import { Ground } from '../components/environment/Ground';
|
|
8
|
+
import { SceneAtmosphere } from '../components/environment/SceneAtmosphere';
|
|
9
|
+
import { SoftGroundShadow } from '../components/environment/SoftGroundShadow';
|
|
10
|
+
import { SunShadowFit } from '../components/environment/SunShadowFit';
|
|
11
|
+
import { HeroBox } from '../prefabs/HeroBox';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The complete neutral starter composition. A scene arranges environment,
|
|
15
|
+
* placeable prefabs, and the camera; it is not itself a Content prefab and
|
|
16
|
+
* should not hide independently placeable entities inside one scenery owner.
|
|
17
|
+
*/
|
|
18
|
+
export function MainScene({ name = 'Main Scene', ...props }: ThreeElements['group']) {
|
|
19
|
+
const sun = useRef<THREE.DirectionalLight>(null);
|
|
20
|
+
return (
|
|
21
|
+
<group name={name} {...props}>
|
|
22
|
+
<SceneAtmosphere />
|
|
23
|
+
<group name="Environment">
|
|
24
|
+
<DaylightSky name="Daylight Sky" />
|
|
25
|
+
<group name="Light Rig">
|
|
26
|
+
<hemisphereLight name="Sky Fill" args={['#e9f8ff', '#87958f', 1.55]} />
|
|
27
|
+
{/* The sun's position is its DIRECTION; `SunShadowFit` moves the node
|
|
28
|
+
and sizes the shadow box from what the camera frames, so the box
|
|
29
|
+
carries no hardcoded scale. Authored lateral extents and depth
|
|
30
|
+
range would be overwritten and are deliberately absent — see that
|
|
31
|
+
component's header for why ±12 units broke every game built at a
|
|
32
|
+
scale other than this scene's. `shadow-bias` is a fraction of the
|
|
33
|
+
fitted depth range, so it stays authored here. */}
|
|
34
|
+
<directionalLight
|
|
35
|
+
ref={sun}
|
|
36
|
+
name="Sun"
|
|
37
|
+
position={[10, 14, 7]}
|
|
38
|
+
intensity={2.7}
|
|
39
|
+
color="#fff4dc"
|
|
40
|
+
castShadow
|
|
41
|
+
shadow-mapSize-width={2048}
|
|
42
|
+
shadow-mapSize-height={2048}
|
|
43
|
+
shadow-bias={-0.00015}
|
|
44
|
+
/>
|
|
45
|
+
<SunShadowFit light={sun} />
|
|
46
|
+
<directionalLight
|
|
47
|
+
name="Cool Fill"
|
|
48
|
+
position={[-7, 7, -9]}
|
|
49
|
+
intensity={0.55}
|
|
50
|
+
color="#b8dcff"
|
|
51
|
+
/>
|
|
52
|
+
</group>
|
|
53
|
+
<Ground name="Ground" />
|
|
54
|
+
<SoftGroundShadow name="Soft Ground Shadow" />
|
|
55
|
+
</group>
|
|
56
|
+
|
|
57
|
+
<HeroBox name="Hero Box" position={[0, 1.3, 0]} rotation={[0, -0.28, 0]} color="#c8dce1" />
|
|
58
|
+
<PerspectiveCamera
|
|
59
|
+
makeDefault
|
|
60
|
+
name="Camera"
|
|
61
|
+
position={[7.35, 3.9, 8.15]}
|
|
62
|
+
fov={41}
|
|
63
|
+
near={0.1}
|
|
64
|
+
far={220}
|
|
65
|
+
/>
|
|
66
|
+
<OrbitControls
|
|
67
|
+
makeDefault
|
|
68
|
+
target={[0, 1.15, 0]}
|
|
69
|
+
enablePan={false}
|
|
70
|
+
minDistance={6.5}
|
|
71
|
+
maxDistance={16}
|
|
72
|
+
minPolarAngle={0.55}
|
|
73
|
+
maxPolarAngle={1.38}
|
|
74
|
+
/>
|
|
75
|
+
</group>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Three root's thin entrypoint. Complete replaceable compositions live in
|
|
3
|
+
* `src/scenes/`; story-backed placeable assets live in `src/prefabs/`; and
|
|
4
|
+
* extracted non-placeable implementation lives in `src/components/`. Folder
|
|
5
|
+
* names describe what a file IS, never merely where it is used.
|
|
6
|
+
*
|
|
7
|
+
* `scenes` is the app's ordinary composition table and `activeScene` selects
|
|
8
|
+
* the component rendered at the root. Add another composition to
|
|
9
|
+
* `src/scenes/`, import it here, and give it a key in the table.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { useThree } from '@react-three/fiber';
|
|
13
|
+
import { useEffect } from 'react';
|
|
14
|
+
import * as THREE from 'three';
|
|
15
|
+
import { QaTester } from './bot/QaTester';
|
|
16
|
+
import { attachKeyboard } from './input';
|
|
17
|
+
import { sfxAudioSystem } from './lib/audio/sfx';
|
|
18
|
+
import { MainScene } from './scenes/MainScene';
|
|
19
|
+
|
|
20
|
+
/** Renderer finish is project-owned state, restored when this world unmounts. */
|
|
21
|
+
function RenderFinish() {
|
|
22
|
+
const renderer = useThree((state) => state.gl);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const previousToneMapping = renderer.toneMapping;
|
|
26
|
+
const previousExposure = renderer.toneMappingExposure;
|
|
27
|
+
const previousShadowsEnabled = renderer.shadowMap?.enabled;
|
|
28
|
+
const previousShadowType = renderer.shadowMap?.type;
|
|
29
|
+
|
|
30
|
+
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
31
|
+
renderer.toneMappingExposure = 0.96;
|
|
32
|
+
if (renderer.shadowMap) {
|
|
33
|
+
renderer.shadowMap.enabled = true;
|
|
34
|
+
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
renderer.toneMapping = previousToneMapping;
|
|
39
|
+
renderer.toneMappingExposure = previousExposure;
|
|
40
|
+
if (renderer.shadowMap && previousShadowType !== undefined) {
|
|
41
|
+
renderer.shadowMap.enabled = previousShadowsEnabled ?? false;
|
|
42
|
+
renderer.shadowMap.type = previousShadowType;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, [renderer]);
|
|
46
|
+
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The physical keyboard half of `src/input.ts`, owned by the world that reads
|
|
52
|
+
* it. The effect's cleanup detaches on unmount, so a Play→stop cycle leaves no
|
|
53
|
+
* window listener behind — the editor's realm audit warns about any that
|
|
54
|
+
* survive, and a listener attached at module load can never be released.
|
|
55
|
+
*/
|
|
56
|
+
function GameKeyboard() {
|
|
57
|
+
useEffect(() => attachKeyboard(window), []);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** This world's swap slot — every composition it can mount, by id. */
|
|
62
|
+
const scenes = {
|
|
63
|
+
main: MainScene,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** The composition mounted at the slot right now. */
|
|
67
|
+
const activeScene: keyof typeof scenes = 'main';
|
|
68
|
+
|
|
69
|
+
function World() {
|
|
70
|
+
const Scene = scenes[activeScene];
|
|
71
|
+
return (
|
|
72
|
+
<>
|
|
73
|
+
<RenderFinish />
|
|
74
|
+
<GameKeyboard />
|
|
75
|
+
{/* The resident QA tester's hands on the frame — everything else about
|
|
76
|
+
the playtesting loop (the seat, the repertoire, pause/handoff) is
|
|
77
|
+
plain application code in src/bot/, reached from `vgai eval` via
|
|
78
|
+
`game.run(({ modules }) => …)` like every other module. */}
|
|
79
|
+
<QaTester />
|
|
80
|
+
<Scene name="Main Scene" />
|
|
81
|
+
</>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const systems = { audio: sfxAudioSystem() };
|
|
86
|
+
|
|
87
|
+
export default World;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noUncheckedIndexedAccess": true,
|
|
9
|
+
"noFallthroughCasesInSwitch": true,
|
|
10
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
11
|
+
"exactOptionalPropertyTypes": true,
|
|
12
|
+
"experimentalDecorators": true,
|
|
13
|
+
"useDefineForClassFields": false,
|
|
14
|
+
"noUnusedLocals": true,
|
|
15
|
+
"noUnusedParameters": true,
|
|
16
|
+
"verbatimModuleSyntax": true,
|
|
17
|
+
"esModuleInterop": true,
|
|
18
|
+
"forceConsistentCasingInFileNames": true,
|
|
19
|
+
"resolveJsonModule": true,
|
|
20
|
+
"isolatedModules": true,
|
|
21
|
+
"skipLibCheck": true,
|
|
22
|
+
"noEmit": true,
|
|
23
|
+
"jsx": "react-jsx",
|
|
24
|
+
"types": ["vite/client"],
|
|
25
|
+
"baseUrl": ".",
|
|
26
|
+
"paths": {
|
|
27
|
+
"@volter/editor-project/*": ["node_modules/@volter/editor-project/src/*"],
|
|
28
|
+
"@volter/threejs-runtime/*": ["node_modules/@volter/threejs-runtime/src/*"],
|
|
29
|
+
"@volter/game-runtime/*": ["node_modules/@volter/game-runtime/src/*"],
|
|
30
|
+
"@editor/*": ["node_modules/@volter/editor-core/src/*"]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"include": ["src", "vgai.adapter.ts"],
|
|
34
|
+
"exclude": ["src/tools", "src/contributions"]
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
// This project's BUILD-TIME Node program — `vite.config.ts` and the
|
|
3
|
+
// config-relative modules it imports (`manifest-entry-modules-plugin.ts`).
|
|
4
|
+
//
|
|
5
|
+
// Why it is its own program rather than an entry in the base config's
|
|
6
|
+
// `include`: the base config types the BROWSER (`types: ["vite/client"]`,
|
|
7
|
+
// no node), which is the same reason `src/tools` needed
|
|
8
|
+
// `tsconfig.tools.json`. `vite.config.ts` reads `process.env` and
|
|
9
|
+
// `__dirname`, so it needs `node` in `types` — and it must not be able to
|
|
10
|
+
// reach browser-only globals by accident either way round.
|
|
11
|
+
//
|
|
12
|
+
// What it closes: before this, NO program in this project's `typecheck`
|
|
13
|
+
// script (nor in the engine repo's `npm run typecheck` graph) included
|
|
14
|
+
// `vite.config.ts`. It was compiled only by Vite's own esbuild, which
|
|
15
|
+
// strips types without checking them — so the file could and did drift
|
|
16
|
+
// out of `ServerOptions`, and the strictness this project sets everywhere
|
|
17
|
+
// else (`noPropertyAccessFromIndexSignature`,
|
|
18
|
+
// `exactOptionalPropertyTypes`) never applied to the one file that
|
|
19
|
+
// decides how the project builds and serves.
|
|
20
|
+
//
|
|
21
|
+
// `exclude` MUST be reset here for the same reason `tsconfig.tools.json`
|
|
22
|
+
// documents: `extends` inherits the base `exclude: ["src/tools"]`, and
|
|
23
|
+
// while that particular pattern cannot match anything in this `include`,
|
|
24
|
+
// leaving inherited excludes in place is how a program silently compiles
|
|
25
|
+
// ZERO files and still exits 0.
|
|
26
|
+
"extends": "./tsconfig.json",
|
|
27
|
+
"compilerOptions": {
|
|
28
|
+
"types": ["vite/client", "node"]
|
|
29
|
+
},
|
|
30
|
+
"include": ["vite.config.ts", "manifest-entry-modules-plugin.ts"],
|
|
31
|
+
"exclude": []
|
|
32
|
+
}
|