@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,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IngestGameAdapter — the {@link GameAdapter} for an UNMODIFIED external three.js
|
|
3
|
+
* game. Its `mount()` is the host-and-ingest path: install the render accessor
|
|
4
|
+
* trap on the shared `three`, run the unmodified game (its own renderer/scene/
|
|
5
|
+
* camera/rAF), capture its live scene on the first frame, and return a
|
|
6
|
+
* {@link MountedGame} whose `authoring` is the {@link IngestAuthoringAdapter} over
|
|
7
|
+
* that live `Object3D` tree. `drivesOwnLoop` is true — the host does not tick it.
|
|
8
|
+
*
|
|
9
|
+
* This is the runtime half of the Phase-B inversion: an unmodified game becomes a
|
|
10
|
+
* peer implementer of the SAME `GameAdapter`/`MountedGame` contract first-party
|
|
11
|
+
* content uses — no `SceneEntity`, no separate editor data model.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { MountedGame } from '@engine/adapter';
|
|
15
|
+
import { readGameContract } from '@engine/adapter/ingest/game-contract';
|
|
16
|
+
import { installSceneCapture, type SceneCaptureHandle } from '@engine/adapter/ingest/scene-capture';
|
|
17
|
+
import { formatLoopGateMessage } from '@engine/adapter/loop-gate-report';
|
|
18
|
+
import * as THREE from 'three';
|
|
19
|
+
// Wave 17 (docs/WAVE17-F13-COMPOSER-RESIZE-FIX-DESIGN.md, D-C2/D-C3): the SAME
|
|
20
|
+
// `EffectComposer` class an ingested game's own `import 'three/examples/jsm/
|
|
21
|
+
// postprocessing/EffectComposer.js'` resolves to (deduped by `resolve.dedupe:
|
|
22
|
+
// ['three', …]` in vite.config.ts — the addon is a file inside the same
|
|
23
|
+
// `three` package tree, not a separately-deduped package). Passed into
|
|
24
|
+
// `installSceneCapture` so the host can also resize a game's own composer.
|
|
25
|
+
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
26
|
+
import type { EditorStore } from '../editor-store';
|
|
27
|
+
import type { IngestGame } from '../ingest/types';
|
|
28
|
+
import { IngestAuthoringAdapter } from './ingest-authoring-adapter';
|
|
29
|
+
import type { IngestOverlay } from './ingest-overlay';
|
|
30
|
+
|
|
31
|
+
export interface MountIngestOptions {
|
|
32
|
+
/** Saved overlay (previous-session edits) to reapply once the scene is walked. */
|
|
33
|
+
overlay?: IngestOverlay | undefined;
|
|
34
|
+
/** Persist callback for `persistence.save()`; absence ⇒ runtime-only. */
|
|
35
|
+
persist?: ((overlay: IngestOverlay) => Promise<void>) | undefined;
|
|
36
|
+
/** Human-readable overlay destination (design §2) — see `overlayPath()`. */
|
|
37
|
+
destination?: string | undefined;
|
|
38
|
+
/** Capture timeout; on expiry the game is degraded to embed-only (default 10s). */
|
|
39
|
+
captureTimeoutMs?: number | undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A mounted ingest game plus the host-side handles the editor needs to tear down. */
|
|
43
|
+
export interface IngestMount {
|
|
44
|
+
game: MountedGame;
|
|
45
|
+
/** The live-scene authoring adapter — absent when capture failed (embedOnly). */
|
|
46
|
+
authoring?: IngestAuthoringAdapter;
|
|
47
|
+
hostEl: HTMLElement;
|
|
48
|
+
/** Live capture stats (draw count, child count) for proof/telemetry. */
|
|
49
|
+
capture: SceneCaptureHandle;
|
|
50
|
+
/** The captured scene (== game.scene) — absent when capture failed (embedOnly). */
|
|
51
|
+
scene?: THREE.Scene;
|
|
52
|
+
/** True when the game's `three` was unreachable (bundled/mismatched) → embed-only. */
|
|
53
|
+
embedOnly?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* D10/T7.6 loop-gate honesty check, extracted for direct unit testing
|
|
58
|
+
* (`ingest-game-adapter-loop-gate.test.ts`): builds the `setPaused` a mounted
|
|
59
|
+
* ingest game exposes to `Game.play.pause()`/`resume()` — separate from
|
|
60
|
+
* `IngestAuthoringAdapter`'s own edit-time `loop.pause()`/`loop.resume()`
|
|
61
|
+
* (gizmo freeze/unfreeze), which always calls through regardless of whether
|
|
62
|
+
* the loop is genuinely gateable. `capture.getAnimationLoop(renderer)` is
|
|
63
|
+
* `null` exactly when this game drives its loop via raw `requestAnimationFrame`
|
|
64
|
+
* instead of `renderer.setAnimationLoop` — a case `loop.pause()` (which just
|
|
65
|
+
* calls `setAnimationLoop(null)`) cannot gate at all (D5/COMPOSITION-DESIGN.md
|
|
66
|
+
* §5.2: gating a raw-rAF loop from outside was demonstrated and rejected).
|
|
67
|
+
* Reports loudly, once, instead of silently pretending the pause worked.
|
|
68
|
+
*/
|
|
69
|
+
export function createIngestLoopGate(
|
|
70
|
+
capture: Pick<SceneCaptureHandle, 'getAnimationLoop'>,
|
|
71
|
+
renderer: THREE.WebGLRenderer,
|
|
72
|
+
worldId: string,
|
|
73
|
+
loop: { pause(): void; resume(): void },
|
|
74
|
+
): { setPaused(paused: boolean): void } {
|
|
75
|
+
let reportedUngateable = false;
|
|
76
|
+
return {
|
|
77
|
+
setPaused(paused: boolean) {
|
|
78
|
+
if (paused && !capture.getAnimationLoop(renderer)) {
|
|
79
|
+
if (!reportedUngateable) {
|
|
80
|
+
reportedUngateable = true;
|
|
81
|
+
// A NEW native console.warn site — suppressed to keep this task's
|
|
82
|
+
// diff at zero NEW lint warnings (same reasoning as
|
|
83
|
+
// `overlay-report.ts`'s identical suppression / `runtime/game.ts`'s
|
|
84
|
+
// `reportGateShortfallOnce`).
|
|
85
|
+
// biome-ignore lint/suspicious/noConsole: see comment above
|
|
86
|
+
console.warn(
|
|
87
|
+
formatLoopGateMessage({
|
|
88
|
+
worldId,
|
|
89
|
+
reason:
|
|
90
|
+
'raw requestAnimationFrame — this game never called renderer.setAnimationLoop, ' +
|
|
91
|
+
'so its loop cannot be gated from outside',
|
|
92
|
+
}),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (paused) loop.pause();
|
|
98
|
+
else loop.resume();
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Wait until the game's async world (e.g. a streamed GLTF) stops growing. */
|
|
104
|
+
async function waitForSceneToSettle(scene: THREE.Scene, maxMs = 5000): Promise<void> {
|
|
105
|
+
const start = performance.now();
|
|
106
|
+
let last = -1;
|
|
107
|
+
let stableTicks = 0;
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
const tick = () => {
|
|
110
|
+
const n = scene.children.length;
|
|
111
|
+
stableTicks = n === last ? stableTicks + 1 : 0;
|
|
112
|
+
last = n;
|
|
113
|
+
if (stableTicks >= 3 || performance.now() - start > maxMs) return resolve();
|
|
114
|
+
setTimeout(tick, 120);
|
|
115
|
+
};
|
|
116
|
+
tick();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Mount an unmodified game and capture its live scene as a `MountedGame`.
|
|
122
|
+
* `store` is needed by the authoring adapter for shared selection state; the
|
|
123
|
+
* captured objects get stable structural-path ids tagged on `userData.entityId`
|
|
124
|
+
* (identity only — NOT a fabricated SceneEntity).
|
|
125
|
+
*/
|
|
126
|
+
export async function mountIngestGame(
|
|
127
|
+
store: EditorStore,
|
|
128
|
+
game: IngestGame,
|
|
129
|
+
gameContainer: HTMLElement,
|
|
130
|
+
opts: MountIngestOptions = {},
|
|
131
|
+
): Promise<IngestMount> {
|
|
132
|
+
// The upstream games expect an element with id="container" to mount into.
|
|
133
|
+
const hostEl = document.createElement('div');
|
|
134
|
+
hostEl.id = 'container';
|
|
135
|
+
hostEl.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;overflow:hidden;';
|
|
136
|
+
gameContainer.appendChild(hostEl);
|
|
137
|
+
|
|
138
|
+
// DOM-shim: stub the elements a DOM-dependent game expects (e.g. #blocker),
|
|
139
|
+
// so its getElementById calls succeed without editing the game.
|
|
140
|
+
const stubEls: HTMLElement[] = [];
|
|
141
|
+
for (const id of game.domStubs ?? []) {
|
|
142
|
+
if (document.getElementById(id)) continue;
|
|
143
|
+
const stub = document.createElement('div');
|
|
144
|
+
stub.id = id;
|
|
145
|
+
stub.style.display = 'none';
|
|
146
|
+
hostEl.appendChild(stub);
|
|
147
|
+
stubEls.push(stub);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 1. Trap the shared three's renderer (the game's `import 'three'` resolves here).
|
|
151
|
+
// Also pass the shared `EffectComposer` addon ctor (Wave 17, D-C2) so a
|
|
152
|
+
// game's own composer is collected too — resize wiring below (D-C3).
|
|
153
|
+
const capture: SceneCaptureHandle = installSceneCapture(THREE, EffectComposer);
|
|
154
|
+
|
|
155
|
+
// 2. Asset-path adapter: redirect the game's relative asset paths to the served files.
|
|
156
|
+
if (game.assets) {
|
|
157
|
+
const map = game.assets;
|
|
158
|
+
THREE.DefaultLoadingManager.setURLModifier((url) => {
|
|
159
|
+
for (const key of Object.keys(map)) if (url.includes(key)) return map[key]!;
|
|
160
|
+
return url;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 3. Run the unmodified game; the trap captures on its first rendered frame.
|
|
165
|
+
// Signal COLD MOUNT before the entry executes: editor mounts are for
|
|
166
|
+
// inspection first, so a session-driven game MAY defer its side-effects
|
|
167
|
+
// (backend connection, narrative, audio) until the editor's play control
|
|
168
|
+
// dispatches 'vgai:ingest-play' (getIngestPlayControl, ingest-mode.ts).
|
|
169
|
+
// Rendering must continue regardless — capture needs a frame — and games
|
|
170
|
+
// that ignore the flag behave exactly as before (opt-in, never demanded).
|
|
171
|
+
(window as unknown as { __vgaiMountCold?: boolean }).__vgaiMountCold = true;
|
|
172
|
+
if (!game.load) throw new Error(`Ingest game "${game.id}" has no module loader`);
|
|
173
|
+
await game.load();
|
|
174
|
+
let rt: Awaited<ReturnType<SceneCaptureHandle['waitForCapture']>>;
|
|
175
|
+
try {
|
|
176
|
+
rt = await capture.waitForCapture(opts.captureTimeoutMs ?? 10_000);
|
|
177
|
+
} catch {
|
|
178
|
+
// Capture failed: the game's `three` is unreachable — a bundled/MISMATCHED
|
|
179
|
+
// version the host trap can't instrument. Degrade gracefully to embed-only
|
|
180
|
+
// (host whatever the game rendered; no scene introspection) — never a silent
|
|
181
|
+
// failure. (docs/UNMODIFIED-GAME-INGESTION-STUDY.md §4A — the version gatekeeper.)
|
|
182
|
+
const dummyScene = new THREE.Scene();
|
|
183
|
+
return {
|
|
184
|
+
embedOnly: true,
|
|
185
|
+
hostEl,
|
|
186
|
+
capture,
|
|
187
|
+
game: {
|
|
188
|
+
kind: 'threejs',
|
|
189
|
+
scene: dummyScene,
|
|
190
|
+
camera: new THREE.PerspectiveCamera(),
|
|
191
|
+
drivesOwnLoop: true,
|
|
192
|
+
resize: () => {},
|
|
193
|
+
dispose: () => {
|
|
194
|
+
capture.uninstall();
|
|
195
|
+
THREE.DefaultLoadingManager.setURLModifier((u) => u);
|
|
196
|
+
for (const el of stubEls) el.remove();
|
|
197
|
+
hostEl.remove();
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Some games append their canvas to document.body — reparent it into the host.
|
|
204
|
+
// A DOM-hybrid game (React/R3F with HTML UI: HUDs, overlay panels, drei <Html>
|
|
205
|
+
// portals) can declare the element that OWNS its canvas via
|
|
206
|
+
// `window.__vgaiGameRoot`; adopting only the bare canvas would strand that UI
|
|
207
|
+
// at the page level over the editor chrome, and following the canvas would
|
|
208
|
+
// require the game to know host layout internals — an arcane demand. Adopt the
|
|
209
|
+
// declared root wholesale so the game's own DOM structure survives intact;
|
|
210
|
+
// games that declare nothing keep the bare-canvas behavior.
|
|
211
|
+
// Contract-first: `window.vgaiGame.root` (the declared game→host contract,
|
|
212
|
+
// game-contract.ts; capabilities by presence) with the pre-contract
|
|
213
|
+
// `__vgaiGameRoot` global as the legacy alias.
|
|
214
|
+
const declaredRoot =
|
|
215
|
+
readGameContract()?.root ?? (window as unknown as { __vgaiGameRoot?: unknown }).__vgaiGameRoot;
|
|
216
|
+
const gameDomRoot =
|
|
217
|
+
declaredRoot instanceof HTMLElement && declaredRoot.contains(rt.renderer.domElement)
|
|
218
|
+
? declaredRoot
|
|
219
|
+
: rt.renderer.domElement;
|
|
220
|
+
if (gameDomRoot !== rt.renderer.domElement) {
|
|
221
|
+
// The pane sizes the adopted root from here on — strip whatever page-level
|
|
222
|
+
// positioning the game used while it owned the whole window.
|
|
223
|
+
gameDomRoot.style.position = 'absolute';
|
|
224
|
+
gameDomRoot.style.inset = '0';
|
|
225
|
+
gameDomRoot.style.width = '';
|
|
226
|
+
gameDomRoot.style.height = '';
|
|
227
|
+
gameDomRoot.style.zIndex = '';
|
|
228
|
+
}
|
|
229
|
+
if (gameDomRoot.parentElement !== hostEl) hostEl.appendChild(gameDomRoot);
|
|
230
|
+
|
|
231
|
+
// 4. Let async world assets stream in, then build the authoring adapter.
|
|
232
|
+
await waitForSceneToSettle(rt.scene);
|
|
233
|
+
|
|
234
|
+
// Loop gate (begin/endEdit): the scene-capture trap recorded the game's
|
|
235
|
+
// setAnimationLoop callback, so we freeze the game's OWN loop (set null) and
|
|
236
|
+
// resume it (re-set the recorded callback) for stable editing — even of dynamic
|
|
237
|
+
// objects. (Games driving their loop via raw requestAnimationFrame instead of
|
|
238
|
+
// setAnimationLoop have no recorded callback → pause is a no-op for them.)
|
|
239
|
+
const loop = {
|
|
240
|
+
pause: () => rt.renderer.setAnimationLoop(null),
|
|
241
|
+
resume: () => {
|
|
242
|
+
const cb = capture.getAnimationLoop(rt.renderer);
|
|
243
|
+
if (cb) rt.renderer.setAnimationLoop(cb);
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
// The adapter walks the scene, then reapplies any saved overlay (Phase C
|
|
247
|
+
// persistence) before the user sees it.
|
|
248
|
+
const authoring = new IngestAuthoringAdapter(store, rt.scene, {
|
|
249
|
+
loop,
|
|
250
|
+
overlay: opts.overlay,
|
|
251
|
+
persist: opts.persist,
|
|
252
|
+
destination: opts.destination,
|
|
253
|
+
camera: rt.camera,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// D10/T7.6: the game-level play-state control surface (`Game.play.pause()`)
|
|
257
|
+
// calls THIS `setPaused` — separately from `IngestAuthoringAdapter`'s own
|
|
258
|
+
// edit-time freeze/unfreeze (which calls `loop.pause()`/`loop.resume()`
|
|
259
|
+
// directly, above), so a gizmo drag never trips the loop-gate honesty
|
|
260
|
+
// report `createIngestLoopGate` makes for an actual play/pause request.
|
|
261
|
+
const loopGate = createIngestLoopGate(capture, rt.renderer, game.id, loop);
|
|
262
|
+
const mounted: MountedGame = {
|
|
263
|
+
kind: 'threejs',
|
|
264
|
+
scene: rt.scene,
|
|
265
|
+
camera: rt.camera,
|
|
266
|
+
drivesOwnLoop: true,
|
|
267
|
+
setPaused: (paused) => loopGate.setPaused(paused),
|
|
268
|
+
// Wave 17 (D-C3): also resize any composer the game renders through, so
|
|
269
|
+
// its own (intentionally downsampled, e.g. `UnrealBloomPass`) render
|
|
270
|
+
// targets track the host pane instead of staying stale at mount size.
|
|
271
|
+
resize: (w, h) => {
|
|
272
|
+
rt.renderer.setSize(w, h, false);
|
|
273
|
+
capture.resizeComposers(w, h);
|
|
274
|
+
},
|
|
275
|
+
dispose: () => {
|
|
276
|
+
try {
|
|
277
|
+
rt.renderer.setAnimationLoop(null);
|
|
278
|
+
rt.renderer.dispose();
|
|
279
|
+
} catch {
|
|
280
|
+
/* ignore */
|
|
281
|
+
}
|
|
282
|
+
capture.uninstall();
|
|
283
|
+
THREE.DefaultLoadingManager.setURLModifier((url) => url);
|
|
284
|
+
for (const el of stubEls) el.remove();
|
|
285
|
+
hostEl.remove();
|
|
286
|
+
},
|
|
287
|
+
authoring,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return { game: mounted, authoring, hostEl, capture, scene: rt.scene };
|
|
291
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iframe embed host — mechanism 2 of the bundled-game path, at its honest floor.
|
|
3
|
+
*
|
|
4
|
+
* A prebuilt/opaque bundle ships its own inlined `three` (or no three at all), so
|
|
5
|
+
* the scene-capture trap can't reach it. Rather than fail, the editor HOSTS the
|
|
6
|
+
* bundle in a sandboxed iframe — it runs as itself, the editor sizes/disposes it —
|
|
7
|
+
* and advertises an embed-only authoring state (no scene introspection). This is
|
|
8
|
+
* the founding docs' "prebuilt bundle, three opaque → iframe embed → tier 0–1"
|
|
9
|
+
* (`ADAPTER-ARCHITECTURE.md` §2.3 coverage table).
|
|
10
|
+
*
|
|
11
|
+
* (The richer "prebuilt bundle whose three IS reachable → tier 2–3 in-realm
|
|
12
|
+
* editing" case is implemented in the sibling `ingest-iframe-reachable-adapter.ts`:
|
|
13
|
+
* the iframe's importmap resolves `three` to the HOST instance via a blob re-export,
|
|
14
|
+
* so the bundle builds host-realm objects and passes its own iframe canvas to the
|
|
15
|
+
* renderer — sidestepping the cross-realm canvas/document hazard. This embed-only
|
|
16
|
+
* floor remains for the truly opaque case, where three is unreachable.)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export interface EmbedMount {
|
|
20
|
+
iframe: HTMLIFrameElement;
|
|
21
|
+
dispose: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Run an opaque bundle's self-contained HTML in a sandboxed iframe (embed-only). */
|
|
25
|
+
export function mountIngestGameEmbed(html: string, gameContainer: HTMLElement): EmbedMount {
|
|
26
|
+
const iframe = document.createElement('iframe');
|
|
27
|
+
iframe.setAttribute('data-testid', 'ingest-embed-frame');
|
|
28
|
+
// allow-scripts so the bundle runs; same-origin is NOT granted → it stays opaque.
|
|
29
|
+
iframe.setAttribute('sandbox', 'allow-scripts');
|
|
30
|
+
iframe.style.cssText =
|
|
31
|
+
'position:absolute;inset:0;width:100%;height:100%;border:0;background:#000;';
|
|
32
|
+
iframe.srcdoc = html;
|
|
33
|
+
gameContainer.appendChild(iframe);
|
|
34
|
+
return {
|
|
35
|
+
iframe,
|
|
36
|
+
dispose: () => iframe.remove(),
|
|
37
|
+
};
|
|
38
|
+
}
|