@vgai/engine 0.2.0 → 0.3.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 (541) hide show
  1. package/README.md +3 -1
  2. package/dist/adapter/authoring.d.ts +404 -0
  3. package/dist/adapter/authoring.d.ts.map +1 -0
  4. package/dist/adapter/authoring.js +22 -0
  5. package/dist/adapter/colyseus-networking-adapter.d.ts +43 -0
  6. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
  7. package/dist/adapter/colyseus-networking-adapter.js +38 -0
  8. package/dist/adapter/first-party-systems.d.ts +38 -0
  9. package/dist/adapter/first-party-systems.d.ts.map +1 -0
  10. package/dist/adapter/first-party-systems.js +77 -0
  11. package/dist/adapter/game-adapter.d.ts +133 -0
  12. package/dist/adapter/game-adapter.d.ts.map +1 -0
  13. package/dist/adapter/game-adapter.js +10 -0
  14. package/dist/adapter/host-context.d.ts +73 -0
  15. package/dist/adapter/host-context.d.ts.map +1 -0
  16. package/dist/adapter/host-context.js +16 -0
  17. package/dist/adapter/index.d.ts +22 -0
  18. package/dist/adapter/index.d.ts.map +1 -0
  19. package/dist/adapter/index.js +15 -0
  20. package/dist/adapter/ingest/game-contract.d.ts +53 -0
  21. package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
  22. package/dist/adapter/ingest/game-contract.js +30 -0
  23. package/dist/adapter/ingest/overlay-applier.d.ts +118 -0
  24. package/dist/adapter/ingest/overlay-applier.d.ts.map +1 -0
  25. package/dist/adapter/ingest/overlay-applier.js +132 -0
  26. package/dist/adapter/ingest/overlay-apply.d.ts +60 -0
  27. package/dist/adapter/ingest/overlay-apply.d.ts.map +1 -0
  28. package/dist/adapter/ingest/overlay-apply.js +101 -0
  29. package/dist/adapter/ingest/overlay-file.d.ts +79 -0
  30. package/dist/adapter/ingest/overlay-file.d.ts.map +1 -0
  31. package/dist/adapter/ingest/overlay-file.js +66 -0
  32. package/dist/adapter/ingest/overlay-report.d.ts +113 -0
  33. package/dist/adapter/ingest/overlay-report.d.ts.map +1 -0
  34. package/dist/adapter/ingest/overlay-report.js +103 -0
  35. package/dist/adapter/ingest/scene-capture.d.ts +97 -0
  36. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
  37. package/dist/adapter/ingest/scene-capture.js +248 -0
  38. package/dist/adapter/ingest/upstream-pin.d.ts +47 -0
  39. package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
  40. package/dist/adapter/ingest/upstream-pin.js +50 -0
  41. package/dist/adapter/loop-gate-report.d.ts +34 -0
  42. package/dist/adapter/loop-gate-report.d.ts.map +1 -0
  43. package/dist/adapter/loop-gate-report.js +37 -0
  44. package/dist/adapter/rapier-physics-adapter.d.ts +12 -0
  45. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
  46. package/dist/adapter/rapier-physics-adapter.js +46 -0
  47. package/dist/adapter/system-adapter.d.ts +133 -0
  48. package/dist/adapter/system-adapter.d.ts.map +1 -0
  49. package/dist/adapter/system-adapter.js +13 -0
  50. package/dist/adapter/transform.d.ts +18 -0
  51. package/dist/adapter/transform.d.ts.map +1 -0
  52. package/dist/adapter/transform.js +1 -0
  53. package/dist/adapter/vgai-scene-game-adapter.d.ts +116 -0
  54. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +1 -0
  55. package/dist/adapter/vgai-scene-game-adapter.js +714 -0
  56. package/dist/adapter/world-kind.d.ts +30 -0
  57. package/dist/adapter/world-kind.d.ts.map +1 -0
  58. package/dist/adapter/world-kind.js +18 -0
  59. package/dist/ai/navigation.d.ts +64 -0
  60. package/dist/ai/navigation.d.ts.map +1 -0
  61. package/dist/ai/navigation.js +133 -0
  62. package/dist/animation/anim-graph-types.d.ts +25 -0
  63. package/dist/animation/anim-graph-types.d.ts.map +1 -0
  64. package/dist/animation/anim-graph-types.js +1 -0
  65. package/dist/animation/animation-clock.d.ts +213 -0
  66. package/dist/animation/animation-clock.d.ts.map +1 -0
  67. package/dist/animation/animation-clock.js +301 -0
  68. package/dist/animation/blend-node.d.ts +22 -0
  69. package/dist/animation/blend-node.d.ts.map +1 -0
  70. package/dist/animation/blend-node.js +97 -0
  71. package/dist/animation/camera-ownership.d.ts +250 -0
  72. package/dist/animation/camera-ownership.d.ts.map +1 -0
  73. package/dist/animation/camera-ownership.js +169 -0
  74. package/dist/animation/cinematic-cues.d.ts +200 -0
  75. package/dist/animation/cinematic-cues.d.ts.map +1 -0
  76. package/dist/animation/cinematic-cues.js +213 -0
  77. package/dist/animation/clip-map.d.ts +12 -0
  78. package/dist/animation/clip-map.d.ts.map +1 -0
  79. package/dist/animation/clip-map.js +37 -0
  80. package/dist/animation/gsap-registration.d.ts +119 -0
  81. package/dist/animation/gsap-registration.d.ts.map +1 -0
  82. package/dist/animation/gsap-registration.js +92 -0
  83. package/dist/animation/theatre-clock-binding.d.ts +89 -0
  84. package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
  85. package/dist/animation/theatre-clock-binding.js +29 -0
  86. package/dist/animation/theatre-director.d.ts +242 -0
  87. package/dist/animation/theatre-director.d.ts.map +1 -0
  88. package/dist/animation/theatre-director.js +235 -0
  89. package/dist/animation/theatre-object-binding.d.ts +305 -0
  90. package/dist/animation/theatre-object-binding.d.ts.map +1 -0
  91. package/dist/animation/theatre-object-binding.js +351 -0
  92. package/dist/animation/xstate-animation-binding.d.ts +111 -0
  93. package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
  94. package/dist/animation/xstate-animation-binding.js +307 -0
  95. package/dist/animation/xstate-animation-meta.d.ts +228 -0
  96. package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
  97. package/dist/animation/xstate-animation-meta.js +221 -0
  98. package/dist/assets.d.ts +26 -0
  99. package/dist/assets.d.ts.map +1 -0
  100. package/dist/assets.js +55 -0
  101. package/dist/audio/index.d.ts +4 -0
  102. package/dist/audio/index.d.ts.map +1 -0
  103. package/dist/audio/index.js +24 -0
  104. package/dist/audio/tone-clock-binding.d.ts +75 -0
  105. package/dist/audio/tone-clock-binding.d.ts.map +1 -0
  106. package/dist/audio/tone-clock-binding.js +29 -0
  107. package/dist/audio/tone-context.d.ts +114 -0
  108. package/dist/audio/tone-context.d.ts.map +1 -0
  109. package/dist/audio/tone-context.js +39 -0
  110. package/dist/audio/tone-offline-render.d.ts +90 -0
  111. package/dist/audio/tone-offline-render.d.ts.map +1 -0
  112. package/dist/audio/tone-offline-render.js +56 -0
  113. package/dist/audio/wav-encode.d.ts +38 -0
  114. package/dist/audio/wav-encode.d.ts.map +1 -0
  115. package/dist/audio/wav-encode.js +97 -0
  116. package/dist/core/game-loop.d.ts +21 -0
  117. package/dist/core/game-loop.d.ts.map +1 -0
  118. package/dist/core/game-loop.js +130 -0
  119. package/dist/core/system-runner.d.ts +120 -0
  120. package/dist/core/system-runner.d.ts.map +1 -0
  121. package/dist/core/system-runner.js +286 -0
  122. package/dist/core/types.d.ts +58 -0
  123. package/dist/core/types.d.ts.map +1 -0
  124. package/dist/core/types.js +25 -0
  125. package/dist/data/data-asset.d.ts +101 -0
  126. package/dist/data/data-asset.d.ts.map +1 -0
  127. package/dist/data/data-asset.js +122 -0
  128. package/dist/data/data-check-core.d.ts +110 -0
  129. package/dist/data/data-check-core.d.ts.map +1 -0
  130. package/dist/data/data-check-core.js +178 -0
  131. package/dist/data/data-ref.d.ts +79 -0
  132. package/dist/data/data-ref.d.ts.map +1 -0
  133. package/dist/data/data-ref.js +130 -0
  134. package/dist/data/vite-plugin-data.d.ts +79 -0
  135. package/dist/data/vite-plugin-data.d.ts.map +1 -0
  136. package/dist/data/vite-plugin-data.js +217 -0
  137. package/dist/dev/console-bridge.d.ts +22 -0
  138. package/dist/dev/console-bridge.d.ts.map +1 -0
  139. package/dist/dev/console-bridge.js +71 -0
  140. package/dist/dev/debug-draw.d.ts +24 -0
  141. package/dist/dev/debug-draw.d.ts.map +1 -0
  142. package/dist/dev/debug-draw.js +73 -0
  143. package/dist/dev/logger.d.ts +30 -0
  144. package/dist/dev/logger.d.ts.map +1 -0
  145. package/dist/dev/logger.js +90 -0
  146. package/dist/ecs/component-manager.d.ts +189 -0
  147. package/dist/ecs/component-manager.d.ts.map +1 -0
  148. package/dist/ecs/component-manager.js +676 -0
  149. package/dist/ecs/game-component.d.ts +97 -0
  150. package/dist/ecs/game-component.d.ts.map +1 -0
  151. package/dist/ecs/game-component.js +80 -0
  152. package/dist/ecs/hmr-swap-report.d.ts +53 -0
  153. package/dist/ecs/hmr-swap-report.d.ts.map +1 -0
  154. package/dist/ecs/hmr-swap-report.js +55 -0
  155. package/dist/index.d.ts +37 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +30 -0
  158. package/dist/input/input-manager.d.ts +596 -0
  159. package/dist/input/input-manager.d.ts.map +1 -0
  160. package/dist/input/input-manager.js +1564 -0
  161. package/dist/input/input-types.d.ts +171 -0
  162. package/dist/input/input-types.d.ts.map +1 -0
  163. package/dist/input/input-types.js +1 -0
  164. package/dist/input/prompt-labels.d.ts +21 -0
  165. package/dist/input/prompt-labels.d.ts.map +1 -0
  166. package/dist/input/prompt-labels.js +121 -0
  167. package/dist/input/rebind-controller.d.ts +59 -0
  168. package/dist/input/rebind-controller.d.ts.map +1 -0
  169. package/dist/input/rebind-controller.js +85 -0
  170. package/dist/input/schema.d.ts +16 -0
  171. package/dist/input/schema.d.ts.map +1 -0
  172. package/dist/input/schema.js +228 -0
  173. package/dist/loader.d.ts +43 -0
  174. package/dist/loader.d.ts.map +1 -0
  175. package/dist/loader.js +59 -0
  176. package/dist/manifest/index.d.ts +5 -0
  177. package/dist/manifest/index.d.ts.map +1 -0
  178. package/dist/manifest/index.js +8 -0
  179. package/dist/manifest/load-file.d.ts +4 -0
  180. package/dist/manifest/load-file.d.ts.map +1 -0
  181. package/dist/manifest/load-file.js +14 -0
  182. package/dist/manifest/load.d.ts +117 -0
  183. package/dist/manifest/load.d.ts.map +1 -0
  184. package/dist/manifest/load.js +255 -0
  185. package/dist/manifest/schema.d.ts +173 -0
  186. package/dist/manifest/schema.d.ts.map +1 -0
  187. package/dist/manifest/schema.js +302 -0
  188. package/dist/physics/collision-system.d.ts +41 -0
  189. package/dist/physics/collision-system.d.ts.map +1 -0
  190. package/dist/physics/collision-system.js +64 -0
  191. package/dist/physics/physics-registry.d.ts +45 -0
  192. package/dist/physics/physics-registry.d.ts.map +1 -0
  193. package/dist/physics/physics-registry.js +65 -0
  194. package/dist/physics/transform-writer.d.ts +16 -0
  195. package/dist/physics/transform-writer.d.ts.map +1 -0
  196. package/dist/physics/transform-writer.js +38 -0
  197. package/dist/physics/trigger-dispatch.d.ts +24 -0
  198. package/dist/physics/trigger-dispatch.d.ts.map +1 -0
  199. package/dist/physics/trigger-dispatch.js +80 -0
  200. package/dist/react/game-state.d.ts +105 -0
  201. package/dist/react/game-state.d.ts.map +1 -0
  202. package/dist/react/game-state.js +144 -0
  203. package/dist/react/use-data.d.ts +60 -0
  204. package/dist/react/use-data.d.ts.map +1 -0
  205. package/dist/react/use-data.js +96 -0
  206. package/dist/react/use-selection.d.ts +75 -0
  207. package/dist/react/use-selection.d.ts.map +1 -0
  208. package/dist/react/use-selection.js +90 -0
  209. package/dist/render/auto-batcher.d.ts +34 -0
  210. package/dist/render/auto-batcher.d.ts.map +1 -0
  211. package/dist/render/auto-batcher.js +140 -0
  212. package/dist/render/render-batch-system.d.ts +33 -0
  213. package/dist/render/render-batch-system.d.ts.map +1 -0
  214. package/dist/render/render-batch-system.js +230 -0
  215. package/dist/render/render-features.d.ts +47 -0
  216. package/dist/render/render-features.d.ts.map +1 -0
  217. package/dist/render/render-features.js +105 -0
  218. package/dist/render/render-settings.d.ts +36 -0
  219. package/dist/render/render-settings.d.ts.map +1 -0
  220. package/dist/render/render-settings.js +51 -0
  221. package/dist/runtime/create-runtime.d.ts +280 -0
  222. package/dist/runtime/create-runtime.d.ts.map +1 -0
  223. package/dist/runtime/create-runtime.js +795 -0
  224. package/dist/runtime/frame-selector-cache.d.ts +41 -0
  225. package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
  226. package/dist/runtime/frame-selector-cache.js +65 -0
  227. package/dist/runtime/game.d.ts +433 -0
  228. package/dist/runtime/game.d.ts.map +1 -0
  229. package/dist/runtime/game.js +569 -0
  230. package/dist/runtime/input-router.d.ts +78 -0
  231. package/dist/runtime/input-router.d.ts.map +1 -0
  232. package/dist/runtime/input-router.js +171 -0
  233. package/dist/runtime/mount-game.d.ts +129 -0
  234. package/dist/runtime/mount-game.d.ts.map +1 -0
  235. package/dist/runtime/mount-game.js +152 -0
  236. package/dist/runtime/mount-manifest.d.ts +119 -0
  237. package/dist/runtime/mount-manifest.d.ts.map +1 -0
  238. package/dist/runtime/mount-manifest.js +204 -0
  239. package/dist/runtime/render-audio-control.d.ts +110 -0
  240. package/dist/runtime/render-audio-control.d.ts.map +1 -0
  241. package/dist/runtime/render-audio-control.js +111 -0
  242. package/dist/runtime/render-control.d.ts +291 -0
  243. package/dist/runtime/render-control.d.ts.map +1 -0
  244. package/dist/runtime/render-control.js +264 -0
  245. package/dist/runtime/render-seed.d.ts +57 -0
  246. package/dist/runtime/render-seed.d.ts.map +1 -0
  247. package/dist/runtime/render-seed.js +74 -0
  248. package/dist/runtime/scene-ui-bridge.d.ts +69 -0
  249. package/dist/runtime/scene-ui-bridge.d.ts.map +1 -0
  250. package/dist/runtime/scene-ui-bridge.js +23 -0
  251. package/dist/runtime/scene-ui-data.d.ts +13 -0
  252. package/dist/runtime/scene-ui-data.d.ts.map +1 -0
  253. package/dist/runtime/scene-ui-data.js +92 -0
  254. package/dist/runtime/state-bridge.d.ts +47 -0
  255. package/dist/runtime/state-bridge.d.ts.map +1 -0
  256. package/dist/runtime/state-bridge.js +53 -0
  257. package/dist/runtime/types.d.ts +179 -0
  258. package/dist/runtime/types.d.ts.map +1 -0
  259. package/dist/runtime/types.js +1 -0
  260. package/dist/scene/asset-loaders.d.ts +79 -0
  261. package/dist/scene/asset-loaders.d.ts.map +1 -0
  262. package/dist/scene/asset-loaders.js +141 -0
  263. package/dist/scene/asset-paths.d.ts +11 -0
  264. package/dist/scene/asset-paths.d.ts.map +1 -0
  265. package/dist/scene/asset-paths.js +108 -0
  266. package/dist/scene/asset-ref-check.d.ts +88 -0
  267. package/dist/scene/asset-ref-check.d.ts.map +1 -0
  268. package/dist/scene/asset-ref-check.js +214 -0
  269. package/dist/scene/asset-registry.d.ts +30 -0
  270. package/dist/scene/asset-registry.d.ts.map +1 -0
  271. package/dist/scene/asset-registry.js +50 -0
  272. package/dist/scene/collider-dimensions.d.ts +63 -0
  273. package/dist/scene/collider-dimensions.d.ts.map +1 -0
  274. package/dist/scene/collider-dimensions.js +98 -0
  275. package/dist/scene/component-registry.d.ts +17 -0
  276. package/dist/scene/component-registry.d.ts.map +1 -0
  277. package/dist/scene/component-registry.js +28 -0
  278. package/dist/scene/defaults.d.ts +252 -0
  279. package/dist/scene/defaults.d.ts.map +1 -0
  280. package/dist/scene/defaults.js +151 -0
  281. package/dist/scene/geometries/index.d.ts +8 -0
  282. package/dist/scene/geometries/index.d.ts.map +1 -0
  283. package/dist/scene/geometries/index.js +7 -0
  284. package/dist/scene/geometries/terrain.d.ts +2 -0
  285. package/dist/scene/geometries/terrain.d.ts.map +1 -0
  286. package/dist/scene/geometries/terrain.js +37 -0
  287. package/dist/scene/geometry-registry.d.ts +24 -0
  288. package/dist/scene/geometry-registry.d.ts.map +1 -0
  289. package/dist/scene/geometry-registry.js +20 -0
  290. package/dist/scene/instance-registry.d.ts +36 -0
  291. package/dist/scene/instance-registry.d.ts.map +1 -0
  292. package/dist/scene/instance-registry.js +55 -0
  293. package/dist/scene/instancers/grid.d.ts +2 -0
  294. package/dist/scene/instancers/grid.d.ts.map +1 -0
  295. package/dist/scene/instancers/grid.js +36 -0
  296. package/dist/scene/instancers/index.d.ts +8 -0
  297. package/dist/scene/instancers/index.d.ts.map +1 -0
  298. package/dist/scene/instancers/index.js +7 -0
  299. package/dist/scene/light-camera-factory.d.ts +23 -0
  300. package/dist/scene/light-camera-factory.d.ts.map +1 -0
  301. package/dist/scene/light-camera-factory.js +68 -0
  302. package/dist/scene/material-factory.d.ts +17 -0
  303. package/dist/scene/material-factory.d.ts.map +1 -0
  304. package/dist/scene/material-factory.js +197 -0
  305. package/dist/scene/material-registry.d.ts +40 -0
  306. package/dist/scene/material-registry.d.ts.map +1 -0
  307. package/dist/scene/material-registry.js +44 -0
  308. package/dist/scene/materials/index.d.ts +8 -0
  309. package/dist/scene/materials/index.d.ts.map +1 -0
  310. package/dist/scene/materials/index.js +7 -0
  311. package/dist/scene/materials/water.d.ts +2 -0
  312. package/dist/scene/materials/water.d.ts.map +1 -0
  313. package/dist/scene/materials/water.js +54 -0
  314. package/dist/scene/parse.d.ts +23 -0
  315. package/dist/scene/parse.d.ts.map +1 -0
  316. package/dist/scene/parse.js +179 -0
  317. package/dist/scene/particles-factory.d.ts +33 -0
  318. package/dist/scene/particles-factory.d.ts.map +1 -0
  319. package/dist/scene/particles-factory.js +282 -0
  320. package/dist/scene/scene-apply.d.ts +109 -0
  321. package/dist/scene/scene-apply.d.ts.map +1 -0
  322. package/dist/scene/scene-apply.js +326 -0
  323. package/dist/scene/scene-diff-schema.d.ts +285 -0
  324. package/dist/scene/scene-diff-schema.d.ts.map +1 -0
  325. package/dist/scene/scene-diff-schema.js +92 -0
  326. package/dist/scene/scene-diff-types.d.ts +40 -0
  327. package/dist/scene/scene-diff-types.d.ts.map +1 -0
  328. package/dist/scene/scene-diff-types.js +14 -0
  329. package/dist/scene/scene-loader.d.ts +177 -0
  330. package/dist/scene/scene-loader.d.ts.map +1 -0
  331. package/dist/scene/scene-loader.js +1213 -0
  332. package/dist/scene/scene-query.d.ts +11 -0
  333. package/dist/scene/scene-query.d.ts.map +1 -0
  334. package/dist/scene/scene-query.js +63 -0
  335. package/dist/scene/scene-types.d.ts +10 -0
  336. package/dist/scene/scene-types.d.ts.map +1 -0
  337. package/dist/scene/scene-types.js +8 -0
  338. package/dist/scene/scene-version.d.ts +26 -0
  339. package/dist/scene/scene-version.d.ts.map +1 -0
  340. package/dist/scene/scene-version.js +34 -0
  341. package/dist/scene/schema/animation.d.ts +8 -0
  342. package/dist/scene/schema/animation.d.ts.map +1 -0
  343. package/dist/scene/schema/animation.js +42 -0
  344. package/dist/scene/schema/audio.d.ts +13 -0
  345. package/dist/scene/schema/audio.d.ts.map +1 -0
  346. package/dist/scene/schema/audio.js +22 -0
  347. package/dist/scene/schema/camera.d.ts +28 -0
  348. package/dist/scene/schema/camera.d.ts.map +1 -0
  349. package/dist/scene/schema/camera.js +17 -0
  350. package/dist/scene/schema/collider.d.ts +40 -0
  351. package/dist/scene/schema/collider.d.ts.map +1 -0
  352. package/dist/scene/schema/collider.js +55 -0
  353. package/dist/scene/schema/entity-ref.d.ts +31 -0
  354. package/dist/scene/schema/entity-ref.d.ts.map +1 -0
  355. package/dist/scene/schema/entity-ref.js +61 -0
  356. package/dist/scene/schema/entity.d.ts +1036 -0
  357. package/dist/scene/schema/entity.d.ts.map +1 -0
  358. package/dist/scene/schema/entity.js +153 -0
  359. package/dist/scene/schema/environment.d.ts +425 -0
  360. package/dist/scene/schema/environment.d.ts.map +1 -0
  361. package/dist/scene/schema/environment.js +357 -0
  362. package/dist/scene/schema/index.d.ts +39 -0
  363. package/dist/scene/schema/index.d.ts.map +1 -0
  364. package/dist/scene/schema/index.js +20 -0
  365. package/dist/scene/schema/instances.d.ts +14 -0
  366. package/dist/scene/schema/instances.d.ts.map +1 -0
  367. package/dist/scene/schema/instances.js +28 -0
  368. package/dist/scene/schema/joint.d.ts +23 -0
  369. package/dist/scene/schema/joint.d.ts.map +1 -0
  370. package/dist/scene/schema/joint.js +23 -0
  371. package/dist/scene/schema/light.d.ts +38 -0
  372. package/dist/scene/schema/light.d.ts.map +1 -0
  373. package/dist/scene/schema/light.js +26 -0
  374. package/dist/scene/schema/material.d.ts +199 -0
  375. package/dist/scene/schema/material.d.ts.map +1 -0
  376. package/dist/scene/schema/material.js +99 -0
  377. package/dist/scene/schema/mesh.d.ts +48 -0
  378. package/dist/scene/schema/mesh.d.ts.map +1 -0
  379. package/dist/scene/schema/mesh.js +82 -0
  380. package/dist/scene/schema/particles.d.ts +2178 -0
  381. package/dist/scene/schema/particles.d.ts.map +1 -0
  382. package/dist/scene/schema/particles.js +321 -0
  383. package/dist/scene/schema/physics.d.ts +56 -0
  384. package/dist/scene/schema/physics.d.ts.map +1 -0
  385. package/dist/scene/schema/physics.js +37 -0
  386. package/dist/scene/schema/scene-file.d.ts +304 -0
  387. package/dist/scene/schema/scene-file.d.ts.map +1 -0
  388. package/dist/scene/schema/scene-file.js +262 -0
  389. package/dist/scene/schema/shadow.d.ts +28 -0
  390. package/dist/scene/schema/shadow.d.ts.map +1 -0
  391. package/dist/scene/schema/shadow.js +20 -0
  392. package/dist/scene/schema/spline.d.ts +25 -0
  393. package/dist/scene/schema/spline.d.ts.map +1 -0
  394. package/dist/scene/schema/spline.js +15 -0
  395. package/dist/scene/schema/tuples.d.ts +12 -0
  396. package/dist/scene/schema/tuples.d.ts.map +1 -0
  397. package/dist/scene/schema/tuples.js +14 -0
  398. package/dist/scene/schema/ui.d.ts +880 -0
  399. package/dist/scene/schema/ui.d.ts.map +1 -0
  400. package/dist/scene/schema/ui.js +506 -0
  401. package/dist/scene/user-data.d.ts +171 -0
  402. package/dist/scene/user-data.d.ts.map +1 -0
  403. package/dist/scene/user-data.js +137 -0
  404. package/dist/setup/setup-audio.d.ts +20 -0
  405. package/dist/setup/setup-audio.d.ts.map +1 -0
  406. package/dist/setup/setup-audio.js +41 -0
  407. package/dist/setup/setup-particles.d.ts +17 -0
  408. package/dist/setup/setup-particles.d.ts.map +1 -0
  409. package/dist/setup/setup-particles.js +16 -0
  410. package/dist/setup/setup-physics.d.ts +25 -0
  411. package/dist/setup/setup-physics.d.ts.map +1 -0
  412. package/dist/setup/setup-physics.js +51 -0
  413. package/dist/setup/setup-renderer.d.ts +69 -0
  414. package/dist/setup/setup-renderer.d.ts.map +1 -0
  415. package/dist/setup/setup-renderer.js +363 -0
  416. package/dist/tools/define-tool.d.ts +105 -0
  417. package/dist/tools/define-tool.d.ts.map +1 -0
  418. package/dist/tools/define-tool.js +82 -0
  419. package/dist/world2d/authoring-2d.d.ts +76 -0
  420. package/dist/world2d/authoring-2d.d.ts.map +1 -0
  421. package/dist/world2d/authoring-2d.js +176 -0
  422. package/dist/world2d/capture-to-scene2d.d.ts +5 -0
  423. package/dist/world2d/capture-to-scene2d.d.ts.map +1 -0
  424. package/dist/world2d/capture-to-scene2d.js +49 -0
  425. package/dist/world2d/collision-2d.d.ts +52 -0
  426. package/dist/world2d/collision-2d.d.ts.map +1 -0
  427. package/dist/world2d/collision-2d.js +70 -0
  428. package/dist/world2d/components-2d.d.ts +47 -0
  429. package/dist/world2d/components-2d.d.ts.map +1 -0
  430. package/dist/world2d/components-2d.js +77 -0
  431. package/dist/world2d/index.d.ts +34 -0
  432. package/dist/world2d/index.d.ts.map +1 -0
  433. package/dist/world2d/index.js +32 -0
  434. package/dist/world2d/ingest-iframe-2d.d.ts +82 -0
  435. package/dist/world2d/ingest-iframe-2d.d.ts.map +1 -0
  436. package/dist/world2d/ingest-iframe-2d.js +166 -0
  437. package/dist/world2d/ingest2d.d.ts +97 -0
  438. package/dist/world2d/ingest2d.d.ts.map +1 -0
  439. package/dist/world2d/ingest2d.js +40 -0
  440. package/dist/world2d/physics2d-registry.d.ts +24 -0
  441. package/dist/world2d/physics2d-registry.d.ts.map +1 -0
  442. package/dist/world2d/physics2d-registry.js +38 -0
  443. package/dist/world2d/pixi-game-adapter.d.ts +107 -0
  444. package/dist/world2d/pixi-game-adapter.d.ts.map +1 -0
  445. package/dist/world2d/pixi-game-adapter.js +211 -0
  446. package/dist/world2d/pixi-surface.d.ts +39 -0
  447. package/dist/world2d/pixi-surface.d.ts.map +1 -0
  448. package/dist/world2d/pixi-surface.js +47 -0
  449. package/dist/world2d/scene-capture-2d.d.ts +43 -0
  450. package/dist/world2d/scene-capture-2d.d.ts.map +1 -0
  451. package/dist/world2d/scene-capture-2d.js +92 -0
  452. package/dist/world2d/scene2d-loader.d.ts +27 -0
  453. package/dist/world2d/scene2d-loader.d.ts.map +1 -0
  454. package/dist/world2d/scene2d-loader.js +274 -0
  455. package/dist/world2d/schema/entity2d.d.ts +102 -0
  456. package/dist/world2d/schema/entity2d.d.ts.map +1 -0
  457. package/dist/world2d/schema/entity2d.js +119 -0
  458. package/dist/world2d/schema/physics2d.d.ts +46 -0
  459. package/dist/world2d/schema/physics2d.d.ts.map +1 -0
  460. package/dist/world2d/schema/physics2d.js +45 -0
  461. package/dist/world2d/schema/sprite.d.ts +42 -0
  462. package/dist/world2d/schema/sprite.d.ts.map +1 -0
  463. package/dist/world2d/schema/sprite.js +63 -0
  464. package/dist/world2d/schema/tilemap.d.ts +15 -0
  465. package/dist/world2d/schema/tilemap.d.ts.map +1 -0
  466. package/dist/world2d/schema/tilemap.js +19 -0
  467. package/dist/world2d/schema/tuples2d.d.ts +20 -0
  468. package/dist/world2d/schema/tuples2d.d.ts.map +1 -0
  469. package/dist/world2d/schema/tuples2d.js +19 -0
  470. package/dist/world2d/system-adapters-2d.d.ts +16 -0
  471. package/dist/world2d/system-adapters-2d.d.ts.map +1 -0
  472. package/dist/world2d/system-adapters-2d.js +37 -0
  473. package/dist/world2d/transform-writer-2d.d.ts +16 -0
  474. package/dist/world2d/transform-writer-2d.d.ts.map +1 -0
  475. package/dist/world2d/transform-writer-2d.js +22 -0
  476. package/dist/world2d/types.d.ts +53 -0
  477. package/dist/world2d/types.d.ts.map +1 -0
  478. package/dist/world2d/types.js +1 -0
  479. package/package.json +18 -4
  480. package/src/adapter/authoring.ts +10 -0
  481. package/src/adapter/first-party-systems.ts +23 -34
  482. package/src/adapter/index.ts +1 -3
  483. package/src/adapter/system-adapter.ts +15 -22
  484. package/src/adapter/vgai-scene-game-adapter.ts +5 -14
  485. package/src/animation/anim-graph-types.ts +12 -43
  486. package/src/animation/animation-clock.ts +479 -0
  487. package/src/animation/camera-ownership.ts +467 -0
  488. package/src/animation/cinematic-cues.ts +451 -0
  489. package/src/animation/clip-map.ts +41 -0
  490. package/src/animation/gsap-registration.ts +184 -0
  491. package/src/animation/theatre-clock-binding.ts +111 -0
  492. package/src/animation/theatre-director.ts +347 -0
  493. package/src/animation/theatre-object-binding.ts +661 -0
  494. package/src/animation/xstate-animation-binding.ts +398 -0
  495. package/src/animation/xstate-animation-meta.ts +282 -0
  496. package/src/audio/index.ts +39 -7
  497. package/src/audio/tone-clock-binding.ts +98 -0
  498. package/src/audio/tone-context.ts +129 -0
  499. package/src/audio/tone-offline-render.ts +167 -0
  500. package/src/audio/wav-encode.ts +119 -0
  501. package/src/core/game-loop.ts +17 -0
  502. package/src/core/types.ts +13 -0
  503. package/src/data/data-asset.ts +167 -0
  504. package/src/data/data-check-core.ts +242 -0
  505. package/src/data/data-ref.ts +145 -0
  506. package/src/data/vite-plugin-data.ts +290 -0
  507. package/src/index.ts +48 -0
  508. package/src/input/input-manager.ts +1206 -32
  509. package/src/input/input-types.ts +155 -3
  510. package/src/input/prompt-labels.ts +122 -0
  511. package/src/input/rebind-controller.ts +105 -0
  512. package/src/input/schema.ts +206 -52
  513. package/src/react/use-data.ts +114 -0
  514. package/src/react/use-selection.tsx +135 -0
  515. package/src/runtime/create-runtime.ts +30 -9
  516. package/src/runtime/render-audio-control.ts +168 -0
  517. package/src/runtime/render-control.ts +522 -0
  518. package/src/runtime/render-seed.ts +79 -0
  519. package/src/runtime/types.ts +0 -5
  520. package/src/scene/asset-loaders.ts +10 -36
  521. package/src/scene/asset-paths.ts +0 -2
  522. package/src/scene/asset-ref-check.ts +248 -0
  523. package/src/scene/parse.ts +133 -0
  524. package/src/scene/scene-loader.ts +81 -96
  525. package/src/scene/schema/animation.ts +30 -79
  526. package/src/scene/schema/entity.ts +20 -0
  527. package/src/scene/schema/index.ts +2 -12
  528. package/src/scene/user-data.ts +8 -9
  529. package/src/setup/setup-renderer.ts +9 -2
  530. package/src/tools/define-tool.ts +152 -0
  531. package/src/animation/anim-graph.ts +0 -406
  532. package/src/animation/anim-system.ts +0 -28
  533. package/src/animation/property-track.ts +0 -178
  534. package/src/animation/schema.ts +0 -204
  535. package/src/audio/ambient.ts +0 -300
  536. package/src/audio/impacts.ts +0 -212
  537. package/src/audio/movement.ts +0 -140
  538. package/src/audio/musical.ts +0 -200
  539. package/src/audio/ui-sounds.ts +0 -171
  540. package/src/audio/vehicle.ts +0 -235
  541. package/src/audio/weapons.ts +0 -152
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Render-control runtime seam (I2, `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`
3
+ * §15 I2). This is the harness a deterministic-capture host (Playwright/CDP,
4
+ * I0/I3/I4) drives: exact-time seeks against the canonical
5
+ * `AnimationClock` (`animation/animation-clock.ts`), and single
6
+ * `preRender`+`render` phase passes across every world on a `Game`
7
+ * (`runtime/game.ts`) — WITHOUT ever advancing gameplay fixed-step substeps
8
+ * (`input`/`prePhysics`/`physics`/`postPhysics`/`gameLogic`/`animation` are
9
+ * never invoked by this seam; `--simulate` (I5) is a different, later, path
10
+ * that deliberately drives `game.runFrame(fixedDt)` instead).
11
+ *
12
+ * This module does NOT reuse `PlayState.step()` (`Game.play.step()`) — that
13
+ * surface only advances the currently-FROZEN (paused) set of worlds and is a
14
+ * whole-call no-op while unpaused (see its doc comment in `runtime/game.ts`);
15
+ * the spec review explicitly flagged it as the wrong seam. `renderOnce`
16
+ * instead walks `game.worlds` directly and calls each world's own
17
+ * `WorldFrameHooks.runPhase` for exactly two phases.
18
+ *
19
+ * Also does NOT install anything by default — a caller must explicitly call
20
+ * {@link installRenderControlHarness}, and even then it only actually
21
+ * publishes `window.__vgaiRender` when the page's URL opts in via
22
+ * `?vgai-render=1` (AC 4: unavailable/protected in normal production
23
+ * gameplay unless explicitly enabled). See `render-seed.ts` for the
24
+ * matching `Math.random` determinism hardening, which must run BEFORE this
25
+ * module (or any other game module) is even imported.
26
+ *
27
+ * I5 (`--simulate` render, §15 I5) is implemented HERE, alongside `renderOnce`:
28
+ * {@link VgaiRenderHarness.simulateSubsteps} drives `game.runFrame(fixedDt)` a
29
+ * fixed integer number of times — the FULL fixed-step gameplay frame (every
30
+ * phase in `PHASE_ORDER`, including `physics`/`gameLogic`/`animation`), unlike
31
+ * `renderOnce`'s deliberately gameplay-free `preRender`+`render`-only pass.
32
+ * A caller that never invokes `simulateSubsteps` (the default, sequence-
33
+ * controlled render — I4) gets byte-identical behavior to before this method
34
+ * existed: `renderOnce`/`seek`/`seekFrame`/`advanceFrame` are untouched by
35
+ * this addition.
36
+ */
37
+
38
+ import { SystemPhase } from '../core/types';
39
+ import type { Game, GameInternal, WorldFrameHooks } from './game';
40
+ import { RENDER_MODE_QUERY_PARAM } from './render-seed';
41
+
42
+ /** Per-subsystem readiness verdict (I2 AC: "Runtime reports asset, shader,
43
+ * font, Theatre, Tone, and scene readiness"). `not-applicable` is the
44
+ * correct answer for any subsystem genuinely absent from a given fixture
45
+ * (spec note: "If a subsystem isn't present in the fixture, report it as
46
+ * not-applicable rather than failing") — never coerced to `ready`. */
47
+ export type ReadinessStatus = 'ready' | 'not-applicable' | 'error';
48
+
49
+ export interface ReadinessEntry {
50
+ readonly status: ReadinessStatus;
51
+ readonly detail?: string;
52
+ }
53
+
54
+ /** The full readiness report `ready()` resolves. One entry per subsystem
55
+ * named in the I2 AC, always present (never a sparse/optional object) so a
56
+ * caller can read every key unconditionally. */
57
+ export interface ReadinessReport {
58
+ readonly assets: ReadinessEntry;
59
+ readonly shaders: ReadinessEntry;
60
+ readonly fonts: ReadinessEntry;
61
+ readonly theatre: ReadinessEntry;
62
+ readonly tone: ReadinessEntry;
63
+ readonly scene: ReadinessEntry;
64
+ }
65
+
66
+ /**
67
+ * Caller-supplied per-subsystem readiness checks. Each hook is optional:
68
+ * absence means that subsystem genuinely does not exist in this fixture/game
69
+ * (reported `not-applicable`), NOT that it's assumed ready. A hook that
70
+ * resolves is `ready`; one that throws/rejects is `error` with the message
71
+ * captured (never silently swallowed, never escalated to fail the whole
72
+ * `ready()` call — one subsystem's failure must not hide the others' status).
73
+ * `fonts` has no hook slot: it is always checked directly against
74
+ * `document.fonts.ready` (universally meaningful in a browser render page),
75
+ * matching the AC's explicit `document.fonts.ready` callout.
76
+ */
77
+ export interface RenderReadinessHooks {
78
+ assets?(): Promise<void> | void;
79
+ shaders?(): Promise<void> | void;
80
+ theatre?(): Promise<void> | void;
81
+ tone?(): Promise<void> | void;
82
+ scene?(): Promise<void> | void;
83
+ }
84
+
85
+ /** The minimal clock surface this seam drives — `AnimationClock`'s `seek`/
86
+ * `seekFrame` (`animation/animation-clock.ts`). Typed narrowly (not
87
+ * imported as a value) so this module never depends on the clock's full
88
+ * surface, just the two methods the render seam actually calls. */
89
+ export interface SeekableClock {
90
+ seek(t: number): unknown;
91
+ seekFrame(n: number, fps: number): unknown;
92
+ }
93
+
94
+ /**
95
+ * I8 render-integration seam: a per-frame, fixed-`dt` advance hook — exactly
96
+ * the engine's `SystemFn` shape (`core/types.ts`) — for a
97
+ * cinematic-participating system whose live-gameplay driver `renderOnce()`
98
+ * deliberately bypasses. The motivating case is `bindXStateAnimation`'s
99
+ * `tick` (`animation/xstate-animation-binding.ts`, E2): in live play it
100
+ * rides the fixed-step `'animation'` phase
101
+ * (`ctx.systems.add(SystemPhase.ANIMATION, binding.tick)`), but
102
+ * `renderOnce()` (I2) runs ONLY `preRender`+`render` — the `'animation'`
103
+ * phase, along with every other gameplay phase, is never touched by design
104
+ * (see this module's top doc comment). Without a distinct advance hook, an
105
+ * `AnimationMixer` driven this way would sit frozen for the entire render:
106
+ * nothing would ever call `mixer.update(dt)`. `advanceFrame` (below) is that
107
+ * hook — a small, explicit registry of `FrameAdvancer`s a render-mode page
108
+ * opts into via {@link RenderControlHarnessOptions.frameAdvancers}, invoked
109
+ * in registration order.
110
+ */
111
+ export type FrameAdvancer = (dt: number) => void;
112
+
113
+ /** The `window.__vgaiRender` surface (I2 AC, extended by I8's `advanceFrame`).
114
+ * Every method here is synchronous except the two that genuinely need to
115
+ * wait on the browser (composited render completion, async readiness
116
+ * probes). */
117
+ export interface VgaiRenderHarness {
118
+ /** Evaluate Theatre/registered-GSAP/cinematic-participating evaluators at
119
+ * exact time `t` (seconds) via `clock.seek(t)` — never advances gameplay
120
+ * substeps. Synchronous: the clock's subscribed evaluators run inline,
121
+ * before this call returns. */
122
+ seek(t: number): void;
123
+ /** Exact-frame variant — `clock.seekFrame(n, fps)`, i.e. `start + n/fps`,
124
+ * bit-exact and drift-free across repeated calls. Same no-substep
125
+ * semantics as {@link seek}. */
126
+ seekFrame(n: number, fps: number): void;
127
+ /**
128
+ * I8 render-integration seam: advance every registered
129
+ * {@link FrameAdvancer} (e.g. an XState/`AnimationMixer` binding's `tick`)
130
+ * by exactly `dt` seconds, in registration order. A render-mode capture
131
+ * loop calls this ONCE per OUTPUT frame, with `dt = 1 / fps`, BEFORE
132
+ * `seekFrame`/`renderOnce` for that frame — see
133
+ * `packages/vgai-sdk/src/render/render-cinematic.ts`'s `captureFrames`, which
134
+ * drives exactly this sequence. `advanceFrame` is a genuinely
135
+ * FORWARD-ONLY, INCREMENTAL tick (it has no notion of "time" to seek
136
+ * to — it only knows "advance by `dt` more") — unlike {@link seek}/
137
+ * {@link seekFrame}, which are absolute and idempotent, calling
138
+ * `advanceFrame` twice never undoes or re-derives a prior call, it always
139
+ * accumulates. This composes correctly with I4's default sequence-
140
+ * controlled render (and I8's reference cinematic) specifically BECAUSE
141
+ * that capture loop only ever walks output frames monotonically forward
142
+ * (`n = 0, 1, 2, ...`); it is NOT safe to call from a scrubber/editor
143
+ * preview that seeks backward or re-visits a frame — a caller that needs
144
+ * that (a future `--simulate`/preview seam) must not reuse this hook as-is.
145
+ * A no-op when no advancers are registered (the default), so this method
146
+ * is always present and always safe to call even for a fixture with
147
+ * nothing to advance (e.g. the I0 `render-cinematic` fixture).
148
+ */
149
+ advanceFrame(dt: number): void;
150
+ /** Runs exactly one `preRender`+`render` phase pass across every
151
+ * host-driven world on the `Game` (z-order is a DOM/canvas-stacking
152
+ * concern already handled by `create-runtime.ts`'s surface stack — this
153
+ * call does not need to reorder anything to composite correctly), then
154
+ * resolves after a double-`requestAnimationFrame` composition fence. */
155
+ renderOnce(): Promise<void>;
156
+ /** Resolves once every declared subsystem has reported in (see
157
+ * {@link ReadinessReport}). */
158
+ ready(): Promise<ReadinessReport>;
159
+ /**
160
+ * I5 `--simulate` seam: advance the FULL fixed-step gameplay frame
161
+ * (`game.runFrame(fixedDt)` — every phase in `PHASE_ORDER`: input,
162
+ * prePhysics, physics, postPhysics, gameLogic, animation, preRender,
163
+ * render) exactly `steps` times, synchronously, in a tight loop. This is
164
+ * what makes physics/gameplay/AI/particles/participating-audio evolve
165
+ * BETWEEN captured output frames under `--simulate` — every real gameplay
166
+ * phase runs, unlike {@link renderOnce} (which runs ONLY `preRender`+
167
+ * `render`, by design, for the I4 sequence-controlled default) or
168
+ * {@link advanceFrame} (which ticks only registered {@link FrameAdvancer}s,
169
+ * never a gameplay phase).
170
+ *
171
+ * `fixedDt` is fixed for the lifetime of this harness (see
172
+ * {@link RenderControlHarnessOptions.simulateFixedDt}, default `1/60` —
173
+ * the same fixed timestep every real host's `createGameLoop` config
174
+ * uses) — callers choose HOW MANY substeps to run per captured frame
175
+ * (`steps`), not the substep's own `dt`, matching the I5 AC's "a fixed
176
+ * integer number of times per output frame" wording exactly.
177
+ *
178
+ * A capture loop that wants BOTH a warmup period (I5 AC: "simulation
179
+ * state can warm up before the capture range") and per-frame substeps
180
+ * calls this twice: once with the warmup step count before frame 0, then
181
+ * once per captured frame with the per-frame step count — there is no
182
+ * separate "warmup" method, because warmup is just simulateSubsteps called
183
+ * before the capture loop starts (see `render-cinematic.ts`'s
184
+ * `captureFrames`, which drives exactly this sequence for `--simulate`
185
+ * requests).
186
+ */
187
+ simulateSubsteps(steps: number): void;
188
+ /**
189
+ * I5 AC 5 ("the render report names every subsystem excluded from
190
+ * deterministic participation"): every subsystem NOT participating in
191
+ * deterministic capture, computed fresh on every call from two sources —
192
+ * (1) `RenderControlHarnessOptions.excludedFromDeterminism`, a static,
193
+ * page-declared list (e.g. "live Colyseus networking", "non-seeded ambient
194
+ * audio") this fixture/game names about itself, and (2) any world this
195
+ * seam itself could not frame-gate (a `drivesOwnLoop` world, or a
196
+ * host-driven world with no `WorldFrameHooks` — the SAME two conditions
197
+ * {@link renderOnce}'s `renderableWorlds` skips, described here as policy
198
+ * rather than merely warned about once to the console). Declared entries
199
+ * come first, in declaration order; world-exclusion entries follow, in
200
+ * `game.worlds` declaration order.
201
+ */
202
+ excludedFromDeterminism(): string[];
203
+ /**
204
+ * I7 fold-in (I5 nit): the ACTUAL fixed substep `dt` (seconds) this
205
+ * harness passes to every `game.runFrame(fixedDt)` call inside
206
+ * {@link simulateSubsteps} — i.e. `RenderControlHarnessOptions.simulateFixedDt`,
207
+ * resolved with its own `1/60` default already applied. Exists so the
208
+ * render pipeline (`render-cinematic.ts`'s `RenderManifestSimulate
209
+ * .fixedTimestep`) can report the REAL value a fixture is using instead of
210
+ * assuming every fixture matches the harness's own default — a fixture
211
+ * that configures a different `simulateFixedDt` (a different Rapier/
212
+ * physics substep) now shows up correctly in the render manifest rather
213
+ * than a silently wrong hardcoded `1/60`.
214
+ */
215
+ simulateFixedDt(): number;
216
+ }
217
+
218
+ export interface RenderControlHarnessOptions {
219
+ /**
220
+ * `GameInternal` (not just the game-facing `Game`) — this harness is
221
+ * itself a host (the render/capture driver), and I5's
222
+ * {@link VgaiRenderHarness.simulateSubsteps} needs the host-only
223
+ * `runFrame` surface (`runtime/game.ts`'s `GameInternal.runFrame` doc
224
+ * comment: "the host loop ... and `GameSession.step()` are the only
225
+ * callers"). Every real call site already holds a `GameInternal` (the
226
+ * direct return of `createGame(...)`), so this is not a new construction
227
+ * requirement, just a narrower declared type than before I5.
228
+ */
229
+ readonly game: GameInternal;
230
+ readonly clock: SeekableClock;
231
+ readonly readiness?: RenderReadinessHooks;
232
+ /** Where to publish the harness. Defaults to the real `window` — override
233
+ * in a unit test to avoid touching the global object. */
234
+ readonly target?: Record<string, unknown>;
235
+ /** Where to read `?vgai-render=1` from. Defaults to `window.location`. */
236
+ readonly location?: { readonly search: string };
237
+ /** I8 render-integration seam — see {@link VgaiRenderHarness.advanceFrame}.
238
+ * Zero or more `FrameAdvancer`s invoked, in array order, on every
239
+ * `harness.advanceFrame(dt)` call. Default `[]` (no-op), which is exactly
240
+ * what a fixture with nothing gameplay-phase-driven (e.g. I0's fixture)
241
+ * needs — `advanceFrame` is still present on the harness, it just has
242
+ * nothing to do. */
243
+ readonly frameAdvancers?: readonly FrameAdvancer[];
244
+ /**
245
+ * I5 `--simulate` seam: the fixed substep `dt` (seconds)
246
+ * {@link VgaiRenderHarness.simulateSubsteps} passes to every
247
+ * `game.runFrame(fixedDt)` call. Default `1/60` — the same fixed timestep
248
+ * every real host's `createGameLoop` config uses (`create-runtime.ts`), so
249
+ * a `--simulate` fixture's Rapier world (whose own `integrationParameters.dt`
250
+ * defaults to `1/60`) stays in lockstep with the gameplay substep unless a
251
+ * fixture deliberately configures both to a different, still-matching,
252
+ * value.
253
+ */
254
+ readonly simulateFixedDt?: number;
255
+ /**
256
+ * I5 AC 5 — see {@link VgaiRenderHarness.excludedFromDeterminism}. A
257
+ * static, page-declared list of subsystems this fixture/game has that do
258
+ * NOT participate in deterministic capture (e.g. live networking,
259
+ * non-seeded ambient audio) — named here as an explicit, reviewable
260
+ * policy rather than silently dropped. Default `[]` (nothing to declare —
261
+ * correct for a fixture with no such subsystem).
262
+ */
263
+ readonly excludedFromDeterminism?: readonly string[];
264
+ }
265
+
266
+ /** Shared by {@link installRenderControlHarness} and any caller that wants
267
+ * to check the opt-in flag before doing render-mode-only setup work (e.g.
268
+ * `render-seed.ts`'s own gate uses the same query param name). */
269
+ export function isRenderModeRequested(location: { readonly search: string }): boolean {
270
+ return new URLSearchParams(location.search).get(RENDER_MODE_QUERY_PARAM) === '1';
271
+ }
272
+
273
+ const RENDER_ONLY_PHASES = [SystemPhase.PRE_RENDER, SystemPhase.RENDER] as const;
274
+
275
+ /**
276
+ * Run exactly one `preRender`+`render` phase pass across every host-driven
277
+ * (`!drivesOwnLoop`) world on `game`, then await the GPU/DOM composition
278
+ * fence. This is the ENTIRE frame this call drives — no `input`,
279
+ * `prePhysics`, `physics`, `postPhysics`, `gameLogic`, or `animation` phase
280
+ * is ever touched, which is what makes this safe to call from a paused-or-
281
+ * stopped clock without silently ticking gameplay. Phases are run as global
282
+ * barriers across worlds (mirroring `GameInternal.runFrame`'s own phase-then-
283
+ * world nesting in `runtime/game.ts`): every world's `preRender` runs before
284
+ * any world's `render`, in `game.worlds` declaration order.
285
+ *
286
+ * Ordering within a phase mirrors `GameInternal.runFrame` EXACTLY (see its
287
+ * doc comment in `runtime/game.ts`): the game-scoped `SystemRunner`
288
+ * (`game.systems`) runs FIRST, before any world's frame hooks. `game.systems`
289
+ * is empty for every game today (nothing registers against it yet), so this
290
+ * is a no-op in practice — but a later slice that registers a Game-scoped
291
+ * `preRender`/`render` system (e.g. a cinematic camera crossfade that must
292
+ * paint once per captured frame) would otherwise be silently MISSED by
293
+ * capture while running fine in live playback, since live playback goes
294
+ * through `runFrame`. Running it here keeps the seam a faithful subset of
295
+ * `runFrame`'s phase pass, not a divergent one.
296
+ *
297
+ * A `drivesOwnLoop` world (self-driven, raw-rAF) has no phase hooks this
298
+ * seam can drive — it is skipped with a loud, once-per-call warning rather
299
+ * than silently omitted, mirroring this file's "fail loudly, never a silent
300
+ * no-op" convention. A host-driven world with no `frame` (an opaque/foreign
301
+ * mount) is skipped the same way — there is no phase hook to call. Both
302
+ * checks happen ONCE, up front (see {@link renderableWorlds}), not per
303
+ * phase — a world unrenderable in `preRender` is unrenderable in `render`
304
+ * too, so warning twice would just be noise.
305
+ */
306
+ async function renderOnce(game: Game): Promise<void> {
307
+ const worlds = renderableWorlds(game);
308
+ for (const phase of RENDER_ONLY_PHASES) {
309
+ // Game-scoped systems first, then per-world frame hooks — the SAME order
310
+ // GameInternal.runFrame uses (runtime/game.ts). See doc comment above.
311
+ game.systems.runPhase(phase, 0);
312
+ for (const world of worlds) {
313
+ world.frame.runPhase(phase, 0);
314
+ }
315
+ }
316
+ await compositionFence();
317
+ }
318
+
319
+ interface RenderableWorld {
320
+ readonly id: string;
321
+ readonly frame: WorldFrameHooks;
322
+ }
323
+
324
+ /** Filter `game.worlds` down to the ones {@link renderOnce} can actually
325
+ * drive (host-driven, with real `WorldFrameHooks`) — see that function's
326
+ * doc comment for why an excluded world is warned about loudly, not
327
+ * silently dropped. */
328
+ function renderableWorlds(game: Game): RenderableWorld[] {
329
+ const result: RenderableWorld[] = [];
330
+ for (const world of game.worlds) {
331
+ if (world.mounted.drivesOwnLoop) {
332
+ warnUnrenderable(
333
+ world.id,
334
+ 'drives its own loop — renderOnce() cannot frame-gate it ' +
335
+ '(docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md §15 I5 names this policy)',
336
+ );
337
+ continue;
338
+ }
339
+ if (!world.frame) {
340
+ warnUnrenderable(
341
+ world.id,
342
+ `(kind: ${world.kind}) has no phase hooks — renderOnce() cannot drive it (opaque/foreign ` +
343
+ 'mount with no frame-gated entry point)',
344
+ );
345
+ continue;
346
+ }
347
+ result.push({ id: world.id, frame: world.frame });
348
+ }
349
+ return result;
350
+ }
351
+
352
+ function warnUnrenderable(worldLabel: string, reason: string): void {
353
+ // biome-ignore lint/suspicious/noConsole: structured, greppable — mirrors runtime/game.ts's own direct console.warn idiom for "cannot gate this world" capability shortfalls.
354
+ console.warn(`[render-control] world "${worldLabel}" ${reason}.`);
355
+ }
356
+
357
+ /**
358
+ * I5 AC 5 policy text for the two conditions {@link renderableWorlds} skips —
359
+ * shared so {@link VgaiRenderHarness.excludedFromDeterminism} names the SAME
360
+ * worlds `renderOnce()` warns about, in the SAME words, rather than
361
+ * maintaining a second, driftable description of the same two checks.
362
+ */
363
+ function computeWorldExclusionReasons(game: Game): string[] {
364
+ const reasons: string[] = [];
365
+ for (const world of game.worlds) {
366
+ if (world.mounted.drivesOwnLoop) {
367
+ reasons.push(
368
+ `world "${world.id}" drives its own loop — cannot be frame-gated for deterministic ` +
369
+ 'capture (docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md §15 I5 names this policy: ' +
370
+ 'FAIL LOUDLY or be excluded only by an explicit declared policy).',
371
+ );
372
+ continue;
373
+ }
374
+ if (!world.frame) {
375
+ reasons.push(
376
+ `world "${world.id}" (kind: ${world.kind}) has no phase hooks — an opaque/foreign mount ` +
377
+ 'with no frame-gated entry point cannot participate in deterministic capture.',
378
+ );
379
+ }
380
+ }
381
+ return reasons;
382
+ }
383
+
384
+ function nextAnimationFrame(): Promise<void> {
385
+ return new Promise((resolve) => {
386
+ requestAnimationFrame(() => resolve());
387
+ });
388
+ }
389
+
390
+ /**
391
+ * GPU/DOM composition fence (I2 AC: "waits for GPU/DOM composition
392
+ * (double-rAF fence ... ) rather than an arbitrary sleep"). Two nested
393
+ * `requestAnimationFrame` callbacks: the first fires once the browser has
394
+ * scheduled a new frame after our `render()` calls above; the second fires
395
+ * once THAT frame has itself been produced and composited — by the time the
396
+ * second callback runs, the compositor has committed the frame our render
397
+ * calls painted, so a screenshot taken immediately after this resolves
398
+ * reflects the seeked state, not a stale one. (The CDP screenshot
399
+ * compositor-commit wait itself is the capture host's job — I0/I3 — this
400
+ * fence is the runtime-side half.)
401
+ */
402
+ async function compositionFence(): Promise<void> {
403
+ await nextAnimationFrame();
404
+ await nextAnimationFrame();
405
+ }
406
+
407
+ async function resolveHook(
408
+ hook: (() => Promise<void> | void) | undefined,
409
+ ): Promise<ReadinessEntry> {
410
+ if (!hook) return { status: 'not-applicable' };
411
+ try {
412
+ await hook();
413
+ return { status: 'ready' };
414
+ } catch (err) {
415
+ return { status: 'error', detail: err instanceof Error ? err.message : String(err) };
416
+ }
417
+ }
418
+
419
+ async function checkFontsReady(): Promise<ReadinessEntry> {
420
+ if (typeof document === 'undefined' || !document.fonts) return { status: 'not-applicable' };
421
+ try {
422
+ await document.fonts.ready;
423
+ return { status: 'ready' };
424
+ } catch (err) {
425
+ return { status: 'error', detail: err instanceof Error ? err.message : String(err) };
426
+ }
427
+ }
428
+
429
+ async function buildReadinessReport(hooks: RenderReadinessHooks): Promise<ReadinessReport> {
430
+ const [assets, shaders, fonts, theatre, tone, scene] = await Promise.all([
431
+ resolveHook(hooks.assets),
432
+ resolveHook(hooks.shaders),
433
+ checkFontsReady(),
434
+ resolveHook(hooks.theatre),
435
+ resolveHook(hooks.tone),
436
+ resolveHook(hooks.scene),
437
+ ]);
438
+ return { assets, shaders, fonts, theatre, tone, scene };
439
+ }
440
+
441
+ /**
442
+ * Build (and, when render mode is actually requested, publish) the
443
+ * `window.__vgaiRender` harness. AC 4 — production protection — lives HERE,
444
+ * not just at the call site: even if a host application calls this
445
+ * unconditionally on every boot, the harness is only ever constructed *and*
446
+ * attached to `target` when `isRenderModeRequested(location)` is true;
447
+ * otherwise this is a no-op that returns `undefined`. A normal production
448
+ * gameplay page therefore never gets `window.__vgaiRender` no matter how
449
+ * this function is wired into its entry point.
450
+ */
451
+ export function installRenderControlHarness(
452
+ opts: RenderControlHarnessOptions,
453
+ ): VgaiRenderHarness | undefined {
454
+ const location = opts.location ?? window.location;
455
+ if (!isRenderModeRequested(location)) return undefined;
456
+
457
+ const { game, clock, readiness = {} } = opts;
458
+ const target = opts.target ?? (window as unknown as Record<string, unknown>);
459
+ const frameAdvancers = opts.frameAdvancers ?? [];
460
+ const simulateFixedDt = opts.simulateFixedDt ?? 1 / 60;
461
+ const declaredExclusions = opts.excludedFromDeterminism ?? [];
462
+
463
+ const harness: VgaiRenderHarness = {
464
+ seek(t: number): void {
465
+ clock.seek(t);
466
+ },
467
+ seekFrame(n: number, fps: number): void {
468
+ clock.seekFrame(n, fps);
469
+ },
470
+ advanceFrame(dt: number): void {
471
+ for (const advancer of frameAdvancers) advancer(dt);
472
+ },
473
+ renderOnce(): Promise<void> {
474
+ return renderOnce(game);
475
+ },
476
+ ready(): Promise<ReadinessReport> {
477
+ return buildReadinessReport(readiness);
478
+ },
479
+ simulateSubsteps(steps: number): void {
480
+ for (let i = 0; i < steps; i++) {
481
+ game.runFrame(simulateFixedDt);
482
+ }
483
+ },
484
+ excludedFromDeterminism(): string[] {
485
+ return [...declaredExclusions, ...computeWorldExclusionReasons(game)];
486
+ },
487
+ simulateFixedDt(): number {
488
+ return simulateFixedDt;
489
+ },
490
+ };
491
+
492
+ target['__vgaiRender'] = harness;
493
+ return harness;
494
+ }
495
+
496
+ /**
497
+ * Defensive assertion for the I2 AC "Pixi worlds are pinned to the WebGL
498
+ * renderer (not WebGPU) in render mode". In THIS engine that invariant
499
+ * already holds unconditionally — `world2d/pixi-surface.ts`'s
500
+ * `createPixiSurface` hardcodes `preference: 'webgl'` on every
501
+ * `Application.init()` call it makes, and `setup/setup-renderer.ts` never
502
+ * constructs a `WebGPURenderer` for threejs worlds either — so there is no
503
+ * live WebGPU code path for a first-party render-mode page to disable.
504
+ * This helper exists for a render-mode installer that mounts a CUSTOM/
505
+ * foreign pixi adapter (`create-runtime.ts`'s `{ module }` pixi path) this
506
+ * engine did not construct itself, to assert the invariant against the
507
+ * live mounted renderer rather than merely trusting it. Duck-typed against
508
+ * pixi.js v8's numeric `RendererType` (`WEBGL = 1`, `WEBGPU = 2`,
509
+ * `CANVAS = 4`) so this file never value-imports `pixi.js` (the same
510
+ * type-only-pixi rule `runtime/game.ts`/`create-runtime.ts` document for
511
+ * themselves).
512
+ */
513
+ export function assertPixiWorldIsWebGL(rendererType: unknown, worldId: string): void {
514
+ const isWebGPU =
515
+ rendererType === 2 || (typeof rendererType === 'string' && /webgpu/i.test(rendererType));
516
+ if (isWebGPU) {
517
+ throw new Error(
518
+ `[render-control] world "${worldId}": Pixi renderer is WebGPU in render mode — ` +
519
+ 'render-control requires WebGL (docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md §15 I2).',
520
+ );
521
+ }
522
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Deterministic `Math.random` seeding for render-control mode (I2 AC,
3
+ * `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md` §15 I2: "`Math.random`
4
+ * is deterministically seeded/stubbed page-wide before any game module
5
+ * executes").
6
+ *
7
+ * Deliberately a ZERO-IMPORT module (no `three`, no other engine file) so
8
+ * its own evaluation is instantaneous — a render-mode entry page loads this
9
+ * as its FIRST `<script type="module">` tag, before the tag that pulls in
10
+ * the actual game/runtime modules. Per the HTML module-script ordering
11
+ * rules, sibling `<script type="module">` tags without `async` execute in
12
+ * document order, and each one's own dependency graph (here, empty) is
13
+ * fully evaluated before the browser moves to the next tag — so calling
14
+ * {@link maybeInstallRenderModeRandom} from this module's importer, in a
15
+ * script tag placed before the game's own entry tag, guarantees every
16
+ * subsequent module's top-level code (and everything it does at runtime)
17
+ * observes the seeded generator, never the platform's real
18
+ * cryptographically-random `Math.random`.
19
+ *
20
+ * This module does not decide WHETHER to seed on its own (importing it has
21
+ * no side effect) — the caller decides, by calling
22
+ * {@link maybeInstallRenderModeRandom} (query-param gated) or
23
+ * {@link installDeterministicRandom} (unconditional) from a tiny bootstrap
24
+ * entry. See `packages/engine/e2e/fixture/render-seed-entry.ts` for the
25
+ * worked bootstrap this module is designed to be loaded from.
26
+ */
27
+
28
+ /**
29
+ * mulberry32 — a small, fast, deterministic 32-bit PRNG. Not cryptographic;
30
+ * this is explicitly a determinism tool (reproducible capture), not a
31
+ * security primitive. Returns a function with the same call signature as
32
+ * `Math.random` (no arguments, `[0, 1)` float).
33
+ */
34
+ export function createMulberry32(seed: number): () => number {
35
+ let state = seed >>> 0;
36
+ return function mulberry32(): number {
37
+ state = (state + 0x6d2b79f5) | 0;
38
+ let t = state;
39
+ t = Math.imul(t ^ (t >>> 15), t | 1);
40
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
41
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Replace the global `Math.random` with a seeded, deterministic generator.
47
+ * Idempotent to call more than once (each call re-seeds from scratch — the
48
+ * last call wins), which matters for HMR-style re-execution the same way
49
+ * `main.ts`'s `registerWorldKind` guard does elsewhere in this runtime.
50
+ */
51
+ export function installDeterministicRandom(seed: number): void {
52
+ Math.random = createMulberry32(seed);
53
+ }
54
+
55
+ /** Query-param name that opts a page into render-control mode (I2 AC 4: the
56
+ * mode must be unavailable/protected in normal production gameplay unless
57
+ * explicitly enabled). Shared with `render-control.ts`'s own production
58
+ * guard so both checks agree on the same flag. */
59
+ export const RENDER_MODE_QUERY_PARAM = 'vgai-render';
60
+ /** Optional query param to pin a specific seed (default below when absent). */
61
+ export const RENDER_SEED_QUERY_PARAM = 'vgai-seed';
62
+ const DEFAULT_RENDER_SEED = 0x9e3779b9; // golden-ratio constant — an arbitrary but fixed default
63
+
64
+ /**
65
+ * Seed `Math.random` iff the page's URL opts into render mode
66
+ * (`?vgai-render=1`), reading an optional `?vgai-seed=<int>` override.
67
+ * Returns whether it seeded, purely for the caller's own diagnostics/log —
68
+ * the bootstrap entry doesn't need to branch on it.
69
+ */
70
+ export function maybeInstallRenderModeRandom(
71
+ location: { search: string } = window.location,
72
+ ): boolean {
73
+ const params = new URLSearchParams(location.search);
74
+ if (params.get(RENDER_MODE_QUERY_PARAM) !== '1') return false;
75
+ const seedParam = params.get(RENDER_SEED_QUERY_PARAM);
76
+ const seed = seedParam !== null && seedParam !== '' ? Number(seedParam) : DEFAULT_RENDER_SEED;
77
+ installDeterministicRandom(Number.isFinite(seed) ? seed : DEFAULT_RENDER_SEED);
78
+ return true;
79
+ }
@@ -2,7 +2,6 @@ import type RAPIER from '@dimforge/rapier3d-compat';
2
2
  import type { EffectComposer } from 'postprocessing';
3
3
  import type * as THREE from 'three';
4
4
  import type { SystemAdapters } from '../adapter/system-adapter';
5
- import type { AnimGraph } from '../animation/anim-graph';
6
5
  import type { AssetCache } from '../assets';
7
6
  import type { createSystemRunner } from '../core/system-runner';
8
7
  import type { createDebugDraw } from '../dev/debug-draw';
@@ -75,10 +74,6 @@ export interface GameContext {
75
74
  * automatically per frame. Dev-only visualization — not for shipped
76
75
  * visuals. */
77
76
  debugDraw: ReturnType<typeof createDebugDraw>;
78
- /** Active animation graphs, keyed by their `Object3D`; ticked in the
79
- * `animation` phase. Look up an entity's `AnimGraph` to set params/triggers.
80
- * GLTF/scene-defined graphs register here automatically. */
81
- animGraphs: Map<THREE.Object3D, AnimGraph>;
82
77
  /** Shared GLTF/texture cache. Use `assets.loadGLTF(...)` etc. to load+cache
83
78
  * models at runtime so repeated loads reuse geometry/material. */
84
79
  assets: AssetCache;