@vgai/engine 0.5.22 → 0.5.24

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 (303) 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-seams.d.ts +5 -0
  28. package/dist/adapter/ingest/game-contract-seams.d.ts.map +1 -1
  29. package/dist/adapter/ingest/game-contract-seams.js +1 -0
  30. package/dist/adapter/ingest/game-contract.d.ts +22 -3
  31. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  32. package/dist/adapter/ingest/game-contract.js +0 -3
  33. package/dist/adapter/ingest/scene-capture.d.ts +19 -23
  34. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  35. package/dist/adapter/ingest/scene-capture.js +143 -17
  36. package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
  37. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  38. package/dist/adapter/native-debug-module.d.ts +40 -5
  39. package/dist/adapter/native-debug-module.d.ts.map +1 -1
  40. package/dist/adapter/native-debug-module.js +36 -9
  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 +2 -2
  45. package/dist/adapter/renderer-config.js +2 -2
  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/core/frame-pacing.d.ts +1 -1
  82. package/dist/core/frame-pacing.js +2 -2
  83. package/dist/core/game-loop.d.ts +1 -3
  84. package/dist/core/game-loop.d.ts.map +1 -1
  85. package/dist/core/game-loop.js +1 -3
  86. package/dist/core/seeded-random.d.ts +1 -1
  87. package/dist/core/sim-clock.d.ts +5 -6
  88. package/dist/core/sim-clock.d.ts.map +1 -1
  89. package/dist/core/sim-clock.js +4 -5
  90. package/dist/core/types.d.ts +1 -3
  91. package/dist/core/types.d.ts.map +1 -1
  92. package/dist/defaults.d.ts +6 -14
  93. package/dist/defaults.d.ts.map +1 -1
  94. package/dist/defaults.js +6 -14
  95. package/dist/dev/register-render-vitals.d.ts +1 -4
  96. package/dist/dev/register-render-vitals.d.ts.map +1 -1
  97. package/dist/dev/register-render-vitals.js +1 -4
  98. package/dist/dev/render-debug-adapter.d.ts +2 -3
  99. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  100. package/dist/dev/render-debug-adapter.js +2 -3
  101. package/dist/dev/render-vitals.d.ts +3 -3
  102. package/dist/dev/render-vitals.js +3 -3
  103. package/dist/dev/webgl-frame-capture.d.ts +1 -1
  104. package/dist/dev/webgl-frame-capture.js +1 -1
  105. package/dist/index.d.ts +2 -5
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +2 -4
  108. package/dist/input/host-pointer.d.ts +122 -0
  109. package/dist/input/host-pointer.d.ts.map +1 -0
  110. package/dist/input/host-pointer.js +160 -0
  111. package/dist/input/input-manager.d.ts +18 -5
  112. package/dist/input/input-manager.d.ts.map +1 -1
  113. package/dist/input/input-manager.js +33 -13
  114. package/dist/input/rebind-controller.d.ts.map +1 -1
  115. package/dist/input/rebind-controller.js +6 -8
  116. package/dist/input/schema.d.ts.map +1 -1
  117. package/dist/input/schema.js +56 -28
  118. package/dist/manifest/filename.d.ts.map +1 -1
  119. package/dist/manifest/filename.js +8 -12
  120. package/dist/manifest/load.d.ts +10 -10
  121. package/dist/manifest/load.d.ts.map +1 -1
  122. package/dist/manifest/load.js +9 -6
  123. package/dist/manifest/schema.d.ts +17 -21
  124. package/dist/manifest/schema.d.ts.map +1 -1
  125. package/dist/manifest/schema.js +45 -35
  126. package/dist/physics/collider-dimensions.d.ts +8 -12
  127. package/dist/physics/collider-dimensions.d.ts.map +1 -1
  128. package/dist/physics/collider-dimensions.js +8 -12
  129. package/dist/pixi/scene-capture.d.ts +11 -13
  130. package/dist/pixi/scene-capture.d.ts.map +1 -1
  131. package/dist/react/world-state.d.ts +1 -1
  132. package/dist/react/world-state.d.ts.map +1 -1
  133. package/dist/render/light-camera-factory.d.ts +5 -7
  134. package/dist/render/light-camera-factory.d.ts.map +1 -1
  135. package/dist/render/light-camera-factory.js +8 -11
  136. package/dist/render/material-factory.js +1 -1
  137. package/dist/render/render-batch-system.d.ts.map +1 -1
  138. package/dist/render/render-features.d.ts +17 -6
  139. package/dist/render/render-features.d.ts.map +1 -1
  140. package/dist/render/render-features.js +0 -28
  141. package/dist/runtime/create-runtime.d.ts +34 -25
  142. package/dist/runtime/create-runtime.d.ts.map +1 -1
  143. package/dist/runtime/create-runtime.js +218 -93
  144. package/dist/runtime/debug-bridge.d.ts +12 -0
  145. package/dist/runtime/debug-bridge.d.ts.map +1 -1
  146. package/dist/runtime/debug-bridge.js +4 -0
  147. package/dist/runtime/debug-registry.d.ts +95 -8
  148. package/dist/runtime/debug-registry.d.ts.map +1 -1
  149. package/dist/runtime/debug-registry.js +24 -3
  150. package/dist/runtime/dev-build.d.ts +2 -2
  151. package/dist/runtime/dev-build.js +2 -2
  152. package/dist/runtime/game-input-seams.d.ts +2 -2
  153. package/dist/runtime/game-input-seams.d.ts.map +1 -1
  154. package/dist/runtime/game.d.ts +102 -41
  155. package/dist/runtime/game.d.ts.map +1 -1
  156. package/dist/runtime/game.js +80 -54
  157. package/dist/runtime/mount-game.d.ts +0 -16
  158. package/dist/runtime/mount-game.d.ts.map +1 -1
  159. package/dist/runtime/mount-game.js +8 -39
  160. package/dist/runtime/mount-manifest.d.ts +22 -14
  161. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  162. package/dist/runtime/mount-manifest.js +18 -18
  163. package/dist/runtime/playtest.d.ts +22 -0
  164. package/dist/runtime/playtest.d.ts.map +1 -0
  165. package/dist/runtime/playtest.js +12 -0
  166. package/dist/runtime/run-ticks-settled.d.ts +34 -0
  167. package/dist/runtime/run-ticks-settled.d.ts.map +1 -0
  168. package/dist/runtime/run-ticks-settled.js +59 -0
  169. package/dist/runtime/state-bridge.d.ts +2 -3
  170. package/dist/runtime/state-bridge.d.ts.map +1 -1
  171. package/dist/runtime/state-bridge.js +1 -0
  172. package/dist/setup/setup-audio.d.ts +12 -0
  173. package/dist/setup/setup-audio.d.ts.map +1 -1
  174. package/dist/setup/setup-audio.js +9 -10
  175. package/dist/setup/setup-renderer.d.ts +2 -25
  176. package/dist/setup/setup-renderer.d.ts.map +1 -1
  177. package/dist/setup/setup-renderer.js +2 -31
  178. package/dist/world3d-react/r3f-root-factory.d.ts +7 -7
  179. package/dist/world3d-react/r3f-root-factory.js +7 -7
  180. package/dist/world3d-react/rapier-physics-bridge.d.ts +9 -8
  181. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  182. package/dist/world3d-react/rapier-physics-bridge.js +100 -48
  183. package/package.json +1 -1
  184. package/schemas/engine-capabilities.json +16 -14
  185. package/schemas/vgai-project.schema.json +35 -26
  186. package/src/adapter/adapter-module.ts +2 -4
  187. package/src/adapter/adapter-surface.ts +1 -1
  188. package/src/adapter/authoring.ts +19 -21
  189. package/src/adapter/binding.ts +468 -0
  190. package/src/adapter/colyseus-networking-adapter.ts +20 -5
  191. package/src/adapter/entrypoint-selection-readers.ts +66 -0
  192. package/src/adapter/entrypoint-selection-source.ts +1 -40
  193. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
  194. package/src/adapter/host-context.ts +45 -15
  195. package/src/adapter/index.ts +23 -11
  196. package/src/adapter/ingest/game-contract-seams.ts +1 -0
  197. package/src/adapter/ingest/game-contract.ts +22 -3
  198. package/src/adapter/ingest/scene-capture.ts +190 -39
  199. package/src/adapter/ingest/visible-capture-window.ts +35 -0
  200. package/src/adapter/native-debug-module.ts +66 -9
  201. package/src/adapter/rapier-physics-adapter.ts +76 -20
  202. package/src/adapter/renderer-config.ts +2 -2
  203. package/src/adapter/root-adapter.ts +7 -7
  204. package/src/adapter/system-adapter.ts +43 -8
  205. package/src/adapter/system-seam-contract.ts +3 -3
  206. package/src/adapter/system-slot.ts +291 -0
  207. package/src/adapter/transform.ts +18 -1
  208. package/src/ai/navigation.ts +30 -3
  209. package/src/animation/anim-graph-types.ts +11 -3
  210. package/src/animation/theatre-clock-binding.ts +4 -4
  211. package/src/animation/xstate-animation-binding.ts +2 -2
  212. package/src/animation/xstate-animation-meta.ts +16 -0
  213. package/src/asset-formats/index.ts +4 -7
  214. package/src/asset-formats/render-env.ts +3 -6
  215. package/src/asset-parse-error.ts +2 -5
  216. package/src/audio/bus-mixer.ts +161 -0
  217. package/src/core/frame-pacing.ts +2 -2
  218. package/src/core/game-loop.ts +1 -3
  219. package/src/core/seeded-random.ts +1 -1
  220. package/src/core/sim-clock.ts +5 -6
  221. package/src/core/types.ts +1 -3
  222. package/src/defaults.ts +6 -14
  223. package/src/dev/register-render-vitals.ts +1 -4
  224. package/src/dev/render-debug-adapter.ts +2 -3
  225. package/src/dev/render-vitals.ts +3 -3
  226. package/src/dev/webgl-frame-capture.ts +1 -1
  227. package/src/index.ts +2 -5
  228. package/src/input/host-pointer.ts +230 -0
  229. package/src/input/input-manager.ts +34 -13
  230. package/src/input/input-types.ts +1 -1
  231. package/src/input/rebind-controller.ts +6 -8
  232. package/src/input/schema.ts +216 -188
  233. package/src/manifest/filename.ts +8 -12
  234. package/src/manifest/load.ts +17 -13
  235. package/src/manifest/schema.ts +55 -47
  236. package/src/physics/collider-dimensions.ts +8 -12
  237. package/src/pixi/scene-capture.ts +12 -15
  238. package/src/react/world-state.tsx +1 -1
  239. package/src/render/light-camera-factory.ts +8 -11
  240. package/src/render/material-factory.ts +1 -1
  241. package/src/render/render-batch-system.ts +14 -6
  242. package/src/render/render-features.ts +17 -35
  243. package/src/runtime/create-runtime.ts +270 -108
  244. package/src/runtime/debug-bridge.ts +16 -0
  245. package/src/runtime/debug-registry.ts +121 -8
  246. package/src/runtime/dev-build.ts +2 -2
  247. package/src/runtime/game-input-seams.ts +2 -2
  248. package/src/runtime/game.ts +180 -80
  249. package/src/runtime/mount-game.ts +8 -56
  250. package/src/runtime/mount-manifest.ts +43 -34
  251. package/src/runtime/playtest.ts +22 -0
  252. package/src/runtime/run-ticks-settled.ts +72 -0
  253. package/src/runtime/state-bridge.ts +3 -3
  254. package/src/setup/setup-audio.ts +21 -11
  255. package/src/setup/setup-renderer.ts +2 -61
  256. package/src/world3d-react/r3f-root-factory.tsx +7 -7
  257. package/src/world3d-react/rapier-physics-bridge.tsx +107 -50
  258. package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
  259. package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
  260. package/dist/adapter/setup-three-root-adapter.js +0 -908
  261. package/dist/animation/clip-map.d.ts +0 -12
  262. package/dist/animation/clip-map.d.ts.map +0 -1
  263. package/dist/animation/clip-map.js +0 -31
  264. package/dist/asset-registry.d.ts +0 -38
  265. package/dist/asset-registry.d.ts.map +0 -1
  266. package/dist/asset-registry.js +0 -66
  267. package/dist/canvas-react/engine-bridge.d.ts +0 -45
  268. package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
  269. package/dist/canvas-react/engine-bridge.js +0 -45
  270. package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
  271. package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
  272. package/dist/canvas-react/pixi-react-adapter.js +0 -294
  273. package/dist/canvas-react/world-context.d.ts +0 -98
  274. package/dist/canvas-react/world-context.d.ts.map +0 -1
  275. package/dist/canvas-react/world-context.js +0 -173
  276. package/dist/dev/debug-draw.d.ts +0 -24
  277. package/dist/dev/debug-draw.d.ts.map +0 -1
  278. package/dist/dev/debug-draw.js +0 -73
  279. package/dist/render/auto-batcher.d.ts +0 -34
  280. package/dist/render/auto-batcher.d.ts.map +0 -1
  281. package/dist/render/auto-batcher.js +0 -140
  282. package/dist/render/lod.d.ts +0 -13
  283. package/dist/render/lod.d.ts.map +0 -1
  284. package/dist/render/lod.js +0 -16
  285. package/dist/runtime/types.d.ts +0 -303
  286. package/dist/runtime/types.d.ts.map +0 -1
  287. package/dist/runtime/types.js +0 -1
  288. package/dist/world3d-react/engine-bridge.d.ts +0 -47
  289. package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
  290. package/dist/world3d-react/engine-bridge.js +0 -73
  291. package/dist/world3d-react/r3f-adapter.d.ts +0 -58
  292. package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
  293. package/dist/world3d-react/r3f-adapter.js +0 -634
  294. package/dist/world3d-react/world-context.d.ts +0 -182
  295. package/dist/world3d-react/world-context.d.ts.map +0 -1
  296. package/dist/world3d-react/world-context.js +0 -235
  297. package/src/adapter/setup-three-root-adapter.ts +0 -1032
  298. package/src/animation/clip-map.ts +0 -34
  299. package/src/asset-registry.ts +0 -89
  300. package/src/dev/debug-draw.ts +0 -80
  301. package/src/render/auto-batcher.ts +0 -168
  302. package/src/render/lod.ts +0 -17
  303. package/src/runtime/types.ts +0 -328
