@vgai/engine 0.3.0 → 0.4.0-canary.20260715.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 (559) hide show
  1. package/package.json +8 -2
  2. package/schemas/engine-api.json +124 -0
  3. package/schemas/engine-api.md +53 -0
  4. package/schemas/engine-capabilities.json +124 -0
  5. package/schemas/inputmap.schema.json +314 -0
  6. package/schemas/mat.schema.json +286 -0
  7. package/schemas/prefab.schema.json +10148 -0
  8. package/schemas/scn2d.schema.json +475 -0
  9. package/schemas/vgai-game.schema.json +383 -0
  10. package/schemas/vscn.schema.json +11007 -0
  11. package/src/adapter/{world-kind.ts → adapter-surface.ts} +6 -6
  12. package/src/adapter/authoring.ts +67 -0
  13. package/src/adapter/game-adapter.ts +8 -8
  14. package/src/adapter/host-context.ts +2 -4
  15. package/src/adapter/index.ts +3 -1
  16. package/src/adapter/system-adapter.ts +73 -0
  17. package/src/adapter/vgai-scene-game-adapter.ts +239 -180
  18. package/src/animation/xstate-animation-binding.ts +300 -262
  19. package/src/animation/xstate-animation-meta.ts +50 -13
  20. package/src/character/cloth-sim.ts +533 -0
  21. package/src/character/spring-chain.ts +307 -0
  22. package/src/core/game-loop.ts +41 -3
  23. package/src/core/seeded-random.ts +161 -0
  24. package/src/core/system-runner.ts +20 -3
  25. package/src/core/types.ts +37 -0
  26. package/src/data/data-asset.ts +1 -1
  27. package/src/dev/performance-profiler.ts +213 -0
  28. package/src/dev/webgl-gpu-timer.ts +53 -0
  29. package/src/ecs/component-manager.ts +45 -12
  30. package/src/ecs/game-component.ts +95 -11
  31. package/src/humanoid/bake.operation.ts +326 -0
  32. package/src/humanoid/body.ts +663 -0
  33. package/src/humanoid/clips.ts +149 -0
  34. package/src/humanoid/compose.ts +209 -0
  35. package/src/humanoid/generate.ts +189 -0
  36. package/src/humanoid/index.ts +36 -0
  37. package/src/humanoid/schema.ts +108 -0
  38. package/src/humanoid/skeleton.ts +345 -0
  39. package/src/index.ts +5 -5
  40. package/src/input/input-manager.ts +701 -22
  41. package/src/input/input-types.ts +5 -2
  42. package/src/manifest/index.ts +5 -5
  43. package/src/manifest/load.ts +125 -72
  44. package/src/manifest/schema.ts +362 -255
  45. package/src/react/game-state.tsx +135 -32
  46. package/src/react/root-adapter.tsx +49 -0
  47. package/src/react/unmanaged-root-detector.ts +66 -0
  48. package/src/react/use-data.ts +12 -2
  49. package/src/runtime/create-runtime.ts +100 -282
  50. package/src/runtime/debug-bridge.ts +483 -0
  51. package/src/runtime/debug-registry.ts +856 -0
  52. package/src/runtime/game.ts +342 -93
  53. package/src/runtime/gameplay-rng-trap.ts +134 -0
  54. package/src/runtime/input-router.ts +7 -7
  55. package/src/runtime/mount-game.ts +40 -38
  56. package/src/runtime/mount-manifest.ts +169 -37
  57. package/src/runtime/render-control.ts +13 -13
  58. package/src/runtime/render-seed.ts +1 -1
  59. package/src/runtime/state-bridge.ts +24 -10
  60. package/src/runtime/types.ts +110 -28
  61. package/src/scene/asset-registry.ts +22 -0
  62. package/src/scene/component-registry.ts +14 -3
  63. package/src/scene/defaults.ts +1 -0
  64. package/src/scene/light-camera-factory.ts +11 -3
  65. package/src/scene/scene-apply.ts +55 -4
  66. package/src/scene/scene-loader.ts +10 -27
  67. package/src/scene/scene-types.ts +0 -1
  68. package/src/scene/schema/index.ts +0 -34
  69. package/src/scene/schema/light.ts +16 -1
  70. package/src/scene/schema/material.ts +96 -91
  71. package/src/scene/schema/scene-file.ts +1 -7
  72. package/src/scene/user-data.ts +14 -1
  73. package/src/setup/setup-renderer.ts +1 -1
  74. package/src/tools/define-tool.ts +50 -11
  75. package/src/world2d/authoring-2d.ts +17 -1
  76. package/src/world2d/collision-2d.ts +1 -1
  77. package/src/world2d/pixi-game-adapter.ts +19 -17
  78. package/src/world2d/scene2d-loader.ts +1 -0
  79. package/src/world2d/types.ts +8 -2
  80. package/dist/adapter/authoring.d.ts +0 -404
  81. package/dist/adapter/authoring.d.ts.map +0 -1
  82. package/dist/adapter/authoring.js +0 -22
  83. package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
  84. package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
  85. package/dist/adapter/colyseus-networking-adapter.js +0 -38
  86. package/dist/adapter/first-party-systems.d.ts +0 -38
  87. package/dist/adapter/first-party-systems.d.ts.map +0 -1
  88. package/dist/adapter/first-party-systems.js +0 -77
  89. package/dist/adapter/game-adapter.d.ts +0 -133
  90. package/dist/adapter/game-adapter.d.ts.map +0 -1
  91. package/dist/adapter/game-adapter.js +0 -10
  92. package/dist/adapter/host-context.d.ts +0 -73
  93. package/dist/adapter/host-context.d.ts.map +0 -1
  94. package/dist/adapter/host-context.js +0 -16
  95. package/dist/adapter/index.d.ts +0 -22
  96. package/dist/adapter/index.d.ts.map +0 -1
  97. package/dist/adapter/index.js +0 -15
  98. package/dist/adapter/ingest/game-contract.d.ts +0 -53
  99. package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
  100. package/dist/adapter/ingest/game-contract.js +0 -30
  101. package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
  102. package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
  103. package/dist/adapter/ingest/overlay-applier.js +0 -132
  104. package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
  105. package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
  106. package/dist/adapter/ingest/overlay-apply.js +0 -101
  107. package/dist/adapter/ingest/overlay-file.d.ts +0 -79
  108. package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
  109. package/dist/adapter/ingest/overlay-file.js +0 -66
  110. package/dist/adapter/ingest/overlay-report.d.ts +0 -113
  111. package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
  112. package/dist/adapter/ingest/overlay-report.js +0 -103
  113. package/dist/adapter/ingest/scene-capture.d.ts +0 -97
  114. package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
  115. package/dist/adapter/ingest/scene-capture.js +0 -248
  116. package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
  117. package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
  118. package/dist/adapter/ingest/upstream-pin.js +0 -50
  119. package/dist/adapter/loop-gate-report.d.ts +0 -34
  120. package/dist/adapter/loop-gate-report.d.ts.map +0 -1
  121. package/dist/adapter/loop-gate-report.js +0 -37
  122. package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
  123. package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
  124. package/dist/adapter/rapier-physics-adapter.js +0 -46
  125. package/dist/adapter/system-adapter.d.ts +0 -133
  126. package/dist/adapter/system-adapter.d.ts.map +0 -1
  127. package/dist/adapter/system-adapter.js +0 -13
  128. package/dist/adapter/transform.d.ts +0 -18
  129. package/dist/adapter/transform.d.ts.map +0 -1
  130. package/dist/adapter/transform.js +0 -1
  131. package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -116
  132. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
  133. package/dist/adapter/vgai-scene-game-adapter.js +0 -714
  134. package/dist/adapter/world-kind.d.ts +0 -30
  135. package/dist/adapter/world-kind.d.ts.map +0 -1
  136. package/dist/adapter/world-kind.js +0 -18
  137. package/dist/ai/navigation.d.ts +0 -64
  138. package/dist/ai/navigation.d.ts.map +0 -1
  139. package/dist/ai/navigation.js +0 -133
  140. package/dist/animation/anim-graph-types.d.ts +0 -25
  141. package/dist/animation/anim-graph-types.d.ts.map +0 -1
  142. package/dist/animation/anim-graph-types.js +0 -1
  143. package/dist/animation/animation-clock.d.ts +0 -213
  144. package/dist/animation/animation-clock.d.ts.map +0 -1
  145. package/dist/animation/animation-clock.js +0 -301
  146. package/dist/animation/blend-node.d.ts +0 -22
  147. package/dist/animation/blend-node.d.ts.map +0 -1
  148. package/dist/animation/blend-node.js +0 -97
  149. package/dist/animation/camera-ownership.d.ts +0 -250
  150. package/dist/animation/camera-ownership.d.ts.map +0 -1
  151. package/dist/animation/camera-ownership.js +0 -169
  152. package/dist/animation/cinematic-cues.d.ts +0 -200
  153. package/dist/animation/cinematic-cues.d.ts.map +0 -1
  154. package/dist/animation/cinematic-cues.js +0 -213
  155. package/dist/animation/clip-map.d.ts +0 -12
  156. package/dist/animation/clip-map.d.ts.map +0 -1
  157. package/dist/animation/clip-map.js +0 -37
  158. package/dist/animation/gsap-registration.d.ts +0 -119
  159. package/dist/animation/gsap-registration.d.ts.map +0 -1
  160. package/dist/animation/gsap-registration.js +0 -92
  161. package/dist/animation/theatre-clock-binding.d.ts +0 -89
  162. package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
  163. package/dist/animation/theatre-clock-binding.js +0 -29
  164. package/dist/animation/theatre-director.d.ts +0 -242
  165. package/dist/animation/theatre-director.d.ts.map +0 -1
  166. package/dist/animation/theatre-director.js +0 -235
  167. package/dist/animation/theatre-object-binding.d.ts +0 -305
  168. package/dist/animation/theatre-object-binding.d.ts.map +0 -1
  169. package/dist/animation/theatre-object-binding.js +0 -351
  170. package/dist/animation/xstate-animation-binding.d.ts +0 -111
  171. package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
  172. package/dist/animation/xstate-animation-binding.js +0 -307
  173. package/dist/animation/xstate-animation-meta.d.ts +0 -228
  174. package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
  175. package/dist/animation/xstate-animation-meta.js +0 -221
  176. package/dist/assets.d.ts +0 -26
  177. package/dist/assets.d.ts.map +0 -1
  178. package/dist/assets.js +0 -55
  179. package/dist/audio/index.d.ts +0 -4
  180. package/dist/audio/index.d.ts.map +0 -1
  181. package/dist/audio/index.js +0 -24
  182. package/dist/audio/tone-clock-binding.d.ts +0 -75
  183. package/dist/audio/tone-clock-binding.d.ts.map +0 -1
  184. package/dist/audio/tone-clock-binding.js +0 -29
  185. package/dist/audio/tone-context.d.ts +0 -114
  186. package/dist/audio/tone-context.d.ts.map +0 -1
  187. package/dist/audio/tone-context.js +0 -39
  188. package/dist/audio/tone-offline-render.d.ts +0 -90
  189. package/dist/audio/tone-offline-render.d.ts.map +0 -1
  190. package/dist/audio/tone-offline-render.js +0 -56
  191. package/dist/audio/wav-encode.d.ts +0 -38
  192. package/dist/audio/wav-encode.d.ts.map +0 -1
  193. package/dist/audio/wav-encode.js +0 -97
  194. package/dist/core/game-loop.d.ts +0 -21
  195. package/dist/core/game-loop.d.ts.map +0 -1
  196. package/dist/core/game-loop.js +0 -130
  197. package/dist/core/system-runner.d.ts +0 -120
  198. package/dist/core/system-runner.d.ts.map +0 -1
  199. package/dist/core/system-runner.js +0 -286
  200. package/dist/core/types.d.ts +0 -58
  201. package/dist/core/types.d.ts.map +0 -1
  202. package/dist/core/types.js +0 -25
  203. package/dist/data/data-asset.d.ts +0 -101
  204. package/dist/data/data-asset.d.ts.map +0 -1
  205. package/dist/data/data-asset.js +0 -122
  206. package/dist/data/data-check-core.d.ts +0 -110
  207. package/dist/data/data-check-core.d.ts.map +0 -1
  208. package/dist/data/data-check-core.js +0 -178
  209. package/dist/data/data-ref.d.ts +0 -79
  210. package/dist/data/data-ref.d.ts.map +0 -1
  211. package/dist/data/data-ref.js +0 -130
  212. package/dist/data/vite-plugin-data.d.ts +0 -79
  213. package/dist/data/vite-plugin-data.d.ts.map +0 -1
  214. package/dist/data/vite-plugin-data.js +0 -217
  215. package/dist/dev/console-bridge.d.ts +0 -22
  216. package/dist/dev/console-bridge.d.ts.map +0 -1
  217. package/dist/dev/console-bridge.js +0 -71
  218. package/dist/dev/debug-draw.d.ts +0 -24
  219. package/dist/dev/debug-draw.d.ts.map +0 -1
  220. package/dist/dev/debug-draw.js +0 -73
  221. package/dist/dev/logger.d.ts +0 -30
  222. package/dist/dev/logger.d.ts.map +0 -1
  223. package/dist/dev/logger.js +0 -90
  224. package/dist/ecs/component-manager.d.ts +0 -189
  225. package/dist/ecs/component-manager.d.ts.map +0 -1
  226. package/dist/ecs/component-manager.js +0 -676
  227. package/dist/ecs/game-component.d.ts +0 -97
  228. package/dist/ecs/game-component.d.ts.map +0 -1
  229. package/dist/ecs/game-component.js +0 -80
  230. package/dist/ecs/hmr-swap-report.d.ts +0 -53
  231. package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
  232. package/dist/ecs/hmr-swap-report.js +0 -55
  233. package/dist/index.d.ts +0 -37
  234. package/dist/index.d.ts.map +0 -1
  235. package/dist/index.js +0 -30
  236. package/dist/input/input-manager.d.ts +0 -596
  237. package/dist/input/input-manager.d.ts.map +0 -1
  238. package/dist/input/input-manager.js +0 -1564
  239. package/dist/input/input-types.d.ts +0 -171
  240. package/dist/input/input-types.d.ts.map +0 -1
  241. package/dist/input/input-types.js +0 -1
  242. package/dist/input/prompt-labels.d.ts +0 -21
  243. package/dist/input/prompt-labels.d.ts.map +0 -1
  244. package/dist/input/prompt-labels.js +0 -121
  245. package/dist/input/rebind-controller.d.ts +0 -59
  246. package/dist/input/rebind-controller.d.ts.map +0 -1
  247. package/dist/input/rebind-controller.js +0 -85
  248. package/dist/input/schema.d.ts +0 -16
  249. package/dist/input/schema.d.ts.map +0 -1
  250. package/dist/input/schema.js +0 -228
  251. package/dist/loader.d.ts +0 -43
  252. package/dist/loader.d.ts.map +0 -1
  253. package/dist/loader.js +0 -59
  254. package/dist/manifest/index.d.ts +0 -5
  255. package/dist/manifest/index.d.ts.map +0 -1
  256. package/dist/manifest/index.js +0 -8
  257. package/dist/manifest/load-file.d.ts +0 -4
  258. package/dist/manifest/load-file.d.ts.map +0 -1
  259. package/dist/manifest/load-file.js +0 -14
  260. package/dist/manifest/load.d.ts +0 -117
  261. package/dist/manifest/load.d.ts.map +0 -1
  262. package/dist/manifest/load.js +0 -255
  263. package/dist/manifest/schema.d.ts +0 -173
  264. package/dist/manifest/schema.d.ts.map +0 -1
  265. package/dist/manifest/schema.js +0 -302
  266. package/dist/physics/collision-system.d.ts +0 -41
  267. package/dist/physics/collision-system.d.ts.map +0 -1
  268. package/dist/physics/collision-system.js +0 -64
  269. package/dist/physics/physics-registry.d.ts +0 -45
  270. package/dist/physics/physics-registry.d.ts.map +0 -1
  271. package/dist/physics/physics-registry.js +0 -65
  272. package/dist/physics/transform-writer.d.ts +0 -16
  273. package/dist/physics/transform-writer.d.ts.map +0 -1
  274. package/dist/physics/transform-writer.js +0 -38
  275. package/dist/physics/trigger-dispatch.d.ts +0 -24
  276. package/dist/physics/trigger-dispatch.d.ts.map +0 -1
  277. package/dist/physics/trigger-dispatch.js +0 -80
  278. package/dist/react/game-state.d.ts +0 -105
  279. package/dist/react/game-state.d.ts.map +0 -1
  280. package/dist/react/game-state.js +0 -144
  281. package/dist/react/use-data.d.ts +0 -60
  282. package/dist/react/use-data.d.ts.map +0 -1
  283. package/dist/react/use-data.js +0 -96
  284. package/dist/react/use-selection.d.ts +0 -75
  285. package/dist/react/use-selection.d.ts.map +0 -1
  286. package/dist/react/use-selection.js +0 -90
  287. package/dist/render/auto-batcher.d.ts +0 -34
  288. package/dist/render/auto-batcher.d.ts.map +0 -1
  289. package/dist/render/auto-batcher.js +0 -140
  290. package/dist/render/render-batch-system.d.ts +0 -33
  291. package/dist/render/render-batch-system.d.ts.map +0 -1
  292. package/dist/render/render-batch-system.js +0 -230
  293. package/dist/render/render-features.d.ts +0 -47
  294. package/dist/render/render-features.d.ts.map +0 -1
  295. package/dist/render/render-features.js +0 -105
  296. package/dist/render/render-settings.d.ts +0 -36
  297. package/dist/render/render-settings.d.ts.map +0 -1
  298. package/dist/render/render-settings.js +0 -51
  299. package/dist/runtime/create-runtime.d.ts +0 -280
  300. package/dist/runtime/create-runtime.d.ts.map +0 -1
  301. package/dist/runtime/create-runtime.js +0 -795
  302. package/dist/runtime/frame-selector-cache.d.ts +0 -41
  303. package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
  304. package/dist/runtime/frame-selector-cache.js +0 -65
  305. package/dist/runtime/game.d.ts +0 -433
  306. package/dist/runtime/game.d.ts.map +0 -1
  307. package/dist/runtime/game.js +0 -569
  308. package/dist/runtime/input-router.d.ts +0 -78
  309. package/dist/runtime/input-router.d.ts.map +0 -1
  310. package/dist/runtime/input-router.js +0 -171
  311. package/dist/runtime/mount-game.d.ts +0 -129
  312. package/dist/runtime/mount-game.d.ts.map +0 -1
  313. package/dist/runtime/mount-game.js +0 -152
  314. package/dist/runtime/mount-manifest.d.ts +0 -119
  315. package/dist/runtime/mount-manifest.d.ts.map +0 -1
  316. package/dist/runtime/mount-manifest.js +0 -204
  317. package/dist/runtime/render-audio-control.d.ts +0 -110
  318. package/dist/runtime/render-audio-control.d.ts.map +0 -1
  319. package/dist/runtime/render-audio-control.js +0 -111
  320. package/dist/runtime/render-control.d.ts +0 -291
  321. package/dist/runtime/render-control.d.ts.map +0 -1
  322. package/dist/runtime/render-control.js +0 -264
  323. package/dist/runtime/render-seed.d.ts +0 -57
  324. package/dist/runtime/render-seed.d.ts.map +0 -1
  325. package/dist/runtime/render-seed.js +0 -74
  326. package/dist/runtime/scene-ui-bridge.d.ts +0 -69
  327. package/dist/runtime/scene-ui-bridge.d.ts.map +0 -1
  328. package/dist/runtime/scene-ui-bridge.js +0 -23
  329. package/dist/runtime/scene-ui-data.d.ts +0 -13
  330. package/dist/runtime/scene-ui-data.d.ts.map +0 -1
  331. package/dist/runtime/scene-ui-data.js +0 -92
  332. package/dist/runtime/state-bridge.d.ts +0 -47
  333. package/dist/runtime/state-bridge.d.ts.map +0 -1
  334. package/dist/runtime/state-bridge.js +0 -53
  335. package/dist/runtime/types.d.ts +0 -179
  336. package/dist/runtime/types.d.ts.map +0 -1
  337. package/dist/runtime/types.js +0 -1
  338. package/dist/scene/asset-loaders.d.ts +0 -79
  339. package/dist/scene/asset-loaders.d.ts.map +0 -1
  340. package/dist/scene/asset-loaders.js +0 -141
  341. package/dist/scene/asset-paths.d.ts +0 -11
  342. package/dist/scene/asset-paths.d.ts.map +0 -1
  343. package/dist/scene/asset-paths.js +0 -108
  344. package/dist/scene/asset-ref-check.d.ts +0 -88
  345. package/dist/scene/asset-ref-check.d.ts.map +0 -1
  346. package/dist/scene/asset-ref-check.js +0 -214
  347. package/dist/scene/asset-registry.d.ts +0 -30
  348. package/dist/scene/asset-registry.d.ts.map +0 -1
  349. package/dist/scene/asset-registry.js +0 -50
  350. package/dist/scene/collider-dimensions.d.ts +0 -63
  351. package/dist/scene/collider-dimensions.d.ts.map +0 -1
  352. package/dist/scene/collider-dimensions.js +0 -98
  353. package/dist/scene/component-registry.d.ts +0 -17
  354. package/dist/scene/component-registry.d.ts.map +0 -1
  355. package/dist/scene/component-registry.js +0 -28
  356. package/dist/scene/defaults.d.ts +0 -252
  357. package/dist/scene/defaults.d.ts.map +0 -1
  358. package/dist/scene/defaults.js +0 -151
  359. package/dist/scene/geometries/index.d.ts +0 -8
  360. package/dist/scene/geometries/index.d.ts.map +0 -1
  361. package/dist/scene/geometries/index.js +0 -7
  362. package/dist/scene/geometries/terrain.d.ts +0 -2
  363. package/dist/scene/geometries/terrain.d.ts.map +0 -1
  364. package/dist/scene/geometries/terrain.js +0 -37
  365. package/dist/scene/geometry-registry.d.ts +0 -24
  366. package/dist/scene/geometry-registry.d.ts.map +0 -1
  367. package/dist/scene/geometry-registry.js +0 -20
  368. package/dist/scene/instance-registry.d.ts +0 -36
  369. package/dist/scene/instance-registry.d.ts.map +0 -1
  370. package/dist/scene/instance-registry.js +0 -55
  371. package/dist/scene/instancers/grid.d.ts +0 -2
  372. package/dist/scene/instancers/grid.d.ts.map +0 -1
  373. package/dist/scene/instancers/grid.js +0 -36
  374. package/dist/scene/instancers/index.d.ts +0 -8
  375. package/dist/scene/instancers/index.d.ts.map +0 -1
  376. package/dist/scene/instancers/index.js +0 -7
  377. package/dist/scene/light-camera-factory.d.ts +0 -23
  378. package/dist/scene/light-camera-factory.d.ts.map +0 -1
  379. package/dist/scene/light-camera-factory.js +0 -68
  380. package/dist/scene/material-factory.d.ts +0 -17
  381. package/dist/scene/material-factory.d.ts.map +0 -1
  382. package/dist/scene/material-factory.js +0 -197
  383. package/dist/scene/material-registry.d.ts +0 -40
  384. package/dist/scene/material-registry.d.ts.map +0 -1
  385. package/dist/scene/material-registry.js +0 -44
  386. package/dist/scene/materials/index.d.ts +0 -8
  387. package/dist/scene/materials/index.d.ts.map +0 -1
  388. package/dist/scene/materials/index.js +0 -7
  389. package/dist/scene/materials/water.d.ts +0 -2
  390. package/dist/scene/materials/water.d.ts.map +0 -1
  391. package/dist/scene/materials/water.js +0 -54
  392. package/dist/scene/parse.d.ts +0 -23
  393. package/dist/scene/parse.d.ts.map +0 -1
  394. package/dist/scene/parse.js +0 -179
  395. package/dist/scene/particles-factory.d.ts +0 -33
  396. package/dist/scene/particles-factory.d.ts.map +0 -1
  397. package/dist/scene/particles-factory.js +0 -282
  398. package/dist/scene/scene-apply.d.ts +0 -109
  399. package/dist/scene/scene-apply.d.ts.map +0 -1
  400. package/dist/scene/scene-apply.js +0 -326
  401. package/dist/scene/scene-diff-schema.d.ts +0 -285
  402. package/dist/scene/scene-diff-schema.d.ts.map +0 -1
  403. package/dist/scene/scene-diff-schema.js +0 -92
  404. package/dist/scene/scene-diff-types.d.ts +0 -40
  405. package/dist/scene/scene-diff-types.d.ts.map +0 -1
  406. package/dist/scene/scene-diff-types.js +0 -14
  407. package/dist/scene/scene-loader.d.ts +0 -177
  408. package/dist/scene/scene-loader.d.ts.map +0 -1
  409. package/dist/scene/scene-loader.js +0 -1213
  410. package/dist/scene/scene-query.d.ts +0 -11
  411. package/dist/scene/scene-query.d.ts.map +0 -1
  412. package/dist/scene/scene-query.js +0 -63
  413. package/dist/scene/scene-types.d.ts +0 -10
  414. package/dist/scene/scene-types.d.ts.map +0 -1
  415. package/dist/scene/scene-types.js +0 -8
  416. package/dist/scene/scene-version.d.ts +0 -26
  417. package/dist/scene/scene-version.d.ts.map +0 -1
  418. package/dist/scene/scene-version.js +0 -34
  419. package/dist/scene/schema/animation.d.ts +0 -8
  420. package/dist/scene/schema/animation.d.ts.map +0 -1
  421. package/dist/scene/schema/animation.js +0 -42
  422. package/dist/scene/schema/audio.d.ts +0 -13
  423. package/dist/scene/schema/audio.d.ts.map +0 -1
  424. package/dist/scene/schema/audio.js +0 -22
  425. package/dist/scene/schema/camera.d.ts +0 -28
  426. package/dist/scene/schema/camera.d.ts.map +0 -1
  427. package/dist/scene/schema/camera.js +0 -17
  428. package/dist/scene/schema/collider.d.ts +0 -40
  429. package/dist/scene/schema/collider.d.ts.map +0 -1
  430. package/dist/scene/schema/collider.js +0 -55
  431. package/dist/scene/schema/entity-ref.d.ts +0 -31
  432. package/dist/scene/schema/entity-ref.d.ts.map +0 -1
  433. package/dist/scene/schema/entity-ref.js +0 -61
  434. package/dist/scene/schema/entity.d.ts +0 -1036
  435. package/dist/scene/schema/entity.d.ts.map +0 -1
  436. package/dist/scene/schema/entity.js +0 -153
  437. package/dist/scene/schema/environment.d.ts +0 -425
  438. package/dist/scene/schema/environment.d.ts.map +0 -1
  439. package/dist/scene/schema/environment.js +0 -357
  440. package/dist/scene/schema/index.d.ts +0 -39
  441. package/dist/scene/schema/index.d.ts.map +0 -1
  442. package/dist/scene/schema/index.js +0 -20
  443. package/dist/scene/schema/instances.d.ts +0 -14
  444. package/dist/scene/schema/instances.d.ts.map +0 -1
  445. package/dist/scene/schema/instances.js +0 -28
  446. package/dist/scene/schema/joint.d.ts +0 -23
  447. package/dist/scene/schema/joint.d.ts.map +0 -1
  448. package/dist/scene/schema/joint.js +0 -23
  449. package/dist/scene/schema/light.d.ts +0 -38
  450. package/dist/scene/schema/light.d.ts.map +0 -1
  451. package/dist/scene/schema/light.js +0 -26
  452. package/dist/scene/schema/material.d.ts +0 -199
  453. package/dist/scene/schema/material.d.ts.map +0 -1
  454. package/dist/scene/schema/material.js +0 -99
  455. package/dist/scene/schema/mesh.d.ts +0 -48
  456. package/dist/scene/schema/mesh.d.ts.map +0 -1
  457. package/dist/scene/schema/mesh.js +0 -82
  458. package/dist/scene/schema/particles.d.ts +0 -2178
  459. package/dist/scene/schema/particles.d.ts.map +0 -1
  460. package/dist/scene/schema/particles.js +0 -321
  461. package/dist/scene/schema/physics.d.ts +0 -56
  462. package/dist/scene/schema/physics.d.ts.map +0 -1
  463. package/dist/scene/schema/physics.js +0 -37
  464. package/dist/scene/schema/scene-file.d.ts +0 -304
  465. package/dist/scene/schema/scene-file.d.ts.map +0 -1
  466. package/dist/scene/schema/scene-file.js +0 -262
  467. package/dist/scene/schema/shadow.d.ts +0 -28
  468. package/dist/scene/schema/shadow.d.ts.map +0 -1
  469. package/dist/scene/schema/shadow.js +0 -20
  470. package/dist/scene/schema/spline.d.ts +0 -25
  471. package/dist/scene/schema/spline.d.ts.map +0 -1
  472. package/dist/scene/schema/spline.js +0 -15
  473. package/dist/scene/schema/tuples.d.ts +0 -12
  474. package/dist/scene/schema/tuples.d.ts.map +0 -1
  475. package/dist/scene/schema/tuples.js +0 -14
  476. package/dist/scene/schema/ui.d.ts +0 -880
  477. package/dist/scene/schema/ui.d.ts.map +0 -1
  478. package/dist/scene/schema/ui.js +0 -506
  479. package/dist/scene/user-data.d.ts +0 -171
  480. package/dist/scene/user-data.d.ts.map +0 -1
  481. package/dist/scene/user-data.js +0 -137
  482. package/dist/setup/setup-audio.d.ts +0 -20
  483. package/dist/setup/setup-audio.d.ts.map +0 -1
  484. package/dist/setup/setup-audio.js +0 -41
  485. package/dist/setup/setup-particles.d.ts +0 -17
  486. package/dist/setup/setup-particles.d.ts.map +0 -1
  487. package/dist/setup/setup-particles.js +0 -16
  488. package/dist/setup/setup-physics.d.ts +0 -25
  489. package/dist/setup/setup-physics.d.ts.map +0 -1
  490. package/dist/setup/setup-physics.js +0 -51
  491. package/dist/setup/setup-renderer.d.ts +0 -69
  492. package/dist/setup/setup-renderer.d.ts.map +0 -1
  493. package/dist/setup/setup-renderer.js +0 -363
  494. package/dist/tools/define-tool.d.ts +0 -105
  495. package/dist/tools/define-tool.d.ts.map +0 -1
  496. package/dist/tools/define-tool.js +0 -82
  497. package/dist/world2d/authoring-2d.d.ts +0 -76
  498. package/dist/world2d/authoring-2d.d.ts.map +0 -1
  499. package/dist/world2d/authoring-2d.js +0 -176
  500. package/dist/world2d/capture-to-scene2d.d.ts +0 -5
  501. package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
  502. package/dist/world2d/capture-to-scene2d.js +0 -49
  503. package/dist/world2d/collision-2d.d.ts +0 -52
  504. package/dist/world2d/collision-2d.d.ts.map +0 -1
  505. package/dist/world2d/collision-2d.js +0 -70
  506. package/dist/world2d/components-2d.d.ts +0 -47
  507. package/dist/world2d/components-2d.d.ts.map +0 -1
  508. package/dist/world2d/components-2d.js +0 -77
  509. package/dist/world2d/index.d.ts +0 -34
  510. package/dist/world2d/index.d.ts.map +0 -1
  511. package/dist/world2d/index.js +0 -32
  512. package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
  513. package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
  514. package/dist/world2d/ingest-iframe-2d.js +0 -166
  515. package/dist/world2d/ingest2d.d.ts +0 -97
  516. package/dist/world2d/ingest2d.d.ts.map +0 -1
  517. package/dist/world2d/ingest2d.js +0 -40
  518. package/dist/world2d/physics2d-registry.d.ts +0 -24
  519. package/dist/world2d/physics2d-registry.d.ts.map +0 -1
  520. package/dist/world2d/physics2d-registry.js +0 -38
  521. package/dist/world2d/pixi-game-adapter.d.ts +0 -107
  522. package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
  523. package/dist/world2d/pixi-game-adapter.js +0 -211
  524. package/dist/world2d/pixi-surface.d.ts +0 -39
  525. package/dist/world2d/pixi-surface.d.ts.map +0 -1
  526. package/dist/world2d/pixi-surface.js +0 -47
  527. package/dist/world2d/scene-capture-2d.d.ts +0 -43
  528. package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
  529. package/dist/world2d/scene-capture-2d.js +0 -92
  530. package/dist/world2d/scene2d-loader.d.ts +0 -27
  531. package/dist/world2d/scene2d-loader.d.ts.map +0 -1
  532. package/dist/world2d/scene2d-loader.js +0 -274
  533. package/dist/world2d/schema/entity2d.d.ts +0 -102
  534. package/dist/world2d/schema/entity2d.d.ts.map +0 -1
  535. package/dist/world2d/schema/entity2d.js +0 -119
  536. package/dist/world2d/schema/physics2d.d.ts +0 -46
  537. package/dist/world2d/schema/physics2d.d.ts.map +0 -1
  538. package/dist/world2d/schema/physics2d.js +0 -45
  539. package/dist/world2d/schema/sprite.d.ts +0 -42
  540. package/dist/world2d/schema/sprite.d.ts.map +0 -1
  541. package/dist/world2d/schema/sprite.js +0 -63
  542. package/dist/world2d/schema/tilemap.d.ts +0 -15
  543. package/dist/world2d/schema/tilemap.d.ts.map +0 -1
  544. package/dist/world2d/schema/tilemap.js +0 -19
  545. package/dist/world2d/schema/tuples2d.d.ts +0 -20
  546. package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
  547. package/dist/world2d/schema/tuples2d.js +0 -19
  548. package/dist/world2d/system-adapters-2d.d.ts +0 -16
  549. package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
  550. package/dist/world2d/system-adapters-2d.js +0 -37
  551. package/dist/world2d/transform-writer-2d.d.ts +0 -16
  552. package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
  553. package/dist/world2d/transform-writer-2d.js +0 -22
  554. package/dist/world2d/types.d.ts +0 -53
  555. package/dist/world2d/types.d.ts.map +0 -1
  556. package/dist/world2d/types.js +0 -1
  557. package/src/runtime/scene-ui-bridge.ts +0 -86
  558. package/src/runtime/scene-ui-data.ts +0 -119
  559. package/src/scene/schema/ui.ts +0 -602
