@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,569 @@
1
+ /**
2
+ * Game root — T7.1 slice 1 ("introduce Game internally") + slice 2 ("world
3
+ * registry + ordered frame algorithm"), extended in T7.3 slice 1 with real
4
+ * `'pixijs'`-kind `WorldInstance` support (`stage`/`physics2d`/`collisions2d`,
5
+ * a real `pixiRoot()`) so `world2d/pixi-game-adapter.ts` can register its
6
+ * world onto a real `Game` instead of driving its own loop, and in T7.3
7
+ * slice 2 with a construction-time stage check (symmetric with the
8
+ * threejs/scene check) and the two-world (threejs + pixijs) proof
9
+ * (`test/game-three-plus-pixi.test.ts`). T6.2 slice 1 adds real `'react'`-kind
10
+ * `WorldInstance` support (`container`, a real `reactRoot()`) — the DOM-root
11
+ * world surface `runtime/create-runtime.ts`'s worlds path now mounts (see
12
+ * `docs/REACT-WORLD-DESIGN.md` §1.B); react worlds host no `ComponentManager`
13
+ * (D8 — components attaching to a react-kind manager already throw,
14
+ * `ecs/component-manager.ts`), so `physics`/`collisions`/`camera`/`frame`
15
+ * stay `undefined` for them exactly like an opaque/foreign mount.
16
+ *
17
+ * See `docs/GAME-ROOT-DESIGN.md` (D6), particularly §4 (the frame algorithm)
18
+ * and §8 stage 2, for the full target shape. This file holds the Game/
19
+ * WorldInstance shell, the NEW game-scoped `SystemRunner`, and the
20
+ * host-facing `runFrame` frame executor. The public surface is NOT frozen
21
+ * yet — do not add these exports to a barrel/index; only the in-scope
22
+ * runtime/adapter files import this module directly. The `gpu` per-world
23
+ * cache is the one remaining slice-1 omission.
24
+ */
25
+ import { formatAudioGateMessage, formatLoopGateMessage } from '../adapter/loop-gate-report';
26
+ import { createSystemRunner } from '../core/system-runner';
27
+ import { PHASE_ORDER, SystemPhase } from '../core/types';
28
+ import { createStateBridge } from './state-bridge';
29
+ /**
30
+ * Build a `WorldInstance` whose kind-narrowed accessors throw descriptively
31
+ * on kind mismatch (GAME-ROOT-DESIGN §3). This is the one place that builds
32
+ * `threeRoot`/`pixiRoot`, so every world (however it's constructed, in this
33
+ * slice or later ones) gets identical throw behavior.
34
+ */
35
+ export function createWorldInstance(init) {
36
+ const { id, kind, pausable = true, adapter, mounted, scene, stage, container, physics, collisions, physics2d, collisions2d, camera, frame, } = init;
37
+ // A threejs world with no scene has nothing for `threeRoot()` to return —
38
+ // fail loudly HERE, at construction, rather than letting `threeRoot()`
39
+ // throw its generic "not a threejs world" message later for a world whose
40
+ // kind IS threejs (checklist item 5; a misleading error for this case).
41
+ if (kind === 'threejs' && !scene) {
42
+ throw new Error(`WorldInstance "${id}" (kind: threejs): a threejs world requires a scene — ` +
43
+ 'pass `scene` in WorldInstanceInit.');
44
+ }
45
+ // Symmetric check for pixijs (T7.3 slice 2) — a pixijs world with no stage
46
+ // has nothing for `pixiRoot()` to return; fail loudly here, at
47
+ // construction, same as the threejs/scene check above.
48
+ if (kind === 'pixijs' && !stage) {
49
+ throw new Error(`WorldInstance "${id}" (kind: pixijs): a pixijs world requires a stage — ` +
50
+ 'pass `stage` in WorldInstanceInit.');
51
+ }
52
+ // Symmetric check for react (T6.2 slice 1, docs/REACT-WORLD-DESIGN.md
53
+ // §1.B) — a react world with no container has nothing for `reactRoot()`
54
+ // to return; fail loudly here, at construction, same as the two checks
55
+ // above.
56
+ if (kind === 'react' && !container) {
57
+ throw new Error(`WorldInstance "${id}" (kind: react): a react world requires a container — ` +
58
+ 'pass `container` in WorldInstanceInit.');
59
+ }
60
+ // Disposed-world guard (GAME-ROOT-DESIGN §8 stage 3 / T7.1 slice 3). There
61
+ // is no `unregisterWorld` (decision 4 — worlds are manifest-declared; a
62
+ // whole Game is disposed, not one world out of its registry), so a caller
63
+ // that disposes ONE world's `mounted` directly (e.g. ending a sub-session)
64
+ // leaves that `WorldInstance` sitting in `Game.worlds` — and `runFrame`
65
+ // would otherwise keep invoking its (now-torn-down) frame hooks every
66
+ // subsequent frame. `MountedGame` has no public "am I disposed" flag to
67
+ // read, so this wraps `mounted.dispose` in place (mutating the SAME mount
68
+ // object every holder of `mounted` shares — calling `mounted.dispose()`
69
+ // directly, exactly like calling `world.mounted.dispose()`, trips this)
70
+ // to flip a private flag, and wraps the frame hooks so they silently no-op
71
+ // once that flag is set. `runFrame` itself needs no knowledge of disposal
72
+ // — a disposed world is skipped by construction from the next call
73
+ // onward. (The opaque-world `mounted.update` fallback path is unaffected
74
+ // by this guard — no opaque-mount two-world scenario exists yet to need it.)
75
+ let disposed = false;
76
+ const originalDispose = mounted.dispose.bind(mounted);
77
+ mounted.dispose = () => {
78
+ disposed = true;
79
+ originalDispose();
80
+ };
81
+ const guardedFrame = frame
82
+ ? {
83
+ runPhase(phase, dt) {
84
+ if (disposed)
85
+ return;
86
+ frame.runPhase(phase, dt);
87
+ },
88
+ endFrame() {
89
+ if (disposed)
90
+ return;
91
+ frame.endFrame?.();
92
+ },
93
+ }
94
+ : undefined;
95
+ return {
96
+ id,
97
+ kind,
98
+ pausable,
99
+ adapter,
100
+ mounted,
101
+ physics,
102
+ collisions,
103
+ physics2d,
104
+ collisions2d,
105
+ camera,
106
+ frame: guardedFrame,
107
+ threeRoot() {
108
+ if (kind !== 'threejs' || !scene) {
109
+ throw new Error(`WorldInstance "${id}" (kind: ${kind}): threeRoot() requested but this world is not ` +
110
+ 'a threejs world');
111
+ }
112
+ return scene;
113
+ },
114
+ pixiRoot() {
115
+ // The `!stage` branch a pixijs world could hit here is now unreachable
116
+ // (T7.3 slice 2): construction above throws for `kind === 'pixijs'`
117
+ // with no `stage`, symmetric with `threeRoot()`'s `scene` guard.
118
+ if (kind !== 'pixijs' || !stage) {
119
+ throw new Error(`WorldInstance "${id}" (kind: ${kind}): pixiRoot() requested but this world is not ` +
120
+ 'a pixijs world');
121
+ }
122
+ return stage;
123
+ },
124
+ reactRoot() {
125
+ // The `!container` branch a react world could hit here is now
126
+ // unreachable (T6.2 slice 1): construction above throws for
127
+ // `kind === 'react'` with no `container`, symmetric with
128
+ // `threeRoot()`/`pixiRoot()`'s guards.
129
+ if (kind !== 'react' || !container) {
130
+ throw new Error(`WorldInstance "${id}" (kind: ${kind}): reactRoot() requested but this world is not ` +
131
+ 'a react world');
132
+ }
133
+ return container;
134
+ },
135
+ };
136
+ }
137
+ /**
138
+ * Type guard for whether a `MountedGame` is a first-party
139
+ * `VgaiSceneGameAdapter` mount (has a live `GameContext` at `.ctx`). Used to
140
+ * decide whether a world's `physics`/`collisions`/`camera` (and, on `Game`,
141
+ * `components`/`input`/`audio`) can be populated from it — an external
142
+ * adapter's mount has none of these first-party handles.
143
+ *
144
+ * Checks the `firstParty: true` brand (checklist item 1), NOT `'ctx' in
145
+ * mounted` — world2d's `MountedGame2D` (`world2d/pixi-game-adapter.ts`) also
146
+ * has a `ctx` key (a `World2DContext`, unrelated to `GameContext`), so a
147
+ * structural `'ctx' in mounted` check would misfire once T7.3 registers 2D
148
+ * worlds onto the same `Game`. The probe is a plain property read, not an
149
+ * `instanceof`/value import of `vgai-scene-game-adapter.ts` — the
150
+ * `VgaiMountedGame` import above stays type-only.
151
+ */
152
+ export function isFirstPartyMounted(mounted) {
153
+ return mounted.firstParty === true;
154
+ }
155
+ function describeMismatch(handle, world) {
156
+ return (`Game.${handle}: default world "${world.id}" (kind: ${world.kind}) is not a first-party ` +
157
+ "mount — hoisting these to true Game ownership is a later slice's work; available only " +
158
+ 'via a first-party default world today');
159
+ }
160
+ /**
161
+ * Construct the (host-internal) Game shell. Callers: `createGameRuntime`
162
+ * builds this BEFORE mounting its one adapter, then registers the default
163
+ * threejs world once mount resolves (see `registerDefaultThreeWorld` in
164
+ * `create-runtime.ts`).
165
+ */
166
+ export function createGame(opts) {
167
+ const worlds = [];
168
+ const systems = createSystemRunner();
169
+ const stateBridge = createStateBridge();
170
+ function requireDefaultWorld() {
171
+ if (worlds.length === 0) {
172
+ throw new Error('Game.defaultWorld: no worlds registered yet');
173
+ }
174
+ return worlds.find((w) => w.kind === 'threejs') ?? worlds[0];
175
+ }
176
+ function requireFirstPartyCtx(handle) {
177
+ const world = requireDefaultWorld();
178
+ if (!isFirstPartyMounted(world.mounted)) {
179
+ throw new Error(describeMismatch(handle, world));
180
+ }
181
+ return world.mounted.ctx;
182
+ }
183
+ // --- Game.systemAdapters aggregation (§7.1-3, probe1) --------------------
184
+ // Warn-once-per-colliding-key state, scoped to this Game instance (a fresh
185
+ // Game gets a fresh warn history) — deliberately NOT reset by anything
186
+ // short of a new `createGame` call, matching `reportedGateShortfalls`
187
+ // above's "once per game instance" idiom.
188
+ const warnedSystemAdapterKeys = new Set();
189
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one cohesive merge-with-collision-report walk (per-world × per-key); splitting the collision-warn branch out would obscure that it's part of the same pass, not reduce real complexity
190
+ function computeSystemAdapters() {
191
+ const result = {};
192
+ const ownerWorldId = new Map();
193
+ for (const world of worlds) {
194
+ const adapters = world.mounted.systems;
195
+ if (!adapters)
196
+ continue;
197
+ for (const key of Object.keys(adapters)) {
198
+ if (adapters[key] === undefined)
199
+ continue;
200
+ const existingOwner = ownerWorldId.get(key);
201
+ if (existingOwner !== undefined) {
202
+ if (!warnedSystemAdapterKeys.has(key)) {
203
+ warnedSystemAdapterKeys.add(key);
204
+ // biome-ignore lint/suspicious/noConsole: structured, greppable — mirrors this file's own reportGateShortfallOnce's deliberate direct console.warn just above
205
+ console.warn(`[game] systemAdapters: "${key}" is registered by both world "${existingOwner}" and ` +
206
+ `world "${world.id}" — the FIRST registration ("${existingOwner}") wins; the later ` +
207
+ 'one is shadowed (docs/GAME-ROOT-DESIGN.md §3: game-scoped system adapters).');
208
+ }
209
+ continue;
210
+ }
211
+ // biome-ignore lint/suspicious/noExplicitAny: SystemAdapters is a plain optional-field record; the per-key copy is correct by construction (same key on both sides), just not expressible without a cast
212
+ result[key] = adapters[key];
213
+ ownerWorldId.set(key, world.id);
214
+ }
215
+ }
216
+ return result;
217
+ }
218
+ // --- D10/T7.6 play-state (Game.play) -------------------------------------
219
+ let paused = false;
220
+ // Dedupe loop-gate/audio-gate shortfall warnings to ONCE per (world, kind)
221
+ // — `pause()` fans out over every world every call; without this a
222
+ // multi-second play session would re-log the same "can't gate" shortfall
223
+ // every time the user hits Pause.
224
+ const reportedGateShortfalls = new Set();
225
+ function reportGateShortfallOnce(kind, worldId, reason) {
226
+ const key = `${kind}:${worldId}`;
227
+ if (reportedGateShortfalls.has(key))
228
+ return;
229
+ reportedGateShortfalls.add(key);
230
+ const message = kind === 'loop'
231
+ ? formatLoopGateMessage({ worldId, reason })
232
+ : formatAudioGateMessage({ worldId, reason });
233
+ // Other native `console.warn`/`console.error` call sites in this file are
234
+ // unsuppressed and already counted in the lint baseline (see `runFrame`'s
235
+ // impl below); this one is a NEW site, so it's suppressed to keep this
236
+ // task's diff at zero NEW warnings (same reasoning as `overlay-report.ts`'s
237
+ // identical suppression).
238
+ // biome-ignore lint/suspicious/noConsole: see comment above
239
+ console.warn(message);
240
+ }
241
+ /** Fan out a loop-gate (self-driven worlds) + audio-gate call over every
242
+ * `pausable` world, reporting honestly (once) wherever the capability is
243
+ * absent — shared by `pause()`/`resume()` below (same fan-out, opposite
244
+ * boolean). */
245
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: fans out TWO independent capability gates (loop, audio) with the same "call it, else report once" shape per world — splitting the two gates into separate loops would duplicate the fan-out, not reduce real complexity
246
+ function setWorldGates(next) {
247
+ for (const world of worlds) {
248
+ if (!world.pausable)
249
+ continue; // pausable:false worlds are untouched by design
250
+ if (world.mounted.drivesOwnLoop) {
251
+ if (world.mounted.setPaused) {
252
+ world.mounted.setPaused(next);
253
+ }
254
+ else if (next) {
255
+ reportGateShortfallOnce('loop', world.id, 'self-driven world, adapter declares no setPaused capability');
256
+ }
257
+ }
258
+ const audio = world.mounted.systems?.audio;
259
+ if (audio) {
260
+ audio.setMuted(next);
261
+ }
262
+ else if (next) {
263
+ reportGateShortfallOnce('audio', world.id, 'no SystemAdapters.audio on this world');
264
+ }
265
+ }
266
+ }
267
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: the frame algorithm (GAME-ROOT-DESIGN §4, now with D10's per-world pause gate + the onlyFrozen step()-only mode) is one cohesive nested loop over phases/worlds — splitting it would obscure the ordering contract documented on GameInternal.runFrame
268
+ function runFrameImpl(dt, frameOpts) {
269
+ const ignorePause = frameOpts?.ignorePause ?? false;
270
+ // `onlyFrozen` is internal-only (not part of the public `GameInternal.runFrame`
271
+ // signature — no external caller sets it) — `Game.play.step()` below is the
272
+ // one and only caller. It ticks EXACTLY the currently-frozen set (host-driven,
273
+ // `pausable`, and `paused`) through every phase + `endFrame`, with the REAL
274
+ // `dt` (not the render-phase's forced `0`), and touches no other world at all
275
+ // — §7.1-2 fix, probe4: the previous `ignorePause` full-frame re-run ticked
276
+ // EVERY host-driven world, double-ticking every already-running
277
+ // `pausable: false` world (D10's ordinary loop never stops ticking them).
278
+ const onlyFrozen = frameOpts?.onlyFrozen ?? false;
279
+ // Checklist item 7: snapshot the world count ONCE at entry and iterate
280
+ // by index in both loops below. A world registered mid-frame (e.g. from
281
+ // a game-scoped system's side effect) joins at the NEXT `runFrame` call,
282
+ // not this one — `for (const world of worlds)` would otherwise pick up
283
+ // a world pushed during this very frame. This also drops the two
284
+ // per-phase `for...of` iterator allocations.
285
+ const n = worlds.length;
286
+ // §7.1-11 fix (probe5): `stateBridge.bump()` must fire iff at least one
287
+ // world actually advanced this call — not unconditionally. `advanced`
288
+ // covers rule (a) below (host-driven worlds this call actually ticked);
289
+ // rule (b): a self-driven world that is RUNNING — which is every
290
+ // self-driven world while not paused, and, while paused, the ones the
291
+ // gate can't reach (`pausable: false`, or no `setPaused` capability) —
292
+ // checked once, up front, over the same `worlds` array (no extra
293
+ // allocation, matching every other loop here). Rule (b) is skipped in
294
+ // `onlyFrozen` mode: a `step()` call bumps iff it ticked a frozen world
295
+ // — self-driven notifications belong to the loop's own `runFrame`s.
296
+ let advanced = false;
297
+ if (!onlyFrozen) {
298
+ for (let i = 0; i < n; i++) {
299
+ const world = worlds[i];
300
+ if (!world.mounted.drivesOwnLoop)
301
+ continue;
302
+ if (!paused || !world.pausable || !world.mounted.setPaused) {
303
+ advanced = true;
304
+ break;
305
+ }
306
+ }
307
+ }
308
+ if (onlyFrozen) {
309
+ // step(): the frozen set is host-driven + pausable + currently paused.
310
+ // While NOT paused this set is empty by construction, so this whole
311
+ // branch is a natural no-op — `Game.play.step()`'s "no-op while
312
+ // running" behavior falls straight out of this, no separate guard
313
+ // needed.
314
+ for (const phase of PHASE_ORDER) {
315
+ for (let i = 0; i < n; i++) {
316
+ const world = worlds[i];
317
+ if (world.mounted.drivesOwnLoop)
318
+ continue;
319
+ if (!(paused && world.pausable))
320
+ continue; // only the frozen set
321
+ try {
322
+ world.frame?.runPhase(phase, dt);
323
+ }
324
+ catch (err) {
325
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) runPhase("${phase}") threw ` +
326
+ '(step()):', err);
327
+ }
328
+ }
329
+ }
330
+ for (let i = 0; i < n; i++) {
331
+ const world = worlds[i];
332
+ if (world.mounted.drivesOwnLoop)
333
+ continue;
334
+ if (!(paused && world.pausable))
335
+ continue;
336
+ advanced = true;
337
+ if (world.frame) {
338
+ try {
339
+ world.frame.endFrame?.();
340
+ }
341
+ catch (err) {
342
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) endFrame() threw (step()):`, err);
343
+ }
344
+ }
345
+ else {
346
+ try {
347
+ world.mounted.update?.(dt);
348
+ }
349
+ catch (err) {
350
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) update() threw (step()):`, err);
351
+ }
352
+ }
353
+ }
354
+ }
355
+ else {
356
+ for (const phase of PHASE_ORDER) {
357
+ systems.runPhase(phase, dt);
358
+ for (let i = 0; i < n; i++) {
359
+ const world = worlds[i];
360
+ if (world.mounted.drivesOwnLoop)
361
+ continue;
362
+ // D10/T7.6: a `pausable` world under an active (non-ignored) pause
363
+ // skips every phase except `render` — its render still runs, every
364
+ // substep, but with `dt` forced to `0` (deterministic: no
365
+ // time-based render effect silently keeps animating a "frozen"
366
+ // scene). A `pausable: false` world (or any world while
367
+ // `ignorePause`) is unaffected.
368
+ const frozen = !ignorePause && paused && world.pausable;
369
+ if (frozen && phase !== SystemPhase.RENDER)
370
+ continue;
371
+ const phaseDt = frozen ? 0 : dt;
372
+ // Checklist item 2: isolate each world's per-phase work — one
373
+ // world's `runPhase` throwing must not starve sibling worlds still
374
+ // due this phase, nor abort the frame. Mirrors `runOne`'s style in
375
+ // `core/system-runner.ts` (loud console.error, never swallowed).
376
+ try {
377
+ world.frame?.runPhase(phase, phaseDt);
378
+ }
379
+ catch (err) {
380
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) runPhase("${phase}") threw:`, err);
381
+ }
382
+ }
383
+ }
384
+ for (let i = 0; i < n; i++) {
385
+ const world = worlds[i];
386
+ if (world.mounted.drivesOwnLoop)
387
+ continue;
388
+ // A fully-frozen world gets no `endFrame`/opaque-`update` call either —
389
+ // there is nothing to "end the frame" of when nothing ran this substep.
390
+ const frozen = !ignorePause && paused && world.pausable;
391
+ if (frozen)
392
+ continue;
393
+ advanced = true;
394
+ if (world.frame) {
395
+ try {
396
+ world.frame.endFrame?.();
397
+ }
398
+ catch (err) {
399
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) endFrame() threw:`, err);
400
+ }
401
+ }
402
+ else {
403
+ // Checklist item 2: same isolation for the opaque-world fallback —
404
+ // one foreign mount's `update` throwing must not starve its
405
+ // siblings' `endFrame`/`update` calls this same loop.
406
+ try {
407
+ world.mounted.update?.(dt);
408
+ }
409
+ catch (err) {
410
+ console.error(`[game] world "${world.id}" (kind: ${world.kind}) update() threw:`, err);
411
+ }
412
+ }
413
+ }
414
+ }
415
+ // T7.4 slice 1 (REACT-STATE-BRIDGE.md §2): bump + notify LAST, after
416
+ // every phase of every world and every world's endFrame/update above —
417
+ // subscribers must only ever observe post-frame state. Bumped at most
418
+ // once per completed `runFrame`/`step()` call, never per phase/world —
419
+ // and, per §7.1-11's fix, only when `advanced` (see above) is true: a
420
+ // fully-gated paused game produces no notifications at all.
421
+ if (advanced)
422
+ stateBridge.bump();
423
+ }
424
+ return {
425
+ loop: opts.loop,
426
+ assets: opts.assets,
427
+ systems,
428
+ get worlds() {
429
+ return worlds;
430
+ },
431
+ world(id) {
432
+ return worlds.find((w) => w.id === id) ?? null;
433
+ },
434
+ get defaultWorld() {
435
+ return requireDefaultWorld();
436
+ },
437
+ get systemAdapters() {
438
+ return computeSystemAdapters();
439
+ },
440
+ get components() {
441
+ return requireFirstPartyCtx('components').components;
442
+ },
443
+ get input() {
444
+ return requireFirstPartyCtx('input').input;
445
+ },
446
+ get audio() {
447
+ return requireFirstPartyCtx('audio').audio;
448
+ },
449
+ state: stateBridge,
450
+ play: {
451
+ get paused() {
452
+ return paused;
453
+ },
454
+ pause() {
455
+ if (paused)
456
+ return;
457
+ paused = true;
458
+ setWorldGates(true);
459
+ },
460
+ resume() {
461
+ if (!paused)
462
+ return;
463
+ paused = false;
464
+ setWorldGates(false);
465
+ },
466
+ step(dt = 1 / 60) {
467
+ // Self-driven pausable worlds advance via their adapter's `step()`
468
+ // capability — but only the ones that are actually FROZEN: the game
469
+ // must be paused, and the world must have been gate-able in the
470
+ // first place (`setPaused` present — a world the gate couldn't reach
471
+ // never stopped, so "stepping" it would double-tick a still-running
472
+ // loop, the same §7.1-2 class as the host-driven fix below). While
473
+ // not paused, nothing here runs — step() is a whole-call no-op.
474
+ if (paused) {
475
+ for (const world of worlds) {
476
+ if (!world.pausable || !world.mounted.drivesOwnLoop)
477
+ continue;
478
+ if (!world.mounted.setPaused)
479
+ continue; // never gated — still running
480
+ if (world.mounted.step) {
481
+ world.mounted.step();
482
+ }
483
+ else {
484
+ reportGateShortfallOnce('loop', world.id, 'self-driven world, adapter declares no step capability');
485
+ }
486
+ }
487
+ }
488
+ // §7.1-2 fix (probe4): tick EXACTLY the frozen (host-driven, pausable,
489
+ // paused) set — not `{ ignorePause: true }`, which re-ran a FULL
490
+ // extra frame for every host-driven world (including already-running
491
+ // `pausable: false` ones — a double-tick, since D10's ordinary loop
492
+ // never stops ticking them). See `runFrameImpl`'s `onlyFrozen` mode.
493
+ runFrameImpl(dt, { onlyFrozen: true });
494
+ },
495
+ },
496
+ queryByComponent(cls, opts) {
497
+ // Checklist item 8a: a `worldId` naming a world that doesn't exist is a
498
+ // caller error (typo'd id, wrong manifest) — degrade loudly, matching
499
+ // repo habit, rather than silently returning `[]`. A worldId that DOES
500
+ // exist but isn't first-party legitimately answers "no components"
501
+ // below (the loop's `!isFirstPartyMounted` `continue`), which stays
502
+ // silent — that's a real, not a mistaken, empty result.
503
+ if (opts?.worldId !== undefined && !worlds.some((w) => w.id === opts.worldId)) {
504
+ throw new Error(`Game.queryByComponent: unknown worldId "${opts.worldId}"`);
505
+ }
506
+ const result = [];
507
+ for (const world of worlds) {
508
+ if (!isFirstPartyMounted(world.mounted))
509
+ continue;
510
+ if (opts?.worldId !== undefined && world.id !== opts.worldId)
511
+ continue;
512
+ if (opts?.kind !== undefined && world.kind !== opts.kind)
513
+ continue;
514
+ // Checklist item 8b: a plain for-loop push instead of
515
+ // `result.push(...arr)` — spread-as-arguments can hit engine/runtime
516
+ // argument-count limits once a world's instance count gets large.
517
+ const instances = world.mounted.ctx.components.queryByComponent(cls);
518
+ for (const inst of instances)
519
+ result.push(inst);
520
+ }
521
+ return result;
522
+ },
523
+ registerWorld(world) {
524
+ if (worlds.some((w) => w.id === world.id)) {
525
+ throw new Error(`Game.registerWorld: duplicate world id "${world.id}"`);
526
+ }
527
+ // Checklist item 6: the SAME `mounted` object registered under two
528
+ // world ids would be double-ticked by `runFrame` (its `frame.runPhase`/
529
+ // `endFrame` called once per registration) and double-dispose-wrapped
530
+ // (`createWorldInstance` wraps `mounted.dispose` in place — a second
531
+ // wrap would flip `disposed` and call through on ITS OWN wrapped
532
+ // `originalDispose`, which is harmless today only by accident of
533
+ // `VgaiSceneGameAdapter.dispose` being idempotent; a foreign adapter
534
+ // has no such guarantee). Reject it outright instead.
535
+ if (worlds.some((w) => w.mounted === world.mounted)) {
536
+ throw new Error(`Game.registerWorld: world "${world.id}" shares its \`mounted\` object with an ` +
537
+ `already-registered world ("${worlds.find((w) => w.mounted === world.mounted).id}") — ` +
538
+ 'the same mount cannot be registered twice.');
539
+ }
540
+ worlds.push(world);
541
+ // T7.4 slice 2 (REACT-STATE-BRIDGE.md §4): a NON-first-party mount
542
+ // (an ingested/foreign world — first-party mounts are exempt, they're
543
+ // observed via `Game.state`/`useGameState` instead) with no `observe`
544
+ // has no state bridge at all — react HUDs cannot subscribe to it, and
545
+ // silently returning `undefined` forever would hide that. Report ONCE
546
+ // per mount, at registration time, matching this file's existing
547
+ // `[game] world "<id>" (kind: <kind>) ...` console idiom (see
548
+ // `runFrame` below).
549
+ //
550
+ // §7.1-15: a `kind: 'react'` world is ALSO exempt — it has no `observe`
551
+ // BY DESIGN (D8/REACT-WORLD-DESIGN.md: a react world's own mounted tree
552
+ // reads state via `Game.state`/`useGameState`, the SAME first-party
553
+ // bridge a threejs/pixijs world's HUD uses, never `WorldStateObserver`
554
+ // — that hook is scoped to the ingested/foreign-world case). Without
555
+ // this exemption every production react world logged a false-positive
556
+ // "no state bridge" warning at registration (probe: every real react
557
+ // world mount), eroding the signal for a genuinely un-observable
558
+ // ingested world.
559
+ if (!isFirstPartyMounted(world.mounted) && world.kind !== 'react' && !world.mounted.observe) {
560
+ console.warn(`[game] world "${world.id}" (kind: ${world.kind}, adapter: "${world.adapter.id}"): ` +
561
+ 'no state bridge — this mounted game has no `observe` (WorldStateObserver); ' +
562
+ 'react HUDs/useWorldObservation cannot subscribe to its state (docs/REACT-STATE-BRIDGE.md §4).');
563
+ }
564
+ },
565
+ runFrame(dt, frameOpts) {
566
+ runFrameImpl(dt, frameOpts);
567
+ },
568
+ };
569
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The delegating input router (COMPOSITION-DESIGN.md D5 §2a) —
3
+ * `createGameRuntime`'s worlds path (T6.1 slice 1,
4
+ * docs/MULTI-WORLD-DESIGN.md §1.C) uses this to route pointer input across
5
+ * N stacked world canvases with exactly ONE root listener.
6
+ *
7
+ * Split into two layers so the decision logic is unit-testable with plain
8
+ * fake worlds — no real DOM/canvas needed:
9
+ *
10
+ * - `stackOrder` / `resolveClaimingWorld`: pure functions over
11
+ * `{id, zOrder, hitTest?}` — "who claims this point".
12
+ * - `applyPointerEventsStacking` / `createInputRouter`: the DOM wiring —
13
+ * sets `pointer-events` CSS per D5 §2a and forwards a claimed event to
14
+ * the claiming world's own canvas.
15
+ *
16
+ * Per-event fall-through (D5 §2b — the sanctioned mechanism for an
17
+ * authoring surface's own interior drag affordances, e.g. the world2d
18
+ * editor's gizmos) is explicitly NOT this file's job (MULTI-WORLD-DESIGN.md
19
+ * task 4) — it stays inside whatever authoring surface needs it.
20
+ */
21
+ /** The pure decision inputs — no DOM. */
22
+ export interface ClaimEntry {
23
+ readonly id: string;
24
+ readonly zOrder: number;
25
+ /**
26
+ * Optional claim predicate over a point RELATIVE TO THE CONTAINER. Absent
27
+ * means: "this world claims only if it is the bottom (lowest zOrder)
28
+ * world" — D5 §2a's stated default ("transparent upper worlds do not
29
+ * claim, the bottom world claims everything").
30
+ */
31
+ readonly hitTest?: ((x: number, y: number) => boolean) | undefined;
32
+ }
33
+ /** The DOM-wiring inputs — one real canvas per world. */
34
+ export interface RouterWorldEntry extends ClaimEntry {
35
+ readonly canvas: HTMLCanvasElement;
36
+ }
37
+ /**
38
+ * Bottom-to-top paint order: ascending `zOrder`, ties -> original array
39
+ * order — the SAME rule `manifest/load.ts`'s `loadGameManifest` sorts
40
+ * worlds by, so a world's DOM stacking position always matches its
41
+ * manifest-resolved zOrder. The last element is the topmost (visually on
42
+ * top / highest z-index).
43
+ */
44
+ export declare function stackOrder<T extends ClaimEntry>(entries: readonly T[]): T[];
45
+ /**
46
+ * Resolve which world's id claims a container-relative point `(x, y)` — D5
47
+ * §2a: walk top-down (topmost first); the first world whose `hitTest`
48
+ * returns true wins ("topmost-claim wins"). A world with no `hitTest` never
49
+ * claims UNLESS it is the bottom-most world, which claims unconditionally
50
+ * (or via its own `hitTest`, if it declares one) — "no-claim falls to
51
+ * bottom". Returns `null` only when `entries` is empty.
52
+ */
53
+ export declare function resolveClaimingWorld(entries: readonly ClaimEntry[], x: number, y: number): string | null;
54
+ /**
55
+ * Sets `canvas.style.pointerEvents` per D5 §1/§2a: the bottom (lowest
56
+ * zOrder) world's canvas is `'auto'` (real user input DOM-hit-tests it by
57
+ * default); every canvas above it is `'none'` (real user input never
58
+ * DOM-hit-tests it — the router's JS-level `hitTest` is what still lets it
59
+ * claim a point via `createInputRouter`'s forwarding).
60
+ */
61
+ export declare function applyPointerEventsStacking(entries: readonly RouterWorldEntry[]): void;
62
+ export interface InputRouterHandle {
63
+ /** Resolve which world claims a container-relative point right now — the
64
+ * pure decision, exposed for callers/tests that don't want to simulate a
65
+ * real DOM event. */
66
+ resolveClaim(x: number, y: number): string | null;
67
+ /** Detach the container listener(s). Idempotent. */
68
+ dispose(): void;
69
+ }
70
+ /**
71
+ * Wire the delegating router onto `container` for `entries` (D5 §2a): apply
72
+ * the pointer-events stacking, then attach ONE capture-phase listener per
73
+ * routed event type that resolves the claiming world and forwards the event
74
+ * to ITS canvas when that world isn't already the natural DOM target (the
75
+ * bottom world, whose canvas is the only one with `pointer-events:auto`).
76
+ */
77
+ export declare function createInputRouter(container: HTMLElement, entries: readonly RouterWorldEntry[]): InputRouterHandle;
78
+ //# sourceMappingURL=input-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-router.d.ts","sourceRoot":"","sources":["../../src/runtime/input-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CACpE;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAK3E;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM,GAAG,IAAI,CAWf;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAKrF;AAyED,MAAM,WAAW,iBAAiB;IAChC;;0BAEsB;IACtB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClD,oDAAoD;IACpD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,iBAAiB,CA8BnB"}