@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,10 @@
1
1
  import type RAPIER from '@dimforge/rapier3d-compat';
2
2
  import type { EffectComposer } from 'postprocessing';
3
3
  import type * as THREE from 'three';
4
+ import type { z } from 'zod';
4
5
  import type { SystemAdapters } from '../adapter/system-adapter';
5
6
  import type { AssetCache } from '../assets';
7
+ import type { SeededRandom } from '../core/seeded-random';
6
8
  import type { createSystemRunner } from '../core/system-runner';
7
9
  import type { createDebugDraw } from '../dev/debug-draw';
8
10
  import type { ComponentManager } from '../ecs/component-manager';
@@ -13,7 +15,87 @@ import type { SceneFile } from '../scene/scene-types';
13
15
  import type { AudioContext as GameAudio } from '../setup/setup-audio';
14
16
  import type { ParticlesContext } from '../setup/setup-particles';
15
17
  import type { Game, WorldInstance } from './game';
16
- import type { SceneUIGameServices } from './scene-ui-bridge';
18
+
19
+ /**
20
+ * The minimal structural shape `ctx.debug.attachRoom` needs from a joined
21
+ * Colyseus room (Task 2.2, `docs/SYNTHETIC-PLAYER-SPEC.md` §3.1's "Multiplayer
22
+ * locus" note): just enough to send the reserved `__vgai:debugCommand`
23
+ * message and listen for its `__vgai:debugCommandResult` reply. Structural,
24
+ * not a Colyseus type import — the same seam-boundary style every other
25
+ * `DebugCtxSurface` member uses (no wrapper around Colyseus itself, D2).
26
+ * `onMessage`'s return type is `unknown` because Colyseus's own return shape
27
+ * (void in some client versions, an unsubscribe function in others) isn't
28
+ * load-bearing here: the registry calls it defensively (invokes it on detach
29
+ * only if it's actually a function).
30
+ */
31
+ export interface DebugRoomHandle {
32
+ send(type: string, message?: unknown): void;
33
+ onMessage(type: string, cb: (message: unknown) => void): unknown;
34
+ }
35
+
36
+ /**
37
+ * Infers a `registerCommand`/`registerReactCommand`/`useDebugCommand`
38
+ * handler's parameter tuple from its declared Zod `args` tuple (dry-run
39
+ * finding, `docs/ACCEPTANCE-DRIVER-BUILD-PLAN.md` Wave 6 ledger —
40
+ * "`registerCommand` fn typing forces `unknown[]` casts"): a real
41
+ * `z.ZodTuple` infers its element types (`z.tuple([z.number(), z.string()])`
42
+ * → `(n: number, s: string) => ...`), while omitting `args` (the generic's
43
+ * `undefined` default) resolves to the original permissive
44
+ * `(...args: unknown[]) => ...` shape every command had before this generic
45
+ * existed. That permissive fallback is deliberate, not just a placeholder —
46
+ * it keeps every existing no-schema registration (including ones whose
47
+ * handler reads positional args the runtime never validates, since
48
+ * `invoke()` only parses `args` against a schema when one is declared)
49
+ * compiling byte-for-byte unchanged.
50
+ */
51
+ export type DebugCommandArgs<T extends z.ZodTuple | undefined = undefined> = T extends z.ZodTuple
52
+ ? z.infer<T>
53
+ : unknown[];
54
+
55
+ /**
56
+ * The authoring half of the debug/synthetic-player seam
57
+ * (`docs/SYNTHETIC-PLAYER-SPEC.md` §3.1) — the read/actuate half is
58
+ * `SystemAdapters.DebugAdapter` (`adapter/system-adapter.ts`). Callable from
59
+ * any GameComponent's `init` (one file per new provider/command), or from a
60
+ * react world's `useDebugProvider`/`useDebugCommand`/`useDebugEmit` hooks. Every registration
61
+ * feeds the ONE game-scoped registry (`runtime/debug-registry.ts`) — never a
62
+ * per-world accumulator.
63
+ */
64
+ export interface DebugCtxSurface {
65
+ /** Register (or replace) a named, JSON-serializable state read. Duplicate
66
+ * names from the SAME world replace + warn once; the SAME name from a
67
+ * DIFFERENT world throws (`DebugError` code `DEBUG_NAME_COLLISION`). */
68
+ registerStateProvider(
69
+ name: string,
70
+ fn: () => unknown,
71
+ opts?: { tier?: 'observable' | 'assisted' },
72
+ ): void;
73
+ /** Register (or replace) an invokable command. `locus` is REQUIRED once the
74
+ * project declares a Colyseus room (`DebugRegistry.setRoomDeclared`) — a
75
+ * fixture must say whether it mutates authoritative (server) or predicted
76
+ * (client) state.
77
+ *
78
+ * Generic over the declared `args` Zod tuple ({@link DebugCommandArgs}) so
79
+ * `fn`'s parameters INFER from it: `registerCommand('setHp', { args:
80
+ * z.tuple([z.number()]) }, (hp) => ...)` types `hp` as `number` with no
81
+ * cast. Leaving `args` off keeps `fn` typed `(...args: unknown[]) => ...`,
82
+ * same as before this generic existed. */
83
+ registerCommand<T extends z.ZodTuple | undefined = undefined>(
84
+ name: string,
85
+ spec: { description?: string; args?: T; locus?: 'client' | 'server' },
86
+ fn: (...args: DebugCommandArgs<T>) => unknown | Promise<unknown>,
87
+ ): void;
88
+ /** Push a tick-stamped event onto the debug event ring (spec §3.3) — the
89
+ * engine stamps `tick`/`simT` at emission, not at read time. */
90
+ emit(event: string, detail?: unknown): void;
91
+ /**
92
+ * Task 2.2 — server-locus command routing (client leg). Call once your
93
+ * game code has joined its Colyseus room, so `locus: 'server'` commands
94
+ * have somewhere to send `__vgai:debugCommand`. Returns a detach function
95
+ * (call on room leave/dispose) — game-scoped, last-attached room wins.
96
+ */
97
+ attachRoom(room: DebugRoomHandle): () => void;
98
+ }
17
99
 