@@ -2,25 +2,25 @@
2
2
  // helper: an ENGINE-side generalization of `examples/tri-world/src/main.ts`'s
3
3
  // hand-built `WorldMountSpec[]`.
4
4
  //
5
- // `resolveAllWorlds`/`resolveWorldAdapter` (`packages/editor/src/
5
+ // `resolveAllWorlds`/`resolveRootAdapter` (`packages/editor/src/
6
6
  // adapter-resolver.ts`) already do this translation for the EDITOR, but they
7
7
  // are Vite-coupled by construction (`/@fs/` dynamic imports of project files
8
8
  // through the dev server, §0.1/§0.5 of the design doc) — unusable from a
9
9
  // plain static build. This module mirrors their per-kind dispatch
10
10
  // (`default-three`/`default-pixi`/`default-react`, `{ module }`, `{ ingest }`)
11
11
  // but never imports a project file itself: the caller's OWN bundler already
12
- // resolved whatever module graph the manifest's worlds need, and hands the
12
+ // resolved whatever module graph the manifest's roots need, and hands the
13
13
  // already-built pieces in via `entries` (keyed by world id) — no `/@fs/`, no
14
14
  // dev server, no editor import.
15
15
  //
16
16
  // Engine-core react/pixi-free discipline (§0.6, mirrored from
