@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,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
@@ -25,7 +25,83 @@ import type { DebugAdapter, DebugCommandInfo, TickStampedEvent } from '../adapte
25
25
  import { createGameScopedSlot } from '../core/game-scoped-slot';
26
26
  import type { GameLoopLiveness } from '../core/types';
27
27
  import type { Game } from './game';
28
- import type { DebugCommandArgs, DebugCtxSurface, DebugRoomHandle } from './types';
28
+
29
+ /**
30
+ * The minimal structural shape `ctx.debug.attachRoom` needs from a joined
31
+ * Colyseus room: just enough to send the reserved `__vgai:debugCommand`
32
+ * message and listen for its `__vgai:debugCommandResult` reply. Structural,
33
+ * not a Colyseus type import — the same seam-boundary style every other
34
+ * `DebugCtxSurface` member uses (no wrapper around Colyseus itself, D2).
35
+ * `onMessage`'s return type is `unknown` because Colyseus's own return shape
36
+ * (void in some client versions, an unsubscribe function in others) isn't
37
+ * load-bearing here: the registry calls it defensively (invokes it on detach
38
+ * only if it's actually a function).
39
+ */
40
+ export interface DebugRoomHandle {
41
+ send(type: string, message?: unknown): void;
42
+ onMessage(type: string, cb: (message: unknown) => void): unknown;
43
+ }
44
+
45
+ /**
46
+ * Infers a `registerCommand`/`registerReactCommand`/`useDebugCommand`
47
+ * handler's parameter tuple from its declared Zod `args` tuple (dry-run
48
+ * finding, ledger — "`registerCommand` fn typing forces `unknown[]` casts"):
49
+ * a real `z.ZodTuple` infers its element types (`z.tuple([z.number(),
50
+ * z.string()])` → `(n: number, s: string) => ...`), while omitting `args`
51
+ * (the generic's `undefined` default) resolves to the original permissive
52
+ * `(...args: unknown[]) => ...` shape every command had before this generic
53
+ * existed. That permissive fallback is deliberate, not just a placeholder —
54
+ * it keeps every existing no-schema registration (including ones whose
55
+ * handler reads positional args the runtime never validates, since
56
+ * `invoke()` only parses `args` against a schema when one is declared)
57
+ * compiling byte-for-byte unchanged.
58
+ */
59
+ export type DebugCommandArgs<T extends z.ZodTuple | undefined = undefined> = T extends z.ZodTuple
60
+ ? z.infer<T>
61
+ : unknown[];
62
+
63
+ /**
64
+ * The authoring half of the debug/synthetic-player seam — the read/actuate half is
65
+ * `SystemAdapters.DebugAdapter` (`adapter/system-adapter.ts`). Callable from any
66
+ * `init` (one file per new provider/command), or from a react world's
67
+ * `useDebugProvider`/`useDebugCommand`/`useDebugEmit` hooks. Every registration feeds the ONE
68
+ * game-scoped registry (`runtime/debug-registry.ts`) — never a per-world accumulator.
69
+ */
70
+ export interface DebugCtxSurface {
71
+ /** Register (or replace) a named, JSON-serializable state read. Duplicate
72
+ * names from the SAME world replace + warn once; the SAME name from a
73
+ * DIFFERENT world throws (`DebugError` code `DEBUG_NAME_COLLISION`). */
74
+ registerStateProvider(
75
+ name: string,
76
+ fn: () => unknown,
77
+ opts?: { tier?: 'observable' | 'assisted' },
78
+ ): void;
79
+ /** Register (or replace) an invokable command. `locus` is REQUIRED once the
80
+ * project declares a Colyseus room (`DebugRegistry.setRoomDeclared`) — a
81
+ * fixture must say whether it mutates authoritative (server) or predicted
82
+ * (client) state.
83
+ *
84
+ * Generic over the declared `args` Zod tuple ({@link DebugCommandArgs}) so
85
+ * `fn`'s parameters INFER from it: `registerCommand('setHp', { args:
86
+ * z.tuple([z.number()]) }, (hp) => ...)` types `hp` as `number` with no
87
+ * cast. Leaving `args` off keeps `fn` typed `(...args: unknown[]) => ...`,
88
+ * same as before this generic existed. */
89
+ registerCommand<T extends z.ZodTuple | undefined = undefined>(
90
+ name: string,
91
+ spec: { description?: string; args?: T; locus?: 'client' | 'server' },
92
+ fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>,
93
+ ): void;
94
+ /** Push a tick-stamped event onto the debug event ring (spec §3.3) — the
95
+ * engine stamps `tick`/`simT` at emission, not at read time. */
96
+ emit(event: string, detail?: unknown): void;
97
+ /**
98
+ * Task 2.2 — server-locus command routing (client leg). Call once your
99
+ * game code has joined its Colyseus room, so `locus: 'server'` commands
100
+ * have somewhere to send `__vgai:debugCommand`. Returns a detach function
101
+ * (call on room leave/dispose) — game-scoped, last-attached room wins.
102
+ */
103
+ attachRoom(room: DebugRoomHandle): () => void;
104
+ }
29
105
 
