@vgai/engine 0.5.0 → 0.5.2

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 (538) hide show
  1. package/package.json +1 -1
  2. package/schemas/engine-capabilities.json +4 -4
  3. package/schemas/vgai-game.schema.json +2 -2
  4. package/src/adapter/authoring.ts +42 -0
  5. package/src/adapter/index.ts +3 -0
  6. package/src/adapter/ingest/overlay-apply.ts +50 -6
  7. package/src/adapter/ingest/scene-capture.ts +51 -2
  8. package/src/adapter/vgai-scene-game-adapter.ts +24 -0
  9. package/src/manifest/schema.ts +7 -3
  10. package/src/runtime/create-runtime.ts +97 -0
  11. package/src/runtime/game.ts +11 -1
  12. package/src/scene/asset-ref-check.ts +1 -1
  13. package/src/scene/scene-loader.ts +2 -2
  14. package/src/scene/user-data.ts +18 -0
  15. package/src/world3d-react/behavior.tsx +19 -11
  16. package/src/world3d-react/r3f-adapter.tsx +8 -0
  17. package/dist/adapter/adapter-surface.d.ts +0 -30
  18. package/dist/adapter/adapter-surface.d.ts.map +0 -1
  19. package/dist/adapter/adapter-surface.js +0 -18
  20. package/dist/adapter/authoring.d.ts +0 -461
  21. package/dist/adapter/authoring.d.ts.map +0 -1
  22. package/dist/adapter/authoring.js +0 -22
  23. package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
  24. package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
  25. package/dist/adapter/colyseus-networking-adapter.js +0 -38
  26. package/dist/adapter/first-party-systems.d.ts +0 -38
  27. package/dist/adapter/first-party-systems.d.ts.map +0 -1
  28. package/dist/adapter/first-party-systems.js +0 -77
  29. package/dist/adapter/game-adapter.d.ts +0 -133
  30. package/dist/adapter/game-adapter.d.ts.map +0 -1
  31. package/dist/adapter/game-adapter.js +0 -10
  32. package/dist/adapter/host-context.d.ts +0 -71
  33. package/dist/adapter/host-context.d.ts.map +0 -1
  34. package/dist/adapter/host-context.js +0 -16
  35. package/dist/adapter/index.d.ts +0 -22
  36. package/dist/adapter/index.d.ts.map +0 -1
  37. package/dist/adapter/index.js +0 -15
  38. package/dist/adapter/ingest/game-contract.d.ts +0 -53
  39. package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
  40. package/dist/adapter/ingest/game-contract.js +0 -30
  41. package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
  42. package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
  43. package/dist/adapter/ingest/overlay-applier.js +0 -132
  44. package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
  45. package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
  46. package/dist/adapter/ingest/overlay-apply.js +0 -101
  47. package/dist/adapter/ingest/overlay-file.d.ts +0 -79
  48. package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
  49. package/dist/adapter/ingest/overlay-file.js +0 -66
  50. package/dist/adapter/ingest/overlay-report.d.ts +0 -113
  51. package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
  52. package/dist/adapter/ingest/overlay-report.js +0 -103
  53. package/dist/adapter/ingest/scene-capture.d.ts +0 -97
  54. package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
  55. package/dist/adapter/ingest/scene-capture.js +0 -248
  56. package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
  57. package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
  58. package/dist/adapter/ingest/upstream-pin.js +0 -50
  59. package/dist/adapter/loop-gate-report.d.ts +0 -34
  60. package/dist/adapter/loop-gate-report.d.ts.map +0 -1
  61. package/dist/adapter/loop-gate-report.js +0 -37
  62. package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
  63. package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
  64. package/dist/adapter/rapier-physics-adapter.js +0 -46
  65. package/dist/adapter/system-adapter.d.ts +0 -206
  66. package/dist/adapter/system-adapter.d.ts.map +0 -1
  67. package/dist/adapter/system-adapter.js +0 -13
  68. package/dist/adapter/transform.d.ts +0 -18
  69. package/dist/adapter/transform.d.ts.map +0 -1
  70. package/dist/adapter/transform.js +0 -1
  71. package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -108
  72. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
  73. package/dist/adapter/vgai-scene-game-adapter.js +0 -762
  74. package/dist/ai/navigation.d.ts +0 -64
  75. package/dist/ai/navigation.d.ts.map +0 -1
  76. package/dist/ai/navigation.js +0 -133
  77. package/dist/animation/anim-graph-types.d.ts +0 -25
  78. package/dist/animation/anim-graph-types.d.ts.map +0 -1
  79. package/dist/animation/anim-graph-types.js +0 -1
  80. package/dist/animation/animation-clock.d.ts +0 -213
  81. package/dist/animation/animation-clock.d.ts.map +0 -1
  82. package/dist/animation/animation-clock.js +0 -301
  83. package/dist/animation/blend-node.d.ts +0 -22
  84. package/dist/animation/blend-node.d.ts.map +0 -1
  85. package/dist/animation/blend-node.js +0 -97
  86. package/dist/animation/camera-ownership.d.ts +0 -250
  87. package/dist/animation/camera-ownership.d.ts.map +0 -1
  88. package/dist/animation/camera-ownership.js +0 -169
  89. package/dist/animation/cinematic-cues.d.ts +0 -200
  90. package/dist/animation/cinematic-cues.d.ts.map +0 -1
  91. package/dist/animation/cinematic-cues.js +0 -213
  92. package/dist/animation/clip-map.d.ts +0 -12
  93. package/dist/animation/clip-map.d.ts.map +0 -1
  94. package/dist/animation/clip-map.js +0 -37
  95. package/dist/animation/gsap-registration.d.ts +0 -119
  96. package/dist/animation/gsap-registration.d.ts.map +0 -1
  97. package/dist/animation/gsap-registration.js +0 -92
  98. package/dist/animation/theatre-clock-binding.d.ts +0 -89
  99. package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
  100. package/dist/animation/theatre-clock-binding.js +0 -29
  101. package/dist/animation/theatre-director.d.ts +0 -242
  102. package/dist/animation/theatre-director.d.ts.map +0 -1
  103. package/dist/animation/theatre-director.js +0 -235
  104. package/dist/animation/theatre-object-binding.d.ts +0 -305
  105. package/dist/animation/theatre-object-binding.d.ts.map +0 -1
  106. package/dist/animation/theatre-object-binding.js +0 -351
  107. package/dist/animation/xstate-animation-binding.d.ts +0 -56
  108. package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
  109. package/dist/animation/xstate-animation-binding.js +0 -331
  110. package/dist/animation/xstate-animation-meta.d.ts +0 -266
  111. package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
  112. package/dist/animation/xstate-animation-meta.js +0 -252
  113. package/dist/assets.d.ts +0 -26
  114. package/dist/assets.d.ts.map +0 -1
  115. package/dist/assets.js +0 -55
  116. package/dist/audio/index.d.ts +0 -4
  117. package/dist/audio/index.d.ts.map +0 -1
  118. package/dist/audio/index.js +0 -24
  119. package/dist/audio/tone-clock-binding.d.ts +0 -75
  120. package/dist/audio/tone-clock-binding.d.ts.map +0 -1
  121. package/dist/audio/tone-clock-binding.js +0 -29
  122. package/dist/audio/tone-context.d.ts +0 -114
  123. package/dist/audio/tone-context.d.ts.map +0 -1
  124. package/dist/audio/tone-context.js +0 -39
  125. package/dist/audio/tone-offline-render.d.ts +0 -90
  126. package/dist/audio/tone-offline-render.d.ts.map +0 -1
  127. package/dist/audio/tone-offline-render.js +0 -56
  128. package/dist/audio/wav-encode.d.ts +0 -38
  129. package/dist/audio/wav-encode.d.ts.map +0 -1
  130. package/dist/audio/wav-encode.js +0 -97
  131. package/dist/character/cloth-sim.d.ts +0 -179
  132. package/dist/character/cloth-sim.d.ts.map +0 -1
  133. package/dist/character/cloth-sim.js +0 -334
  134. package/dist/character/spring-chain.d.ts +0 -135
  135. package/dist/character/spring-chain.d.ts.map +0 -1
  136. package/dist/character/spring-chain.js +0 -165
  137. package/dist/core/game-loop.d.ts +0 -42
  138. package/dist/core/game-loop.d.ts.map +0 -1
  139. package/dist/core/game-loop.js +0 -167
  140. package/dist/core/seeded-random.d.ts +0 -69
  141. package/dist/core/seeded-random.d.ts.map +0 -1
  142. package/dist/core/seeded-random.js +0 -121
  143. package/dist/core/system-runner.d.ts +0 -120
  144. package/dist/core/system-runner.d.ts.map +0 -1
  145. package/dist/core/system-runner.js +0 -297
  146. package/dist/core/types.d.ts +0 -92
  147. package/dist/core/types.d.ts.map +0 -1
  148. package/dist/core/types.js +0 -25
  149. package/dist/data/data-asset.d.ts +0 -101
  150. package/dist/data/data-asset.d.ts.map +0 -1
  151. package/dist/data/data-asset.js +0 -122
  152. package/dist/data/data-check-core.d.ts +0 -110
  153. package/dist/data/data-check-core.d.ts.map +0 -1
  154. package/dist/data/data-check-core.js +0 -178
  155. package/dist/data/data-ref.d.ts +0 -79
  156. package/dist/data/data-ref.d.ts.map +0 -1
  157. package/dist/data/data-ref.js +0 -130
  158. package/dist/data/vite-plugin-data.d.ts +0 -79
  159. package/dist/data/vite-plugin-data.d.ts.map +0 -1
  160. package/dist/data/vite-plugin-data.js +0 -217
  161. package/dist/dev/console-bridge.d.ts +0 -22
  162. package/dist/dev/console-bridge.d.ts.map +0 -1
  163. package/dist/dev/console-bridge.js +0 -71
  164. package/dist/dev/debug-draw.d.ts +0 -24
  165. package/dist/dev/debug-draw.d.ts.map +0 -1
  166. package/dist/dev/debug-draw.js +0 -73
  167. package/dist/dev/logger.d.ts +0 -30
  168. package/dist/dev/logger.d.ts.map +0 -1
  169. package/dist/dev/logger.js +0 -90
  170. package/dist/dev/performance-profiler.d.ts +0 -60
  171. package/dist/dev/performance-profiler.d.ts.map +0 -1
  172. package/dist/dev/performance-profiler.js +0 -181
  173. package/dist/dev/webgl-gpu-timer.d.ts +0 -8
  174. package/dist/dev/webgl-gpu-timer.d.ts.map +0 -1
  175. package/dist/dev/webgl-gpu-timer.js +0 -52
  176. package/dist/ecs/component-manager.d.ts +0 -205
  177. package/dist/ecs/component-manager.d.ts.map +0 -1
  178. package/dist/ecs/component-manager.js +0 -706
  179. package/dist/ecs/game-component.d.ts +0 -146
  180. package/dist/ecs/game-component.d.ts.map +0 -1
  181. package/dist/ecs/game-component.js +0 -141
  182. package/dist/ecs/hmr-swap-report.d.ts +0 -53
  183. package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
  184. package/dist/ecs/hmr-swap-report.js +0 -55
  185. package/dist/humanoid/bake.operation.d.ts +0 -119
  186. package/dist/humanoid/bake.operation.d.ts.map +0 -1
  187. package/dist/humanoid/bake.operation.js +0 -228
  188. package/dist/humanoid/body.d.ts +0 -101
  189. package/dist/humanoid/body.d.ts.map +0 -1
  190. package/dist/humanoid/body.js +0 -530
  191. package/dist/humanoid/clips.d.ts +0 -62
  192. package/dist/humanoid/clips.d.ts.map +0 -1
  193. package/dist/humanoid/clips.js +0 -121
  194. package/dist/humanoid/compose.d.ts +0 -75
  195. package/dist/humanoid/compose.d.ts.map +0 -1
  196. package/dist/humanoid/compose.js +0 -176
  197. package/dist/humanoid/generate.d.ts +0 -92
  198. package/dist/humanoid/generate.d.ts.map +0 -1
  199. package/dist/humanoid/generate.js +0 -124
  200. package/dist/humanoid/index.d.ts +0 -24
  201. package/dist/humanoid/index.d.ts.map +0 -1
  202. package/dist/humanoid/index.js +0 -18
  203. package/dist/humanoid/schema.d.ts +0 -35
  204. package/dist/humanoid/schema.d.ts.map +0 -1
  205. package/dist/humanoid/schema.js +0 -87
  206. package/dist/humanoid/skeleton.d.ts +0 -103
  207. package/dist/humanoid/skeleton.d.ts.map +0 -1
  208. package/dist/humanoid/skeleton.js +0 -289
  209. package/dist/index.d.ts +0 -37
  210. package/dist/index.d.ts.map +0 -1
  211. package/dist/index.js +0 -30
  212. package/dist/input/input-manager.d.ts +0 -945
  213. package/dist/input/input-manager.d.ts.map +0 -1
  214. package/dist/input/input-manager.js +0 -2207
  215. package/dist/input/input-types.d.ts +0 -174
  216. package/dist/input/input-types.d.ts.map +0 -1
  217. package/dist/input/input-types.js +0 -1
  218. package/dist/input/prompt-labels.d.ts +0 -21
  219. package/dist/input/prompt-labels.d.ts.map +0 -1
  220. package/dist/input/prompt-labels.js +0 -121
  221. package/dist/input/rebind-controller.d.ts +0 -59
  222. package/dist/input/rebind-controller.d.ts.map +0 -1
  223. package/dist/input/rebind-controller.js +0 -85
  224. package/dist/input/schema.d.ts +0 -16
  225. package/dist/input/schema.d.ts.map +0 -1
  226. package/dist/input/schema.js +0 -228
  227. package/dist/loader.d.ts +0 -43
  228. package/dist/loader.d.ts.map +0 -1
  229. package/dist/loader.js +0 -59
  230. package/dist/manifest/index.d.ts +0 -5
  231. package/dist/manifest/index.d.ts.map +0 -1
  232. package/dist/manifest/index.js +0 -8
  233. package/dist/manifest/load-file.d.ts +0 -4
  234. package/dist/manifest/load-file.d.ts.map +0 -1
  235. package/dist/manifest/load-file.js +0 -14
  236. package/dist/manifest/load.d.ts +0 -144
  237. package/dist/manifest/load.d.ts.map +0 -1
  238. package/dist/manifest/load.js +0 -273
  239. package/dist/manifest/schema.d.ts +0 -230
  240. package/dist/manifest/schema.d.ts.map +0 -1
  241. package/dist/manifest/schema.js +0 -394
  242. package/dist/physics/collision-system.d.ts +0 -41
  243. package/dist/physics/collision-system.d.ts.map +0 -1
  244. package/dist/physics/collision-system.js +0 -64
  245. package/dist/physics/physics-registry.d.ts +0 -45
  246. package/dist/physics/physics-registry.d.ts.map +0 -1
  247. package/dist/physics/physics-registry.js +0 -65
  248. package/dist/physics/transform-writer.d.ts +0 -16
  249. package/dist/physics/transform-writer.d.ts.map +0 -1
  250. package/dist/physics/transform-writer.js +0 -38
  251. package/dist/physics/trigger-dispatch.d.ts +0 -24
  252. package/dist/physics/trigger-dispatch.d.ts.map +0 -1
  253. package/dist/physics/trigger-dispatch.js +0 -80
  254. package/dist/react/game-state.d.ts +0 -156
  255. package/dist/react/game-state.d.ts.map +0 -1
  256. package/dist/react/game-state.js +0 -222
  257. package/dist/react/root-adapter.d.ts +0 -11
  258. package/dist/react/root-adapter.d.ts.map +0 -1
  259. package/dist/react/root-adapter.js +0 -41
  260. package/dist/react/unmanaged-root-detector.d.ts +0 -12
  261. package/dist/react/unmanaged-root-detector.d.ts.map +0 -1
  262. package/dist/react/unmanaged-root-detector.js +0 -45
  263. package/dist/react/use-data.d.ts +0 -60
  264. package/dist/react/use-data.d.ts.map +0 -1
  265. package/dist/react/use-data.js +0 -101
  266. package/dist/react/use-selection.d.ts +0 -75
  267. package/dist/react/use-selection.d.ts.map +0 -1
  268. package/dist/react/use-selection.js +0 -90
  269. package/dist/render/auto-batcher.d.ts +0 -34
  270. package/dist/render/auto-batcher.d.ts.map +0 -1
  271. package/dist/render/auto-batcher.js +0 -140
  272. package/dist/render/render-batch-system.d.ts +0 -33
  273. package/dist/render/render-batch-system.d.ts.map +0 -1
  274. package/dist/render/render-batch-system.js +0 -230
  275. package/dist/render/render-features.d.ts +0 -47
  276. package/dist/render/render-features.d.ts.map +0 -1
  277. package/dist/render/render-features.js +0 -105
  278. package/dist/render/render-settings.d.ts +0 -36
  279. package/dist/render/render-settings.d.ts.map +0 -1
  280. package/dist/render/render-settings.js +0 -51
  281. package/dist/runtime/create-runtime.d.ts +0 -249
  282. package/dist/runtime/create-runtime.d.ts.map +0 -1
  283. package/dist/runtime/create-runtime.js +0 -641
  284. package/dist/runtime/debug-bridge.d.ts +0 -257
  285. package/dist/runtime/debug-bridge.d.ts.map +0 -1
  286. package/dist/runtime/debug-bridge.js +0 -224
  287. package/dist/runtime/debug-registry.d.ts +0 -288
  288. package/dist/runtime/debug-registry.d.ts.map +0 -1
  289. package/dist/runtime/debug-registry.js +0 -513
  290. package/dist/runtime/frame-selector-cache.d.ts +0 -41
  291. package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
  292. package/dist/runtime/frame-selector-cache.js +0 -65
  293. package/dist/runtime/game.d.ts +0 -496
  294. package/dist/runtime/game.d.ts.map +0 -1
  295. package/dist/runtime/game.js +0 -741
  296. package/dist/runtime/gameplay-rng-trap.d.ts +0 -48
  297. package/dist/runtime/gameplay-rng-trap.d.ts.map +0 -1
  298. package/dist/runtime/gameplay-rng-trap.js +0 -96
  299. package/dist/runtime/input-router.d.ts +0 -78
  300. package/dist/runtime/input-router.d.ts.map +0 -1
  301. package/dist/runtime/input-router.js +0 -171
  302. package/dist/runtime/mount-game.d.ts +0 -129
  303. package/dist/runtime/mount-game.d.ts.map +0 -1
  304. package/dist/runtime/mount-game.js +0 -152
  305. package/dist/runtime/mount-manifest.d.ts +0 -173
  306. package/dist/runtime/mount-manifest.d.ts.map +0 -1
  307. package/dist/runtime/mount-manifest.js +0 -297
  308. package/dist/runtime/render-audio-control.d.ts +0 -110
  309. package/dist/runtime/render-audio-control.d.ts.map +0 -1
  310. package/dist/runtime/render-audio-control.js +0 -111
  311. package/dist/runtime/render-control.d.ts +0 -291
  312. package/dist/runtime/render-control.d.ts.map +0 -1
  313. package/dist/runtime/render-control.js +0 -264
  314. package/dist/runtime/render-seed.d.ts +0 -57
  315. package/dist/runtime/render-seed.d.ts.map +0 -1
  316. package/dist/runtime/render-seed.js +0 -74
  317. package/dist/runtime/state-bridge.d.ts +0 -61
  318. package/dist/runtime/state-bridge.d.ts.map +0 -1
  319. package/dist/runtime/state-bridge.js +0 -63
  320. package/dist/runtime/types.d.ts +0 -253
  321. package/dist/runtime/types.d.ts.map +0 -1
  322. package/dist/runtime/types.js +0 -1
  323. package/dist/scene/asset-loaders.d.ts +0 -79
  324. package/dist/scene/asset-loaders.d.ts.map +0 -1
  325. package/dist/scene/asset-loaders.js +0 -141
  326. package/dist/scene/asset-paths.d.ts +0 -11
  327. package/dist/scene/asset-paths.d.ts.map +0 -1
  328. package/dist/scene/asset-paths.js +0 -108
  329. package/dist/scene/asset-ref-check.d.ts +0 -88
  330. package/dist/scene/asset-ref-check.d.ts.map +0 -1
  331. package/dist/scene/asset-ref-check.js +0 -214
  332. package/dist/scene/asset-registry.d.ts +0 -38
  333. package/dist/scene/asset-registry.d.ts.map +0 -1
  334. package/dist/scene/asset-registry.js +0 -66
  335. package/dist/scene/collider-dimensions.d.ts +0 -63
  336. package/dist/scene/collider-dimensions.d.ts.map +0 -1
  337. package/dist/scene/collider-dimensions.js +0 -98
  338. package/dist/scene/component-registry.d.ts +0 -22
  339. package/dist/scene/component-registry.d.ts.map +0 -1
  340. package/dist/scene/component-registry.js +0 -37
  341. package/dist/scene/defaults.d.ts +0 -252
  342. package/dist/scene/defaults.d.ts.map +0 -1
  343. package/dist/scene/defaults.js +0 -151
  344. package/dist/scene/geometries/index.d.ts +0 -8
  345. package/dist/scene/geometries/index.d.ts.map +0 -1
  346. package/dist/scene/geometries/index.js +0 -7
  347. package/dist/scene/geometries/terrain.d.ts +0 -2
  348. package/dist/scene/geometries/terrain.d.ts.map +0 -1
  349. package/dist/scene/geometries/terrain.js +0 -37
  350. package/dist/scene/geometry-registry.d.ts +0 -24
  351. package/dist/scene/geometry-registry.d.ts.map +0 -1
  352. package/dist/scene/geometry-registry.js +0 -20
  353. package/dist/scene/instance-registry.d.ts +0 -36
  354. package/dist/scene/instance-registry.d.ts.map +0 -1
  355. package/dist/scene/instance-registry.js +0 -55
  356. package/dist/scene/instancers/grid.d.ts +0 -2
  357. package/dist/scene/instancers/grid.d.ts.map +0 -1
  358. package/dist/scene/instancers/grid.js +0 -36
  359. package/dist/scene/instancers/index.d.ts +0 -8
  360. package/dist/scene/instancers/index.d.ts.map +0 -1
  361. package/dist/scene/instancers/index.js +0 -7
  362. package/dist/scene/light-camera-factory.d.ts +0 -23
  363. package/dist/scene/light-camera-factory.d.ts.map +0 -1
  364. package/dist/scene/light-camera-factory.js +0 -68
  365. package/dist/scene/material-factory.d.ts +0 -17
  366. package/dist/scene/material-factory.d.ts.map +0 -1
  367. package/dist/scene/material-factory.js +0 -197
  368. package/dist/scene/material-registry.d.ts +0 -40
  369. package/dist/scene/material-registry.d.ts.map +0 -1
  370. package/dist/scene/material-registry.js +0 -44
  371. package/dist/scene/materials/index.d.ts +0 -8
  372. package/dist/scene/materials/index.d.ts.map +0 -1
  373. package/dist/scene/materials/index.js +0 -7
  374. package/dist/scene/materials/water.d.ts +0 -2
  375. package/dist/scene/materials/water.d.ts.map +0 -1
  376. package/dist/scene/materials/water.js +0 -54
  377. package/dist/scene/parse.d.ts +0 -23
  378. package/dist/scene/parse.d.ts.map +0 -1
  379. package/dist/scene/parse.js +0 -179
  380. package/dist/scene/particles-factory.d.ts +0 -33
  381. package/dist/scene/particles-factory.d.ts.map +0 -1
  382. package/dist/scene/particles-factory.js +0 -282
  383. package/dist/scene/scene-apply.d.ts +0 -109
  384. package/dist/scene/scene-apply.d.ts.map +0 -1
  385. package/dist/scene/scene-apply.js +0 -370
  386. package/dist/scene/scene-diff-schema.d.ts +0 -285
  387. package/dist/scene/scene-diff-schema.d.ts.map +0 -1
  388. package/dist/scene/scene-diff-schema.js +0 -92
  389. package/dist/scene/scene-diff-types.d.ts +0 -40
  390. package/dist/scene/scene-diff-types.d.ts.map +0 -1
  391. package/dist/scene/scene-diff-types.js +0 -14
  392. package/dist/scene/scene-loader.d.ts +0 -167
  393. package/dist/scene/scene-loader.d.ts.map +0 -1
  394. package/dist/scene/scene-loader.js +0 -1211
  395. package/dist/scene/scene-query.d.ts +0 -11
  396. package/dist/scene/scene-query.d.ts.map +0 -1
  397. package/dist/scene/scene-query.js +0 -63
  398. package/dist/scene/scene-types.d.ts +0 -10
  399. package/dist/scene/scene-types.d.ts.map +0 -1
  400. package/dist/scene/scene-types.js +0 -8
  401. package/dist/scene/scene-version.d.ts +0 -26
  402. package/dist/scene/scene-version.d.ts.map +0 -1
  403. package/dist/scene/scene-version.js +0 -34
  404. package/dist/scene/schema/animation.d.ts +0 -8
  405. package/dist/scene/schema/animation.d.ts.map +0 -1
  406. package/dist/scene/schema/animation.js +0 -42
  407. package/dist/scene/schema/audio.d.ts +0 -13
  408. package/dist/scene/schema/audio.d.ts.map +0 -1
  409. package/dist/scene/schema/audio.js +0 -22
  410. package/dist/scene/schema/camera.d.ts +0 -28
  411. package/dist/scene/schema/camera.d.ts.map +0 -1
  412. package/dist/scene/schema/camera.js +0 -17
  413. package/dist/scene/schema/collider.d.ts +0 -40
  414. package/dist/scene/schema/collider.d.ts.map +0 -1
  415. package/dist/scene/schema/collider.js +0 -55
  416. package/dist/scene/schema/entity-ref.d.ts +0 -31
  417. package/dist/scene/schema/entity-ref.d.ts.map +0 -1
  418. package/dist/scene/schema/entity-ref.js +0 -61
  419. package/dist/scene/schema/entity.d.ts +0 -1036
  420. package/dist/scene/schema/entity.d.ts.map +0 -1
  421. package/dist/scene/schema/entity.js +0 -153
  422. package/dist/scene/schema/environment.d.ts +0 -425
  423. package/dist/scene/schema/environment.d.ts.map +0 -1
  424. package/dist/scene/schema/environment.js +0 -357
  425. package/dist/scene/schema/index.d.ts +0 -37
  426. package/dist/scene/schema/index.d.ts.map +0 -1
  427. package/dist/scene/schema/index.js +0 -19
  428. package/dist/scene/schema/instances.d.ts +0 -14
  429. package/dist/scene/schema/instances.d.ts.map +0 -1
  430. package/dist/scene/schema/instances.js +0 -28
  431. package/dist/scene/schema/joint.d.ts +0 -23
  432. package/dist/scene/schema/joint.d.ts.map +0 -1
  433. package/dist/scene/schema/joint.js +0 -23
  434. package/dist/scene/schema/light.d.ts +0 -38
  435. package/dist/scene/schema/light.d.ts.map +0 -1
  436. package/dist/scene/schema/light.js +0 -26
  437. package/dist/scene/schema/material.d.ts +0 -199
  438. package/dist/scene/schema/material.d.ts.map +0 -1
  439. package/dist/scene/schema/material.js +0 -103
  440. package/dist/scene/schema/mesh.d.ts +0 -48
  441. package/dist/scene/schema/mesh.d.ts.map +0 -1
  442. package/dist/scene/schema/mesh.js +0 -82
  443. package/dist/scene/schema/particles.d.ts +0 -2178
  444. package/dist/scene/schema/particles.d.ts.map +0 -1
  445. package/dist/scene/schema/particles.js +0 -321
  446. package/dist/scene/schema/physics.d.ts +0 -56
  447. package/dist/scene/schema/physics.d.ts.map +0 -1
  448. package/dist/scene/schema/physics.js +0 -37
  449. package/dist/scene/schema/scene-file.d.ts +0 -303
  450. package/dist/scene/schema/scene-file.d.ts.map +0 -1
  451. package/dist/scene/schema/scene-file.js +0 -256
  452. package/dist/scene/schema/shadow.d.ts +0 -28
  453. package/dist/scene/schema/shadow.d.ts.map +0 -1
  454. package/dist/scene/schema/shadow.js +0 -20
  455. package/dist/scene/schema/spline.d.ts +0 -25
  456. package/dist/scene/schema/spline.d.ts.map +0 -1
  457. package/dist/scene/schema/spline.js +0 -15
  458. package/dist/scene/schema/tuples.d.ts +0 -12
  459. package/dist/scene/schema/tuples.d.ts.map +0 -1
  460. package/dist/scene/schema/tuples.js +0 -14
  461. package/dist/scene/user-data.d.ts +0 -185
  462. package/dist/scene/user-data.d.ts.map +0 -1
  463. package/dist/scene/user-data.js +0 -144
  464. package/dist/setup/setup-audio.d.ts +0 -20
  465. package/dist/setup/setup-audio.d.ts.map +0 -1
  466. package/dist/setup/setup-audio.js +0 -41
  467. package/dist/setup/setup-particles.d.ts +0 -17
  468. package/dist/setup/setup-particles.d.ts.map +0 -1
  469. package/dist/setup/setup-particles.js +0 -16
  470. package/dist/setup/setup-physics.d.ts +0 -25
  471. package/dist/setup/setup-physics.d.ts.map +0 -1
  472. package/dist/setup/setup-physics.js +0 -51
  473. package/dist/setup/setup-renderer.d.ts +0 -69
  474. package/dist/setup/setup-renderer.d.ts.map +0 -1
  475. package/dist/setup/setup-renderer.js +0 -363
  476. package/dist/tools/define-tool.d.ts +0 -130
  477. package/dist/tools/define-tool.d.ts.map +0 -1
  478. package/dist/tools/define-tool.js +0 -96
  479. package/dist/world2d/authoring-2d.d.ts +0 -80
  480. package/dist/world2d/authoring-2d.d.ts.map +0 -1
  481. package/dist/world2d/authoring-2d.js +0 -195
  482. package/dist/world2d/capture-to-scene2d.d.ts +0 -5
  483. package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
  484. package/dist/world2d/capture-to-scene2d.js +0 -49
  485. package/dist/world2d/collision-2d.d.ts +0 -52
  486. package/dist/world2d/collision-2d.d.ts.map +0 -1
  487. package/dist/world2d/collision-2d.js +0 -70
  488. package/dist/world2d/components-2d.d.ts +0 -47
  489. package/dist/world2d/components-2d.d.ts.map +0 -1
  490. package/dist/world2d/components-2d.js +0 -77
  491. package/dist/world2d/index.d.ts +0 -34
  492. package/dist/world2d/index.d.ts.map +0 -1
  493. package/dist/world2d/index.js +0 -32
  494. package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
  495. package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
  496. package/dist/world2d/ingest-iframe-2d.js +0 -166
  497. package/dist/world2d/ingest2d.d.ts +0 -97
  498. package/dist/world2d/ingest2d.d.ts.map +0 -1
  499. package/dist/world2d/ingest2d.js +0 -40
  500. package/dist/world2d/physics2d-registry.d.ts +0 -24
  501. package/dist/world2d/physics2d-registry.d.ts.map +0 -1
  502. package/dist/world2d/physics2d-registry.js +0 -38
  503. package/dist/world2d/pixi-game-adapter.d.ts +0 -107
  504. package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
  505. package/dist/world2d/pixi-game-adapter.js +0 -210
  506. package/dist/world2d/pixi-surface.d.ts +0 -39
  507. package/dist/world2d/pixi-surface.d.ts.map +0 -1
  508. package/dist/world2d/pixi-surface.js +0 -47
  509. package/dist/world2d/scene-capture-2d.d.ts +0 -43
  510. package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
  511. package/dist/world2d/scene-capture-2d.js +0 -92
  512. package/dist/world2d/scene2d-loader.d.ts +0 -27
  513. package/dist/world2d/scene2d-loader.d.ts.map +0 -1
  514. package/dist/world2d/scene2d-loader.js +0 -275
  515. package/dist/world2d/schema/entity2d.d.ts +0 -102
  516. package/dist/world2d/schema/entity2d.d.ts.map +0 -1
  517. package/dist/world2d/schema/entity2d.js +0 -119
  518. package/dist/world2d/schema/physics2d.d.ts +0 -46
  519. package/dist/world2d/schema/physics2d.d.ts.map +0 -1
  520. package/dist/world2d/schema/physics2d.js +0 -45
  521. package/dist/world2d/schema/sprite.d.ts +0 -42
  522. package/dist/world2d/schema/sprite.d.ts.map +0 -1
  523. package/dist/world2d/schema/sprite.js +0 -63
  524. package/dist/world2d/schema/tilemap.d.ts +0 -15
  525. package/dist/world2d/schema/tilemap.d.ts.map +0 -1
  526. package/dist/world2d/schema/tilemap.js +0 -19
  527. package/dist/world2d/schema/tuples2d.d.ts +0 -20
  528. package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
  529. package/dist/world2d/schema/tuples2d.js +0 -19
  530. package/dist/world2d/system-adapters-2d.d.ts +0 -16
  531. package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
  532. package/dist/world2d/system-adapters-2d.js +0 -37
  533. package/dist/world2d/transform-writer-2d.d.ts +0 -16
  534. package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
  535. package/dist/world2d/transform-writer-2d.js +0 -22
  536. package/dist/world2d/types.d.ts +0 -59
  537. package/dist/world2d/types.d.ts.map +0 -1
  538. package/dist/world2d/types.js +0 -1