@@ -1 +1 @@
1
- {"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/create-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/create-runtime.ts"],"names":[],"mappings":"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"}
@@ -1,54 +1,55 @@
1
1
  import * as THREE from 'three';
2
2
  import { assertNever } from '../adapter/adapter-surface';
3
+ import { createRootBinding } from '../adapter/binding';
3
4
  import { createAssetCache } from '../assets';
4
5
  import { createGameLoop } from '../core/game-loop';
5
6
  import { createHostRenderer } from '../setup/setup-renderer';
7
+ import { getDebugRegistry } from './debug-registry';
6
8
  // TYPE-ONLY: `create-runtime.ts` must never value-import `pixi.js` — a canvas
7
9
  // `RootMountSpec`'s `adapter` is supplied ALREADY-CONSTRUCTED by the caller, so
8
10
  // the host only ever needs the seam's types.
9
- import { createGame, createRootInstance, isFirstPartyMounted, } from './game';
11
+ import { createGame, createRootInstance, } from './game';
10
12
  import { createInputRouter, stackOrder } from './input-router';
11
13
  import { installRenderControlHarness, isRenderModeRequested } from './render-control';
12
- /**
13
- * Register a three world for a freshly-mounted game onto the Game shell. Shared
14
- * by `createGameRuntime` and every headless test harness
15
- * (`test/game-root.test.ts`, `test/frame-order.test.ts`,
16
- * `test/game-two-roots.test.ts`) so there is exactly one code path for this
17
- * wiring. `physics`/`collisions`/`camera`/`frame` are populated from the mount's
18
- * first-party `GameContext`/ `MountedSetupThreeRoot` when available, left
19
- * `undefined` otherwise (an external adapter's mount has none of these
20
- * first-party handles — `frame` in particular is what makes
21
- * `GameInternal.runFrame` fall back to a single opaque
22
- * `mounted.update` call per substep for such a world).
23
- */
24
- function firstPartyExtras(mounted) {
25
- if (!isFirstPartyMounted(mounted))
26
- return {};
27
- return {
28
- physics: mounted.ctx.physics,
29
- collisions: mounted.ctx.collisions,
30
- camera: mounted.ctx.camera,
31
- frame: mounted.frame,
32
- };
33
- }
34
14
  /**
35
15
  * Register a three world onto the Game shell. `opts.id` defaults to
36
16
  * `'main'`; multi-root callers pass an explicit id. This is the one
37
17
  * registration path for a three world, whatever its id.
38
18
  */
