@vgai/engine 0.5.21 → 0.5.23

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 (339) hide show
  1. package/README.md +6 -3
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +2 -4
  4. package/dist/adapter/adapter-surface.d.ts +1 -1
  5. package/dist/adapter/adapter-surface.js +1 -1
  6. package/dist/adapter/authoring.d.ts +19 -21
  7. package/dist/adapter/authoring.d.ts.map +1 -1
  8. package/dist/adapter/authoring.js +2 -2
  9. package/dist/adapter/binding.d.ts +341 -0
  10. package/dist/adapter/binding.d.ts.map +1 -0
  11. package/dist/adapter/binding.js +148 -0
  12. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
  13. package/dist/adapter/colyseus-networking-adapter.js +23 -4
  14. package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
  15. package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
  16. package/dist/adapter/entrypoint-selection-readers.js +63 -0
  17. package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
  18. package/dist/adapter/entrypoint-selection-source.js +1 -44
  19. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  20. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
  21. package/dist/adapter/host-context.d.ts +46 -15
  22. package/dist/adapter/host-context.d.ts.map +1 -1
  23. package/dist/adapter/host-context.js +2 -9
  24. package/dist/adapter/index.d.ts +11 -12
  25. package/dist/adapter/index.d.ts.map +1 -1
  26. package/dist/adapter/index.js +9 -10
  27. package/dist/adapter/ingest/game-contract.d.ts +0 -3
  28. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  29. package/dist/adapter/ingest/game-contract.js +0 -3
  30. package/dist/adapter/ingest/scene-capture.d.ts +19 -23
  31. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  32. package/dist/adapter/ingest/scene-capture.js +143 -17
  33. package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
  34. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  35. package/dist/adapter/manifest-interpreter.d.ts +59 -0
  36. package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
  37. package/dist/adapter/manifest-interpreter.js +50 -0
  38. package/dist/adapter/native-debug-module.d.ts +71 -3
  39. package/dist/adapter/native-debug-module.d.ts.map +1 -1
  40. package/dist/adapter/native-debug-module.js +146 -10
  41. package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
  42. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
  43. package/dist/adapter/rapier-physics-adapter.js +50 -36
  44. package/dist/adapter/renderer-config.d.ts +3 -3
  45. package/dist/adapter/renderer-config.js +3 -3
  46. package/dist/adapter/root-adapter.d.ts +7 -7
  47. package/dist/adapter/root-adapter.js +4 -4
  48. package/dist/adapter/system-adapter.d.ts +45 -7
  49. package/dist/adapter/system-adapter.d.ts.map +1 -1
  50. package/dist/adapter/system-seam-contract.d.ts +3 -3
  51. package/dist/adapter/system-seam-contract.js +3 -3
  52. package/dist/adapter/system-slot.d.ts +168 -0
  53. package/dist/adapter/system-slot.d.ts.map +1 -0
  54. package/dist/adapter/system-slot.js +229 -0
  55. package/dist/adapter/transform.d.ts +11 -1
  56. package/dist/adapter/transform.d.ts.map +1 -1
  57. package/dist/ai/navigation.d.ts +17 -1
  58. package/dist/ai/navigation.d.ts.map +1 -1
  59. package/dist/ai/navigation.js +26 -5
  60. package/dist/animation/anim-graph-types.d.ts +11 -3
  61. package/dist/animation/anim-graph-types.d.ts.map +1 -1
  62. package/dist/animation/theatre-clock-binding.d.ts +4 -4
  63. package/dist/animation/theatre-clock-binding.js +4 -4
  64. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  65. package/dist/animation/xstate-animation-binding.js +2 -2
  66. package/dist/animation/xstate-animation-meta.d.ts +13 -0
  67. package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
  68. package/dist/animation/xstate-animation-meta.js +14 -0
  69. package/dist/asset-formats/index.d.ts +4 -7
  70. package/dist/asset-formats/index.d.ts.map +1 -1
  71. package/dist/asset-formats/index.js +4 -7
  72. package/dist/asset-formats/render-env.d.ts +5 -8
  73. package/dist/asset-formats/render-env.d.ts.map +1 -1
  74. package/dist/asset-formats/render-env.js +3 -6
  75. package/dist/asset-parse-error.d.ts +2 -5
  76. package/dist/asset-parse-error.d.ts.map +1 -1
  77. package/dist/asset-parse-error.js +2 -5
  78. package/dist/audio/bus-mixer.d.ts +101 -0
  79. package/dist/audio/bus-mixer.d.ts.map +1 -0
  80. package/dist/audio/bus-mixer.js +115 -0
  81. package/dist/canvas-react/index.d.ts +5 -12
  82. package/dist/canvas-react/index.d.ts.map +1 -1
  83. package/dist/canvas-react/index.js +5 -12
  84. package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
  85. package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
  86. package/dist/canvas-react/pixi-react-root-factory.js +274 -36
  87. package/dist/core/countdown-timer.d.ts +118 -0
  88. package/dist/core/countdown-timer.d.ts.map +1 -0
  89. package/dist/core/countdown-timer.js +137 -0
  90. package/dist/core/deferred-commands.d.ts +127 -0
  91. package/dist/core/deferred-commands.d.ts.map +1 -0
  92. package/dist/core/deferred-commands.js +132 -0
  93. package/dist/core/frame-pacing.d.ts +1 -1
  94. package/dist/core/frame-pacing.js +2 -2
  95. package/dist/core/game-loop.d.ts +1 -3
  96. package/dist/core/game-loop.d.ts.map +1 -1
  97. package/dist/core/game-loop.js +1 -3
  98. package/dist/core/seeded-random.d.ts +1 -1
  99. package/dist/core/sim-clock.d.ts +19 -8
  100. package/dist/core/sim-clock.d.ts.map +1 -1
  101. package/dist/core/sim-clock.js +18 -7
  102. package/dist/core/types.d.ts +1 -3
  103. package/dist/core/types.d.ts.map +1 -1
  104. package/dist/defaults.d.ts +6 -14
  105. package/dist/defaults.d.ts.map +1 -1
  106. package/dist/defaults.js +6 -14
  107. package/dist/dev/instruments.d.ts +38 -11
  108. package/dist/dev/instruments.d.ts.map +1 -1
  109. package/dist/dev/instruments.js +81 -11
  110. package/dist/dev/register-render-vitals.d.ts +1 -4
  111. package/dist/dev/register-render-vitals.d.ts.map +1 -1
  112. package/dist/dev/register-render-vitals.js +1 -4
  113. package/dist/dev/render-debug-adapter.d.ts +2 -3
  114. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  115. package/dist/dev/render-debug-adapter.js +2 -3
  116. package/dist/dev/render-vitals.d.ts +3 -3
  117. package/dist/dev/render-vitals.js +3 -3
  118. package/dist/dev/webgl-frame-capture.d.ts +1 -1
  119. package/dist/dev/webgl-frame-capture.js +1 -1
  120. package/dist/index.d.ts +2 -5
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +2 -4
  123. package/dist/input/host-pointer.d.ts +122 -0
  124. package/dist/input/host-pointer.d.ts.map +1 -0
  125. package/dist/input/host-pointer.js +160 -0
  126. package/dist/input/input-manager.d.ts +33 -5
  127. package/dist/input/input-manager.d.ts.map +1 -1
  128. package/dist/input/input-manager.js +48 -13
  129. package/dist/input/rebind-controller.d.ts.map +1 -1
  130. package/dist/input/rebind-controller.js +6 -8
  131. package/dist/input/schema.d.ts.map +1 -1
  132. package/dist/input/schema.js +56 -28
  133. package/dist/manifest/filename.d.ts.map +1 -1
  134. package/dist/manifest/filename.js +8 -12
  135. package/dist/manifest/load.d.ts +10 -10
  136. package/dist/manifest/load.d.ts.map +1 -1
  137. package/dist/manifest/load.js +9 -6
  138. package/dist/manifest/schema.d.ts +17 -21
  139. package/dist/manifest/schema.d.ts.map +1 -1
  140. package/dist/manifest/schema.js +45 -35
  141. package/dist/physics/collider-dimensions.d.ts +8 -12
  142. package/dist/physics/collider-dimensions.d.ts.map +1 -1
  143. package/dist/physics/collider-dimensions.js +8 -12
  144. package/dist/pixi/scene-capture.d.ts +11 -13
  145. package/dist/pixi/scene-capture.d.ts.map +1 -1
  146. package/dist/react/world-state.d.ts +1 -1
  147. package/dist/react/world-state.d.ts.map +1 -1
  148. package/dist/render/directional-shadow-fit.d.ts +88 -0
  149. package/dist/render/directional-shadow-fit.d.ts.map +1 -0
  150. package/dist/render/directional-shadow-fit.js +133 -0
  151. package/dist/render/environment-capture.d.ts +68 -0
  152. package/dist/render/environment-capture.d.ts.map +1 -0
  153. package/dist/render/environment-capture.js +90 -0
  154. package/dist/render/ibl-override-material.d.ts +97 -0
  155. package/dist/render/ibl-override-material.d.ts.map +1 -0
  156. package/dist/render/ibl-override-material.js +114 -0
  157. package/dist/render/light-camera-factory.d.ts +5 -7
  158. package/dist/render/light-camera-factory.d.ts.map +1 -1
  159. package/dist/render/light-camera-factory.js +8 -11
  160. package/dist/render/material-factory.js +1 -1
  161. package/dist/render/render-batch-system.d.ts.map +1 -1
  162. package/dist/render/render-features.d.ts +17 -6
  163. package/dist/render/render-features.d.ts.map +1 -1
  164. package/dist/render/render-features.js +0 -28
  165. package/dist/runtime/create-runtime.d.ts +34 -25
  166. package/dist/runtime/create-runtime.d.ts.map +1 -1
  167. package/dist/runtime/create-runtime.js +218 -93
  168. package/dist/runtime/debug-registry.d.ts +77 -8
  169. package/dist/runtime/debug-registry.d.ts.map +1 -1
  170. package/dist/runtime/debug-registry.js +3 -3
  171. package/dist/runtime/dev-build.d.ts +2 -2
  172. package/dist/runtime/dev-build.js +2 -2
  173. package/dist/runtime/game-input-seams.d.ts +51 -0
  174. package/dist/runtime/game-input-seams.d.ts.map +1 -0
  175. package/dist/runtime/game-input-seams.js +86 -0
  176. package/dist/runtime/game.d.ts +104 -40
  177. package/dist/runtime/game.d.ts.map +1 -1
  178. package/dist/runtime/game.js +119 -61
  179. package/dist/runtime/mount-game.d.ts +0 -16
  180. package/dist/runtime/mount-game.d.ts.map +1 -1
  181. package/dist/runtime/mount-game.js +26 -41
  182. package/dist/runtime/mount-manifest.d.ts +22 -14
  183. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  184. package/dist/runtime/mount-manifest.js +22 -20
  185. package/dist/runtime/playtest.d.ts +22 -0
  186. package/dist/runtime/playtest.d.ts.map +1 -0
  187. package/dist/runtime/playtest.js +12 -0
  188. package/dist/runtime/state-bridge.d.ts +2 -3
  189. package/dist/runtime/state-bridge.d.ts.map +1 -1
  190. package/dist/runtime/state-bridge.js +1 -0
  191. package/dist/setup/setup-audio.d.ts +12 -0
  192. package/dist/setup/setup-audio.d.ts.map +1 -1
  193. package/dist/setup/setup-audio.js +9 -10
  194. package/dist/setup/setup-renderer.d.ts +2 -25
  195. package/dist/setup/setup-renderer.d.ts.map +1 -1
  196. package/dist/setup/setup-renderer.js +2 -31
  197. package/dist/world3d-react/index.d.ts +15 -25
  198. package/dist/world3d-react/index.d.ts.map +1 -1
  199. package/dist/world3d-react/index.js +15 -25
  200. package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
  201. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
  202. package/dist/world3d-react/r3f-root-factory.js +403 -57
  203. package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
  204. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  205. package/dist/world3d-react/rapier-physics-bridge.js +143 -58
  206. package/package.json +1 -1
  207. package/schemas/engine-capabilities.json +16 -14
  208. package/schemas/vgai-project.schema.json +35 -26
  209. package/src/adapter/adapter-module.ts +2 -4
  210. package/src/adapter/adapter-surface.ts +1 -1
  211. package/src/adapter/authoring.ts +19 -21
  212. package/src/adapter/binding.ts +468 -0
  213. package/src/adapter/colyseus-networking-adapter.ts +20 -5
  214. package/src/adapter/entrypoint-selection-readers.ts +66 -0
  215. package/src/adapter/entrypoint-selection-source.ts +1 -40
  216. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
  217. package/src/adapter/host-context.ts +45 -15
  218. package/src/adapter/index.ts +23 -11
  219. package/src/adapter/ingest/game-contract.ts +0 -3
  220. package/src/adapter/ingest/scene-capture.ts +190 -39
  221. package/src/adapter/ingest/visible-capture-window.ts +35 -0
  222. package/src/adapter/manifest-interpreter.ts +64 -0
  223. package/src/adapter/native-debug-module.ts +248 -15
  224. package/src/adapter/rapier-physics-adapter.ts +76 -20
  225. package/src/adapter/renderer-config.ts +3 -3
  226. package/src/adapter/root-adapter.ts +7 -7
  227. package/src/adapter/system-adapter.ts +43 -8
  228. package/src/adapter/system-seam-contract.ts +3 -3
  229. package/src/adapter/system-slot.ts +291 -0
  230. package/src/adapter/transform.ts +18 -1
  231. package/src/ai/navigation.ts +30 -3
  232. package/src/animation/anim-graph-types.ts +11 -3
  233. package/src/animation/theatre-clock-binding.ts +4 -4
  234. package/src/animation/xstate-animation-binding.ts +2 -2
  235. package/src/animation/xstate-animation-meta.ts +16 -0
  236. package/src/asset-formats/index.ts +4 -7
  237. package/src/asset-formats/render-env.ts +3 -6
  238. package/src/asset-parse-error.ts +2 -5
  239. package/src/audio/bus-mixer.ts +161 -0
  240. package/src/canvas-react/index.ts +5 -21
  241. package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
  242. package/src/core/countdown-timer.ts +188 -0
  243. package/src/core/deferred-commands.ts +174 -0
  244. package/src/core/frame-pacing.ts +2 -2
  245. package/src/core/game-loop.ts +1 -3
  246. package/src/core/seeded-random.ts +1 -1
  247. package/src/core/sim-clock.ts +19 -8
  248. package/src/core/types.ts +1 -3
  249. package/src/defaults.ts +6 -14
  250. package/src/dev/instruments.ts +108 -11
  251. package/src/dev/register-render-vitals.ts +1 -4
  252. package/src/dev/render-debug-adapter.ts +2 -3
  253. package/src/dev/render-vitals.ts +3 -3
  254. package/src/dev/webgl-frame-capture.ts +1 -1
  255. package/src/index.ts +2 -5
  256. package/src/input/host-pointer.ts +230 -0
  257. package/src/input/input-manager.ts +49 -13
  258. package/src/input/input-types.ts +1 -1
  259. package/src/input/rebind-controller.ts +6 -8
  260. package/src/input/schema.ts +216 -188
  261. package/src/manifest/filename.ts +8 -12
  262. package/src/manifest/load.ts +17 -13
  263. package/src/manifest/schema.ts +55 -47
  264. package/src/physics/collider-dimensions.ts +8 -12
  265. package/src/pixi/scene-capture.ts +12 -15
  266. package/src/react/world-state.tsx +1 -1
  267. package/src/render/directional-shadow-fit.ts +156 -0
  268. package/src/render/environment-capture.ts +102 -0
  269. package/src/render/ibl-override-material.ts +170 -0
  270. package/src/render/light-camera-factory.ts +8 -11
  271. package/src/render/material-factory.ts +1 -1
  272. package/src/render/render-batch-system.ts +14 -6
  273. package/src/render/render-features.ts +17 -35
  274. package/src/runtime/create-runtime.ts +270 -108
  275. package/src/runtime/debug-registry.ts +84 -8
  276. package/src/runtime/dev-build.ts +2 -2
  277. package/src/runtime/game-input-seams.ts +108 -0
  278. package/src/runtime/game.ts +231 -85
  279. package/src/runtime/mount-game.ts +31 -57
  280. package/src/runtime/mount-manifest.ts +47 -36
  281. package/src/runtime/playtest.ts +22 -0
  282. package/src/runtime/state-bridge.ts +3 -3
  283. package/src/setup/setup-audio.ts +21 -11
  284. package/src/setup/setup-renderer.ts +2 -61
  285. package/src/world3d-react/index.ts +15 -31
  286. package/src/world3d-react/r3f-root-factory.tsx +451 -60
  287. package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
  288. package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
  289. package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
  290. package/dist/adapter/setup-three-root-adapter.js +0 -908
  291. package/dist/animation/clip-map.d.ts +0 -12
  292. package/dist/animation/clip-map.d.ts.map +0 -1
  293. package/dist/animation/clip-map.js +0 -31
  294. package/dist/asset-registry.d.ts +0 -38
  295. package/dist/asset-registry.d.ts.map +0 -1
  296. package/dist/asset-registry.js +0 -66
  297. package/dist/canvas-react/engine-bridge.d.ts +0 -45
  298. package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
  299. package/dist/canvas-react/engine-bridge.js +0 -45
  300. package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
  301. package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
  302. package/dist/canvas-react/pixi-react-adapter.js +0 -294
  303. package/dist/canvas-react/world-context.d.ts +0 -98
  304. package/dist/canvas-react/world-context.d.ts.map +0 -1
  305. package/dist/canvas-react/world-context.js +0 -173
  306. package/dist/dev/debug-draw.d.ts +0 -24
  307. package/dist/dev/debug-draw.d.ts.map +0 -1
  308. package/dist/dev/debug-draw.js +0 -73
  309. package/dist/render/auto-batcher.d.ts +0 -34
  310. package/dist/render/auto-batcher.d.ts.map +0 -1
  311. package/dist/render/auto-batcher.js +0 -140
  312. package/dist/render/lod.d.ts +0 -13
  313. package/dist/render/lod.d.ts.map +0 -1
  314. package/dist/render/lod.js +0 -16
  315. package/dist/runtime/types.d.ts +0 -303
  316. package/dist/runtime/types.d.ts.map +0 -1
  317. package/dist/runtime/types.js +0 -1
  318. package/dist/world3d-react/engine-bridge.d.ts +0 -47
  319. package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
  320. package/dist/world3d-react/engine-bridge.js +0 -73
  321. package/dist/world3d-react/r3f-adapter.d.ts +0 -58
  322. package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
  323. package/dist/world3d-react/r3f-adapter.js +0 -634
  324. package/dist/world3d-react/world-context.d.ts +0 -182
  325. package/dist/world3d-react/world-context.d.ts.map +0 -1
  326. package/dist/world3d-react/world-context.js +0 -235
  327. package/src/adapter/setup-three-root-adapter.ts +0 -1032
  328. package/src/animation/clip-map.ts +0 -34
  329. package/src/asset-registry.ts +0 -89
  330. package/src/canvas-react/engine-bridge.ts +0 -59
  331. package/src/canvas-react/pixi-react-adapter.tsx +0 -356
  332. package/src/canvas-react/world-context.ts +0 -253
  333. package/src/dev/debug-draw.ts +0 -80
  334. package/src/render/auto-batcher.ts +0 -168
  335. package/src/render/lod.ts +0 -17
  336. package/src/runtime/types.ts +0 -328
  337. package/src/world3d-react/engine-bridge.ts +0 -86
  338. package/src/world3d-react/r3f-adapter.tsx +0 -717
  339. package/src/world3d-react/world-context.ts +0 -358