17
17
  // `create-runtime.ts`'s own documented rule for its `Pixi2DGameAdapter`/
18
- // `ReactWorldAdapter` type-only imports): this file never value-imports
18
+ // `ReactRootAdapter` type-only imports): this file never value-imports
19
19
  // `pixi.js`, `world2d/pixi-game-adapter.ts`, `react`, or `react-dom` — a
20
20
  // pixijs or react world's adapter is ALWAYS supplied already-constructed via
21
21
  // `entries[id].adapter` (the caller's own module graph built it, exactly like
22
22
  // `tri-world`'s original hand-mount built `new PixiSceneGameAdapter(...)` and
23
- // a hand-rolled `ReactWorldAdapter` itself). Threejs is different: `three`/
23
+ // a hand-rolled `ReactRootAdapter` itself). Threejs is different: `three`/
24
24
  // `VgaiSceneGameAdapter` are already unconditional dependencies of every
25
25
  // caller of `createGameRuntime`'s legacy path (this same file's sibling,
26
26
  // immediately below in this directory), so building a `VgaiSceneGameAdapter`
@@ -28,21 +28,25 @@
28
28
  // weight — only pixi/react are avoided.
29
29
 
30
30
  import { fromSetup, VgaiSceneGameAdapter } from '../adapter';
