@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,129 @@
|
|
|
1
|
+
import type { ThreeElements } from '@react-three/fiber';
|
|
2
|
+
import { useEffect, useMemo } from 'react';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
|
|
5
|
+
|
|
6
|
+
export type GroundProps = Omit<ThreeElements['group'], 'children'> & {
|
|
7
|
+
size?: number;
|
|
8
|
+
gridSize?: number;
|
|
9
|
+
gridDivisions?: number;
|
|
10
|
+
showGrid?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** World-units-per-cell at which a grid line counts as MAJOR (one per 5 cells at defaults). */
|
|
14
|
+
const MAJOR_LINE_EVERY = 10;
|
|
15
|
+
|
|
16
|
+
/** One merged geometry holding every X- and Z-aligned line of one weight tier. */
|
|
17
|
+
function buildGridLines(coordinates: number[], thickness: number, length: number) {
|
|
18
|
+
// An empty class of lines (every line major, or none) must still be a
|
|
19
|
+
// geometry: `mergeGeometries([])` reads the first entry's index and throws,
|
|
20
|
+
// which took the whole world down from an inspector edit and persisted the
|
|
21
|
+
// crash into source — a reload failed the same way (runhuman pass 48).
|
|
22
|
+
if (coordinates.length === 0) return new THREE.BufferGeometry();
|
|
23
|
+
const boxes: THREE.BufferGeometry[] = [];
|
|
24
|
+
for (const coordinate of coordinates) {
|
|
25
|
+
const alongZ = new THREE.BoxGeometry(thickness, 0.006, length);
|
|
26
|
+
alongZ.translate(coordinate, 0, 0);
|
|
27
|
+
const alongX = new THREE.BoxGeometry(length, 0.006, thickness);
|
|
28
|
+
alongX.translate(0, 0, coordinate);
|
|
29
|
+
boxes.push(alongZ, alongX);
|
|
30
|
+
}
|
|
31
|
+
const merged = mergeGeometries(boxes);
|
|
32
|
+
for (const box of boxes) box.dispose();
|
|
33
|
+
return merged;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Radial white→black gradient; as the surface's alphaMap it melts the floor's
|
|
37
|
+
* edge into the sky the way distance fog used to — but view-independently, so
|
|
38
|
+
* the soft horizon survives the Scene view's fog-neutral draw policy. */
|
|
39
|
+
function buildEdgeFadeTexture() {
|
|
40
|
+
const size = 256;
|
|
41
|
+
const canvas = document.createElement('canvas');
|
|
42
|
+
canvas.width = size;
|
|
43
|
+
canvas.height = size;
|
|
44
|
+
const context = canvas.getContext('2d');
|
|
45
|
+
if (context) {
|
|
46
|
+
const gradient = context.createRadialGradient(
|
|
47
|
+
size / 2,
|
|
48
|
+
size / 2,
|
|
49
|
+
(size / 2) * 0.5,
|
|
50
|
+
size / 2,
|
|
51
|
+
size / 2,
|
|
52
|
+
(size / 2) * 0.94,
|
|
53
|
+
);
|
|
54
|
+
gradient.addColorStop(0, '#ffffff');
|
|
55
|
+
gradient.addColorStop(1, '#000000');
|
|
56
|
+
context.fillStyle = gradient;
|
|
57
|
+
context.fillRect(0, 0, size, size);
|
|
58
|
+
}
|
|
59
|
+
return new THREE.CanvasTexture(canvas);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The starter scene's floor assembly. It is scene support, not a placeable prefab. */
|
|
63
|
+
export function Ground({
|
|
64
|
+
name = 'Ground',
|
|
65
|
+
size = 180,
|
|
66
|
+
gridSize = 80,
|
|
67
|
+
gridDivisions = 40,
|
|
68
|
+
showGrid = true,
|
|
69
|
+
...props
|
|
70
|
+
}: GroundProps) {
|
|
71
|
+
const edgeFade = useMemo(() => buildEdgeFadeTexture(), []);
|
|
72
|
+
useEffect(() => () => edgeFade.dispose(), [edgeFade]);
|
|
73
|
+
|
|
74
|
+
// Every value here is authorable from the Inspector, including mid-edit
|
|
75
|
+
// states (0, blank, negative): clamp to what a grid can be instead of
|
|
76
|
+
// letting NaN or Infinity reach the geometry.
|
|
77
|
+
const safeSize = Number.isFinite(size) && size > 0 ? size : 0.01;
|
|
78
|
+
const safeGridSize = Number.isFinite(gridSize) && gridSize > 0 ? gridSize : 0.01;
|
|
79
|
+
const safeDivisions =
|
|
80
|
+
Number.isFinite(gridDivisions) && gridDivisions >= 1
|
|
81
|
+
? Math.min(Math.floor(gridDivisions), 400)
|
|
82
|
+
: 1;
|
|
83
|
+
const gridGeometries = useMemo(() => {
|
|
84
|
+
const half = safeGridSize / 2;
|
|
85
|
+
const spacing = safeGridSize / safeDivisions;
|
|
86
|
+
const coordinates = Array.from({ length: safeDivisions + 1 }, (_, i) => -half + i * spacing);
|
|
87
|
+
const isMajor = (c: number) => Math.abs(c % MAJOR_LINE_EVERY) < spacing / 2;
|
|
88
|
+
return {
|
|
89
|
+
major: buildGridLines(coordinates.filter(isMajor), 0.028, safeGridSize),
|
|
90
|
+
minor: buildGridLines(
|
|
91
|
+
coordinates.filter((c) => !isMajor(c)),
|
|
92
|
+
0.014,
|
|
93
|
+
safeGridSize,
|
|
94
|
+
),
|
|
95
|
+
};
|
|
96
|
+
}, [safeGridSize, safeDivisions]);
|
|
97
|
+
useEffect(
|
|
98
|
+
() => () => {
|
|
99
|
+
gridGeometries.major.dispose();
|
|
100
|
+
gridGeometries.minor.dispose();
|
|
101
|
+
},
|
|
102
|
+
[gridGeometries],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<group name={name} {...props}>
|
|
107
|
+
<mesh name="Surface" rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
|
|
108
|
+
<circleGeometry args={[safeSize / 2, 96]} />
|
|
109
|
+
<meshStandardMaterial
|
|
110
|
+
color="#d2d0c6"
|
|
111
|
+
roughness={0.86}
|
|
112
|
+
metalness={0.02}
|
|
113
|
+
transparent
|
|
114
|
+
alphaMap={edgeFade}
|
|
115
|
+
/>
|
|
116
|
+
</mesh>
|
|
117
|
+
{showGrid && (
|
|
118
|
+
<group name="Construction Grid" position={[0, 0.018, 0]}>
|
|
119
|
+
<mesh name="Major Lines" geometry={gridGeometries.major}>
|
|
120
|
+
<meshBasicMaterial color="#587785" transparent opacity={0.23} depthWrite={false} />
|
|
121
|
+
</mesh>
|
|
122
|
+
<mesh name="Minor Lines" geometry={gridGeometries.minor}>
|
|
123
|
+
<meshBasicMaterial color="#587785" transparent opacity={0.115} depthWrite={false} />
|
|
124
|
+
</mesh>
|
|
125
|
+
</group>
|
|
126
|
+
)}
|
|
127
|
+
</group>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createPortal, useThree } from '@react-three/fiber';
|
|
2
|
+
|
|
3
|
+
/** Native Fiber scene attachments. Their constructor literals remain the
|
|
4
|
+
* project's source of truth and are directly tunable in the World Inspector. */
|
|
5
|
+
export function SceneAtmosphere() {
|
|
6
|
+
const scene = useThree((state) => state.scene);
|
|
7
|
+
return createPortal(
|
|
8
|
+
<>
|
|
9
|
+
<color attach="background" args={['#a9d8f2']} />
|
|
10
|
+
<fog attach="fog" args={['#c8e3ef', 32, 105]} />
|
|
11
|
+
</>,
|
|
12
|
+
scene,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ThreeElements } from '@react-three/fiber';
|
|
2
|
+
import { useFrame } from '@react-three/fiber';
|
|
3
|
+
import { useRef } from 'react';
|
|
4
|
+
import type * as THREE from 'three';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The starter camera's authored orbit distance (|position − target| of the
|
|
8
|
+
* scene's camera rig). Factor 1 of the fit below — at the shipped framing the
|
|
9
|
+
* plane reproduces the exact decor the starter always had, by construction.
|
|
10
|
+
*/
|
|
11
|
+
const STARTER_VIEW_DISTANCE = 11.3;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A lightweight contact shadow with no render-target or asset dependency.
|
|
15
|
+
*
|
|
16
|
+
* SCALE-HONEST like `SunShadowFit` (the WORK.md cm-scale defect, measured
|
|
17
|
+
* 2026-08-29): the plane used to hardcode 4.8×3.2 m at y = 0.028 m, which
|
|
18
|
+
* SLICES through any object under ~10 cm — a 96 mm mug scene wore the decor
|
|
19
|
+
* plane through its middle. A starter must not encode a scale, so the
|
|
20
|
+
* plane's size and hover height are now derived per frame from how far the
|
|
21
|
+
* camera is from what it orbits, exactly the way the sun's shadow box reads
|
|
22
|
+
* its extents from the view. Frame a mug from 26 cm and the plane is ~11 cm
|
|
23
|
+
* wide floating 0.6 mm off the ground; the shipped meter-scale look is
|
|
24
|
+
* unchanged (factor 1 at the authored camera). Authored `position`/`scale`
|
|
25
|
+
* props are deliberately not honored — the fit overwrites them every frame
|
|
26
|
+
* (the SunShadowFit contract); replace the component to author decor by hand.
|
|
27
|
+
*/
|
|
28
|
+
export function SoftGroundShadow({ name = 'Soft Ground Shadow', ...props }: ThreeElements['mesh']) {
|
|
29
|
+
const mesh = useRef<THREE.Mesh>(null);
|
|
30
|
+
useFrame(({ camera, controls }) => {
|
|
31
|
+
const m = mesh.current;
|
|
32
|
+
if (!m) return;
|
|
33
|
+
const target = (controls as { target?: THREE.Vector3 } | null)?.target;
|
|
34
|
+
const factor = target ? camera.position.distanceTo(target) / STARTER_VIEW_DISTANCE : 1;
|
|
35
|
+
m.scale.set(4.8 * factor, 3.2 * factor, 1);
|
|
36
|
+
m.position.set(-0.55 * factor, 0.028 * factor, -0.48 * factor);
|
|
37
|
+
});
|
|
38
|
+
return (
|
|
39
|
+
<mesh ref={mesh} name={name} rotation={[-Math.PI / 2, 0, -0.18]} {...props}>
|
|
40
|
+
<planeGeometry args={[1, 1]} />
|
|
41
|
+
<shaderMaterial
|
|
42
|
+
transparent
|
|
43
|
+
depthWrite={false}
|
|
44
|
+
vertexShader={`
|
|
45
|
+
varying vec2 vUv;
|
|
46
|
+
void main() {
|
|
47
|
+
vUv = uv;
|
|
48
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
49
|
+
}
|
|
50
|
+
`}
|
|
51
|
+
fragmentShader={`
|
|
52
|
+
varying vec2 vUv;
|
|
53
|
+
void main() {
|
|
54
|
+
vec2 delta = (vUv - 0.5) * 2.0;
|
|
55
|
+
float falloff = 1.0 - smoothstep(0.05, 1.0, dot(delta, delta));
|
|
56
|
+
gl_FragColor = vec4(0.19, 0.26, 0.29, falloff * falloff * 0.19);
|
|
57
|
+
}
|
|
58
|
+
`}
|
|
59
|
+
/>
|
|
60
|
+
</mesh>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { useFrame } from '@react-three/fiber';
|
|
2
|
+
import { fitDirectionalShadowToCamera } from '@volter/threejs-runtime/render/directional-shadow-fit';
|
|
3
|
+
import { type RefObject, useEffect } from 'react';
|
|
4
|
+
import * as THREE from 'three';
|
|
5
|
+
|
|
6
|
+
/** Frame scratch. Read and dropped inside one synchronous callback, so one set serves every instance. */
|
|
7
|
+
const _lightOrientation = new THREE.Quaternion();
|
|
8
|
+
const _parentInverse = new THREE.Matrix4();
|
|
9
|
+
const _authoredAim = new THREE.Vector3();
|
|
10
|
+
const _origin = new THREE.Vector3();
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* How much farther than the framed subject the shadow box reaches. 1.0 would
|
|
14
|
+
* stop the slice exactly at what the camera orbits; this covers the ground the
|
|
15
|
+
* subject's shadow falls on and whatever stands just behind it, and at the
|
|
16
|
+
* authored camera it reproduces the box the starter used to hardcode
|
|
17
|
+
* (`shadow-camera-left/right/top/bottom = ±12`) to within a few percent — the
|
|
18
|
+
* meter-scale look is unchanged by construction.
|
|
19
|
+
*/
|
|
20
|
+
const VIEW_DEPTH_FACTOR = 1.35;
|
|
21
|
+
|
|
22
|
+
/** Shadow-map texels of offset along the surface normal. The standard cure for
|
|
23
|
+
* self-shadow acne on curved casters, and the reason it is derived from the
|
|
24
|
+
* fit rather than authored: a constant would be wrong by exactly the factor
|
|
25
|
+
* the box changed size. */
|
|
26
|
+
const NORMAL_BIAS_TEXELS = 1.5;
|
|
27
|
+
|
|
28
|
+
/** Depth range, as a multiple of the box radius, either side of the light. The
|
|
29
|
+
* fit puts the light AT the box centre, so casters stand on both sides of it
|
|
30
|
+
* and the range is symmetric. */
|
|
31
|
+
const DEPTH_RANGE_FACTOR = 3;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Size the sun's shadow box to WHAT THE CAMERA IS LOOKING AT, so shadows are
|
|
35
|
+
* correct at whatever scale this game turns out to be.
|
|
36
|
+
*
|
|
37
|
+
* THE DEFECT THIS CLOSES (measured 2026-08-29). `DirectionalLightShadow` is an
|
|
38
|
+
* orthographic camera with authored extents, and the starter authored ±12
|
|
39
|
+
* units over a 2048 map — 11.7 mm of world per shadow texel. That is invisible
|
|
40
|
+
* on the 2.55 m focal cube this scene ships with, and ruinous the moment a game
|
|
41
|
+
* is built at another scale: on a 96 mm ceramic mug one texel spans an eighth
|
|
42
|
+
* of the whole object, so the cast shadow disappears into quantization and the
|
|
43
|
+
* glaze wears diagonal acne stripes. No amount of `shadow-bias` fixes it,
|
|
44
|
+
* because the resolution — not the offset — is what is wrong. A starter scene
|
|
45
|
+
* must not encode a scale, and ±12 is a scale.
|
|
46
|
+
*
|
|
47
|
+
* `fitDirectionalShadowToCamera` (engine) supplies the geometry: the bounding
|
|
48
|
+
* sphere of the camera's frustum slice, with the centre quantized to whole
|
|
49
|
+
* shadow texels so a moving camera cannot make shadow edges crawl. Its method
|
|
50
|
+
* is transcribed from `top-down-strategy`'s `CameraFittedShadow`, which fits
|
|
51
|
+
* the same light to a panning camera. What is THIS scene's:
|
|
52
|
+
*
|
|
53
|
+
* - **the view depth is read, not authored.** The strategy scene knows its own
|
|
54
|
+
* map is worth 45 units of shadow; a starter knows nothing about the game
|
|
55
|
+
* that will grow out of it, so the depth comes from how far the camera is
|
|
56
|
+
* from what it orbits ({@link VIEW_DEPTH_FACTOR}). Frame a mug from 26 cm
|
|
57
|
+
* and the texel is a third of a millimetre; frame a hillside from 200 m and
|
|
58
|
+
* it is centimetres. That IS the scale-honesty.
|
|
59
|
+
* - **the depth range and `normalBias` are fitted too.** A range in world
|
|
60
|
+
* units is as much a hardcoded scale as the lateral extents, and
|
|
61
|
+
* `shadow.bias` is normalized against it — so both are derived from the
|
|
62
|
+
* fitted radius, and the light's authored `shadow-bias` keeps its meaning at
|
|
63
|
+
* every scale.
|
|
64
|
+
*
|
|
65
|
+
* The light's authored `position` stays the sun's DIRECTION; this moves the
|
|
66
|
+
* node so the box is centred on the view, and re-anchors the aim onto a target
|
|
67
|
+
* parented to the light so moving it cannot rotate the sun.
|
|
68
|
+
*/
|
|
69
|
+
export function SunShadowFit({
|
|
70
|
+
light,
|
|
71
|
+
}: {
|
|
72
|
+
/** The sun to fit. Its authored transform stays the sun's DIRECTION. */
|
|
73
|
+
light: RefObject<THREE.DirectionalLight | null>;
|
|
74
|
+
}) {
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const sun = light.current;
|
|
77
|
+
if (!sun) return;
|
|
78
|
+
const authoredPosition = sun.position.clone();
|
|
79
|
+
const authoredTarget = sun.target;
|
|
80
|
+
sun.updateWorldMatrix(true, false);
|
|
81
|
+
authoredTarget.updateWorldMatrix(true, false);
|
|
82
|
+
// Aim by a target parented to the light, so moving the light translates
|
|
83
|
+
// both and the direction is unchanged by definition.
|
|
84
|
+
const travellingTarget = new THREE.Object3D();
|
|
85
|
+
travellingTarget.position.copy(
|
|
86
|
+
sun.worldToLocal(_authoredAim.setFromMatrixPosition(authoredTarget.matrixWorld)),
|
|
87
|
+
);
|
|
88
|
+
sun.add(travellingTarget);
|
|
89
|
+
sun.target = travellingTarget;
|
|
90
|
+
return () => {
|
|
91
|
+
sun.remove(travellingTarget);
|
|
92
|
+
sun.target = authoredTarget;
|
|
93
|
+
sun.position.copy(authoredPosition);
|
|
94
|
+
};
|
|
95
|
+
}, [light]);
|
|
96
|
+
|
|
97
|
+
useFrame((state) => {
|
|
98
|
+
const sun = light.current;
|
|
99
|
+
const shadow = sun?.shadow;
|
|
100
|
+
if (!sun || !shadow || sun.parent === null) return;
|
|
101
|
+
const camera = state.camera;
|
|
102
|
+
camera.updateWorldMatrix(true, false);
|
|
103
|
+
sun.updateWorldMatrix(true, false);
|
|
104
|
+
sun.getWorldQuaternion(_lightOrientation);
|
|
105
|
+
|
|
106
|
+
// What the camera is looking at: the default controls' orbit target when
|
|
107
|
+
// there are controls (the starter's OrbitControls declares `makeDefault`),
|
|
108
|
+
// else the world origin — the point a scene with no controls is composed
|
|
109
|
+
// around. Either way it is a POINT IN THE WORLD, so its distance from the
|
|
110
|
+
// camera is in the game's own units and carries the game's own scale.
|
|
111
|
+
const target = (state.controls as unknown as { target?: unknown } | null)?.target;
|
|
112
|
+
const framed = target instanceof THREE.Vector3 ? target : _origin.set(0, 0, 0);
|
|
113
|
+
const viewDepth = camera.position.distanceTo(framed) * VIEW_DEPTH_FACTOR;
|
|
114
|
+
|
|
115
|
+
const fit = fitDirectionalShadowToCamera(
|
|
116
|
+
camera,
|
|
117
|
+
_lightOrientation,
|
|
118
|
+
viewDepth,
|
|
119
|
+
shadow.mapSize.x,
|
|
120
|
+
);
|
|
121
|
+
const box = shadow.camera;
|
|
122
|
+
box.left = -fit.radius;
|
|
123
|
+
box.right = fit.radius;
|
|
124
|
+
box.top = fit.radius;
|
|
125
|
+
box.bottom = -fit.radius;
|
|
126
|
+
// Symmetric, because the light sits at the box centre with casters on both
|
|
127
|
+
// sides of it. Authored `shadow-bias` is a fraction of THIS range, so it
|
|
128
|
+
// stays a fixed fraction of the scene rather than a fixed world distance.
|
|
129
|
+
box.far = fit.radius * DEPTH_RANGE_FACTOR;
|
|
130
|
+
box.near = -box.far;
|
|
131
|
+
box.updateProjectionMatrix();
|
|
132
|
+
shadow.normalBias = fit.texelWorldSize * NORMAL_BIAS_TEXELS;
|
|
133
|
+
// `position` is parent-local; the fitted centre is in world space.
|
|
134
|
+
sun.parent.updateWorldMatrix(true, false);
|
|
135
|
+
sun.position.copy(
|
|
136
|
+
fit.center.applyMatrix4(_parentInverse.copy(sun.parent.matrixWorld).invert()),
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# `src/contributions/` — what this game adds to the editor
|
|
2
|
+
|
|
3
|
+
These files are this game's editor plugin. They are ordinary React/TSX, found
|
|
4
|
+
by filename:
|
|
5
|
+
|
|
6
|
+
- `*.inspector.tsx` — a section on an inspected subject;
|
|
7
|
+
- `*.document.tsx` — a workspace document;
|
|
8
|
+
- `*.utility.tsx` — a compact bottom-drawer instrument;
|
|
9
|
+
- `*.analytics.tsx` — the game-owned body inside the shared Gameplay Session
|
|
10
|
+
shell.
|
|
11
|
+
|
|
12
|
+
There is no registry, command vocabulary, generated form, or prescribed panel
|
|
13
|
+
layout. A contribution exports its `point`, its `title`, and its default React
|
|
14
|
+
component. Write the surface this game's studio would actually use, in the
|
|
15
|
+
game's own vocabulary. Import controls from `@volter/editor-sdk/widgets`; use ordinary
|
|
16
|
+
React and CSS for the rest.
|
|
17
|
+
|
|
18
|
+
A completed contribution is a usable interface: game-specific labels,
|
|
19
|
+
relevant readings and working controls. Raw JSON/object dumps do not fulfill
|
|
20
|
+
the contribution. Verify its actual presentation and controls before removing
|
|
21
|
+
the unfinished-stub warning.
|
|
22
|
+
|
|
23
|
+
## Live game modules
|
|
24
|
+
|
|
25
|
+
A live contribution must read the running mount's own module instances through
|
|
26
|
+
[`use-game-modules.ts`](./use-game-modules.ts). Do not directly import a
|
|
27
|
+
gameplay module from a contribution: the editor and game have different import
|
|
28
|
+
graphs, so that creates a second, phantom copy of module state.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import type { ToolInspectorContributionProps } from '@volter/editor-sdk/contributions';
|
|
32
|
+
import { Button } from '@volter/editor-sdk/widgets';
|
|
33
|
+
import { useGameModules } from './use-game-modules';
|
|
34
|
+
|
|
35
|
+
export const point = 'selection.inspector';
|
|
36
|
+
export const title = 'Cooling QA';
|
|
37
|
+
|
|
38
|
+
export default function CoolingQa({ play }: ToolInspectorContributionProps) {
|
|
39
|
+
const { mods, error } = useGameModules(play, {
|
|
40
|
+
cooling: 'src/sim/cooling.ts',
|
|
41
|
+
});
|
|
42
|
+
const cooling = mods?.cooling as
|
|
43
|
+
| { readCooling?: () => { temperature: number }; setupHeatSpike?: () => void }
|
|
44
|
+
| undefined;
|
|
45
|
+
const state = cooling?.readCooling?.();
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div>
|
|
49
|
+
<div>{error ?? `Temperature: ${state?.temperature ?? '—'}`}</div>
|
|
50
|
+
<Button onClick={() => cooling?.setupHeatSpike?.()}>Set up heat spike</Button>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The module owns the mechanic, readout, and setup function. The contribution is
|
|
57
|
+
only its human face. A coding agent reaches the exact same functions through:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
game.run(async ({ modules }) => {
|
|
61
|
+
const cooling = await modules('src/sim/cooling.ts');
|
|
62
|
+
return cooling.readCooling();
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## The three starter surfaces
|
|
67
|
+
|
|
68
|
+
These three panels arrive with the `studio` addition (`game-editor create <name> --with
|
|
69
|
+
studio`, or `--template full`). NO preset brings them otherwise — nothing a
|
|
70
|
+
project inherits may error, and these three THROW until they are rewritten
|
|
71
|
+
(orchestrator ruling, 2026-09-19). Asking for `studio` is asking for the TODO.
|
|
72
|
+
|
|
73
|
+
- `tester.inspector.tsx` is deliberately unfinished. Rewrite it whole as the
|
|
74
|
+
live QA cockpit for this game: controller ownership, available goals, the
|
|
75
|
+
active goal's intent/step/target/progress/blocker/decision/outcome, start and
|
|
76
|
+
redirect controls, stop/handoff, setup cheats, and the live readings needed
|
|
77
|
+
to judge rare situations. Setup may conjure a situation; the resident tester
|
|
78
|
+
still exercises the mechanic through normal input at simulation speed.
|
|
79
|
+
- `data.document.tsx` is deliberately unfinished. Render the game's typed
|
|
80
|
+
literals from `src/data/` with the derived columns and charts collaborators
|
|
81
|
+
need. Delete the file when the game genuinely has no authored content
|
|
82
|
+
tables.
|
|
83
|
+
- `analytics.analytics.tsx` is deliberately unfinished. The editor owns the durable Gameplay
|
|
84
|
+
Session selector, real-time scrub rail, and optional recording preview. Its
|
|
85
|
+
body receives the selected log and cursor and deliberately receives no live
|
|
86
|
+
`play` object. Replace the stub with analysis of the selected session that
|
|
87
|
+
answers this game's development questions. A raw event listing does not
|
|
88
|
+
fulfill the contribution; never import live simulation state into Analytics.
|
|
89
|
+
|
|
90
|
+
All three stubs emit `VGAI_STUB_UNIMPLEMENTED`. That warning keeps the live
|
|
91
|
+
console red, and `npm run check-idioms` reports it as unfinished work. Remove
|
|
92
|
+
the sentinel only by replacing the stub with the game's real surface (or by
|
|
93
|
+
honestly deleting the optional Data surface), not by silencing the warning.
|
|
94
|
+
|
|
95
|
+
There is no committed autoplay route or QA spec. Playtesting is interactive:
|
|
96
|
+
the developer arranges a situation through exported setup functions, directs
|
|
97
|
+
the resident tester toward a goal, advances sim time, reads the play log and
|
|
98
|
+
visible result, and redirects as needed. `logs/play-*.jsonl` is the receipt.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOT IMPLEMENTED — this game's Analytics contribution.
|
|
3
|
+
*
|
|
4
|
+
* Replace this stub with analysis that answers this game's development
|
|
5
|
+
* questions. Choose its metrics and presentation from the game's needs.
|
|
6
|
+
* A raw event listing does not fulfill this contribution.
|
|
7
|
+
*
|
|
8
|
+
* The editor already supplies the Gameplay Session picker, playback/scrub
|
|
9
|
+
* controls and optional recording preview. Keep those shared facilities;
|
|
10
|
+
* derive this contribution's analysis from the selected session and cursor
|
|
11
|
+
* supplied through gameplaySessions, never from live simulation state.
|
|
12
|
+
*/
|
|
13
|
+
import type { ToolAnalyticsContributionProps } from '@volter/editor-sdk/contributions';
|
|
14
|
+
|
|
15
|
+
export const point = 'workspace.analytics';
|
|
16
|
+
export const title = 'Analytics';
|
|
17
|
+
|
|
18
|
+
const unfinished =
|
|
19
|
+
'VGAI_STUB_UNIMPLEMENTED: src/contributions/analytics.analytics.tsx — replace this stub with game-specific analysis of recorded Gameplay Sessions; playback is provided by the editor.';
|
|
20
|
+
|
|
21
|
+
// biome-ignore lint/suspicious/noConsole: unopened starter obligations remain visible in the editor console
|
|
22
|
+
console.error(unfinished);
|
|
23
|
+
|
|
24
|
+
export default function AnalyticsStub(_props: ToolAnalyticsContributionProps): never {
|
|
25
|
+
throw new Error(unfinished);
|
|
26
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOT IMPLEMENTED — this game's DATA surface.
|
|
3
|
+
*
|
|
4
|
+
* An OBLIGATION, not an implementation: the game's numbers and content
|
|
5
|
+
* tables (`src/data/` — plain typed TS literals) must be viewable, with
|
|
6
|
+
* their derived picture, by the humans collaborating on this game. How is
|
|
7
|
+
* yours. REWRITE THIS FILE WHOLE; the error below holds `vgai console`
|
|
8
|
+
* red until you do.
|
|
9
|
+
*
|
|
10
|
+
* The method: render the data modules as tables (a plain `<table>` until a
|
|
11
|
+
* table earns a grid — then `react-data-grid`) with the DERIVED columns a
|
|
12
|
+
* studio spreadsheet would compute ($/unit, payback, crossover points —
|
|
13
|
+
* plain functions beside the data), and graphs from a common charting
|
|
14
|
+
* library (e.g. Recharts). Import the data modules directly — for inert
|
|
15
|
+
* data that is file truth, which is what a data view shows. The worked
|
|
16
|
+
* reference: datacenter-tycoon's data document.
|
|
17
|
+
*
|
|
18
|
+
* A game with genuinely NO content tables deletes this file — the
|
|
19
|
+
* deletion, visible in git, is the honest declaration.
|
|
20
|
+
*/
|
|
21
|
+
import type { ToolContributionProps } from '@volter/editor-sdk/contributions';
|
|
22
|
+
|
|
23
|
+
export const point = 'workspace.document';
|
|
24
|
+
export const title = 'Data';
|
|
25
|
+
|
|
26
|
+
// Module-scope on purpose — the demand is visible from editor boot.
|
|
27
|
+
const unfinished =
|
|
28
|
+
"VGAI_STUB_UNIMPLEMENTED: src/contributions/data.document.tsx — render this game's data (src/data/) with its derived columns, or delete this file if the game truly has no content tables (its header says how).";
|
|
29
|
+
|
|
30
|
+
// biome-ignore lint/suspicious/noConsole: unopened starter obligations remain visible in the editor console
|
|
31
|
+
console.error(unfinished);
|
|
32
|
+
|
|
33
|
+
export default function DataStub(_props: ToolContributionProps): never {
|
|
34
|
+
throw new Error(unfinished);
|
|
35
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `pagesFromUiModules` FINDER (ARCHITECTURE-CORE §The project model,
|
|
3
|
+
* "Documents, not scenes"): every project module under the selection's
|
|
4
|
+
* `include` globs that exports a React component is a `page` document —
|
|
5
|
+
* what a website is made of, the way a game is made of scenes. Select it
|
|
6
|
+
* in `vgai.adapter.ts`:
|
|
7
|
+
*
|
|
8
|
+
* documents: { find: [{ finder: 'pagesFromUiModules', include: ['src/ui/**\/*page.tsx'] }] }
|
|
9
|
+
*
|
|
10
|
+
* The glob IS the page rule: a project names its pages by where it keeps
|
|
11
|
+
* them. This module is a plain object the HOST registers; it mounts no UI
|
|
12
|
+
* and reads the project only through `input.sources`.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
|
|
16
|
+
const COMPONENT_EXPORT =
|
|
17
|
+
/export\s+(?:default\s+)?(?:function\s+[A-Z]\w*\s*\(|const\s+[A-Z]\w*\s*[:=])/;
|
|
18
|
+
|
|
19
|
+
export const finder = {
|
|
20
|
+
name: 'pagesFromUiModules',
|
|
21
|
+
schema: z
|
|
22
|
+
.object({
|
|
23
|
+
finder: z.literal('pagesFromUiModules'),
|
|
24
|
+
include: z
|
|
25
|
+
.array(z.string().min(1))
|
|
26
|
+
.min(1)
|
|
27
|
+
.describe('Project-relative globs of the page modules (`src/ui/**/*page.tsx`)'),
|
|
28
|
+
})
|
|
29
|
+
.strict(),
|
|
30
|
+
run(
|
|
31
|
+
_selection: { finder: 'pagesFromUiModules'; include: readonly string[] },
|
|
32
|
+
input: { sources?: readonly { path: string; source: string }[] },
|
|
33
|
+
) {
|
|
34
|
+
const entries = [];
|
|
35
|
+
const notes: string[] = [];
|
|
36
|
+
for (const file of input.sources ?? []) {
|
|
37
|
+
if (!COMPONENT_EXPORT.test(file.source)) {
|
|
38
|
+
notes.push(`${file.path}: exports no component — not a page`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const name = (file.path.split('/').pop() ?? file.path)
|
|
42
|
+
.replace(/\.[cm]?[jt]sx?$/, '')
|
|
43
|
+
.replace(/[-_.]?page$/i, '');
|
|
44
|
+
entries.push({
|
|
45
|
+
id: `page:${file.path}`,
|
|
46
|
+
label: name || 'page',
|
|
47
|
+
kind: 'page',
|
|
48
|
+
region: null,
|
|
49
|
+
authorable: true,
|
|
50
|
+
reach: { kind: 'root-mount' as const },
|
|
51
|
+
source: { path: file.path },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
entries,
|
|
56
|
+
notes,
|
|
57
|
+
// One page is the page; two is a choice the site's author states.
|
|
58
|
+
...(entries.length === 1 ? { default: entries[0]!.id } : {}),
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
} as const;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOT IMPLEMENTED — this game's TESTER surface.
|
|
3
|
+
*
|
|
4
|
+
* This stub is an OBLIGATION, not an implementation. It claims WHAT this
|
|
5
|
+
* game must make available: a live QA cockpit that helps a human or AI tester
|
|
6
|
+
* direct the resident tester, understand its goals and decisions, arrange
|
|
7
|
+
* difficult situations, and judge the mechanic under test. It says nothing
|
|
8
|
+
* about HOW. REWRITE THIS FILE WHOLE in the game's own vocabulary: rename it,
|
|
9
|
+
* split it into several faces, and structure it the way THIS game's studio
|
|
10
|
+
* would. The error below holds `vgai console` red until you do; delete it
|
|
11
|
+
* with the stub.
|
|
12
|
+
*
|
|
13
|
+
* Make the controller's current owner and the tester's repertoire legible.
|
|
14
|
+
* While a goal runs, expose enough of its mind to explain its intent, current
|
|
15
|
+
* step and target, progress, blockers, latest observation or decision, and
|
|
16
|
+
* outcome. Give the operator clear ways to start, direct, redirect, stop, and
|
|
17
|
+
* hand off the tester. A control's outcome or refusal must be visible,
|
|
18
|
+
* including a goal that completes before the next paint.
|
|
19
|
+
* Present these as readable game-specific labels, readings and controls.
|
|
20
|
+
* A raw JSON/object dump does not fulfill this contribution; keep the
|
|
21
|
+
* unfinished error until the actual interface meets this requirement.
|
|
22
|
+
*
|
|
23
|
+
* Put setup cheats here when honest play would make a QA situation costly or
|
|
24
|
+
* rare, together with the exact live readings needed to judge it. A cheat may
|
|
25
|
+
* establish the situation; the tester still exercises the behavior under
|
|
26
|
+
* judgment through the game's normal input path at simulation speed.
|
|
27
|
+
* Historical metrics belong in Analytics, and authored content or tuning
|
|
28
|
+
* belongs in Data.
|
|
29
|
+
*
|
|
30
|
+
* Read the RUNNING game's own modules through `useGameModules`
|
|
31
|
+
* (`./use-game-modules` — a direct import from a contribution is a phantom
|
|
32
|
+
* second copy); hand-type the slice of each module you read. Human controls
|
|
33
|
+
* call the same ordinary exported functions an agent reaches through
|
|
34
|
+
* `game.run(({ modules }) => ...)`. The worked reference is the
|
|
35
|
+
* datacenter-tycoon game's `src/tools/`.
|
|
36
|
+
*/
|
|
37
|
+
import type {
|
|
38
|
+
ToolContributionNode,
|
|
39
|
+
ToolInspectorContributionMatchContext,
|
|
40
|
+
ToolInspectorContributionProps,
|
|
41
|
+
} from '@volter/editor-sdk/contributions';
|
|
42
|
+
|
|
43
|
+
export const point = 'selection.inspector';
|
|
44
|
+
export const title = 'Tester';
|
|
45
|
+
|
|
46
|
+
export function match(
|
|
47
|
+
node: ToolContributionNode | null,
|
|
48
|
+
_adapter: unknown,
|
|
49
|
+
context?: ToolInspectorContributionMatchContext,
|
|
50
|
+
): boolean {
|
|
51
|
+
return node === null && context?.nullSubjectId === 'game';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Module-scope on purpose: fires the moment the editor loads this game's
|
|
55
|
+
// contributions, so the demand is visible before anyone opens the panel.
|
|
56
|
+
const unfinished =
|
|
57
|
+
"VGAI_STUB_UNIMPLEMENTED: src/contributions/tester.inspector.tsx — imagine this game's tester helper surface and rewrite the file whole (its header says how).";
|
|
58
|
+
|
|
59
|
+
// biome-ignore lint/suspicious/noConsole: unopened starter obligations remain visible in the editor console
|
|
60
|
+
console.error(unfinished);
|
|
61
|
+
|
|
62
|
+
export default function TesterInspectorStub(_props: ToolInspectorContributionProps): never {
|
|
63
|
+
throw new Error(unfinished);
|
|
64
|
+
}
|