18
100
  /**
19
101
  * All engine subsystems, passed to every game `setup(ctx)` and to each
@@ -84,21 +166,17 @@ export interface GameContext {
84
166
  /** Manager for all live GameComponent instances (attach/detach/HMR). The
85
167
  * scene loader drives this; gameplay code rarely touches it directly. */
86
168
  components: ComponentManager;
87
- /** DOM element overlaying the canvas for game UI (React via `mountUI`, or
88
- * vanilla). `pointer-events:none` by default — set `auto` on interactive
89
- * elements. Cleared on scene switch / hot-reload. */
90
- uiContainer: HTMLDivElement;
91
169
  /** Register a game-owned `SystemAdapters` capability (networking,
92
170
  * navigation, …) on the mounted game's adapter surface, so the editor's
93
171
  * introspection panels (via `getActiveSystems()`) can see it. The engine
94
- * wires the first-party physics/input/assets/animation entries itself;
172
+ * wires the first-party physics/input/assets/audio entries itself;
95
173
  * capabilities the GAME owns (a Colyseus connection, a NavMeshManager)
96
174
  * are registered here by the game's setup. Optional capability — absent
97
175
  * in contexts that expose no adapter surface (some test harnesses);
98
176
  * call as `ctx.registerSystemAdapter?.(…)`.
99
177
  *
100
178
  * Ordering contract: **game registrations always win** — the engine seeds
101
- * its first-party entries (physics/input/assets/animation) BEFORE setup()
179
+ * its first-party entries (physics/input/assets/audio) BEFORE setup()
102
180
  * runs, so a game that registers any of those same kinds during its own
103
181
  * setup overrides the engine's entry, not the other way around. This also
104
182
  * holds across a warm restart (`hotReload`): every kind the outgoing game
@@ -108,27 +186,31 @@ export interface GameContext {
108
186
  * mounted surface. */
109
187
  registerSystemAdapter?<K extends keyof SystemAdapters>(kind: K, adapter: SystemAdapters[K]): void;
110
188
 