30
106
  /** Engine-local error for the debug seam — mirrors the `code` + `data` shape
31
107
  * `packages/vgai-sdk/src/errors.ts` uses (no import: the engine does not
@@ -74,7 +150,7 @@ const SERVER_COMMAND_TIMEOUT_MS = 10_000;
74
150
  * actuates through — the SAME three methods `InputManager` exposes
75
151
  * (`setVirtualAction`/`tapVirtualAction`/`clearVirtualActions`, Task 1.4),
76
152
  * typed narrowly here so this module never imports `InputManager` itself.
77
- * Wired once by the hosting adapter (`setup-three-root-adapter.ts`, at the
153
+ * Wired once by the hosting adapter (`world3d-react/r3f-root-factory.tsx`, at the
78
154
  * same seed spot as `setInputActionsSource`) — absent until then. */
79
155
  export interface DebugVirtualInputTarget {
80
156
  setVirtualAction(
@@ -187,7 +263,7 @@ interface CommandEntry {
187
263
 
188
264
  /** What {@link createDebugRegistry} returns — the adapter half (`DebugAdapter`,
189
265
  * for `SystemAdapters.debug`) plus the registration/lifecycle surface the
190
- * hosting adapter (`setup-three-root-adapter.ts`) and `createGame` drive. */
266
+ * hosting adapter (`world3d-react/r3f-root-factory.tsx`) and `createGame` drive. */
191
267
  export interface DebugRegistry {
192
268
  /** The `SystemAdapters.debug` implementer — one shared instance, seeded
193
269
  * onto every world's adapter bag. */
@@ -238,7 +314,7 @@ export interface DebugRegistry {
238
314
  * `{version: 1, seed: null, fixedDt: null, ticks: []}`. `seed`/`fixedDt`
239
315
  * are the two replay-critical metadata fields the design doc's format
240
316
  * sketch (§2.c) calls for beside the raw per-tick deltas — the wiring
241
- * adapter (`setup-three-root-adapter.ts`) assembles them from
317
+ * adapter (`world3d-react/r3f-root-factory.tsx`) assembles them from
242
318
  * `getSeededRandom(game)?.seed`/`host.game?.loop.fixedDt` alongside
243
319
  * `InputManager.getInputTrace()`'s own `{version, ticks}`. An `engine`
244
320
  * (package version) stamp remains a KNOWN GAP — no build-time version
@@ -297,7 +373,7 @@ export interface DebugRegistry {
297
373
  /** D15/T-D15.3/.5 — the CURRENT shared game tick (the same counter the
298
374
  * built-in `time` provider's `tick` field reads), for a per-world
299
375
  * `InputManager.poll(tick)` call to key its `scheduleActionAtTick`
300
- * numbering off — see `setup-three-root-adapter.ts`'s `systems.add('input',
376
+ * numbering off — see `world3d-react/r3f-root-factory.tsx`'s `systems.add('input',
301
377
  * ...)` wiring. `0` for a bare `createDebugRegistry()` test stand-in with
302
378
  * no real `Game`/tick counter behind it (matching `getTick`'s own
303
379
  * constructor-supplied default in that case). */
@@ -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`.
@@ -0,0 +1,108 @@
1
+ /**
2
+ * The GAME-SCOPED input wiring one world mount owns — HOST work performed from
3
+ * outside the world's own tree, shared verbatim by the three and canvas lanes
4
+ * (a project has ONE input map and one bot-input doctrine, whatever surface
5
+ * reads them).
6
+ *
7
+ * Two things happen here:
8
+ *
9
+ * 1. the project's input map is loaded through `Game.loadInputMap` (game-owned,
10
+ * load-once), so the actions the project declared exist;
11
+ * 2. this root's seams are registered on the game-scoped debug registry
12
+ * (`setVirtualInputTarget`/`setInputActionsSource`/`setInputTraceSource`),
13
+ * which is what makes `game.input.hold/tap/...` (the bot/`vgai eval` input
14
+ * doctrine) and the built-in `input.actions`/`input.trace` providers
15
+ * resolve to this world instead of throwing `DEBUG_INPUT_UNAVAILABLE`.
16
+ *
17
+ * A world's React tree receives no vgai context — this wiring is precisely the
18
+ * part that never needed one: every closure below reads GAME-scoped state the
19
+ * host owns (`game.input`, `game.loop.fixedDt`, the game's seed).
20
+ *
21
+ * `optionalInputMap` is the CONVENTIONAL-PATH probe used when the project
22
+ * never named a map: an absent file is the ordinary state of a brand-new
23
+ * project, so it resolves quietly instead of printing an error on every boot.
24
+ * A map that exists and fails to parse is as loud as ever.
25
+ *
26
+ * LIFETIME, honestly: `registry.strip(id)` runs on the mount's dispose, but it
27
+ * walks providers/commands only — the three seams set here survive it, keyed
28
+ * by this world's id, until a remount of the same id overwrites them. That
29
+ * residue is inert rather than hidden: every closure reads game-scoped state,
30
+ * so a stale entry actuates exactly what a live one would. What it can still
31
+ * do is name a dead world in `DEBUG_INPUT_WORLD_NOT_FOUND`'s registered list.
32
+ * Do not write "the strip clears the input seams" anywhere without changing
33
+ * `strip` to actually do it.
34
+ */
35
+
36
+ import type { HostGameHandle } from '../adapter/host-context';
37
+ import { getSeededRandom } from '../core/seeded-random';
38
+ import type { DebugRegistry } from './debug-registry';
39
+
40
+ /** The conventional input-map location every scaffolded project ships
41
+ * (`public/inputmaps/default.inputmap.json`). */
42
+ export const DEFAULT_INPUT_MAP_PATH = '/inputmaps/default.inputmap.json';
43
+
44
+ /** The slice of a host context this wiring reads — satisfied structurally by
45
+ * both `ThreeHostContext` and `CanvasHostContext`. */
46
+ export interface GameInputSeamHost {
47
+ readonly game?: HostGameHandle | null | undefined;
48
+ readonly headless?: boolean | undefined;
49
+ }
50
+
51
+ export function wireGameInputSeams(
52
+ host: GameInputSeamHost,
53
+ registry: DebugRegistry,
54
+ options: {
55
+ readonly id: string;
56
+ readonly inputMapPath?: string | null | undefined;
57
+ readonly optionalInputMap?: boolean | undefined;
58
+ },
59
+ ): Promise<void> {
60
+ const { id, inputMapPath = DEFAULT_INPUT_MAP_PATH, optionalInputMap = false } = options;
61
+ if (!host.game) return Promise.resolve();
62
+ const game = host.game;
63
+ const input = game.input;
64
+ registry.setInputActionsSource(id, () =>
65
+ input.actionNames().map((name) => ({ name, valueType: input.getActionValueType(name) })),
66
+ );
67
+ registry.setInputTraceSource(id, () => {
68
+ const raw = input.getInputTrace();
69
+ return {
70
+ version: raw.version,
71
+ seed: getSeededRandom(game)?.seed ?? null,
72
+ fixedDt: game.loop.fixedDt,
73
+ ticks: raw.ticks,
74
+ };
75
+ });
76
+ registry.setVirtualInputTarget(id, {
77
+ setVirtualAction: (action, value) => input.setVirtualAction(action, value),
78
+ tapVirtualAction: (action) => input.tapVirtualAction(action),
79
+ clearVirtualActions: () => input.clearVirtualActions(),
80
+ scheduleActionAtTick: (tick, action, value) => input.scheduleActionAtTick(tick, action, value),
81
+ startInputRecording: () => input.startInputRecording(),
82
+ stopInputRecording: () => input.stopInputRecording(),
83
+ isInputRecording: () => input.isInputRecording(),
84
+ injectAxis: (sourceId, value) => input.injectAxis(sourceId, value),
85
+ injectVector2: (sourceId, value) => input.injectVector2(sourceId, value),
86
+ injectPointerDelta: (sourceId, delta) => input.injectPointerDelta(sourceId, delta),
87
+ injectPointerPosition: (sourceId, value) => input.injectPointerPosition(sourceId, value),
88
+ });
89
+ if (host.headless || inputMapPath === null) return Promise.resolve();
90
+ // Load-once through the game-owned path (competing paths across roots throw
91
+ // THERE, loudly). A FAILED load (missing/bad file) must not fail the mount:
92
+ // a world with no declared actions is legal. It degrades loudly instead —
93
+ // naming exactly what breaks.
94
+ // The non-optional call passes ONE argument, exactly as it always has — a
95
+ // trailing `undefined` is a different call to any observer of it.
96
+ const load = optionalInputMap
97
+ ? game.loadInputMap(inputMapPath, { optional: true })
98
+ : game.loadInputMap(inputMapPath);
99
+ return load.catch((err: unknown) => {
100
+ // biome-ignore lint/suspicious/noConsole: deliberate loud degrade — the documented alternative to failing the mount (see comment above)
101
+ console.error(
102
+ `world "${id}": failed to load input map "${inputMapPath}" — declared input ` +
103
+ 'actions and `game.input.*` (bot/virtual input) will not work until a valid map ' +
104
+ `loads. Ship one at the conventional path (${DEFAULT_INPUT_MAP_PATH}). ` +
105
+ `Cause: ${err instanceof Error ? err.message : String(err)}`,
106
+ );
107
+ });
108
+ }