@vgai/engine 0.3.0 → 0.4.0-canary.20260715.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (559) hide show
  1. package/package.json +8 -2
  2. package/schemas/engine-api.json +124 -0
  3. package/schemas/engine-api.md +53 -0
  4. package/schemas/engine-capabilities.json +124 -0
  5. package/schemas/inputmap.schema.json +314 -0
  6. package/schemas/mat.schema.json +286 -0
  7. package/schemas/prefab.schema.json +10148 -0
  8. package/schemas/scn2d.schema.json +475 -0
  9. package/schemas/vgai-game.schema.json +383 -0
  10. package/schemas/vscn.schema.json +11007 -0
  11. package/src/adapter/{world-kind.ts → adapter-surface.ts} +6 -6
  12. package/src/adapter/authoring.ts +67 -0
  13. package/src/adapter/game-adapter.ts +8 -8
  14. package/src/adapter/host-context.ts +2 -4
  15. package/src/adapter/index.ts +3 -1
  16. package/src/adapter/system-adapter.ts +73 -0
  17. package/src/adapter/vgai-scene-game-adapter.ts +239 -180
  18. package/src/animation/xstate-animation-binding.ts +300 -262
  19. package/src/animation/xstate-animation-meta.ts +50 -13
  20. package/src/character/cloth-sim.ts +533 -0
  21. package/src/character/spring-chain.ts +307 -0
  22. package/src/core/game-loop.ts +41 -3
  23. package/src/core/seeded-random.ts +161 -0
  24. package/src/core/system-runner.ts +20 -3
  25. package/src/core/types.ts +37 -0
  26. package/src/data/data-asset.ts +1 -1
  27. package/src/dev/performance-profiler.ts +213 -0
  28. package/src/dev/webgl-gpu-timer.ts +53 -0
  29. package/src/ecs/component-manager.ts +45 -12
  30. package/src/ecs/game-component.ts +95 -11
  31. package/src/humanoid/bake.operation.ts +326 -0
  32. package/src/humanoid/body.ts +663 -0
  33. package/src/humanoid/clips.ts +149 -0
  34. package/src/humanoid/compose.ts +209 -0
  35. package/src/humanoid/generate.ts +189 -0
  36. package/src/humanoid/index.ts +36 -0
  37. package/src/humanoid/schema.ts +108 -0
  38. package/src/humanoid/skeleton.ts +345 -0
  39. package/src/index.ts +5 -5
  40. package/src/input/input-manager.ts +701 -22
  41. package/src/input/input-types.ts +5 -2
  42. package/src/manifest/index.ts +5 -5
  43. package/src/manifest/load.ts +125 -72
  44. package/src/manifest/schema.ts +362 -255
  45. package/src/react/game-state.tsx +135 -32
  46. package/src/react/root-adapter.tsx +49 -0
  47. package/src/react/unmanaged-root-detector.ts +66 -0
  48. package/src/react/use-data.ts +12 -2
  49. package/src/runtime/create-runtime.ts +100 -282
  50. package/src/runtime/debug-bridge.ts +483 -0
  51. package/src/runtime/debug-registry.ts +856 -0
  52. package/src/runtime/game.ts +342 -93
  53. package/src/runtime/gameplay-rng-trap.ts +134 -0
  54. package/src/runtime/input-router.ts +7 -7
  55. package/src/runtime/mount-game.ts +40 -38
  56. package/src/runtime/mount-manifest.ts +169 -37
  57. package/src/runtime/render-control.ts +13 -13
  58. package/src/runtime/render-seed.ts +1 -1
  59. package/src/runtime/state-bridge.ts +24 -10
  60. package/src/runtime/types.ts +110 -28
  61. package/src/scene/asset-registry.ts +22 -0
  62. package/src/scene/component-registry.ts +14 -3
  63. package/src/scene/defaults.ts +1 -0
  64. package/src/scene/light-camera-factory.ts +11 -3
  65. package/src/scene/scene-apply.ts +55 -4
  66. package/src/scene/scene-loader.ts +10 -27
  67. package/src/scene/scene-types.ts +0 -1
  68. package/src/scene/schema/index.ts +0 -34
  69. package/src/scene/schema/light.ts +16 -1
  70. package/src/scene/schema/material.ts +96 -91
  71. package/src/scene/schema/scene-file.ts +1 -7
  72. package/src/scene/user-data.ts +14 -1
  73. package/src/setup/setup-renderer.ts +1 -1
  74. package/src/tools/define-tool.ts +50 -11
  75. package/src/world2d/authoring-2d.ts +17 -1
  76. package/src/world2d/collision-2d.ts +1 -1
  77. package/src/world2d/pixi-game-adapter.ts +19 -17
  78. package/src/world2d/scene2d-loader.ts +1 -0
  79. package/src/world2d/types.ts +8 -2
  80. package/dist/adapter/authoring.d.ts +0 -404
  81. package/dist/adapter/authoring.d.ts.map +0 -1
  82. package/dist/adapter/authoring.js +0 -22
  83. package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
  84. package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
  85. package/dist/adapter/colyseus-networking-adapter.js +0 -38
  86. package/dist/adapter/first-party-systems.d.ts +0 -38
  87. package/dist/adapter/first-party-systems.d.ts.map +0 -1
  88. package/dist/adapter/first-party-systems.js +0 -77
  89. package/dist/adapter/game-adapter.d.ts +0 -133
  90. package/dist/adapter/game-adapter.d.ts.map +0 -1
  91. package/dist/adapter/game-adapter.js +0 -10
  92. package/dist/adapter/host-context.d.ts +0 -73
  93. package/dist/adapter/host-context.d.ts.map +0 -1
  94. package/dist/adapter/host-context.js +0 -16
  95. package/dist/adapter/index.d.ts +0 -22
  96. package/dist/adapter/index.d.ts.map +0 -1
  97. package/dist/adapter/index.js +0 -15
  98. package/dist/adapter/ingest/game-contract.d.ts +0 -53
  99. package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
  100. package/dist/adapter/ingest/game-contract.js +0 -30
  101. package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
  102. package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
  103. package/dist/adapter/ingest/overlay-applier.js +0 -132
  104. package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
  105. package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
  106. package/dist/adapter/ingest/overlay-apply.js +0 -101
  107. package/dist/adapter/ingest/overlay-file.d.ts +0 -79
  108. package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
  109. package/dist/adapter/ingest/overlay-file.js +0 -66
  110. package/dist/adapter/ingest/overlay-report.d.ts +0 -113
  111. package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
  112. package/dist/adapter/ingest/overlay-report.js +0 -103
  113. package/dist/adapter/ingest/scene-capture.d.ts +0 -97
  114. package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
  115. package/dist/adapter/ingest/scene-capture.js +0 -248
  116. package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
  117. package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
  118. package/dist/adapter/ingest/upstream-pin.js +0 -50
  119. package/dist/adapter/loop-gate-report.d.ts +0 -34
  120. package/dist/adapter/loop-gate-report.d.ts.map +0 -1
  121. package/dist/adapter/loop-gate-report.js +0 -37
  122. package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
  123. package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
  124. package/dist/adapter/rapier-physics-adapter.js +0 -46
  125. package/dist/adapter/system-adapter.d.ts +0 -133
  126. package/dist/adapter/system-adapter.d.ts.map +0 -1
  127. package/dist/adapter/system-adapter.js +0 -13
  128. package/dist/adapter/transform.d.ts +0 -18
  129. package/dist/adapter/transform.d.ts.map +0 -1
  130. package/dist/adapter/transform.js +0 -1
  131. package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -116
  132. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
  133. package/dist/adapter/vgai-scene-game-adapter.js +0 -714
  134. package/dist/adapter/world-kind.d.ts +0 -30
  135. package/dist/adapter/world-kind.d.ts.map +0 -1
  136. package/dist/adapter/world-kind.js +0 -18
  137. package/dist/ai/navigation.d.ts +0 -64
  138. package/dist/ai/navigation.d.ts.map +0 -1
  139. package/dist/ai/navigation.js +0 -133
  140. package/dist/animation/anim-graph-types.d.ts +0 -25
  141. package/dist/animation/anim-graph-types.d.ts.map +0 -1
  142. package/dist/animation/anim-graph-types.js +0 -1
  143. package/dist/animation/animation-clock.d.ts +0 -213
  144. package/dist/animation/animation-clock.d.ts.map +0 -1
  145. package/dist/animation/animation-clock.js +0 -301
  146. package/dist/animation/blend-node.d.ts +0 -22
  147. package/dist/animation/blend-node.d.ts.map +0 -1
  148. package/dist/animation/blend-node.js +0 -97
  149. package/dist/animation/camera-ownership.d.ts +0 -250
  150. package/dist/animation/camera-ownership.d.ts.map +0 -1
  151. package/dist/animation/camera-ownership.js +0 -169
  152. package/dist/animation/cinematic-cues.d.ts +0 -200
  153. package/dist/animation/cinematic-cues.d.ts.map +0 -1
  154. package/dist/animation/cinematic-cues.js +0 -213
  155. package/dist/animation/clip-map.d.ts +0 -12
  156. package/dist/animation/clip-map.d.ts.map +0 -1
  157. package/dist/animation/clip-map.js +0 -37
  158. package/dist/animation/gsap-registration.d.ts +0 -119
  159. package/dist/animation/gsap-registration.d.ts.map +0 -1
  160. package/dist/animation/gsap-registration.js +0 -92
  161. package/dist/animation/theatre-clock-binding.d.ts +0 -89
  162. package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
  163. package/dist/animation/theatre-clock-binding.js +0 -29
  164. package/dist/animation/theatre-director.d.ts +0 -242
  165. package/dist/animation/theatre-director.d.ts.map +0 -1
  166. package/dist/animation/theatre-director.js +0 -235
  167. package/dist/animation/theatre-object-binding.d.ts +0 -305
  168. package/dist/animation/theatre-object-binding.d.ts.map +0 -1
  169. package/dist/animation/theatre-object-binding.js +0 -351
  170. package/dist/animation/xstate-animation-binding.d.ts +0 -111
  171. package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
  172. package/dist/animation/xstate-animation-binding.js +0 -307
  173. package/dist/animation/xstate-animation-meta.d.ts +0 -228
  174. package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
  175. package/dist/animation/xstate-animation-meta.js +0 -221
  176. package/dist/assets.d.ts +0 -26
  177. package/dist/assets.d.ts.map +0 -1
  178. package/dist/assets.js +0 -55
  179. package/dist/audio/index.d.ts +0 -4
  180. package/dist/audio/index.d.ts.map +0 -1
  181. package/dist/audio/index.js +0 -24
  182. package/dist/audio/tone-clock-binding.d.ts +0 -75
  183. package/dist/audio/tone-clock-binding.d.ts.map +0 -1
  184. package/dist/audio/tone-clock-binding.js +0 -29
  185. package/dist/audio/tone-context.d.ts +0 -114
  186. package/dist/audio/tone-context.d.ts.map +0 -1
  187. package/dist/audio/tone-context.js +0 -39
  188. package/dist/audio/tone-offline-render.d.ts +0 -90
  189. package/dist/audio/tone-offline-render.d.ts.map +0 -1
  190. package/dist/audio/tone-offline-render.js +0 -56
  191. package/dist/audio/wav-encode.d.ts +0 -38
  192. package/dist/audio/wav-encode.d.ts.map +0 -1
  193. package/dist/audio/wav-encode.js +0 -97
  194. package/dist/core/game-loop.d.ts +0 -21
  195. package/dist/core/game-loop.d.ts.map +0 -1
  196. package/dist/core/game-loop.js +0 -130
  197. package/dist/core/system-runner.d.ts +0 -120
  198. package/dist/core/system-runner.d.ts.map +0 -1
  199. package/dist/core/system-runner.js +0 -286
  200. package/dist/core/types.d.ts +0 -58
  201. package/dist/core/types.d.ts.map +0 -1
  202. package/dist/core/types.js +0 -25
  203. package/dist/data/data-asset.d.ts +0 -101
  204. package/dist/data/data-asset.d.ts.map +0 -1
  205. package/dist/data/data-asset.js +0 -122
  206. package/dist/data/data-check-core.d.ts +0 -110
  207. package/dist/data/data-check-core.d.ts.map +0 -1
  208. package/dist/data/data-check-core.js +0 -178
  209. package/dist/data/data-ref.d.ts +0 -79
  210. package/dist/data/data-ref.d.ts.map +0 -1
  211. package/dist/data/data-ref.js +0 -130
  212. package/dist/data/vite-plugin-data.d.ts +0 -79
  213. package/dist/data/vite-plugin-data.d.ts.map +0 -1
  214. package/dist/data/vite-plugin-data.js +0 -217
  215. package/dist/dev/console-bridge.d.ts +0 -22
  216. package/dist/dev/console-bridge.d.ts.map +0 -1
  217. package/dist/dev/console-bridge.js +0 -71
  218. package/dist/dev/debug-draw.d.ts +0 -24
  219. package/dist/dev/debug-draw.d.ts.map +0 -1
  220. package/dist/dev/debug-draw.js +0 -73
  221. package/dist/dev/logger.d.ts +0 -30
  222. package/dist/dev/logger.d.ts.map +0 -1
  223. package/dist/dev/logger.js +0 -90
  224. package/dist/ecs/component-manager.d.ts +0 -189
  225. package/dist/ecs/component-manager.d.ts.map +0 -1
  226. package/dist/ecs/component-manager.js +0 -676
  227. package/dist/ecs/game-component.d.ts +0 -97
  228. package/dist/ecs/game-component.d.ts.map +0 -1
  229. package/dist/ecs/game-component.js +0 -80
  230. package/dist/ecs/hmr-swap-report.d.ts +0 -53
  231. package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
  232. package/dist/ecs/hmr-swap-report.js +0 -55
  233. package/dist/index.d.ts +0 -37
  234. package/dist/index.d.ts.map +0 -1
  235. package/dist/index.js +0 -30
  236. package/dist/input/input-manager.d.ts +0 -596
  237. package/dist/input/input-manager.d.ts.map +0 -1
  238. package/dist/input/input-manager.js +0 -1564
  239. package/dist/input/input-types.d.ts +0 -171
  240. package/dist/input/input-types.d.ts.map +0 -1
  241. package/dist/input/input-types.js +0 -1
  242. package/dist/input/prompt-labels.d.ts +0 -21
  243. package/dist/input/prompt-labels.d.ts.map +0 -1
  244. package/dist/input/prompt-labels.js +0 -121
  245. package/dist/input/rebind-controller.d.ts +0 -59
  246. package/dist/input/rebind-controller.d.ts.map +0 -1
  247. package/dist/input/rebind-controller.js +0 -85
  248. package/dist/input/schema.d.ts +0 -16
  249. package/dist/input/schema.d.ts.map +0 -1
  250. package/dist/input/schema.js +0 -228
  251. package/dist/loader.d.ts +0 -43
  252. package/dist/loader.d.ts.map +0 -1
  253. package/dist/loader.js +0 -59
  254. package/dist/manifest/index.d.ts +0 -5
  255. package/dist/manifest/index.d.ts.map +0 -1
  256. package/dist/manifest/index.js +0 -8
  257. package/dist/manifest/load-file.d.ts +0 -4
  258. package/dist/manifest/load-file.d.ts.map +0 -1
  259. package/dist/manifest/load-file.js +0 -14
  260. package/dist/manifest/load.d.ts +0 -117
  261. package/dist/manifest/load.d.ts.map +0 -1
  262. package/dist/manifest/load.js +0 -255
  263. package/dist/manifest/schema.d.ts +0 -173
  264. package/dist/manifest/schema.d.ts.map +0 -1
  265. package/dist/manifest/schema.js +0 -302
  266. package/dist/physics/collision-system.d.ts +0 -41
  267. package/dist/physics/collision-system.d.ts.map +0 -1
  268. package/dist/physics/collision-system.js +0 -64
  269. package/dist/physics/physics-registry.d.ts +0 -45
  270. package/dist/physics/physics-registry.d.ts.map +0 -1
  271. package/dist/physics/physics-registry.js +0 -65
  272. package/dist/physics/transform-writer.d.ts +0 -16
  273. package/dist/physics/transform-writer.d.ts.map +0 -1
  274. package/dist/physics/transform-writer.js +0 -38
  275. package/dist/physics/trigger-dispatch.d.ts +0 -24
  276. package/dist/physics/trigger-dispatch.d.ts.map +0 -1
  277. package/dist/physics/trigger-dispatch.js +0 -80
  278. package/dist/react/game-state.d.ts +0 -105
  279. package/dist/react/game-state.d.ts.map +0 -1
  280. package/dist/react/game-state.js +0 -144
  281. package/dist/react/use-data.d.ts +0 -60
  282. package/dist/react/use-data.d.ts.map +0 -1
  283. package/dist/react/use-data.js +0 -96
  284. package/dist/react/use-selection.d.ts +0 -75
  285. package/dist/react/use-selection.d.ts.map +0 -1
  286. package/dist/react/use-selection.js +0 -90
  287. package/dist/render/auto-batcher.d.ts +0 -34
  288. package/dist/render/auto-batcher.d.ts.map +0 -1
  289. package/dist/render/auto-batcher.js +0 -140
  290. package/dist/render/render-batch-system.d.ts +0 -33
  291. package/dist/render/render-batch-system.d.ts.map +0 -1
  292. package/dist/render/render-batch-system.js +0 -230
  293. package/dist/render/render-features.d.ts +0 -47
  294. package/dist/render/render-features.d.ts.map +0 -1
  295. package/dist/render/render-features.js +0 -105
  296. package/dist/render/render-settings.d.ts +0 -36
  297. package/dist/render/render-settings.d.ts.map +0 -1
  298. package/dist/render/render-settings.js +0 -51
  299. package/dist/runtime/create-runtime.d.ts +0 -280
  300. package/dist/runtime/create-runtime.d.ts.map +0 -1
  301. package/dist/runtime/create-runtime.js +0 -795
  302. package/dist/runtime/frame-selector-cache.d.ts +0 -41
  303. package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
  304. package/dist/runtime/frame-selector-cache.js +0 -65
  305. package/dist/runtime/game.d.ts +0 -433
  306. package/dist/runtime/game.d.ts.map +0 -1
  307. package/dist/runtime/game.js +0 -569
  308. package/dist/runtime/input-router.d.ts +0 -78
  309. package/dist/runtime/input-router.d.ts.map +0 -1
  310. package/dist/runtime/input-router.js +0 -171
  311. package/dist/runtime/mount-game.d.ts +0 -129
  312. package/dist/runtime/mount-game.d.ts.map +0 -1
  313. package/dist/runtime/mount-game.js +0 -152
  314. package/dist/runtime/mount-manifest.d.ts +0 -119
  315. package/dist/runtime/mount-manifest.d.ts.map +0 -1
  316. package/dist/runtime/mount-manifest.js +0 -204
  317. package/dist/runtime/render-audio-control.d.ts +0 -110
  318. package/dist/runtime/render-audio-control.d.ts.map +0 -1
  319. package/dist/runtime/render-audio-control.js +0 -111
  320. package/dist/runtime/render-control.d.ts +0 -291
  321. package/dist/runtime/render-control.d.ts.map +0 -1
  322. package/dist/runtime/render-control.js +0 -264
  323. package/dist/runtime/render-seed.d.ts +0 -57
  324. package/dist/runtime/render-seed.d.ts.map +0 -1
  325. package/dist/runtime/render-seed.js +0 -74
  326. package/dist/runtime/scene-ui-bridge.d.ts +0 -69
  327. package/dist/runtime/scene-ui-bridge.d.ts.map +0 -1
  328. package/dist/runtime/scene-ui-bridge.js +0 -23
  329. package/dist/runtime/scene-ui-data.d.ts +0 -13
  330. package/dist/runtime/scene-ui-data.d.ts.map +0 -1
  331. package/dist/runtime/scene-ui-data.js +0 -92
  332. package/dist/runtime/state-bridge.d.ts +0 -47
  333. package/dist/runtime/state-bridge.d.ts.map +0 -1
  334. package/dist/runtime/state-bridge.js +0 -53
  335. package/dist/runtime/types.d.ts +0 -179
  336. package/dist/runtime/types.d.ts.map +0 -1
  337. package/dist/runtime/types.js +0 -1
  338. package/dist/scene/asset-loaders.d.ts +0 -79
  339. package/dist/scene/asset-loaders.d.ts.map +0 -1
  340. package/dist/scene/asset-loaders.js +0 -141
  341. package/dist/scene/asset-paths.d.ts +0 -11
  342. package/dist/scene/asset-paths.d.ts.map +0 -1
  343. package/dist/scene/asset-paths.js +0 -108
  344. package/dist/scene/asset-ref-check.d.ts +0 -88
  345. package/dist/scene/asset-ref-check.d.ts.map +0 -1
  346. package/dist/scene/asset-ref-check.js +0 -214
  347. package/dist/scene/asset-registry.d.ts +0 -30
  348. package/dist/scene/asset-registry.d.ts.map +0 -1
  349. package/dist/scene/asset-registry.js +0 -50
  350. package/dist/scene/collider-dimensions.d.ts +0 -63
  351. package/dist/scene/collider-dimensions.d.ts.map +0 -1
  352. package/dist/scene/collider-dimensions.js +0 -98
  353. package/dist/scene/component-registry.d.ts +0 -17
  354. package/dist/scene/component-registry.d.ts.map +0 -1
  355. package/dist/scene/component-registry.js +0 -28
  356. package/dist/scene/defaults.d.ts +0 -252
  357. package/dist/scene/defaults.d.ts.map +0 -1
  358. package/dist/scene/defaults.js +0 -151
  359. package/dist/scene/geometries/index.d.ts +0 -8
  360. package/dist/scene/geometries/index.d.ts.map +0 -1
  361. package/dist/scene/geometries/index.js +0 -7
  362. package/dist/scene/geometries/terrain.d.ts +0 -2
  363. package/dist/scene/geometries/terrain.d.ts.map +0 -1
  364. package/dist/scene/geometries/terrain.js +0 -37
  365. package/dist/scene/geometry-registry.d.ts +0 -24
  366. package/dist/scene/geometry-registry.d.ts.map +0 -1
  367. package/dist/scene/geometry-registry.js +0 -20
  368. package/dist/scene/instance-registry.d.ts +0 -36
  369. package/dist/scene/instance-registry.d.ts.map +0 -1
  370. package/dist/scene/instance-registry.js +0 -55
  371. package/dist/scene/instancers/grid.d.ts +0 -2
  372. package/dist/scene/instancers/grid.d.ts.map +0 -1
  373. package/dist/scene/instancers/grid.js +0 -36
  374. package/dist/scene/instancers/index.d.ts +0 -8
  375. package/dist/scene/instancers/index.d.ts.map +0 -1
  376. package/dist/scene/instancers/index.js +0 -7
  377. package/dist/scene/light-camera-factory.d.ts +0 -23
  378. package/dist/scene/light-camera-factory.d.ts.map +0 -1
  379. package/dist/scene/light-camera-factory.js +0 -68
  380. package/dist/scene/material-factory.d.ts +0 -17
  381. package/dist/scene/material-factory.d.ts.map +0 -1
  382. package/dist/scene/material-factory.js +0 -197
  383. package/dist/scene/material-registry.d.ts +0 -40
  384. package/dist/scene/material-registry.d.ts.map +0 -1
  385. package/dist/scene/material-registry.js +0 -44
  386. package/dist/scene/materials/index.d.ts +0 -8
  387. package/dist/scene/materials/index.d.ts.map +0 -1
  388. package/dist/scene/materials/index.js +0 -7
  389. package/dist/scene/materials/water.d.ts +0 -2
  390. package/dist/scene/materials/water.d.ts.map +0 -1
  391. package/dist/scene/materials/water.js +0 -54
  392. package/dist/scene/parse.d.ts +0 -23
  393. package/dist/scene/parse.d.ts.map +0 -1
  394. package/dist/scene/parse.js +0 -179
  395. package/dist/scene/particles-factory.d.ts +0 -33
  396. package/dist/scene/particles-factory.d.ts.map +0 -1
  397. package/dist/scene/particles-factory.js +0 -282
  398. package/dist/scene/scene-apply.d.ts +0 -109
  399. package/dist/scene/scene-apply.d.ts.map +0 -1
  400. package/dist/scene/scene-apply.js +0 -326
  401. package/dist/scene/scene-diff-schema.d.ts +0 -285
  402. package/dist/scene/scene-diff-schema.d.ts.map +0 -1
  403. package/dist/scene/scene-diff-schema.js +0 -92
  404. package/dist/scene/scene-diff-types.d.ts +0 -40
  405. package/dist/scene/scene-diff-types.d.ts.map +0 -1
  406. package/dist/scene/scene-diff-types.js +0 -14
  407. package/dist/scene/scene-loader.d.ts +0 -177
  408. package/dist/scene/scene-loader.d.ts.map +0 -1
  409. package/dist/scene/scene-loader.js +0 -1213
  410. package/dist/scene/scene-query.d.ts +0 -11
  411. package/dist/scene/scene-query.d.ts.map +0 -1
  412. package/dist/scene/scene-query.js +0 -63
  413. package/dist/scene/scene-types.d.ts +0 -10
  414. package/dist/scene/scene-types.d.ts.map +0 -1
  415. package/dist/scene/scene-types.js +0 -8
  416. package/dist/scene/scene-version.d.ts +0 -26
  417. package/dist/scene/scene-version.d.ts.map +0 -1
  418. package/dist/scene/scene-version.js +0 -34
  419. package/dist/scene/schema/animation.d.ts +0 -8
  420. package/dist/scene/schema/animation.d.ts.map +0 -1
  421. package/dist/scene/schema/animation.js +0 -42
  422. package/dist/scene/schema/audio.d.ts +0 -13
  423. package/dist/scene/schema/audio.d.ts.map +0 -1
  424. package/dist/scene/schema/audio.js +0 -22
  425. package/dist/scene/schema/camera.d.ts +0 -28
  426. package/dist/scene/schema/camera.d.ts.map +0 -1
  427. package/dist/scene/schema/camera.js +0 -17
  428. package/dist/scene/schema/collider.d.ts +0 -40
  429. package/dist/scene/schema/collider.d.ts.map +0 -1
  430. package/dist/scene/schema/collider.js +0 -55
  431. package/dist/scene/schema/entity-ref.d.ts +0 -31
  432. package/dist/scene/schema/entity-ref.d.ts.map +0 -1
  433. package/dist/scene/schema/entity-ref.js +0 -61
  434. package/dist/scene/schema/entity.d.ts +0 -1036
  435. package/dist/scene/schema/entity.d.ts.map +0 -1
  436. package/dist/scene/schema/entity.js +0 -153
  437. package/dist/scene/schema/environment.d.ts +0 -425
  438. package/dist/scene/schema/environment.d.ts.map +0 -1
  439. package/dist/scene/schema/environment.js +0 -357
  440. package/dist/scene/schema/index.d.ts +0 -39
  441. package/dist/scene/schema/index.d.ts.map +0 -1
  442. package/dist/scene/schema/index.js +0 -20
  443. package/dist/scene/schema/instances.d.ts +0 -14
  444. package/dist/scene/schema/instances.d.ts.map +0 -1
  445. package/dist/scene/schema/instances.js +0 -28
  446. package/dist/scene/schema/joint.d.ts +0 -23
  447. package/dist/scene/schema/joint.d.ts.map +0 -1
  448. package/dist/scene/schema/joint.js +0 -23
  449. package/dist/scene/schema/light.d.ts +0 -38
  450. package/dist/scene/schema/light.d.ts.map +0 -1
  451. package/dist/scene/schema/light.js +0 -26
  452. package/dist/scene/schema/material.d.ts +0 -199
  453. package/dist/scene/schema/material.d.ts.map +0 -1
  454. package/dist/scene/schema/material.js +0 -99
  455. package/dist/scene/schema/mesh.d.ts +0 -48
  456. package/dist/scene/schema/mesh.d.ts.map +0 -1
  457. package/dist/scene/schema/mesh.js +0 -82
  458. package/dist/scene/schema/particles.d.ts +0 -2178
  459. package/dist/scene/schema/particles.d.ts.map +0 -1
  460. package/dist/scene/schema/particles.js +0 -321
  461. package/dist/scene/schema/physics.d.ts +0 -56
  462. package/dist/scene/schema/physics.d.ts.map +0 -1
  463. package/dist/scene/schema/physics.js +0 -37
  464. package/dist/scene/schema/scene-file.d.ts +0 -304
  465. package/dist/scene/schema/scene-file.d.ts.map +0 -1
  466. package/dist/scene/schema/scene-file.js +0 -262
  467. package/dist/scene/schema/shadow.d.ts +0 -28
  468. package/dist/scene/schema/shadow.d.ts.map +0 -1
  469. package/dist/scene/schema/shadow.js +0 -20
  470. package/dist/scene/schema/spline.d.ts +0 -25
  471. package/dist/scene/schema/spline.d.ts.map +0 -1
  472. package/dist/scene/schema/spline.js +0 -15
  473. package/dist/scene/schema/tuples.d.ts +0 -12
  474. package/dist/scene/schema/tuples.d.ts.map +0 -1
  475. package/dist/scene/schema/tuples.js +0 -14
  476. package/dist/scene/schema/ui.d.ts +0 -880
  477. package/dist/scene/schema/ui.d.ts.map +0 -1
  478. package/dist/scene/schema/ui.js +0 -506
  479. package/dist/scene/user-data.d.ts +0 -171
  480. package/dist/scene/user-data.d.ts.map +0 -1
  481. package/dist/scene/user-data.js +0 -137
  482. package/dist/setup/setup-audio.d.ts +0 -20
  483. package/dist/setup/setup-audio.d.ts.map +0 -1
  484. package/dist/setup/setup-audio.js +0 -41
  485. package/dist/setup/setup-particles.d.ts +0 -17
  486. package/dist/setup/setup-particles.d.ts.map +0 -1
  487. package/dist/setup/setup-particles.js +0 -16
  488. package/dist/setup/setup-physics.d.ts +0 -25
  489. package/dist/setup/setup-physics.d.ts.map +0 -1
  490. package/dist/setup/setup-physics.js +0 -51
  491. package/dist/setup/setup-renderer.d.ts +0 -69
  492. package/dist/setup/setup-renderer.d.ts.map +0 -1
  493. package/dist/setup/setup-renderer.js +0 -363
  494. package/dist/tools/define-tool.d.ts +0 -105
  495. package/dist/tools/define-tool.d.ts.map +0 -1
  496. package/dist/tools/define-tool.js +0 -82
  497. package/dist/world2d/authoring-2d.d.ts +0 -76
  498. package/dist/world2d/authoring-2d.d.ts.map +0 -1
  499. package/dist/world2d/authoring-2d.js +0 -176
  500. package/dist/world2d/capture-to-scene2d.d.ts +0 -5
  501. package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
  502. package/dist/world2d/capture-to-scene2d.js +0 -49
  503. package/dist/world2d/collision-2d.d.ts +0 -52
  504. package/dist/world2d/collision-2d.d.ts.map +0 -1
  505. package/dist/world2d/collision-2d.js +0 -70
  506. package/dist/world2d/components-2d.d.ts +0 -47
  507. package/dist/world2d/components-2d.d.ts.map +0 -1
  508. package/dist/world2d/components-2d.js +0 -77
  509. package/dist/world2d/index.d.ts +0 -34
  510. package/dist/world2d/index.d.ts.map +0 -1
  511. package/dist/world2d/index.js +0 -32
  512. package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
  513. package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
  514. package/dist/world2d/ingest-iframe-2d.js +0 -166
  515. package/dist/world2d/ingest2d.d.ts +0 -97
  516. package/dist/world2d/ingest2d.d.ts.map +0 -1
  517. package/dist/world2d/ingest2d.js +0 -40
  518. package/dist/world2d/physics2d-registry.d.ts +0 -24
  519. package/dist/world2d/physics2d-registry.d.ts.map +0 -1
  520. package/dist/world2d/physics2d-registry.js +0 -38
  521. package/dist/world2d/pixi-game-adapter.d.ts +0 -107
  522. package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
  523. package/dist/world2d/pixi-game-adapter.js +0 -211
  524. package/dist/world2d/pixi-surface.d.ts +0 -39
  525. package/dist/world2d/pixi-surface.d.ts.map +0 -1
  526. package/dist/world2d/pixi-surface.js +0 -47
  527. package/dist/world2d/scene-capture-2d.d.ts +0 -43
  528. package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
  529. package/dist/world2d/scene-capture-2d.js +0 -92
  530. package/dist/world2d/scene2d-loader.d.ts +0 -27
  531. package/dist/world2d/scene2d-loader.d.ts.map +0 -1
  532. package/dist/world2d/scene2d-loader.js +0 -274
  533. package/dist/world2d/schema/entity2d.d.ts +0 -102
  534. package/dist/world2d/schema/entity2d.d.ts.map +0 -1
  535. package/dist/world2d/schema/entity2d.js +0 -119
  536. package/dist/world2d/schema/physics2d.d.ts +0 -46
  537. package/dist/world2d/schema/physics2d.d.ts.map +0 -1
  538. package/dist/world2d/schema/physics2d.js +0 -45
  539. package/dist/world2d/schema/sprite.d.ts +0 -42
  540. package/dist/world2d/schema/sprite.d.ts.map +0 -1
  541. package/dist/world2d/schema/sprite.js +0 -63
  542. package/dist/world2d/schema/tilemap.d.ts +0 -15
  543. package/dist/world2d/schema/tilemap.d.ts.map +0 -1
  544. package/dist/world2d/schema/tilemap.js +0 -19
  545. package/dist/world2d/schema/tuples2d.d.ts +0 -20
  546. package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
  547. package/dist/world2d/schema/tuples2d.js +0 -19
  548. package/dist/world2d/system-adapters-2d.d.ts +0 -16
  549. package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
  550. package/dist/world2d/system-adapters-2d.js +0 -37
  551. package/dist/world2d/transform-writer-2d.d.ts +0 -16
  552. package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
  553. package/dist/world2d/transform-writer-2d.js +0 -22
  554. package/dist/world2d/types.d.ts +0 -53
  555. package/dist/world2d/types.d.ts.map +0 -1
  556. package/dist/world2d/types.js +0 -1
  557. package/src/runtime/scene-ui-bridge.ts +0 -86
  558. package/src/runtime/scene-ui-data.ts +0 -119
  559. package/src/scene/schema/ui.ts +0 -602
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Engine-PUBLISHED `GameProvider`/`useGame`/`useGameState`/`useWorldObservation`
3
- * (D-Z5, `docs/WAVE3-ADAPTER-PLUMBING-DESIGN.md` §D-Z5) — the canonical,
4
- * opt-in react entry for the T7.4 state bridge (`docs/REACT-STATE-BRIDGE.md`
5
- * §3). This is a SEPARATE, react-value-importing module under
2
+ * Canonical `GameProvider`/`useGame`/`useGameState`/`useWorldObservation`
3
+ * entry for React adapter roots. Also home to `useDebugProvider` and
4
+ * `useDebugCommand`/`useDebugEmit`, the React-facing debug seam.
5
+ *
6
+ * This is a SEPARATE, react-value-importing module under
6
7
  * `packages/engine/src/react/` — colocated per REACT-STATE-BRIDGE §3's own
