@vgai/engine 0.2.0 → 0.3.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.
Files changed (541) hide show
  1. package/README.md +3 -1
  2. package/dist/adapter/authoring.d.ts +404 -0
  3. package/dist/adapter/authoring.d.ts.map +1 -0
  4. package/dist/adapter/authoring.js +22 -0
  5. package/dist/adapter/colyseus-networking-adapter.d.ts +43 -0
  6. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
  7. package/dist/adapter/colyseus-networking-adapter.js +38 -0
  8. package/dist/adapter/first-party-systems.d.ts +38 -0
  9. package/dist/adapter/first-party-systems.d.ts.map +1 -0
  10. package/dist/adapter/first-party-systems.js +77 -0
  11. package/dist/adapter/game-adapter.d.ts +133 -0
  12. package/dist/adapter/game-adapter.d.ts.map +1 -0
  13. package/dist/adapter/game-adapter.js +10 -0
  14. package/dist/adapter/host-context.d.ts +73 -0
  15. package/dist/adapter/host-context.d.ts.map +1 -0
  16. package/dist/adapter/host-context.js +16 -0
  17. package/dist/adapter/index.d.ts +22 -0
  18. package/dist/adapter/index.d.ts.map +1 -0
  19. package/dist/adapter/index.js +15 -0
  20. package/dist/adapter/ingest/game-contract.d.ts +53 -0
  21. package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
  22. package/dist/adapter/ingest/game-contract.js +30 -0
  23. package/dist/adapter/ingest/overlay-applier.d.ts +118 -0
  24. package/dist/adapter/ingest/overlay-applier.d.ts.map +1 -0
  25. package/dist/adapter/ingest/overlay-applier.js +132 -0
  26. package/dist/adapter/ingest/overlay-apply.d.ts +60 -0
  27. package/dist/adapter/ingest/overlay-apply.d.ts.map +1 -0
  28. package/dist/adapter/ingest/overlay-apply.js +101 -0
  29. package/dist/adapter/ingest/overlay-file.d.ts +79 -0
  30. package/dist/adapter/ingest/overlay-file.d.ts.map +1 -0
  31. package/dist/adapter/ingest/overlay-file.js +66 -0
  32. package/dist/adapter/ingest/overlay-report.d.ts +113 -0
  33. package/dist/adapter/ingest/overlay-report.d.ts.map +1 -0
  34. package/dist/adapter/ingest/overlay-report.js +103 -0
  35. package/dist/adapter/ingest/scene-capture.d.ts +97 -0
  36. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
  37. package/dist/adapter/ingest/scene-capture.js +248 -0
  38. package/dist/adapter/ingest/upstream-pin.d.ts +47 -0
  39. package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
  40. package/dist/adapter/ingest/upstream-pin.js +50 -0
  41. package/dist/adapter/loop-gate-report.d.ts +34 -0
  42. package/dist/adapter/loop-gate-report.d.ts.map +1 -0
  43. package/dist/adapter/loop-gate-report.js +37 -0
  44. package/dist/adapter/rapier-physics-adapter.d.ts +12 -0
  45. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
  46. package/dist/adapter/rapier-physics-adapter.js +46 -0
  47. package/dist/adapter/system-adapter.d.ts +133 -0
  48. package/dist/adapter/system-adapter.d.ts.map +1 -0
  49. package/dist/adapter/system-adapter.js +13 -0
  50. package/dist/adapter/transform.d.ts +18 -0
  51. package/dist/adapter/transform.d.ts.map +1 -0
  52. package/dist/adapter/transform.js +1 -0
  53. package/dist/adapter/vgai-scene-game-adapter.d.ts +116 -0
  54. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +1 -0
  55. package/dist/adapter/vgai-scene-game-adapter.js +714 -0
  56. package/dist/adapter/world-kind.d.ts +30 -0
  57. package/dist/adapter/world-kind.d.ts.map +1 -0
  58. package/dist/adapter/world-kind.js +18 -0
  59. package/dist/ai/navigation.d.ts +64 -0
  60. package/dist/ai/navigation.d.ts.map +1 -0
  61. package/dist/ai/navigation.js +133 -0
  62. package/dist/animation/anim-graph-types.d.ts +25 -0
  63. package/dist/animation/anim-graph-types.d.ts.map +1 -0
  64. package/dist/animation/anim-graph-types.js +1 -0
  65. package/dist/animation/animation-clock.d.ts +213 -0
  66. package/dist/animation/animation-clock.d.ts.map +1 -0
  67. package/dist/animation/animation-clock.js +301 -0
  68. package/dist/animation/blend-node.d.ts +22 -0
  69. package/dist/animation/blend-node.d.ts.map +1 -0
  70. package/dist/animation/blend-node.js +97 -0
  71. package/dist/animation/camera-ownership.d.ts +250 -0
  72. package/dist/animation/camera-ownership.d.ts.map +1 -0
  73. package/dist/animation/camera-ownership.js +169 -0
  74. package/dist/animation/cinematic-cues.d.ts +200 -0
  75. package/dist/animation/cinematic-cues.d.ts.map +1 -0
  76. package/dist/animation/cinematic-cues.js +213 -0
  77. package/dist/animation/clip-map.d.ts +12 -0
  78. package/dist/animation/clip-map.d.ts.map +1 -0
  79. package/dist/animation/clip-map.js +37 -0
  80. package/dist/animation/gsap-registration.d.ts +119 -0
  81. package/dist/animation/gsap-registration.d.ts.map +1 -0
  82. package/dist/animation/gsap-registration.js +92 -0
  83. package/dist/animation/theatre-clock-binding.d.ts +89 -0
  84. package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
  85. package/dist/animation/theatre-clock-binding.js +29 -0
  86. package/dist/animation/theatre-director.d.ts +242 -0
  87. package/dist/animation/theatre-director.d.ts.map +1 -0
  88. package/dist/animation/theatre-director.js +235 -0
  89. package/dist/animation/theatre-object-binding.d.ts +305 -0
  90. package/dist/animation/theatre-object-binding.d.ts.map +1 -0
  91. package/dist/animation/theatre-object-binding.js +351 -0
  92. package/dist/animation/xstate-animation-binding.d.ts +111 -0
  93. package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
  94. package/dist/animation/xstate-animation-binding.js +307 -0
  95. package/dist/animation/xstate-animation-meta.d.ts +228 -0
  96. package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
  97. package/dist/animation/xstate-animation-meta.js +221 -0
  98. package/dist/assets.d.ts +26 -0
  99. package/dist/assets.d.ts.map +1 -0
  100. package/dist/assets.js +55 -0
  101. package/dist/audio/index.d.ts +4 -0
  102. package/dist/audio/index.d.ts.map +1 -0
  103. package/dist/audio/index.js +24 -0
  104. package/dist/audio/tone-clock-binding.d.ts +75 -0
  105. package/dist/audio/tone-clock-binding.d.ts.map +1 -0
  106. package/dist/audio/tone-clock-binding.js +29 -0
  107. package/dist/audio/tone-context.d.ts +114 -0
  108. package/dist/audio/tone-context.d.ts.map +1 -0
  109. package/dist/audio/tone-context.js +39 -0
  110. package/dist/audio/tone-offline-render.d.ts +90 -0
  111. package/dist/audio/tone-offline-render.d.ts.map +1 -0
  112. package/dist/audio/tone-offline-render.js +56 -0
  113. package/dist/audio/wav-encode.d.ts +38 -0
  114. package/dist/audio/wav-encode.d.ts.map +1 -0
  115. package/dist/audio/wav-encode.js +97 -0
  116. package/dist/core/game-loop.d.ts +21 -0
  117. package/dist/core/game-loop.d.ts.map +1 -0
  118. package/dist/core/game-loop.js +130 -0
  119. package/dist/core/system-runner.d.ts +120 -0
  120. package/dist/core/system-runner.d.ts.map +1 -0
  121. package/dist/core/system-runner.js +286 -0
  122. package/dist/core/types.d.ts +58 -0
  123. package/dist/core/types.d.ts.map +1 -0
  124. package/dist/core/types.js +25 -0
  125. package/dist/data/data-asset.d.ts +101 -0
  126. package/dist/data/data-asset.d.ts.map +1 -0
  127. package/dist/data/data-asset.js +122 -0
  128. package/dist/data/data-check-core.d.ts +110 -0
  129. package/dist/data/data-check-core.d.ts.map +1 -0
  130. package/dist/data/data-check-core.js +178 -0
  131. package/dist/data/data-ref.d.ts +79 -0
  132. package/dist/data/data-ref.d.ts.map +1 -0
  133. package/dist/data/data-ref.js +130 -0
  134. package/dist/data/vite-plugin-data.d.ts +79 -0
  135. package/dist/data/vite-plugin-data.d.ts.map +1 -0
  136. package/dist/data/vite-plugin-data.js +217 -0
  137. package/dist/dev/console-bridge.d.ts +22 -0
  138. package/dist/dev/console-bridge.d.ts.map +1 -0
  139. package/dist/dev/console-bridge.js +71 -0
  140. package/dist/dev/debug-draw.d.ts +24 -0
  141. package/dist/dev/debug-draw.d.ts.map +1 -0
  142. package/dist/dev/debug-draw.js +73 -0
  143. package/dist/dev/logger.d.ts +30 -0
  144. package/dist/dev/logger.d.ts.map +1 -0
  145. package/dist/dev/logger.js +90 -0
  146. package/dist/ecs/component-manager.d.ts +189 -0
  147. package/dist/ecs/component-manager.d.ts.map +1 -0
  148. package/dist/ecs/component-manager.js +676 -0
  149. package/dist/ecs/game-component.d.ts +97 -0
  150. package/dist/ecs/game-component.d.ts.map +1 -0
  151. package/dist/ecs/game-component.js +80 -0
  152. package/dist/ecs/hmr-swap-report.d.ts +53 -0
  153. package/dist/ecs/hmr-swap-report.d.ts.map +1 -0
  154. package/dist/ecs/hmr-swap-report.js +55 -0
  155. package/dist/index.d.ts +37 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +30 -0
  158. package/dist/input/input-manager.d.ts +596 -0
  159. package/dist/input/input-manager.d.ts.map +1 -0
  160. package/dist/input/input-manager.js +1564 -0
  161. package/dist/input/input-types.d.ts +171 -0
  162. package/dist/input/input-types.d.ts.map +1 -0
  163. package/dist/input/input-types.js +1 -0
  164. package/dist/input/prompt-labels.d.ts +21 -0
  165. package/dist/input/prompt-labels.d.ts.map +1 -0
  166. package/dist/input/prompt-labels.js +121 -0
  167. package/dist/input/rebind-controller.d.ts +59 -0
  168. package/dist/input/rebind-controller.d.ts.map +1 -0
  169. package/dist/input/rebind-controller.js +85 -0
  170. package/dist/input/schema.d.ts +16 -0
  171. package/dist/input/schema.d.ts.map +1 -0
  172. package/dist/input/schema.js +228 -0
  173. package/dist/loader.d.ts +43 -0
  174. package/dist/loader.d.ts.map +1 -0
  175. package/dist/loader.js +59 -0
  176. package/dist/manifest/index.d.ts +5 -0
  177. package/dist/manifest/index.d.ts.map +1 -0
  178. package/dist/manifest/index.js +8 -0
  179. package/dist/manifest/load-file.d.ts +4 -0
  180. package/dist/manifest/load-file.d.ts.map +1 -0
  181. package/dist/manifest/load-file.js +14 -0
  182. package/dist/manifest/load.d.ts +117 -0
  183. package/dist/manifest/load.d.ts.map +1 -0
  184. package/dist/manifest/load.js +255 -0
  185. package/dist/manifest/schema.d.ts +173 -0
  186. package/dist/manifest/schema.d.ts.map +1 -0
  187. package/dist/manifest/schema.js +302 -0
  188. package/dist/physics/collision-system.d.ts +41 -0
  189. package/dist/physics/collision-system.d.ts.map +1 -0
  190. package/dist/physics/collision-system.js +64 -0
  191. package/dist/physics/physics-registry.d.ts +45 -0
  192. package/dist/physics/physics-registry.d.ts.map +1 -0
  193. package/dist/physics/physics-registry.js +65 -0
  194. package/dist/physics/transform-writer.d.ts +16 -0
  195. package/dist/physics/transform-writer.d.ts.map +1 -0
  196. package/dist/physics/transform-writer.js +38 -0
  197. package/dist/physics/trigger-dispatch.d.ts +24 -0
  198. package/dist/physics/trigger-dispatch.d.ts.map +1 -0
  199. package/dist/physics/trigger-dispatch.js +80 -0
  200. package/dist/react/game-state.d.ts +105 -0
  201. package/dist/react/game-state.d.ts.map +1 -0
  202. package/dist/react/game-state.js +144 -0
  203. package/dist/react/use-data.d.ts +60 -0
  204. package/dist/react/use-data.d.ts.map +1 -0
  205. package/dist/react/use-data.js +96 -0
  206. package/dist/react/use-selection.d.ts +75 -0
  207. package/dist/react/use-selection.d.ts.map +1 -0
  208. package/dist/react/use-selection.js +90 -0
  209. package/dist/render/auto-batcher.d.ts +34 -0
  210. package/dist/render/auto-batcher.d.ts.map +1 -0
  211. package/dist/render/auto-batcher.js +140 -0
  212. package/dist/render/render-batch-system.d.ts +33 -0
  213. package/dist/render/render-batch-system.d.ts.map +1 -0
  214. package/dist/render/render-batch-system.js +230 -0
  215. package/dist/render/render-features.d.ts +47 -0
  216. package/dist/render/render-features.d.ts.map +1 -0
  217. package/dist/render/render-features.js +105 -0
  218. package/dist/render/render-settings.d.ts +36 -0
  219. package/dist/render/render-settings.d.ts.map +1 -0
  220. package/dist/render/render-settings.js +51 -0
  221. package/dist/runtime/create-runtime.d.ts +280 -0
  222. package/dist/runtime/create-runtime.d.ts.map +1 -0
  223. package/dist/runtime/create-runtime.js +795 -0
  224. package/dist/runtime/frame-selector-cache.d.ts +41 -0
  225. package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
  226. package/dist/runtime/frame-selector-cache.js +65 -0
  227. package/dist/runtime/game.d.ts +433 -0
  228. package/dist/runtime/game.d.ts.map +1 -0
  229. package/dist/runtime/game.js +569 -0
  230. package/dist/runtime/input-router.d.ts +78 -0
  231. package/dist/runtime/input-router.d.ts.map +1 -0
  232. package/dist/runtime/input-router.js +171 -0
  233. package/dist/runtime/mount-game.d.ts +129 -0
  234. package/dist/runtime/mount-game.d.ts.map +1 -0
  235. package/dist/runtime/mount-game.js +152 -0
  236. package/dist/runtime/mount-manifest.d.ts +119 -0
  237. package/dist/runtime/mount-manifest.d.ts.map +1 -0
  238. package/dist/runtime/mount-manifest.js +204 -0
  239. package/dist/runtime/render-audio-control.d.ts +110 -0
  240. package/dist/runtime/render-audio-control.d.ts.map +1 -0
  241. package/dist/runtime/render-audio-control.js +111 -0
  242. package/dist/runtime/render-control.d.ts +291 -0
  243. package/dist/runtime/render-control.d.ts.map +1 -0
  244. package/dist/runtime/render-control.js +264 -0
  245. package/dist/runtime/render-seed.d.ts +57 -0
  246. package/dist/runtime/render-seed.d.ts.map +1 -0
  247. package/dist/runtime/render-seed.js +74 -0
  248. package/dist/runtime/scene-ui-bridge.d.ts +69 -0
  249. package/dist/runtime/scene-ui-bridge.d.ts.map +1 -0
  250. package/dist/runtime/scene-ui-bridge.js +23 -0
  251. package/dist/runtime/scene-ui-data.d.ts +13 -0
  252. package/dist/runtime/scene-ui-data.d.ts.map +1 -0
  253. package/dist/runtime/scene-ui-data.js +92 -0
  254. package/dist/runtime/state-bridge.d.ts +47 -0
  255. package/dist/runtime/state-bridge.d.ts.map +1 -0
  256. package/dist/runtime/state-bridge.js +53 -0
  257. package/dist/runtime/types.d.ts +179 -0
  258. package/dist/runtime/types.d.ts.map +1 -0
  259. package/dist/runtime/types.js +1 -0
  260. package/dist/scene/asset-loaders.d.ts +79 -0
  261. package/dist/scene/asset-loaders.d.ts.map +1 -0
  262. package/dist/scene/asset-loaders.js +141 -0
  263. package/dist/scene/asset-paths.d.ts +11 -0
  264. package/dist/scene/asset-paths.d.ts.map +1 -0
  265. package/dist/scene/asset-paths.js +108 -0
  266. package/dist/scene/asset-ref-check.d.ts +88 -0
  267. package/dist/scene/asset-ref-check.d.ts.map +1 -0
  268. package/dist/scene/asset-ref-check.js +214 -0
  269. package/dist/scene/asset-registry.d.ts +30 -0
  270. package/dist/scene/asset-registry.d.ts.map +1 -0
  271. package/dist/scene/asset-registry.js +50 -0
  272. package/dist/scene/collider-dimensions.d.ts +63 -0
  273. package/dist/scene/collider-dimensions.d.ts.map +1 -0
  274. package/dist/scene/collider-dimensions.js +98 -0
  275. package/dist/scene/component-registry.d.ts +17 -0
  276. package/dist/scene/component-registry.d.ts.map +1 -0
  277. package/dist/scene/component-registry.js +28 -0
  278. package/dist/scene/defaults.d.ts +252 -0
  279. package/dist/scene/defaults.d.ts.map +1 -0
  280. package/dist/scene/defaults.js +151 -0
  281. package/dist/scene/geometries/index.d.ts +8 -0
  282. package/dist/scene/geometries/index.d.ts.map +1 -0
  283. package/dist/scene/geometries/index.js +7 -0
  284. package/dist/scene/geometries/terrain.d.ts +2 -0
  285. package/dist/scene/geometries/terrain.d.ts.map +1 -0
  286. package/dist/scene/geometries/terrain.js +37 -0
  287. package/dist/scene/geometry-registry.d.ts +24 -0
  288. package/dist/scene/geometry-registry.d.ts.map +1 -0
  289. package/dist/scene/geometry-registry.js +20 -0
  290. package/dist/scene/instance-registry.d.ts +36 -0
  291. package/dist/scene/instance-registry.d.ts.map +1 -0
  292. package/dist/scene/instance-registry.js +55 -0
  293. package/dist/scene/instancers/grid.d.ts +2 -0
  294. package/dist/scene/instancers/grid.d.ts.map +1 -0
  295. package/dist/scene/instancers/grid.js +36 -0
  296. package/dist/scene/instancers/index.d.ts +8 -0
  297. package/dist/scene/instancers/index.d.ts.map +1 -0
  298. package/dist/scene/instancers/index.js +7 -0
  299. package/dist/scene/light-camera-factory.d.ts +23 -0
  300. package/dist/scene/light-camera-factory.d.ts.map +1 -0
  301. package/dist/scene/light-camera-factory.js +68 -0
  302. package/dist/scene/material-factory.d.ts +17 -0
  303. package/dist/scene/material-factory.d.ts.map +1 -0
  304. package/dist/scene/material-factory.js +197 -0
  305. package/dist/scene/material-registry.d.ts +40 -0
  306. package/dist/scene/material-registry.d.ts.map +1 -0
  307. package/dist/scene/material-registry.js +44 -0
  308. package/dist/scene/materials/index.d.ts +8 -0
  309. package/dist/scene/materials/index.d.ts.map +1 -0
  310. package/dist/scene/materials/index.js +7 -0
  311. package/dist/scene/materials/water.d.ts +2 -0
  312. package/dist/scene/materials/water.d.ts.map +1 -0
  313. package/dist/scene/materials/water.js +54 -0
  314. package/dist/scene/parse.d.ts +23 -0
  315. package/dist/scene/parse.d.ts.map +1 -0
  316. package/dist/scene/parse.js +179 -0
  317. package/dist/scene/particles-factory.d.ts +33 -0
  318. package/dist/scene/particles-factory.d.ts.map +1 -0
  319. package/dist/scene/particles-factory.js +282 -0
  320. package/dist/scene/scene-apply.d.ts +109 -0
  321. package/dist/scene/scene-apply.d.ts.map +1 -0
  322. package/dist/scene/scene-apply.js +326 -0
  323. package/dist/scene/scene-diff-schema.d.ts +285 -0
  324. package/dist/scene/scene-diff-schema.d.ts.map +1 -0
  325. package/dist/scene/scene-diff-schema.js +92 -0
  326. package/dist/scene/scene-diff-types.d.ts +40 -0
  327. package/dist/scene/scene-diff-types.d.ts.map +1 -0
  328. package/dist/scene/scene-diff-types.js +14 -0
  329. package/dist/scene/scene-loader.d.ts +177 -0
  330. package/dist/scene/scene-loader.d.ts.map +1 -0
  331. package/dist/scene/scene-loader.js +1213 -0
  332. package/dist/scene/scene-query.d.ts +11 -0
  333. package/dist/scene/scene-query.d.ts.map +1 -0
  334. package/dist/scene/scene-query.js +63 -0
  335. package/dist/scene/scene-types.d.ts +10 -0
  336. package/dist/scene/scene-types.d.ts.map +1 -0
  337. package/dist/scene/scene-types.js +8 -0
  338. package/dist/scene/scene-version.d.ts +26 -0
  339. package/dist/scene/scene-version.d.ts.map +1 -0
  340. package/dist/scene/scene-version.js +34 -0
  341. package/dist/scene/schema/animation.d.ts +8 -0
  342. package/dist/scene/schema/animation.d.ts.map +1 -0
  343. package/dist/scene/schema/animation.js +42 -0
  344. package/dist/scene/schema/audio.d.ts +13 -0
  345. package/dist/scene/schema/audio.d.ts.map +1 -0
  346. package/dist/scene/schema/audio.js +22 -0
  347. package/dist/scene/schema/camera.d.ts +28 -0
  348. package/dist/scene/schema/camera.d.ts.map +1 -0
  349. package/dist/scene/schema/camera.js +17 -0
  350. package/dist/scene/schema/collider.d.ts +40 -0
  351. package/dist/scene/schema/collider.d.ts.map +1 -0
  352. package/dist/scene/schema/collider.js +55 -0
  353. package/dist/scene/schema/entity-ref.d.ts +31 -0
  354. package/dist/scene/schema/entity-ref.d.ts.map +1 -0
  355. package/dist/scene/schema/entity-ref.js +61 -0
  356. package/dist/scene/schema/entity.d.ts +1036 -0
  357. package/dist/scene/schema/entity.d.ts.map +1 -0
  358. package/dist/scene/schema/entity.js +153 -0
  359. package/dist/scene/schema/environment.d.ts +425 -0
  360. package/dist/scene/schema/environment.d.ts.map +1 -0
  361. package/dist/scene/schema/environment.js +357 -0
  362. package/dist/scene/schema/index.d.ts +39 -0
  363. package/dist/scene/schema/index.d.ts.map +1 -0
  364. package/dist/scene/schema/index.js +20 -0
  365. package/dist/scene/schema/instances.d.ts +14 -0
  366. package/dist/scene/schema/instances.d.ts.map +1 -0
  367. package/dist/scene/schema/instances.js +28 -0
  368. package/dist/scene/schema/joint.d.ts +23 -0
  369. package/dist/scene/schema/joint.d.ts.map +1 -0
  370. package/dist/scene/schema/joint.js +23 -0
  371. package/dist/scene/schema/light.d.ts +38 -0
  372. package/dist/scene/schema/light.d.ts.map +1 -0
  373. package/dist/scene/schema/light.js +26 -0
  374. package/dist/scene/schema/material.d.ts +199 -0
  375. package/dist/scene/schema/material.d.ts.map +1 -0
  376. package/dist/scene/schema/material.js +99 -0
  377. package/dist/scene/schema/mesh.d.ts +48 -0
  378. package/dist/scene/schema/mesh.d.ts.map +1 -0
  379. package/dist/scene/schema/mesh.js +82 -0
  380. package/dist/scene/schema/particles.d.ts +2178 -0
  381. package/dist/scene/schema/particles.d.ts.map +1 -0
  382. package/dist/scene/schema/particles.js +321 -0
  383. package/dist/scene/schema/physics.d.ts +56 -0
  384. package/dist/scene/schema/physics.d.ts.map +1 -0
  385. package/dist/scene/schema/physics.js +37 -0
  386. package/dist/scene/schema/scene-file.d.ts +304 -0
  387. package/dist/scene/schema/scene-file.d.ts.map +1 -0
  388. package/dist/scene/schema/scene-file.js +262 -0
  389. package/dist/scene/schema/shadow.d.ts +28 -0
  390. package/dist/scene/schema/shadow.d.ts.map +1 -0
  391. package/dist/scene/schema/shadow.js +20 -0
  392. package/dist/scene/schema/spline.d.ts +25 -0
  393. package/dist/scene/schema/spline.d.ts.map +1 -0
  394. package/dist/scene/schema/spline.js +15 -0
  395. package/dist/scene/schema/tuples.d.ts +12 -0
  396. package/dist/scene/schema/tuples.d.ts.map +1 -0
  397. package/dist/scene/schema/tuples.js +14 -0
  398. package/dist/scene/schema/ui.d.ts +880 -0
  399. package/dist/scene/schema/ui.d.ts.map +1 -0
  400. package/dist/scene/schema/ui.js +506 -0
  401. package/dist/scene/user-data.d.ts +171 -0
  402. package/dist/scene/user-data.d.ts.map +1 -0
  403. package/dist/scene/user-data.js +137 -0
  404. package/dist/setup/setup-audio.d.ts +20 -0
  405. package/dist/setup/setup-audio.d.ts.map +1 -0
  406. package/dist/setup/setup-audio.js +41 -0
  407. package/dist/setup/setup-particles.d.ts +17 -0
  408. package/dist/setup/setup-particles.d.ts.map +1 -0
  409. package/dist/setup/setup-particles.js +16 -0
  410. package/dist/setup/setup-physics.d.ts +25 -0
  411. package/dist/setup/setup-physics.d.ts.map +1 -0
  412. package/dist/setup/setup-physics.js +51 -0
  413. package/dist/setup/setup-renderer.d.ts +69 -0
  414. package/dist/setup/setup-renderer.d.ts.map +1 -0
  415. package/dist/setup/setup-renderer.js +363 -0
  416. package/dist/tools/define-tool.d.ts +105 -0
  417. package/dist/tools/define-tool.d.ts.map +1 -0
  418. package/dist/tools/define-tool.js +82 -0
  419. package/dist/world2d/authoring-2d.d.ts +76 -0
  420. package/dist/world2d/authoring-2d.d.ts.map +1 -0
  421. package/dist/world2d/authoring-2d.js +176 -0
  422. package/dist/world2d/capture-to-scene2d.d.ts +5 -0
  423. package/dist/world2d/capture-to-scene2d.d.ts.map +1 -0
  424. package/dist/world2d/capture-to-scene2d.js +49 -0
  425. package/dist/world2d/collision-2d.d.ts +52 -0
  426. package/dist/world2d/collision-2d.d.ts.map +1 -0
  427. package/dist/world2d/collision-2d.js +70 -0
  428. package/dist/world2d/components-2d.d.ts +47 -0
  429. package/dist/world2d/components-2d.d.ts.map +1 -0
  430. package/dist/world2d/components-2d.js +77 -0
  431. package/dist/world2d/index.d.ts +34 -0
  432. package/dist/world2d/index.d.ts.map +1 -0
  433. package/dist/world2d/index.js +32 -0
  434. package/dist/world2d/ingest-iframe-2d.d.ts +82 -0
  435. package/dist/world2d/ingest-iframe-2d.d.ts.map +1 -0
  436. package/dist/world2d/ingest-iframe-2d.js +166 -0
  437. package/dist/world2d/ingest2d.d.ts +97 -0
  438. package/dist/world2d/ingest2d.d.ts.map +1 -0
  439. package/dist/world2d/ingest2d.js +40 -0
  440. package/dist/world2d/physics2d-registry.d.ts +24 -0
  441. package/dist/world2d/physics2d-registry.d.ts.map +1 -0
  442. package/dist/world2d/physics2d-registry.js +38 -0
  443. package/dist/world2d/pixi-game-adapter.d.ts +107 -0
  444. package/dist/world2d/pixi-game-adapter.d.ts.map +1 -0
  445. package/dist/world2d/pixi-game-adapter.js +211 -0
  446. package/dist/world2d/pixi-surface.d.ts +39 -0
  447. package/dist/world2d/pixi-surface.d.ts.map +1 -0
  448. package/dist/world2d/pixi-surface.js +47 -0
  449. package/dist/world2d/scene-capture-2d.d.ts +43 -0
  450. package/dist/world2d/scene-capture-2d.d.ts.map +1 -0
  451. package/dist/world2d/scene-capture-2d.js +92 -0
  452. package/dist/world2d/scene2d-loader.d.ts +27 -0
  453. package/dist/world2d/scene2d-loader.d.ts.map +1 -0
  454. package/dist/world2d/scene2d-loader.js +274 -0
  455. package/dist/world2d/schema/entity2d.d.ts +102 -0
  456. package/dist/world2d/schema/entity2d.d.ts.map +1 -0
  457. package/dist/world2d/schema/entity2d.js +119 -0
  458. package/dist/world2d/schema/physics2d.d.ts +46 -0
  459. package/dist/world2d/schema/physics2d.d.ts.map +1 -0
  460. package/dist/world2d/schema/physics2d.js +45 -0
  461. package/dist/world2d/schema/sprite.d.ts +42 -0
  462. package/dist/world2d/schema/sprite.d.ts.map +1 -0
  463. package/dist/world2d/schema/sprite.js +63 -0
  464. package/dist/world2d/schema/tilemap.d.ts +15 -0
  465. package/dist/world2d/schema/tilemap.d.ts.map +1 -0
  466. package/dist/world2d/schema/tilemap.js +19 -0
  467. package/dist/world2d/schema/tuples2d.d.ts +20 -0
  468. package/dist/world2d/schema/tuples2d.d.ts.map +1 -0
  469. package/dist/world2d/schema/tuples2d.js +19 -0
  470. package/dist/world2d/system-adapters-2d.d.ts +16 -0
  471. package/dist/world2d/system-adapters-2d.d.ts.map +1 -0
  472. package/dist/world2d/system-adapters-2d.js +37 -0
  473. package/dist/world2d/transform-writer-2d.d.ts +16 -0
  474. package/dist/world2d/transform-writer-2d.d.ts.map +1 -0
  475. package/dist/world2d/transform-writer-2d.js +22 -0
  476. package/dist/world2d/types.d.ts +53 -0
  477. package/dist/world2d/types.d.ts.map +1 -0
  478. package/dist/world2d/types.js +1 -0
  479. package/package.json +18 -4
  480. package/src/adapter/authoring.ts +10 -0
  481. package/src/adapter/first-party-systems.ts +23 -34
  482. package/src/adapter/index.ts +1 -3
  483. package/src/adapter/system-adapter.ts +15 -22
  484. package/src/adapter/vgai-scene-game-adapter.ts +5 -14
  485. package/src/animation/anim-graph-types.ts +12 -43
  486. package/src/animation/animation-clock.ts +479 -0
  487. package/src/animation/camera-ownership.ts +467 -0
  488. package/src/animation/cinematic-cues.ts +451 -0
  489. package/src/animation/clip-map.ts +41 -0
  490. package/src/animation/gsap-registration.ts +184 -0
  491. package/src/animation/theatre-clock-binding.ts +111 -0
  492. package/src/animation/theatre-director.ts +347 -0
  493. package/src/animation/theatre-object-binding.ts +661 -0
  494. package/src/animation/xstate-animation-binding.ts +398 -0
  495. package/src/animation/xstate-animation-meta.ts +282 -0
  496. package/src/audio/index.ts +39 -7
  497. package/src/audio/tone-clock-binding.ts +98 -0
  498. package/src/audio/tone-context.ts +129 -0
  499. package/src/audio/tone-offline-render.ts +167 -0
  500. package/src/audio/wav-encode.ts +119 -0
  501. package/src/core/game-loop.ts +17 -0
  502. package/src/core/types.ts +13 -0
  503. package/src/data/data-asset.ts +167 -0
  504. package/src/data/data-check-core.ts +242 -0
  505. package/src/data/data-ref.ts +145 -0
  506. package/src/data/vite-plugin-data.ts +290 -0
  507. package/src/index.ts +48 -0
  508. package/src/input/input-manager.ts +1206 -32
  509. package/src/input/input-types.ts +155 -3
  510. package/src/input/prompt-labels.ts +122 -0
  511. package/src/input/rebind-controller.ts +105 -0
  512. package/src/input/schema.ts +206 -52
  513. package/src/react/use-data.ts +114 -0
  514. package/src/react/use-selection.tsx +135 -0
  515. package/src/runtime/create-runtime.ts +30 -9
  516. package/src/runtime/render-audio-control.ts +168 -0
  517. package/src/runtime/render-control.ts +522 -0
  518. package/src/runtime/render-seed.ts +79 -0
  519. package/src/runtime/types.ts +0 -5
  520. package/src/scene/asset-loaders.ts +10 -36
  521. package/src/scene/asset-paths.ts +0 -2
  522. package/src/scene/asset-ref-check.ts +248 -0
  523. package/src/scene/parse.ts +133 -0
  524. package/src/scene/scene-loader.ts +81 -96
  525. package/src/scene/schema/animation.ts +30 -79
  526. package/src/scene/schema/entity.ts +20 -0
  527. package/src/scene/schema/index.ts +2 -12
  528. package/src/scene/user-data.ts +8 -9
  529. package/src/setup/setup-renderer.ts +9 -2
  530. package/src/tools/define-tool.ts +152 -0
  531. package/src/animation/anim-graph.ts +0 -406
  532. package/src/animation/anim-system.ts +0 -28
  533. package/src/animation/property-track.ts +0 -178
  534. package/src/animation/schema.ts +0 -204
  535. package/src/audio/ambient.ts +0 -300
  536. package/src/audio/impacts.ts +0 -212
  537. package/src/audio/movement.ts +0 -140
  538. package/src/audio/musical.ts +0 -200
  539. package/src/audio/ui-sounds.ts +0 -171
  540. package/src/audio/vehicle.ts +0 -235
  541. package/src/audio/weapons.ts +0 -152