189
+ /** The debug/synthetic-player authoring surface (`docs/SYNTHETIC-PLAYER-SPEC.md`
190
+ * §3.1) — see {@link DebugCtxSurface}. Optional, same absence precedent as
191
+ * `registerSystemAdapter`: present on every first-party mount, absent only
192
+ * in bare test harnesses that build a hand-rolled `ctx`. */
193
+ debug?: DebugCtxSurface;
194
+
111
195
  /**
112
- * Register (or replace) this game's scene-UI game-time services — the data
113
- * source, custom onEvent handler, and/or worldProjector overrides a scene's
114
- * authored UI mounts against (design/24-scene-ui.md D2/D7). Optional, same
115
- * precedent as `registerSystemAdapter`: absent in contexts with no scene-UI
116
- * surface at all (bare test harnesses).
117
- *
118
- * Timing is safe by construction: the scene loader awaits
119
- * `componentManager.initAll()` before `loadScene`/`loadSceneFromData`
120
- * return, and the adapter mounts scene UI only after that — so calling this
121
- * from a `GameComponent.init()` always beats the mount (its services are
122
- * folded into the FIRST render, not a late update). A call AFTER the mount
123
- * (e.g. from a click handler) updates the live mount in place instead
124
- * (`SceneUIHandle.update`, or a dispose+remount if the renderer has none).
125
- *
126
- * Per-key merge (D2): a key set here always wins over both the project's
127
- * registration-time registry and the engine's own D4/D5/D6 defaults. Hot
128
- * reload strips every game-registered key back to none before the incoming
129
- * game's `init()` runs — same contract as `registerSystemAdapter`'s re-seed.
196
+ * D15 (T-D15.1, `docs/D15-DETERMINISM-DESIGN.md` §2.a) — the game-scoped,
197
+ * named-stream seeded PRNG. `ctx.random()` draws from the `'gameplay'`
198
+ * stream; `ctx.random.stream('vfx')` (or any other name) draws from an
199
+ * INDEPENDENT stream, so a cosmetic/VFX draw can never shift the gameplay
200
+ * draw sequence. Use this instead of raw `Math.random()` for anything a
201
+ * project wants to keep reproducible; `ctx.random` itself always exists
202
+ * and is always internally consistent (same seed ⇒ same sequence) whether
203
+ * or not the project's manifest declares `determinism.seededRandom` — that
204
+ * flag only gates the BOOT-TIME seeding from
205
+ * `manifest.determinism.defaultSeed`/`?vgai-seed=`, the burn-down lint
206
+ * scan, and the dev-mode `Math.random` phase trap (three separate
207
+ * enforcers, `test/gameplay-rng-ban.test.ts` + `runtime/gameplay-rng-trap.ts`),
208
+ * never `ctx.random`'s mere presence. Same absence precedent as `debug`
209
+ * above: present on every first-party mount, optional only for bare test
210
+ * harnesses that build a hand-rolled `ctx`. `reseed(seed)` (future draws
211
+ * only) is `play.seed.set`'s eventual target (T-D15.6, not yet wired).
130
212
  */
131
- setSceneUIServices?(services: SceneUIGameServices): void;
213
+ random?: SeededRandom;
132
214
 
133
215
  // ─── Game root (T7.1 slice 1 — GAME-ROOT-DESIGN.md D6) ───
134
216
 
@@ -138,9 +220,9 @@ export interface GameContext {
138
220
  * harness that builds a hand-rolled `ctx` object keeps compiling
139
221
  * unmodified — the same precedent as `registerSystemAdapter`. */
140
222
  game?: Game | undefined;
141
- /** Alias for `game.worlds` — the live, declaration-ordered world registry.
223
+ /** Alias for `game.roots` — the live, declaration-ordered world registry.
142
224
  * Same optionality/absence rule as `game` above. */
143
- worlds?: ReadonlyArray<WorldInstance> | undefined;
225
+ roots?: ReadonlyArray<WorldInstance> | undefined;
144
226
  }
145
227
 
146
228
  /** Return value from a game setup function. */
@@ -5,6 +5,7 @@
5
5
  * and editor entity factory import from this module.
6
6
  */
7
7
 
8
+ import * as THREE from 'three';
8
9
  import { resolveUrl } from '../loader';
9
10
 