@@ -16,7 +16,7 @@ import { createDebugRegistry, DebugError, registerDebugRegistry, } from './debug
16
16
  import { createGameplayRngTrap, registerGameplayRngTrapControl } from './gameplay-rng-trap';
17
17
  import { createStateBridge } from './state-bridge';
18
18
  /**
19
- * WO-P13 — the tail of `PHASE_ORDER` that presents rather than simulates, and
19
+ * The tail of `PHASE_ORDER` that presents rather than simulates, and
20
20
  * therefore runs once per DISPLAY frame (`runRenderFrameImpl`) rather than
21
21
  * once per fixed substep. The same two phases `runTicks`' `skipRenderPhases`
22
22
  * fast-forward skips and `render-control.ts`'s `renderOnce()` drives — one
@@ -31,7 +31,7 @@ const DISPLAY_RATE_PHASES = PHASE_ORDER.filter((phase) => phase === SystemPhase.
31
31
  * slice or later ones) gets identical throw behavior.
32
32
  */
33
33
  export function createRootInstance(init) {
34
- const { id, kind, pausable = true, adapter, mounted, scene, stage, container, physics, collisions, physics2d, camera, frame, } = init;
34
+ const { id, kind, pausable = true, adapter, mounted, scene, stage, container, physics, collisions, physics2d, camera, frame, binding = null, } = init;
35
35
  // A three world with no scene has nothing for `threeScene()` to return —
36
36
  // fail loudly HERE, at construction, rather than letting `threeScene()`
37
37
  // throw its generic "not a three world" message later for a world whose
@@ -64,11 +64,11 @@ export function createRootInstance(init) {
64
64
  // read, so this wraps `mounted.dispose` in place (mutating the SAME mount
65
65
  // object every holder of `mounted` shares — calling `mounted.dispose()`
66
66
  // directly, exactly like calling `world.mounted.dispose()`, trips this)
67
- // to flip a private flag, and wraps the frame hooks so they silently no-op
68
- // once that flag is set. `runFrame` itself needs no knowledge of disposal
69
- // a disposed world is skipped by construction from the next call
70
- // onward. (The opaque-world `mounted.update` fallback path is unaffected
71
- // by this guard no opaque-mount two-world scenario exists yet to need it.)
67
+ // to flip a flag this instance exposes as `disposed`, and wraps the frame
68
+ // hooks so they silently no-op once it is set. `runFrame` reads `disposed`
69
+ // and skips the world outright, which is what also covers the OPAQUE
70
+ // `mounted.update` fallback — the path every three root takes now that a
71
+ // mount is a plain `RootAdapter` with no phase-partitioned entry point.
72
72
  let disposed = false;
73
73
  const originalDispose = mounted.dispose.bind(mounted);
74
74
  mounted.dispose = () => {
@@ -100,6 +100,10 @@ export function createRootInstance(init) {
100
100
  physics2d,
101
101
  camera,
102
102
  frame: guardedFrame,
103
+ binding,
104
+ get disposed() {
105
+ return disposed;
106
+ },
103
107
  threeScene() {
104
108
  if (kind !== 'three' || !scene) {
105
109
  throw new Error(`RootInstance "${id}" (kind: ${kind}): threeScene() requested but this world is not ` +
@@ -130,22 +134,6 @@ export function createRootInstance(init) {
130
134
  },
131
135
  };
132
136
  }
133
- /**
134
- * Type guard for whether a `MountedThreeRoot` is a first-party
135
- * `SetupThreeRootAdapter` mount (has a live `GameContext` at `.ctx`). Used to
136
- * decide whether a world's `physics`/`collisions`/`camera` can be populated
137
- * from it — an external
138
- * adapter's mount has none of these first-party handles.
139
- *
140
- * Checks the `firstParty: true` brand (checklist item 1), NOT `'ctx' in
141
- * mounted` — a foreign mount may carry an unrelated `ctx` key, so a
142
- * structural `'ctx' in mounted` check would misfire. The probe is a plain property read, not an
143
- * `instanceof`/value import of `setup-three-root-adapter.ts` — the
144
- * `MountedSetupThreeRoot` import above stays type-only.
145
- */
146
- export function isFirstPartyMounted(mounted) {
147
- return mounted.firstParty === true;
148
- }
149
137
  /**
150
138
  * Read an owner's Rapier handles, treating an absent pair as "this owner holds
151
139
  * no rigid bodies" — the honest reading for a world (R3F, or a bare
@@ -162,15 +150,14 @@ function readRapierHandles(owner) {
162
150
  * only *when*; this is the *what*, and it lives here because it is the runtime
163
151
  * that knows about Rapier and shared geometry.
164
152
  *
165
- * The order mirrors `adapter/setup-three-root-adapter.ts`'s world teardown for
153
+ * The order mirrors `adapter/world3d-react/r3f-root-factory.tsx`'s world teardown for
166
154
  * ONE subtree. Within the physics step,
167
155
  * `rapierWorld.removeRigidBody(body)` comes BEFORE `physics.remove(node)`: the
168
156
  * registry's `remove()` only drops index entries, so reversing the two leaks
169
157
  * the Rapier body.
170
158
  *
171
- * `owners` is every world that could own part of the subtree `createGame`
172
- * passes all of its first-party three roots as their `GameContext`, a bare
173
- * adapter mount passes its own ctx. `physics.get` is a no-op for a node the
159
+ * `owners` is every world that could own part of the subtree. `physics.get`
160
+ * is a no-op for a node the
174
161
  * owner does not own, so offering the subtree to each is safe.
175
162
  *
176
163
  * Safe on an object already removed or already disposed: `removeFromParent` on
@@ -212,13 +199,17 @@ export function disposeDebrisSubtree(obj, owners) {
212
199
  }
213
200
  }
214
201
  /**
215
- * The {@link DebrisOwner}s one registered world contributes: its `GameContext`
216
- * when the mount is first-party, else nothing. Written as a standalone function
202
+ * The {@link DebrisOwner}s one registered world contributes. Written as a
203
+ * standalone function
217
204
  * so `createGame`'s clock disposer is one line and the "which mounts count"
218
205
  * rule has exactly one home.
219
206
  */
220
- function debrisOwnersOf(world) {
221
- return isFirstPartyMounted(world.mounted) ? [world.mounted.ctx] : [];
207
+ function debrisOwnersOf(_world) {
208
+ // No mount carries first-party Rapier handles: physics is a declared
209
+ // system built inside the world's own tree, and the library owns its
210
+ // bodies' lifecycles there. The owner list stays as the disposal seam's
211
+ // shape; today it is always empty.
212
+ return [];
222
213
  }
223
214
  /**
224
215
  * Construct the (host-internal) Game shell. Callers: `createGameRuntime`
@@ -233,7 +224,7 @@ export function createGame(opts) {
233
224
  const input = new InputManager();
234
225
  const stateBridge = createStateBridge();
235
226
  // D15 (T-D15.1) — the game-scoped seeded-random surface every world's
236
- // `ctx.random` aliases (see `setup-three-root-adapter.ts`'s `ctx.random =
227
+ // `ctx.random` aliases (see `world3d-react/r3f-root-factory.tsx`'s `ctx.random =
237
228
  // ...`, wired the same way `ctx.debug` is just below). Constructed
238
229
  // unconditionally (cheap — a handful of closures) regardless of whether
239
230
  // this project ever declares `determinism.seededRandom`; only the BOOT
@@ -266,7 +257,7 @@ export function createGame(opts) {
266
257
  // the CURRENT values.
267
258
  let tick = 0;
268
259
  let simT = 0;
269
- // WO-P13 — the display-rate half. `renderAlpha` is the last alpha
260
+ // The display-rate half. `renderAlpha` is the last alpha
270
261
  // `runRenderFrameImpl` presented at (0 until a host drives one); the set is
271
262
  // the `RenderStepped`-shaped registry `Game.onRenderStep` feeds. Deliberately
272
263
  // NOT beside `tick`/`simT` in meaning: neither of these ever advances sim
@@ -282,7 +273,7 @@ export function createGame(opts) {
282
273
  //
283
274
  // The disposer is supplied HERE rather than inside the clock because
284
275
  // `core/sim-clock.ts` deliberately knows nothing about Rapier or shared
285
- // geometry. It mirrors `setup-three-root-adapter.ts`'s world teardown
276
+ // geometry. It mirrors `world3d-react/r3f-root-factory.tsx`'s world teardown
286
277
  // ordering for ONE subtree.
287
278
  const simClock = createSimClock({
288
279
  // Every mount that could own part of the subtree is offered it:
@@ -335,7 +326,17 @@ export function createGame(opts) {
335
326
  // above's "once per game instance" idiom.
336
327
  const warnedSystemAdapterKeys = new Set();
337
328
  const systemAdapterListeners = new Set();
338
- // 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
329
+ /** Per-root slots installed by `installDeclaredSystemAdapters` the native
330
+ * module surface's static `systems` declaration. Merged BEFORE the same
331
+ * root's live `mounted.systems` below, so during migration a lingering
332
+ * component registration for a declared slot is shadowed (with the
333
+ * standard warning) rather than silently winning by running later. */
334
+ const declaredSystemAdapters = new Map();
335
+ /** Per-root POSITIVE ABSENCES from the same declaration — `absent(reason)`
336
+ * slots. Nothing binds them (there is nothing to bind); they are kept so a
337
+ * reader can tell an answered absence from an unasked question. */
338
+ const declaredAbsences = new Map();
339
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one cohesive merge-with-collision-report walk (per-world × per-source × per-key); splitting the collision-warn branch out would obscure that it's part of the same pass, not reduce real complexity
339
340
  function computeSystemAdapters() {
340
341
  // Debug is game-scoped: React hooks, probes, and the built-in time
341
342
  // provider all register with the one registry created above, regardless
@@ -345,10 +346,7 @@ export function createGame(opts) {
345
346
  // intentional shared registration it is.
346
347
  const result = { debug: debugRegistry.adapter };
347
348
  const ownerRootId = new Map([['debug', '(game)']]);
348
- for (const world of roots) {
349
- const adapters = world.mounted.systems;
350
- if (!adapters)
351
- continue;
349
+ const merge = (owner, adapters, quietKeys) => {
352
350
  for (const key of Object.keys(adapters)) {
353
351
  if (adapters[key] === undefined)
354
352
  continue;
@@ -360,18 +358,35 @@ export function createGame(opts) {
360
358
  // collision, so it must never warn.
361
359
  if (result[key] === adapters[key])
362
360
  continue;
361
+ // A world's own DECLARED slot overriding that same world's
362
+ // substrate-seeded default (the three lane pre-seeds physics/audio/
363
+ // renderDebug into `mounted.systems`) is the door working as
364
+ // intended, not a collision — same silence `ctx.
365
+ // registerSystemAdapter` gives the same override. Cross-root
366
+ // collisions still warn.
367
+ if (quietKeys?.has(key))
368
+ continue;
363
369
  if (!warnedSystemAdapterKeys.has(key)) {
364
370
  warnedSystemAdapterKeys.add(key);
365
371
  // biome-ignore lint/suspicious/noConsole: structured, greppable — mirrors this file's own reportGateShortfallOnce's deliberate direct console.warn just above
366
- console.warn(`[game] systemAdapters: "${key}" is registered by both world "${existingOwner}" and ` +
367
- `world "${world.id}" — the FIRST registration ("${existingOwner}") wins; the later ` +
372
+ console.warn(`[game] systemAdapters: "${key}" is registered by both ${existingOwner} and ` +
373
+ `${owner} — the FIRST registration (${existingOwner}) wins; the later ` +
368
374
  'one is shadowed (game-scoped system adapters).');
369
375
  }
370
376
  continue;
371
377
  }
372
378
  // 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
373
379
  result[key] = adapters[key];
374
- ownerRootId.set(key, world.id);
380
+ ownerRootId.set(key, owner);
381
+ }
382
+ };
383
+ for (const world of roots) {
384
+ const declared = declaredSystemAdapters.get(world.id);
385
+ if (declared)
386
+ merge(`world "${world.id}" (declared systems export)`, declared);
387
+ const adapters = world.mounted.systems;
388
+ if (adapters) {
389
+ merge(`world "${world.id}"`, adapters, declared ? new Set(Object.keys(declared)) : undefined);
375
390
  }
376
391
  }
377
392
  return result;
@@ -405,6 +420,14 @@ export function createGame(opts) {
405
420
  // 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
406
421
  function setRootGates(next) {
407
422
  for (const world of roots) {
423
+ // A disposed world stays in `roots` (there is no `unregisterRoot`), and
424
+ // its adapter's `setPaused`/`systems.audio` reach a renderer, ticker or
425
+ // audio graph that `dispose()` already released — the same reason
426
+ // `runFrame`/`runRenderFrame`/`runTicks` skip it. Without this, a
427
+ // pause/resume after a partial teardown calls into freed resources, and
428
+ // the audio leg re-mutes a context that no longer exists.
429
+ if (world.disposed)
430
+ continue;
408
431
  if (!world.pausable)
409
432
  continue; // pausable:false roots are untouched by design
410
433
  if (world.mounted.drivesOwnLoop) {
@@ -435,14 +458,14 @@ export function createGame(opts) {
435
458
  if (rngTrapEnabled)
436
459
  rngTrap.enable();
437
460
  profiler.beginFrame();
438
- // D15/T-D15.4 + WO-P13: the render-phase skip. Two callers set it, for the
461
+ // The render-phase skip. Two callers set it, for the
439
462
  // same reason — this substep is not the thing that paints. `runTicks`'s
440
463
  // `render: 'none'|'last'` fast-forward sets it on every tick it doesn't
441
464
  // want to paint (see `runTicks`'s doc comment on `GameInternal`), and a
442
465
  // DISPLAY-RATE host sets it on every substep because `runRenderFrame`
443
- // paints once per real frame instead. Unlike `onlyFrozen` below it is no
444
- // longer internal-only: it is part of the public `GameInternal.runFrame`
445
- // signature, since an external host is now one of those two callers.
466
+ // paints once per real frame instead. Unlike `onlyFrozen` below it is not
467
+ // internal-only: it is part of the public `GameInternal.runFrame`
468
+ // signature, since an external host is one of those two callers.
446
469
  const skipRenderPhases = frameOpts?.skipRenderPhases ?? false;
447
470
  // `onlyFrozen` is internal-only (not part of the public `GameInternal.runFrame`
448
471
  // signature — no external caller sets it) — `Game.play.step()` below is the
@@ -460,6 +483,8 @@ export function createGame(opts) {
460
483
  inputFrameActive = false;
461
484
  for (let i = 0; i < n; i++) {
462
485
  const world = roots[i];
486
+ if (world.disposed)
487
+ continue;
463
488
  if (onlyFrozen) {
464
489
  if (paused && world.pausable && !world.mounted.drivesOwnLoop) {
465
490
  inputFrameActive = true;
@@ -487,6 +512,8 @@ export function createGame(opts) {
487
512
  if (!onlyFrozen) {
488
513
  for (let i = 0; i < n; i++) {
489
514
  const world = roots[i];
515
+ if (world.disposed)
516
+ continue;
490
517
  if (!world.mounted.drivesOwnLoop)
491
518
  continue;
492
519
  if (!paused || !world.pausable || !world.mounted.setPaused) {
@@ -512,6 +539,8 @@ export function createGame(opts) {
512
539
  systems.runPhase(phase, dt);
513
540
  for (let i = 0; i < n; i++) {
514
541
  const world = roots[i];
542
+ if (world.disposed)
543
+ continue;
515
544
  if (world.mounted.drivesOwnLoop)
516
545
  continue;
517
546
  if (!(paused && world.pausable))
@@ -528,6 +557,8 @@ export function createGame(opts) {
528
557
  }
529
558
  for (let i = 0; i < n; i++) {
530
559
  const world = roots[i];
560
+ if (world.disposed)
561
+ continue;
531
562
  if (world.mounted.drivesOwnLoop)
532
563
  continue;
533
564
  if (!(paused && world.pausable))
@@ -563,6 +594,8 @@ export function createGame(opts) {
563
594
  systems.runPhase(phase, dt);
564
595
  for (let i = 0; i < n; i++) {
565
596
  const world = roots[i];
597
+ if (world.disposed)
598
+ continue;
566
599
  if (world.mounted.drivesOwnLoop)
567
600
  continue;
568
601
  // D10/T7.6: a `pausable` world under an active pause
@@ -590,6 +623,8 @@ export function createGame(opts) {
590
623
  }
591
624
  for (let i = 0; i < n; i++) {
592
625
  const world = roots[i];
626
+ if (world.disposed)
627
+ continue;
593
628
  if (world.mounted.drivesOwnLoop)
594
629
  continue;
595
630
  // A fully-frozen world gets no `endFrame`/opaque-`update` call either —
@@ -645,7 +680,7 @@ export function createGame(opts) {
645
680
  rngTrap.disable();
646
681
  }
647
682
  /**
648
- * WO-P13 — one display frame's PRESENTATION pass. See
683
+ * One display frame's PRESENTATION pass. See
649
684
  * `GameInternal.runRenderFrame`'s doc comment for the contract; this is the
650
685
  * `preRender`+`render` slice of `runFrameImpl`'s phase loop, lifted out and
651
686
  * driven by the loop's own per-real-frame callback instead of by the substep
@@ -693,6 +728,8 @@ export function createGame(opts) {
693
728
  systems.runPhase(phase, displayDt);
694
729
  for (let i = 0; i < n; i++) {
695
730
  const world = roots[i];
731
+ if (world.disposed)
732
+ continue;
696
733
  if (world.mounted.drivesOwnLoop)
697
734
  continue;
698
735
  // D10/T7.6, carried over verbatim in substance: a frozen world still
@@ -741,6 +778,26 @@ export function createGame(opts) {
741
778
  for (const listener of systemAdapterListeners)
742
779
  listener();
743
780
  },
781
+ get declaredSystemAbsences() {
782
+ return [...declaredAbsences.values()].flat();
783
+ },
784
+ installDeclaredSystemAdapters(rootId, slots, absent = []) {
785
+ if (!roots.some((w) => w.id === rootId)) {
786
+ throw new Error(`installDeclaredSystemAdapters: no mounted root is named "${rootId}" ` +
787
+ `(mounted: ${roots.map((w) => `"${w.id}"`).join(', ') || 'none'}).`);
788
+ }
789
+ if (declaredSystemAdapters.has(rootId)) {
790
+ throw new Error(`installDeclaredSystemAdapters: root "${rootId}" already installed its declared ` +
791
+ 'systems — a declaration is static and installs exactly once per mount.');
792
+ }
793
+ declaredSystemAdapters.set(rootId, slots);
794
+ // ALWAYS set, never merge: a re-install (an HMR of the entry's `systems`
795
+ // table) that dropped an `absent()` marker must also drop the recorded
796
+ // absence, or the coverage report keeps printing a game statement the
797
+ // game no longer makes.
798
+ declaredAbsences.set(rootId, absent);
799
+ gameInternal.notifySystemAdaptersChanged();
800
+ },
744
801
  input,
745
802
  state: stateBridge,
746
803
  play: {
@@ -769,6 +826,11 @@ export function createGame(opts) {
769
826
  // not paused, nothing here runs — step() is a whole-call no-op.
770
827
  if (paused) {
771
828
  for (const world of roots) {
829
+ // Same disposed-world guard `runFrameImpl` (and `setRootGates`)
830
+ // make: a disposed world's `mounted.step` drives a loop whose
831
+ // resources are already freed.
832
+ if (world.disposed)
833
+ continue;
772
834
  if (!world.pausable || !world.mounted.drivesOwnLoop)
773
835
  continue;
774
836
  if (!world.mounted.setPaused)
@@ -794,8 +856,8 @@ export function createGame(opts) {
794
856
  // `endFrame` called once per registration) and double-dispose-wrapped
795
857
  // (`createRootInstance` wraps `mounted.dispose` in place — a second
796
858
  // wrap would flip `disposed` and call through on ITS OWN wrapped
797
- // `originalDispose`, which is harmless today only by accident of
798
- // `SetupThreeRootAdapter.dispose` being idempotent; a foreign adapter
859
+ // `originalDispose`, which would be harmless only if the adapter's
860
+ // dispose happened to be idempotent; a foreign adapter
799
861
  // has no such guarantee). Reject it outright instead.
800
862
  if (roots.some((w) => w.mounted === world.mounted)) {
801
863
  throw new Error(`Game.registerRoot: world "${world.id}" shares its \`mounted\` object with an ` +
@@ -805,14 +867,14 @@ export function createGame(opts) {
805
867
  roots.push(world);
806
868
  gameInternal.notifySystemAdaptersChanged();
807
869
  // Notify state-bridge subscribers THE INSTANT the world list changes —
808
- // not just at the next completed `runFrame`. Root-cause fix for the
809
- // "roots: " (empty) hang in `36-r3f-first-party.spec.ts` on CI (gate
810
- // 4): `mountAllRootSpecs` (`create-runtime.ts`) mounts roots
870
+ // not just at the next completed `runFrame`. Otherwise a UI that lists
871
+ // worlds hangs on an empty list: `mountAllRootSpecs`
872
+ // (`create-runtime.ts`) mounts roots
811
873
  // SEQUENTIALLY, and a react world's `adapter.mount()`
812
874
  // (`resolveDefaultReactAdapter`/`mountOneReactRoot`) renders its tree —
813
875
  // synchronously in some React builds, but React 19's concurrent
814
876
  // renderer does NOT guarantee a synchronous first commit (see
815
- // `r3f-adapter.tsx`'s own doc comment on `onCreated`) — BEFORE the
877
+ // `r3f-root-factory.tsx`'s own doc comment on `onCreated`) — BEFORE the
816
878
  // caller calls `registerRoot` for that very world. A `useWorldState`
817
879
  // selector reading `g.roots` can therefore render for the first time
818
880
  // while `roots` is still missing entries that register moments later.
@@ -856,15 +918,11 @@ export function createGame(opts) {
856
918
  // world mount), eroding the signal for a genuinely un-observable
857
919
  // ingested world.
858
920
  // A HOST-DRIVEN mount (`drivesOwnLoop: false`, notably the R3F adapter)
859
- // is observable through `Game.state` even though it does not carry the
860
- // classic scene adapter's `firstParty` brand: it ticks inside
861
- // `runFrame`, so the frame-versioned bridge covers it. Requiring a
921
+ // is observable through `Game.state` when it ticks inside
922
+ // `runFrame` the frame-versioned bridge covers it. Requiring a
862
923
  // foreign-world `observe` bridge there produces a false warning while
863
924
  // the canonical bridge is already live.
864
- if (!isFirstPartyMounted(world.mounted) &&
865
- world.mounted.drivesOwnLoop &&
866
- world.kind !== 'dom' &&
867
- !world.mounted.observe) {
925
+ if (world.mounted.drivesOwnLoop && world.kind !== 'dom' && !world.mounted.observe) {
868
926
  console.warn(`[game] world "${world.id}" (kind: ${world.kind}, adapter: "${world.adapter.id}"): ` +
869
927
  'no state bridge — this mounted game has no `observe` (RootStateObserver); ' +
870
928
  'react HUDs/useRootObservation cannot subscribe to its state.');
@@ -952,7 +1010,7 @@ export function createGame(opts) {
952
1010
  // root's `mounted.dispose()`, whereas a per-root teardown may be ending
953
1011
  // just one sub-session while sibling roots keep running (see the
954
1012
  // disposed-world guard in `runFrame`). It used to be disposed from
955
- // `setup-three-root-adapter.ts`'s teardown, which meant disposing one of
1013
+ // `world3d-react/r3f-root-factory.tsx`'s teardown, which meant disposing one of
956
1014
  // two three roots froze `now()` for the whole Game, rejected the other
957
1015
  // world's pending `delay`s and turned its `after()` calls into silent
958
1016
  // no-ops. Note the asymmetry that gives the bug away: `seededRandom` and
@@ -80,22 +80,6 @@ export declare function isAdapterRegistered(kind: string): boolean;
80
80
  * registry without cross-test leakage.
81
81
  */
82
82
  export declare function __clearAdapterSurfaceRegistryForTests(): void;
83
- /**
84
- * A ready-to-register {@link AdapterSurfaceFactory} for `kind: 'three'` roots
85
- * that follow the first-party entry-module convention (`export const
86
- * adapter` and/or `export async function setup`). Threejs is safe to
87
- * ship as an exported convenience (unlike canvas/react) because `three`/
88
- * `SetupThreeRootAdapter` are already unconditional engine dependencies —
89
- * see `mount-manifest.ts`'s header comment. Still never auto-registered:
90
- * the registry itself stays zero-policy (see this file's header comment) —
91
- * a caller opts in with `registerAdapter('three', defaultThreeAdapterFactory)`.
92
- *
93
- * Resolution mirrors `mount-manifest.ts`'s own `resolveThreeAdapter` branch
94
- * order: an entry module's `adapter` export wins outright; else its `setup`
95
- * export (wrapping via `fromSetup` happens inside `mountManifestRoots`
96
- * itself — this factory just returns the `MountEntry` shape).
97
- */
98
- export declare const defaultThreeAdapterFactory: AdapterSurfaceFactory;
99
83
  export interface MountGameOptions {
100
84
  /** Explicit per-world entries, same shape `mountManifestRoots` accepts —
101
85
  * ALWAYS wins over a registered kind factory for that world id (backward
@@ -1 +1 @@
1
- {"version":3,"file":"mount-game.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-game.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,KAAK,UAAU,EAAuC,MAAM,kBAAkB,CAAC;AAQxF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;6DACyD;IACzD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD;;;mFAG+E;IAC/E,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;gEAC4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,+EAA+E;AAC/E,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,4BAA4B,KAC9B,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAQtC;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAUlF;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,IAAI,IAAI,CAE5D;AAcD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,EAAE,qBAexC,CAAC;AAMF,MAAM,WAAW,gBAAgB;IAC/B;;;kEAG8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;CACrE;AAyBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,OAAO,EACtB,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,WAAW,CAAC,CA6CtB"}
1
+ {"version":3,"file":"mount-game.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-game.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,KAAK,UAAU,EAAuC,MAAM,kBAAkB,CAAC;AAOxF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;6DACyD;IACzD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD;;;mFAG+E;IAC/E,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;gEAC4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,+EAA+E;AAC/E,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,4BAA4B,KAC9B,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAQtC;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAUlF;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,IAAI,IAAI,CAE5D;AAMD,MAAM,WAAW,gBAAgB;IAC/B;;;kEAG8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;CACrE;AA+BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,OAAO,EACtB,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,WAAW,CAAC,CAqDtB"}
@@ -12,11 +12,14 @@
12
12
  // callers register, but it registers NONE itself. In particular there is no
13
13
  // built-in 'canvas'/'react' registration here (that would require this file
14
14
  // to value-import `pixi.js`/`react`/`react-dom`, exactly what `mount-manifest
15
- // .ts` forbids); a project that has a canvas or react world MUST register a
16
- // factory for that kind itself — see `defaultThreeAdapterFactory` below for why
17
- // even the 'three' convenience export is a plain function the CALLER
18
- // registers, not something this module wires up automatically.
19
- import { installNativeDebugBindings, nativeDebugBindingFromEntryModule, } from '../adapter/native-debug-module';
15
+ // .ts` forbids); a project that has a three, canvas, or react world MUST
16
+ // register a factory for that kind itself — the factories live with the
17
+ // modules that own their dependencies (`r3fRootFactory` in
18
+ // `@engine/world3d-react`, its Pixi twin in `@engine/canvas-react`), never
19
+ // wired up here automatically.
20
+ import { declaredRoots } from '../adapter/manifest-interpreter';
21
+ import { installNativeDebugBindings, installNativeSystemsBindings, nativeDebugBindingFromEntryModule, nativeSystemsBindingFromEntryModule, } from '../adapter/native-debug-module';
22
+ import { publishDevInstruments } from '../dev/instruments';
20
23
  import { mountManifestRoots, resolveManifest } from './mount-manifest';
21
24
  import { assertExportedOrInEditor } from './unexported-game-trap';
22
25
  // ---------------------------------------------------------------------------
@@ -61,44 +64,12 @@ export function isAdapterRegistered(kind) {
61
64
  export function __clearAdapterSurfaceRegistryForTests() {
62
65
  registry.clear();
63
66
  }
64
- /**
65
- * A ready-to-register {@link AdapterSurfaceFactory} for `kind: 'three'` roots
66
- * that follow the first-party entry-module convention (`export const
67
- * adapter` and/or `export async function setup`). Threejs is safe to
68
- * ship as an exported convenience (unlike canvas/react) because `three`/
69
- * `SetupThreeRootAdapter` are already unconditional engine dependencies —
70
- * see `mount-manifest.ts`'s header comment. Still never auto-registered:
71
- * the registry itself stays zero-policy (see this file's header comment) —
72
- * a caller opts in with `registerAdapter('three', defaultThreeAdapterFactory)`.
73
- *
74
- * Resolution mirrors `mount-manifest.ts`'s own `resolveThreeAdapter` branch
75
- * order: an entry module's `adapter` export wins outright; else its `setup`
76
- * export (wrapping via `fromSetup` happens inside `mountManifestRoots`
77
- * itself — this factory just returns the `MountEntry` shape).
78
- */
79
- export const defaultThreeAdapterFactory = (world, ctx) => {
80
- const mod = ctx.entryModule;
81
- if (mod?.adapter)
82
- return { kind: 'three', adapter: mod.adapter };
83
- if (mod?.setup)
84
- return { kind: 'three', setup: mod.setup };
85
- if (world.entry !== undefined) {
86
- throw new Error(`defaultThreeAdapterFactory: entry module "${world.entry}" for world "${world.id}" exports ` +
87
- 'neither `adapter` nor `setup` — every first-party entry module exports at least one ' +
88
- '(export one from the declared entry module).');
89
- }
90
- throw new Error(`defaultThreeAdapterFactory: world "${world.id}" declares no \`entry\` — a three root is ` +
91
- 'authored as a TSX/R3F world module; point `entry` at it.');
92
- };
93
67
  /** True for the one shape `mountManifestRoots` can ALREADY mount with zero
94
68
  * `entries[id]` at all.
95
69
  *
96
- * WO-8: nothing is self-sufficient any more. The one shape that was — a plain
97
- * `default`-adapter, SCENE-driven, no-`entry` three world, which
98
- * `resolveThreeAdapter`'s scene branch could mount from the manifest alone —
99
- * died with the `.vscn.json` format. `load.ts` now rejects a three root with no
70
+ * NOTHING is self-sufficient: `load.ts` rejects a three root with no
100
71
  * `entry` outright, so every world needs a registered factory or an explicit
101
- * entry, and this predicate is retained only to keep the loud-degrade error the
72
+ * entry. This predicate is retained so the loud-degrade error stays the
102
73
  * documented outcome rather than a silent skip. */
103
74
  function worldIsSelfSufficient(_world) {
104
75
  return false;
@@ -109,6 +80,12 @@ function nativeDebugForEntry(world, entryModule) {
109
80
  const binding = nativeDebugBindingFromEntryModule(world.id, entryModule);
110
81
  return binding ? [binding] : [];
111
82
  }
83
+ function nativeSystemsForEntry(world, entryModule) {
84
+ if (entryModule === undefined || world.adapter.type !== 'builtin')
85
+ return [];
86
+ const binding = nativeSystemsBindingFromEntryModule(world.id, entryModule, world.surface);
87
+ return binding ? [binding] : [];
88
+ }
112
89
  /**
113
90
  * Mount every world declared by a `vgai.project.json` manifest onto `host
114
91
  * .container`, resolving each world's kind through the `registerAdapter`
@@ -137,7 +114,8 @@ export async function mountGameFromManifest(manifestInput, host, opts = {}) {
137
114
  const manifest = resolveManifest(manifestInput);
138
115
  const entries = { ...opts.entries };
139
116
  const nativeDebug = [];
140
- for (const world of manifest.roots) {
117
+ const nativeSystems = [];
118
+ for (const world of declaredRoots(manifest)) {
141
119
  if (entries[world.id] !== undefined)
142
120
  continue; // explicit entry always wins
143
121
  const factory = registry.get(world.adapter.identity);
@@ -146,6 +124,7 @@ export async function mountGameFromManifest(manifestInput, host, opts = {}) {
146
124
  ? await host.loadEntryModule(world.entry)
147
125
  : undefined;
148
126
  nativeDebug.push(...nativeDebugForEntry(world, entryModule));
127
+ nativeSystems.push(...nativeSystemsForEntry(world, entryModule));
149
128
  entries[world.id] = await factory(world, { host, entryModule });
150
129
  continue;
151
130
  }
@@ -154,7 +133,7 @@ export async function mountGameFromManifest(manifestInput, host, opts = {}) {
154
133
  throw new Error(`mountGameFromManifest: root "${world.id}" (adapter "${world.adapter.identity}") has no registered ` +
155
134
  `adapter factory and no explicit entries["${world.id}"] — call ` +
156
135
  `registerAdapter("${world.adapter.identity}", factory) before mounting (see ` +
157
- '`defaultThreeAdapterFactory` for a worked three example), or pass ' +
136
+ '`r3fRootFactory` in `@vgai/engine/world3d-react` for the worked three factory), or pass ' +
158
137
  `opts.entries["${world.id}"] directly (see mount-manifest.ts's \`MountEntry\`).`);
159
138
  }
160
139
  const session = await mountManifestRoots({
@@ -166,5 +145,11 @@ export async function mountGameFromManifest(manifestInput, host, opts = {}) {
166
145
  headless: host.headless,
167
146
  });
168
147
  installNativeDebugBindings(session.game, nativeDebug);
148
+ installNativeSystemsBindings(session.game, nativeSystems);
149
+ // The universal instruments are host furniture on EVERY mount path — the
150
+ // editor installs them in its own bindings pass; the standalone composer
151
+ // installs them here. The disposer is deliberately dropped: the set's one
152
+ // resource lives on this Game and dies with it.
153
+ publishDevInstruments(session.game);
169
154
  return session;
170
155
  }
@@ -1,8 +1,9 @@
1
+ import type { RootDeclaration } from '../adapter/binding';
1
2
  import type { RootAdapter } from '../adapter/root-adapter';
2
3
  import { type ResolvedGameManifest } from '../manifest/load';
3
4
  import { type GameSession } from './create-runtime';
4
5
  import { type DebugBridgeWindowTarget } from './debug-bridge';
5
- import type { GameSetupFn, PlaytestContext } from './types';
6
+ import type { PlaytestContext } from './playtest';
6
7
  /**
7
8
  * A caller-supplied entry for a `kind: 'three'` world — two ways to satisfy
8
9
  * it, matching the two shapes `resolveDefaultThreeAdapter` supports (an
@@ -11,20 +12,27 @@ import type { GameSetupFn, PlaytestContext } from './types';
11
12
  * - `{ adapter }` — a fully-constructed {@link RootAdapter} (first-party or
12
13
  * not). Always wins if present, regardless of the world's `entry` field —
13
14
  * full caller control, including for a `{ module }`-adapter world
14
- * (mountManifestRoots cannot import an arbitrary module path itself).
15
- * - `{ setup }` — for an `entry`-declaring world: the project's own
16
- * `entry` module's exported `setup` function (the same `GameSetupFn`
17
- * shape `loadProjectScripts` extracts editor-side). Wrapped in a
18
- * `SetupThreeRootAdapter` here, mirroring `resolveDefaultThreeAdapter`'s
19
- * entry branch exactly.
20
- *
21
- * The former third shape, `{ componentRegistry }` for a `scene`-declaring
22
- * world, went with the `.vscn.json` format in WO-8.
15
+ * (mountManifestRoots cannot import an arbitrary module path itself
16
+ * for a default-exported world, build the adapter with
17
+ * `resolveR3FEntryAdapter(entryModule, worldId)` from
18
+ * `@vgai/engine/world3d-react` and pass it here).
23
19
  */
24
- export interface ThreeMountEntry {
20
+ export interface ThreeMountEntry extends MountEntryDeclaration {
25
21
  readonly kind: 'three';
26
22
  readonly adapter?: RootAdapter | undefined;
27
- readonly setup?: GameSetupFn | undefined;
23
+ }
24
+ /**
25
+ * The half of a root's binding declaration a CALLER holds — everything in
26
+ * `adapter/binding.ts`'s {@link RootDeclaration} except `root`, which this
27
+ * file already has from the manifest it just resolved.
28
+ *
29
+ * Optional throughout, and absent is the honest state for a caller who built
30
+ * an adapter by hand out of its own module graph: there is no entry namespace
31
+ * to report a static surface for, so the root registers with `binding: null`
32
+ * rather than one describing a module nobody loaded.
33
+ */
34
+ export interface MountEntryDeclaration {
35
+ readonly declaration?: Omit<RootDeclaration, 'root'> | undefined;
28
36
  }
29
37
  /**
30
38
  * A caller-supplied entry for a `kind: 'canvas'` world — ALWAYS a
@@ -34,7 +42,7 @@ export interface ThreeMountEntry {
34
42
  * `pixi.js`, which it deliberately never does (see this file's header
35
43
  * comment).
36
44
  */
37
- export interface PixiMountEntry {
45
+ export interface PixiMountEntry extends MountEntryDeclaration {
38
46
  readonly kind: 'canvas';
39
47
  readonly adapter: RootAdapter<'canvas'>;
40
48
  }
@@ -51,7 +59,7 @@ export interface PixiMountEntry {
51
59
  * itself (see this file's header comment) — building the adapter is
52
60
  * entirely the caller's job.
53
61
  */
54
- export interface ReactMountEntry {
62
+ export interface ReactMountEntry extends MountEntryDeclaration {
55
63
  readonly kind: 'dom';
56
64
  readonly adapter: RootAdapter<'dom'>;
57
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mount-manifest.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mount-manifest.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-manifest.ts"],"names":[],"mappings":"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"}