7
8
  * "colocate the react-facing hooks with the HUD seam, not the react-free
8
9
  * core" rule, just now living IN the engine package rather than only in the
@@ -11,34 +12,26 @@
11
12
  * invariant is proved by `packages/engine/test/react-core-import-ban.test.ts`
12
13
  * (AC-F1).
13
14
  *
14
- * This module is the SPEC others port faithfully: it was originally authored
15
- * as `packages/editor/template/src/ui/game-state.tsx` (T7.4); that file is
16
- * now a thin re-export of this one (D-Z5 step 3) so every NEW scaffolded
17
- * project gets ONE canonical context, while existing projects with their own
18
- * full copy (their own `createContext`) keep working untouched — adoption of
19
- * THIS module is an option, never a forced migration (D-Z5).
20
- *
21
- * Context-identity landmine (unchanged from the template file's own history,
22
- * still the reason `loadProjectGameProvider`/the virtual-module plugin exist
23
- * in `packages/editor/src/adapter-resolver.ts` /
24
- * `packages/editor/vite-plugin-react-world-provider.ts`): `<GameProvider>`
25
- * and `useGame()` must resolve against the SAME `createContext()` call. A
26
- * project that ships its OWN `src/ui/game-state.tsx` (its own
27
- * `createContext`) must be wrapped by ITS OWN `GameProvider` — wrapping it
28
- * with THIS module's `GameProvider` instead would split context and
29
- * `useGame()` would throw "no Game in context" even though a `<GameProvider>`
30
- * genuinely wraps the tree (proved by
31
- * `packages/editor/test/game-state-context-split.test.tsx`, AC-F1). This is
32
- * exactly why the engine-published fallback (`resolveIngestReactAdapter`'s
33
- * D-Y3 upgrade, `default-react`'s optional fallback) only ever fires when the
34
- * project's OWN `src/ui/game-state.tsx` is ABSENT — an unmodified foreign
35
- * entry that imports no vgai hooks has no context to split.
15
+ * Every host and game imports this one module, so provider and hooks share
16
+ * one `createContext()` identity. The engine core outside `src/react/`
17
+ * remains React-free, enforced by `react-core-import-ban.test.ts`.
36
18
  */
37
19
 
38
- import { createContext, type ReactNode, useContext, useRef, useSyncExternalStore } from 'react';
20
+ import {
21
+ createContext,
22
+ type PropsWithChildren,
23
+ useCallback,
24
+ useContext,
25
+ useEffect,
26
+ useRef,
27
+ useSyncExternalStore,
28
+ } from 'react';
29
+ import type { z } from 'zod';
39
30
  import type { WorldStateObserver } from '../adapter';
31
+ import { getDebugRegistry } from '../runtime/debug-registry';
40
32
  import { createFrameSelectorCache, type Equals, shallow } from '../runtime/frame-selector-cache';
41
33
  import type { Game } from '../runtime/game';
34
+ import type { DebugCommandArgs } from '../runtime/types';
42
35
 
43
36
  /** Re-exported for convenience — the opt-in equality for selectors that
44
37
  * return a fresh object/array/tuple every call (default is `Object.is`). */
@@ -47,10 +40,21 @@ export { shallow };
47
40
  const GameContext = createContext<Game | null>(null);
48
41
 
49
42
  /** Provide the `Game` to `useGameState`/`useGame` for everything mounted
50
- * beneath it. Compose it around whatever renders your tree (`mountUI`, a
51
- * react world's `createRoot(...).render(...)`, etc.) — see the module doc
52
- * comment above for the context-identity rule this hook family depends on. */
53
- export function GameProvider({ game, children }: { game: Game; children: ReactNode }) {
43
+ * beneath it. Adapter-root hosts install this provider automatically — see the module doc
44
+ * comment above for the context-identity rule this hook family depends on.
45
+ *
46
+ * Props use `PropsWithChildren` (children optional in the TYPE, not
47
+ * runtime-optional in practice — you always want children mounted under
48
+ * the provider) rather than a bare `{ children: ReactNode }` field: a
49
+ * required `children` in `P` makes TS's `createElement<P>(type, props?:
50
+ * Attributes & P, ...children)` overload reject the plain 3-arg call
51
+ * `React.createElement(GameProvider, { game }, child)` (no JSX transform,
52
+ * e.g. a `.ts` main composing a sibling `.tsx` HUD) with "Property
53
+ * 'children' is missing" even though the 3rd arg supplies it — issue #97.
54
+ * Making `children` optional in the type lets that overload resolve; the
55
+ * rest-arg children are still wired through to `children` at runtime by
56
+ * React itself, unchanged. See `test/game-state-create-element-types.test.tsx`. */
57
+ export function GameProvider({ game, children }: PropsWithChildren<{ game: Game }>) {
54
58
  return <GameContext.Provider value={game}>{children}</GameContext.Provider>;
55
59
  }
56
60
 
@@ -109,7 +113,7 @@ export function requireWorldObserver(game: Game, worldId: string): WorldStateObs
109
113
  const world = game.world(worldId);
110
114
  if (!world) {
111
115
  throw new Error(
112
- `useWorldObservation: no world registered with id "${worldId}" — check game.worlds for the ` +
116
+ `useWorldObservation: no world registered with id "${worldId}" — check game.roots for the ` +
113
117
  'ids actually registered.',
114
118
  );
115
119
  }
@@ -170,3 +174,102 @@ export function useWorldObservation<T>(
170
174
  () => cacheRef.current!.get(versionRef.current, () => selector(observer.snapshot())),
171
175
  );
172
176
  }
177
+
178
+ /**
179
+ * The debug seam's react-world registration door (Task 1.5,
180
+ * `docs/SYNTHETIC-PLAYER-SPEC.md` §3.1): react roots have no `setup()`/
181
+ * `ctx.debug` of their own, so this hook registers a named state provider
182
+ * into the SAME game-scoped registry every `GameComponent`'s `ctx.debug`
183
+ * feeds (`getDebugRegistry(game)`, `runtime/debug-registry.ts`), readable
184
+ * through `game.systemAdapters.debug.state(name)` exactly like a
185
+ * `ctx.debug.registerStateProvider` call.
186
+ *
187
+ * Registers ONCE per mount (keyed on `name`) and unregisters on unmount —
188
+ * silently, like hot-reload's `strip()`. Re-renders never re-register or
189
+ * re-warn: `fn` is kept in a ref updated every render, so the registered
190
+ * closure always calls the CURRENT `fn` without touching the registry.
191
+ * Outside a `<GameProvider>` (or against a bare test `Game` built without a
192
+ * registry) this is an inert no-op — it never throws, matching the "no seam
193
+ * without a consumer" degrade every optional `ctx.*` surface follows.
194
+ */
195
+ export function useDebugProvider(
196
+ name: string,
197
+ fn: () => unknown,
198
+ opts?: { tier?: 'observable' | 'assisted' },
199
+ ): void {
200
+ const game = useContext(GameContext);
201
+ const fnRef = useRef(fn);
202
+ fnRef.current = fn;
203
+ const tier = opts?.tier;
204
+
205
+ useEffect(() => {
206
+ const registry = game && getDebugRegistry(game);
207
+ if (!registry) return;
208
+ return registry.registerReactProvider(name, () => fnRef.current(), { tier });
209
+ // `tier` is deliberately NOT a dep (same reasoning as `useDebugCommand`'s
210
+ // `spec`) — captured once at mount, so it never forces re-registration.
211
+ }, [game, name]);
212
+ }
213
+
214
+ /**
215
+ * The command-side counterpart of {@link useDebugProvider} — registers an
216
+ * invokable debug command into the same game-scoped registry, readable
217
+ * through `game.systemAdapters.debug.commands()`/`invoke(name, args)`.
218
+ *
219
+ * Same mount/unmount/ref-latest contract as {@link useDebugProvider}: `spec`
220
+ * (description/args/locus) is captured at registration time, `fn` always
221
+ * calls through to the latest render's closure via a ref, and the hook is an
222
+ * inert no-op with no `<GameProvider>` in scope.
223
+ *
224
+ * Generic over the declared `args` Zod tuple, same as
225
+ * `DebugCtxSurface.registerCommand` ({@link DebugCommandArgs}, dry-run
226
+ * finding — `docs/ACCEPTANCE-DRIVER-BUILD-PLAN.md` Wave 6 ledger): declaring
227
+ * `args: z.tuple([z.number(), z.string()])` types `fn`'s parameters as
228
+ * `(n: number, s: string) => ...` with no `unknown[]` cast; omitting `args`
229
+ * keeps `fn` typed `(...args: unknown[]) => ...` as before.
230
+ */
231
+ export function useDebugCommand<T extends z.ZodTuple | undefined = undefined>(
232
+ name: string,
233
+ spec: { description?: string; args?: T; locus?: 'client' | 'server' },
234
+ fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>,
235
+ ): void {
236
+ const game = useContext(GameContext);
237
+ const fnRef = useRef(fn);
238
+ fnRef.current = fn;
239
+
240
+ useEffect(() => {
241
+ const registry = game && getDebugRegistry(game);
242
+ if (!registry) return;
243
+ return registry.registerReactCommand(name, spec, (...args: DebugCommandArgs<T>) =>
244
+ fnRef.current(...args),
245
+ );
246
+ // `spec` is deliberately NOT a dep (like `equals` above) — captured once
247
+ // at mount, so a fresh inline object literal every render never forces
248
+ // re-registration.
249
+ }, [game, name]);
250
+ }
251
+
252
+ /**
253
+ * The event-side counterpart of {@link useDebugProvider} and
254
+ * {@link useDebugCommand}. Returns a stable callback that writes a
255
+ * tick-stamped event to the game-scoped debug flight recorder:
256
+ *
257
+ * ```tsx
258
+ * const emit = useDebugEmit();
259
+ * emit('score-changed', { score });
260
+ * ```
261
+ *
262
+ * It is an inert no-op outside a `<GameProvider>`, matching the optional
263
+ * behavior of the other React debug hooks. Games never need to import the
264
+ * debug registry or know its internal React provenance id.
265
+ */
266
+ export function useDebugEmit(): (event: string, detail?: unknown) => void {
267
+ const game = useContext(GameContext);
268
+ return useCallback(
269
+ (event: string, detail?: unknown) => {
270
+ if (!game) return;
271
+ getDebugRegistry(game)?.emitReact(event, detail);
272
+ },
273
+ [game],
274
+ );
275
+ }
@@ -0,0 +1,49 @@
1
+ import { type ComponentType, createElement } from 'react';
2
+ import { flushSync } from 'react-dom';
3
+ import { createRoot } from 'react-dom/client';
4
+ import type { MountedReactGame, ReactRootAdapter, ReactWorldHost } from '../runtime/create-runtime';
5
+ import { isAdapterRegistered, registerAdapter } from '../runtime/mount-game';
6
+ import { GameProvider } from './game-state';
7
+
8
+ interface ReactEntryModule {
9
+ readonly default?: ComponentType;
10
+ }
11
+
12
+ /** Construct one canonical React root adapter for direct host composition. */
13
+ export function createReactRootAdapter(id: string, Entry: ComponentType): ReactRootAdapter {
14
+ return {
15
+ id,
16
+ async mount(host: ReactWorldHost): Promise<MountedReactGame> {
17
+ if (!host.game) throw new Error(`React root "${id}" requires a Game host.`);
18
+ const reactRoot = createRoot(host.container);
19
+ flushSync(() => {
20
+ reactRoot.render(createElement(GameProvider, { game: host.game! }, createElement(Entry)));
21
+ });
22
+ return {
23
+ kind: 'react',
24
+ container: host.container,
25
+ drivesOwnLoop: false,
26
+ dispose: () => reactRoot.unmount(),
27
+ };
28
+ },
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Register the engine's React adapter-root factory. This module is an
34
+ * explicit optional React entry point: engine core never imports it, while a
35
+ * React game host imports it once and receives the canonical root lifecycle.
36
+ */
37
+ export function registerReactAdapter(): void {
38
+ if (isAdapterRegistered('react')) return;
39
+ registerAdapter('react', (root, { entryModule }) => {
40
+ const Entry = (entryModule as ReactEntryModule | undefined)?.default;
41
+ if (!Entry) {
42
+ throw new Error(
43
+ `React root "${root.id}" entry "${root.entry ?? '(missing)'}" must default-export a component.`,
44
+ );
45
+ }
46
+
47
+ return { kind: 'react', adapter: createReactRootAdapter(root.id, Entry) };
48
+ });
49
+ }
@@ -0,0 +1,66 @@
1
+ export interface UnmanagedReactRootFinding {
2
+ readonly file: string;
3
+ readonly line: number;
4
+ readonly api: 'createRoot' | 'hydrateRoot' | 'ReactDOM.render';
5
+ }
6
+
7
+ function lineAt(source: string, offset: number): number {
8
+ return source.slice(0, offset).split('\n').length;
9
+ }
10
+
11
+ /**
12
+ * Find project-owned React DOM root creation. VGAI hosts React through
13
+ * manifest adapter roots, so any of these calls in game source creates an
14
+ * unmanaged second lifecycle and is a hard validation error.
15
+ */
16
+ export function detectUnmanagedReactRoots(
17
+ source: string,
18
+ file: string,
19
+ ): UnmanagedReactRootFinding[] {
20
+ const findings: UnmanagedReactRootFinding[] = [];
21
+ const aliases = new Map<string, 'createRoot' | 'hydrateRoot'>();
22
+
23
+ for (const match of source.matchAll(/import\s*\{([^}]*)\}\s*from\s*['"]react-dom\/client['"]/g)) {
24
+ for (const member of (match[1] ?? '').split(',')) {
25
+ const parsed = member.trim().match(/^(createRoot|hydrateRoot)(?:\s+as\s+([\w$]+))?$/);
26
+ if (parsed) aliases.set(parsed[2] ?? parsed[1]!, parsed[1] as 'createRoot' | 'hydrateRoot');
27
+ }
28
+ }
29
+
30
+ for (const [alias, api] of aliases) {
31
+ const call = new RegExp(`\\b${alias.replace(/[$]/g, '\\$&')}\\s*\\(`, 'g');
32
+ for (const match of source.matchAll(call)) {
33
+ findings.push({ file, line: lineAt(source, match.index ?? 0), api });
34
+ }
35
+ }
36
+
37
+ const namespaceNames = new Set<string>();
38
+ for (const match of source.matchAll(
39
+ /import\s+(?:\*\s+as\s+|)([\w$]+)\s+from\s*['"]react-dom(?:\/client)?['"]/g,
40
+ )) {
41
+ namespaceNames.add(match[1]!);
42
+ }
43
+ namespaceNames.add('ReactDOM');
44
+ for (const name of namespaceNames) {
45
+ for (const api of ['createRoot', 'hydrateRoot', 'render'] as const) {
46
+ const call = new RegExp(`\\b${name}\\.${api}\\s*\\(`, 'g');
47
+ for (const match of source.matchAll(call)) {
48
+ findings.push({
49
+ file,
50
+ line: lineAt(source, match.index ?? 0),
51
+ api: api === 'render' ? 'ReactDOM.render' : api,
52
+ });
53
+ }
54
+ }
55
+ }
56
+
57
+ return findings.filter(
58
+ (finding, index) =>
59
+ findings.findIndex(
60
+ (candidate) =>
61
+ candidate.file === finding.file &&
62
+ candidate.line === finding.line &&
63
+ candidate.api === finding.api,
64
+ ) === index,
65
+ );
66
+ }
@@ -5,11 +5,11 @@
5
5
  * Lives under `packages/engine/src/react/` deliberately: this is the ONE
6
6
  * directory of the engine allowed to value-import react (colocated with
7
7
  * `game-state.tsx` per the react-free-core rule proved by
8
- * `test/react-core-import-ban.test.ts`). Game worlds that aren't react keep
8
+ * `test/react-core-import-ban.test.ts`). Game roots that aren't react keep
9
9
  * using `DataHandle.get()`/`subscribe()` directly (§2.3).
10
10
  *
11
11
  * - {@link useData} — subscribe a component to any W1 `DataHandle`; works in
12
- * project tools, react worlds, and HUD overlays alike.
12
+ * project tools, react roots, and HUD overlays alike.
13
13
  * - {@link writeData} — EDITOR-TOOL plumbing: write a whole `.data.json`
14
14
  * back through the editor dev server, closing the live-tuning loop
15
15
  * (widget → file write → Vite HMR → `hotSwap` → {@link useData} re-render
@@ -89,6 +89,16 @@ export async function writeData(
89
89
  ?.replace(/\.data\.json$/, '')}.schema.json`;
90
90
  const content = `${JSON.stringify({ $schema: schemaRef, ...rest }, null, 2)}\n`;
91
91
 
92
+ const transactionalWriter = (
93
+ globalThis as typeof globalThis & {
94
+ __vgaiHistoryWriteData?: (path: string, content: string) => Promise<void>;
95
+ }
96
+ ).__vgaiHistoryWriteData;
97
+ if (transactionalWriter) {
98
+ await transactionalWriter(projectRelativePath, content);
99
+ return;
100
+ }
101
+
92
102
  let res: Response;
93
103
  try {
94
104
  res = await fetch('/__editor/data-file', {