@vgai/editor 0.2.0 → 0.4.0-canary.20260715.0
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/README.md +24 -0
- package/dist/assets/axe-C7YBtOuM.js +30 -0
- package/dist/assets/browserAll-DDtGGE48.js +1 -0
- package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
- package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
- package/dist/assets/game-BdTHR2_X.js +1 -0
- package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
- package/dist/assets/game-CcHfYxjP.js +1 -0
- package/dist/assets/game-Cqzj_lpD.js +1 -0
- package/dist/assets/game-DSZdeCHu.js +1 -0
- package/dist/assets/game-Dch9sAPc.js +1 -0
- package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
- package/dist/assets/game-loop-DMIgSMV-.js +1 -0
- package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
- package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
- package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
- package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
- package/dist/assets/index-CQEfi217.js +15412 -0
- package/dist/assets/index-Dvi-V0NE.css +1 -0
- package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
- package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
- package/dist/assets/react-18-C9eHn8x1.js +1 -0
- package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
- package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
- package/dist/index.html +15 -13
- package/dist/ingest/racing-game/vgai.game.json +5 -4
- package/dist/ingest/simcity/vgai.game.json +5 -4
- package/dist/ingest/tanks/vgai.game.json +5 -4
- package/dist/project-scripts.bundle.js +3917 -0
- package/dist/scenes/untitled.vscn.json +2 -0
- package/dist-server/packaged.mjs +7697 -3435
- package/package.json +31 -4
- package/scripts/probe-reporter.ts +349 -0
- package/scripts/run-probe.ts +2260 -0
- package/server/asset-catalog-audit.ts +268 -0
- package/server/asset-catalog-v2.ts +146 -0
- package/server/asset-library-routes.ts +276 -58
- package/server/canonical-path.ts +1 -1
- package/server/dev.ts +148 -44
- package/server/editor-server.ts +888 -61
- package/server/editor-sse.ts +115 -4
- package/server/harness-chat-service.ts +796 -0
- package/server/local-asset-catalog.ts +157 -22
- package/server/packaged.ts +51 -21
- package/server/process-shutdown.ts +136 -0
- package/server/prod.ts +9 -6
- package/server/project-hmr-files.ts +41 -0
- package/server/project-operations.ts +343 -0
- package/server/project-optimize-deps-entries.ts +4 -4
- package/server/project-output-writer.ts +156 -0
- package/server/project-validation.ts +140 -0
- package/server/project-view.ts +8 -50
- package/server/server-utils.ts +75 -10
- package/server/session-registry.ts +12 -0
- package/src/EditorContext.tsx +107 -3
- package/src/action-registry.ts +115 -17
- package/src/adapter-resolver.ts +213 -478
- package/src/asset-events.ts +64 -1
- package/src/asset-preview.ts +906 -0
- package/src/asset-selection.ts +121 -0
- package/src/asset-workflow/asset-capabilities.ts +259 -0
- package/src/asset-workflow/asset-editor-errors.ts +46 -0
- package/src/asset-workflow/asset-import-pipeline.ts +176 -0
- package/src/asset-workflow/asset-library-query.ts +107 -0
- package/src/asset-workflow/asset-types.ts +192 -0
- package/src/asset-workflow/asset-workflow-quality.ts +65 -0
- package/src/asset-workflow/import-contract.ts +113 -0
- package/src/asset-workflow/model-conversion.ts +126 -0
- package/src/asset-workflow/model-inspection.ts +185 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +153 -0
- package/src/asset-workflow/project-asset-operations.ts +119 -0
- package/src/asset-workflow/thumbnail-system.ts +172 -0
- package/src/authoring/active-systems.ts +15 -0
- package/src/authoring/boundary-authoring-adapter.ts +16 -5
- package/src/authoring/composite-authoring-adapter.ts +305 -124
- package/src/authoring/design-time-layers.ts +300 -117
- package/src/authoring/edit-mode-authoring.ts +278 -293
- package/src/authoring/embed-only-adapter.ts +4 -2
- package/src/authoring/first-party-hierarchy-menu.ts +7 -2
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
- package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
- package/src/authoring/first-party-inspector/register.tsx +13 -2
- package/src/authoring/ingest-authoring-adapter.ts +142 -45
- package/src/authoring/mount-failure-report.ts +5 -5
- package/src/authoring/provenance.ts +41 -0
- package/src/authoring/react-dom-authoring-adapter.ts +92 -92
- package/src/authoring/react-inspector-section.tsx +489 -51
- package/src/authoring/react-world-authoring-adapter.ts +541 -306
- package/src/authoring/story-overlay.ts +1 -1
- package/src/authoring/story-types.ts +11 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
- package/src/authoring/viewport-tool-context.ts +78 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +186 -0
- package/src/authoring/world-pan-state.ts +33 -17
- package/src/authoring/world-session-state.ts +1 -1
- package/src/authoring/world2d-authoring-adapter.ts +109 -52
- package/src/availability-tick.ts +56 -0
- package/src/browser-play-entry.ts +5 -5
- package/src/browser-project-scripts.ts +1 -0
- package/src/build-identity.ts +15 -0
- package/src/command-listener.ts +893 -19
- package/src/components/AlignToolbar.tsx +74 -63
- package/src/components/AppRoot.tsx +193 -26
- package/src/components/ApplicationMenus.tsx +272 -0
- package/src/components/AssetBrowser.tsx +1450 -293
- package/src/components/AssetEditorShell.tsx +141 -0
- package/src/components/AssetImportDetails.tsx +218 -0
- package/src/components/AssetLibraryPanel.tsx +14 -0
- package/src/components/CameraInfo.tsx +11 -20
- package/src/components/CenterDocuments.tsx +585 -0
- package/src/components/CommandPalette.tsx +75 -30
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +57 -112
- package/src/components/DebugConsolePanel.tsx +461 -0
- package/src/components/DebuggerPanel.tsx +165 -0
- package/src/components/DefaultEditorLayout.tsx +167 -231
- package/src/components/GameHierarchy.tsx +873 -290
- package/src/components/GamePerformanceOverlay.tsx +46 -0
- package/src/components/HarnessChatPanel.tsx +2352 -0
- package/src/components/HistoryPanel.tsx +226 -0
- package/src/components/Inspector.tsx +153 -99
- package/src/components/InspectorToolSection.tsx +6 -4
- package/src/components/MountFailureBanner.tsx +31 -48
- package/src/components/NetworkSection.tsx +25 -14
- package/src/components/OnlineAssetBrowser.tsx +794 -343
- package/src/components/OverlayReportBanner.tsx +38 -64
- package/src/components/PerformancePanel.tsx +206 -0
- package/src/components/PlayBar.tsx +93 -263
- package/src/components/PrefabSaveDialog.tsx +55 -127
- package/src/components/ProjectHeader.css +60 -0
- package/src/components/ProjectHeader.tsx +170 -105
- package/src/components/ProjectScreen.tsx +246 -184
- package/src/components/ReactCanvasControls.tsx +185 -0
- package/src/components/ResolutionPicker.tsx +85 -0
- package/src/components/RootActivateDialog.tsx +39 -68
- package/src/components/SaveDialog.tsx +55 -127
- package/src/components/SaveStatus.tsx +11 -29
- package/src/components/StartupLoadingScreen.tsx +96 -0
- package/src/components/StateWatchPanel.tsx +302 -0
- package/src/components/StatsOverlay.tsx +12 -5
- package/src/components/StatusBar.tsx +64 -0
- package/src/components/ThemeManagerDialog.css +89 -0
- package/src/components/ThemeManagerDialog.tsx +371 -0
- package/src/components/ToolHost.tsx +26 -15
- package/src/components/Toolbar.tsx +117 -214
- package/src/components/VgaiVoxelLogo.tsx +89 -0
- package/src/components/ViewportOverlay.tsx +97 -172
- package/src/components/ViewportPanel.tsx +130 -31
- package/src/components/WorkspaceDock.tsx +891 -0
- package/src/components/WorldSelectionOverlay.tsx +51 -63
- package/src/components/WorldTextEditor.tsx +9 -5
- package/src/components/asset-documents.tsx +390 -0
- package/src/components/asset-editor-persistence.ts +44 -0
- package/src/components/asset-selection-section.tsx +338 -0
- package/src/components/asset-viewers/AudioViewer.tsx +73 -21
- package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
- package/src/components/asset-viewers/ImageViewer.tsx +43 -11
- package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
- package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
- package/src/components/asset-viewers/ModelViewer.tsx +805 -121
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
- package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
- package/src/components/asset-workflow.css +506 -0
- package/src/components/build-documents.tsx +696 -0
- package/src/components/core-utilities.tsx +75 -0
- package/src/components/data-documents.tsx +364 -0
- package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
- package/src/components/debugger-panel-state.ts +57 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
- package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
- package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
- package/src/components/inspector-widgets/FontPicker.tsx +13 -21
- package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
- package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
- package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
- package/src/components/inspector-widgets/shared.tsx +90 -49
- package/src/components/inspectors/AnimationSection.tsx +39 -40
- package/src/components/inspectors/AudioSection.tsx +28 -39
- package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
- package/src/components/inspectors/CameraSection.tsx +14 -23
- package/src/components/inspectors/ComponentsSection.tsx +39 -43
- package/src/components/inspectors/JointsSection.tsx +34 -43
- package/src/components/inspectors/LightSection.tsx +90 -35
- package/src/components/inspectors/MaterialSection.tsx +137 -174
- package/src/components/inspectors/MeshSection.tsx +9 -17
- package/src/components/inspectors/NavigationSection.tsx +8 -15
- package/src/components/inspectors/ParticleSection.tsx +91 -76
- package/src/components/inspectors/PhysicsSection.tsx +42 -46
- package/src/components/inspectors/PostProcessingSection.tsx +28 -36
- package/src/components/inspectors/RenderingSection.tsx +12 -20
- package/src/components/inspectors/ShadowSection.tsx +7 -8
- package/src/components/inspectors/SplineSection.tsx +31 -42
- package/src/components/inspectors/TransformSection.tsx +14 -22
- package/src/components/patterns/Dialog.tsx +95 -0
- package/src/components/patterns/Fields.tsx +44 -0
- package/src/components/patterns/List.tsx +25 -0
- package/src/components/patterns/StateSurface.tsx +40 -0
- package/src/components/patterns/Surfaces.tsx +115 -0
- package/src/components/patterns/Tabs.tsx +80 -0
- package/src/components/patterns/Toolbar.tsx +51 -0
- package/src/components/patterns/Tree.tsx +72 -0
- package/src/components/primitives/Button.tsx +46 -0
- package/src/components/primitives/ColorInput.tsx +11 -47
- package/src/components/primitives/EditorIcon.tsx +99 -0
- package/src/components/primitives/FormControls.tsx +71 -0
- package/src/components/primitives/JsonInput.tsx +15 -2
- package/src/components/primitives/Layout.tsx +100 -0
- package/src/components/primitives/Menu.tsx +105 -0
- package/src/components/primitives/NumberInput.tsx +8 -35
- package/src/components/primitives/Panel.tsx +49 -44
- package/src/components/primitives/SectionHeader.tsx +10 -28
- package/src/components/primitives/Text.tsx +46 -0
- package/src/components/primitives/Tooltip.tsx +20 -12
- package/src/components/primitives/Vec3Input.tsx +3 -0
- package/src/components/primitives/banner-tones.ts +33 -0
- package/src/components/primitives/editor-icons.ts +102 -0
- package/src/components/primitives/panel-header-styles.ts +30 -0
- package/src/components/project-operation-documents.tsx +226 -0
- package/src/components/status-contributions.tsx +175 -0
- package/src/components/story-documents-register.ts +15 -0
- package/src/components/story-documents.tsx +1185 -0
- package/src/components/tool-documents.tsx +110 -0
- package/src/components/workspace-dock.css +293 -0
- package/src/components/workspace-history.ts +33 -0
- package/src/components/world-documents.tsx +145 -0
- package/src/components/xstate-documents.tsx +209 -0
- package/src/composite-screenshot.ts +248 -0
- package/src/design-system/index.ts +70 -0
- package/src/design-system-stories/Foundation.stories.tsx +183 -0
- package/src/design-system-stories/Patterns.stories.tsx +251 -0
- package/src/design-system-stories/Workspace.stories.tsx +538 -0
- package/src/doctor/report.ts +57 -13
- package/src/editor-api.ts +295 -31
- package/src/editor-compatibility.ts +200 -0
- package/src/editor-console.ts +35 -17
- package/src/editor-hotkeys.ts +85 -33
- package/src/editor-store.ts +538 -233
- package/src/editor-viewport.ts +160 -34
- package/src/entity-factory.ts +14 -3
- package/src/gizmo-registry.ts +21 -5
- package/src/harness-chat-editor-context.ts +37 -0
- package/src/harness-chat-indicator.ts +68 -0
- package/src/harness-chat-layout.ts +53 -0
- package/src/harness-chat-lifecycle.ts +170 -0
- package/src/harness-chat-reconnect.ts +85 -0
- package/src/harness-chat-types.ts +409 -0
- package/src/hierarchy-drop.ts +50 -0
- package/src/hierarchy-expansion-state.ts +100 -0
- package/src/hierarchy-menu-registry.ts +1 -1
- package/src/hierarchy-projection.ts +76 -0
- package/src/history/editor-session.ts +21 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-service.ts +904 -0
- package/src/history/json-history-resource.ts +165 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +266 -0
- package/src/history/project-root-history-backends.ts +53 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +108 -0
- package/src/history/source-history-backend.ts +374 -0
- package/src/history/types.ts +100 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hosted-example.ts +12 -2
- package/src/hotkeys.ts +89 -18
- package/src/ingest/discovery-react.ts +9 -10
- package/src/ingest/discovery.ts +4 -4
- package/src/ingest/discovery2d.ts +5 -5
- package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
- package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
- package/src/ingest/games/games-fps/vgai.game.json +3 -3
- package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
- package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
- package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
- package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
- package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
- package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
- package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
- package/src/ingest/types.ts +1 -1
- package/src/ingest-mode.ts +47 -52
- package/src/ingest-siblings.ts +23 -33
- package/src/initial-scene.ts +1 -2
- package/src/main.tsx +16 -8
- package/src/manifest-project.ts +10 -12
- package/src/model-thumbnail.ts +261 -26
- package/src/module-mode.ts +44 -50
- package/src/play-log-events.ts +26 -0
- package/src/play-mode.ts +495 -401
- package/src/play-scene-adoption.ts +23 -0
- package/src/playground/main.ts +68 -24
- package/src/playwright-shim.ts +473 -0
- package/src/project-manager.ts +90 -10
- package/src/project-operations.ts +112 -0
- package/src/project-story-discovery.ts +25 -0
- package/src/project-tool-discovery.ts +43 -0
- package/src/scene-serializer.ts +0 -6
- package/src/scene-sync.ts +7 -2
- package/src/script-loader.ts +3 -3
- package/src/skeleton-helper.ts +57 -0
- package/src/storage/seed.ts +68 -8
- package/src/stories/StoryPreviewMount.tsx +265 -0
- package/src/stories/action-stories.fixture.tsx +44 -0
- package/src/stories/button-stories.fixture.tsx +50 -0
- package/src/stories/compose-project-stories.ts +182 -0
- package/src/stories/loader-stories.fixture.tsx +53 -0
- package/src/stories/story-discovery.ts +130 -0
- package/src/stories/story-registry.ts +146 -0
- package/src/theme-css.ts +1049 -0
- package/src/theme-library.ts +238 -0
- package/src/theme-preference.ts +130 -0
- package/src/theme.ts +527 -0
- package/src/tool-loader.ts +80 -24
- package/src/ui-source/inspect.ts +27 -4
- package/src/ui-source/source-write-backend.ts +83 -22
- package/src/widgets/index.ts +9 -18
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-dock-controller.ts +64 -0
- package/src/workspace-document-ids.ts +5 -0
- package/src/workspace-document-registry.ts +367 -0
- package/src/workspace-state-persistence.ts +455 -0
- package/src/workspace-status-registry.ts +110 -0
- package/src/workspace-utility-commands.ts +49 -0
- package/src/workspace-utility-registry.ts +161 -0
- package/src/world-document-routing.ts +16 -0
- package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
- package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
- package/src/xstate-inspect/use-live-actor-state.ts +39 -0
- package/src/xstate-inspect/xstate-graph.ts +265 -0
- package/src/xstate-inspect/xstate-layout.ts +76 -0
- package/src/z-index.ts +26 -0
- package/template/.claude/skills/editor/SKILL.md +129 -90
- package/template/AGENTS.md +1110 -0
- package/template/CLAUDE.md +1 -512
- package/template/IDIOMS.md +50 -0
- package/template/check-idioms.ts +706 -0
- package/template/manifest-entry-modules-plugin.ts +53 -0
- package/template/package.json +13 -4
- package/template/public/scenes/default.scn2d.json +6 -0
- package/template/public/scenes/default.vscn.json +7 -1
- package/template/public/scenes/untitled.vscn.json +10 -0
- package/template/scripts/playtest.ts +40 -0
- package/template/server/loopback.ts +75 -0
- package/template/server/rooms/arena-room.ts +69 -1
- package/template/server/rooms/game-room.ts +68 -1
- package/template/src/data/README.md +9 -4
- package/template/src/data/data-ref.ts +35 -0
- package/template/src/data/tuning.schema.ts +1 -1
- package/template/src/main.ts +41 -62
- package/template/src/manifest-entry-modules.d.ts +3 -0
- package/template/src/operations/README.md +88 -0
- package/template/src/runtime/pixi-adapter.ts +24 -0
- package/template/src/scripts/components/data-spinner.ts +43 -2
- package/template/src/scripts/components/spin-lap-math.ts +27 -0
- package/template/src/tools/README.md +5 -3
- package/template/src/tools/example.tool.tsx +13 -7
- package/template/src/ui/Button.stories.tsx +66 -0
- package/template/src/ui/RebindPanel.tsx +2 -6
- package/template/src/ui/game.tsx +17 -0
- package/template/tests/acceptance/example.spec.ts +64 -0
- package/template/tests/logic/example.test.ts +31 -0
- package/template/tests/logic/room.test.ts +100 -0
- package/template/tests/tsconfig.json +30 -0
- package/template/validate-manifest.ts +5 -5
- package/template/validate-scenes.ts +50 -18
- package/template/vgai.game.json +20 -13
- package/template/vite.config.ts +77 -16
- package/vite-plugin-ui-oid.ts +261 -17
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
- package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
- package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
- package/dist/assets/browserAll-CEkWYlFk.js +0 -1
- package/dist/assets/create-runtime-DYIWr3va.js +0 -1
- package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
- package/dist/assets/game-8SDZPPgH.js +0 -1
- package/dist/assets/game-CevorxyV.js +0 -1
- package/dist/assets/game-Di7XlywD.js +0 -1
- package/dist/assets/game-DjnCaw8R.js +0 -1
- package/dist/assets/game-Q9A0aXSV.js +0 -1
- package/dist/assets/index-CPVV6pjw.js +0 -1
- package/dist/assets/index-CpOnYyeD.js +0 -213
- package/dist/assets/index-Dr8H_6Rl.js +0 -1
- package/dist/assets/index-_bCaipUk.js +0 -13650
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
- package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
- package/dist/assets/scene-query-BivAHhJu.js +0 -1
- package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
- package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
- package/src/authoring/scene-ui-layer.ts +0 -485
- package/src/authoring/ui-authoring-adapter.ts +0 -325
- package/src/authoring/ui-hierarchy-menu.ts +0 -40
- package/src/authoring/ui-inspector-sections.tsx +0 -156
- package/src/authoring/undo-timeline.ts +0 -145
- package/src/components/BottomPanel.tsx +0 -326
- package/src/components/BuildPanel.tsx +0 -455
- package/src/components/FolderTree.tsx +0 -179
- package/src/components/RightPanel.tsx +0 -166
- package/src/components/WorldContextMenu.tsx +0 -257
- package/src/components/asset-viewers/AssetViewer.tsx +0 -38
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
- package/src/scene-ui-mode/active-scene-ui.ts +0 -58
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
- package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
- package/src/ui-editor/inspector.tsx +0 -563
- package/src/ui-editor/node-ops.ts +0 -266
- package/src/ui-editor/overlay.tsx +0 -380
- package/src/ui-editor/palette.tsx +0 -114
- package/src/ui-editor/react-store.ts +0 -78
- package/src/ui-editor/timeline-panel.tsx +0 -443
- package/src/ui-editor/ui-edit-store.ts +0 -552
- package/src/ui-editor/ui-prefab.ts +0 -95
- package/template/project.json +0 -9
- package/template/src/scripts/main.ts +0 -94
- package/template/src/ui/DefaultHud.tsx +0 -40
- package/template/src/ui/game-state.tsx +0 -37
- package/template/src/ui/mount-default-hud.tsx +0 -19
- package/template/src/ui/mount-ui.ts +0 -15
- package/vite-plugin-react-world-provider.ts +0 -81
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L1-equivalent for multiplayer (`docs/ACCEPTANCE-DRIVER-SPEC.md` §2.3's
|
|
3
|
+
* "Multiplayer lane", Acceptance Driver build plan Task 4.4): boots the
|
|
4
|
+
* shipped `server/loopback.ts` harness in-process (the REAL `startColyseus`
|
|
5
|
+
* bootstrap + shipped `GameRoom`, on an ephemeral port — no mocks) and
|
|
6
|
+
* round-trips ONE message: the `__vgai:debugCommand` handler
|
|
7
|
+
* (`server/rooms/game-room.ts`), gated open via the `allowDebugCommands` room
|
|
8
|
+
* option, with a real `@colyseus/sdk` client.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Client, type Room } from '@colyseus/sdk';
|
|
12
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
13
|
+
import { type LoopbackColyseus, startLoopbackColyseus } from '../../server/loopback.js';
|
|
14
|
+
|
|
15
|
+
function withTimeout<T>(promise: Promise<T>, ms: number, label: string): Promise<T> {
|
|
16
|
+
return Promise.race([
|
|
17
|
+
promise,
|
|
18
|
+
new Promise<T>((_, reject) => {
|
|
19
|
+
setTimeout(() => reject(new Error(`timed out after ${ms}ms waiting for: ${label}`)), ms);
|
|
20
|
+
}),
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('game_room debugCommand round-trip over a loopback Colyseus server (no mocks)', () => {
|
|
25
|
+
let server: LoopbackColyseus | null = null;
|
|
26
|
+
let room: Room | null = null;
|
|
27
|
+
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
await room?.leave().catch(() => {});
|
|
30
|
+
room = null;
|
|
31
|
+
server?.stop();
|
|
32
|
+
server = null;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('give-score mutates authoritative state and replies via __vgai:debugCommandResult', async () => {
|
|
36
|
+
server = await startLoopbackColyseus();
|
|
37
|
+
const client = new Client(server.url);
|
|
38
|
+
|
|
39
|
+
// The room option this room's onCreate reads (server/rooms/game-room.ts)
|
|
40
|
+
// — off by default, exactly what `vgai probe`/this harness opts into.
|
|
41
|
+
room = await client.joinOrCreate('game_room', { allowDebugCommands: true });
|
|
42
|
+
|
|
43
|
+
const resultPromise = new Promise<{ requestId: string; ok: boolean; result?: unknown }>(
|
|
44
|
+
(resolve) => {
|
|
45
|
+
room!.onMessage('__vgai:debugCommandResult', (payload: unknown) => {
|
|
46
|
+
resolve(payload as { requestId: string; ok: boolean; result?: unknown });
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
room.send('__vgai:debugCommand', { name: 'give-score', args: [5], requestId: 'req-1' });
|
|
52
|
+
|
|
53
|
+
const reply = await withTimeout(resultPromise, 5000, '__vgai:debugCommandResult');
|
|
54
|
+
expect(reply.requestId).toBe('req-1');
|
|
55
|
+
expect(reply.ok).toBe(true);
|
|
56
|
+
expect(reply.result).toEqual({ score: 5 });
|
|
57
|
+
}, 15000);
|
|
58
|
+
|
|
59
|
+
// AC-A3.2's refusal half (Acceptance Driver build plan Appendix B, D18's
|
|
60
|
+
// "off otherwise" server-side gate): a plain `npm run server` boot — no
|
|
61
|
+
// `allowDebugCommands` room option AND no `VGAI_ALLOW_DEBUG_COMMANDS` env
|
|
62
|
+
// var — must refuse `__vgai:debugCommand` rather than silently execute it.
|
|
63
|
+
it('refuses __vgai:debugCommand when booted without allowDebugCommands or the env var', async () => {
|
|
64
|
+
// Defensive: this room's `onCreate` also honors the env var (frozen
|
|
65
|
+
// decision: env-var OR room-option) — guard against it leaking in from
|
|
66
|
+
// whatever booted this test process, so the refusal path is actually
|
|
67
|
+
// exercised rather than accidentally skipped.
|
|
68
|
+
const previousEnv = process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
|
|
69
|
+
delete process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
|
|
70
|
+
try {
|
|
71
|
+
server = await startLoopbackColyseus();
|
|
72
|
+
const client = new Client(server.url);
|
|
73
|
+
|
|
74
|
+
// No `allowDebugCommands` option at all — the default a plain `npm run
|
|
75
|
+
// server` boot gets.
|
|
76
|
+
room = await client.joinOrCreate('game_room', {});
|
|
77
|
+
|
|
78
|
+
const resultPromise = new Promise<{ requestId: string; ok: boolean; error?: unknown }>(
|
|
79
|
+
(resolve) => {
|
|
80
|
+
room!.onMessage('__vgai:debugCommandResult', (payload: unknown) => {
|
|
81
|
+
resolve(payload as { requestId: string; ok: boolean; error?: unknown });
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
room.send('__vgai:debugCommand', { name: 'give-score', args: [5], requestId: 'req-2' });
|
|
87
|
+
|
|
88
|
+
const reply = await withTimeout(resultPromise, 5000, '__vgai:debugCommandResult');
|
|
89
|
+
expect(reply.requestId).toBe('req-2');
|
|
90
|
+
expect(reply.ok).toBe(false);
|
|
91
|
+
expect(reply.error).toBe('debug commands disabled');
|
|
92
|
+
} finally {
|
|
93
|
+
if (previousEnv === undefined) {
|
|
94
|
+
delete process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
|
|
95
|
+
} else {
|
|
96
|
+
process.env['VGAI_ALLOW_DEBUG_COMMANDS'] = previousEnv;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}, 15000);
|
|
100
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM"],
|
|
7
|
+
// `tests/logic/room.test.ts` (Task 4.4) relatively imports `../../server/
|
|
8
|
+
// loopback.ts`, which transitively pulls in `server/rooms/*.ts` — those
|
|
9
|
+
// use `@colyseus/schema`'s `@type(...)` property decorators, which only
|
|
10
|
+
// type-check under the legacy decorators calling convention (matches
|
|
11
|
+
// `server/tsconfig.json`'s own flags).
|
|
12
|
+
"experimentalDecorators": true,
|
|
13
|
+
"useDefineForClassFields": false,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUncheckedIndexedAccess": true,
|
|
16
|
+
"noFallthroughCasesInSwitch": true,
|
|
17
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
18
|
+
"exactOptionalPropertyTypes": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"verbatimModuleSyntax": true,
|
|
22
|
+
"esModuleInterop": true,
|
|
23
|
+
"forceConsistentCasingInFileNames": true,
|
|
24
|
+
"resolveJsonModule": true,
|
|
25
|
+
"isolatedModules": true,
|
|
26
|
+
"skipLibCheck": true,
|
|
27
|
+
"noEmit": true
|
|
28
|
+
},
|
|
29
|
+
"include": ["./**/*.ts"]
|
|
30
|
+
}
|
|
@@ -10,7 +10,7 @@ import { loadGameManifestFile } from '@vgai/engine/manifest/load-file';
|
|
|
10
10
|
// gets a working `npm run validate-manifest`. Validates each given
|
|
11
11
|
// `vgai.game.json` path via `loadGameManifestFile` (parse -> cross-field
|
|
12
12
|
// checks -> resolution, see docs/GAME-MANIFEST-DESIGN.md §5) and prints the
|
|
13
|
-
// resolved
|
|
13
|
+
// resolved adapter-root list (id, adapter identity, per-context
|
|
14
14
|
// capability tiers) on success. Any failure prints a descriptive error and
|
|
15
15
|
// exits 1.
|
|
16
16
|
//
|
|
@@ -32,13 +32,13 @@ for (const manifestPath of manifestPaths) {
|
|
|
32
32
|
console.log(
|
|
33
33
|
`${manifestPath}: OK — "${resolved.name}" v${resolved.version} (engine ${resolved.engine.version})`,
|
|
34
34
|
);
|
|
35
|
-
for (const
|
|
36
|
-
const { adapter } =
|
|
35
|
+
for (const root of resolved.roots) {
|
|
36
|
+
const { adapter } = root;
|
|
37
37
|
const adapterLabel =
|
|
38
38
|
adapter.type === 'ingest' ? `${adapter.identity} (${adapter.strategy})` : adapter.identity;
|
|
39
39
|
console.log(
|
|
40
|
-
`
|
|
41
|
-
`tiers={local: ${
|
|
40
|
+
` root "${root.id}" adapter=${adapterLabel} ` +
|
|
41
|
+
`tiers={local: ${root.capabilities.local}, hosted: ${root.capabilities.hosted}}`,
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
} catch (e) {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
isGameComponentClass,
|
|
7
7
|
} from '@vgai/engine/scene/component-registry';
|
|
8
8
|
import { parsePrefabFile, parseSceneFile, SceneParseError } from '@vgai/engine/scene/parse';
|
|
9
|
-
import type { SceneEntity } from '@vgai/engine/scene/scene-types';
|
|
9
|
+
import type { PrefabFile, SceneEntity, SceneFile } from '@vgai/engine/scene/scene-types';
|
|
10
10
|
import { ASSET_CONTENT_EXTENSIONS, validateAssetContentFile } from './validate-asset-content';
|
|
11
11
|
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -30,7 +30,21 @@ import { ASSET_CONTENT_EXTENSIONS, validateAssetContentFile } from './validate-a
|
|
|
30
30
|
// 1. Structural validity (Zod schema parse) — scenes, prefabs, AND the
|
|
31
31
|
// fetched-asset formats (.mat.json/.inputmap.json/.instances.json)
|
|
32
32
|
// 2. Asset references point to files that exist on disk
|
|
33
|
-
// 3. Components exist in the registry
|
|
33
|
+
// 3. Components exist in the registry, AND every authored field is one the
|
|
34
|
+
// component's schema actually declares — run BY DEFAULT (no flag
|
|
35
|
+
// needed): a leftover scene referencing a component that was renamed or
|
|
36
|
+
// deleted used to pass "all OK" as long as it was --components-checked
|
|
37
|
+
// by hand. `src/scripts/registry(.ts)` is imported opportunistically —
|
|
38
|
+
// if it imports cleanly, component checks run; if it can't be imported
|
|
39
|
+
// (missing, or a real syntax/type error), ONE line explains that
|
|
40
|
+
// component-level validation was SKIPPED and why, and the command still
|
|
41
|
+
// exits 0 on structural success (a broken registry blocks its own
|
|
42
|
+
// typecheck already; this command must not become a second, confusing
|
|
43
|
+
// way to learn that).
|
|
44
|
+
// `--components` upgrades this to STRICT mode: a registry that can't be
|
|
45
|
+
// imported is then a hard failure (exit 1) instead of a soft skip — for
|
|
46
|
+
// callers (CI, a pre-release check) that need to assert component
|
|
47
|
+
// validation definitely ran, not merely attempted.
|
|
34
48
|
// ---------------------------------------------------------------------------
|
|
35
49
|
|
|
36
50
|
const args = process.argv.slice(2);
|
|
@@ -42,29 +56,47 @@ if (!existsSync(publicDir)) {
|
|
|
42
56
|
process.exit(1);
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
59
|
+
// Component-level validation is opt-OUT (default ON), not opt-in.
|
|
60
|
+
// `--components` only changes what happens when the registry can't be
|
|
61
|
+
// imported: soft-skip (default) vs. hard-fail (strict).
|
|
62
|
+
const strictComponents = args.includes('--components');
|
|
48
63
|
let componentRegistry: ComponentRegistry | null = null;
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
// The registry path is relative to the root folder being validated.
|
|
66
|
+
const registryPath = join(rootDir, 'src/scripts/registry');
|
|
67
|
+
const hasComponentDocuments =
|
|
68
|
+
collectFiles(publicDir, '.vscn.json').length > 0 ||
|
|
69
|
+
collectFiles(publicDir, '.prefab.json').length > 0;
|
|
70
|
+
// React-only projects deliberately have no scene documents or component
|
|
71
|
+
// registry. Silence is the honest result there: there is nothing whose
|
|
72
|
+
// component names could be checked, even in --components mode.
|
|
73
|
+
if (hasComponentDocuments) {
|
|
54
74
|
try {
|
|
55
75
|
const mod = await import(registryPath);
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
if (mod.componentRegistry) {
|
|
77
|
+
componentRegistry = mod.componentRegistry;
|
|
78
|
+
} else if (strictComponents) {
|
|
58
79
|
console.error(`Registry at ${registryPath} does not export "componentRegistry"`);
|
|
59
80
|
process.exit(1);
|
|
81
|
+
} else {
|
|
82
|
+
console.warn(
|
|
83
|
+
`Component-level validation skipped — ${registryPath} does not export "componentRegistry" ` +
|
|
84
|
+
'(pass --components to make this a hard failure). Continuing with structural checks only.',
|
|
85
|
+
);
|
|
60
86
|
}
|
|
61
87
|
} catch (e) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
88
|
+
if (strictComponents) {
|
|
89
|
+
console.error(
|
|
90
|
+
`--components requires a project with src/scripts/registry.ts exporting componentRegistry.\n` +
|
|
91
|
+
` Looked in: ${registryPath}\n` +
|
|
92
|
+
` Error: ${e}`,
|
|
93
|
+
);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
console.warn(
|
|
97
|
+
`Component-level validation skipped — could not import registry at ${registryPath}: ${e} ` +
|
|
98
|
+
'(pass --components to make this a hard failure). Continuing with structural checks only.',
|
|
66
99
|
);
|
|
67
|
-
process.exit(1);
|
|
68
100
|
}
|
|
69
101
|
}
|
|
70
102
|
|
|
@@ -149,7 +181,7 @@ for (const path of assetContentFiles) {
|
|
|
149
181
|
for (const path of sceneFiles) {
|
|
150
182
|
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
151
183
|
|
|
152
|
-
let data;
|
|
184
|
+
let data: SceneFile;
|
|
153
185
|
try {
|
|
154
186
|
data = parseSceneFile(raw);
|
|
155
187
|
} catch (e) {
|
|
@@ -177,7 +209,7 @@ for (const path of sceneFiles) {
|
|
|
177
209
|
for (const path of prefabFiles) {
|
|
178
210
|
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
179
211
|
|
|
180
|
-
let data;
|
|
212
|
+
let data: PrefabFile;
|
|
181
213
|
try {
|
|
182
214
|
data = parsePrefabFile(raw);
|
|
183
215
|
} catch (e) {
|
package/template/vgai.game.json
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
2
|
+
"$schema": "./packages/engine/schemas/vgai-game.schema.json",
|
|
3
|
+
"manifestVersion": 2,
|
|
4
|
+
"name": "My Game",
|
|
5
|
+
"appId": "com.example.mygame",
|
|
6
|
+
"editorPort": 5173,
|
|
4
7
|
"version": "0.1.0",
|
|
5
8
|
"engine": {
|
|
6
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.0-canary.20260715.0"
|
|
7
10
|
},
|
|
8
|
-
"worlds": [
|
|
9
|
-
{
|
|
10
|
-
"id": "main",
|
|
11
|
-
"kind": "threejs",
|
|
12
|
-
"adapter": "default",
|
|
13
|
-
"entry": "src/scripts/main.ts",
|
|
14
|
-
"scene": "scenes/default.vscn.json"
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
11
|
"resolution": {
|
|
18
12
|
"width": 1280,
|
|
19
13
|
"height": 720
|
|
20
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"roots": [
|
|
16
|
+
{
|
|
17
|
+
"id": "world",
|
|
18
|
+
"adapter": "threejs",
|
|
19
|
+
"scene": "scenes/default.vscn.json"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "ui",
|
|
23
|
+
"adapter": "react",
|
|
24
|
+
"entry": "src/ui/game.tsx",
|
|
25
|
+
"zOrder": 100
|
|
26
|
+
}
|
|
27
|
+
]
|
|
21
28
|
}
|
package/template/vite.config.ts
CHANGED
|
@@ -8,7 +8,9 @@ import { defineConfig } from 'vite';
|
|
|
8
8
|
import { vgaiDataCheck } from '../../engine/src/data/vite-plugin-data';
|
|
9
9
|
// Config-relative TS imports get bundled the same way — that is what lets the
|
|
10
10
|
// project's executable Zod schemas reach the build-time check below.
|
|
11
|
+
import { manifestEntryModulesPlugin } from './manifest-entry-modules-plugin';
|
|
11
12
|
import { dataAssets } from './src/data/assets';
|
|
13
|
+
import manifest from './vgai.game.json';
|
|
12
14
|
|
|
13
15
|
// P2P builds (launched with `?net=p2p-host` / `?net=p2p-join`) route the Colyseus
|
|
14
16
|
// packages onto @vgai/p2p-colyseus's browser-safe compat shims: `browser.ts` exposes
|
|
@@ -33,6 +35,41 @@ const p2pAliases = p2pBuild
|
|
|
33
35
|
}
|
|
34
36
|
: {};
|
|
35
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Run-4 dry-run friction #2 — auto-detect drvfs the SAME way the editor dev
|
|
40
|
+
* server does (`packages/editor/server/server-utils.ts`'s
|
|
41
|
+
* `resolveWatcherPollOptions`, and `dev.ts`'s own `projectOnDrvfs` check):
|
|
42
|
+
* on WSL, a project living on a Windows drive (`/mnt/<drive>/…`) never fires
|
|
43
|
+
* inotify, so without polling this standalone server (`npm run game`)
|
|
44
|
+
* silently misses every external file edit — the same failure mode
|
|
45
|
+
* `dev.ts`'s comment documents for the editor. Before this fix, this file
|
|
46
|
+
* read ONLY `VGAI_WATCH_POLL`, so a project on drvfs polled in the editor
|
|
47
|
+
* but NOT in the standalone server — the two disagreed for no reason a
|
|
48
|
+
* developer could see.
|
|
49
|
+
*
|
|
50
|
+
* Not a shared import: this file cannot reach
|
|
51
|
+
* `packages/editor/server/server-utils.ts` the way it reaches the engine
|
|
52
|
+
* (`../../engine/src/...` above) — a scaffolded project depends on
|
|
53
|
+
* `@vgai/engine` and gets the CLI scaffolder's engine-relative path rewrite
|
|
54
|
+
* (`rewriteEngineRelativeFilePath`, `create-vgai-project/src/scaffold.ts`);
|
|
55
|
+
* there is no equivalent rewrite (or dependency) for the editor's `server/`
|
|
56
|
+
* code, which is never vendored into a scaffolded project at all. So this
|
|
57
|
+
* duplicates the tiny drvfs check rather than reaching across a package
|
|
58
|
+
* boundary that doesn't exist here — same contract as the editor's own
|
|
59
|
+
* helper: `VGAI_WATCH_POLL=0` forces polling off anywhere, `=1`/`=<ms>`
|
|
60
|
+
* forces it on with that interval, unset auto-enables on a drvfs mount.
|
|
61
|
+
*/
|
|
62
|
+
function resolveWatchOption(): { usePolling: true; interval: number } | undefined {
|
|
63
|
+
const raw = process.env.VGAI_WATCH_POLL;
|
|
64
|
+
if (raw !== undefined && raw !== '') {
|
|
65
|
+
if (raw === '0') return undefined;
|
|
66
|
+
const ms = Number(raw);
|
|
67
|
+
return { usePolling: true, interval: Number.isFinite(ms) && ms > 1 ? ms : 1000 };
|
|
68
|
+
}
|
|
69
|
+
const onDrvfs = process.platform === 'linux' && /^\/mnt\/[a-z]\//i.test(__dirname);
|
|
70
|
+
return onDrvfs ? { usePolling: true, interval: 1000 } : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
36
73
|
export default defineConfig({
|
|
37
74
|
// Build-path validation (docs/DATA-TOOLS-DESIGN.md §6.7, build-only): every
|
|
38
75
|
// registered data asset must still parse through its schema (the EXACT
|
|
@@ -40,6 +77,7 @@ export default defineConfig({
|
|
|
40
77
|
// no `src/tools/` module may reach the shipped bundle (§4: tools are
|
|
41
78
|
// editor-only — never serve testers a build with dev/cheat surfaces).
|
|
42
79
|
plugins: [
|
|
80
|
+
manifestEntryModulesPlugin(manifest),
|
|
43
81
|
vgaiDataCheck({
|
|
44
82
|
root: __dirname,
|
|
45
83
|
assets: dataAssets.map((a) => ({
|
|
@@ -53,6 +91,22 @@ export default defineConfig({
|
|
|
53
91
|
'@engine': path.resolve(__dirname, '../../engine/src'),
|
|
54
92
|
...p2pAliases,
|
|
55
93
|
},
|
|
94
|
+
// react/react-dom dedupe (GH #123): the '@engine' alias above resolves
|
|
95
|
+
// at the SOURCE-LINKED engine checkout, so when Vite bundles the
|
|
96
|
+
// engine's react bridge module (`src/react/game-state.tsx` — the
|
|
97
|
+
// `<GameProvider>` / `useGameState` HUD bridge), module resolution walks
|
|
98
|
+
// up from THAT file and finds the CHECKOUT's `node_modules/react` — a
|
|
99
|
+
// different physical copy (often a different version) than this
|
|
100
|
+
// project's own. Two Reacts in one page means the Context object
|
|
101
|
+
// `GameProvider` creates is not the one this project's tree looks up
|
|
102
|
+
// via `useContext`, so the documented HUD pattern crashes with "Invalid
|
|
103
|
+
// hook call" / "Cannot read properties of null (reading 'useContext')"
|
|
104
|
+
// on first render.
|
|
105
|
+
// `dedupe` forces Vite to collapse both import paths onto a single
|
|
106
|
+
// physical copy. Same fix, same reasoning, already applied for the
|
|
107
|
+
// identical dual-instance failure in this repo's own root
|
|
108
|
+
// `vite.config.ts` and in `examples/r3f-probe/vite.config.ts`.
|
|
109
|
+
dedupe: ['react', 'react-dom'],
|
|
56
110
|
},
|
|
57
111
|
optimizeDeps: {
|
|
58
112
|
// Pre-bundle deps that are only reached through the dynamically imported
|
|
@@ -94,22 +148,29 @@ export default defineConfig({
|
|
|
94
148
|
// observed causing a CI e2e spec to hang waiting on the wrong server. See
|
|
95
149
|
// packages/editor/e2e/helpers/server.ts's `startStandaloneServer`.
|
|
96
150
|
strictPort: true,
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
151
|
+
// Poll for file changes instead of relying on inotify — AUTO-ENABLED on
|
|
152
|
+
// WSL when the project lives on a Windows drive (/mnt/c, drvfs: inotify
|
|
153
|
+
// never fires there), or edits to src/data/*.data.json silently never
|
|
154
|
+
// hot-reload into the running game (docs/DATA-TOOLS-DESIGN.md §2.3).
|
|
155
|
+
// `VGAI_WATCH_POLL` is an explicit override (`=0` off anywhere, `=1`/
|
|
156
|
+
// `=<ms>` on anywhere) — see `resolveWatchOption` above, which the
|
|
157
|
+
// EDITOR dev server's own auto-detect mirrors, so one behavior covers
|
|
158
|
+
// both surfaces without the developer having to set anything. Safe to
|
|
159
|
+
// enable here: this standalone server only watches the project tree,
|
|
160
|
+
// which is small.
|
|
161
|
+
//
|
|
162
|
+
// VGAI_NO_WATCH=1 (`vgai probe`, Acceptance Driver build plan Task 4.1):
|
|
163
|
+
// disable watching entirely — a mid-run Vite reload resets
|
|
164
|
+
// `window.__vgai`/whatever is driving the standalone page out from under
|
|
165
|
+
// an in-flight acceptance run (the hollowstone reload-kills-the-run
|
|
166
|
+
// lesson). Mutually exclusive with the poll option (same `server.watch`
|
|
167
|
+
// key) — NO_WATCH wins when both would otherwise apply.
|
|
168
|
+
...(process.env.VGAI_NO_WATCH
|
|
169
|
+
? { watch: null }
|
|
170
|
+
: (() => {
|
|
171
|
+
const watch = resolveWatchOption();
|
|
172
|
+
return watch ? { watch } : {};
|
|
173
|
+
})()),
|
|
113
174
|
allowedHosts:
|
|
114
175
|
process.env.VITE_ALLOWED_HOSTS === 'all'
|
|
115
176
|
? true
|