31
+ import { assertNever } from '../adapter/adapter-surface';
31
32
  import type { GameAdapter } from '../adapter/game-adapter';
32
- import { assertNever } from '../adapter/world-kind';
33
33
  import {
34
34
  loadGameManifest,
35
+ type ResolvedAdapterRoot,
35
36
  type ResolvedGameManifest,
36
- type ResolvedWorldEntry,
37
37
  } from '../manifest/load';
38
38
  import type { ComponentRegistry } from '../scene/component-registry';
39
39
  import {
40
40
  createGameRuntime,
41
41
  type GameSession,
42
42
  type Pixi2DGameAdapter,
43
- type ReactWorldAdapter,
43
+ type ReactRootAdapter,
44
44
  type WorldMountSpec,
45
45
  } from './create-runtime';
46
+ import { type DebugBridgeWindowTarget, maybeInstallDebugBridge } from './debug-bridge';
47
+ import { getDebugRegistry } from './debug-registry';
48
+ import { getGameplayRngTrapControl } from './gameplay-rng-trap';
49
+ import { RENDER_SEED_QUERY_PARAM } from './render-seed';
46
50
  import type { GameSetupFn } from './types';
47
51
 
48
52
  // ---------------------------------------------------------------------------
@@ -96,7 +100,7 @@ export interface PixiMountEntry {
96
100
 
97
101
  /**
98
102
  * A caller-supplied entry for a `kind: 'react'` world — ALWAYS a
99
- * fully-constructed {@link ReactWorldAdapter} (the caller's own module graph
103
+ * fully-constructed {@link ReactRootAdapter} (the caller's own module graph
100
104
  * calls `createRoot(host.container).render(<GameProvider game={host.game}>
101
105
  * <Entry/></GameProvider>)` itself, exactly like `tri-world`'s original
102
106
  * hand-mount did). A standalone build has ONE module graph, so there is no
@@ -109,7 +113,7 @@ export interface PixiMountEntry {
109
113
  */
110
114
  export interface ReactMountEntry {
111
115
  readonly kind: 'react';
112
- readonly adapter: ReactWorldAdapter;
116
+ readonly adapter: ReactRootAdapter;
113
117
  }
114
118
 
115
119
  export type MountEntry = ThreeMountEntry | PixiMountEntry | ReactMountEntry;
@@ -143,6 +147,71 @@ export interface MountManifestOptions {
143
147
  /** Forwarded to `createGameRuntime` — Node/headless test harnesses only,
144
148
  * never a real host. See `WorldsRuntimeConfig.headless`. */
145
149
  readonly headless?: boolean | undefined;
150
+ /**
151
+ * Task 2.1 (`docs/ACCEPTANCE-DRIVER-BUILD-PLAN.md`,
152
+ * `docs/SYNTHETIC-PLAYER-SPEC.md` §3.4): overrides for the `?vgai-debug=1`
153
+ * bridge `mountManifestWorlds` installs at the tail of every mount — the
154
+ * engine-owned install point so every standalone project gets it with zero
155
+ * template edits. Omit both in a real host (defaults to `window.location`/
156
+ * `window`); a headless test supplies fakes here instead of touching the
157
+ * global object, mirroring `render-control.ts`'s own `location`/`target`
158
+ * override precedent.
159
+ */
160
+ readonly debugBridge?:
161
+ | {
162
+ readonly url?: { readonly search: string } | undefined;
163
+ readonly window?: DebugBridgeWindowTarget | undefined;
164
+ }
165
+ | undefined;
166
+ /**
167
+ * D15 (T-D15.1) — the "explicit config" leg of the boot-time seed
168
+ * precedence (`manifest.determinism.defaultSeed` → `?vgai-seed=` → this),
169
+ * highest-precedence, for a caller that already knows the exact seed it
170
+ * wants (a future CLI `--seed`/probe fixture `seed` option, T-D15.6).
171
+ * Ignored entirely unless the manifest declares
172
+ * `determinism.seededRandom` — see `resolveDeterminismSeed` below.
173
+ */
174
+ readonly seed?: number | undefined;
175
+ /** Where to read `?vgai-seed=` from for the boot-time seed reader. Same
176
+ * override precedent as `debugBridge.url` (defaults to `window.location`
177
+ * when a real `window` exists; a headless caller with no override gets no
178
+ * query-param seed, same as `maybeInstallDebugBridge`'s own url default). */
179
+ readonly seedUrl?: { readonly search: string } | undefined;
180
+ }
181
+
182
+ /**
183
+ * D15 (T-D15.1) boot-time seed reader — resolves the root seed
184
+ * `mountManifestWorlds` threads into `createGameRuntime` (and therefore
185
+ * `createGame`, BEFORE any world's `mount()`/`setup()` runs). Returns
186
+ * `undefined` when the manifest doesn't declare `determinism.seededRandom`
187
+ * at all — `?vgai-seed=` and `defaultSeed` are both ignored in that case
188
+ * (§2.a: "the mount path seeds ctx.random ... iff declared"; an undeclared
189
+ * project's `ctx.random` still exists, just boots from `createGame`'s own
190
+ * fixed default, unaffected by the manifest or the URL).
191
+ *
192
+ * Precedence when declared (highest wins): `explicitSeed` (a caller-supplied
193
+ * config value) → `?vgai-seed=<int>` on `url` → `manifest.determinism
194
+ * .defaultSeed`.
195
+ */
196
+ export function resolveDeterminismSeed(opts: {
197
+ readonly determinism: ResolvedGameManifest['determinism'];
198
+ readonly explicitSeed: number | undefined;
199
+ readonly url: { readonly search: string } | undefined;
200
+ }): number | undefined {
201
+ if (opts.determinism?.seededRandom !== true) return undefined;
202
+ const querySeed = opts.url ? readSeedQueryParam(opts.url) : undefined;
203
+ return opts.explicitSeed ?? querySeed ?? opts.determinism.defaultSeed;
204
+ }
205
+
206
+ function readSeedQueryParam(url: { readonly search: string }): number | undefined {
207
+ const raw = new URLSearchParams(url.search).get(RENDER_SEED_QUERY_PARAM);
208
+ if (raw === null || raw === '') return undefined;
209
+ const parsed = Number(raw);
210
+ return Number.isFinite(parsed) ? parsed : undefined;
211
+ }
212
+
213
+ function hasRealWindow(): boolean {
214
+ return typeof window !== 'undefined';
146
215
  }
147
216
 
148
217
  // `mountManifestWorlds` returns the SAME `GameSession` shape
@@ -159,24 +228,24 @@ export type MountedManifestSession = GameSession;
159
228
  /**
160
229
  * Distinguish an already-`loadGameManifest`d {@link ResolvedGameManifest}
161
230
  * from a raw (pre-Zod-parse) manifest value. The two shapes differ in
162
- * exactly one load-bearing way for this check: a `ResolvedWorldEntry.adapter`
231
+ * exactly one load-bearing way for this check: a `ResolvedAdapterRoot.adapter`
163
232
  * is `{ type: 'default' | 'module' | 'ingest', identity, ... }`, while a raw
164
- * `WorldEntry.adapter` is the literal string `'default'` or a bare `{module}`/
233
+ * `AdapterRoot.adapter` is the literal string `'default'` or a bare `{module}`/
165
234
  * `{ingest}` object with NO `type`/`identity` fields (`schema.ts`'s
166
- * `WorldAdapterSchema`). An empty `worlds` array is treated as "not resolved"
235
+ * `RootAdapterSchema`). An empty `roots` array is treated as "not resolved"
167
236
  * (falls through to `loadGameManifest`, whose own Zod validation reports the
168
237
  * empty-array error, if any, more precisely than a guess here could).
169
238
  */
170
239
  function looksAlreadyResolved(value: unknown): value is ResolvedGameManifest {
171
240
  if (typeof value !== 'object' || value === null) return false;
172
- const worlds = (value as { worlds?: unknown }).worlds;
173
- if (!Array.isArray(worlds) || worlds.length === 0) return false;
174
- return worlds.every((world) => {
241
+ const roots = (value as { roots?: unknown }).roots;
242
+ if (!Array.isArray(roots) || roots.length === 0) return false;
243
+ return roots.every((world) => {
175
244
  if (typeof world !== 'object' || world === null) return false;
176
245
  const adapter = (world as { adapter?: unknown }).adapter;
177
246
  if (typeof adapter !== 'object' || adapter === null) return false;
178
247
  const type = (adapter as { type?: unknown }).type;
179
- return type === 'default' || type === 'module' || type === 'ingest';
248
+ return type === 'builtin' || type === 'module' || type === 'ingest';
180
249
  });
181
250
  }
182
251
 
@@ -192,12 +261,12 @@ export function resolveManifest(raw: unknown): ResolvedGameManifest {
192
261
  }
193
262
 
194
263
  // ---------------------------------------------------------------------------
195
- // Per-kind entry -> adapter resolution (mirrors `resolveWorldAdapter`'s
264
+ // Per-kind entry -> adapter resolution (mirrors `resolveRootAdapter`'s
196
265
  // per-identity dispatch, `packages/editor/src/adapter-resolver.ts`)
197
266
  // ---------------------------------------------------------------------------
198
267
 
199
268
  function resolveThreeAdapter(
200
- world: ResolvedWorldEntry,
269
+ world: ResolvedAdapterRoot,
201
270
  entry: ThreeMountEntry | undefined,
202
271
  ): GameAdapter {
203
272
  if (entry?.adapter) return entry.adapter;
@@ -213,7 +282,7 @@ function resolveThreeAdapter(
213
282
  if (world.adapter.type === 'ingest') {
214
283
  throw new Error(
215
284
  `mountManifestWorlds: world "${world.id}" (threejs) declares an { ingest } adapter — ` +
216
- "ingest worlds require the editor's dev-server-backed mount machinery (an EditorStore " +
285
+ "ingest roots require the editor's dev-server-backed mount machinery (an EditorStore " +
217
286
  "plus iframe/DOM capture, see adapter-resolver.ts's resolveIngestThreeAdapter) and are " +
218
287
  'not supported by mountManifestWorlds (docs/WAVE3-ADAPTER-PLUMBING-DESIGN.md D-Z7 — no ' +
219
288
  'porting aids, no hosted ingest routes).',
@@ -249,7 +318,7 @@ function resolveThreeAdapter(
249
318
  }
250
319
 
251
320
  function resolvePixiAdapter(
252
- world: ResolvedWorldEntry,
321
+ world: ResolvedAdapterRoot,
253
322
  entry: PixiMountEntry | undefined,
254
323
  ): Pixi2DGameAdapter {
255
324
  if (entry?.adapter) return entry.adapter;
@@ -263,13 +332,13 @@ function resolvePixiAdapter(
263
332
  }
264
333
 
265
334
  function resolveReactAdapter(
266
- world: ResolvedWorldEntry,
335
+ world: ResolvedAdapterRoot,
267
336
  entry: ReactMountEntry | undefined,
268
- ): ReactWorldAdapter {
337
+ ): ReactRootAdapter {
269
338
  if (entry?.adapter) return entry.adapter;
270
339
  throw new Error(
271
340
  `mountManifestWorlds: world "${world.id}" (react) has no entries["${world.id}"] — a react ` +
272
- 'world always needs a caller-supplied, already-constructed `ReactWorldAdapter` ' +
341
+ 'world always needs a caller-supplied, already-constructed `ReactRootAdapter` ' +
273
342
  `(entries["${world.id}"] = { kind: 'react', adapter }, mounting via your own already-imported ` +
274
343
  'react-dom `createRoot` + your own `<GameProvider>`) — mountManifestWorlds never ' +
275
344
  "value-imports react/react-dom (mirrors create-runtime.ts's own react-free-core discipline; " +
@@ -278,13 +347,13 @@ function resolveReactAdapter(
278
347
  }
279
348
 
280
349
  function buildWorldMountSpec(
281
- world: ResolvedWorldEntry,
350
+ world: ResolvedAdapterRoot,
282
351
  entry: MountEntry | undefined,
283
352
  ): WorldMountSpec {
284
- if (entry !== undefined && entry.kind !== world.kind) {
353
+ if (entry !== undefined && entry.kind !== world.surface) {
285
354
  throw new Error(
286
355
  `mountManifestWorlds: entries["${world.id}"] declares kind "${entry.kind}" but the ` +
287
- `manifest's world "${world.id}" is kind "${world.kind}" — fix the entries key (or the ` +
356
+ `manifest's root "${world.id}" uses surface "${world.surface}" — fix the entries key (or the ` +
288
357
  'manifest) so the two agree.',
289
358
  );
290
359
  }
@@ -300,23 +369,23 @@ function buildWorldMountSpec(
300
369
  // above (or `entry` is `undefined`) — TS can't narrow a `Record` lookup
301
370
  // through that runtime check, so each branch casts to its own entry shape;
302
371
  // the actual safety comes from the mismatch guard, not from the cast.
303
- if (world.kind === 'threejs') {
372
+ if (world.surface === 'threejs') {
304
373
  const threeEntry = entry as ThreeMountEntry | undefined;
305
374
  return { ...base, kind: 'threejs', adapter: resolveThreeAdapter(world, threeEntry) };
306
375
  }
307
- if (world.kind === 'pixijs') {
376
+ if (world.surface === 'pixijs') {
308
377
  const pixiEntry = entry as PixiMountEntry | undefined;
309
378
  return { ...base, kind: 'pixijs', adapter: resolvePixiAdapter(world, pixiEntry) };
310
379
  }
311
- if (world.kind === 'react') {
380
+ if (world.surface === 'react') {
312
381
  const reactEntry = entry as ReactMountEntry | undefined;
313
382
  return { ...base, kind: 'react', adapter: resolveReactAdapter(world, reactEntry) };
314
383
  }
315
384
  // Exhaustiveness guard (§7.4-2, same idiom as `resolveAllWorlds`'s own
316
- // dispatch loop): `world.kind` is the closed `WorldEntry['kind']` union
385
+ // dispatch loop): `world.kind` is the closed `AdapterRoot['kind']` union
317
386
  // (`z.enum(['threejs','pixijs','react'])`), so a hypothetical 4th kind
318
387
  // must fail to compile here, not silently fall through.
319
- return assertNever(world.kind, 'mountManifestWorlds');
388
+ return assertNever(world.surface, 'mountManifestWorlds');
320
389
  }
321
390
 
322
391
  // ---------------------------------------------------------------------------
@@ -328,7 +397,7 @@ function buildWorldMountSpec(
328
397
  * standalone — no editor, no dev server. The generalization of
329
398
  * `examples/tri-world/src/main.ts`'s hand-built `WorldMountSpec[]` (D-Z2,
330
399
  * docs/WAVE3-ADAPTER-PLUMBING-DESIGN.md). Reuses the pure `loadGameManifest`
331
- * + `createGameRuntime({ worlds })` and mirrors `resolveAllWorlds`'s per-kind
400
+ * + `createGameRuntime({ roots })` and mirrors `resolveAllWorlds`'s per-kind
332
401
  * dispatch — but every entry the manifest needs beyond what a `default`-
333
402
  * adapter scene/entry can express on its own comes from the caller's OWN
334
403
  * already-imported module graph (`opts.entries`), never a dynamic import
@@ -342,20 +411,83 @@ function buildWorldMountSpec(
342
411
  */
343
412
  export async function mountManifestWorlds(opts: MountManifestOptions): Promise<GameSession> {
344
413
  const manifest = resolveManifest(opts.manifest);
345
- if (manifest.worlds.length === 0) {
346
- throw new Error('mountManifestWorlds: manifest declares no worlds — nothing to mount.');
414
+ if (manifest.roots.length === 0) {
415
+ throw new Error('mountManifestWorlds: manifest declares no roots — nothing to mount.');
347
416
  }
348
417
  const entries = opts.entries ?? {};
349
418
 
350
- const worlds: WorldMountSpec[] = manifest.worlds.map((world) =>
419
+ const roots: WorldMountSpec[] = manifest.roots.map((world) =>
351
420
  buildWorldMountSpec(world, entries[world.id]),
352
421
  );
353
422
 
354
- return createGameRuntime({
423
+ // D15 (T-D15.1) — resolved BEFORE `createGameRuntime` (which constructs the
424
+ // Game, and therefore `ctx.random`, before any world's `mount()`/`setup()`
425
+ // runs — see `createGame`'s own doc comment): the seed must be baked in at
426
+ // construction time, not patched in afterward, or a world's `setup()`
427
+ // would already have drawn from the wrong (default) sequence before any
428
+ // post-hoc reseed could take effect.
429
+ const seedUrl = opts.seedUrl ?? (hasRealWindow() ? window.location : undefined);
430
+ const resolvedSeed = resolveDeterminismSeed({
431
+ determinism: manifest.determinism,
432
+ explicitSeed: opts.seed,
433
+ url: seedUrl,
434
+ });
435
+
436
+ const session = await createGameRuntime({
355
437
  container: opts.container,
356
- worlds,
438
+ roots,
357
439
  width: opts.width ?? manifest.resolution?.width,
358
440
  height: opts.height ?? manifest.resolution?.height,
359
441
  headless: opts.headless,
442
+ seed: resolvedSeed,
360
443
  });
444
+
445
+ // D15 (T-D15.3) — the dev-mode Math.random phase trap: only while the
446
+ // manifest declares the contract AND this is a dev build (mirrors D18's
447
+ // debug-bridge gate — `import.meta.env.DEV`, never a production build
448
+ // unless something ELSE explicitly opts in, which this trap has no
449
+ // opt-in for at all: it is dev-only, full stop). `getGameplayRngTrapControl`
450
+ // returns `null` only for a bare `Game`-shaped test stand-in predating
451
+ // T7.1 — real mounts always have one (same precedent as `getDebugRegistry`
452
+ // just below).
453
+ if (manifest.determinism?.seededRandom === true && Boolean(import.meta.env?.DEV)) {
454
+ getGameplayRngTrapControl(session.game)?.setEnabled(true);
455
+ }
456
+
457
+ // Task 2.1 — install the `?vgai-debug=1` bridge at the TAIL of every
458
+ // manifest mount (engine-owned, so a standalone project gets it with zero
459
+ // template edits). `getDebugRegistry` returns `null` only for a bare
460
+ // `Game`-shaped test stand-in predating T7.1 — real mounts always have one.
461
+ const debugRegistry = getDebugRegistry(session.game);
462
+ if (debugRegistry) {
463
+ // Defect 3 fix: `setRoomDeclared` (the locus-required rule — a project
464
+ // with a Colyseus room must declare `locus: 'client' | 'server'` on every
465
+ // debug command, docs/SYNTHETIC-PLAYER-SPEC.md §3.1) was never actually
466
+ // called from a real mount path — this is that wiring. `manifest.server`
467
+ // (`ResolvedGameManifest.server`, `manifest/load.ts`) is `{ room, module }
468
+ // | undefined`; its mere presence is the "this project declares a room"
469
+ // signal, independent of whether/when the game actually joins it.
470
+ if (manifest.server) {
471
+ debugRegistry.setRoomDeclared(true);
472
+ }
473
+ // Defect 5 fix: `maybeInstallDebugBridge` adds `window` listeners and
474
+ // publishes `window.__vgai` with no way to undo either — wire its
475
+ // `uninstall()` into THIS session's own `stop()` so a caller that tears
476
+ // this mount down doesn't leave the bridge (and its listeners) live.
477
+ const bridgeHandle = maybeInstallDebugBridge({
478
+ registry: debugRegistry,
479
+ manifest,
480
+ url: opts.debugBridge?.url,
481
+ window: opts.debugBridge?.window,
482
+ });
483
+ if (bridgeHandle) {
484
+ const stopSession = session.stop;
485
+ session.stop = () => {
486
+ bridgeHandle.uninstall();
487
+ stopSession();
488
+ };
489
+ }
490
+ }
491
+
492
+ return session;
361
493
  }
@@ -10,10 +10,10 @@
10
10
  * that deliberately drives `game.runFrame(fixedDt)` instead).
11
11
  *
12
12
  * This module does NOT reuse `PlayState.step()` (`Game.play.step()`) — that
13
- * surface only advances the currently-FROZEN (paused) set of worlds and is a
13
+ * surface only advances the currently-FROZEN (paused) set of roots and is a
14
14
  * whole-call no-op while unpaused (see its doc comment in `runtime/game.ts`);
15
15
  * the spec review explicitly flagged it as the wrong seam. `renderOnce`
16
- * instead walks `game.worlds` directly and calls each world's own
16
+ * instead walks `game.roots` directly and calls each world's own
17
17
  * `WorldFrameHooks.runPhase` for exactly two phases.
18
18
  *
19
19
  * Also does NOT install anything by default — a caller must explicitly call
@@ -197,7 +197,7 @@ export interface VgaiRenderHarness {
197
197
  * {@link renderOnce}'s `renderableWorlds` skips, described here as policy
198
198
  * rather than merely warned about once to the console). Declared entries
199
199
  * come first, in declaration order; world-exclusion entries follow, in
200
- * `game.worlds` declaration order.
200
+ * `game.roots` declaration order.
201
201
  */
202
202
  excludedFromDeterminism(): string[];
203
203
  /**
@@ -279,9 +279,9 @@ const RENDER_ONLY_PHASES = [SystemPhase.PRE_RENDER, SystemPhase.RENDER] as const
279
279
  * `prePhysics`, `physics`, `postPhysics`, `gameLogic`, or `animation` phase
280
280
  * is ever touched, which is what makes this safe to call from a paused-or-
281
281
  * stopped clock without silently ticking gameplay. Phases are run as global
282
- * barriers across worlds (mirroring `GameInternal.runFrame`'s own phase-then-
282
+ * barriers across roots (mirroring `GameInternal.runFrame`'s own phase-then-
283
283
  * world nesting in `runtime/game.ts`): every world's `preRender` runs before
284
- * any world's `render`, in `game.worlds` declaration order.
284
+ * any world's `render`, in `game.roots` declaration order.
285
285
  *
286
286
  * Ordering within a phase mirrors `GameInternal.runFrame` EXACTLY (see its
287
287
  * doc comment in `runtime/game.ts`): the game-scoped `SystemRunner`
@@ -304,12 +304,12 @@ const RENDER_ONLY_PHASES = [SystemPhase.PRE_RENDER, SystemPhase.RENDER] as const
304
304
  * too, so warning twice would just be noise.
305
305
  */
306
306
  async function renderOnce(game: Game): Promise<void> {
307
- const worlds = renderableWorlds(game);
307
+ const roots = renderableWorlds(game);
308
308
  for (const phase of RENDER_ONLY_PHASES) {
309
309
  // Game-scoped systems first, then per-world frame hooks — the SAME order
310
310
  // GameInternal.runFrame uses (runtime/game.ts). See doc comment above.
311
311
  game.systems.runPhase(phase, 0);
312
- for (const world of worlds) {
312
+ for (const world of roots) {
313
313
  world.frame.runPhase(phase, 0);
314
314
  }
315
315
  }
@@ -321,13 +321,13 @@ interface RenderableWorld {
321
321
  readonly frame: WorldFrameHooks;
322
322
  }
323
323
 
324
- /** Filter `game.worlds` down to the ones {@link renderOnce} can actually
324
+ /** Filter `game.roots` down to the ones {@link renderOnce} can actually
325
325
  * drive (host-driven, with real `WorldFrameHooks`) — see that function's
326
326
  * doc comment for why an excluded world is warned about loudly, not
327
327
  * silently dropped. */
328
328
  function renderableWorlds(game: Game): RenderableWorld[] {
329
329
  const result: RenderableWorld[] = [];
330
- for (const world of game.worlds) {
330
+ for (const world of game.roots) {
331
331
  if (world.mounted.drivesOwnLoop) {
332
332
  warnUnrenderable(
333
333
  world.id,
@@ -357,12 +357,12 @@ function warnUnrenderable(worldLabel: string, reason: string): void {
357
357
  /**
358
358
  * I5 AC 5 policy text for the two conditions {@link renderableWorlds} skips —
359
359
  * shared so {@link VgaiRenderHarness.excludedFromDeterminism} names the SAME
360
- * worlds `renderOnce()` warns about, in the SAME words, rather than
360
+ * roots `renderOnce()` warns about, in the SAME words, rather than
361
361
  * maintaining a second, driftable description of the same two checks.
362
362
  */
363
363
  function computeWorldExclusionReasons(game: Game): string[] {
364
364
  const reasons: string[] = [];
365
- for (const world of game.worlds) {
365
+ for (const world of game.roots) {
366
366
  if (world.mounted.drivesOwnLoop) {
367
367
  reasons.push(
368
368
  `world "${world.id}" drives its own loop — cannot be frame-gated for deterministic ` +
@@ -494,12 +494,12 @@ export function installRenderControlHarness(
494
494
  }
495
495
 
496
496
  /**
497
- * Defensive assertion for the I2 AC "Pixi worlds are pinned to the WebGL
497
+ * Defensive assertion for the I2 AC "Pixi roots are pinned to the WebGL
498
498
  * renderer (not WebGPU) in render mode". In THIS engine that invariant
499
499
  * already holds unconditionally — `world2d/pixi-surface.ts`'s
500
500
  * `createPixiSurface` hardcodes `preference: 'webgl'` on every
501
501
  * `Application.init()` call it makes, and `setup/setup-renderer.ts` never
502
- * constructs a `WebGPURenderer` for threejs worlds either — so there is no
502
+ * constructs a `WebGPURenderer` for threejs roots either — so there is no
503
503
  * live WebGPU code path for a first-party render-mode page to disable.
504
504
  * This helper exists for a render-mode installer that mounts a CUSTOM/
505
505
  * foreign pixi adapter (`create-runtime.ts`'s `{ module }` pixi path) this
@@ -46,7 +46,7 @@ export function createMulberry32(seed: number): () => number {
46
46
  * Replace the global `Math.random` with a seeded, deterministic generator.
47
47
  * Idempotent to call more than once (each call re-seeds from scratch — the
48
48
  * last call wins), which matters for HMR-style re-execution the same way
49
- * `main.ts`'s `registerWorldKind` guard does elsewhere in this runtime.
49
+ * `main.ts`'s `registerAdapterSurface` guard does elsewhere in this runtime.
50
50
  */
51
51
  export function installDeterministicRandom(seed: number): void {
52
52
  Math.random = createMulberry32(seed);
@@ -12,26 +12,40 @@
12
12
  *
13
13
  * This file is plain, react-free TypeScript any consumer could use — no
14
14
  * react import here, or anywhere under `runtime/` (the react-facing
15
- * `useGameState` hook, which DOES import react, is deliberately colocated
16
- * with the `mountUI` seam instead — see `packages/editor/template/src/
17
- * ui/game-state.tsx`).
15
+ * `useGameState` hook, which DOES import React, lives at
16
+ * `packages/engine/src/react/game-state.tsx`).
17
+ *
18
+ * SECOND trigger for `bump()` (`Game.registerWorld`, `runtime/game.ts`): the
19
+ * `roots` list is also state a `useGameState` selector can read
20
+ * (`g.roots.map(...)`, the T6.2 two-world-compose gate), and it changes
21
+ * OUTSIDE the frame loop — `registerWorld` is called as each world finishes
22
+ * mounting, which can happen well before the host's loop has ticked even
23
+ * once. Without an immediate notification here, a selector that first reads
24
+ * `g.roots` before every world has registered stays stuck on that stale
25
+ * snapshot until the next completed frame — which, on a slow/contended host
26
+ * or a backgrounded tab, may be arbitrarily delayed. See `registerWorld`'s
27
+ * own doc comment for the concrete CI failure this closes.
18
28
  */
19
29
 
20
30
  /** Frame-versioned, react-free subscription surface — `docs/REACT-STATE-BRIDGE.md` §2. */
21
31
  export interface GameStateBridge {
22
- /** Monotonic; bumped once per completed `runFrame`. Starts at 0 before the
23
- * first frame has ever completed. */
32
+ /** Monotonic; bumped once per completed `runFrame`, AND once per
33
+ * `Game.registerWorld` call (world-list changes are observable state too
34
+ * — see this file's module doc comment). Starts at 0 before the first of
35
+ * either has happened. Never treat this as a literal frame COUNT — only
36
+ * "did it change" is a contract any consumer may rely on. */
24
37
  readonly frameVersion: number;
25
- /** Notified at most once per frame, after ALL phases of ALL worlds (and
38
+ /** Notified at most once per frame, after ALL phases of ALL roots (and
26
39
  * their `endFrame` hooks) have run. Returns an unsubscribe function. */
27
40
  subscribe(onFrame: () => void): () => void;
28
41
  }
29
42
 
30
- /** Host-internal extension of {@link GameStateBridge}: adds `bump`, the
31
- * method `GameInternal.runFrame` calls at its tail. NOT part of the
32
- * game-facing `Game.state` surface (typed as the narrower
43
+ /** Host-internal extension of {@link GameStateBridge}: adds `bump`, called
44
+ * both by `GameInternal.runFrame` at its tail AND by `Game.registerWorld`
45
+ * when the world list changes (see this file's module doc comment). NOT
46
+ * part of the game-facing `Game.state` surface (typed as the narrower
33
47
  * `GameStateBridge` there) — games/components/hooks never call `bump`
34
- * directly; only the frame executor does. */
48
+ * directly; only the frame executor and the world registry do. */
35
49
  export interface GameStateBridgeInternal extends GameStateBridge {
36
50
  /** Bump `frameVersion` by one and notify every current subscriber, in
37
51
  * subscription order. Subscriber errors are isolated (per-subscriber