10
11
  export interface ImportCorrection {
@@ -18,6 +19,27 @@ export interface AssetMeta {
18
19
  importCorrection?: ImportCorrection;
19
20
  }
20
21
 
22
+ /**
23
+ * Apply an asset's visual-only import correction to the loaded GLTF content.
24
+ * Call this on the model child, before placing it under the entity wrapper, so
25
+ * gameplay transforms, physics, cameras, and movement remain in VGAI's Y-up /
26
+ * -Z-forward coordinate contract.
27
+ */
28
+ export function applyImportCorrection(
29
+ content: THREE.Object3D,
30
+ correction: ImportCorrection | undefined,
31
+ ): void {
32
+ if (!correction) return;
33
+ if (correction.scale !== undefined) content.scale.multiplyScalar(correction.scale);
34
+ if (correction.rotation) {
35
+ content.rotation.set(
36
+ THREE.MathUtils.degToRad(correction.rotation[0]),
37
+ THREE.MathUtils.degToRad(correction.rotation[1]),
38
+ THREE.MathUtils.degToRad(correction.rotation[2]),
39
+ );
40
+ }
41
+ }
42
+
21
43
  type AssetRegistry = Record<string, AssetMeta>;
22
44
 
23
45
  let registryCache: AssetRegistry | null = null;
@@ -1,13 +1,24 @@
1
1
  import type * as THREE from 'three';
2
2
  import type { ComponentManager } from '../ecs/component-manager';
3
- import { GameComponent, type GameComponentClass } from '../ecs/game-component';
3
+ import {
4
+ GAME_COMPONENT_BRAND,
5
+ GameComponent,
6
+ type GameComponentClass,
7
+ } from '../ecs/game-component';
4
8
 
5
9
  /** A registry mapping component names to GameComponent classes. */
6
10
  export type ComponentRegistry = Record<string, GameComponentClass>;
7
11
 
8
- /** Type guard: is this value a GameComponent class? */
12
+ /** Type guard: is this value a GameComponent class? `instanceof` alone is NOT
13
+ * enough: a scaffolded project's node-side scripts resolve TWO physical
14
+ * copies of the engine (published `@vgai/engine/*` + the `@engine/*` source
15
+ * alias), and a class extending the OTHER copy's `GameComponent` fails the
16
+ * prototype-chain check — so this also accepts the cross-copy
17
+ * {@link GAME_COMPONENT_BRAND}. */
9
18
  export function isGameComponentClass(entry: unknown): entry is GameComponentClass {
10
- return typeof entry === 'function' && entry.prototype instanceof GameComponent;
19
+ if (typeof entry !== 'function') return false;
20
+ if (entry.prototype instanceof GameComponent) return true;
21
+ return (entry as unknown as Record<symbol, unknown>)[GAME_COMPONENT_BRAND] === true;
11
22
  }
12
23
 
13
24
  /**
@@ -40,6 +40,7 @@ export const DEFAULTS = {
40
40
  intensity: 1,
41
41
  groundColor: '#000000',
42
42
  distance: 0,
43
+ decay: 2,
43
44
  angle: Math.PI / 6,
44
45
  penumbra: 0,
45
46
  // three.js's own RectAreaLight constructor defaults (area lights only).
@@ -42,15 +42,23 @@ export function createLight(def: SceneLight): THREE.Light {
42
42
  case 'directional':
43
43
  return new THREE.DirectionalLight(color, intensity);
44
44
  case 'point':
45
- return new THREE.PointLight(color, intensity, def.distance ?? d.distance);
46
- case 'spot':
47
- return new THREE.SpotLight(
45
+ return new THREE.PointLight(
46
+ color,
47
+ intensity,
48
+ def.distance ?? d.distance,
49
+ def.decay ?? d.decay,
50
+ );
51
+ case 'spot': {
52
+ const light = new THREE.SpotLight(
48
53
  color,
49
54
  intensity,
50
55
  def.distance ?? d.distance,
51
56
  def.angle ?? d.angle,
52
57
  def.penumbra ?? d.penumbra,
53
58
  );
59
+ light.decay = def.decay ?? d.decay;
60
+ return light;
61
+ }
54
62
  case 'hemisphere':
55
63
  return new THREE.HemisphereLight(color, def.groundColor ?? d.groundColor, intensity);
56
64
  case 'area': {
@@ -114,6 +114,49 @@ function cloneEntity(e: SceneEntity): SceneEntity {
114
114
  return JSON.parse(JSON.stringify(e)) as SceneEntity;
115
115
  }
116
116
 
117
+ /** True iff at least one entity in the tree (at any depth) carries a persisted `id`. */
118
+ function hasAnyPersistedId(entities: SceneEntity[]): boolean {
119
+ for (const e of entities) {
120
+ if (e.id) return true;
121
+ if (e.children && hasAnyPersistedId(e.children)) return true;
122
+ }
123
+ return false;
124
+ }
125
+
126
+ /**
127
+ * The id-persistence trap, made honest.
128
+ *
129
+ * `id` is `z.string().optional()` in the entity schema ("auto-generated if
130
+ * omitted"), and the ids an agent can actually DISCOVER — `vgai status`' —
131
+ * are the RUNTIME uuids a live editor session assigns to id-less entities on
132
+ * load (`editor-store.ts`'s `assignMissingIds`). `applyDiff` resolves ops
133
+ * against the FILE. So for any scene authored the normal way (hand-written,
134
+ * or scaffolded — none of which shipped with ids), the only ids on offer
135
+ * could never resolve here, and the failure read `entity not found` — as if
136
+ * the CALLER had typo'd the id. It is not a typo: NOTHING in that file could
137
+ * ever have matched.
138
+ *
139
+ * The durable half of the fix makes ids real (the editor now persists
140
+ * auto-assigned ids back to the scene file on load — see `loadDocument`), so
141
+ * this message is the safety net for a file that has not been through that
142
+ * path yet. It fires ONLY when the scene has zero persisted ids at all — a
143
+ * genuine bad-id typo against an id-carrying scene still gets the plain,
144
+ * unpadded message.
145
+ */
146
+ const NO_IDS_HINT =
147
+ ' — and this scene file has NO persisted entity ids AT ALL, so nothing in it could have ' +
148
+ 'matched, whatever id the op named. This is almost certainly not a typo: `vgai status` ' +
149
+ 'reports RUNTIME ids a live editor session assigns to id-less entities on load, and those ' +
150
+ 'only exist in the FILE once the editor has written them back (it now does that ' +
151
+ 'automatically, via autosave, shortly after the scene loads). Open this scene in the editor ' +
152
+ '(`vgai edit`), let it autosave, then re-read the ids with `vgai status` and retry. Do not ' +
153
+ 'hand-write ids into the file.';
154
+
155
+ /** Append the no-ids explanation to a not-found message when (and only when) the file has no ids. */
156
+ function notFound(message: string, sceneHasIds: boolean): string {
157
+ return sceneHasIds ? message : message + NO_IDS_HINT;
158
+ }
159
+
117
160
  /** Recursively search `list` (and descendants) for `id`; if found, splice it out (subtree intact) and return it. */
118
161
  function detachById(list: SceneEntity[], id: string): SceneEntity | undefined {
119
162
  for (let i = 0; i < list.length; i++) {
@@ -168,6 +211,9 @@ interface Placement {
168
211
  export function applyDiff(scene: SceneFile, diff: SceneDiff): SceneFile {
169
212
  const working: SceneFile = JSON.parse(JSON.stringify(scene)) as SceneFile;
170
213
  const ops = diff.ops;
214
+ // Captured from the INPUT scene, before any op mutates `working` — see
215
+ // `NO_IDS_HINT` above for what this distinguishes and why.
216
+ const sceneHasIds = hasAnyPersistedId(scene.entities);
171
217
 
172
218
  // --- Metadata / environment (independent of entity ops) ---
173
219
  if (diff.metaChanged && diff.newName !== undefined) {
@@ -227,7 +273,12 @@ export function applyDiff(scene: SceneFile, diff: SceneDiff): SceneFile {
227
273
  if (pendingMoves.size > 0) {
228
274
  const i = [...pendingMoves][0]!;
229
275
  const op = ops[i] as Extract<DiffOp, { type: 'move' }>;
230
- throw new ApplyDiffError('entity not found (nothing to move)', i, 'move', op.id);
276
+ throw new ApplyDiffError(
277
+ notFound('entity not found (nothing to move)', sceneHasIds),
278
+ i,
279
+ 'move',
280
+ op.id,
281
+ );
231
282
  }
232
283
 
233
284
  // --- Phase 2: removes (a not-found target is fine if it was already swept
@@ -243,7 +294,7 @@ export function applyDiff(scene: SceneFile, diff: SceneDiff): SceneFile {
243
294
  }
244
295
  if (sweptIds.has(op.id)) return;
245
296
  throw new ApplyDiffError(
246
- 'entity not found (already removed via an ancestor, or an invalid id)',
297
+ notFound('entity not found (already removed via an ancestor, or an invalid id)', sceneHasIds),
247
298
  i,
248
299
  'remove',
249
300
  op.id,
@@ -311,7 +362,7 @@ export function applyDiff(scene: SceneFile, diff: SceneDiff): SceneFile {
311
362
  if (!parentNode) {
312
363
  const bad = placements[0]!;
313
364
  throw new ApplyDiffError(
314
- `parent entity "${parentId}" not found`,
365
+ notFound(`parent entity "${parentId}" not found`, sceneHasIds),
315
366
  bad.opIndex,
316
367
  bad.opType,
317
368
  bad.entityId,
@@ -341,7 +392,7 @@ export function applyDiff(scene: SceneFile, diff: SceneDiff): SceneFile {
341
392
  if (op.type !== 'update') return;
342
393
  const node = byId.get(op.id);
343
394
  if (!node) {
344
- throw new ApplyDiffError('entity not found', i, 'update', op.id);
395
+ throw new ApplyDiffError(notFound('entity not found', sceneHasIds), i, 'update', op.id);
345
396
  }
346
397
  const { id: _id, children: _children, ...fields } = op.entity;
347
398
  for (const key of Object.keys(node) as (keyof SceneEntity)[]) {
@@ -16,7 +16,7 @@ import {
16
16
  loadGLTF,
17
17
  resolveGltfNode,
18
18
  } from './asset-loaders';
19
- import { getAssetMeta, loadRegistry } from './asset-registry';
19
+ import { applyImportCorrection, getAssetMeta, loadRegistry } from './asset-registry';
20
20
  import { computeColliderWorldDimensions, computeColliderWorldOffset } from './collider-dimensions';
21
21
  import { applyComponents, type ComponentRegistry } from './component-registry';
22
22
  import { DEFAULTS } from './defaults';
@@ -39,7 +39,6 @@ import {
39
39
  type SceneMaterial,
40
40
  type ScenePhysics,
41
41
  type SceneSpline,
42
- type UIRoot,
43
42
  } from './scene-types';
44
43
  import { isEntityRefSchema } from './schema/entity-ref';
45
44
  import { getUserData, setUserData } from './user-data';
@@ -213,16 +212,6 @@ export interface SceneInstance {
213
212
  /** Parsed scene environment, if any — lets the runtime apply post-processing
214
213
  * (which needs the composer/camera the loader doesn't have). */
215
214
  environment?: SceneEnvironment | undefined;
216
- /**
217
- * The scene file's top-level `ui` tree (React UI roots/canvases, A1),
218
- * carried through verbatim from the parsed `SceneFile` by BOTH `loadScene`
219
- * and `loadSceneFromData` (single source of truth — R8 item 7 / B). Opaque
220
- * to the loader itself; the adapter passes it to `renderSceneUI` (the
221
- * injected React renderer) so scenePath and sceneData mounts render the
222
- * SAME scene-authored UI instead of only the sceneData branch special-
223
- * casing it. `undefined` when the scene file has no `ui` field.
224
- */
225
- ui?: UIRoot[] | undefined;
226
215
  /**
227
216
  * Authored entity id -> spawned Object3D (design/24-scene-ui.md D5). The
228
217
  * SAME map `spawnEntity`/`createSceneJoints` build internally (id-less
@@ -526,7 +515,6 @@ async function instantiateScene(
526
515
  navMesh,
527
516
  cameras,
528
517
  environment: data.environment,
529
- ui: data.ui,
530
518
  entities: idMap,
531
519
  update(dt: number) {
532
520
  for (const fn of tickFns) fn(dt);
@@ -674,20 +662,7 @@ async function spawnEntity(
674
662
  }
675
663
 
676
664
  // Apply import correction from asset registry
677
- const meta = getAssetMeta(def.mesh.src);
678
- if (meta?.importCorrection) {
679
- const ic = meta.importCorrection;
680
- if (ic.scale !== undefined) {
681
- content.scale.multiplyScalar(ic.scale);
682
- }
683
- if (ic.rotation) {
684
- content.rotation.set(
685
- THREE.MathUtils.degToRad(ic.rotation[0]),
686
- THREE.MathUtils.degToRad(ic.rotation[1]),
687
- THREE.MathUtils.degToRad(ic.rotation[2]),
688
- );
689
- }
690
- }
665
+ applyImportCorrection(content, getAssetMeta(def.mesh.src)?.importCorrection);
691
666
 
692
667
  // Wrap in a group so entity transform and import correction are separated.
693
668
  // `content` carries import correction; wrapper carries entity transform.
@@ -1098,6 +1073,14 @@ function createPhysicsBody(
1098
1073
  }
1099
1074
  if (col.isSensor) {
1100
1075
  colliderDesc.setSensor(true);
1076
+ // Rapier's DEFAULT omits every non-dynamic pair. Player characters are
1077
+ // commonly position-based kinematic bodies and authored pickups commonly
1078
+ // use fixed sensors, so DEFAULT makes the pair invisible to the physics
1079
+ // event queue even after the KCC correctly excludes sensors from movement
1080
+ // blocking. A sensor's contract is observation, not contact response:
1081
+ // enable every body-type pair so real overlaps consistently reach
1082
+ // onTriggerEnter/Exit.
1083
+ colliderDesc.setActiveCollisionTypes(rapier.ActiveCollisionTypes.ALL);
1101
1084
  }
1102
1085
  // All scene-loaded colliders opt into collision events — sensors need them for
1103
1086
  // onTriggerEnter/onTriggerExit, and solid colliders need them for onCollision
@@ -28,7 +28,6 @@ export type {
28
28
  ScenePostProcessing,
29
29
  SceneSpline,
30
30
  SceneToneMapping,
31
- UIRoot,
32
31
  } from './schema';
33
32
 
34
33
  export { mergePrefabInstance } from './schema';
@@ -49,37 +49,3 @@ export { SceneSplineOverrideSchema, SceneSplineSchema } from './spline';
49
49
  // Inferred types
50
50
  export type { Quat, SceneTransform, Vec3 } from './tuples';
51
51
  export { QuatSchema, TransformSchema, Vec3Schema } from './tuples';
52
- // UI scene-graph schema (editable React UI in the scene graph)
53
- export type {
54
- UIAnimatableProperty,
55
- UIAnimation,
56
- UIBinding,
57
- UIEasing,
58
- UIKeyframe,
59
- UILayout,
60
- UINode,
61
- UINodeKind,
62
- UIPrefabFile,
63
- UIRoot,
64
- UIStyle,
65
- UITheme,
66
- UIThemeFile,
67
- UITrack,
68
- } from './ui';
69
- export {
70
- UIAnimatablePropertySchema,
71
- UIAnimationSchema,
72
- UIBindingSchema,
73
- UIEasingSchema,
74
- UIKeyframeSchema,
75
- UILayoutSchema,
76
- UINodeKindSchema,
77
- UINodeSchema,
78
- UIPrefabFileSchema,
79
- UIRootSchema,
80
- UIStateStylesSchema,
81
- UIStyleSchema,
82
- UIThemeFileSchema,
83
- UIThemeSchema,
84
- UITrackSchema,
85
- } from './ui';
@@ -3,12 +3,27 @@ import { z } from 'zod';
3
3
  const SceneLightBase = z.object({
4
4
  type: z.enum(['directional', 'point', 'spot', 'hemisphere', 'area']).describe('Light type'),
5
5
  color: z.string().optional().describe('Light color as CSS hex string'),
6
- intensity: z.number().optional().describe('Light intensity multiplier'),
6
+ intensity: z
7
+ .number()
8
+ .optional()
9
+ .describe(
10
+ 'Native Three.js light intensity. Point and spot lights use candela with inverse-square ' +
11
+ 'falloff (a value near 1 is candle-scale); area lights use nit; directional and ' +
12
+ 'hemisphere lights use Three.js scene-light intensity units.',
13
+ ),
7
14
  groundColor: z.string().optional().describe('Ground color for hemisphere lights'),
8
15
  distance: z
9
16
  .number()
10
17
  .optional()
11
18
  .describe('Maximum range of the light. 0 = infinite (point/spot only)'),
19
+ decay: z
20
+ .number()
21
+ .nonnegative()
22
+ .optional()
23
+ .describe(
24
+ 'Native Three.js distance-decay exponent for point/spot lights. Default 2 gives ' +
25
+ 'physically correct inverse-square falloff.',
26
+ ),
12
27
  angle: z.number().optional().describe('Spotlight cone angle in radians (spot only)'),
13
28
  penumbra: z.number().optional().describe('Spotlight penumbra softness 0–1 (spot only)'),
14
29
  width: z