@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
@@ -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,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The game-scoped debug/synthetic-player registry. ONE registry per `Game` root —
3
- * every world's `ctx.debug` (see `DebugCtxSurface`, `runtime/types.ts`) feeds the
3
+ * every world's `ctx.debug` (see {@link DebugCtxSurface} below) feeds the
4
4
  * SAME registry via {@link DebugRegistry.forRoot}, so a name a game registers is
5
5
  * visible (and name-collision-checked) across every world, not just the one that
6
6
  * registered it. `createGame` (`runtime/game.ts`) constructs the registry
@@ -10,8 +10,8 @@
10
10
  * rather than threading it through every call site.
11
11
  *
12
12
  * Provenance note: a registration's "world" is the MOUNT's adapter id (the
13
- * `fromSetup(id, ...)` / `SetupThreeRootConfig.id` a project already names each
14
- * world's entry with) rather than the `RootInstance.id` `registerThreeRoot`
13
+ * id a project's root adapter already carries) rather than the
14
+ * `RootInstance.id` `registerThreeRoot`
15
15
  * assigns — that id isn't known until AFTER `mount()` resolves (`create-
16
16
  * runtime.ts` calls `registerThreeRoot` with it only once `mount()` returns),
17
17
  * which is after every `setup()`-time registration has already run. For the
@@ -23,7 +23,76 @@ import { z } from 'zod';
23
23
  import type { DebugAdapter } from '../adapter/system-adapter';
24
24
  import type { GameLoopLiveness } from '../core/types';
25
25
  import type { Game } from './game';
26
- import type { DebugCommandArgs, DebugCtxSurface } from './types';
26
+ /**
27
+ * The minimal structural shape `ctx.debug.attachRoom` needs from a joined
28
+ * Colyseus room: just enough to send the reserved `__vgai:debugCommand`
29
+ * message and listen for its `__vgai:debugCommandResult` reply. Structural,
30
+ * not a Colyseus type import — the same seam-boundary style every other
31
+ * `DebugCtxSurface` member uses (no wrapper around Colyseus itself, D2).
32
+ * `onMessage`'s return type is `unknown` because Colyseus's own return shape
33
+ * (void in some client versions, an unsubscribe function in others) isn't
34
+ * load-bearing here: the registry calls it defensively (invokes it on detach
35
+ * only if it's actually a function).
36
+ */
37
+ export interface DebugRoomHandle {
38
+ send(type: string, message?: unknown): void;
39
+ onMessage(type: string, cb: (message: unknown) => void): unknown;
40
+ }
41
+ /**
42
+ * Infers a `registerCommand`/`registerReactCommand`/`useDebugCommand`
43
+ * handler's parameter tuple from its declared Zod `args` tuple (dry-run
44
+ * finding, ledger — "`registerCommand` fn typing forces `unknown[]` casts"):
45
+ * a real `z.ZodTuple` infers its element types (`z.tuple([z.number(),
46
+ * z.string()])` → `(n: number, s: string) => ...`), while omitting `args`
47
+ * (the generic's `undefined` default) resolves to the original permissive
48
+ * `(...args: unknown[]) => ...` shape every command had before this generic
49
+ * existed. That permissive fallback is deliberate, not just a placeholder —
50
+ * it keeps every existing no-schema registration (including ones whose
51
+ * handler reads positional args the runtime never validates, since
52
+ * `invoke()` only parses `args` against a schema when one is declared)
53
+ * compiling byte-for-byte unchanged.
54
+ */
55
+ export type DebugCommandArgs<T extends z.ZodTuple | undefined = undefined> = T extends z.ZodTuple ? z.infer<T> : unknown[];
56
+ /**
57
+ * The authoring half of the debug/synthetic-player seam — the read/actuate half is
58
+ * `SystemAdapters.DebugAdapter` (`adapter/system-adapter.ts`). Callable from any
59
+ * `init` (one file per new provider/command), or from a react world's
60
+ * `useDebugProvider`/`useDebugCommand`/`useDebugEmit` hooks. Every registration feeds the ONE
61
+ * game-scoped registry (`runtime/debug-registry.ts`) — never a per-world accumulator.
62
+ */
63
+ export interface DebugCtxSurface {
64
+ /** Register (or replace) a named, JSON-serializable state read. Duplicate
65
+ * names from the SAME world replace + warn once; the SAME name from a
66
+ * DIFFERENT world throws (`DebugError` code `DEBUG_NAME_COLLISION`). */
67
+ registerStateProvider(name: string, fn: () => unknown, opts?: {
68
+ tier?: 'observable' | 'assisted';
69
+ }): void;
70
+ /** Register (or replace) an invokable command. `locus` is REQUIRED once the
71
+ * project declares a Colyseus room (`DebugRegistry.setRoomDeclared`) — a
72
+ * fixture must say whether it mutates authoritative (server) or predicted
73
+ * (client) state.
74
+ *
75
+ * Generic over the declared `args` Zod tuple ({@link DebugCommandArgs}) so
76
+ * `fn`'s parameters INFER from it: `registerCommand('setHp', { args:
77
+ * z.tuple([z.number()]) }, (hp) => ...)` types `hp` as `number` with no
78
+ * cast. Leaving `args` off keeps `fn` typed `(...args: unknown[]) => ...`,
79
+ * same as before this generic existed. */
80
+ registerCommand<T extends z.ZodTuple | undefined = undefined>(name: string, spec: {
81
+ description?: string;
82
+ args?: T;
83
+ locus?: 'client' | 'server';
84
+ }, fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>): void;
85
+ /** Push a tick-stamped event onto the debug event ring (spec §3.3) — the
86
+ * engine stamps `tick`/`simT` at emission, not at read time. */
87
+ emit(event: string, detail?: unknown): void;
88
+ /**
89
+ * Task 2.2 — server-locus command routing (client leg). Call once your
90
+ * game code has joined its Colyseus room, so `locus: 'server'` commands
91
+ * have somewhere to send `__vgai:debugCommand`. Returns a detach function
92
+ * (call on room leave/dispose) — game-scoped, last-attached room wins.
93
+ */
94
+ attachRoom(room: DebugRoomHandle): () => void;
95
+ }
27
96
  /** Engine-local error for the debug seam — mirrors the `code` + `data` shape
28
97
  * `packages/vgai-sdk/src/errors.ts` uses (no import: the engine does not
29
98
  * depend on `@vgai/sdk`). `code` is always machine-readable; nothing reading
@@ -37,7 +106,7 @@ export declare class DebugError extends Error {
37
106
  * actuates through — the SAME three methods `InputManager` exposes
38
107
  * (`setVirtualAction`/`tapVirtualAction`/`clearVirtualActions`, Task 1.4),
39
108
  * typed narrowly here so this module never imports `InputManager` itself.
40
- * Wired once by the hosting adapter (`setup-three-root-adapter.ts`, at the
109
+ * Wired once by the hosting adapter (`world3d-react/r3f-root-factory.tsx`, at the
41
110
  * same seed spot as `setInputActionsSource`) — absent until then. */
42
111
  export interface DebugVirtualInputTarget {
43
112
  setVirtualAction(action: string, value: boolean | number | {
@@ -115,7 +184,7 @@ export interface RunTicksTarget {
115
184
  }
116
185
  /** What {@link createDebugRegistry} returns — the adapter half (`DebugAdapter`,
117
186
  * for `SystemAdapters.debug`) plus the registration/lifecycle surface the
118
- * hosting adapter (`setup-three-root-adapter.ts`) and `createGame` drive. */
187
+ * hosting adapter (`world3d-react/r3f-root-factory.tsx`) and `createGame` drive. */
119
188
  export interface DebugRegistry {
120
189
  /** The `SystemAdapters.debug` implementer — one shared instance, seeded
121
190
  * onto every world's adapter bag. */
@@ -169,7 +238,7 @@ export interface DebugRegistry {
169
238
  * `{version: 1, seed: null, fixedDt: null, ticks: []}`. `seed`/`fixedDt`
170
239
  * are the two replay-critical metadata fields the design doc's format
171
240
  * sketch (§2.c) calls for beside the raw per-tick deltas — the wiring
172
- * adapter (`setup-three-root-adapter.ts`) assembles them from
241
+ * adapter (`world3d-react/r3f-root-factory.tsx`) assembles them from
173
242
  * `getSeededRandom(game)?.seed`/`host.game?.loop.fixedDt` alongside
174
243
  * `InputManager.getInputTrace()`'s own `{version, ticks}`. An `engine`
175
244
  * (package version) stamp remains a KNOWN GAP — no build-time version
@@ -228,7 +297,7 @@ export interface DebugRegistry {
228
297
  /** D15/T-D15.3/.5 — the CURRENT shared game tick (the same counter the
229
298
  * built-in `time` provider's `tick` field reads), for a per-world
230
299
  * `InputManager.poll(tick)` call to key its `scheduleActionAtTick`
231
- * numbering off — see `setup-three-root-adapter.ts`'s `systems.add('input',
300
+ * numbering off — see `world3d-react/r3f-root-factory.tsx`'s `systems.add('input',
232
301
  * ...)` wiring. `0` for a bare `createDebugRegistry()` test stand-in with
233
302
  * no real `Game`/tick counter behind it (matching `getTick`'s own
234
303
  * constructor-supplied default in that case). */
@@ -1 +1 @@
1
- {"version":3,"file":"debug-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,2BAA2B,CAAC;AAElG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAmB,MAAM,SAAS,CAAC;AAElF;;;8CAG8C;AAC9C,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;gBAExC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAM1E;AA6BD;;;;;sEAKsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GACjD;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,mBAAmB,IAAI,IAAI,CAAC;IAC5B;;4BAEwB;IACxB,oBAAoB,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GACjD,IAAI,CAAC;IACR,mBAAmB,IAAI,IAAI,CAAC;IAC5B,kBAAkB,IAAI,IAAI,CAAC;IAC3B,gBAAgB,IAAI,OAAO,CAAC;IAC5B;;;8EAG0E;IAC1E,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5E,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAChF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED;;;;iEAIiE;AACjE,MAAM,WAAW,eAAe;IAC9B;;kCAE8B;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;CAClC;AAED;;;kEAGkE;AAClE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACnD;AA+CD;;8EAE8E;AAC9E,MAAM,WAAW,aAAa;IAC5B;0CACsC;IACtC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B;iFAC6E;IAC7E,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAAC;IAC1C;;;sDAGkD;IAClD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACjD;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;kEAC8D;IAC9D,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzC;;;;;;6EAMyE;IACzE,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,IAAI,CAAC;IAC9F;;;;;;;;;;;;iFAY6E;IAC7E,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAAC;IACzE;;;;;;;;;;;;;;;;gFAgB4E;IAC5E,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC9E;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAAC;IACxE;;;;;;;;;OASG;IACH,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAChD;;;;iDAI6C;IAC7C,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAAC;IAC3C;;;;;;sDAMkD;IAClD,WAAW,IAAI,MAAM,CAAC;IACtB;;;;;;;;iBAQa;IACb,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,EACjB,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,YAAY,GAAG,UAAU,GAAG,SAAS,CAAA;KAAE,GACtD,MAAM,IAAI,CAAC;IACd;;sCAEkC;IAClC,oBAAoB,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,GAAG,SAAS,GAAG,SAAS,EAC/D,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;KAAE,EACrE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAC/D,MAAM,IAAI,CAAC;CACf;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,OAAO,IAAI,MAAM,CAAC;IAClB,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,IAAI,gBAAgB,CAAC;CACtC,GAAG,aAAa,CAwfhB;AAID;kFACkF;AAClF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAE/E;AAED;;8EAE8E;AAC9E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,GAAG,IAAI,CAEjE"}
1
+ {"version":3,"file":"debug-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-registry.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The game-scoped debug/synthetic-player registry. ONE registry per `Game` root —
3
- * every world's `ctx.debug` (see `DebugCtxSurface`, `runtime/types.ts`) feeds the
3
+ * every world's `ctx.debug` (see {@link DebugCtxSurface} below) feeds the
4
4
  * SAME registry via {@link DebugRegistry.forRoot}, so a name a game registers is
5
5
  * visible (and name-collision-checked) across every world, not just the one that
6
6
  * registered it. `createGame` (`runtime/game.ts`) constructs the registry
@@ -10,8 +10,8 @@
10
10
  * rather than threading it through every call site.
11
11
  *
12
12
  * Provenance note: a registration's "world" is the MOUNT's adapter id (the
13
- * `fromSetup(id, ...)` / `SetupThreeRootConfig.id` a project already names each
14
- * world's entry with) rather than the `RootInstance.id` `registerThreeRoot`
13
+ * id a project's root adapter already carries) rather than the
14
+ * `RootInstance.id` `registerThreeRoot`
15
15
  * assigns — that id isn't known until AFTER `mount()` resolves (`create-
16
16
  * runtime.ts` calls `registerThreeRoot` with it only once `mount()` returns),
17
17
  * which is after every `setup()`-time registration has already run. For the
@@ -9,8 +9,8 @@
9
9
  *
10
10
  * Ownership, stated in one place (the build rule):
11
11
  * - OWNER: this function. It resolves the answer; nothing else derives it.
12
- * - SHARERS: the two three-root adapters (`adapter/setup-three-root-adapter.ts`
13
- * and `world3d-react/r3f-adapter.tsx`), which seed live render vitals only
12
+ * - SHARERS: the three-root adapter (`world3d-react/r3f-root-factory.tsx`),
13
+ * which seeds live render vitals only
14
14
  * under it, and the `static-batch` capability's mutation watch and `Frozen`
15
15
  * warning. Any future dev-only instrument calls this too, with its own
16
16
  * `override`.