@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
package/src/module-mode.ts
CHANGED
|
@@ -11,18 +11,18 @@
|
|
|
11
11
|
* override (`setActiveAuthoring`).
|
|
12
12
|
*
|
|
13
13
|
* FINDING (report prominently — see this slice's "Report back"): this is a
|
|
14
|
-
* gap `play-mode.ts`'s existing `
|
|
14
|
+
* gap `play-mode.ts`'s existing `resolveRootAdapter` call (its single-world
|
|
15
15
|
* Play branch) does NOT close. That branch always calls
|
|
16
16
|
* `installPlayAuthoring(store)`, which drives the hierarchy/inspector from
|
|
17
17
|
* `getActiveAuthoring(store)` — i.e. the FIRST-PARTY `.vscn`-over-`store`
|
|
18
18
|
* adapter — never from `session.mounted.authoring`. That's the right choice
|
|
19
|
-
* for `default-three`/`default-pixi`/`default-react`
|
|
19
|
+
* for `default-three`/`default-pixi`/`default-react` roots (their mounted
|
|
20
20
|
* scene mirrors the store's OWN document), but it is WRONG for a `{ module }`
|
|
21
21
|
* world: a custom adapter builds its scene from its own code, so driving the
|
|
22
22
|
* inspector from the store's `.vscn` document would show an unrelated (empty,
|
|
23
23
|
* for a fresh CLI-on-folder project) tree instead of the module's real
|
|
24
24
|
* objects. `play-mode.ts` is out of scope for this slice (sibling agent's
|
|
25
|
-
* region), so rather than leave `{ module }`
|
|
25
|
+
* region), so rather than leave `{ module }` roots unreachable through the
|
|
26
26
|
* real editor UI at all, this file gives them their OWN auto-mount route —
|
|
27
27
|
* mirroring ingest mode's already-established shape (auto-mount on load,
|
|
28
28
|
* install the mounted adapter as the override, swap the viewport onto the
|
|
@@ -56,17 +56,17 @@
|
|
|
56
56
|
* world for every kind (its `'module'` switch case is kind-agnostic) and
|
|
57
57
|
* ALREADY hands it back as the correctly-kinded `WorldMountSpec` — so the fix
|
|
58
58
|
* is routing, not an engine change: mirror `ingest-mode.ts`'s
|
|
59
|
-
* `enterIngestModeReact` recipe (one-element `resolveAllWorlds` +
|
|
60
|
-
* `createGameRuntime({ container,
|
|
59
|
+
* `enterIngestModeReact` recipe (one-element `resolveAllWorlds` + roots-path
|
|
60
|
+
* `createGameRuntime({ container, roots })`) instead of the legacy single-
|
|
61
61
|
* adapter path. `tryManifestModuleRoute` below picks between the two based on
|
|
62
|
-
* `firstWorld.
|
|
62
|
+
* `firstWorld.surface` — threejs module roots keep calling
|
|
63
63
|
* `enterModuleModeFromManifestWorld` byte-for-byte; the D-X6 guard stays
|
|
64
64
|
* reachable (and its own tests unmodified) for any caller that still invokes
|
|
65
65
|
* that function directly with a non-three world.
|
|
66
66
|
*/
|
|
67
67
|
|
|
68
68
|
import type { AuthoringAdapter } from '@engine/adapter';
|
|
69
|
-
import type {
|
|
69
|
+
import type { ResolvedAdapterRoot, ResolvedGameManifest } from '@engine/manifest/load';
|
|
70
70
|
import type { GameSession, WorldMountSpec } from '@engine/runtime/create-runtime';
|
|
71
71
|
import { setUserData } from '@engine/scene/user-data';
|
|
72
72
|
import type * as THREE from 'three';
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
formatTierShortfallMessage,
|
|
77
77
|
type TierShortfallReport,
|
|
78
78
|
} from './achieved-tier';
|
|
79
|
-
import { resolveAllWorlds,
|
|
79
|
+
import { resolveAllWorlds, resolveRootAdapter } from './adapter-resolver';
|
|
80
80
|
import { setActiveAuthoring } from './authoring/active-adapter';
|
|
81
81
|
import { setActiveSystems } from './authoring/active-systems';
|
|
82
82
|
import { makeEmbedOnlyAdapter } from './authoring/embed-only-adapter';
|
|
@@ -92,12 +92,6 @@ import { getCurrentProject } from './project-manager';
|
|
|
92
92
|
interface ModuleSession {
|
|
93
93
|
store: EditorStore;
|
|
94
94
|
stop: () => void;
|
|
95
|
-
/** Absent on the worlds-path route (D-Y1 below) — that route owns no
|
|
96
|
-
* standalone canvas of its own; `createGameRuntime`'s worlds-path session
|
|
97
|
-
* builds and tears down its own per-world surface(s) directly inside the
|
|
98
|
-
* game container. Present (and removed on exit) only for the legacy
|
|
99
|
-
* threejs single-adapter path's own hand-created canvas. */
|
|
100
|
-
canvas?: HTMLCanvasElement | undefined;
|
|
101
95
|
}
|
|
102
96
|
|
|
103
97
|
let _session: ModuleSession | null = null;
|
|
@@ -152,14 +146,14 @@ export function withStoreSelection(
|
|
|
152
146
|
* .local` (always resolved/explicit for a module world — the loader requires
|
|
153
147
|
* it, `manifest/load.ts`'s `resolveCapabilities`) is the declared tier; the
|
|
154
148
|
* ACTUAL achieved tier is recomputed here (in addition to
|
|
155
|
-
* `
|
|
149
|
+
* `resolveRootAdapter`'s own internal, warn-only check, T3.4 slice 1) purely
|
|
156
150
|
* to expose the structured values on the `__vgaiModule` dev/e2e hook below —
|
|
157
151
|
* this does not log a second shortfall line, it only reads the same pure
|
|
158
152
|
* computation slice 1 already logs from inside the resolver.
|
|
159
153
|
*/
|
|
160
154
|
export async function enterModuleModeFromManifestWorld(
|
|
161
155
|
store: EditorStore,
|
|
162
|
-
world:
|
|
156
|
+
world: ResolvedAdapterRoot,
|
|
163
157
|
projectRoot: string,
|
|
164
158
|
): Promise<void> {
|
|
165
159
|
const gameContainer = getGameContainer();
|
|
@@ -171,24 +165,26 @@ export async function enterModuleModeFromManifestWorld(
|
|
|
171
165
|
store.setPlayState('playing');
|
|
172
166
|
editorConsole.log(`Mounting custom adapter module for world "${world.id}"`, 'adapter');
|
|
173
167
|
|
|
174
|
-
// `
|
|
168
|
+
// `resolveRootAdapter`'s `module` branch (T3.4 slice 1) already: path-guards
|
|
175
169
|
// + shape-checks the module, then wraps its `mount` with the achieved-tier
|
|
176
170
|
// warn-only check (`withAchievedTierCheck`) — reused verbatim here, not
|
|
177
171
|
// duplicated.
|
|
178
|
-
const adapter = await
|
|
172
|
+
const adapter = await resolveRootAdapter(world, projectRoot);
|
|
179
173
|
|
|
180
|
-
const canvas = document.createElement('canvas');
|
|
181
|
-
canvas.style.cssText = 'width:100%;height:100%;display:block;';
|
|
182
|
-
gameContainer.appendChild(canvas);
|
|
183
174
|
const w = gameContainer.clientWidth || 800;
|
|
184
175
|
const h = gameContainer.clientHeight || 600;
|
|
185
176
|
|
|
186
177
|
const { createGameRuntime } = await import('@engine/runtime/create-runtime');
|
|
187
|
-
const session = await createGameRuntime({
|
|
178
|
+
const session = await createGameRuntime({
|
|
179
|
+
container: gameContainer,
|
|
180
|
+
width: w,
|
|
181
|
+
height: h,
|
|
182
|
+
roots: [{ id: world.id, kind: 'threejs', adapter }],
|
|
183
|
+
});
|
|
188
184
|
const mounted = session.mounted;
|
|
189
185
|
|
|
190
186
|
// D-X6 honesty guard (docs/EXTERNAL-FOLDER-INGEST-DESIGN.md §2/§6 slice S4):
|
|
191
|
-
// this route only wires up THREE.Scene-shaped
|
|
187
|
+
// this route only wires up THREE.Scene-shaped roots — everything below
|
|
192
188
|
// (`tagObjectsWithEntityIds`, `store.enterPlayScene`) assumes `mounted.scene`
|
|
193
189
|
// exists. A pixi/react `{ module }` world's mounted result has NO `.scene`
|
|
194
190
|
// at all (`MountedPixiWorld`/`MountedReactWorld`, `@engine/adapter` —
|
|
@@ -197,19 +193,19 @@ export async function enterModuleModeFromManifestWorld(
|
|
|
197
193
|
// `undefined` into `enterPlayScene` — exactly the silent dead end D-X6
|
|
198
194
|
// replaces with a loud, named error (anti-shim / degrade-loudly). Trust
|
|
199
195
|
// the mounted result's OWN self-declared `kind` tag over the manifest's
|
|
200
|
-
// `world.
|
|
196
|
+
// `world.surface` — it is what the module ACTUALLY returned; an absent `kind`
|
|
201
197
|
// (a pre-T7.5 module adapter that never had to declare one) is treated as
|
|
202
198
|
// the historical threejs-only default, so existing module fixtures are
|
|
203
199
|
// unaffected.
|
|
204
200
|
const mountedKind = (mounted as unknown as { kind?: string }).kind;
|
|
205
201
|
if (mountedKind !== undefined && mountedKind !== 'threejs') {
|
|
206
|
-
|
|
202
|
+
session.stop();
|
|
207
203
|
store.setPlayState('stopped');
|
|
208
204
|
throw new Error(
|
|
209
205
|
`enterModuleModeFromManifestWorld: world "${world.id}" (kind: "${mountedKind}") is a ` +
|
|
210
206
|
'{ module } adapter whose mounted result is not a threejs world — v1 module-mount ' +
|
|
211
|
-
'route only wires up THREE.Scene-shaped
|
|
212
|
-
'(docs/EXTERNAL-FOLDER-INGEST-DESIGN.md D-X6). Pixi/react { module }
|
|
207
|
+
'route only wires up THREE.Scene-shaped roots into enterPlayScene ' +
|
|
208
|
+
'(docs/EXTERNAL-FOLDER-INGEST-DESIGN.md D-X6). Pixi/react { module } roots have no ' +
|
|
213
209
|
'mount plumbing yet — kind-parameterized HostContext + per-kind module mounting is ' +
|
|
214
210
|
'wave 2, gated on its own design doc. This throws loudly instead of silently passing ' +
|
|
215
211
|
'`undefined` into enterPlayScene.',
|
|
@@ -218,7 +214,6 @@ export async function enterModuleModeFromManifestWorld(
|
|
|
218
214
|
|
|
219
215
|
_session = {
|
|
220
216
|
store,
|
|
221
|
-
canvas,
|
|
222
217
|
stop: () => session.stop(),
|
|
223
218
|
};
|
|
224
219
|
|
|
@@ -246,7 +241,7 @@ export async function enterModuleModeFromManifestWorld(
|
|
|
246
241
|
world.capabilities.local,
|
|
247
242
|
achievedTier,
|
|
248
243
|
);
|
|
249
|
-
// Belt-and-suspenders:
|
|
244
|
+
// Belt-and-suspenders: resolveRootAdapter's own wrapping already warned once
|
|
250
245
|
// via editorConsole (slice 1) — this does not warn again, only formats the
|
|
251
246
|
// SAME message onto the structured dev/e2e hook below for assertions.
|
|
252
247
|
if (shortfall) {
|
|
@@ -291,14 +286,13 @@ export function exitModuleMode(): void {
|
|
|
291
286
|
} catch {
|
|
292
287
|
/* ignore */
|
|
293
288
|
}
|
|
294
|
-
s.canvas?.remove();
|
|
295
289
|
delete (window as unknown as Record<string, unknown>)['__vgaiModule'];
|
|
296
290
|
editorConsole.log('Module adapter mode stopped', 'adapter');
|
|
297
291
|
}
|
|
298
292
|
|
|
299
293
|
// ---------------------------------------------------------------------------
|
|
300
294
|
// D-Y1 (docs/EXTERNAL-REACT-AND-MODULE-DESIGN.md §1/§4 slice S1) —
|
|
301
|
-
//
|
|
295
|
+
// roots-path routing for non-three `{ module }` roots
|
|
302
296
|
// ---------------------------------------------------------------------------
|
|
303
297
|
|
|
304
298
|
/**
|
|
@@ -306,7 +300,7 @@ export function exitModuleMode(): void {
|
|
|
306
300
|
* world through the WORLDS PATH — the D-Y1 sibling of
|
|
307
301
|
* `enterModuleModeFromManifestWorld` above, mirroring `ingest-mode.ts`'s
|
|
308
302
|
* `enterIngestModeReact` recipe exactly: one-element `resolveAllWorlds` +
|
|
309
|
-
*
|
|
303
|
+
* roots-path `createGameRuntime({ container, roots })`, which hands the
|
|
310
304
|
* module adapter its own native `World2DHost`/`ReactWorldHost` — no
|
|
311
305
|
* `HostContext`, no `.scene` assumption, no engine-side change needed (the
|
|
312
306
|
* wave-2 study's §0 finding: `resolveAllWorlds`'s `'module'` case is already
|
|
@@ -314,13 +308,13 @@ export function exitModuleMode(): void {
|
|
|
314
308
|
*
|
|
315
309
|
* Only THIS one world mounts (mirrors the legacy path's own "only ever the
|
|
316
310
|
* first world" behavior, `tryManifestModuleRoute` below): `manifest`'s other
|
|
317
|
-
*
|
|
311
|
+
* roots (if any) are discarded via the one-element `{ ...manifest, roots:
|
|
318
312
|
* [world] }` passed to `resolveAllWorlds` — a real multi-world manifest whose
|
|
319
313
|
* FIRST world is a non-three module adapter is out of scope here exactly as
|
|
320
314
|
* it always was for the legacy route.
|
|
321
315
|
*
|
|
322
316
|
* `withAchievedTierCheck` (already wrapped inside `resolveModuleAdapter`,
|
|
323
|
-
* reached identically through `resolveAllWorlds` -> `
|
|
317
|
+
* reached identically through `resolveAllWorlds` -> `resolveRootAdapter` ->
|
|
324
318
|
* the `'module'` case) runs completely unmodified here — an over-claiming
|
|
325
319
|
* module world still gets its shortfall logged loudly by the resolver itself;
|
|
326
320
|
* this function neither bypasses nor re-derives that check, only reads the
|
|
@@ -342,8 +336,8 @@ export function exitModuleMode(): void {
|
|
|
342
336
|
* not scene-adoption-keyed) — exactly like `enterIngestModeReact`.
|
|
343
337
|
*/
|
|
344
338
|
/**
|
|
345
|
-
* Mount a single `{ module }` world (any kind) through the SCOPED
|
|
346
|
-
* recipe — a one-element `resolveAllWorlds` +
|
|
339
|
+
* Mount a single `{ module }` world (any kind) through the SCOPED roots-path
|
|
340
|
+
* recipe — a one-element `resolveAllWorlds` + roots-path `createGameRuntime`
|
|
347
341
|
* — with NO global side effects of its own (no `setActiveAuthoring`, no
|
|
348
342
|
* `store`/viewport writes, no dev hooks). Extracted (D-V4,
|
|
349
343
|
* docs/WAVE5-MULTIWORLD-INGEST-DESIGN.md) so BOTH this file's own
|
|
@@ -356,22 +350,22 @@ export function exitModuleMode(): void {
|
|
|
356
350
|
*/
|
|
357
351
|
export async function mountModuleWorldRuntime(
|
|
358
352
|
manifest: ResolvedGameManifest,
|
|
359
|
-
world:
|
|
353
|
+
world: ResolvedAdapterRoot,
|
|
360
354
|
projectRoot: string,
|
|
361
355
|
container: HTMLElement,
|
|
362
356
|
width: number,
|
|
363
357
|
height: number,
|
|
364
358
|
): Promise<{ session: GameSession; specs: WorldMountSpec[] }> {
|
|
365
359
|
const { createGameRuntime } = await import('@engine/runtime/create-runtime');
|
|
366
|
-
const specs = await resolveAllWorlds({ ...manifest,
|
|
367
|
-
const session = await createGameRuntime({ container,
|
|
360
|
+
const specs = await resolveAllWorlds({ ...manifest, roots: [world] }, projectRoot);
|
|
361
|
+
const session = await createGameRuntime({ container, roots: specs, width, height });
|
|
368
362
|
return { session, specs };
|
|
369
363
|
}
|
|
370
364
|
|
|
371
365
|
export async function enterModuleModeWorldsPath(
|
|
372
366
|
store: EditorStore,
|
|
373
367
|
manifest: ResolvedGameManifest,
|
|
374
|
-
world:
|
|
368
|
+
world: ResolvedAdapterRoot,
|
|
375
369
|
projectRoot: string,
|
|
376
370
|
): Promise<void> {
|
|
377
371
|
const gameContainer = getGameContainer();
|
|
@@ -382,7 +376,7 @@ export async function enterModuleModeWorldsPath(
|
|
|
382
376
|
|
|
383
377
|
store.setPlayState('playing');
|
|
384
378
|
editorConsole.log(
|
|
385
|
-
`Mounting custom adapter module for world "${world.id}" (kind: ${world.
|
|
379
|
+
`Mounting custom adapter module for world "${world.id}" (kind: ${world.surface}, roots path)`,
|
|
386
380
|
'adapter',
|
|
387
381
|
);
|
|
388
382
|
|
|
@@ -397,7 +391,7 @@ export async function enterModuleModeWorldsPath(
|
|
|
397
391
|
h,
|
|
398
392
|
);
|
|
399
393
|
|
|
400
|
-
const worldInstance = session.game.
|
|
394
|
+
const worldInstance = session.game.roots[0]!;
|
|
401
395
|
const mounted = worldInstance.mounted;
|
|
402
396
|
const adapterId = specs[0]!.adapter.id;
|
|
403
397
|
|
|
@@ -423,7 +417,7 @@ export async function enterModuleModeWorldsPath(
|
|
|
423
417
|
world.capabilities.local,
|
|
424
418
|
achievedTier,
|
|
425
419
|
);
|
|
426
|
-
// Belt-and-suspenders:
|
|
420
|
+
// Belt-and-suspenders: resolveRootAdapter's own wrapping already warned once
|
|
427
421
|
// via editorConsole (T3.4 slice 1) — this does not warn again, only formats
|
|
428
422
|
// the SAME message onto the structured dev/e2e hook below for assertions.
|
|
429
423
|
if (shortfall) {
|
|
@@ -449,14 +443,14 @@ export async function enterModuleModeWorldsPath(
|
|
|
449
443
|
* whose FIRST world declares a `{ module }` adapter auto-mounts it. Same
|
|
450
444
|
* "applied or not" contract as `tryManifestIngestRoute`.
|
|
451
445
|
*
|
|
452
|
-
* D-Y1: dispatches on `firstWorld.
|
|
446
|
+
* D-Y1: dispatches on `firstWorld.surface` — threejs keeps calling
|
|
453
447
|
* `enterModuleModeFromManifestWorld` byte-for-byte (its own D-X6 guard stays
|
|
454
448
|
* as the backstop for any OTHER path that might still funnel a non-three
|
|
455
449
|
* mount into it); `pixijs`/`react` route through the new
|
|
456
450
|
* `enterModuleModeWorldsPath` above instead.
|
|
457
451
|
*
|
|
458
452
|
* D-V2 (docs/WAVE5-MULTIWORLD-INGEST-DESIGN.md, F24 composite): if the
|
|
459
|
-
* manifest declares ANY `{ ingest }` world (anywhere in `
|
|
453
|
+
* manifest declares ANY `{ ingest }` world (anywhere in `roots`, not just
|
|
460
454
|
* first), this route declines — composites are owned by the ingest routes
|
|
461
455
|
* (`ingest-mode.ts`'s `tryManifestIngestRoute*`), which mount the one ingest
|
|
462
456
|
* world through their own enter path and any `{ module }` SIBLING through
|
|
@@ -471,8 +465,8 @@ export async function enterModuleModeWorldsPath(
|
|
|
471
465
|
export async function tryManifestModuleRoute(store: EditorStore): Promise<boolean> {
|
|
472
466
|
if (getEditorMode() === 'browser') return false; // no dev server to serve /vgai.game.json / /@fs/ from
|
|
473
467
|
const manifest = await fetchGameManifest().catch(() => null);
|
|
474
|
-
if (manifest?.
|
|
475
|
-
const firstWorld = manifest?.
|
|
468
|
+
if (manifest?.roots.some((w) => w.adapter.type === 'ingest')) return false;
|
|
469
|
+
const firstWorld = manifest?.roots[0];
|
|
476
470
|
if (firstWorld === undefined || firstWorld.adapter.type !== 'module') return false;
|
|
477
471
|
|
|
478
472
|
const project = getCurrentProject();
|
|
@@ -492,7 +486,7 @@ export async function tryManifestModuleRoute(store: EditorStore): Promise<boolea
|
|
|
492
486
|
return true;
|
|
493
487
|
}
|
|
494
488
|
try {
|
|
495
|
-
if (firstWorld.
|
|
489
|
+
if (firstWorld.surface === 'pixijs' || firstWorld.surface === 'react') {
|
|
496
490
|
await enterModuleModeWorldsPath(store, manifest!, firstWorld, project.rootPath);
|
|
497
491
|
} else {
|
|
498
492
|
await enterModuleModeFromManifestWorld(store, firstWorld, project.rootPath);
|
|
@@ -501,10 +495,10 @@ export async function tryManifestModuleRoute(store: EditorStore): Promise<boolea
|
|
|
501
495
|
editorConsole.error(`Manifest { module } auto-mount failed: ${err}`, 'adapter');
|
|
502
496
|
// D-W3 (docs/WAVE4-FTUE-HARDENING-DESIGN.md §D-W3, F9) — the fourth of the
|
|
503
497
|
// four manifest-route catch blocks (three/pixi/react in ingest-mode.ts,
|
|
504
|
-
// this one for `{ module }`
|
|
498
|
+
// this one for `{ module }` roots); same loud-banner-slot population.
|
|
505
499
|
setMountFailureReport({
|
|
506
500
|
worldId: firstWorld.id,
|
|
507
|
-
kind: firstWorld.
|
|
501
|
+
kind: firstWorld.surface,
|
|
508
502
|
identity: firstWorld.adapter.identity,
|
|
509
503
|
message: formatMountFailureMessage(err),
|
|
510
504
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TickStampedEvent } from '@engine/adapter/system-adapter';
|
|
2
|
+
import type { LogEntry } from './editor-api';
|
|
3
|
+
|
|
4
|
+
/** Convert newly observed game-authored debug events into persistent JSONL entries. */
|
|
5
|
+
export function debugEventsToLogEntries(
|
|
6
|
+
events: readonly TickStampedEvent[],
|
|
7
|
+
sinceSeq: number,
|
|
8
|
+
wallTime = Date.now(),
|
|
9
|
+
): { entries: LogEntry[]; lastSeq: number } {
|
|
10
|
+
const fresh = events.filter((event) => event.seq > sinceSeq).sort((a, b) => a.seq - b.seq);
|
|
11
|
+
return {
|
|
12
|
+
entries: fresh.map((event) => ({
|
|
13
|
+
t: wallTime,
|
|
14
|
+
level: 'info',
|
|
15
|
+
source: 'game-event',
|
|
16
|
+
msg: event.event,
|
|
17
|
+
tick: event.tick,
|
|
18
|
+
simT: event.simT,
|
|
19
|
+
meta: {
|
|
20
|
+
seq: event.seq,
|
|
21
|
+
...(event.detail !== undefined ? { detail: event.detail } : {}),
|
|
22
|
+
},
|
|
23
|
+
})),
|
|
24
|
+
lastSeq: fresh.at(-1)?.seq ?? sinceSeq,
|
|
25
|
+
};
|
|
26
|
+
}
|