@@ -0,0 +1,714 @@
1
+ /**
2
+ * VgaiSceneGameAdapter — the FIRST-PARTY implementer of {@link GameAdapter}.
3
+ *
4
+ * This is where `.vscn` + `GameComponent` + Rapier live now: the host no longer
5
+ * knows about any of them. `mount(host)` builds the full first-party runtime
6
+ * (the body that used to live inline in `create-runtime.ts`) from a neutral
7
+ * {@link HostContext}, runs the game's `setup`/scene load, and returns a
8
+ * {@link MountedGame}. First-party content is now just one implementer of the
9
+ * same interface an unmodified external game implements (Phase B).
10
+ *
11
+ * `GameSetupFn` / `GameContext` are imported ONLY here (and in the example
12
+ * `fromSetup` wrappers) — never by the host. That confinement is the inversion.
13
+ */
14
+ import RAPIER from '@dimforge/rapier3d-compat';
15
+ import * as THREE from 'three';
16
+ import { createSystemRunner } from '../core/system-runner';
17
+ import { createDebugDraw } from '../dev/debug-draw';
18
+ import { createComponentManager } from '../ecs/component-manager';
19
+ import { InputManager } from '../input/input-manager';
20
+ import { setAssetPrefix } from '../loader';
21
+ import { createCollisionSystem } from '../physics/collision-system';
22
+ import { createPhysicsRegistry } from '../physics/physics-registry';
23
+ import { createTransformWriter } from '../physics/transform-writer';
24
+ import { createTriggerDispatch } from '../physics/trigger-dispatch';
25
+ import { RenderBatchSystem } from '../render/render-batch-system';
26
+ import { resolveRenderSettings } from '../render/render-settings';
27
+ import { renderSceneUI, } from '../runtime/scene-ui-bridge';
28
+ import { gameStateDataSource } from '../runtime/scene-ui-data';
29
+ import { tickCustomMaterials } from '../scene/material-registry';
30
+ import { clearAssetCaches, loadScene, loadSceneFromData, updateSceneLODs, } from '../scene/scene-loader';
31
+ import { hasUserData, setUserData } from '../scene/user-data';
32
+ import { setupAudio } from '../setup/setup-audio';
33
+ import { setupParticles } from '../setup/setup-particles';
34
+ import { setupPhysics, updatePhysicsDebug } from '../setup/setup-physics';
35
+ import { applyRendererSettings, applyScenePostProcessing, createSceneView, } from '../setup/setup-renderer';
36
+ import { createAudioSystemAdapter, createInputManagerAdapter, createNavigationAdapter, createVgaiAssetAdapter, } from './first-party-systems';
37
+ import { createRapierPhysicsAdapter } from './rapier-physics-adapter';
38
+ /** Minimal stand-in for the GPU composer when mounting headlessly. */
39
+ function headlessComposer(renderer) {
40
+ return {
41
+ render: () => { },
42
+ setSize: () => { },
43
+ dispose: () => { },
44
+ addPass: () => { },
45
+ removeAllPasses: () => { },
46
+ passes: [],
47
+ getRenderer: () => renderer,
48
+ };
49
+ }
50
+ /**
51
+ * Wrap a first-party `setup` function as a {@link GameAdapter}. This is how every
52
+ * first-party example becomes an implementer of the same interface an external
53
+ * game implements — with no change to the setup's body.
54
+ */
55
+ export function fromSetup(id, setup) {
56
+ return new VgaiSceneGameAdapter({ id, setup });
57
+ }
58
+ export class VgaiSceneGameAdapter {
59
+ config;
60
+ id;
61
+ constructor(config = {}) {
62
+ this.config = config;
63
+ this.id = config.id ?? 'vgai-scene';
64
+ }
65
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one cohesive first-party bootstrap (moved verbatim from create-runtime); splitting it would obscure the ordering contract
66
+ async mount(host) {
67
+ const { setup, editorPreview, scenePath, sceneData, componentRegistry, uiRegistry, inputMapPath = '/inputmaps/default.inputmap.json', assetPrefix = '/', } = this.config;
68
+ const headless = host.headless === true;
69
+ const { width, height } = host.surface;
70
+ const renderer = host.renderer;
71
+ setAssetPrefix(assetPrefix);
72
+ // --- Scene view (scene/camera/composer). Browser: the canonical builder, so
73
+ // behavior is byte-identical to the old create-runtime. Headless: plain
74
+ // scene/camera + a no-op composer (no GPU). ---
75
+ let scene;
76
+ let camera;
77
+ let composer;
78
+ if (headless) {
79
+ scene = new THREE.Scene();
80
+ scene.background = new THREE.Color(0x1a1a2e);
81
+ camera = new THREE.PerspectiveCamera(60, width / height || 1, 0.1, 1000);
82
+ camera.position.set(0, 5, 10);
83
+ camera.lookAt(0, 0, 0);
84
+ composer = headlessComposer(renderer);
85
+ }
86
+ else {
87
+ const view = createSceneView(renderer, width, height);
88
+ scene = view.scene;
89
+ camera = view.camera;
90
+ composer = view.composer;
91
+ }
92
+ // --- Rapier physics ---
93
+ await RAPIER.init();
94
+ const physics = setupPhysics(RAPIER, scene);
95
+ const physicsRegistry = createPhysicsRegistry();
96
+ const writeTransforms = createTransformWriter(physicsRegistry, scene);
97
+ // --- Input (InputManager attaches window listeners; stub it headlessly) ---
98
+ const input = headless ? headlessInput() : new InputManager();
99
+ if (!headless)
100
+ await input.loadMap(inputMapPath);
101
+ // --- Collision system ---
102
+ const collisions = createCollisionSystem(physics.rapierWorld, physics.eventQueue);
103
+ // --- Audio (Web Audio — browser only) ---
104
+ const audio = headless ? headlessAudio() : setupAudio(camera);
105
+ // --- Particles (three.quarks BatchedRenderer) ---
106
+ const particles = setupParticles(scene);
107
+ // --- UI container (host-provided) ---
108
+ const uiContainer = host.ui;
109
+ // --- Debug draw / assets ---
110
+ const debugDraw = createDebugDraw(scene);
111
+ const assets = host.assets;
112
+ // --- System runner (engine-level systems) ---
113
+ const systems = createSystemRunner();
114
+ systems.add('input', () => input.poll());
115
+ systems.add('physics', () => physics.rapierWorld.step(physics.eventQueue));
116
+ systems.add('postPhysics', () => {
117
+ collisions.drain();
118
+ writeTransforms();
119
+ });
120
+ systems.add('preRender', (dt) => {
121
+ particles.batchedRenderer.update(dt);
122
+ tickCustomMaterials(scene, dt);
123
+ updateSceneLODs(scene, camera);
124
+ });
125
+ if (!headless) {
126
+ systems.add('render', (dt) => {
127
+ composer.render(dt);
128
+ if (physics.debugEnabled)
129
+ updatePhysicsDebug(physics.rapierWorld, physics.debugMesh);
130
+ });
131
+ }
132
+ // --- Debug toggle (browser only) ---
133
+ const onDebugToggle = (e) => {
134
+ if (e.code === 'KeyP') {
135
+ physics.debugEnabled = !physics.debugEnabled;
136
+ physics.debugMesh.visible = physics.debugEnabled;
137
+ }
138
+ };
139
+ if (!headless)
140
+ window.addEventListener('keydown', onDebugToggle);
141
+ const postFrame = () => input.endFrame();
142
+ // The mounted game's adapter surface (`mounted.systems`). Declared before
143
+ // ctx so `ctx.registerSystemAdapter` can close over it: the engine fills
144
+ // the first-party entries below; GAME-owned capabilities (networking,
145
+ // navigation) are registered by the game's setup through the ctx hook.
146
+ // The editor holds this same object reference (setActiveSystems), so
147
+ // late registrations are visible to its panels at read time.
148
+ const systemAdapters = {};
149
+ // Game-registered scene-UI services (design/24-scene-ui.md D2/D7) — a `let`
150
+ // bag mutated by `ctx.setSceneUIServices`, declared here (BEFORE `ctx` is
151
+ // built) so the closure below has something to capture: a GameComponent
152
+ // calling `ctx.setSceneUIServices` from its `init()` runs DURING
153
+ // `componentManager.initAll()` (scene-loader.ts), which is awaited before
154
+ // `loadScene`/`loadFromData` return below — well before `sceneUIHandle`
155
+ // exists — so early calls just accumulate here and are folded into the
156
+ // FIRST render (`buildSceneUIServices`, below) rather than routed through
157
+ // the late-update path.
158
+ let sceneUIServices = {};
159
+ // --- GameContext (the first-party runtime surface) ---
160
+ const ctx = {
161
+ scene,
162
+ camera,
163
+ rapierWorld: physics.rapierWorld,
164
+ rapier: RAPIER,
165
+ physics: physicsRegistry,
166
+ input,
167
+ collisions,
168
+ composer,
169
+ audio,
170
+ particles,
171
+ debugDraw,
172
+ assets,
173
+ systems,
174
+ components: null,
175
+ uiContainer,
176
+ registerSystemAdapter: (kind, adapter) => {
177
+ systemAdapters[kind] = adapter;
178
+ },
179
+ setSceneUIServices: (incoming) => {
180
+ sceneUIServices = { ...sceneUIServices, ...incoming };
181
+ // Late call (after the initial mount already resolved a sceneInstance
182
+ // and rendered it): route to the live handle instead of just banking
183
+ // the services for a mount that already happened (D7).
184
+ if (sceneUIHandle && sceneInstance) {
185
+ const merged = buildSceneUIServices(sceneInstance);
186
+ if (sceneUIHandle.update) {
187
+ sceneUIHandle.update(merged);
188
+ }
189
+ else {
190
+ sceneUIHandle.dispose();
191
+ sceneUIHandle = sceneInstance.ui
192
+ ? renderSceneUI(uiContainer, sceneInstance.ui, merged)
193
+ : null;
194
+ }
195
+ }
196
+ },
197
+ };
198
+ // Game root (T7.1 slice 1): only present once the host has constructed a
199
+ // Game shell (createGameRuntime does this before mount; headless/foreign
200
+ // hosts may omit it — ctx.game/ctx.worlds simply stay undefined, which is
201
+ // the documented zero-break behavior). `ctx.worlds` is assigned the SAME
202
+ // live array `host.game` mutates via `registerWorld` (not a copy) — the
203
+ // default world is registered AFTER mount returns, and this reference
204
+ // must observe that later push.
205
+ if (host.game) {
206
+ ctx.game = host.game;
207
+ ctx.worlds = host.game.worlds;
208
+ }
209
+ ctx.components = createComponentManager(ctx, physicsRegistry);
210
+ collisions.onCollision(createTriggerDispatch(physicsRegistry, ctx.components, physics.rapierWorld, ctx));
211
+ // Everything registered above (engine systems + the ComponentManager's
212
+ // per-phase tick, just wired in) is "engine" and must survive a warm
213
+ // restart. Everything a game (setup()/scenePath/sceneData, below) adds
214
+ // from here on is "game" content that `hotReload` bulk-removes via
215
+ // `systems.removeAllNonEngine()` on every restart (T1.7).
216
+ systems.markEngineBoundary();
217
+ // First-party System adapters over the real subsystems — seeded HERE,
218
+ // BEFORE setup()/scene load runs below, so that a game which registers any
219
+ // of these kinds during its own setup (via `ctx.registerSystemAdapter`)
220
+ // always wins over the engine's first-party entry (see
221
+ // registerSystemAdapter's docstring in runtime/types.ts). `navigation` is
222
+ // ALSO first-party now (R8 item 7): `createNavigationAdapter` wraps the
223
+ // real `NavMeshManager` a scenePath/sceneData scene load may produce (see
224
+ // `applySceneNavigation` below) — it is wired once that scene instance
225
+ // resolves, not here (no NavMeshManager exists yet at this point in the
226
+ // mount). `networking` remains the one game-owned capability with no
227
+ // first-party implementer; it simply starts absent here.
228
+ systemAdapters.physics = createRapierPhysicsAdapter(physicsRegistry, physics.debugMesh);
229
+ systemAdapters.input = createInputManagerAdapter(input);
230
+ systemAdapters.assets = createVgaiAssetAdapter();
231
+ // D10/T7.6: the audio seam `Game.play.pause()` silences on pause. Works
232
+ // against the headless stand-in too (`headlessAudio()`'s plain
233
+ // `masterGain.gain` object) — this world's `pause()` mutes it harmlessly.
234
+ systemAdapters.audio = createAudioSystemAdapter(audio);
235
+ // Snapshot of the engine-owned adapter kinds, taken right after seeding
236
+ // and before any setup() has had a chance to run. `hotReload`/`disposeGame`
237
+ // use this to strip every GAME-registered kind (including an override of a
238
+ // first-party kind) left over from the outgoing game, so a warm restart or
239
+ // a full stop never exposes a disposed game's networking/etc. adapter to
240
+ // the next setup.
241
+ const engineAdapterKinds = new Set(Object.keys(systemAdapters));
242
+ // 'navigation' is engine-owned too (R8 item 7), but the scene load that
243
+ // populates it (below, `applySceneNavigation`) happens AFTER this
244
+ // snapshot — add it explicitly so the generic "strip every non-engine
245
+ // kind" step (hotReload/disposeGame) never mistakes a first-party
246
+ // navigation adapter for game-registered content and deletes it. (The
247
+ // adapter is still kept in sync with the CURRENT scene's NavMeshManager
248
+ // via the dedicated `clear navigation adapter` teardown step below, which
249
+ // runs independently of this snapshot.)
250
+ engineAdapterKinds.add('navigation');
251
+ // --- Scene / game setup ---
252
+ const engineSceneChildren = new Set(scene.children.slice());
253
+ // Tag engine-owned infra (particle BatchedRenderer, debug-draw + subtrees) so
254
+ // the editor's play-mode hierarchy skips them — they're not game entities.
255
+ for (const c of engineSceneChildren) {
256
+ c.traverse((n) => setUserData(n, 'engineInternal', true));
257
+ }
258
+ let currentCleanup = null;
259
+ let sceneUIHandle = null;
260
+ let batchSystem = null;
261
+ // The scenePath/sceneData branch's resolved SceneInstance, if either ran
262
+ // (stays undefined for a `setup`-based mount — see the `sceneUI` deriva-
263
+ // tion below). Single source of truth for both the scene-graph `ui` tree
264
+ // and (potentially, in future) other instance-derived wiring.
265
+ let sceneInstance;
266
+ // Apply scene-level render settings + transparent auto-batching after a scene
267
+ // loads (GPU host only). Gated on the resolved `environment.rendering` cascade
268
+ // (defaults preserve prior behavior when a scene omits `rendering`).
269
+ const applySceneRendering = (inst) => {
270
+ if (headless)
271
+ return;
272
+ const scope = inst.environment?.rendering;
273
+ const settings = resolveRenderSettings(scope);
274
+ // live renderer settings (shadows, resolution scale)
275
+ applyRendererSettings(renderer, scope);
276
+ // post-processing master switch: (re)build when the scene defines effects OR
277
+ // the master is off (to strip the default bloom pass down to a plain scene).
278
+ if (inst.environment?.postProcessing || !settings['postProcessing']) {
279
+ applyScenePostProcessing(composer, renderer, scene, camera, inst.environment);
280
+ }
281
+ // transparent batching: collapse static/mover meshes sharing a signature
282
+ if (settings['autoBatch']) {
283
+ batchSystem = new RenderBatchSystem(scene, settings);
284
+ batchSystem.build();
285
+ ctx.systems.add('preRender', () => batchSystem?.update());
286
+ if (import.meta.env?.DEV)
287
+ window.__vgaiBatch = batchSystem;
288
+ }
289
+ };
290
+ // Wire the (first-party) navigation system adapter to whichever
291
+ // NavMeshManager the CURRENT scene instance carries — reassigned on every
292
+ // scene load, and explicitly cleared (not just left stale) when the new
293
+ // scene has none, so `mounted.systems.navigation` never lingers pointing
294
+ // at a manager a later teardown step disposes (R8 item 7).
295
+ const applySceneNavigation = (inst) => {
296
+ if (inst.navMesh) {
297
+ systemAdapters.navigation = createNavigationAdapter(inst.navMesh);
298
+ }
299
+ else {
300
+ delete systemAdapters.navigation;
301
+ }
302
+ };
303
+ // Scratch vector for the D5 default worldProjector — reused across calls
304
+ // (one per bound world-tracked canvas per render), never allocated per-frame.
305
+ const _sceneUIProjectorTmp = new THREE.Vector3();
306
+ // The D4 default data source subscribes to game.state for its whole
307
+ // lifetime with no unsubscribe path, so it must be built at most ONCE per
308
+ // adapter mount — buildSceneUIServices runs again on every late
309
+ // setSceneUIServices call, and rebuilding it there would both leak a
310
+ // subscription and force every bound node to resubscribe to a fresh store.
311
+ let defaultSceneUIData;
312
+ /**
313
+ * Assemble the services `renderSceneUI` receives (design/24-scene-ui.md
314
+ * D2): engine defaults (D4 data source, D5 worldProjector, D6 onEvent) <-
315
+ * the project's per-mount UI registry (D11, editor-play threading) <-
316
+ * game-registered services (`ctx.setSceneUIServices`) — per key, each
317
+ * later layer winning over the one before it.
318
+ */
319
+ const buildSceneUIServices = (inst) => {
320
+ const defaults = {
321
+ onEvent: (handlerId) => {
322
+ console.warn(`scene-ui: unhandled UI event "${handlerId}" — register onEvent via ctx.setSceneUIServices`);
323
+ },
324
+ worldProjector: (id) => {
325
+ const obj = inst.entities.get(id);
326
+ if (!obj)
327
+ return null;
328
+ const projected = obj.getWorldPosition(_sceneUIProjectorTmp).project(camera);
329
+ if (projected.z > 1)
330
+ return null; // behind the camera -> hidden
331
+ const w = uiContainer.clientWidth;
332
+ const h = uiContainer.clientHeight;
333
+ // Rounded (not sub-pixel) — matches CrtScreen's integer-rounding
334
+ // (crt-screen.ts), which exists specifically to stop an asymptotic
335
+ // camera lerp from shimmering a tracked canvas every frame.
336
+ return {
337
+ x: Math.round(((projected.x + 1) / 2) * w),
338
+ y: Math.round(((1 - projected.y) / 2) * h),
339
+ };
340
+ },
341
+ };
342
+ // Lazily and at-most-once; skipped entirely while the game supplies its
343
+ // own `data` service (no point subscribing a default nobody reads).
344
+ if (!sceneUIServices.data && ctx.game && componentRegistry) {
345
+ defaultSceneUIData ??= gameStateDataSource(ctx.game, componentRegistry);
346
+ defaults.data = defaultSceneUIData;
347
+ }
348
+ const registryPortion = {
349
+ ...(uiRegistry?.components ? { components: uiRegistry.components } : {}),
350
+ ...(uiRegistry?.transforms ? { transforms: uiRegistry.transforms } : {}),
351
+ ...(uiRegistry?.strings ? { strings: uiRegistry.strings } : {}),
352
+ };
353
+ return { ...defaults, ...registryPortion, ...sceneUIServices };
354
+ };
355
+ const loadFromData = async (data) => {
356
+ const inst = await loadSceneFromData(data, {
357
+ scene,
358
+ rapierWorld: ctx.rapierWorld,
359
+ rapier: ctx.rapier,
360
+ physics: ctx.physics,
361
+ audioListener: ctx.audio.listener,
362
+ ...(componentRegistry ? { componentRegistry } : {}),
363
+ componentManager: ctx.components,
364
+ particleRenderer: ctx.particles.batchedRenderer,
365
+ ...(headless ? {} : { renderer }),
366
+ });
367
+ applySceneRendering(inst);
368
+ applySceneNavigation(inst);
369
+ ctx.systems.add('postPhysics', (dt) => inst.update(dt));
370
+ return inst;
371
+ };
372
+ if (setup) {
373
+ if (headless)
374
+ throw new Error('VgaiSceneGameAdapter: setup-based games require a GPU host');
375
+ currentCleanup = await setup(ctx, editorPreview);
376
+ }
377
+ else if (scenePath) {
378
+ const inst = await loadScene(scenePath, {
379
+ scene,
380
+ rapierWorld: ctx.rapierWorld,
381
+ rapier: ctx.rapier,
382
+ physics: ctx.physics,
383
+ audioListener: ctx.audio.listener,
384
+ ...(componentRegistry ? { componentRegistry } : {}),
385
+ componentManager: ctx.components,
386
+ particleRenderer: ctx.particles.batchedRenderer,
387
+ ...(headless ? {} : { renderer }),
388
+ });
389
+ applyEditorCamera(editorPreview, camera) || adoptSceneCamera(inst, camera);
390
+ applySceneRendering(inst);
391
+ applySceneNavigation(inst);
392
+ ctx.systems.add('postPhysics', (dt) => inst.update(dt));
393
+ sceneInstance = inst;
394
+ // A pre-baked navmesh (sibling .navmesh file — see scene-loader.ts) holds
395
+ // live recast-navigation WASM handles that leak unless destroyed
396
+ // explicitly; dispose it alongside the scene instance on teardown.
397
+ currentCleanup = {
398
+ dispose: () => {
399
+ inst.navMesh?.dispose(scene);
400
+ inst.dispose();
401
+ },
402
+ };
403
+ }
404
+ else if (sceneData) {
405
+ const inst = await loadFromData(sceneData);
406
+ applyEditorCamera(editorPreview, camera) || adoptSceneCamera(inst, camera);
407
+ sceneInstance = inst;
408
+ currentCleanup = {
409
+ dispose: () => {
410
+ inst.navMesh?.dispose(scene);
411
+ inst.dispose();
412
+ },
413
+ };
414
+ }
415
+ // Render scene-graph UI (the `ui` tree) into the overlay via the injected React
416
+ // renderer (B1). Sourced from the loaded `SceneInstance` — the single source of
417
+ // truth for BOTH the scenePath and sceneData branches (R8 item 7 / B: previously
418
+ // only sceneData's raw `SceneFile.ui` was read via a `resolvedSceneData` special-
419
+ // case, so a scenePath mount's `ui` tree was silently dropped even though
420
+ // `loadScene` fully parses it). A `setup`-based mount has no `sceneInstance` at
421
+ // all — its game owns any UI mounting itself. No-op if no UI or no renderer
422
+ // registered. Engine stays React-free.
423
+ const sceneUI = sceneInstance?.ui;
424
+ if (sceneUI && sceneInstance && !headless) {
425
+ sceneUIHandle = renderSceneUI(uiContainer, sceneUI, buildSceneUIServices(sceneInstance));
426
+ }
427
+ // Idempotency guard for disposeGame — see below. Declared here (not inside
428
+ // disposeGame) so hotReload can also refuse to run on an already-disposed
429
+ // adapter.
430
+ let disposed = false;
431
+ // Run one teardown step in isolation: a throwing step (e.g. a
432
+ // GameComponent's dispose() misbehaving, or a WASM free() panicking) must
433
+ // not abort the remaining steps — otherwise a single bad component leaks
434
+ // the Rapier world and skips input.dispose() with no way to retry (a
435
+ // second call is a no-op once `disposed` is set). Logs and continues.
436
+ const safeStep = (label, fn) => {
437
+ try {
438
+ fn();
439
+ }
440
+ catch (err) {
441
+ console.error(`VgaiSceneGameAdapter: teardown step "${label}" threw (continuing)`, err);
442
+ }
443
+ };
444
+ const disposeGame = () => {
445
+ // A second stop() must be a safe no-op — do NOT double-free the Rapier
446
+ // world/EventQueue (WASM handles panic/throw on a second free) or
447
+ // double-run teardown side effects.
448
+ if (disposed)
449
+ return;
450
+ disposed = true;
451
+ safeStep('batchSystem.teardown', () => {
452
+ batchSystem?.teardown(); // re-attach detached sources before scene teardown
453
+ batchSystem = null;
454
+ });
455
+ safeStep('currentCleanup.dispose', () => {
456
+ currentCleanup?.dispose();
457
+ currentCleanup = null;
458
+ });
459
+ // The scene instance's NavMeshManager (if any) was just disposed above
460
+ // (currentCleanup.dispose calls `inst.navMesh?.dispose(scene)`) — clear
461
+ // the wrapper too, or `mounted.systems.navigation` would keep pointing
462
+ // at a freed manager (R8 item 7). Unconditional: harmless if navigation
463
+ // was never set.
464
+ safeStep('clear navigation adapter', () => {
465
+ delete systemAdapters.navigation;
466
+ });
467
+ if (!headless) {
468
+ safeStep('removeEventListener(keydown)', () => window.removeEventListener('keydown', onDebugToggle));
469
+ }
470
+ // Components BEFORE the physics world is freed/bodies are removed: a
471
+ // GameComponent's dispose() may read `this.rigidBody`/`this.collider`
472
+ // (see game-component.ts) — freeing the world first would make those
473
+ // dangling WASM references. Isolated: a throwing component dispose must
474
+ // not prevent the world/eventQueue frees or input.dispose() below.
475
+ safeStep('components.clear', () => ctx.components.clear());
476
+ safeStep('remove rigid bodies', () => {
477
+ const handles = [];
478
+ physics.rapierWorld.forEachRigidBody((b) => handles.push(b.handle));
479
+ for (const h of handles) {
480
+ const b = physics.rapierWorld.getRigidBody(h);
481
+ if (b)
482
+ physics.rapierWorld.removeRigidBody(b);
483
+ }
484
+ });
485
+ safeStep('rapierWorld.free', () => physics.rapierWorld.free());
486
+ safeStep('eventQueue.free', () => physics.eventQueue.free()); // WASM handle — must be freed manually
487
+ safeStep('physicsRegistry.clear', () => physicsRegistry.clear());
488
+ safeStep('scene children dispose', () => {
489
+ for (const obj of [...scene.children]) {
490
+ scene.remove(obj);
491
+ obj.traverse((node) => {
492
+ if (node instanceof THREE.Mesh) {
493
+ if (!hasUserData(node, '__sharedGeometry'))
494
+ node.geometry?.dispose();
495
+ if (Array.isArray(node.material))
496
+ node.material.forEach((m) => {
497
+ m.dispose();
498
+ });
499
+ else
500
+ node.material?.dispose();
501
+ }
502
+ });
503
+ }
504
+ scene.fog = null;
505
+ scene.background = null;
506
+ scene.environment = null;
507
+ });
508
+ safeStep('clearAssetCaches', () => clearAssetCaches());
509
+ safeStep('debugDraw.clear', () => debugDraw.clear());
510
+ safeStep('sceneUIHandle.dispose', () => {
511
+ sceneUIHandle?.dispose();
512
+ sceneUIHandle = null;
513
+ });
514
+ safeStep('uiContainer reset', () => {
515
+ uiContainer.innerHTML = '';
516
+ });
517
+ // R8 item 7 (C) — disposeGame (Stop) used to skip both of these, unlike
518
+ // hotReload (warm restart), which already ran them: a game lifecycle
519
+ // system registered via `ctx.systems.register(...)` never had its
520
+ // `dispose()` hook called on a full Stop, and a game-registered
521
+ // systemAdapters kind (e.g. a `setup`-registered 'networking') survived
522
+ // a Stop and would be visible on a STALE `mounted.systems` even though
523
+ // the game that owned it is gone. Same two steps, same relative
524
+ // ordering as hotReload (right after `uiContainer reset`, before the
525
+ // engine-owned audio/input teardown below, which hotReload doesn't
526
+ // touch at all since it warm-restarts rather than tearing engine
527
+ // subsystems down).
528
+ safeStep('systems.removeAllNonEngine', () => systems.removeAllNonEngine());
529
+ safeStep('strip game-registered systemAdapters', () => {
530
+ for (const kind of Object.keys(systemAdapters)) {
531
+ if (!engineAdapterKinds.has(kind))
532
+ delete systemAdapters[kind];
533
+ }
534
+ });
535
+ if (!headless) {
536
+ safeStep('audio teardown', () => {
537
+ audio.masterGain.gain.value = 0;
538
+ audio.listener.context.suspend();
539
+ camera.remove(audio.listener);
540
+ composer.dispose();
541
+ });
542
+ }
543
+ safeStep('input.dispose', () => input.dispose());
544
+ };
545
+ const hotReload = async (newSetup, newEditorPreview) => {
546
+ if (disposed) {
547
+ throw new Error('VgaiSceneGameAdapter: cannot hotReload after dispose()/stop()');
548
+ }
549
+ // Full parity with disposeGame for the parts a warm restart rebuilds:
550
+ // batch-render teardown, game cleanup, component batch teardown (in that
551
+ // ordering, BEFORE bodies are pulled from the world — see disposeGame),
552
+ // scene-UI dispose (React root unmount), and bulk system removal. Each
553
+ // step isolated the same way as disposeGame — one throwing step (e.g. a
554
+ // component dispose) must not abort the rest of the warm restart.
555
+ safeStep('batchSystem.teardown', () => {
556
+ batchSystem?.teardown(); // re-attach detached sources before scene teardown
557
+ batchSystem = null;
558
+ });
559
+ safeStep('currentCleanup.dispose', () => {
560
+ currentCleanup?.dispose();
561
+ currentCleanup = null;
562
+ });
563
+ // Same reasoning as disposeGame: the outgoing scene instance's
564
+ // NavMeshManager was just disposed above, and `hotReload`'s `newSetup`
565
+ // (below) never auto-wires a replacement (that only happens for THIS
566
+ // adapter's own scenePath/sceneData mount, once, at initial mount) — so
567
+ // clear the stale wrapper here. A `newSetup` that wants navigation may
568
+ // register its own via `ctx.registerSystemAdapter('navigation', ...)`.
569
+ safeStep('clear navigation adapter', () => {
570
+ delete systemAdapters.navigation;
571
+ });
572
+ safeStep('components.clear', () => ctx.components.clear());
573
+ safeStep('remove rigid bodies', () => {
574
+ const handles = [];
575
+ physics.rapierWorld.forEachRigidBody((b) => handles.push(b.handle));
576
+ for (const h of handles) {
577
+ const b = physics.rapierWorld.getRigidBody(h);
578
+ if (b)
579
+ physics.rapierWorld.removeRigidBody(b);
580
+ }
581
+ physicsRegistry.clear();
582
+ });
583
+ safeStep('scene children dispose', () => {
584
+ for (const obj of [...scene.children]) {
585
+ if (engineSceneChildren.has(obj))
586
+ continue;
587
+ scene.remove(obj);
588
+ obj.traverse((node) => {
589
+ if (node instanceof THREE.Mesh) {
590
+ if (!hasUserData(node, '__sharedGeometry'))
591
+ node.geometry?.dispose();
592
+ if (Array.isArray(node.material))
593
+ node.material.forEach((m) => {
594
+ m.dispose();
595
+ });
596
+ else
597
+ node.material?.dispose();
598
+ }
599
+ });
600
+ }
601
+ scene.fog = null;
602
+ scene.background = null;
603
+ scene.environment = null;
604
+ });
605
+ safeStep('debugDraw.clear', () => debugDraw.clear());
606
+ safeStep('sceneUIHandle.dispose', () => {
607
+ sceneUIHandle?.dispose();
608
+ sceneUIHandle = null;
609
+ });
610
+ // Strip game-registered scene-UI services back to none before the
611
+ // incoming game's setup/init runs (D7) — same contract as the
612
+ // systemAdapters strip below: a disposed game's onEvent/data/
613
+ // worldProjector must never leak onto the next mount.
614
+ safeStep('reset sceneUIServices', () => {
615
+ sceneUIServices = {};
616
+ });
617
+ safeStep('uiContainer reset', () => {
618
+ uiContainer.innerHTML = '';
619
+ });
620
+ // Bulk-remove every system the outgoing game registered (this restart's
621
+ // predecessor) so warm restarts never accumulate duplicate systems —
622
+ // engine systems registered before mount()'s boundary mark are untouched.
623
+ safeStep('systems.removeAllNonEngine', () => systems.removeAllNonEngine());
624
+ // Strip every GAME-registered systemAdapters kind left by the outgoing
625
+ // game (including any override of a first-party kind) so the disposed
626
+ // game's networking/etc. adapter is never exposed to the next setup —
627
+ // see registerSystemAdapter's docstring in runtime/types.ts. ('navigation'
628
+ // is engine-kind and is NOT touched here — it's a first-party adapter now,
629
+ // kept in sync with the current scene's NavMeshManager by the dedicated
630
+ // `clear navigation adapter` step above instead.) The new setup below
631
+ // either re-registers a kind or it stays absent.
632
+ safeStep('strip game-registered systemAdapters', () => {
633
+ for (const kind of Object.keys(systemAdapters)) {
634
+ if (!engineAdapterKinds.has(kind))
635
+ delete systemAdapters[kind];
636
+ }
637
+ });
638
+ currentCleanup = await newSetup(ctx, newEditorPreview);
639
+ };
640
+ return {
641
+ kind: 'threejs',
642
+ scene,
643
+ camera,
644
+ firstParty: true,
645
+ drivesOwnLoop: false,
646
+ update: (dt) => {
647
+ systems.run(dt);
648
+ postFrame();
649
+ },
650
+ resize: (w, h) => {
651
+ const safeWidth = Math.max(1, w);
652
+ const safeHeight = Math.max(1, h);
653
+ composer.setSize(safeWidth, safeHeight);
654
+ camera.aspect = safeWidth / safeHeight;
655
+ camera.updateProjectionMatrix();
656
+ },
657
+ dispose: disposeGame,
658
+ systems: systemAdapters,
659
+ ctx,
660
+ composer: headless ? null : composer,
661
+ hotReload,
662
+ frame: {
663
+ runPhase: (phase, dt) => systems.runPhase(phase, dt),
664
+ endFrame: postFrame,
665
+ },
666
+ };
667
+ }
668
+ }
669
+ // --- Camera precedence helpers (moved from create-runtime, unchanged) ---
670
+ function applyEditorCamera(editor, runtimeCamera) {
671
+ if (!editor?.viewportCamera)
672
+ return false;
673
+ runtimeCamera.position.fromArray(editor.viewportCamera.position);
674
+ runtimeCamera.quaternion.fromArray(editor.viewportCamera.quaternion);
675
+ return true;
676
+ }
677
+ export function adoptSceneCamera(sceneInstance, runtimeCamera) {
678
+ const sceneCam = sceneInstance.cameras[0];
679
+ if (!sceneCam)
680
+ return false;
681
+ const parent = sceneCam.parent;
682
+ if (parent) {
683
+ parent.updateMatrixWorld(true);
684
+ runtimeCamera.position.copy(parent.getWorldPosition(new THREE.Vector3()));
685
+ runtimeCamera.quaternion.copy(parent.getWorldQuaternion(new THREE.Quaternion()));
686
+ }
687
+ if (sceneCam instanceof THREE.PerspectiveCamera) {
688
+ runtimeCamera.fov = sceneCam.fov;
689
+ runtimeCamera.near = sceneCam.near;
690
+ runtimeCamera.far = sceneCam.far;
691
+ runtimeCamera.updateProjectionMatrix();
692
+ }
693
+ return true;
694
+ }
695
+ /** Headless input stand-in — `InputManager` attaches `window` listeners in its
696
+ * constructor, which Node lacks. The scene-data path never reads input. */
697
+ function headlessInput() {
698
+ return {
699
+ poll: () => { },
700
+ endFrame: () => { },
701
+ dispose: () => { },
702
+ loadMap: async () => { },
703
+ isPressed: () => false,
704
+ getAxis: () => 0,
705
+ };
706
+ }
707
+ /** Headless audio stand-in (no Web Audio). Only the fields the loader/cleanup
708
+ * touch are present; setup-based games never mount headlessly. */
709
+ function headlessAudio() {
710
+ return {
711
+ listener: undefined,
712
+ masterGain: { gain: { value: 1 } },
713
+ };
714
+ }