39
19
  export function registerThreeRoot(game, adapter, mounted, opts) {
20
+ const pausable = opts?.pausable ?? true;
40
21
  const world = createRootInstance({
41
22
  id: opts?.id ?? 'main',
42
23
  kind: 'three',
43
- pausable: opts?.pausable ?? true,
24
+ pausable,
44
25
  adapter,
45
26
  mounted,
46
27
  scene: mounted.scene,
47
- ...firstPartyExtras(mounted),
28
+ binding: bindRoot(game, opts?.declaration, {
29
+ surface: 'three',
30
+ adapter: adapter,
31
+ }, mounted, pausable),
48
32
  });
49
33
  game.registerRoot(world);
50
34
  return world;
51
35
  }
36
+ /**
37
+ * Complete the root's binding at the first moment it CAN be completed: the
38
+ * declaration is what the resolver knew, `mounted`/`adapter`/`pausable` are
39
+ * what mounting produced, and the debug registry is the game's own. Nothing
40
+ * here loads or fabricates — see `createRootBinding`.
41
+ */
42
+ function bindRoot(game, declaration, adapter, mounted, pausable) {
43
+ if (!declaration)
44
+ return null;
45
+ return createRootBinding({
46
+ ...declaration,
47
+ adapter,
48
+ mounted,
49
+ pausable,
50
+ debugRegistry: getDebugRegistry(game),
51
+ });
52
+ }
52
53
  /**
53
54
  * Register a canvas world onto the Game shell — the pixi analog of
54
55
  * {@link registerThreeRoot}. `adapter` is the seam's own
@@ -58,13 +59,15 @@ export function registerThreeRoot(game, adapter, mounted, opts) {
58
59
  */
