@vgai/editor 0.2.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/LICENSE +661 -0
- package/README.md +35 -0
- package/dist/a/b/c/test-nested.json +1 -0
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +1 -0
- package/dist/assets/SelectionBox-BXsv_6aH.js +1 -0
- package/dist/assets/browser-project-scripts-DOru4L1x.js +2 -0
- package/dist/assets/browserAll-CEkWYlFk.js +1 -0
- package/dist/assets/collision-world-DniMB0qq.glb +0 -0
- package/dist/assets/create-runtime-DYIWr3va.js +1 -0
- package/dist/assets/data-asset-Bb9sIM7i.js +5 -0
- package/dist/assets/esbuild-BHljloGq.wasm +0 -0
- package/dist/assets/fake-three-BMTQ9rl_.js +1 -0
- package/dist/assets/game-8SDZPPgH.js +1 -0
- package/dist/assets/game-BI111o5f.js +10 -0
- package/dist/assets/game-CevorxyV.js +1 -0
- package/dist/assets/game-Di1H0gFj.js +1 -0
- package/dist/assets/game-Di7XlywD.js +1 -0
- package/dist/assets/game-DjnCaw8R.js +1 -0
- package/dist/assets/game-Q9A0aXSV.js +1 -0
- package/dist/assets/game-pt_1lQLv.js +1 -0
- package/dist/assets/game-source-CvidN7AB.js +1 -0
- package/dist/assets/game-xsOho_wg.js +83 -0
- package/dist/assets/index-Bp5cecD6.js +12 -0
- package/dist/assets/index-CPVV6pjw.js +1 -0
- package/dist/assets/index-CpOnYyeD.js +213 -0
- package/dist/assets/index-Cs8xwv3e.js +1 -0
- package/dist/assets/index-DL7RcQ0n.js +27 -0
- package/dist/assets/index-Dr8H_6Rl.js +1 -0
- package/dist/assets/index-_bCaipUk.js +13650 -0
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +1 -0
- package/dist/assets/mount-manifest-Bhk0ohsl.js +1 -0
- package/dist/assets/recast-navigation.wasm-compat-CvP4UGK6.js +1 -0
- package/dist/assets/scene-query-BivAHhJu.js +1 -0
- package/dist/assets/stats.module--VATS4Kh.js +1 -0
- package/dist/assets/webworkerAll-BLrH0F6F.js +1 -0
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +1 -0
- package/dist/assets/xstate.esm-BgUD33nl.js +3 -0
- package/dist/index.html +37 -0
- package/dist/ingest/racing-game/UPSTREAM.md +68 -0
- package/dist/ingest/racing-game/a/Inter-Black.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Black.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-BlackItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-BlackItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Bold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Bold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-BoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-BoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLight.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLight.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLightItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLightItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Italic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Italic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Light.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Light.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-LightItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-LightItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Medium.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Medium.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-MediumItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-MediumItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Regular.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Regular.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Thin.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Thin.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ThinItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ThinItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-italic.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-roman.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/index.css +1 -0
- package/dist/ingest/racing-game/images/bronze.png +0 -0
- package/dist/ingest/racing-game/images/gold.png +0 -0
- package/dist/ingest/racing-game/images/silver.png +0 -0
- package/dist/ingest/racing-game/index.html +15 -0
- package/dist/ingest/racing-game/models/chassis-draco.glb +0 -0
- package/dist/ingest/racing-game/models/track-draco.glb +0 -0
- package/dist/ingest/racing-game/models/wheel-draco.glb +0 -0
- package/dist/ingest/racing-game/rg-entry.js +1 -0
- package/dist/ingest/racing-game/sounds/accelerate.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/boost.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/crash.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/engine.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/honk.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/tire-brake.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/train.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/water.mp3 +0 -0
- package/dist/ingest/racing-game/textures/cursor.svg +3 -0
- package/dist/ingest/racing-game/textures/dikhololo_night_1k.hdr +0 -0
- package/dist/ingest/racing-game/textures/heightmap_1024.png +0 -0
- package/dist/ingest/racing-game/textures/mask.svg +11 -0
- package/dist/ingest/racing-game/textures/no_sound.png +0 -0
- package/dist/ingest/racing-game/three-r139.module.js +50617 -0
- package/dist/ingest/racing-game/vendor.js +179 -0
- package/dist/ingest/racing-game/vgai.game.json +20 -0
- package/dist/ingest/simcity/UPSTREAM.md +65 -0
- package/dist/ingest/simcity/favicon.ico +0 -0
- package/dist/ingest/simcity/fonts/Bebas-Regular.otf +0 -0
- package/dist/ingest/simcity/fonts/Digitalt.otf +0 -0
- package/dist/ingest/simcity/fonts/Stanberry.ttf +0 -0
- package/dist/ingest/simcity/icons/bulldozer-color.png +0 -0
- package/dist/ingest/simcity/icons/bulldozer.png +0 -0
- package/dist/ingest/simcity/icons/calendar.png +0 -0
- package/dist/ingest/simcity/icons/factory-color.png +0 -0
- package/dist/ingest/simcity/icons/factory.png +0 -0
- package/dist/ingest/simcity/icons/house-color.png +0 -0
- package/dist/ingest/simcity/icons/house.png +0 -0
- package/dist/ingest/simcity/icons/job.png +0 -0
- package/dist/ingest/simcity/icons/office.png +0 -0
- package/dist/ingest/simcity/icons/pause-color.png +0 -0
- package/dist/ingest/simcity/icons/pause.png +0 -0
- package/dist/ingest/simcity/icons/person.png +0 -0
- package/dist/ingest/simcity/icons/play-color.png +0 -0
- package/dist/ingest/simcity/icons/play.png +0 -0
- package/dist/ingest/simcity/icons/power-color.png +0 -0
- package/dist/ingest/simcity/icons/power-line-color.png +0 -0
- package/dist/ingest/simcity/icons/power.png +0 -0
- package/dist/ingest/simcity/icons/road-color.png +0 -0
- package/dist/ingest/simcity/icons/road.png +0 -0
- package/dist/ingest/simcity/icons/select-color.png +0 -0
- package/dist/ingest/simcity/icons/select.png +0 -0
- package/dist/ingest/simcity/icons/store-color.png +0 -0
- package/dist/ingest/simcity/index.html +94 -0
- package/dist/ingest/simcity/index.js +58 -0
- package/dist/ingest/simcity/main.css +233 -0
- package/dist/ingest/simcity/models/armored-truck.glb +0 -0
- package/dist/ingest/simcity/models/building-block-4floor-corner.glb +0 -0
- package/dist/ingest/simcity/models/building-block-4floor-short.glb +0 -0
- package/dist/ingest/simcity/models/building-block-5floor.glb +0 -0
- package/dist/ingest/simcity/models/building-burger-joint.glb +0 -0
- package/dist/ingest/simcity/models/building-cafe.glb +0 -0
- package/dist/ingest/simcity/models/building-casino.glb +0 -0
- package/dist/ingest/simcity/models/building-cinema.glb +0 -0
- package/dist/ingest/simcity/models/building-house-block-big.glb +0 -0
- package/dist/ingest/simcity/models/building-house-family-large.glb +0 -0
- package/dist/ingest/simcity/models/building-house-family-small.glb +0 -0
- package/dist/ingest/simcity/models/building-office-balcony.glb +0 -0
- package/dist/ingest/simcity/models/building-office-big.glb +0 -0
- package/dist/ingest/simcity/models/building-office-pyramid.glb +0 -0
- package/dist/ingest/simcity/models/building-office-tall.glb +0 -0
- package/dist/ingest/simcity/models/building-office.glb +0 -0
- package/dist/ingest/simcity/models/building-restaurant.glb +0 -0
- package/dist/ingest/simcity/models/building-skyscraper.glb +0 -0
- package/dist/ingest/simcity/models/car-ambulance-pickup.glb +0 -0
- package/dist/ingest/simcity/models/car-baywatch.glb +0 -0
- package/dist/ingest/simcity/models/car-hippie-van.glb +0 -0
- package/dist/ingest/simcity/models/car-passenger-race.glb +0 -0
- package/dist/ingest/simcity/models/car-passenger.glb +0 -0
- package/dist/ingest/simcity/models/car-police.glb +0 -0
- package/dist/ingest/simcity/models/car-taxi.glb +0 -0
- package/dist/ingest/simcity/models/car-tow-truck.glb +0 -0
- package/dist/ingest/simcity/models/car-truck-dump.glb +0 -0
- package/dist/ingest/simcity/models/car-veteran.glb +0 -0
- package/dist/ingest/simcity/models/construction-small.glb +0 -0
- package/dist/ingest/simcity/models/data-center.glb +0 -0
- package/dist/ingest/simcity/models/industry-factory-old.glb +0 -0
- package/dist/ingest/simcity/models/industry-factory.glb +0 -0
- package/dist/ingest/simcity/models/industry-refinery.glb +0 -0
- package/dist/ingest/simcity/models/industry-warehouse.glb +0 -0
- package/dist/ingest/simcity/models/power_line_pole_modified.glb +0 -0
- package/dist/ingest/simcity/models/tile-plain_grass.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-curve.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-end.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-intersection-t.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-intersection.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-straight.glb +0 -0
- package/dist/ingest/simcity/models/truck.glb +0 -0
- package/dist/ingest/simcity/statusIcons/no-power.png +0 -0
- package/dist/ingest/simcity/statusIcons/no-road-access.png +0 -0
- package/dist/ingest/simcity/textures/base.png +0 -0
- package/dist/ingest/simcity/textures/grid.png +0 -0
- package/dist/ingest/simcity/textures/specular.png +0 -0
- package/dist/ingest/simcity/three-r155.module.js +51466 -0
- package/dist/ingest/simcity/vgai.game.json +20 -0
- package/dist/ingest/tanks/UPSTREAM.md +69 -0
- package/dist/ingest/tanks/index.html +214 -0
- package/dist/ingest/tanks/models/pixelTank.fbx +0 -0
- package/dist/ingest/tanks/tanks-entry.js +92 -0
- package/dist/ingest/tanks/three-r170.module.js +54571 -0
- package/dist/ingest/tanks/vgai.game.json +20 -0
- package/dist/inputmaps/default.inputmap.json +41 -0
- package/dist/jsm/libs/draco/gltf/draco_decoder.js +33 -0
- package/dist/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/dist/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/dist/scenes/untitled.vscn.json +29 -0
- package/dist/textures/waternormals.jpg +0 -0
- package/dist-server/packaged.mjs +18155 -0
- package/package.json +36 -0
- package/server/asset-library-routes.ts +833 -0
- package/server/canonical-path.ts +50 -0
- package/server/cloud-asset-catalog.ts +101 -0
- package/server/dev.ts +350 -0
- package/server/editor-server.ts +1537 -0
- package/server/editor-sse.ts +73 -0
- package/server/game-globals-shadow.ts +58 -0
- package/server/local-asset-catalog.ts +163 -0
- package/server/packaged.ts +571 -0
- package/server/prod.ts +75 -0
- package/server/project-optimize-deps-entries.ts +149 -0
- package/server/project-view.ts +65 -0
- package/server/server-utils.ts +430 -0
- package/server/session-registry.ts +93 -0
- package/src/EditorContext.tsx +87 -0
- package/src/achieved-tier.ts +126 -0
- package/src/action-registry.ts +268 -0
- package/src/adapter-resolver.ts +1858 -0
- package/src/asset-events.ts +100 -0
- package/src/authoring/active-adapter.ts +98 -0
- package/src/authoring/active-systems.ts +50 -0
- package/src/authoring/boundary-authoring-adapter.ts +178 -0
- package/src/authoring/composite-authoring-adapter.ts +891 -0
- package/src/authoring/design-time-layers.ts +776 -0
- package/src/authoring/edit-mode-authoring.ts +643 -0
- package/src/authoring/embed-only-adapter.ts +57 -0
- package/src/authoring/ephemeral-persistence.ts +26 -0
- package/src/authoring/eyedropper-session.ts +69 -0
- package/src/authoring/first-party-hierarchy-menu.ts +74 -0
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +118 -0
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +550 -0
- package/src/authoring/first-party-inspector/HeaderSection.tsx +329 -0
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +44 -0
- package/src/authoring/first-party-inspector/register.tsx +108 -0
- package/src/authoring/ingest-authoring-adapter.ts +475 -0
- package/src/authoring/ingest-capture.ts +94 -0
- package/src/authoring/ingest-game-adapter.ts +291 -0
- package/src/authoring/ingest-iframe-adapter.ts +38 -0
- package/src/authoring/ingest-iframe-reachable-adapter.ts +401 -0
- package/src/authoring/ingest-overlay.ts +193 -0
- package/src/authoring/layered-pick.ts +87 -0
- package/src/authoring/mount-failure-report.ts +112 -0
- package/src/authoring/overlay-report.ts +52 -0
- package/src/authoring/project-scenes.ts +111 -0
- package/src/authoring/react-dom-authoring-adapter.ts +795 -0
- package/src/authoring/react-inspector-section.tsx +1041 -0
- package/src/authoring/react-world-authoring-adapter.ts +2400 -0
- package/src/authoring/root-activation.ts +61 -0
- package/src/authoring/scene-ui-layer.ts +485 -0
- package/src/authoring/story-overlay.ts +48 -0
- package/src/authoring/ui-authoring-adapter.ts +325 -0
- package/src/authoring/ui-hierarchy-menu.ts +40 -0
- package/src/authoring/ui-inspector-sections.tsx +156 -0
- package/src/authoring/undo-timeline.ts +145 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +746 -0
- package/src/authoring/viewport-pick-context.ts +31 -0
- package/src/authoring/viewport-raycast.ts +80 -0
- package/src/authoring/world-overlay.ts +76 -0
- package/src/authoring/world-pan-state.ts +115 -0
- package/src/authoring/world-session-state.ts +102 -0
- package/src/authoring/world2d-authoring-adapter.ts +313 -0
- package/src/browser-external-watch.ts +98 -0
- package/src/browser-play-entry.ts +112 -0
- package/src/browser-project-scripts.ts +112 -0
- package/src/browser-transpile.ts +246 -0
- package/src/browser-watch-reload.ts +100 -0
- package/src/command-listener.ts +326 -0
- package/src/components/AlignToolbar.tsx +189 -0
- package/src/components/AppRoot.tsx +73 -0
- package/src/components/AssetBrowser.tsx +502 -0
- package/src/components/BottomPanel.tsx +326 -0
- package/src/components/BuildPanel.tsx +455 -0
- package/src/components/CameraInfo.tsx +56 -0
- package/src/components/CommandPalette.tsx +265 -0
- package/src/components/ConsolePanel.tsx +272 -0
- package/src/components/DataPanel.tsx +1268 -0
- package/src/components/DefaultEditorLayout.tsx +509 -0
- package/src/components/FolderTree.tsx +179 -0
- package/src/components/GameHierarchy.tsx +1349 -0
- package/src/components/Inspector.tsx +671 -0
- package/src/components/InspectorToolSection.tsx +74 -0
- package/src/components/MountFailureBanner.tsx +110 -0
- package/src/components/NetworkSection.tsx +109 -0
- package/src/components/OnlineAssetBrowser.tsx +448 -0
- package/src/components/OverlayReportBanner.tsx +122 -0
- package/src/components/PlayBar.tsx +356 -0
- package/src/components/PrefabSaveDialog.tsx +201 -0
- package/src/components/ProjectHeader.tsx +174 -0
- package/src/components/ProjectScreen.tsx +1004 -0
- package/src/components/RightPanel.tsx +166 -0
- package/src/components/RootActivateDialog.tsx +105 -0
- package/src/components/SaveDialog.tsx +197 -0
- package/src/components/SaveStatus.tsx +69 -0
- package/src/components/StatsOverlay.tsx +35 -0
- package/src/components/ToolHost.tsx +80 -0
- package/src/components/Toolbar.tsx +307 -0
- package/src/components/ViewportOverlay.tsx +234 -0
- package/src/components/ViewportPanel.tsx +369 -0
- package/src/components/WorldContextMenu.tsx +257 -0
- package/src/components/WorldSelectionOverlay.tsx +2003 -0
- package/src/components/WorldTextEditor.tsx +86 -0
- package/src/components/asset-viewers/AssetViewer.tsx +38 -0
- package/src/components/asset-viewers/AudioViewer.tsx +149 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +77 -0
- package/src/components/asset-viewers/ImageViewer.tsx +65 -0
- package/src/components/asset-viewers/InputMapViewer.tsx +206 -0
- package/src/components/asset-viewers/ModelViewer.tsx +180 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +236 -0
- package/src/components/data-csv.ts +301 -0
- package/src/components/entity-name-commit.ts +18 -0
- package/src/components/inspector-property-grouping.ts +65 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +188 -0
- package/src/components/inspector-widgets/BorderEditor.tsx +305 -0
- package/src/components/inspector-widgets/ColorPicker.tsx +548 -0
- package/src/components/inspector-widgets/FilterEditor.tsx +108 -0
- package/src/components/inspector-widgets/FontPicker.tsx +196 -0
- package/src/components/inspector-widgets/GradientEditor.tsx +277 -0
- package/src/components/inspector-widgets/ScrubbableInput.tsx +152 -0
- package/src/components/inspector-widgets/ShadowEditor.tsx +332 -0
- package/src/components/inspector-widgets/color-utils.ts +202 -0
- package/src/components/inspector-widgets/gallery-main.tsx +167 -0
- package/src/components/inspector-widgets/index.ts +22 -0
- package/src/components/inspector-widgets/shared.tsx +135 -0
- package/src/components/inspectors/AnimationSection.tsx +143 -0
- package/src/components/inspectors/AudioSection.tsx +215 -0
- package/src/components/inspectors/BoneAttachmentSection.tsx +82 -0
- package/src/components/inspectors/CameraSection.tsx +105 -0
- package/src/components/inspectors/ComponentsSection.tsx +358 -0
- package/src/components/inspectors/JointsSection.tsx +255 -0
- package/src/components/inspectors/LightSection.tsx +116 -0
- package/src/components/inspectors/MaterialSection.tsx +1189 -0
- package/src/components/inspectors/MeshSection.tsx +99 -0
- package/src/components/inspectors/NavigationSection.tsx +58 -0
- package/src/components/inspectors/ParticleSection.tsx +681 -0
- package/src/components/inspectors/PhysicsSection.tsx +326 -0
- package/src/components/inspectors/PostProcessingSection.tsx +1290 -0
- package/src/components/inspectors/RenderingSection.tsx +109 -0
- package/src/components/inspectors/ShadowSection.tsx +84 -0
- package/src/components/inspectors/SplineSection.tsx +191 -0
- package/src/components/inspectors/TransformSection.tsx +191 -0
- package/src/components/inspectors/json-schema-fields.ts +281 -0
- package/src/components/inspectors/multi-edit-utils.ts +49 -0
- package/src/components/inspectors/zod-fields.ts +184 -0
- package/src/components/primitives/ColorInput.tsx +109 -0
- package/src/components/primitives/JsonInput.tsx +98 -0
- package/src/components/primitives/NumberInput.tsx +164 -0
- package/src/components/primitives/Panel.tsx +68 -0
- package/src/components/primitives/SectionHeader.tsx +45 -0
- package/src/components/primitives/Tooltip.tsx +82 -0
- package/src/components/primitives/Vec3Input.tsx +62 -0
- package/src/components/world-overlay-gestures.ts +1438 -0
- package/src/doctor/data-checks.ts +285 -0
- package/src/doctor/report.ts +386 -0
- package/src/editor-api.ts +700 -0
- package/src/editor-console.ts +194 -0
- package/src/editor-hotkeys.ts +441 -0
- package/src/editor-layers.ts +2 -0
- package/src/editor-mode.ts +28 -0
- package/src/editor-store.ts +2225 -0
- package/src/editor-viewport.ts +1924 -0
- package/src/entity-factory.ts +221 -0
- package/src/game-globals-prelude.ts +27 -0
- package/src/gated-globals.ts +131 -0
- package/src/generated/setup-by-example.generated.ts +53 -0
- package/src/gizmo-registry.ts +608 -0
- package/src/handle-system.ts +221 -0
- package/src/hierarchy-menu-registry.ts +70 -0
- package/src/hierarchy-rows.ts +73 -0
- package/src/hosted-example.ts +160 -0
- package/src/hotkeys.ts +142 -0
- package/src/ingest/discovery-react.ts +132 -0
- package/src/ingest/discovery.ts +205 -0
- package/src/ingest/discovery2d.ts +204 -0
- package/src/ingest/esm-entry-resolution.ts +102 -0
- package/src/ingest/games/bloom-composer/game.js +99 -0
- package/src/ingest/games/bloom-composer/vgai.game.json +21 -0
- package/src/ingest/games/embed-bundle/embed.html +10 -0
- package/src/ingest/games/embed-bundle/vgai.game.json +21 -0
- package/src/ingest/games/games-fps/assets/collision-world.glb +0 -0
- package/src/ingest/games/games-fps/game.js +479 -0
- package/src/ingest/games/games-fps/vgai.game.json +24 -0
- package/src/ingest/games/iframe-reachable/game-source.js +58 -0
- package/src/ingest/games/iframe-reachable/vgai.game.json +21 -0
- package/src/ingest/games/interactive-cubes/game.js +139 -0
- package/src/ingest/games/interactive-cubes/vgai.game.json +21 -0
- package/src/ingest/games/mismatched-three/fake-three.js +38 -0
- package/src/ingest/games/mismatched-three/game.js +10 -0
- package/src/ingest/games/mismatched-three/vgai.game.json +22 -0
- package/src/ingest/games/own-three-bundled/game.js +43 -0
- package/src/ingest/games/own-three-bundled/vgai.game.json +21 -0
- package/src/ingest/games/pointerlock-maze/game.js +288 -0
- package/src/ingest/games/pointerlock-maze/vgai.game.json +22 -0
- package/src/ingest/games-2d/_fixtures/first-party-scene.scn2d.json +124 -0
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +25 -0
- package/src/ingest/games-2d/bunnymark/game.ts +88 -0
- package/src/ingest/games-2d/bunnymark/vgai.game.json +21 -0
- package/src/ingest/games-2d/flappy/game.ts +148 -0
- package/src/ingest/games-2d/flappy/vgai.game.json +21 -0
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +25 -0
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +25 -0
- package/src/ingest/games-2d/tilemap-camera/game.ts +115 -0
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +21 -0
- package/src/ingest/games-react/react-rpg/entry.tsx +185 -0
- package/src/ingest/games-react/react-rpg/shims.d.ts +26 -0
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +129 -0
- package/src/ingest/games-react/react-rpg/vgai.game.json +21 -0
- package/src/ingest/host-namespace-registry.ts +196 -0
- package/src/ingest/types.ts +127 -0
- package/src/ingest-hierarchy-rows.ts +207 -0
- package/src/ingest-mode.ts +2092 -0
- package/src/ingest-siblings.ts +466 -0
- package/src/initial-scene.ts +194 -0
- package/src/inspector-section-registry.ts +117 -0
- package/src/interactive-edit-scope.ts +34 -0
- package/src/main.tsx +23 -0
- package/src/manifest-project.ts +43 -0
- package/src/model-thumbnail.ts +156 -0
- package/src/module-mode.ts +513 -0
- package/src/navmesh-handler.ts +94 -0
- package/src/packaged-runtime.ts +49 -0
- package/src/play-mode.ts +1148 -0
- package/src/playground/main.ts +206 -0
- package/src/project-manager.ts +173 -0
- package/src/scene-diff.ts +112 -0
- package/src/scene-serializer.ts +144 -0
- package/src/scene-sync.ts +587 -0
- package/src/scene-ui-mode/active-scene-ui.ts +58 -0
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +152 -0
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +29 -0
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +74 -0
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +49 -0
- package/src/scene-ui-mode/ui-prefab-io.ts +76 -0
- package/src/script-loader.ts +143 -0
- package/src/storage/fsa-storage.ts +55 -0
- package/src/storage/handle-storage.ts +150 -0
- package/src/storage/handle-store.ts +116 -0
- package/src/storage/http-storage.ts +137 -0
- package/src/storage/index.ts +147 -0
- package/src/storage/mem-storage.ts +135 -0
- package/src/storage/opfs-storage.ts +25 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/seed.ts +106 -0
- package/src/storage/types.ts +110 -0
- package/src/tool-loader.ts +291 -0
- package/src/ui-editor/inspector.tsx +563 -0
- package/src/ui-editor/node-ops.ts +266 -0
- package/src/ui-editor/overlay.tsx +380 -0
- package/src/ui-editor/palette.tsx +114 -0
- package/src/ui-editor/react-store.ts +78 -0
- package/src/ui-editor/timeline-panel.tsx +443 -0
- package/src/ui-editor/ui-edit-store.ts +552 -0
- package/src/ui-editor/ui-prefab.ts +95 -0
- package/src/ui-source/inspect.ts +544 -0
- package/src/ui-source/oid-transform.ts +133 -0
- package/src/ui-source/source-write-backend.ts +203 -0
- package/src/ui-source/tailwind-map.ts +174 -0
- package/src/ui-source/writer.ts +1175 -0
- package/src/widgets/index.ts +73 -0
- package/template/.claude/skills/editor/SKILL.md +252 -0
- package/template/CLAUDE.md +512 -0
- package/template/LICENSE +30 -0
- package/template/emit-schemas.ts +42 -0
- package/template/index.html +17 -0
- package/template/package.json +53 -0
- package/template/project.json +9 -0
- package/template/public/audio/ambient-arena.wav +0 -0
- package/template/public/audio/ambient-music.wav +0 -0
- package/template/public/audio/ambient-nature.wav +0 -0
- package/template/public/audio/ambient-wind.wav +0 -0
- package/template/public/inputmaps/default.inputmap.json +41 -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/scenes/default.vscn.json +43 -0
- package/template/public/scenes/untitled.vscn.json +29 -0
- package/template/public/textures/waternormals.jpg +0 -0
- package/template/server/colyseus-setup.ts +85 -0
- package/template/server/main.ts +34 -0
- package/template/server/rooms/arena-room.ts +420 -0
- package/template/server/rooms/game-room.ts +162 -0
- package/template/server/rooms.ts +15 -0
- package/template/server/tsconfig.json +19 -0
- package/template/src/data/README.md +40 -0
- package/template/src/data/assets.ts +31 -0
- package/template/src/data/tuning.data.json +5 -0
- package/template/src/data/tuning.schema.json +21 -0
- package/template/src/data/tuning.schema.ts +34 -0
- package/template/src/data/tuning.ts +24 -0
- package/template/src/main.ts +157 -0
- package/template/src/scripts/components/data-spinner.ts +45 -0
- package/template/src/scripts/components/scene-camera.ts +40 -0
- package/template/src/scripts/main.ts +94 -0
- package/template/src/scripts/registry.ts +46 -0
- package/template/src/tools/README.md +14 -0
- package/template/src/tools/example.tool.tsx +91 -0
- package/template/src/tools/spin.tool.tsx +101 -0
- package/template/src/ui/Button.tsx +27 -0
- package/template/src/ui/DefaultHud.tsx +40 -0
- package/template/src/ui/KeyHint.tsx +25 -0
- package/template/src/ui/Panel.tsx +52 -0
- package/template/src/ui/RebindPanel.tsx +129 -0
- package/template/src/ui/Slider.tsx +28 -0
- package/template/src/ui/StatusDot.tsx +22 -0
- package/template/src/ui/Toggle.tsx +19 -0
- package/template/src/ui/game-state.tsx +37 -0
- package/template/src/ui/index.ts +7 -0
- package/template/src/ui/mount-default-hud.tsx +19 -0
- package/template/src/ui/mount-ui.ts +15 -0
- package/template/tsconfig.json +36 -0
- package/template/validate-asset-content.ts +78 -0
- package/template/validate-manifest.ts +55 -0
- package/template/validate-scenes.ts +211 -0
- package/template/vgai.game.json +21 -0
- package/template/vite.config.ts +128 -0
- package/vite-plugin-example-assets.ts +60 -0
- package/vite-plugin-game-globals.ts +46 -0
- package/vite-plugin-game-static.ts +71 -0
- package/vite-plugin-project-game-static.ts +84 -0
- package/vite-plugin-react-game-static.ts +98 -0
- package/vite-plugin-react-world-provider.ts +81 -0
- package/vite-plugin-react-world-runtime.ts +76 -0
- package/vite-plugin-ui-oid.ts +561 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { watchSceneChanges } from './browser-watch-reload';
|
|
2
|
+
import { connectEvents } from './editor-api';
|
|
3
|
+
import { getEditorMode } from './editor-mode';
|
|
4
|
+
|
|
5
|
+
export interface AssetMovedEvent {
|
|
6
|
+
oldPath: string;
|
|
7
|
+
newPath: string;
|
|
8
|
+
updatedFiles: string[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface SceneChangedEvent {
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Connect to the editor server's SSE endpoint for asset events.
|
|
18
|
+
* Returns a cleanup function to disconnect.
|
|
19
|
+
*/
|
|
20
|
+
export function connectAssetEvents(onAssetMoved: (event: AssetMovedEvent) => void): () => void {
|
|
21
|
+
// Browser mode (Phase A2): no Node dev server / SSE. A rename can't be
|
|
22
|
+
// reconstructed from self-derived watch events — a move surfaces as an
|
|
23
|
+
// unlinked `remove` + `create` with no old→new pairing — so asset-move sync
|
|
24
|
+
// stays a server-only signal (revisit with A4's external-change detection).
|
|
25
|
+
if (getEditorMode() === 'browser') {
|
|
26
|
+
void onAssetMoved;
|
|
27
|
+
return () => {};
|
|
28
|
+
}
|
|
29
|
+
const source = connectEvents();
|
|
30
|
+
|
|
31
|
+
source.addEventListener('asset-moved', (e: MessageEvent) => {
|
|
32
|
+
try {
|
|
33
|
+
const data = JSON.parse(e.data) as AssetMovedEvent;
|
|
34
|
+
onAssetMoved(data);
|
|
35
|
+
} catch {
|
|
36
|
+
/* ignore malformed events */
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return () => source.close();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Connect to the editor server's SSE endpoint for scene file changes.
|
|
45
|
+
* Returns a cleanup function to disconnect.
|
|
46
|
+
*/
|
|
47
|
+
export function connectSceneEvents(onSceneChanged: (event: SceneChangedEvent) => void): () => void {
|
|
48
|
+
// Browser mode (Phase A2): no Node dev server / SSE. Derive scene-change
|
|
49
|
+
// events from the storage backend's own writes — the browser backend is the
|
|
50
|
+
// sole writer, so its self-derived events are the change signal (own-write
|
|
51
|
+
// echoes are suppressed downstream by the store's `_lastSavedContent` guard).
|
|
52
|
+
// See browser-watch-reload.ts.
|
|
53
|
+
if (getEditorMode() === 'browser') {
|
|
54
|
+
return watchSceneChanges(onSceneChanged);
|
|
55
|
+
}
|
|
56
|
+
const source = connectEvents();
|
|
57
|
+
|
|
58
|
+
source.addEventListener('scene-changed', (e: MessageEvent) => {
|
|
59
|
+
try {
|
|
60
|
+
const data = JSON.parse(e.data) as SceneChangedEvent;
|
|
61
|
+
onSceneChanged(data);
|
|
62
|
+
} catch {
|
|
63
|
+
/* ignore malformed events */
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return () => source.close();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Connect to the editor server's SSE endpoint for project TOOL file
|
|
72
|
+
* add/unlink events (W6a, docs/DATA-TOOLS-DESIGN.md §7 W4 field note c). The
|
|
73
|
+
* server's `src/`-scoped watcher (`editor-server.ts`'s `startWatcher()`)
|
|
74
|
+
* broadcasts `tool-files-changed` whenever a `src/tools/*.tool.tsx` is added
|
|
75
|
+
* or removed; the event carries no payload of substance beyond the touched
|
|
76
|
+
* path — callers just re-run their own full rescan (`refreshProjectTools` is
|
|
77
|
+
* cheap by design, same physics as the D3 "discovery IS the folder scan"
|
|
78
|
+
* rule the DATA tab already follows).
|
|
79
|
+
*/
|
|
80
|
+
export function connectToolFileEvents(onChanged: () => void): () => void {
|
|
81
|
+
// Browser mode: no Node dev server / SSE — a project-src file add/remove
|
|
82
|
+
// can't be observed from the browser sandbox anyway (no filesystem watch).
|
|
83
|
+
if (getEditorMode() === 'browser') return () => {};
|
|
84
|
+
const source = connectEvents();
|
|
85
|
+
source.addEventListener('tool-files-changed', () => onChanged());
|
|
86
|
+
return () => source.close();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Connect to the editor server's SSE endpoint for project DATA file
|
|
91
|
+
* add/unlink events (W6a). Mirrors `connectToolFileEvents` for
|
|
92
|
+
* `src/data/*.data.json` / `*.schema.json` — the DATA tab's `refresh()` is
|
|
93
|
+
* the same rescan `active`-tab activation already triggers.
|
|
94
|
+
*/
|
|
95
|
+
export function connectDataFileEvents(onChanged: () => void): () => void {
|
|
96
|
+
if (getEditorMode() === 'browser') return () => {};
|
|
97
|
+
const source = connectEvents();
|
|
98
|
+
source.addEventListener('data-files-changed', () => onChanged());
|
|
99
|
+
return () => source.close();
|
|
100
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor's active {@link AuthoringAdapter} handle.
|
|
3
|
+
*
|
|
4
|
+
* The editor UI talks to the authoring contract through THIS accessor rather than
|
|
5
|
+
* reaching into `EditorStore` / `SceneEntity` directly. Today the only implementer
|
|
6
|
+
* is {@link VgaiSceneAuthoringAdapter} (first-party `.vscn`), so the accessor wraps
|
|
7
|
+
* the active store; when an ingested game is mounted (Phase B) the same accessor
|
|
8
|
+
* returns its `IngestAuthoringAdapter` and the UI code below it does not change.
|
|
9
|
+
*
|
|
10
|
+
* The adapter is a stateless delegating wrapper over the store, so we memoize one
|
|
11
|
+
* per store (a store's identity is stable for the editor session).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { AuthoringAdapter } from '@engine/adapter';
|
|
15
|
+
import type { EditorStore } from '../editor-store';
|
|
16
|
+
import { VgaiSceneAuthoringAdapter } from './vgai-scene-authoring-adapter';
|
|
17
|
+
|
|
18
|
+
const byStore = new WeakMap<EditorStore, AuthoringAdapter>();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A non-first-party adapter (today: the ingest adapter for an unmodified game)
|
|
22
|
+
* that, while set, becomes the active authoring adapter. The editor renders its
|
|
23
|
+
* adapter-driven (format-neutral) hierarchy/inspector panels instead of the
|
|
24
|
+
* first-party `SceneEntity` panels while an override is active.
|
|
25
|
+
*/
|
|
26
|
+
let _override: AuthoringAdapter | null = null;
|
|
27
|
+
|
|
28
|
+
/** Install/clear the active authoring override (ingest mode enters/exits). */
|
|
29
|
+
export function setActiveAuthoring(adapter: AuthoringAdapter | null): void {
|
|
30
|
+
_override = adapter;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** True when a non-first-party adapter is driving authoring (e.g. ingest). */
|
|
34
|
+
export function hasAuthoringOverride(): boolean {
|
|
35
|
+
return _override !== null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A1 — brand for the edit-mode composite (`edit-mode-authoring.ts`). Unlike an
|
|
40
|
+
* ingest/play override — a FOREIGN adapter whose document the store does not
|
|
41
|
+
* own — the edit-mode composite's FOCUSED child is the store's own first-party
|
|
42
|
+
* `VgaiSceneAuthoringAdapter` writing through the store's own save path. So
|
|
43
|
+
* the store's save guard (`_blockedForSave`) must NOT block it: an edit to the
|
|
44
|
+
* focused world must Ctrl+S/autosave to disk exactly like a single-scene
|
|
45
|
+
* project. The brand lives on the composite instance and disappears the moment
|
|
46
|
+
* `setActiveAuthoring(null)` clears the slot (the predicate checks the CURRENT
|
|
47
|
+
* `_override`'s identity), so no separate lifecycle state can go stale.
|
|
48
|
+
*/
|
|
49
|
+
const EDIT_MODE_BRAND = Symbol('vgai.editModeComposite');
|
|
50
|
+
|
|
51
|
+
/** Mark `adapter` as the edit-mode composite (A1). */
|
|
52
|
+
export function markEditModeOverride(adapter: AuthoringAdapter): void {
|
|
53
|
+
(adapter as unknown as Record<symbol, unknown>)[EDIT_MODE_BRAND] = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** True when the ACTIVE override is the edit-mode composite (A1) — the store's
|
|
57
|
+
* save guard allows the focused first-party child to persist through it. */
|
|
58
|
+
export function activeOverrideIsEditMode(): boolean {
|
|
59
|
+
return (
|
|
60
|
+
_override !== null &&
|
|
61
|
+
(_override as unknown as Record<symbol, unknown>)[EDIT_MODE_BRAND] === true
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Peek the raw override slot (or null) without a store handle — for a session
|
|
67
|
+
* that needs to install ITS OWN override while preserving whatever was active
|
|
68
|
+
* before it, so it can restore that exact value on exit instead of assuming
|
|
69
|
+
* null (e.g. play-mode's ephemeral-persistence wrapper, T3.2 slice 1).
|
|
70
|
+
*/
|
|
71
|
+
export function getAuthoringOverride(): AuthoringAdapter | null {
|
|
72
|
+
return _override;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Every node id in an adapter's hierarchy (for select-all over an ingested tree). */
|
|
76
|
+
export function collectAllNodeIds(adapter: AuthoringAdapter): string[] {
|
|
77
|
+
const ids: string[] = [];
|
|
78
|
+
const walk = (node: { id: string; childIds: string[] }): void => {
|
|
79
|
+
ids.push(node.id);
|
|
80
|
+
for (const cid of node.childIds) {
|
|
81
|
+
const c = adapter.hierarchy.node(cid);
|
|
82
|
+
if (c) walk(c);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
for (const r of adapter.hierarchy.roots()) walk(r);
|
|
86
|
+
return ids;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** The authoring adapter the editor UI should drive for `store`. */
|
|
90
|
+
export function getActiveAuthoring(store: EditorStore): AuthoringAdapter {
|
|
91
|
+
if (_override) return _override;
|
|
92
|
+
let a = byStore.get(store);
|
|
93
|
+
if (!a) {
|
|
94
|
+
a = new VgaiSceneAuthoringAdapter(store);
|
|
95
|
+
byStore.set(store, a);
|
|
96
|
+
}
|
|
97
|
+
return a;
|
|
98
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active system adapters the editor's authoring path coordinates with.
|
|
3
|
+
*
|
|
4
|
+
* A mounted game may expose `SystemAdapters` (physics / networking / …). The
|
|
5
|
+
* editor's gizmo-commit (through the `AuthoringAdapter.transforms` provider)
|
|
6
|
+
* consults THESE so it can:
|
|
7
|
+
* - freeze a physics-owned body while the gizmo edits it, then commit the edited
|
|
8
|
+
* pose to the body and resume (the founding doc's "frozen edit" mode —
|
|
9
|
+
* generalizes the old `setEcsSyncTransform` teleport behind `PhysicsAdapter`);
|
|
10
|
+
* - report a network-owned object's authority and keep remote/server-authoritative
|
|
11
|
+
* objects inspect-only (`NetworkingAdapter`).
|
|
12
|
+
*
|
|
13
|
+
* Play-mode (first-party) installs the first-party `RapierPhysicsAdapter` /
|
|
14
|
+
* `ColyseusNetworkingAdapter` here on enter and clears them on exit; an ingested
|
|
15
|
+
* game would install its own. The editor never names Rapier/Colyseus — only the
|
|
16
|
+
* `PhysicsAdapter` / `NetworkingAdapter` interfaces.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { SystemAdapters } from '@engine/adapter';
|
|
20
|
+
|
|
21
|
+
let _systems: SystemAdapters = {};
|
|
22
|
+
|
|
23
|
+
/** Install the active mounted game's System adapters (play-mode on enter). */
|
|
24
|
+
export function setActiveSystems(systems: SystemAdapters | null): void {
|
|
25
|
+
_systems = systems ?? {};
|
|
26
|
+
}
|
|
27
|
+
/** The active System adapters (physics/networking/input/assets/animation/navigation). */
|
|
28
|
+
export function getActiveSystems(): SystemAdapters {
|
|
29
|
+
return _systems;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function setActivePhysics(p: SystemAdapters['physics'] | null): void {
|
|
33
|
+
const next = { ..._systems };
|
|
34
|
+
if (p) next.physics = p;
|
|
35
|
+
else delete next.physics;
|
|
36
|
+
_systems = next;
|
|
37
|
+
}
|
|
38
|
+
export function getActivePhysics(): SystemAdapters['physics'] | null {
|
|
39
|
+
return _systems.physics ?? null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function setActiveNetworking(n: SystemAdapters['networking'] | null): void {
|
|
43
|
+
const next = { ..._systems };
|
|
44
|
+
if (n) next.networking = n;
|
|
45
|
+
else delete next.networking;
|
|
46
|
+
_systems = next;
|
|
47
|
+
}
|
|
48
|
+
export function getActiveNetworking(): SystemAdapters['networking'] | null {
|
|
49
|
+
return _systems.networking ?? null;
|
|
50
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BoundaryAuthoringAdapter — A1's read-only {@link AuthoringAdapter} for a
|
|
3
|
+
* manifest-declared world that is NOT currently mounted (edit mode only runs
|
|
4
|
+
* the FOCUSED threejs world live — every other declared world is disclosed,
|
|
5
|
+
* not simulated; see `edit-mode-authoring.ts`'s doc comment for the seam this
|
|
6
|
+
* plugs into, and B1 for the "mount it live" upgrade path).
|
|
7
|
+
*
|
|
8
|
+
* A single node, one per world: label = the world id (or, for an unresolvable
|
|
9
|
+
* world, `⚠ <id> (unresolvable)` — #18, never a silent drop), `kind` = the
|
|
10
|
+
* manifest world kind, inspector exposes kind/adapter/entry-or-scene
|
|
11
|
+
* path/zOrder/pausable (+ `reason` when unresolvable) as READ-ONLY
|
|
12
|
+
* properties. No children, no live object, no structural/transform ops — this
|
|
13
|
+
* adapter's entire job is "say the world exists and why it isn't live yet".
|
|
14
|
+
*
|
|
15
|
+
* Resolvability is a CALLER decision (`edit-mode-authoring.ts` computes the
|
|
16
|
+
* reason from the manifest world entry) — this adapter just renders whatever
|
|
17
|
+
* reason string it's given; it never itself decides a world is broken.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type {
|
|
21
|
+
AuthoringAdapter,
|
|
22
|
+
AuthoringCapabilities,
|
|
23
|
+
EditorNode,
|
|
24
|
+
HierarchyProvider,
|
|
25
|
+
InspectorProvider,
|
|
26
|
+
PickProvider,
|
|
27
|
+
PropertyDescriptor,
|
|
28
|
+
SelectionProvider,
|
|
29
|
+
} from '@engine/adapter';
|
|
30
|
+
import type * as THREE from 'three';
|
|
31
|
+
import type { EditorStore } from '../editor-store';
|
|
32
|
+
|
|
33
|
+
/** The display-relevant slice of a manifest world entry — deliberately loose
|
|
34
|
+
* (plain strings, not the engine's validated `WorldEntry['kind']` union) so
|
|
35
|
+
* an UNRESOLVABLE world (unknown kind, e.g.) can still be described. */
|
|
36
|
+
export interface BoundaryWorldInfo {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly kind: string;
|
|
39
|
+
/** Display string for the manifest's `adapter` field (e.g. `'default'`,
|
|
40
|
+
* `'module:<path>'`) — omitted when not meaningfully derivable. */
|
|
41
|
+
readonly adapter?: string | undefined;
|
|
42
|
+
/** Whichever of `scene`/`entry` the world declares (display-only — this
|
|
43
|
+
* adapter never reads the file). */
|
|
44
|
+
readonly entryOrScenePath?: string | undefined;
|
|
45
|
+
readonly zOrder: number;
|
|
46
|
+
readonly pausable: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const NO_CAPABILITIES: AuthoringCapabilities = {
|
|
50
|
+
transform: false,
|
|
51
|
+
material: false,
|
|
52
|
+
inspectorFields: false,
|
|
53
|
+
create: false,
|
|
54
|
+
delete: false,
|
|
55
|
+
reparent: false,
|
|
56
|
+
persist: false,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export class BoundaryAuthoringAdapter implements AuthoringAdapter {
|
|
60
|
+
readonly capabilities: AuthoringCapabilities = NO_CAPABILITIES;
|
|
61
|
+
private readonly world: BoundaryWorldInfo;
|
|
62
|
+
/** Non-null ⇒ error-node mode (#18) — set by the caller, never computed here. */
|
|
63
|
+
private readonly reason: string | null;
|
|
64
|
+
private readonly store: EditorStore;
|
|
65
|
+
/**
|
|
66
|
+
* D12 (B4) — a pixi design-time layer's stage hit-test, wired in by
|
|
67
|
+
* `design-time-layers.ts`'s `mountPixiLayer` success handler (a Boundary is
|
|
68
|
+
* still the pixi world's ONLY authoring adapter for the whole S-B effort —
|
|
69
|
+
* see this class's own doc comment — so its `pickable` rides on THIS
|
|
70
|
+
* adapter rather than a second pixi-specific one). Absent for every other
|
|
71
|
+
* Boundary (an unresolved/error world, or any non-pixi world) ⇒ this
|
|
72
|
+
* adapter reports no `pickable` at all, today's behavior. A plain
|
|
73
|
+
* conditionally-assigned field (not a getter always returning `{ pick:
|
|
74
|
+
* undefined }`) — this repo's `exactOptionalPropertyTypes` requires the key
|
|
75
|
+
* to be genuinely ABSENT, not present with an `undefined` value, to satisfy
|
|
76
|
+
* `AuthoringAdapter.pickable?: PickProvider`.
|
|
77
|
+
*/
|
|
78
|
+
readonly pickable?: PickProvider;
|
|
79
|
+
|
|
80
|
+
constructor(
|
|
81
|
+
store: EditorStore,
|
|
82
|
+
world: BoundaryWorldInfo,
|
|
83
|
+
reason?: string,
|
|
84
|
+
pick?: PickProvider['pick'],
|
|
85
|
+
) {
|
|
86
|
+
this.store = store;
|
|
87
|
+
this.world = world;
|
|
88
|
+
this.reason = reason ?? null;
|
|
89
|
+
if (pick) this.pickable = { pick };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private get label(): string {
|
|
93
|
+
return this.reason ? `⚠ ${this.world.id} (unresolvable)` : this.world.id;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private get node(): EditorNode {
|
|
97
|
+
return {
|
|
98
|
+
id: this.world.id,
|
|
99
|
+
label: this.label,
|
|
100
|
+
kind: this.world.kind,
|
|
101
|
+
parentId: null,
|
|
102
|
+
childIds: [],
|
|
103
|
+
flags: {},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
readonly hierarchy: HierarchyProvider = {
|
|
108
|
+
roots: (): EditorNode[] => [this.node],
|
|
109
|
+
node: (id) => (id === this.world.id ? this.node : null),
|
|
110
|
+
object3D: (_id) => null,
|
|
111
|
+
idForObject3D: (_o: THREE.Object3D) => null,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Selection delegates to the editor-global {@link EditorStore} selection set
|
|
116
|
+
* — the SAME seam `IngestAuthoringAdapter`/`ReactWorldAuthoringAdapter` use
|
|
117
|
+
* (selection is editor UI state, not a per-adapter document concern). Without
|
|
118
|
+
* this, clicking a Boundary/error node in `IngestHierarchy` (the panel the
|
|
119
|
+
* composite drives) would be a silent no-op, so the node — and its `reason`
|
|
120
|
+
* (#18) — could never be selected or inspected (defect 3). It also makes the
|
|
121
|
+
* composite's empty-clear (`selection.set([])` routed to `children[0]`) work
|
|
122
|
+
* when a Boundary sorts first (defect 4).
|
|
123
|
+
*/
|
|
124
|
+
readonly selection: SelectionProvider = {
|
|
125
|
+
get: () => [...this.store.selectedEntityIds],
|
|
126
|
+
set: (ids) => this.store.selectMultiple(ids),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
readonly inspector: InspectorProvider = {
|
|
130
|
+
properties: (id): PropertyDescriptor[] => {
|
|
131
|
+
if (id !== this.world.id) return [];
|
|
132
|
+
const props: PropertyDescriptor[] = [
|
|
133
|
+
{ path: 'kind', label: 'Kind', type: 'string', readonly: true },
|
|
134
|
+
];
|
|
135
|
+
if (this.world.adapter !== undefined) {
|
|
136
|
+
props.push({ path: 'adapter', label: 'Adapter', type: 'string', readonly: true });
|
|
137
|
+
}
|
|
138
|
+
if (this.world.entryOrScenePath !== undefined) {
|
|
139
|
+
props.push({ path: 'path', label: 'Entry / Scene', type: 'string', readonly: true });
|
|
140
|
+
}
|
|
141
|
+
props.push(
|
|
142
|
+
{ path: 'zOrder', label: 'Z Order', type: 'number', readonly: true },
|
|
143
|
+
{ path: 'pausable', label: 'Pausable', type: 'boolean', readonly: true },
|
|
144
|
+
);
|
|
145
|
+
if (this.reason) {
|
|
146
|
+
props.push({ path: 'reason', label: 'Reason', type: 'string', readonly: true });
|
|
147
|
+
}
|
|
148
|
+
return props;
|
|
149
|
+
},
|
|
150
|
+
get: (id, path) => {
|
|
151
|
+
if (id !== this.world.id) return undefined;
|
|
152
|
+
switch (path) {
|
|
153
|
+
case 'kind':
|
|
154
|
+
return this.world.kind;
|
|
155
|
+
case 'adapter':
|
|
156
|
+
return this.world.adapter;
|
|
157
|
+
case 'path':
|
|
158
|
+
return this.world.entryOrScenePath;
|
|
159
|
+
case 'zOrder':
|
|
160
|
+
return this.world.zOrder;
|
|
161
|
+
case 'pausable':
|
|
162
|
+
return this.world.pausable;
|
|
163
|
+
case 'reason':
|
|
164
|
+
return this.reason ?? undefined;
|
|
165
|
+
default:
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
// Read-only — every property above is display-derived from the manifest;
|
|
170
|
+
// there is nowhere to persist a write to (matches how a not-yet-mounted
|
|
171
|
+
// world has no live document). No-op rather than throw, matching the
|
|
172
|
+
// reserved-paths convention's "adapters that don't support a path simply
|
|
173
|
+
// don't offer it" floor.
|
|
174
|
+
set: (_id, _path, _value) => {
|
|
175
|
+
// Intentionally inert.
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|