@@ -1,762 +0,0 @@
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 { createSeededRandom, DEFAULT_SEEDED_RANDOM_SEED, getSeededRandom, } from '../core/seeded-random';
17
- import { createSystemRunner } from '../core/system-runner';
18
- import { createDebugDraw } from '../dev/debug-draw';
19
- import { createWebGLGpuTimer } from '../dev/webgl-gpu-timer';
20
- import { createComponentManager } from '../ecs/component-manager';
21
- import { InputManager } from '../input/input-manager';
22
- import { setAssetPrefix } from '../loader';
23
- import { createCollisionSystem } from '../physics/collision-system';
24
- import { createPhysicsRegistry } from '../physics/physics-registry';
25
- import { createTransformWriter } from '../physics/transform-writer';
26
- import { createTriggerDispatch } from '../physics/trigger-dispatch';
27
- import { RenderBatchSystem } from '../render/render-batch-system';
28
- import { resolveRenderSettings } from '../render/render-settings';
29
- import { createDebugRegistry, getDebugRegistry, } from '../runtime/debug-registry';
30
- import { tickCustomMaterials } from '../scene/material-registry';
31
- import { clearAssetCaches, loadScene, loadSceneFromData, updateSceneLODs, } from '../scene/scene-loader';
32
- import { hasUserData, setUserData } from '../scene/user-data';
33
- import { setupAudio } from '../setup/setup-audio';
34
- import { setupParticles } from '../setup/setup-particles';
35
- import { setupPhysics, updatePhysicsDebug } from '../setup/setup-physics';
36
- import { applyRendererSettings, applyScenePostProcessing, createSceneView, } from '../setup/setup-renderer';
37
- import { createAudioSystemAdapter, createInputManagerAdapter, createNavigationAdapter, createVgaiAssetAdapter, } from './first-party-systems';
38
- import { createRapierPhysicsAdapter } from './rapier-physics-adapter';
39
- /** Minimal stand-in for the GPU composer when mounting headlessly. */
40
- function headlessComposer(renderer) {
41
- return {
42
- render: () => { },
43
- setSize: () => { },
44
- dispose: () => { },
45
- addPass: () => { },
46
- removeAllPasses: () => { },
47
- passes: [],
48
- getRenderer: () => renderer,
49
- };
50
- }
51
- /**
52
- * Wrap a first-party `setup` function as a {@link GameAdapter}. This is how every
53
- * first-party example becomes an implementer of the same interface an external
54
- * game implements — with no change to the setup's body.
55
- */
56
- export function fromSetup(id, setup) {
57
- return new VgaiSceneGameAdapter({ id, setup });
58
- }
59
- export class VgaiSceneGameAdapter {
60
- config;
61
- id;
62
- constructor(config = {}) {
63
- this.config = config;
64
- this.id = config.id ?? 'vgai-scene';
65
- }
66
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one cohesive first-party bootstrap (moved verbatim from create-runtime); splitting it would obscure the ordering contract
67
- async mount(host) {
68
- const { setup, editorPreview, scenePath, sceneData, componentRegistry, inputMapPath = '/inputmaps/default.inputmap.json', assetPrefix = '/', } = this.config;
69
- const headless = host.headless === true;
70
- const { width, height } = host.surface;
71
- const renderer = host.renderer;
72
- setAssetPrefix(assetPrefix);
73
- // --- Scene view (scene/camera/composer). Browser: the canonical builder, so
74
- // behavior is byte-identical to the old create-runtime. Headless: plain
75
- // scene/camera + a no-op composer (no GPU). ---
76
- let scene;
77
- let camera;
78
- let composer;
79
- if (headless) {
80
- scene = new THREE.Scene();
81
- scene.background = new THREE.Color(0x1a1a2e);
82
- camera = new THREE.PerspectiveCamera(60, width / height || 1, 0.1, 1000);
83
- camera.position.set(0, 5, 10);
84
- camera.lookAt(0, 0, 0);
85
- composer = headlessComposer(renderer);
86
- }
87
- else {
88
- const view = createSceneView(renderer, width, height);
89
- scene = view.scene;
90
- camera = view.camera;
91
- composer = view.composer;
92
- }
93
- // --- Rapier physics ---
94
- await RAPIER.init();
95
- const physics = setupPhysics(RAPIER, scene);
96
- const physicsRegistry = createPhysicsRegistry();
97
- const writeTransforms = createTransformWriter(physicsRegistry, scene);
98
- // --- Input (InputManager attaches window listeners; stub it headlessly) ---
99
- const input = headless ? headlessInput() : new InputManager();
100
- if (!headless)
101
- await input.loadMap(inputMapPath);
102
- // --- Collision system ---
103
- const collisions = createCollisionSystem(physics.rapierWorld, physics.eventQueue);
104
- // --- Audio (Web Audio — browser only) ---
105
- const audio = headless ? headlessAudio() : setupAudio(camera);
106
- // --- Particles (three.quarks BatchedRenderer) ---
107
- const particles = setupParticles(scene);
108
- // --- Debug draw / assets ---
109
- const debugDraw = createDebugDraw(scene);
110
- const assets = host.assets;
111
- // Test/headless adapters may provide the renderer surface needed by the
112
- // runtime without a real WebGL context. GPU timing is optional diagnostics:
113
- // degrade honestly when the renderer/context cannot expose extensions.
114
- const rendererContext = typeof renderer.getContext === 'function' ? renderer.getContext() : undefined;
115
- const gpuTimer = !headless && rendererContext && typeof rendererContext.getExtension === 'function'
116
- ? createWebGLGpuTimer(rendererContext)
117
- : null;
118
- // --- System runner (engine-level systems) ---
119
- const systems = createSystemRunner(host.game?.profiler.systemObserver, 'threejs');
120
- // D15/T-D15.3/.5: pass the LIVE shared game tick (not a locally-counted
121
- // one) into every `poll()` call — `debugRegistry` is declared further
122
- // down in this same `mount()` (it needs `ctx`/`systemAdapters` to exist
123
- // first), but this callback only ever executes during real frame
124
- // ticks, long after `mount()` has fully returned and `debugRegistry` is
125
- // initialized (a safe closure-over-a-later-const, not a genuine
126
- // use-before-init). `host.game` gates it: a bare mount with no `Game`
127
- // shell behind it (test harnesses predating T7.1) has no shared tick to
128
- // key off, so `InputManager.poll()` falls back to its own internal
129
- // self-incrementing counter instead (unchanged pre-D15 behavior) rather
130
- // than being pinned to a constant `0` forever.
131
- systems.add('input', () => input.poll(host.game ? debugRegistry.getGameTick() : undefined), {
132
- name: 'input.poll',
133
- });
134
- systems.add('physics', () => physics.rapierWorld.step(physics.eventQueue), {
135
- name: 'physics.step',
136
- });
137
- systems.add('postPhysics', () => {
138
- collisions.drain();
139
- writeTransforms();
140
- }, { name: 'physics.sync' });
141
- systems.add('preRender', (dt) => {
142
- particles.batchedRenderer.update(dt);
143
- tickCustomMaterials(scene, dt);
144
- updateSceneLODs(scene, camera);
145
- }, { name: 'materials-and-particles' });
146
- if (!headless) {
147
- systems.add('render', (dt) => {
148
- if (host.game?.profiler.enabled)
149
- gpuTimer?.begin();
150
- try {
151
- composer.render(dt);
152
- }
153
- finally {
154
- gpuTimer?.end();
155
- }
156
- if (physics.debugEnabled)
157
- updatePhysicsDebug(physics.rapierWorld, physics.debugMesh);
158
- }, { name: 'three.render' });
159
- }
160
- // --- Debug toggle (browser only) ---
161
- const onDebugToggle = (e) => {
162
- if (e.code === 'KeyP') {
163
- physics.debugEnabled = !physics.debugEnabled;
164
- physics.debugMesh.visible = physics.debugEnabled;
165
- }
166
- };
167
- if (!headless)
168
- window.addEventListener('keydown', onDebugToggle);
169
- const postFrame = () => {
170
- input.endFrame();
171
- if (host.game?.profiler.enabled) {
172
- host.game.profiler.reportRender({
173
- gpuMs: gpuTimer?.poll() ?? null,
174
- drawCalls: renderer.info.render.calls,
175
- triangles: renderer.info.render.triangles,
176
- geometries: renderer.info.memory.geometries,
177
- textures: renderer.info.memory.textures,
178
- });
179
- }
180
- };
181
- // The mounted game's adapter surface (`mounted.systems`). Declared before
182
- // ctx so `ctx.registerSystemAdapter` can close over it: the engine fills
183
- // the first-party entries below; GAME-owned capabilities (networking,
184
- // navigation) are registered by the game's setup through the ctx hook.
185
- // The editor holds this same object reference (setActiveSystems), so
186
- // late registrations are visible to its panels at read time.
187
- const systemAdapters = {};
188
- // --- GameContext (the first-party runtime surface) ---
189
- const ctx = {
190
- scene,
191
- camera,
192
- rapierWorld: physics.rapierWorld,
193
- rapier: RAPIER,
194
- physics: physicsRegistry,
195
- input,
196
- collisions,
197
- composer,
198
- audio,
199
- particles,
200
- debugDraw,
201
- assets,
202
- systems,
203
- components: null,
204
- registerSystemAdapter: (kind, adapter) => {
205
- systemAdapters[kind] = adapter;
206
- },
207
- };
208
- // Game root (T7.1 slice 1): only present once the host has constructed a
209
- // Game shell (createGameRuntime does this before mount; headless/foreign
210
- // hosts may omit it — ctx.game/ctx.roots simply stay undefined, which is
211
- // the documented zero-break behavior). `ctx.roots` is assigned the SAME
212
- // live array `host.game` mutates via `registerWorld` (not a copy) — the
213
- // default world is registered AFTER mount returns, and this reference
214
- // must observe that later push.
215
- if (host.game) {
216
- ctx.game = host.game;
217
- ctx.roots = host.game.roots;
218
- }
219
- ctx.components = createComponentManager(ctx, physicsRegistry);
220
- collisions.onCollision(createTriggerDispatch(physicsRegistry, ctx.components, physics.rapierWorld, ctx));
221
- // Everything registered above (engine systems + the ComponentManager's
222
- // per-phase tick, just wired in) is "engine" and must survive a warm
223
- // restart. Everything a game (setup()/scenePath/sceneData, below) adds
224
- // from here on is "game" content that `hotReload` bulk-removes via
225
- // `systems.removeAllNonEngine()` on every restart (T1.7).
226
- systems.markEngineBoundary();
227
- // First-party System adapters over the real subsystems — seeded HERE,
228
- // BEFORE setup()/scene load runs below, so that a game which registers any
229
- // of these kinds during its own setup (via `ctx.registerSystemAdapter`)
230
- // always wins over the engine's first-party entry (see
231
- // registerSystemAdapter's docstring in runtime/types.ts). `navigation` is
232
- // ALSO first-party now (R8 item 7): `createNavigationAdapter` wraps the
233
- // real `NavMeshManager` a scenePath/sceneData scene load may produce (see
234
- // `applySceneNavigation` below) — it is wired once that scene instance
235
- // resolves, not here (no NavMeshManager exists yet at this point in the
236
- // mount). `networking` remains the one game-owned capability with no
237
- // first-party implementer; it simply starts absent here.
238
- systemAdapters.physics = createRapierPhysicsAdapter(physicsRegistry, physics.debugMesh);
239
- systemAdapters.input = createInputManagerAdapter(input);
240
- systemAdapters.assets = createVgaiAssetAdapter();
241
- // D10/T7.6: the audio seam `Game.play.pause()` silences on pause. Works
242
- // against the headless stand-in too (`headlessAudio()`'s plain
243
- // `masterGain.gain` object) — this world's `pause()` mutes it harmlessly.
244
- systemAdapters.audio = createAudioSystemAdapter(audio);
245
- // Debug/synthetic-player seam (T1.1, docs/SYNTHETIC-PLAYER-SPEC.md §3.1):
246
- // ONE registry per Game root, shared across every world that mounts onto
247
- // it — `getDebugRegistry(host.game)` reaches the SAME accumulator
248
- // `createGame` filed, so a second/third world's `ctx.debug` feeds it too
249
- // (see debug-registry.ts's module doc for the provenance/id note). A
250
- // mount with no Game shell at all (bare test harnesses predating T7.1)
251
- // gets a private, mount-local registry instead — same absence precedent
252
- // as `ctx.game`/`ctx.roots` above.
253
- const debugRegistry = (host.game ? getDebugRegistry(host.game) : null) ??
254
- createDebugRegistry({ getTick: () => 0, getSimT: () => 0 });
255
- systemAdapters.debug = debugRegistry.adapter;
256
- ctx.debug = debugRegistry.forWorld(this.id);
257
- // T1.2: the InputManager is a first-party per-world handle the registry
258
- // has no other way to reach — wired as a lazy supplier (not a direct
259
- // read here), scoped to THIS world's id, so the built-in `input.actions`
260
- // provider always reflects the CURRENT action set, not a snapshot taken
261
- // at mount time. Per-world (not a single last-writer-wins slot) since
262
- // D15/T-D15.5 — see `debug-registry.ts`'s `setInputActionsSource` doc.
263
- debugRegistry.setInputActionsSource(this.id, () => typeof input.actionNames === 'function'
264
- ? input.actionNames().map((name) => ({ name, valueType: input.getActionValueType(name) }))
265
- : []);
266
- // D15/T-D15.5 — same lazy-supplier pattern (and same headless-stand-in
267
- // guard) as `setInputActionsSource` immediately above: the built-in
268
- // `input.trace` provider always reads the CURRENT recorded trace, never
269
- // a snapshot taken at mount time. `seed`/`fixedDt` are assembled here
270
- // (not inside `InputManager`, which has no business knowing about
271
- // `ctx.random` or the loop) — the two replay-critical metadata fields
272
- // the design doc's format sketch (§2.c) calls for beside the raw
273
- // per-tick deltas; `null` only absent a Game/ctx.random behind this
274
- // mount, matching every other "no Game" fallback in this file.
275
- debugRegistry.setInputTraceSource(this.id, () => {
276
- const raw = typeof input.getInputTrace === 'function'
277
- ? input.getInputTrace()
278
- : { version: 1, ticks: [] };
279
- const seed = (host.game ? getSeededRandom(host.game) : null)?.seed ?? null;
280
- const fixedDt = host.game?.loop.fixedDt ?? null;
281
- return { version: raw.version, seed, fixedDt, ticks: raw.ticks };
282
- });
283
- // Task 2.1 — the same InputManager instance, wired as the debug bridge's
284
- // actuation target (`runtime/debug-bridge.ts`'s `input.*` methods) at the
285
- // same seed spot as `setInputActionsSource` above. Per-world (D15 review
286
- // objection 2 fix) — see `debug-registry.ts`'s `setVirtualInputTarget`
287
- // doc for why this used to be a single last-writer-wins slot.
288
- debugRegistry.setVirtualInputTarget(this.id, {
289
- setVirtualAction: (action, value) => input.setVirtualAction(action, value),
290
- tapVirtualAction: (action) => input.tapVirtualAction(action),
291
- clearVirtualActions: () => input.clearVirtualActions(),
292
- scheduleActionAtTick: (tick, action, value) => input.scheduleActionAtTick(tick, action, value),
293
- startInputRecording: () => input.startInputRecording(),
294
- stopInputRecording: () => input.stopInputRecording(),
295
- isInputRecording: () => input.isInputRecording(),
296
- injectAxis: (sourceId, value) => input.injectAxis(sourceId, value),
297
- injectVector2: (sourceId, value) => input.injectVector2(sourceId, value),
298
- injectPointerDelta: (sourceId, delta) => input.injectPointerDelta(sourceId, delta),
299
- injectPointerPosition: (sourceId, value) => input.injectPointerPosition(sourceId, value),
300
- });
301
- // R4-class fix — wire the InputManager's `'input.schedule.dropped'` sink
302
- // to THIS world's debug registry, same seed spot/precedent as
303
- // `setInputActionsSource`/`setVirtualInputTarget` above (typeof-guarded:
304
- // a headless `InputManager` stand-in may have no `setDebugEmit`).
305
- if (typeof input.setDebugEmit === 'function') {
306
- input.setDebugEmit((event, detail) => ctx.debug?.emit(event, detail));
307
- }
308
- // D15 (T-D15.1) — same "ONE per Game root, shared across every world"
309
- // pattern as the debug registry immediately above: `getSeededRandom
310
- // (host.game)` reaches the SAME `SeededRandom` `createGame` filed (boot-
311
- // seeded by the manifest-aware mount path, `mount-manifest.ts`, before
312
- // ANY world's `mount()`/`setup()` runs — see `createGame`'s own doc
313
- // comment), so every world's `ctx.random` is the identical instance, not
314
- // a per-world copy. Same absence precedent as `ctx.debug`: a mount with
315
- // no Game shell at all gets a private, mount-local surface instead.
316
- ctx.random =
317
- (host.game ? getSeededRandom(host.game) : null) ??
318
- createSeededRandom(DEFAULT_SEEDED_RANDOM_SEED);
319
- // Snapshot of the engine-owned adapter kinds, taken right after seeding
320
- // and before any setup() has had a chance to run. `hotReload`/`disposeGame`
321
- // use this to strip every GAME-registered kind (including an override of a
322
- // first-party kind) left over from the outgoing game, so a warm restart or
323
- // a full stop never exposes a disposed game's networking/etc. adapter to
324
- // the next setup.
325
- const engineAdapterKinds = new Set(Object.keys(systemAdapters));
326
- // 'navigation' is engine-owned too (R8 item 7), but the scene load that
327
- // populates it (below, `applySceneNavigation`) happens AFTER this
328
- // snapshot — add it explicitly so the generic "strip every non-engine
329
- // kind" step (hotReload/disposeGame) never mistakes a first-party
330
- // navigation adapter for game-registered content and deletes it. (The
331
- // adapter is still kept in sync with the CURRENT scene's NavMeshManager
332
- // via the dedicated `clear navigation adapter` teardown step below, which
333
- // runs independently of this snapshot.)
334
- engineAdapterKinds.add('navigation');
335
- // --- Scene / game setup ---
336
- const engineSceneChildren = new Set(scene.children.slice());
337
- // Tag engine-owned infra (particle BatchedRenderer, debug-draw + subtrees) so
338
- // the editor's play-mode hierarchy skips them — they're not game entities.
339
- for (const c of engineSceneChildren) {
340
- c.traverse((n) => setUserData(n, 'engineInternal', true));
341
- }
342
- let currentCleanup = null;
343
- let batchSystem = null;
344
- // Apply scene-level render settings + transparent auto-batching after a scene
345
- // loads (GPU host only). Gated on the resolved `environment.rendering` cascade
346
- // (defaults preserve prior behavior when a scene omits `rendering`).
347
- const applySceneRendering = (inst) => {
348
- if (headless)
349
- return;
350
- const scope = inst.environment?.rendering;
351
- const settings = resolveRenderSettings(scope);
352
- // live renderer settings (shadows, resolution scale)
353
- applyRendererSettings(renderer, scope);
354
- // post-processing master switch: (re)build when the scene defines effects OR
355
- // the master is off (to strip the default bloom pass down to a plain scene).
356
- if (inst.environment?.postProcessing || !settings['postProcessing']) {
357
- applyScenePostProcessing(composer, renderer, scene, camera, inst.environment);
358
- }
359
- // transparent batching: collapse static/mover meshes sharing a signature
360
- if (settings['autoBatch']) {
361
- batchSystem = new RenderBatchSystem(scene, settings);
362
- batchSystem.build();
363
- ctx.systems.add('preRender', () => batchSystem?.update());
364
- if (import.meta.env?.DEV)
365
- window.__vgaiBatch = batchSystem;
366
- }
367
- };
368
- // Wire the (first-party) navigation system adapter to whichever
369
- // NavMeshManager the CURRENT scene instance carries — reassigned on every
370
- // scene load, and explicitly cleared (not just left stale) when the new
371
- // scene has none, so `mounted.systems.navigation` never lingers pointing
372
- // at a manager a later teardown step disposes (R8 item 7).
373
- const applySceneNavigation = (inst) => {
374
- if (inst.navMesh) {
375
- systemAdapters.navigation = createNavigationAdapter(inst.navMesh);
376
- }
377
- else {
378
- delete systemAdapters.navigation;
379
- }
380
- };
381
- const loadFromData = async (data) => {
382
- const inst = await loadSceneFromData(data, {
383
- scene,
384
- rapierWorld: ctx.rapierWorld,
385
- rapier: ctx.rapier,
386
- physics: ctx.physics,
387
- audioListener: ctx.audio.listener,
388
- ...(componentRegistry ? { componentRegistry } : {}),
389
- componentManager: ctx.components,
390
- particleRenderer: ctx.particles.batchedRenderer,
391
- ...(headless ? {} : { renderer }),
392
- });
393
- applySceneRendering(inst);
394
- applySceneNavigation(inst);
395
- ctx.systems.add('postPhysics', (dt) => inst.update(dt));
396
- return inst;
397
- };
398
- if (setup) {
399
- if (headless)
400
- throw new Error('VgaiSceneGameAdapter: setup-based games require a GPU host');
401
- currentCleanup = await setup(ctx, editorPreview);
402
- }
403
- else if (scenePath) {
404
- // #139: captured BEFORE load so adoptSceneCamera can tell whether a
405
- // component (e.g. SceneCamera.init) already framed the camera.
406
- const preLoadPose = captureCameraPose(camera);
407
- const inst = await loadScene(scenePath, {
408
- scene,
409
- rapierWorld: ctx.rapierWorld,
410
- rapier: ctx.rapier,
411
- physics: ctx.physics,
412
- audioListener: ctx.audio.listener,
413
- ...(componentRegistry ? { componentRegistry } : {}),
414
- componentManager: ctx.components,
415
- particleRenderer: ctx.particles.batchedRenderer,
416
- ...(headless ? {} : { renderer }),
417
- });
418
- applyEditorCamera(editorPreview, camera) || adoptSceneCamera(inst, camera, preLoadPose);
419
- applySceneRendering(inst);
420
- applySceneNavigation(inst);
421
- ctx.systems.add('postPhysics', (dt) => inst.update(dt));
422
- // A pre-baked navmesh (sibling .navmesh file — see scene-loader.ts) holds
423
- // live recast-navigation WASM handles that leak unless destroyed
424
- // explicitly; dispose it alongside the scene instance on teardown.
425
- currentCleanup = {
426
- dispose: () => {
427
- inst.navMesh?.dispose(scene);
428
- inst.dispose();
429
- },
430
- };
431
- }
432
- else if (sceneData) {
433
- const preLoadPose = captureCameraPose(camera);
434
- const inst = await loadFromData(sceneData);
435
- applyEditorCamera(editorPreview, camera) || adoptSceneCamera(inst, camera, preLoadPose);
436
- currentCleanup = {
437
- dispose: () => {
438
- inst.navMesh?.dispose(scene);
439
- inst.dispose();
440
- },
441
- };
442
- }
443
- // Idempotency guard for disposeGame — see below. Declared here (not inside
444
- // disposeGame) so hotReload can also refuse to run on an already-disposed
445
- // adapter.
446
- let disposed = false;
447
- // Run one teardown step in isolation: a throwing step (e.g. a
448
- // GameComponent's dispose() misbehaving, or a WASM free() panicking) must
449
- // not abort the remaining steps — otherwise a single bad component leaks
450
- // the Rapier world and skips input.dispose() with no way to retry (a
451
- // second call is a no-op once `disposed` is set). Logs and continues.
452
- const safeStep = (label, fn) => {
453
- try {
454
- fn();
455
- }
456
- catch (err) {
457
- console.error(`VgaiSceneGameAdapter: teardown step "${label}" threw (continuing)`, err);
458
- }
459
- };
460
- const disposeGame = () => {
461
- // A second stop() must be a safe no-op — do NOT double-free the Rapier
462
- // world/EventQueue (WASM handles panic/throw on a second free) or
463
- // double-run teardown side effects.
464
- if (disposed)
465
- return;
466
- disposed = true;
467
- safeStep('batchSystem.teardown', () => {
468
- batchSystem?.teardown(); // re-attach detached sources before scene teardown
469
- batchSystem = null;
470
- });
471
- safeStep('currentCleanup.dispose', () => {
472
- currentCleanup?.dispose();
473
- currentCleanup = null;
474
- });
475
- // The scene instance's NavMeshManager (if any) was just disposed above
476
- // (currentCleanup.dispose calls `inst.navMesh?.dispose(scene)`) — clear
477
- // the wrapper too, or `mounted.systems.navigation` would keep pointing
478
- // at a freed manager (R8 item 7). Unconditional: harmless if navigation
479
- // was never set.
480
- safeStep('clear navigation adapter', () => {
481
- delete systemAdapters.navigation;
482
- });
483
- if (!headless) {
484
- safeStep('removeEventListener(keydown)', () => window.removeEventListener('keydown', onDebugToggle));
485
- }
486
- // Components BEFORE the physics world is freed/bodies are removed: a
487
- // GameComponent's dispose() may read `this.rigidBody`/`this.collider`
488
- // (see game-component.ts) — freeing the world first would make those
489
- // dangling WASM references. Isolated: a throwing component dispose must
490
- // not prevent the world/eventQueue frees or input.dispose() below.
491
- safeStep('components.clear', () => ctx.components.clear());
492
- safeStep('remove rigid bodies', () => {
493
- const handles = [];
494
- physics.rapierWorld.forEachRigidBody((b) => handles.push(b.handle));
495
- for (const h of handles) {
496
- const b = physics.rapierWorld.getRigidBody(h);
497
- if (b)
498
- physics.rapierWorld.removeRigidBody(b);
499
- }
500
- });
501
- safeStep('rapierWorld.free', () => physics.rapierWorld.free());
502
- safeStep('eventQueue.free', () => physics.eventQueue.free()); // WASM handle — must be freed manually
503
- safeStep('physicsRegistry.clear', () => physicsRegistry.clear());
504
- safeStep('scene children dispose', () => {
505
- for (const obj of [...scene.children]) {
506
- scene.remove(obj);
507
- obj.traverse((node) => {
508
- if (node instanceof THREE.Mesh) {
509
- if (!hasUserData(node, '__sharedGeometry'))
510
- node.geometry?.dispose();
511
- if (Array.isArray(node.material))
512
- node.material.forEach((m) => {
513
- m.dispose();
514
- });
515
- else
516
- node.material?.dispose();
517
- }
518
- });
519
- }
520
- scene.fog = null;
521
- scene.background = null;
522
- scene.environment = null;
523
- });
524
- safeStep('clearAssetCaches', () => clearAssetCaches());
525
- safeStep('debugDraw.clear', () => debugDraw.clear());
526
- // R8 item 7 (C) — disposeGame (Stop) used to skip both of these, unlike
527
- // hotReload (warm restart), which already ran them: a game lifecycle
528
- // system registered via `ctx.systems.register(...)` never had its
529
- // `dispose()` hook called on a full Stop, and a game-registered
530
- // systemAdapters kind (e.g. a `setup`-registered 'networking') survived
531
- // a Stop and would be visible on a STALE `mounted.systems` even though
532
- // the game that owned it is gone. Same two steps, same relative
533
- // ordering as hotReload (before the
534
- // engine-owned audio/input teardown below, which hotReload doesn't
535
- // touch at all since it warm-restarts rather than tearing engine
536
- // subsystems down).
537
- safeStep('systems.removeAllNonEngine', () => systems.removeAllNonEngine());
538
- safeStep('strip game-registered systemAdapters', () => {
539
- for (const kind of Object.keys(systemAdapters)) {
540
- if (!engineAdapterKinds.has(kind))
541
- delete systemAdapters[kind];
542
- }
543
- });
544
- // Defect 2 fix: a full Stop means the whole GAME is going away (every
545
- // world it mounted, plus any react-door registrations from its HUDs)
546
- // — unlike hotReload below (a SINGLE mount warm-restarting), so this is
547
- // the one call site that legitimately wants strip()'s global, no-id
548
- // form rather than scoping to `this.id`.
549
- safeStep('debugRegistry.strip', () => debugRegistry.strip());
550
- if (!headless) {
551
- safeStep('audio teardown', () => {
552
- audio.masterGain.gain.value = 0;
553
- audio.listener.context.suspend();
554
- camera.remove(audio.listener);
555
- composer.dispose();
556
- });
557
- }
558
- safeStep('input.dispose', () => input.dispose());
559
- safeStep('gpuTimer.dispose', () => gpuTimer?.dispose());
560
- };
561
- const hotReload = async (newSetup, newEditorPreview) => {
562
- if (disposed) {
563
- throw new Error('VgaiSceneGameAdapter: cannot hotReload after dispose()/stop()');
564
- }
565
- // Full parity with disposeGame for the parts a warm restart rebuilds:
566
- // batch-render teardown, game cleanup, component batch teardown (in that
567
- // ordering, BEFORE bodies are pulled from the world — see disposeGame),
568
- // scene-UI dispose (React root unmount), and bulk system removal. Each
569
- // step isolated the same way as disposeGame — one throwing step (e.g. a
570
- // component dispose) must not abort the rest of the warm restart.
571
- safeStep('batchSystem.teardown', () => {
572
- batchSystem?.teardown(); // re-attach detached sources before scene teardown
573
- batchSystem = null;
574
- });
575
- safeStep('currentCleanup.dispose', () => {
576
- currentCleanup?.dispose();
577
- currentCleanup = null;
578
- });
579
- // Same reasoning as disposeGame: the outgoing scene instance's
580
- // NavMeshManager was just disposed above, and `hotReload`'s `newSetup`
581
- // (below) never auto-wires a replacement (that only happens for THIS
582
- // adapter's own scenePath/sceneData mount, once, at initial mount) — so
583
- // clear the stale wrapper here. A `newSetup` that wants navigation may
584
- // register its own via `ctx.registerSystemAdapter('navigation', ...)`.
585
- safeStep('clear navigation adapter', () => {
586
- delete systemAdapters.navigation;
587
- });
588
- safeStep('components.clear', () => ctx.components.clear());
589
- safeStep('remove rigid bodies', () => {
590
- const handles = [];
591
- physics.rapierWorld.forEachRigidBody((b) => handles.push(b.handle));
592
- for (const h of handles) {
593
- const b = physics.rapierWorld.getRigidBody(h);
594
- if (b)
595
- physics.rapierWorld.removeRigidBody(b);
596
- }
597
- physicsRegistry.clear();
598
- });
599
- safeStep('scene children dispose', () => {
600
- for (const obj of [...scene.children]) {
601
- if (engineSceneChildren.has(obj))
602
- continue;
603
- scene.remove(obj);
604
- obj.traverse((node) => {
605
- if (node instanceof THREE.Mesh) {
606
- if (!hasUserData(node, '__sharedGeometry'))
607
- node.geometry?.dispose();
608
- if (Array.isArray(node.material))
609
- node.material.forEach((m) => {
610
- m.dispose();
611
- });
612
- else
613
- node.material?.dispose();
614
- }
615
- });
616
- }
617
- scene.fog = null;
618
- scene.background = null;
619
- scene.environment = null;
620
- });
621
- safeStep('debugDraw.clear', () => debugDraw.clear());
622
- // Bulk-remove every system the outgoing game registered (this restart's
623
- // predecessor) so warm restarts never accumulate duplicate systems —
624
- // engine systems registered before mount()'s boundary mark are untouched.
625
- safeStep('systems.removeAllNonEngine', () => systems.removeAllNonEngine());
626
- // Strip every GAME-registered systemAdapters kind left by the outgoing
627
- // game (including any override of a first-party kind) so the disposed
628
- // game's networking/etc. adapter is never exposed to the next setup —
629
- // see registerSystemAdapter's docstring in runtime/types.ts. ('navigation'
630
- // is engine-kind and is NOT touched here — it's a first-party adapter now,
631
- // kept in sync with the current scene's NavMeshManager by the dedicated
632
- // `clear navigation adapter` step above instead.) The new setup below
633
- // either re-registers a kind or it stays absent.
634
- safeStep('strip game-registered systemAdapters', () => {
635
- for (const kind of Object.keys(systemAdapters)) {
636
- if (!engineAdapterKinds.has(kind))
637
- delete systemAdapters[kind];
638
- }
639
- });
640
- // Hot-reload re-seed (spec §3.1): the incoming game's setup (below)
641
- // re-registers its providers/commands under the SAME worldId — strip()
642
- // clears the outgoing game's registrations first so that re-seed is
643
- // silent (no stale duplicate-name warning) rather than "replacing" a
644
- // dead game's entries. Defect 2 fix: scoped to THIS mount's worldId
645
- // (`this.id`) — a blind global strip() here wiped every OTHER live
646
- // world's registrations on every warm restart of just this one, plus
647
- // every react-door registration (whose `useEffect` cleanup never
648
- // re-fires to restore them after someone else's strip).
649
- safeStep('debugRegistry.strip', () => debugRegistry.strip(this.id));
650
- currentCleanup = await newSetup(ctx, newEditorPreview);
651
- };
652
- return {
653
- kind: 'threejs',
654
- scene,
655
- camera,
656
- firstParty: true,
657
- drivesOwnLoop: false,
658
- update: (dt) => {
659
- systems.run(dt);
660
- postFrame();
661
- },
662
- resize: (w, h) => {
663
- const safeWidth = Math.max(1, w);
664
- const safeHeight = Math.max(1, h);
665
- composer.setSize(safeWidth, safeHeight);
666
- camera.aspect = safeWidth / safeHeight;
667
- camera.updateProjectionMatrix();
668
- },
669
- dispose: disposeGame,
670
- systems: systemAdapters,
671
- ctx,
672
- composer: headless ? null : composer,
673
- hotReload,
674
- frame: {
675
- runPhase: (phase, dt) => systems.runPhase(phase, dt),
676
- endFrame: postFrame,
677
- },
678
- };
679
- }
680
- }
681
- // --- Camera precedence helpers (moved from create-runtime, unchanged) ---
682
- function applyEditorCamera(editor, runtimeCamera) {
683
- if (!editor?.viewportCamera)
684
- return false;
685
- runtimeCamera.position.fromArray(editor.viewportCamera.position);
686
- runtimeCamera.quaternion.fromArray(editor.viewportCamera.quaternion);
687
- return true;
688
- }
689
- export function captureCameraPose(camera) {
690
- return { position: camera.position.clone(), quaternion: camera.quaternion.clone() };
691
- }
692
- export function adoptSceneCamera(sceneInstance, runtimeCamera, preLoadPose) {
693
- const sceneCam = sceneInstance.cameras[0];
694
- if (!sceneCam)
695
- return false;
696
- // #133 (blind run #4): `camera.type: 'orthographic'` builds a real
697
- // OrthographicCamera in the scene graph (`createCamera`), but the RUNTIME
698
- // renders through a hardcoded PerspectiveCamera — the authored projection
699
- // silently never reached the screen. Until ortho support is ranked
700
- // (implement-vs-reject, owner call on #133), say so loudly instead of
701
- // letting a coplanar game render in unexplained perspective.
702
- if (sceneCam.isOrthographicCamera) {
703
- console.warn("adoptSceneCamera (#133): this scene's camera is ORTHOGRAPHIC, but the runtime camera is " +
704
- 'perspective-only — the orthographic projection is NOT applied (only the pose is). ' +
705
- 'Use type: "perspective" (a long-lens fake: far position + small fov) until #133 lands.');
706
- }
707
- // #139 (blind run #5): if a GameComponent already positioned/oriented the
708
- // runtime camera during scene load (`SceneCamera.init`'s
709
- // `ctx.camera.position.set` + `lookAt` is the blessed shape), the camera
710
- // ENTITY's transform must not stomp it — an unauthored `transform.rotation`
711
- // is identity ("stare down −Z"), which silently blanked an entire correct
712
- // game while every state-based probe spec passed. Components win the pose;
713
- // the entity still contributes the LENS (fov/near/far below), which
714
- // `SceneCamera` never sets.
715
- const componentFramedCamera = preLoadPose !== undefined &&
716
- (!runtimeCamera.position.equals(preLoadPose.position) ||
717
- !runtimeCamera.quaternion.equals(preLoadPose.quaternion));
718
- const parent = sceneCam.parent;
719
- if (parent && !componentFramedCamera) {
720
- parent.updateMatrixWorld(true);
721
- runtimeCamera.position.copy(parent.getWorldPosition(new THREE.Vector3()));
722
- const worldQuat = parent.getWorldQuaternion(new THREE.Quaternion());
723
- runtimeCamera.quaternion.copy(worldQuat);
724
- // Identity orientation on an adopted scene camera is almost never intent
725
- // (it means "look at the horizon down −Z", not "look at my scene") — the
726
- // exact silent-blank-viewport footgun above. Adopt it anyway (authored
727
- // data is truth) but say so loudly, with the two blessed remedies.
728
- if (Math.abs(1 - Math.abs(worldQuat.w)) < 1e-6) {
729
- console.warn('adoptSceneCamera (#139): the scene camera entity has no rotation — the runtime camera ' +
730
- 'will stare horizontally down −Z and may show nothing. Either attach the SceneCamera ' +
731
- 'component (position + lookAt, no quaternion math) or author transform.rotation on ' +
732
- 'the camera entity.');
733
- }
734
- }
735
- if (sceneCam instanceof THREE.PerspectiveCamera) {
736
- runtimeCamera.fov = sceneCam.fov;
737
- runtimeCamera.near = sceneCam.near;
738
- runtimeCamera.far = sceneCam.far;
739
- runtimeCamera.updateProjectionMatrix();
740
- }
741
- return true;
742
- }
743
- /** Headless input stand-in — `InputManager` attaches `window` listeners in its
744
- * constructor, which Node lacks. The scene-data path never reads input. */
745
- function headlessInput() {
746
- return {
747
- poll: () => { },
748
- endFrame: () => { },
749
- dispose: () => { },
750
- loadMap: async () => { },
751
- isPressed: () => false,
752
- getAxis: () => 0,
753
- };
754
- }
755
- /** Headless audio stand-in (no Web Audio). Only the fields the loader/cleanup
756
- * touch are present; setup-based games never mount headlessly. */
757
- function headlessAudio() {
758
- return {
759
- listener: undefined,
760
- masterGain: { gain: { value: 1 } },
761
- };
762
- }