59
60
  export function registerPixiRoot(game, adapter, mounted, opts) {
60
61
  const id = opts?.id ?? 'main';
62
+ const pausable = opts?.pausable ?? true;
61
63
  const world = createRootInstance({
62
64
  id,
63
65
  kind: 'canvas',
64
- pausable: opts?.pausable ?? true,
66
+ pausable,
65
67
  adapter,
66
68
  mounted,
67
69
  stage: mounted.stage,
70
+ binding: bindRoot(game, opts?.declaration, { surface: 'canvas', adapter }, mounted, pausable),
68
71
  });
69
72
  game.registerRoot(world);
70
73
  return world;
@@ -81,13 +84,15 @@ export function registerPixiRoot(game, adapter, mounted, opts) {
81
84
  * needs `.id`, so this passes through with zero cast.
82
85
  */
83
86
  export function registerReactRoot(game, adapter, mounted, container, opts) {
87
+ const pausable = opts?.pausable ?? true;
84
88
  const world = createRootInstance({
85
89
  id: opts?.id ?? 'main',
86
90
  kind: 'dom',
87
- pausable: opts?.pausable ?? true,
91
+ pausable,
88
92
  adapter,
89
93
  mounted,
90
94
  container,
95
+ binding: bindRoot(game, opts?.declaration, { surface: 'dom', adapter }, mounted, pausable),
91
96
  });
92
97
  game.registerRoot(world);
93
98
  return world;
@@ -106,9 +111,8 @@ export async function createGameRuntime(config) {
106
111
  // Universal root host
107
112
  // ---------------------------------------------------------------------------
108
113
  /** A stand-in `THREE.WebGLRenderer` for headless (`headless:true`) three
109
- * roots mirrors `SetupThreeRootAdapter.mount`'s own `headlessComposer`
110
- * pattern (`adapter/setup-three-root-adapter.ts`): a headless first-party
111
- * mount never calls a render-phase method on `host.renderer` at all, so
114
+ * roots: a headless mount never calls a render-phase method on
115
+ * `host.renderer` at all, so
112
116
  * this only needs to satisfy the handful of calls THIS file itself makes
113
117
  * (`setPixelRatio`/`setClearColor`/`setSize` at mount, `dispose`/
114
118
  * `forceContextLoss` at teardown) — never a real GL call. Node conformance
@@ -122,6 +126,46 @@ function createHeadlessRendererStub() {
122
126
  forceContextLoss() { },
123
127
  };
124
128
  }
129
+ /**
130
+ * Reclaim ONE mounted root: its adapter, the renderer this file constructed for
131
+ * it (including the WebGL context — a browser keeps only a handful alive, so
132
+ * `dispose()` alone is not enough), and its stacked surface element.
133
+ *
134
+ * ONE body, TWO callers, deliberately: the session's `fullCleanup` (a normal
135
+ * stop) and `mountAllRootSpecs`'s partial-mount ROLLBACK (a later root's mount
136
+ * rejected, so the roots that already mounted must not survive the rejection).
137
+ * Those two must never drift — a rollback that reclaims less than a stop is how
138
+ * a failed play leaves a live renderer and a lost GL context behind with no
139
+ * handle anywhere able to reach it.
140
+ *
141
+ * Throws only what the adapter's own `dispose()` throws; every caller wraps it
142
+ * per entry so one bad root cannot abort the rest of the teardown.
143
+ */
144
+ function disposeMountedRoot(entry, container) {
145
+ try {
146
+ entry.mounted.dispose();
147
+ }
148
+ finally {
149
+ // Renderer + surface release run even when the adapter's dispose threw:
150
+ // the GL context is the scarce resource, and the caller still sees the
151
+ // error (this rethrows through the `finally`).
152
+ entry.renderer?.dispose();
153
+ entry.renderer?.forceContextLoss();
154
+ // Remove from the element's CURRENT parent, not the mount-time
155
+ // `container`: the editor's Game panel re-parents the live surfaces
156
+ // when its mount element swaps (fill <-> device preset, W2c), and
157
+ // `container.removeChild` would throw NotFoundError after such a move.
158
+ // `container` remains the fallback for hosts whose element stand-ins
159
+ // never wire `parentNode` (headless unit fixtures); an element already
160
+ // detached by such a host is a no-op via the catch.
161
+ try {
162
+ (entry.element.parentNode ?? container).removeChild(entry.element);
163
+ }
164
+ catch {
165
+ /* already detached — nothing to remove */
166
+ }
167
+ }
168
+ }
125
169
  /** Mount one three `RootMountSpec` (canvas + renderer construction, per
126
170
  * D5 §1/§4, then `registerThreeRoot`). Split out of
127
171
  * `createRootsGameRuntime` purely to keep that function's own branching
@@ -175,7 +219,11 @@ async function mountOneThreeRoot(spec, ctx) {
175
219
  game,
176
220
  };
177
221
  const mounted = await spec.adapter.mount(host);
178
- registerThreeRoot(game, spec.adapter, mounted, { id: spec.id, pausable: spec.pausable });
222
+ registerThreeRoot(game, spec.adapter, mounted, {
223
+ id: spec.id,
224
+ pausable: spec.pausable,
225
+ declaration: spec.declaration,
226
+ });
179
227
  return {
180
228
  mountedEntry: { id: spec.id, kind: 'three', element: canvas, mounted, renderer },
181
229
  routerEntry: { id: spec.id, zOrder: spec.zOrder ?? 0, canvas, hitTest: spec.hitTest },
@@ -186,7 +234,7 @@ async function mountOneThreeRoot(spec, ctx) {
186
234
  * `mountOneThreeRoot` above.
187
235
  *
188
236
  * Unlike `mountOneThreeRoot`, this needs no explicit `canvas.style.width`/
189
- * `.height` re-assertion (E4.R1). `pixi-surface.ts` constructs its
237
+ * `.height` re-assertion. The canvas surface constructs its
190
238
  * `Application` with `autoDensity: true`, which makes PIXI ITSELF re-stamp
191
239
  * `canvas.style.width`/`.height` (real CSS px, matching the LOGICAL
192
240
  * width/height passed to `resize()`) on every `app.renderer.resize()` call —
@@ -215,6 +263,7 @@ async function mountOnePixiRoot(spec, ctx) {
215
263
  registerPixiRoot(game, spec.adapter, mounted, {
216
264
  id: spec.id,
217
265
  pausable: spec.pausable,
266
+ declaration: spec.declaration,
218
267
  });
219
268
  return {
220
269
  mountedEntry: {
@@ -271,6 +320,7 @@ layer) {
271
320
  registerReactRoot(game, spec.adapter, mounted, layer, {
272
321
  id: spec.id,
273
322
  pausable: spec.pausable,
323
+ declaration: spec.declaration,
274
324
  });
275
325
  return {
276
326
  mountedEntry: {
@@ -289,8 +339,8 @@ layer) {
289
339
  * per D5 §1, z-order/ties exactly matching
290
340
  * `manifest/load.ts`'s sort, ONE `Game`, and registers every world onto it
291
341
  * via `registerThreeRoot`/`registerPixiRoot`/`registerReactRoot` — the
292
- * SAME wiring `test/game-three-plus-pixi.test.ts` proves by hand for the
293
- * three/pixi pair. Worlds MOUNT in `roots` ARRAY order ("manifest
342
+ * SAME wiring `test/create-runtime-worlds.test.ts` proves for the
343
+ * three/canvas pair. Worlds MOUNT in `roots` ARRAY order ("manifest
294
344
  * declaration order" — the frame/registration axis), independent of
295
345
  * `zOrder` (the canvas-stacking/rendering axis) — the two orders can differ
296
346
  * and both are honored correctly.
@@ -344,37 +394,60 @@ function installDefaultRootDevGlobals(game) {
344
394
  * comment).
345
395
  */
346
396
  async function mountAllRootSpecs(mountSpecs, bottomId, inputs) {
347
- const { surfacesById, ...shared } = inputs;
397
+ const { surfacesById, container, ...shared } = inputs;
348
398
  const mountedEntries = [];
349
399
  const routerEntries = [];
350
- for (const spec of mountSpecs) {
351
- const isBottom = spec.id === bottomId;
352
- if (spec.kind === 'dom') {
353
- const layer = surfacesById.get(spec.id);
354
- const { mountedEntry } = await mountOneReactRoot(spec, shared.game, layer);
400
+ try {
401
+ for (const spec of mountSpecs) {
402
+ const isBottom = spec.id === bottomId;
403
+ if (spec.kind === 'dom') {
404
+ const layer = surfacesById.get(spec.id);
405
+ const { mountedEntry } = await mountOneReactRoot(spec, shared.game, layer);
406
+ mountedEntries.push(mountedEntry);
407
+ continue;
408
+ }
409
+ const canvas = surfacesById.get(spec.id);
410
+ const oneCtx = { ...shared, canvas, isBottom };
411
+ let mountedEntry;
412
+ let routerEntry;
413
+ if (spec.kind === 'three') {
414
+ ({ mountedEntry, routerEntry } = await mountOneThreeRoot(spec, oneCtx));
415
+ }
416
+ else if (spec.kind === 'canvas') {
417
+ ({ mountedEntry, routerEntry } = await mountOnePixiRoot(spec, oneCtx));
418
+ }
419
+ else {
420
+ // Exhaustiveness guard (§7.4-2): 'react' was already handled by the
421
+ // early `continue` above, so only a hypothetical 4th `AdapterSurface` can
422
+ // reach here — fail loudly rather than silently defaulting. `spec`
423
+ // itself (not `spec.kind`) is what TS has narrowed to `never`, since
424
+ // `RootMountSpec` is a discriminated union at the object level.
425
+ assertNever(spec, 'create-runtime mount loop');
426
+ }
355
427
  mountedEntries.push(mountedEntry);
356
- continue;
357
- }
358
- const canvas = surfacesById.get(spec.id);
359
- const oneCtx = { ...shared, canvas, isBottom };
360
- let mountedEntry;
361
- let routerEntry;
362
- if (spec.kind === 'three') {
363
- ({ mountedEntry, routerEntry } = await mountOneThreeRoot(spec, oneCtx));
428
+ routerEntries.push(routerEntry);
364
429
  }
365
- else if (spec.kind === 'canvas') {
366
- ({ mountedEntry, routerEntry } = await mountOnePixiRoot(spec, oneCtx));
367
- }
368
- else {
369
- // Exhaustiveness guard (§7.4-2): 'react' was already handled by the
370
- // early `continue` above, so only a hypothetical 4th `AdapterSurface` can
371
- // reach here fail loudly rather than silently defaulting. `spec`
372
- // itself (not `spec.kind`) is what TS has narrowed to `never`, since
373
- // `RootMountSpec` is a discriminated union at the object level.
374
- assertNever(spec, 'create-runtime mount loop');
430
+ }
431
+ catch (err) {
432
+ // PARTIAL MOUNT ROLLBACK. Roots mount sequentially, so a rejection from
433
+ // root N leaves roots 1..N-1 fully live — renderer, WebGL context, R3F
434
+ // tree, adapter registrations and NOTHING ever gets a handle to them:
435
+ // this function throws instead of returning, so no `GameSession` (and
436
+ // therefore no `stop()`) is ever constructed. Reclaim them here, in
437
+ // REVERSE mount order (the inverse of the order they were built in), then
438
+ // rethrow the ORIGINAL error the mount failure is what the caller must
439
+ // see, never a teardown error raised while cleaning up after it.
440
+ for (let i = mountedEntries.length - 1; i >= 0; i--) {
441
+ const entry = mountedEntries[i];
442
+ try {
443
+ disposeMountedRoot(entry, container);
444
+ }
445
+ catch (disposeErr) {
446
+ // biome-ignore lint/suspicious/noConsole: a rollback failure must be visible; the original mount error is still what we rethrow
447
+ console.error(`createGameRuntime: rolling back root "${entry.id}" after a mount failure threw:`, disposeErr);
448
+ }
375
449
  }
376
- mountedEntries.push(mountedEntry);
377
- routerEntries.push(routerEntry);
450
+ throw err;
378
451
  }
379
452
  return { mountedEntries, routerEntries };
380
453
  }
@@ -424,6 +497,34 @@ function installSessionRenderHarness(game, location, targetOverride) {
424
497
  delete target['__vgaiRender'];
425
498
  };
426
499
  }
500
+ /**
501
+ * Reclaim what `createRootsGameRuntime` built for ITSELF when the mount
502
+ * rejects. `mountAllRootSpecs` has already rolled back every root that DID
503
+ * mount, so what is left is the Game shell (holding whatever registrations
504
+ * those roots made into it) and the stacked surface elements of the roots that
505
+ * never got to mount. Neither is reachable afterwards: the mount throws instead
506
+ * of returning, so no `GameSession` — and therefore no `stop()` — ever exists.
507
+ *
508
+ * Never throws: the MOUNT error is what the caller must see, so a failure while
509
+ * cleaning up after it is reported and swallowed.
510
+ */
511
+ function reclaimAfterMountFailure(game, surfaces, container) {
512
+ try {
513
+ game.dispose();
514
+ }
515
+ catch (disposeErr) {
516
+ // biome-ignore lint/suspicious/noConsole: a failed rollback must be visible; the original mount error is what the caller gets
517
+ console.error('createGameRuntime: disposing the game after a mount failure threw:', disposeErr);
518
+ }
519
+ for (const surface of surfaces) {
520
+ try {
521
+ (surface.parentNode ?? container).removeChild(surface);
522
+ }
523
+ catch {
524
+ /* already detached by the per-root rollback */
525
+ }
526
+ }
527
+ }
427
528
  async function createRootsGameRuntime(config) {
428
529
  const { container, roots: specs, width, height, headless = false, seed, playtest } = config;
429
530
  if (specs.length === 0) {
@@ -514,14 +615,14 @@ async function createRootsGameRuntime(config) {
514
615
  // host's explicit `simulateSubsteps`/`renderOnce` calls — wall-clock time
515
616
  // passing while a screenshot is taken must not move the world.
516
617
  externalDrive: renderMode,
517
- // WO-P13 — sim and presentation are wired to different callbacks here:
618
+ // Sim and presentation are wired to different callbacks here:
518
619
  // `update` runs the gameplay phases once per consumed fixed substep with
519
620
  // `preRender`/`render` withheld, and `render` runs those two once per real
520
621
  // display frame with the interpolation alpha. Both closures are invoked
521
622
  // only from the loop's own rAF arm, which `externalDrive` never arms — so
522
623
  // a capture/offline-export page (`renderMode`) reaches neither, and its
523
624
  // `simulateSubsteps` → `game.runFrame(fixedDt)` path stays frame-exact,
524
- // rendering inside the substep exactly as it did before this flip.
625
+ // rendering inside the substep.
525
626
  update: (dt) => {
526
627
  if (started)
527
628
  game.runFrame(dt, { skipRenderPhases: true });
@@ -537,16 +638,25 @@ async function createRootsGameRuntime(config) {
537
638
  // `createRootsGameRuntime`'s own cyclomatic complexity down (E4) — same
538
639
  // reason `mountOneThreeRoot`/`mountOnePixiRoot` are already split out
539
640
  // below.
540
- const { mountedEntries, routerEntries } = await mountAllRootSpecs(mountSpecs, bottomId, {
541
- game,
542
- surfacesById,
543
- w,
544
- h,
545
- dpr,
546
- headless,
547
- assets,
548
- antialias: config.antialias,
549
- });
641
+ let mounted;
642
+ try {
643
+ mounted = await mountAllRootSpecs(mountSpecs, bottomId, {
644
+ game,
645
+ surfacesById,
646
+ container,
647
+ w,
648
+ h,
649
+ dpr,
650
+ headless,
651
+ assets,
652
+ antialias: config.antialias,
653
+ });
654
+ }
655
+ catch (err) {
656
+ reclaimAfterMountFailure(game, surfacesById.values(), container);
657
+ throw err;
658
+ }
659
+ const { mountedEntries, routerEntries } = mounted;
550
660
  // --- Delegating input router (D5 §2a) ---
551
661
  const router = createInputRouter(container, routerEntries);
552
662
  started = true;
@@ -566,38 +676,53 @@ async function createRootsGameRuntime(config) {
566
676
  resolveStopComplete = resolve;
567
677
  });
568
678
  let stopping = false;
679
+ /**
680
+ * Reclaim EVERYTHING this session owns, and let no single failure stop that.
681
+ *
682
+ * Teardown used to be one `try` over the whole body, so a throwing
683
+ * `entry.mounted.dispose()` on root 1 skipped root 2's disposal, both
684
+ * renderers' `forceContextLoss`, `game.dispose()` and the two global
685
+ * retractions — while `stopComplete` still resolved and the editor still
686
+ * reported the instance reclaimed. Every step is now isolated: a failure is
687
+ * COLLECTED and reported, never allowed to abort the steps after it.
688
+ */
569
689
  function fullCleanup() {
570
690
  if (stopping)
571
691
  return;
572
692
  stopping = true;
693
+ const failures = [];
694
+ /** Run one teardown step; record its failure and keep going. */
695
+ const step = (name, run) => {
696
+ try {
697
+ run();
698
+ }
699
+ catch (error) {
700
+ failures.push({ step: name, error });
701
+ }
702
+ };
573
703
  try {
574
- loop.stop();
575
- router.dispose();
704
+ step('loop.stop', () => loop.stop());
705
+ step('router.dispose', () => router.dispose());
576
706
  for (const entry of mountedEntries) {
577
- entry.mounted.dispose();
578
- entry.renderer?.dispose();
579
- entry.renderer?.forceContextLoss();
580
- // Remove from the element's CURRENT parent, not the mount-time
581
- // `container`: the editor's Game panel re-parents the live surfaces
582
- // when its mount element swaps (fill <-> device preset, W2c), and
583
- // `container.removeChild` would throw NotFoundError after such a move.
584
- // `container` remains the fallback for hosts whose element stand-ins
585
- // never wire `parentNode` (headless unit fixtures); an element already
586
- // detached by such a host is a no-op via the catch.
587
- try {
588
- (entry.element.parentNode ?? container).removeChild(entry.element);
589
- }
590
- catch {
591
- /* already detached — nothing to remove */
592
- }
707
+ step(`root "${entry.id}"`, () => disposeMountedRoot(entry, container));
593
708
  }
594
- game.dispose();
595
- retractDevGlobals();
596
- retractRenderHarness?.();
709
+ step('game.dispose', () => game.dispose());
710
+ step('dev globals', () => retractDevGlobals());
711
+ step('render harness', () => retractRenderHarness?.());
597
712
  }
598
713
  finally {
599
714
  void Promise.allSettled(mountedEntries.map((entry) => entry.mounted.disposeComplete ?? Promise.resolve())).then(() => resolveStopComplete());
600
715
  }
716
+ if (failures.length > 0) {
717
+ // LOUD, and after everything else has been reclaimed. `stop()` is called
718
+ // from hosts that must not be left half-torn-down by an early throw, so
719
+ // the report comes last — but it IS a report: a silent partial teardown
720
+ // is the failure this whole restructure exists to end. The editor's
721
+ // `exitPlayMode` catches it and prints it to the editor console.
722
+ throw new AggregateError(failures.map((f) => f.error), `Game session teardown failed in ${failures.length} step(s): ${failures
723
+ .map((f) => f.step)
724
+ .join(', ')}. Every other step still ran.`);
725
+ }
601
726
  }
602
727
  return {
603
728
  stop: fullCleanup,
@@ -152,6 +152,18 @@ export interface VgaiDebugHandle {
152
152
  * silent no-op.
153
153
  */
154
154
  runTicks(n: number, opts?: RunTicksOptions): void;
155
+ /**
156
+ * The SETTLED-AWARE variant of {@link runTicks} (`runtime/run-ticks-settled.ts` — one
157
+ * implementation with the editor relay's `run-ticks` case, D17): drives the budget one tick
158
+ * at a time and, before each tick, waits for every registered world-settled probe
159
+ * (`DebugRegistry.registerWorldSettledProbe`, declared by the game's `debug.settled` entry
160
+ * export) — so a tick never races a scene remount's async commit, and WHICH tick first runs
161
+ * a freshly reloaded world is a function of the sim rather than wall timing. Session tick
162
+ * drivers (`@vgai/live`'s fastForward) prefer this door; with no probe registered it behaves
163
+ * exactly like {@link runTicks}. Bounded: throws `WORLD_UNSETTLED_TIMEOUT` if a probe never
164
+ * settles.
165
+ */
166
+ runTicksSettled(n: number, opts?: RunTicksOptions): Promise<void>;
155
167
  /**
156
168
  * Collapses `input.setVirtualAction(action, true)` → wait `simSeconds` of
157
169
  * REAL sim time (real ticks — deliberately NOT `runTicks`/fast-forward;
@@ -1 +1 @@
1
- {"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@
15
15
  * field whose runtime reader THIS module is).
16
16
  */
17
17
  import { DebugError } from './debug-registry';
18
+ import { runTicksWhenSettled } from './run-ticks-settled';
18
19
  /** Query-param name that opts a standalone page into the debug bridge (D18) —
19
20
  * mirrors `render-seed.ts`'s `RENDER_MODE_QUERY_PARAM` naming/shape, own
20
21
  * const because this is a different call site with a different flag. */
@@ -216,6 +217,9 @@ function buildDebugHandle(opts) {
216
217
  }
217
218
  target.runTicks(n, runTicksOpts);
218
219
  },
220
+ runTicksSettled(n, runTicksOpts) {
221
+ return runTicksWhenSettled(registry, n, runTicksOpts);
222
+ },
219
223
  async holdFor(action, simSeconds, worldId) {
220
224
  const target = requireInputTarget('holdFor', worldId);
221
225
  const setResult = target.setVirtualAction(action, true);