@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
@@ -1,7 +1,39 @@
1
- export { hum, nature, rain, wind } from './ambient';
2
- export { bounce, crash, explosion, hit } from './impacts';
3
- export { footstep, jump, whoosh } from './movement';
4
- export { arpeggio, bassPulse, stinger } from './musical';
5
- export { uiClick, uiError, uiHover, uiSuccess } from './ui-sounds';
6
- export { brakeSqueal, engineDrone, tireSkid } from './vehicle';
7
- export { chargeUp, gunshot, laser } from './weapons';
1
+ // Engine-core audio surface (spec §13 workstream G).
2
+ //
3
+ // G3 ("Replace or Relocate Procedural Audio Helpers") removed the former
4
+ // `musical.ts`/`weapons.ts`/`impacts.ts`/`vehicle.ts`/`ambient.ts`/
5
+ // `movement.ts`/`ui-sounds.ts` — raw-`AudioContext`/`Math.random`-driven
6
+ // oscillator and noise-buffer SFX generators that were engine-owned but
7
+ // non-spatial (they never touched `THREE.PositionalAudio`, so the "spatial
8
+ // one-shot helper" exception in the G3 acceptance criteria does not apply to
9
+ // them). Each was either relocated verbatim into the example project that
10
+ // used it (`examples/{third-person,fps,third-person-arena,rts,vehicle}/src/
11
+ // procedural-audio.ts`) or deleted as dead code with no shipped consumer
12
+ // (`bassPulse`/`arpeggio`/`gunshot`/`laser`/`bounce`/`crash`/`explosion`/
13
+ // `tireSkid`/`wind`/`rain`/`hum`/`nature`/`uiHover`/`uiError`). The canonical
14
+ // replacements — a procedural-music example built directly on Tone's own API
15
+ // and a spatial-audio example built directly on `THREE.PositionalAudio` — are
16
+ // `examples/audio-showcase`.
17
+ //
18
+ // What remains here is the genuine engine-core audio capability: the G1/G2
19
+ // Tone↔Three context bridge and offline render (`wav-encode.ts`, the G4
20
+ // PCM->WAV encoder, is consumed by its own module path, not this barrel — see
21
+ // `packages/engine/src/runtime/render-audio-control.ts`).
22
+ export {
23
+ bindClockToTone,
24
+ type ToneClockBinding,
25
+ type ToneClockBindingOptions,
26
+ type ToneTransportLike,
27
+ } from './tone-clock-binding';
28
+ export {
29
+ bridgeToneToThreeAudio,
30
+ connectToneBusToMasterGain,
31
+ resumeSharedAudio,
32
+ type ToneAudioBridge,
33
+ } from './tone-context';
34
+ export {
35
+ renderToneOffline,
36
+ type ToneOfflineComposeFn,
37
+ type ToneOfflineRenderRequest,
38
+ type ToneOfflineRenderResult,
39
+ } from './tone-offline-render';
@@ -0,0 +1,98 @@
1
+ import type { AnimationClock, ClockEvaluatorHandle } from '../animation/animation-clock';
2
+ import type { SystemPhaseName } from '../core/types';
3
+
4
+ /**
5
+ * G2 — Integrate Tone with the Canonical Clock, preview/real-time half
6
+ * (spec §13 G2, §10 D1). Mirrors `animation/theatre-clock-binding.ts`'s D2
7
+ * pattern exactly, on purpose: the canonical `AnimationClock` is the single
8
+ * source of truth for "what time is it", and every participating system
9
+ * (Theatre's sequence position, a registered GSAP timeline, and — here — a
10
+ * Tone transport) is seeked to match it on every clock crossing. Tone must
11
+ * never be left to free-run its own real-time clock while participating in
12
+ * a cinematic, for the exact same reason Theatre isn't: deterministic
13
+ * export, offline scrubbing, and no wall-clock dependency
14
+ * (`animation-clock.ts`'s module doc explains why in full).
15
+ *
16
+ * ## Why setting `transport.seconds` is enough
17
+ *
18
+ * Setting `Tone.getTransport().seconds` repositions the transport's
19
+ * playhead synchronously; it does not itself start real-time ticking (that
20
+ * still requires an explicit `transport.start()`, which this binding
21
+ * deliberately never calls — see the module doc on `animation-clock.ts` for
22
+ * why nothing in this codebase is allowed to drive its own
23
+ * `requestAnimationFrame`/wall-clock loop). A clock-seeked Tone transport is
24
+ * a pure function of `clock.time`, exactly like a Theatre sequence's
25
+ * `position` setter.
26
+ *
27
+ * ## Structural (not nominal) transport typing
28
+ *
29
+ * `ToneTransportLike` intentionally types only the ONE property this
30
+ * binding touches (`seconds`), the same narrowing discipline
31
+ * `runtime/render-control.ts`'s `SeekableClock` uses for the canonical
32
+ * clock. `Tone.getTransport()`'s real `TransportClass` satisfies this
33
+ * structurally with no adapter — pass it directly at the real call site.
34
+ * The narrow type is also what makes this binding's own unit tests real
35
+ * (not mocked-away): `packages/engine/test/audio/tone-clock-binding.test.ts`
36
+ * exercises the FULL seek/pause/loop/time-scale matrix against a real
37
+ * `AnimationClock` and a plain `{ seconds: number }` object — no Tone
38
+ * import, no `AudioContext`, and it still proves the exact behavior a real
39
+ * `Tone.Transport` will see, because `TransportClass` IS a
40
+ * `ToneTransportLike` at the type level.
41
+ */
42
+
43
+ export interface ToneTransportLike {
44
+ seconds: number;
45
+ }
46
+
47
+ export interface ToneClockBindingOptions {
48
+ /**
49
+ * Which `AnimationClock` phase to seek the transport in. Defaults to
50
+ * `'animation'` — the same phase `theatre-clock-binding.ts` uses by
51
+ * default, so a Theatre sequence and a Tone transport bound to the same
52
+ * clock stay in lockstep with each other (`PHASE_ORDER`-then-registration-
53
+ * order — see `animation-clock.ts`'s `subscribe` doc comment).
54
+ */
55
+ phase?: SystemPhaseName;
56
+ }
57
+
58
+ export interface ToneClockBinding {
59
+ /** Removes the clock evaluator. No further `transport.seconds` writes
60
+ * occur after this — the transport is left at whatever position it was
61
+ * last seeked to (matches `TheatreClockBinding.dispose`'s contract). */
62
+ dispose(): void;
63
+ }
64
+
65
+ /**
66
+ * Subscribe `transport.seconds = clock.time` to every crossing of `clock`
67
+ * in the given phase (default `'animation'`). Returns a disposer; call it
68
+ * to stop driving the transport (e.g. on `GameCleanup.dispose()`, or before
69
+ * rebinding on hot reload — this is what keeps HMR from accumulating
70
+ * duplicate listeners).
71
+ *
72
+ * Only call this for a Tone composition that PARTICIPATES in a cinematic
73
+ * (spec G2 AC). Ordinary, non-cinematic game music should drive Tone's own
74
+ * real-time transport directly (`transport.start()`, `Tone.Transport.bpm`,
75
+ * etc. — see `tone-context.ts`'s "escape hatch" section) and must NEVER be
76
+ * bound here, since a bound transport's position is entirely clock-driven
77
+ * and `start()`/`stop()` calls on it would fight this binding's writes.
78
+ */
79
+ export function bindClockToTone(
80
+ clock: AnimationClock,
81
+ transport: ToneTransportLike,
82
+ options: ToneClockBindingOptions = {},
83
+ ): ToneClockBinding {
84
+ const phase = options.phase ?? 'animation';
85
+
86
+ const handle: ClockEvaluatorHandle = clock.subscribe(phase, (crossing) => {
87
+ transport.seconds = crossing.currentTime;
88
+ });
89
+
90
+ let disposed = false;
91
+ return {
92
+ dispose(): void {
93
+ if (disposed) return;
94
+ disposed = true;
95
+ handle.dispose();
96
+ },
97
+ };
98
+ }
@@ -0,0 +1,129 @@
1
+ import type { ToneAudioNode } from 'tone';
2
+ import * as Tone from 'tone';
3
+
4
+ /**
5
+ * G1 — Establish Audio Ownership (spec §13 G1, §3.6, §4).
6
+ *
7
+ * ## The boundary
8
+ *
9
+ * Two independent, native-vocabulary audio systems coexist in every VGAI
10
+ * game, each with a genuinely different job. This module does not wrap
11
+ * either one — it only decides who owns which native `AudioContext` and how
12
+ * the two graphs meet:
13
+ *
14
+ * - **Three/Web Audio** (`setup/setup-audio.ts`) remains authoritative for
15
+ * SPATIAL audio: `THREE.AudioListener` (attached to the active camera)
16
+ * and `THREE.Audio`/`THREE.PositionalAudio` sources. (G3, a later unit,
17
+ * has since removed the non-spatial engine-owned one-shot procedural
18
+ * helpers this comment used to name here — `audio/impacts.ts`,
19
+ * `audio/weapons.ts`, `audio/ambient.ts`, and their siblings — relocating
20
+ * each into the example project that used it, or deleting it as dead code;
21
+ * see `packages/engine/src/audio/index.ts`'s header comment and
22
+ * `examples/audio-showcase` for the canonical native-Tone/native-Three
23
+ * replacements. This module's own boundary/bridge is unchanged by that
24
+ * unit.)
25
+ * - **Tone.js** owns musical transport, tempo, scheduling, synthesis, and
26
+ * procedural composition — imported and used with its OWN native API
27
+ * (`new Tone.Synth()`, `Tone.getTransport()`, `Tone.Offline(...)`,
28
+ * `Tone.getContext()`), never through a VGAI-renamed wrapper (spec §1's
29
+ * native-library rule). See `packages/engine/test/audio/tone-context.test.ts`
30
+ * for a direct, unwrapped usage example.
31
+ *
32
+ * ## Why they must share one native `AudioContext`
33
+ *
34
+ * Both systems ultimately talk to exactly one hardware output. If Tone ran
35
+ * its own independently-created `AudioContext` alongside
36
+ * `THREE.AudioListener`'s, they would: fight over autoplay-policy resume
37
+ * state (two contexts, two `state`s, two places a "click to start audio"
38
+ * gesture would need to unlock); produce TWO separate graphs that a single
39
+ * mute/volume control cannot coherently silence; and — fatally for G4/I6 —
40
+ * make deterministic offline capture impossible to align with the video's
41
+ * frame-addressed render range, since there would be no single graph whose
42
+ * lifecycle (suspend/resume/close) the render/capture harness can reason
43
+ * about.
44
+ *
45
+ * `bridgeToneToThreeAudio` fixes this: it points Tone's global context
46
+ * (`Tone.setContext`) at the SAME native `AudioContext` instance
47
+ * `THREE.AudioListener` already created (`setupAudio(camera).listener.context`,
48
+ * `setup/setup-audio.ts`). After bridging,
49
+ * `Tone.getContext().rawContext === threeListener.context` — there is
50
+ * exactly one native context. One `.resume()`/`.suspend()` call (or
51
+ * `Tone.start()`, which does both) affects both systems, and routing a Tone
52
+ * bus into `setupAudio()`'s `masterGain` (see `connectToneBusToMasterGain`
53
+ * below) puts Tone's output under the SAME mute/master-volume control as
54
+ * every `THREE.Audio` source.
55
+ *
56
+ * ## What this module does NOT do
57
+ *
58
+ * It does not create an `AudioContext` (that remains `setupAudio`'s job —
59
+ * call `bridgeToneToThreeAudio` AFTER `setupAudio(camera)`, before
60
+ * constructing any Tone node: Tone nodes built against the PREVIOUS global
61
+ * context are not retroactively migrated — Tone's own `setContext` contract,
62
+ * not a VGAI limitation). It does not wrap any Tone class, and it does not
63
+ * touch THREE's audio path at all. G3 (a later unit) is where engine-owned
64
+ * procedural helpers get rewritten directly on Tone or relocated to game
65
+ * code — this module only owns the context boundary + bridge.
66
+ *
67
+ * ## Escape hatch — ordinary (non-cinematic) game music
68
+ *
69
+ * None of the above requires participating in a cinematic. Once bridged,
70
+ * ordinary game music can drive Tone's REAL real-time transport exactly as
71
+ * Tone's own docs describe — `Tone.getTransport().bpm.value = 128`,
72
+ * `Tone.getTransport().start()`, `new Tone.Sequence(...).start(0)`, etc. —
73
+ * with no VGAI involvement at all. `tone-clock-binding.ts` (G2) is opt-in,
74
+ * only for the case where a Tone composition must stay in lockstep with the
75
+ * canonical `AnimationClock` because it participates in a cinematic.
76
+ */
77
+
78
+ /** Result of {@link bridgeToneToThreeAudio} — the shared native context plus
79
+ * a re-checkable assertion, so a caller/test doesn't need to re-derive the
80
+ * bridging logic to confirm it still holds later. */
81
+ export interface ToneAudioBridge {
82
+ /** The native `AudioContext` Tone and `THREE.AudioListener` now share. */
83
+ readonly context: AudioContext;
84
+ /** True iff `Tone.getContext().rawContext` is still exactly `context`
85
+ * (identity, not equality — proves ONE shared native context, not two
86
+ * compatible-looking ones). */
87
+ isBridged(): boolean;
88
+ }
89
+
90
+ /**
91
+ * Point Tone's global context at `context` (typically
92
+ * `setupAudio(camera).listener.context` from `setup/setup-audio.ts`). Call
93
+ * this once per game boot, after `setupAudio(camera)`, before constructing
94
+ * any Tone node.
95
+ */
96
+ export function bridgeToneToThreeAudio(context: AudioContext): ToneAudioBridge {
97
+ Tone.setContext(context);
98
+ return {
99
+ context,
100
+ isBridged: () => Tone.getContext().rawContext === context,
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Route a Tone output node (a bus, `Tone.getDestination()`, or any
106
+ * `Tone.Gain` used as a submix) into the SAME `masterGain`
107
+ * `setupAudio()` created, so Tone output is silenced/attenuated by the
108
+ * identical mute/volume control as every `THREE.Audio`/`THREE.PositionalAudio`
109
+ * source. `toneNode` is Tone's own `ToneAudioNode` type (no VGAI wrapper);
110
+ * `masterGain` is the plain native `GainNode` `setupAudio()` already
111
+ * returns — Tone's `.connect()` natively accepts a raw `AudioNode` as its
112
+ * destination, so no adapter node is needed on either side.
113
+ */
114
+ export function connectToneBusToMasterGain(toneNode: ToneAudioNode, masterGain: GainNode): void {
115
+ toneNode.connect(masterGain);
116
+ }
117
+
118
+ /**
119
+ * Resume the shared context after a user gesture. Because
120
+ * {@link bridgeToneToThreeAudio} guarantees Tone and THREE share the
121
+ * identical native context, calling `Tone.start()` — which both resumes the
122
+ * context AND runs Tone's own autoplay-unlock bookkeeping (a silent-buffer
123
+ * trick required on some browsers) — is sufficient to unstick BOTH systems;
124
+ * a separate `context.resume()` call on the THREE side is redundant once
125
+ * bridged, not required.
126
+ */
127
+ export async function resumeSharedAudio(): Promise<void> {
128
+ await Tone.start();
129
+ }
@@ -0,0 +1,167 @@
1
+ import { Offline } from 'tone';
2
+
3
+ /**
4
+ * G2 — Integrate Tone with the Canonical Clock, OFFLINE-render half (spec
5
+ * §13 G2, and the G4/I6 seam it is deliberately shaped for). This module
6
+ * renders a Tone composition over an exact `[start, end)` time range to a
7
+ * real `AudioBuffer` via `Tone.Offline` — i.e. `OfflineAudioContext`, NOT a
8
+ * live real-time `AudioContext` — such that identical inputs produce
9
+ * bit-identical output samples on every call. This is what makes offline
10
+ * Tone audio safe to mux into a deterministically-rendered video (G4/I6):
11
+ * the video side already re-renders frame-by-frame from an exact clock
12
+ * position, and this is the audio side's equivalent — an exact re-render
13
+ * from an exact time range, not a live capture of whatever happened to play.
14
+ *
15
+ * ## Why this can't run in plain Node (documented, not assumed)
16
+ *
17
+ * `Tone.Offline` ultimately constructs a real `OfflineAudioContext`
18
+ * (via `standardized-audio-context`, Tone's own dependency). Node has no
19
+ * native Web Audio implementation, so `standardized-audio-context` throws
20
+ * `"Missing the native OfflineAudioContext constructor."` the moment
21
+ * `Tone.Offline(...)` is actually invoked — confirmed empirically against
22
+ * this repo's installed `tone@15.1.22` before writing this module (plain
23
+ * `import * as Tone from 'tone'` succeeds; calling `Tone.Offline(...)` in a
24
+ * Node process throws immediately). There is no lightweight polyfill in this
25
+ * repo's dependency tree, and installing a native Node Web Audio addon is
26
+ * out of scope for this unit (build-box constraints). The determinism proof
27
+ * for this module therefore runs in a REAL headless-Chromium page via
28
+ * Playwright — see `packages/engine/e2e/tests/tone-audio-g1-g2.spec.ts`
29
+ * — mirroring how I0 proved video-frame determinism. This module's own
30
+ * `packages/engine/test/audio/tone-offline-render.test.ts` covers everything
31
+ * that does NOT require a real `OfflineAudioContext` (range validation,
32
+ * synchronous pre-render cancellation) directly in Node.
33
+ *
34
+ * ## Composition contract
35
+ *
36
+ * `compose` is called by `Tone.Offline` itself, inside the offline context —
37
+ * build the SAME graph you would in real-time Tone code
38
+ * (`new Tone.Synth().toDestination()`, `context.transport.schedule(...)`,
39
+ * etc; see Tone's own `Offline` docs). Nothing about this wrapper changes
40
+ * Tone's native API surface — `compose`'s parameter is `Tone.Offline`'s own
41
+ * callback type, re-derived structurally (`Parameters<typeof Offline>[0]`)
42
+ * rather than duplicated, so this module can never drift from Tone's actual
43
+ * signature.
44
+ *
45
+ * ## Cancellation — cooperative, not a true mid-render abort
46
+ *
47
+ * The Web Audio spec gives `OfflineAudioContext` no `.close()`/cancel API
48
+ * once `startRendering()` is in flight, and neither does Tone. `signal`
49
+ * therefore provides COOPERATIVE cancellation only: if `signal` is already
50
+ * aborted before this function calls `Tone.Offline`, the render never
51
+ * starts at all (checked synchronously, before any `OfflineAudioContext` is
52
+ * created). If `signal` aborts WHILE a render is in flight, this function's
53
+ * returned promise rejects immediately with an `AbortError` — so a caller
54
+ * (e.g. a render-cancellation UI action) sees the render "stop" from its own
55
+ * perspective and never receives/uses the resulting buffer — even though
56
+ * the underlying browser-native render may keep running in the background
57
+ * until it would have finished anyway. This is an honest, documented
58
+ * limitation, not a gap: no browser API makes a stronger guarantee possible.
59
+ */
60
+
61
+ /** Tone's own `Offline` callback signature, re-derived (not re-typed) so
62
+ * this module can never drift from the real function it wraps. */
63
+ export type ToneOfflineComposeFn = Parameters<typeof Offline>[0];
64
+
65
+ export interface ToneOfflineRenderRequest {
66
+ /** Canonical/Theatre-time range start, in seconds. */
67
+ readonly start: number;
68
+ /** Canonical/Theatre-time range end, in seconds. Must be `> start`. */
69
+ readonly end: number;
70
+ /** Output sample rate. Default 44100 (CD-quality, FFmpeg's usual default). */
71
+ readonly sampleRate?: number;
72
+ /** Output channel count. Default 2 (stereo). */
73
+ readonly channels?: number;
74
+ /** Builds the Tone graph inside the offline context — Tone's native
75
+ * `Offline` callback, unmodified. Receives local time `0` at `start`. */
76
+ readonly compose: ToneOfflineComposeFn;
77
+ /** Optional cooperative-cancellation signal — see module doc above. */
78
+ readonly signal?: AbortSignal;
79
+ }
80
+
81
+ export interface ToneOfflineRenderResult {
82
+ /** The rendered PCM, as a real (native) `AudioBuffer` — `.getChannelData(n)`
83
+ * gives the Float32 samples for channel `n`, ready for a digest/RMS
84
+ * computation or (eventually, G4/I6) FFmpeg muxing. */
85
+ readonly buffer: AudioBuffer;
86
+ readonly durationSeconds: number;
87
+ readonly sampleRate: number;
88
+ readonly channels: number;
89
+ }
90
+
91
+ const DEFAULT_SAMPLE_RATE = 44100;
92
+ const DEFAULT_CHANNELS = 2;
93
+
94
+ /** Render `request.compose`'s Tone graph offline over `[start, end)`,
95
+ * producing a deterministic `AudioBuffer`. See module doc for the
96
+ * determinism/cancellation contract. */
97
+ export async function renderToneOffline(
98
+ request: ToneOfflineRenderRequest,
99
+ ): Promise<ToneOfflineRenderResult> {
100
+ const {
101
+ start,
102
+ end,
103
+ sampleRate = DEFAULT_SAMPLE_RATE,
104
+ channels = DEFAULT_CHANNELS,
105
+ compose,
106
+ signal,
107
+ } = request;
108
+
109
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) {
110
+ throw new Error(
111
+ `[tone-offline-render] invalid range [${start}, ${end}) — end must be a finite number > start`,
112
+ );
113
+ }
114
+ if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
115
+ throw new Error(
116
+ `[tone-offline-render] sampleRate must be a finite number > 0, got ${sampleRate}`,
117
+ );
118
+ }
119
+ if (!Number.isInteger(channels) || channels <= 0) {
120
+ throw new Error(`[tone-offline-render] channels must be a positive integer, got ${channels}`);
121
+ }
122
+ // Cooperative cancellation, checked BEFORE ever constructing an
123
+ // OfflineAudioContext — an already-aborted signal must never start a
124
+ // render at all (see module doc).
125
+ if (signal?.aborted) {
126
+ throw createAbortError();
127
+ }
128
+
129
+ const durationSeconds = end - start;
130
+ const renderPromise = Offline(compose, durationSeconds, channels, sampleRate);
131
+ const toneBuffer = signal ? await raceAbort(renderPromise, signal) : await renderPromise;
132
+ const buffer = toneBuffer.get();
133
+ if (!buffer) {
134
+ throw new Error('[tone-offline-render] Tone.Offline resolved without a decoded AudioBuffer');
135
+ }
136
+
137
+ return {
138
+ buffer,
139
+ durationSeconds,
140
+ sampleRate: buffer.sampleRate,
141
+ channels: buffer.numberOfChannels,
142
+ };
143
+ }
144
+
145
+ function createAbortError(): DOMException {
146
+ return new DOMException('[tone-offline-render] render canceled', 'AbortError');
147
+ }
148
+
149
+ /** Race `promise` against `signal` firing — resolves/rejects with whichever
150
+ * happens first, without altering the underlying Web Audio render (see
151
+ * module doc's "cooperative, not a true mid-render abort" section). */
152
+ function raceAbort<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {
153
+ return new Promise<T>((resolve, reject) => {
154
+ const onAbort = () => reject(createAbortError());
155
+ signal.addEventListener('abort', onAbort, { once: true });
156
+ promise.then(
157
+ (value) => {
158
+ signal.removeEventListener('abort', onAbort);
159
+ resolve(value);
160
+ },
161
+ (err: unknown) => {
162
+ signal.removeEventListener('abort', onAbort);
163
+ reject(err);
164
+ },
165
+ );
166
+ });
167
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Pure PCM -> 16-bit WAV encoder (spec §15 I6 "Encode and Mux", audio half —
3
+ * `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`). This module takes
4
+ * already-rendered Float32 channel data (e.g. `AudioBuffer.getChannelData(n)`
5
+ * from a `Tone.Offline` render, `audio/tone-offline-render.ts`) and produces
6
+ * a standard little-endian, 16-bit-PCM, interleaved RIFF/WAVE file as raw
7
+ * bytes — no `AudioBuffer`/`AudioContext` dependency, so this runs equally in
8
+ * a browser render-mode page (`runtime/render-audio-control.ts`) and in
9
+ * plain Node (this module's own `packages/engine/test/audio/wav-encode.test.ts`,
10
+ * no Playwright needed).
11
+ *
12
+ * 16-bit PCM (not 32-bit float) is the deliberate choice named by the I6 AC
13
+ * ("16-bit PCM WAV is fine") — it is universally decodable by every FFmpeg
14
+ * build without an extra format flag, keeping the video-mux step's ffmpeg
15
+ * invocation ordinary and portable.
16
+ */
17
+
18
+ export interface PcmToWavInput {
19
+ /** One `Float32Array` per channel, each sample in `[-1, 1]` (values outside
20
+ * that range are clamped, not thrown on — real synthesis can transiently
21
+ * clip). All channels must have equal length. */
22
+ readonly channelData: readonly Float32Array[];
23
+ readonly sampleRate: number;
24
+ }
25
+
26
+ const BYTES_PER_SAMPLE = 2; // 16-bit PCM
27
+ const WAV_HEADER_BYTES = 44;
28
+
29
+ function clamp(value: number, lo: number, hi: number): number {
30
+ return Math.min(hi, Math.max(lo, value));
31
+ }
32
+
33
+ function writeAsciiString(view: DataView, offset: number, text: string): void {
34
+ for (let i = 0; i < text.length; i++) {
35
+ view.setUint8(offset + i, text.charCodeAt(i));
36
+ }
37
+ }
38
+
39
+ /** Encode `input` as a complete little-endian, 16-bit-PCM, interleaved
40
+ * RIFF/WAVE file (44-byte canonical header + data chunk). Throws on an
41
+ * empty/mismatched channel set rather than silently producing a malformed
42
+ * file — this module's own contribution to the "fail loudly, never a
43
+ * silent no-op" convention `runtime/render-control.ts` documents. */
44
+ export function encodeWav16(input: PcmToWavInput): Uint8Array {
45
+ const { channelData, sampleRate } = input;
46
+ const numChannels = channelData.length;
47
+ if (numChannels === 0) {
48
+ throw new Error('[wav-encode] channelData must contain at least one channel');
49
+ }
50
+ if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
51
+ throw new Error(`[wav-encode] sampleRate must be a finite number > 0, got ${sampleRate}`);
52
+ }
53
+ const numFrames = channelData[0]?.length ?? 0;
54
+ for (let ch = 0; ch < numChannels; ch++) {
55
+ const len = channelData[ch]?.length ?? -1;
56
+ if (len !== numFrames) {
57
+ throw new Error(
58
+ `[wav-encode] channel ${ch} has length ${len}, expected ${numFrames} (all channels must match)`,
59
+ );
60
+ }
61
+ }
62
+
63
+ const blockAlign = numChannels * BYTES_PER_SAMPLE;
64
+ const byteRate = sampleRate * blockAlign;
65
+ const dataSize = numFrames * blockAlign;
66
+
67
+ const buffer = new ArrayBuffer(WAV_HEADER_BYTES + dataSize);
68
+ const view = new DataView(buffer);
69
+
70
+ // RIFF chunk descriptor
71
+ writeAsciiString(view, 0, 'RIFF');
72
+ view.setUint32(4, 36 + dataSize, true);
73
+ writeAsciiString(view, 8, 'WAVE');
74
+
75
+ // fmt subchunk (PCM)
76
+ writeAsciiString(view, 12, 'fmt ');
77
+ view.setUint32(16, 16, true); // subchunk size for PCM
78
+ view.setUint16(20, 1, true); // audio format 1 = PCM
79
+ view.setUint16(22, numChannels, true);
80
+ view.setUint32(24, sampleRate, true);
81
+ view.setUint32(28, byteRate, true);
82
+ view.setUint16(32, blockAlign, true);
83
+ view.setUint16(34, BYTES_PER_SAMPLE * 8, true); // bits per sample
84
+
85
+ // data subchunk
86
+ writeAsciiString(view, 36, 'data');
87
+ view.setUint32(40, dataSize, true);
88
+
89
+ let offset = WAV_HEADER_BYTES;
90
+ for (let i = 0; i < numFrames; i++) {
91
+ for (let ch = 0; ch < numChannels; ch++) {
92
+ const sample = clamp(channelData[ch]?.[i] ?? 0, -1, 1);
93
+ const intSample = Math.round(sample < 0 ? sample * 0x8000 : sample * 0x7fff);
94
+ view.setInt16(offset, intSample, true);
95
+ offset += BYTES_PER_SAMPLE;
96
+ }
97
+ }
98
+
99
+ return new Uint8Array(buffer);
100
+ }
101
+
102
+ /** RMS + peak over all channels/samples — the same "non-trivial audio, not
103
+ * an all-zero buffer" sanity check `tone-audio-main.ts`'s fixture computes,
104
+ * factored out here so both that fixture and the render-audio harness can
105
+ * share one implementation instead of drifting copies. */
106
+ export function pcmStats(channelData: readonly Float32Array[]): { rms: number; peak: number } {
107
+ let sumSquares = 0;
108
+ let peak = 0;
109
+ let count = 0;
110
+ for (const data of channelData) {
111
+ for (let i = 0; i < data.length; i++) {
112
+ const v = data[i] ?? 0;
113
+ sumSquares += v * v;
114
+ peak = Math.max(peak, Math.abs(v));
115
+ count++;
116
+ }
117
+ }
118
+ return { rms: count > 0 ? Math.sqrt(sumSquares / count) : 0, peak };
119
+ }
@@ -18,6 +18,13 @@ export function createGameLoop(config: GameLoopConfig) {
18
18
  const maxSubSteps = config.maxSubSteps ?? 8;
19
19
  // Also the accumulator's hard ceiling (see the spiral-of-death guard below).
20
20
  const maxAccumulator = fixedDt * maxSubSteps;
21
+ // I2 (render-control runtime mode, see `GameLoopConfig.externalDrive`'s
22
+ // doc comment): in this mode `start()` below deliberately skips both the
23
+ // `requestAnimationFrame` arm AND the `visibilitychange` listener install —
24
+ // no wall-clock timing source ever exists for this loop instance, so
25
+ // `config.update` can only ever be invoked by an external driver calling
26
+ // into the render-control seam, never by this file's own `frame()`.
27
+ const externalDrive = config.externalDrive ?? false;
21
28
 
22
29
  let accumulator = 0;
23
30
  let lastTime = 0;
@@ -87,6 +94,16 @@ export function createGameLoop(config: GameLoopConfig) {
87
94
  hiddenPaused = false;
88
95
  lastTime = performance.now();
89
96
  accumulator = 0;
97
+
98
+ // External-drive mode (I2): never arm rAF and never install the
99
+ // visibilitychange auto-stop handler. `running` still flips `true`
100
+ // above (so `isRunning`/`stop()` behave normally for a caller that
101
+ // treats this loop as "started"), but nothing will ever call
102
+ // `frame()` — a headless/backgrounded capture page cannot have this
103
+ // loop silently killed by `document.hidden`, because there is no
104
+ // listener to fire in the first place.
105
+ if (externalDrive) return;
106
+
90
107
  rafId = requestAnimationFrame(frame);
91
108
 
92
109
  if (!visibilityListenerAttached && typeof document !== 'undefined') {
package/src/core/types.ts CHANGED
@@ -55,4 +55,17 @@ export interface GameLoopConfig {
55
55
  * produces zero substeps calls `update` zero times and renders zero times.
56
56
  */
57
57
  update: (dt: number) => void;
58
+ /**
59
+ * External-drive mode (I2, `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`
60
+ * §15 I2): when `true`, `start()` never arms a `requestAnimationFrame`
61
+ * chain and never installs the `visibilitychange`/`document.hidden`
62
+ * auto-stop handler — so a headless/backgrounded capture page cannot have
63
+ * its loop silently killed by the tab-hidden guard, and `config.update`
64
+ * is never invoked by wall-clock/RAF timing at all. The caller (a render
65
+ * harness) drives frames itself instead — see `runtime/render-control.ts`,
66
+ * which calls a world's phase hooks directly rather than going through
67
+ * this loop's `update` callback. Default `false` (normal wall-clock RAF
68
+ * playback, unchanged).
69
+ */
70
+ externalDrive?: boolean;
58
71
  }