@vgai/engine 0.5.0 → 0.5.2

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 (538) hide show
  1. package/package.json +1 -1
  2. package/schemas/engine-capabilities.json +4 -4
  3. package/schemas/vgai-game.schema.json +2 -2
  4. package/src/adapter/authoring.ts +42 -0
  5. package/src/adapter/index.ts +3 -0
  6. package/src/adapter/ingest/overlay-apply.ts +50 -6
  7. package/src/adapter/ingest/scene-capture.ts +51 -2
  8. package/src/adapter/vgai-scene-game-adapter.ts +24 -0
  9. package/src/manifest/schema.ts +7 -3
  10. package/src/runtime/create-runtime.ts +97 -0
  11. package/src/runtime/game.ts +11 -1
  12. package/src/scene/asset-ref-check.ts +1 -1
  13. package/src/scene/scene-loader.ts +2 -2
  14. package/src/scene/user-data.ts +18 -0
  15. package/src/world3d-react/behavior.tsx +19 -11
  16. package/src/world3d-react/r3f-adapter.tsx +8 -0
  17. package/dist/adapter/adapter-surface.d.ts +0 -30
  18. package/dist/adapter/adapter-surface.d.ts.map +0 -1
  19. package/dist/adapter/adapter-surface.js +0 -18
  20. package/dist/adapter/authoring.d.ts +0 -461
  21. package/dist/adapter/authoring.d.ts.map +0 -1
  22. package/dist/adapter/authoring.js +0 -22
  23. package/dist/adapter/colyseus-networking-adapter.d.ts +0 -43
  24. package/dist/adapter/colyseus-networking-adapter.d.ts.map +0 -1
  25. package/dist/adapter/colyseus-networking-adapter.js +0 -38
  26. package/dist/adapter/first-party-systems.d.ts +0 -38
  27. package/dist/adapter/first-party-systems.d.ts.map +0 -1
  28. package/dist/adapter/first-party-systems.js +0 -77
  29. package/dist/adapter/game-adapter.d.ts +0 -133
  30. package/dist/adapter/game-adapter.d.ts.map +0 -1
  31. package/dist/adapter/game-adapter.js +0 -10
  32. package/dist/adapter/host-context.d.ts +0 -71
  33. package/dist/adapter/host-context.d.ts.map +0 -1
  34. package/dist/adapter/host-context.js +0 -16
  35. package/dist/adapter/index.d.ts +0 -22
  36. package/dist/adapter/index.d.ts.map +0 -1
  37. package/dist/adapter/index.js +0 -15
  38. package/dist/adapter/ingest/game-contract.d.ts +0 -53
  39. package/dist/adapter/ingest/game-contract.d.ts.map +0 -1
  40. package/dist/adapter/ingest/game-contract.js +0 -30
  41. package/dist/adapter/ingest/overlay-applier.d.ts +0 -118
  42. package/dist/adapter/ingest/overlay-applier.d.ts.map +0 -1
  43. package/dist/adapter/ingest/overlay-applier.js +0 -132
  44. package/dist/adapter/ingest/overlay-apply.d.ts +0 -60
  45. package/dist/adapter/ingest/overlay-apply.d.ts.map +0 -1
  46. package/dist/adapter/ingest/overlay-apply.js +0 -101
  47. package/dist/adapter/ingest/overlay-file.d.ts +0 -79
  48. package/dist/adapter/ingest/overlay-file.d.ts.map +0 -1
  49. package/dist/adapter/ingest/overlay-file.js +0 -66
  50. package/dist/adapter/ingest/overlay-report.d.ts +0 -113
  51. package/dist/adapter/ingest/overlay-report.d.ts.map +0 -1
  52. package/dist/adapter/ingest/overlay-report.js +0 -103
  53. package/dist/adapter/ingest/scene-capture.d.ts +0 -97
  54. package/dist/adapter/ingest/scene-capture.d.ts.map +0 -1
  55. package/dist/adapter/ingest/scene-capture.js +0 -248
  56. package/dist/adapter/ingest/upstream-pin.d.ts +0 -47
  57. package/dist/adapter/ingest/upstream-pin.d.ts.map +0 -1
  58. package/dist/adapter/ingest/upstream-pin.js +0 -50
  59. package/dist/adapter/loop-gate-report.d.ts +0 -34
  60. package/dist/adapter/loop-gate-report.d.ts.map +0 -1
  61. package/dist/adapter/loop-gate-report.js +0 -37
  62. package/dist/adapter/rapier-physics-adapter.d.ts +0 -12
  63. package/dist/adapter/rapier-physics-adapter.d.ts.map +0 -1
  64. package/dist/adapter/rapier-physics-adapter.js +0 -46
  65. package/dist/adapter/system-adapter.d.ts +0 -206
  66. package/dist/adapter/system-adapter.d.ts.map +0 -1
  67. package/dist/adapter/system-adapter.js +0 -13
  68. package/dist/adapter/transform.d.ts +0 -18
  69. package/dist/adapter/transform.d.ts.map +0 -1
  70. package/dist/adapter/transform.js +0 -1
  71. package/dist/adapter/vgai-scene-game-adapter.d.ts +0 -108
  72. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +0 -1
  73. package/dist/adapter/vgai-scene-game-adapter.js +0 -762
  74. package/dist/ai/navigation.d.ts +0 -64
  75. package/dist/ai/navigation.d.ts.map +0 -1
  76. package/dist/ai/navigation.js +0 -133
  77. package/dist/animation/anim-graph-types.d.ts +0 -25
  78. package/dist/animation/anim-graph-types.d.ts.map +0 -1
  79. package/dist/animation/anim-graph-types.js +0 -1
  80. package/dist/animation/animation-clock.d.ts +0 -213
  81. package/dist/animation/animation-clock.d.ts.map +0 -1
  82. package/dist/animation/animation-clock.js +0 -301
  83. package/dist/animation/blend-node.d.ts +0 -22
  84. package/dist/animation/blend-node.d.ts.map +0 -1
  85. package/dist/animation/blend-node.js +0 -97
  86. package/dist/animation/camera-ownership.d.ts +0 -250
  87. package/dist/animation/camera-ownership.d.ts.map +0 -1
  88. package/dist/animation/camera-ownership.js +0 -169
  89. package/dist/animation/cinematic-cues.d.ts +0 -200
  90. package/dist/animation/cinematic-cues.d.ts.map +0 -1
  91. package/dist/animation/cinematic-cues.js +0 -213
  92. package/dist/animation/clip-map.d.ts +0 -12
  93. package/dist/animation/clip-map.d.ts.map +0 -1
  94. package/dist/animation/clip-map.js +0 -37
  95. package/dist/animation/gsap-registration.d.ts +0 -119
  96. package/dist/animation/gsap-registration.d.ts.map +0 -1
  97. package/dist/animation/gsap-registration.js +0 -92
  98. package/dist/animation/theatre-clock-binding.d.ts +0 -89
  99. package/dist/animation/theatre-clock-binding.d.ts.map +0 -1
  100. package/dist/animation/theatre-clock-binding.js +0 -29
  101. package/dist/animation/theatre-director.d.ts +0 -242
  102. package/dist/animation/theatre-director.d.ts.map +0 -1
  103. package/dist/animation/theatre-director.js +0 -235
  104. package/dist/animation/theatre-object-binding.d.ts +0 -305
  105. package/dist/animation/theatre-object-binding.d.ts.map +0 -1
  106. package/dist/animation/theatre-object-binding.js +0 -351
  107. package/dist/animation/xstate-animation-binding.d.ts +0 -56
  108. package/dist/animation/xstate-animation-binding.d.ts.map +0 -1
  109. package/dist/animation/xstate-animation-binding.js +0 -331
  110. package/dist/animation/xstate-animation-meta.d.ts +0 -266
  111. package/dist/animation/xstate-animation-meta.d.ts.map +0 -1
  112. package/dist/animation/xstate-animation-meta.js +0 -252
  113. package/dist/assets.d.ts +0 -26
  114. package/dist/assets.d.ts.map +0 -1
  115. package/dist/assets.js +0 -55
  116. package/dist/audio/index.d.ts +0 -4
  117. package/dist/audio/index.d.ts.map +0 -1
  118. package/dist/audio/index.js +0 -24
  119. package/dist/audio/tone-clock-binding.d.ts +0 -75
  120. package/dist/audio/tone-clock-binding.d.ts.map +0 -1
  121. package/dist/audio/tone-clock-binding.js +0 -29
  122. package/dist/audio/tone-context.d.ts +0 -114
  123. package/dist/audio/tone-context.d.ts.map +0 -1
  124. package/dist/audio/tone-context.js +0 -39
  125. package/dist/audio/tone-offline-render.d.ts +0 -90
  126. package/dist/audio/tone-offline-render.d.ts.map +0 -1
  127. package/dist/audio/tone-offline-render.js +0 -56
  128. package/dist/audio/wav-encode.d.ts +0 -38
  129. package/dist/audio/wav-encode.d.ts.map +0 -1
  130. package/dist/audio/wav-encode.js +0 -97
  131. package/dist/character/cloth-sim.d.ts +0 -179
  132. package/dist/character/cloth-sim.d.ts.map +0 -1
  133. package/dist/character/cloth-sim.js +0 -334
  134. package/dist/character/spring-chain.d.ts +0 -135
  135. package/dist/character/spring-chain.d.ts.map +0 -1
  136. package/dist/character/spring-chain.js +0 -165
  137. package/dist/core/game-loop.d.ts +0 -42
  138. package/dist/core/game-loop.d.ts.map +0 -1
  139. package/dist/core/game-loop.js +0 -167
  140. package/dist/core/seeded-random.d.ts +0 -69
  141. package/dist/core/seeded-random.d.ts.map +0 -1
  142. package/dist/core/seeded-random.js +0 -121
  143. package/dist/core/system-runner.d.ts +0 -120
  144. package/dist/core/system-runner.d.ts.map +0 -1
  145. package/dist/core/system-runner.js +0 -297
  146. package/dist/core/types.d.ts +0 -92
  147. package/dist/core/types.d.ts.map +0 -1
  148. package/dist/core/types.js +0 -25
  149. package/dist/data/data-asset.d.ts +0 -101
  150. package/dist/data/data-asset.d.ts.map +0 -1
  151. package/dist/data/data-asset.js +0 -122
  152. package/dist/data/data-check-core.d.ts +0 -110
  153. package/dist/data/data-check-core.d.ts.map +0 -1
  154. package/dist/data/data-check-core.js +0 -178
  155. package/dist/data/data-ref.d.ts +0 -79
  156. package/dist/data/data-ref.d.ts.map +0 -1
  157. package/dist/data/data-ref.js +0 -130
  158. package/dist/data/vite-plugin-data.d.ts +0 -79
  159. package/dist/data/vite-plugin-data.d.ts.map +0 -1
  160. package/dist/data/vite-plugin-data.js +0 -217
  161. package/dist/dev/console-bridge.d.ts +0 -22
  162. package/dist/dev/console-bridge.d.ts.map +0 -1
  163. package/dist/dev/console-bridge.js +0 -71
  164. package/dist/dev/debug-draw.d.ts +0 -24
  165. package/dist/dev/debug-draw.d.ts.map +0 -1
  166. package/dist/dev/debug-draw.js +0 -73
  167. package/dist/dev/logger.d.ts +0 -30
  168. package/dist/dev/logger.d.ts.map +0 -1
  169. package/dist/dev/logger.js +0 -90
  170. package/dist/dev/performance-profiler.d.ts +0 -60
  171. package/dist/dev/performance-profiler.d.ts.map +0 -1
  172. package/dist/dev/performance-profiler.js +0 -181
  173. package/dist/dev/webgl-gpu-timer.d.ts +0 -8
  174. package/dist/dev/webgl-gpu-timer.d.ts.map +0 -1
  175. package/dist/dev/webgl-gpu-timer.js +0 -52
  176. package/dist/ecs/component-manager.d.ts +0 -205
  177. package/dist/ecs/component-manager.d.ts.map +0 -1
  178. package/dist/ecs/component-manager.js +0 -706
  179. package/dist/ecs/game-component.d.ts +0 -146
  180. package/dist/ecs/game-component.d.ts.map +0 -1
  181. package/dist/ecs/game-component.js +0 -141
  182. package/dist/ecs/hmr-swap-report.d.ts +0 -53
  183. package/dist/ecs/hmr-swap-report.d.ts.map +0 -1
  184. package/dist/ecs/hmr-swap-report.js +0 -55
  185. package/dist/humanoid/bake.operation.d.ts +0 -119
  186. package/dist/humanoid/bake.operation.d.ts.map +0 -1
  187. package/dist/humanoid/bake.operation.js +0 -228
  188. package/dist/humanoid/body.d.ts +0 -101
  189. package/dist/humanoid/body.d.ts.map +0 -1
  190. package/dist/humanoid/body.js +0 -530
  191. package/dist/humanoid/clips.d.ts +0 -62
  192. package/dist/humanoid/clips.d.ts.map +0 -1
  193. package/dist/humanoid/clips.js +0 -121
  194. package/dist/humanoid/compose.d.ts +0 -75
  195. package/dist/humanoid/compose.d.ts.map +0 -1
  196. package/dist/humanoid/compose.js +0 -176
  197. package/dist/humanoid/generate.d.ts +0 -92
  198. package/dist/humanoid/generate.d.ts.map +0 -1
  199. package/dist/humanoid/generate.js +0 -124
  200. package/dist/humanoid/index.d.ts +0 -24
  201. package/dist/humanoid/index.d.ts.map +0 -1
  202. package/dist/humanoid/index.js +0 -18
  203. package/dist/humanoid/schema.d.ts +0 -35
  204. package/dist/humanoid/schema.d.ts.map +0 -1
  205. package/dist/humanoid/schema.js +0 -87
  206. package/dist/humanoid/skeleton.d.ts +0 -103
  207. package/dist/humanoid/skeleton.d.ts.map +0 -1
  208. package/dist/humanoid/skeleton.js +0 -289
  209. package/dist/index.d.ts +0 -37
  210. package/dist/index.d.ts.map +0 -1
  211. package/dist/index.js +0 -30
  212. package/dist/input/input-manager.d.ts +0 -945
  213. package/dist/input/input-manager.d.ts.map +0 -1
  214. package/dist/input/input-manager.js +0 -2207
  215. package/dist/input/input-types.d.ts +0 -174
  216. package/dist/input/input-types.d.ts.map +0 -1
  217. package/dist/input/input-types.js +0 -1
  218. package/dist/input/prompt-labels.d.ts +0 -21
  219. package/dist/input/prompt-labels.d.ts.map +0 -1
  220. package/dist/input/prompt-labels.js +0 -121
  221. package/dist/input/rebind-controller.d.ts +0 -59
  222. package/dist/input/rebind-controller.d.ts.map +0 -1
  223. package/dist/input/rebind-controller.js +0 -85
  224. package/dist/input/schema.d.ts +0 -16
  225. package/dist/input/schema.d.ts.map +0 -1
  226. package/dist/input/schema.js +0 -228
  227. package/dist/loader.d.ts +0 -43
  228. package/dist/loader.d.ts.map +0 -1
  229. package/dist/loader.js +0 -59
  230. package/dist/manifest/index.d.ts +0 -5
  231. package/dist/manifest/index.d.ts.map +0 -1
  232. package/dist/manifest/index.js +0 -8
  233. package/dist/manifest/load-file.d.ts +0 -4
  234. package/dist/manifest/load-file.d.ts.map +0 -1
  235. package/dist/manifest/load-file.js +0 -14
  236. package/dist/manifest/load.d.ts +0 -144
  237. package/dist/manifest/load.d.ts.map +0 -1
  238. package/dist/manifest/load.js +0 -273
  239. package/dist/manifest/schema.d.ts +0 -230
  240. package/dist/manifest/schema.d.ts.map +0 -1
  241. package/dist/manifest/schema.js +0 -394
  242. package/dist/physics/collision-system.d.ts +0 -41
  243. package/dist/physics/collision-system.d.ts.map +0 -1
  244. package/dist/physics/collision-system.js +0 -64
  245. package/dist/physics/physics-registry.d.ts +0 -45
  246. package/dist/physics/physics-registry.d.ts.map +0 -1
  247. package/dist/physics/physics-registry.js +0 -65
  248. package/dist/physics/transform-writer.d.ts +0 -16
  249. package/dist/physics/transform-writer.d.ts.map +0 -1
  250. package/dist/physics/transform-writer.js +0 -38
  251. package/dist/physics/trigger-dispatch.d.ts +0 -24
  252. package/dist/physics/trigger-dispatch.d.ts.map +0 -1
  253. package/dist/physics/trigger-dispatch.js +0 -80
  254. package/dist/react/game-state.d.ts +0 -156
  255. package/dist/react/game-state.d.ts.map +0 -1
  256. package/dist/react/game-state.js +0 -222
  257. package/dist/react/root-adapter.d.ts +0 -11
  258. package/dist/react/root-adapter.d.ts.map +0 -1
  259. package/dist/react/root-adapter.js +0 -41
  260. package/dist/react/unmanaged-root-detector.d.ts +0 -12
  261. package/dist/react/unmanaged-root-detector.d.ts.map +0 -1
  262. package/dist/react/unmanaged-root-detector.js +0 -45
  263. package/dist/react/use-data.d.ts +0 -60
  264. package/dist/react/use-data.d.ts.map +0 -1
  265. package/dist/react/use-data.js +0 -101
  266. package/dist/react/use-selection.d.ts +0 -75
  267. package/dist/react/use-selection.d.ts.map +0 -1
  268. package/dist/react/use-selection.js +0 -90
  269. package/dist/render/auto-batcher.d.ts +0 -34
  270. package/dist/render/auto-batcher.d.ts.map +0 -1
  271. package/dist/render/auto-batcher.js +0 -140
  272. package/dist/render/render-batch-system.d.ts +0 -33
  273. package/dist/render/render-batch-system.d.ts.map +0 -1
  274. package/dist/render/render-batch-system.js +0 -230
  275. package/dist/render/render-features.d.ts +0 -47
  276. package/dist/render/render-features.d.ts.map +0 -1
  277. package/dist/render/render-features.js +0 -105
  278. package/dist/render/render-settings.d.ts +0 -36
  279. package/dist/render/render-settings.d.ts.map +0 -1
  280. package/dist/render/render-settings.js +0 -51
  281. package/dist/runtime/create-runtime.d.ts +0 -249
  282. package/dist/runtime/create-runtime.d.ts.map +0 -1
  283. package/dist/runtime/create-runtime.js +0 -641
  284. package/dist/runtime/debug-bridge.d.ts +0 -257
  285. package/dist/runtime/debug-bridge.d.ts.map +0 -1
  286. package/dist/runtime/debug-bridge.js +0 -224
  287. package/dist/runtime/debug-registry.d.ts +0 -288
  288. package/dist/runtime/debug-registry.d.ts.map +0 -1
  289. package/dist/runtime/debug-registry.js +0 -513
  290. package/dist/runtime/frame-selector-cache.d.ts +0 -41
  291. package/dist/runtime/frame-selector-cache.d.ts.map +0 -1
  292. package/dist/runtime/frame-selector-cache.js +0 -65
  293. package/dist/runtime/game.d.ts +0 -496
  294. package/dist/runtime/game.d.ts.map +0 -1
  295. package/dist/runtime/game.js +0 -741
  296. package/dist/runtime/gameplay-rng-trap.d.ts +0 -48
  297. package/dist/runtime/gameplay-rng-trap.d.ts.map +0 -1
  298. package/dist/runtime/gameplay-rng-trap.js +0 -96
  299. package/dist/runtime/input-router.d.ts +0 -78
  300. package/dist/runtime/input-router.d.ts.map +0 -1
  301. package/dist/runtime/input-router.js +0 -171
  302. package/dist/runtime/mount-game.d.ts +0 -129
  303. package/dist/runtime/mount-game.d.ts.map +0 -1
  304. package/dist/runtime/mount-game.js +0 -152
  305. package/dist/runtime/mount-manifest.d.ts +0 -173
  306. package/dist/runtime/mount-manifest.d.ts.map +0 -1
  307. package/dist/runtime/mount-manifest.js +0 -297
  308. package/dist/runtime/render-audio-control.d.ts +0 -110
  309. package/dist/runtime/render-audio-control.d.ts.map +0 -1
  310. package/dist/runtime/render-audio-control.js +0 -111
  311. package/dist/runtime/render-control.d.ts +0 -291
  312. package/dist/runtime/render-control.d.ts.map +0 -1
  313. package/dist/runtime/render-control.js +0 -264
  314. package/dist/runtime/render-seed.d.ts +0 -57
  315. package/dist/runtime/render-seed.d.ts.map +0 -1
  316. package/dist/runtime/render-seed.js +0 -74
  317. package/dist/runtime/state-bridge.d.ts +0 -61
  318. package/dist/runtime/state-bridge.d.ts.map +0 -1
  319. package/dist/runtime/state-bridge.js +0 -63
  320. package/dist/runtime/types.d.ts +0 -253
  321. package/dist/runtime/types.d.ts.map +0 -1
  322. package/dist/runtime/types.js +0 -1
  323. package/dist/scene/asset-loaders.d.ts +0 -79
  324. package/dist/scene/asset-loaders.d.ts.map +0 -1
  325. package/dist/scene/asset-loaders.js +0 -141
  326. package/dist/scene/asset-paths.d.ts +0 -11
  327. package/dist/scene/asset-paths.d.ts.map +0 -1
  328. package/dist/scene/asset-paths.js +0 -108
  329. package/dist/scene/asset-ref-check.d.ts +0 -88
  330. package/dist/scene/asset-ref-check.d.ts.map +0 -1
  331. package/dist/scene/asset-ref-check.js +0 -214
  332. package/dist/scene/asset-registry.d.ts +0 -38
  333. package/dist/scene/asset-registry.d.ts.map +0 -1
  334. package/dist/scene/asset-registry.js +0 -66
  335. package/dist/scene/collider-dimensions.d.ts +0 -63
  336. package/dist/scene/collider-dimensions.d.ts.map +0 -1
  337. package/dist/scene/collider-dimensions.js +0 -98
  338. package/dist/scene/component-registry.d.ts +0 -22
  339. package/dist/scene/component-registry.d.ts.map +0 -1
  340. package/dist/scene/component-registry.js +0 -37
  341. package/dist/scene/defaults.d.ts +0 -252
  342. package/dist/scene/defaults.d.ts.map +0 -1
  343. package/dist/scene/defaults.js +0 -151
  344. package/dist/scene/geometries/index.d.ts +0 -8
  345. package/dist/scene/geometries/index.d.ts.map +0 -1
  346. package/dist/scene/geometries/index.js +0 -7
  347. package/dist/scene/geometries/terrain.d.ts +0 -2
  348. package/dist/scene/geometries/terrain.d.ts.map +0 -1
  349. package/dist/scene/geometries/terrain.js +0 -37
  350. package/dist/scene/geometry-registry.d.ts +0 -24
  351. package/dist/scene/geometry-registry.d.ts.map +0 -1
  352. package/dist/scene/geometry-registry.js +0 -20
  353. package/dist/scene/instance-registry.d.ts +0 -36
  354. package/dist/scene/instance-registry.d.ts.map +0 -1
  355. package/dist/scene/instance-registry.js +0 -55
  356. package/dist/scene/instancers/grid.d.ts +0 -2
  357. package/dist/scene/instancers/grid.d.ts.map +0 -1
  358. package/dist/scene/instancers/grid.js +0 -36
  359. package/dist/scene/instancers/index.d.ts +0 -8
  360. package/dist/scene/instancers/index.d.ts.map +0 -1
  361. package/dist/scene/instancers/index.js +0 -7
  362. package/dist/scene/light-camera-factory.d.ts +0 -23
  363. package/dist/scene/light-camera-factory.d.ts.map +0 -1
  364. package/dist/scene/light-camera-factory.js +0 -68
  365. package/dist/scene/material-factory.d.ts +0 -17
  366. package/dist/scene/material-factory.d.ts.map +0 -1
  367. package/dist/scene/material-factory.js +0 -197
  368. package/dist/scene/material-registry.d.ts +0 -40
  369. package/dist/scene/material-registry.d.ts.map +0 -1
  370. package/dist/scene/material-registry.js +0 -44
  371. package/dist/scene/materials/index.d.ts +0 -8
  372. package/dist/scene/materials/index.d.ts.map +0 -1
  373. package/dist/scene/materials/index.js +0 -7
  374. package/dist/scene/materials/water.d.ts +0 -2
  375. package/dist/scene/materials/water.d.ts.map +0 -1
  376. package/dist/scene/materials/water.js +0 -54
  377. package/dist/scene/parse.d.ts +0 -23
  378. package/dist/scene/parse.d.ts.map +0 -1
  379. package/dist/scene/parse.js +0 -179
  380. package/dist/scene/particles-factory.d.ts +0 -33
  381. package/dist/scene/particles-factory.d.ts.map +0 -1
  382. package/dist/scene/particles-factory.js +0 -282
  383. package/dist/scene/scene-apply.d.ts +0 -109
  384. package/dist/scene/scene-apply.d.ts.map +0 -1
  385. package/dist/scene/scene-apply.js +0 -370
  386. package/dist/scene/scene-diff-schema.d.ts +0 -285
  387. package/dist/scene/scene-diff-schema.d.ts.map +0 -1
  388. package/dist/scene/scene-diff-schema.js +0 -92
  389. package/dist/scene/scene-diff-types.d.ts +0 -40
  390. package/dist/scene/scene-diff-types.d.ts.map +0 -1
  391. package/dist/scene/scene-diff-types.js +0 -14
  392. package/dist/scene/scene-loader.d.ts +0 -167
  393. package/dist/scene/scene-loader.d.ts.map +0 -1
  394. package/dist/scene/scene-loader.js +0 -1211
  395. package/dist/scene/scene-query.d.ts +0 -11
  396. package/dist/scene/scene-query.d.ts.map +0 -1
  397. package/dist/scene/scene-query.js +0 -63
  398. package/dist/scene/scene-types.d.ts +0 -10
  399. package/dist/scene/scene-types.d.ts.map +0 -1
  400. package/dist/scene/scene-types.js +0 -8
  401. package/dist/scene/scene-version.d.ts +0 -26
  402. package/dist/scene/scene-version.d.ts.map +0 -1
  403. package/dist/scene/scene-version.js +0 -34
  404. package/dist/scene/schema/animation.d.ts +0 -8
  405. package/dist/scene/schema/animation.d.ts.map +0 -1
  406. package/dist/scene/schema/animation.js +0 -42
  407. package/dist/scene/schema/audio.d.ts +0 -13
  408. package/dist/scene/schema/audio.d.ts.map +0 -1
  409. package/dist/scene/schema/audio.js +0 -22
  410. package/dist/scene/schema/camera.d.ts +0 -28
  411. package/dist/scene/schema/camera.d.ts.map +0 -1
  412. package/dist/scene/schema/camera.js +0 -17
  413. package/dist/scene/schema/collider.d.ts +0 -40
  414. package/dist/scene/schema/collider.d.ts.map +0 -1
  415. package/dist/scene/schema/collider.js +0 -55
  416. package/dist/scene/schema/entity-ref.d.ts +0 -31
  417. package/dist/scene/schema/entity-ref.d.ts.map +0 -1
  418. package/dist/scene/schema/entity-ref.js +0 -61
  419. package/dist/scene/schema/entity.d.ts +0 -1036
  420. package/dist/scene/schema/entity.d.ts.map +0 -1
  421. package/dist/scene/schema/entity.js +0 -153
  422. package/dist/scene/schema/environment.d.ts +0 -425
  423. package/dist/scene/schema/environment.d.ts.map +0 -1
  424. package/dist/scene/schema/environment.js +0 -357
  425. package/dist/scene/schema/index.d.ts +0 -37
  426. package/dist/scene/schema/index.d.ts.map +0 -1
  427. package/dist/scene/schema/index.js +0 -19
  428. package/dist/scene/schema/instances.d.ts +0 -14
  429. package/dist/scene/schema/instances.d.ts.map +0 -1
  430. package/dist/scene/schema/instances.js +0 -28
  431. package/dist/scene/schema/joint.d.ts +0 -23
  432. package/dist/scene/schema/joint.d.ts.map +0 -1
  433. package/dist/scene/schema/joint.js +0 -23
  434. package/dist/scene/schema/light.d.ts +0 -38
  435. package/dist/scene/schema/light.d.ts.map +0 -1
  436. package/dist/scene/schema/light.js +0 -26
  437. package/dist/scene/schema/material.d.ts +0 -199
  438. package/dist/scene/schema/material.d.ts.map +0 -1
  439. package/dist/scene/schema/material.js +0 -103
  440. package/dist/scene/schema/mesh.d.ts +0 -48
  441. package/dist/scene/schema/mesh.d.ts.map +0 -1
  442. package/dist/scene/schema/mesh.js +0 -82
  443. package/dist/scene/schema/particles.d.ts +0 -2178
  444. package/dist/scene/schema/particles.d.ts.map +0 -1
  445. package/dist/scene/schema/particles.js +0 -321
  446. package/dist/scene/schema/physics.d.ts +0 -56
  447. package/dist/scene/schema/physics.d.ts.map +0 -1
  448. package/dist/scene/schema/physics.js +0 -37
  449. package/dist/scene/schema/scene-file.d.ts +0 -303
  450. package/dist/scene/schema/scene-file.d.ts.map +0 -1
  451. package/dist/scene/schema/scene-file.js +0 -256
  452. package/dist/scene/schema/shadow.d.ts +0 -28
  453. package/dist/scene/schema/shadow.d.ts.map +0 -1
  454. package/dist/scene/schema/shadow.js +0 -20
  455. package/dist/scene/schema/spline.d.ts +0 -25
  456. package/dist/scene/schema/spline.d.ts.map +0 -1
  457. package/dist/scene/schema/spline.js +0 -15
  458. package/dist/scene/schema/tuples.d.ts +0 -12
  459. package/dist/scene/schema/tuples.d.ts.map +0 -1
  460. package/dist/scene/schema/tuples.js +0 -14
  461. package/dist/scene/user-data.d.ts +0 -185
  462. package/dist/scene/user-data.d.ts.map +0 -1
  463. package/dist/scene/user-data.js +0 -144
  464. package/dist/setup/setup-audio.d.ts +0 -20
  465. package/dist/setup/setup-audio.d.ts.map +0 -1
  466. package/dist/setup/setup-audio.js +0 -41
  467. package/dist/setup/setup-particles.d.ts +0 -17
  468. package/dist/setup/setup-particles.d.ts.map +0 -1
  469. package/dist/setup/setup-particles.js +0 -16
  470. package/dist/setup/setup-physics.d.ts +0 -25
  471. package/dist/setup/setup-physics.d.ts.map +0 -1
  472. package/dist/setup/setup-physics.js +0 -51
  473. package/dist/setup/setup-renderer.d.ts +0 -69
  474. package/dist/setup/setup-renderer.d.ts.map +0 -1
  475. package/dist/setup/setup-renderer.js +0 -363
  476. package/dist/tools/define-tool.d.ts +0 -130
  477. package/dist/tools/define-tool.d.ts.map +0 -1
  478. package/dist/tools/define-tool.js +0 -96
  479. package/dist/world2d/authoring-2d.d.ts +0 -80
  480. package/dist/world2d/authoring-2d.d.ts.map +0 -1
  481. package/dist/world2d/authoring-2d.js +0 -195
  482. package/dist/world2d/capture-to-scene2d.d.ts +0 -5
  483. package/dist/world2d/capture-to-scene2d.d.ts.map +0 -1
  484. package/dist/world2d/capture-to-scene2d.js +0 -49
  485. package/dist/world2d/collision-2d.d.ts +0 -52
  486. package/dist/world2d/collision-2d.d.ts.map +0 -1
  487. package/dist/world2d/collision-2d.js +0 -70
  488. package/dist/world2d/components-2d.d.ts +0 -47
  489. package/dist/world2d/components-2d.d.ts.map +0 -1
  490. package/dist/world2d/components-2d.js +0 -77
  491. package/dist/world2d/index.d.ts +0 -34
  492. package/dist/world2d/index.d.ts.map +0 -1
  493. package/dist/world2d/index.js +0 -32
  494. package/dist/world2d/ingest-iframe-2d.d.ts +0 -82
  495. package/dist/world2d/ingest-iframe-2d.d.ts.map +0 -1
  496. package/dist/world2d/ingest-iframe-2d.js +0 -166
  497. package/dist/world2d/ingest2d.d.ts +0 -97
  498. package/dist/world2d/ingest2d.d.ts.map +0 -1
  499. package/dist/world2d/ingest2d.js +0 -40
  500. package/dist/world2d/physics2d-registry.d.ts +0 -24
  501. package/dist/world2d/physics2d-registry.d.ts.map +0 -1
  502. package/dist/world2d/physics2d-registry.js +0 -38
  503. package/dist/world2d/pixi-game-adapter.d.ts +0 -107
  504. package/dist/world2d/pixi-game-adapter.d.ts.map +0 -1
  505. package/dist/world2d/pixi-game-adapter.js +0 -210
  506. package/dist/world2d/pixi-surface.d.ts +0 -39
  507. package/dist/world2d/pixi-surface.d.ts.map +0 -1
  508. package/dist/world2d/pixi-surface.js +0 -47
  509. package/dist/world2d/scene-capture-2d.d.ts +0 -43
  510. package/dist/world2d/scene-capture-2d.d.ts.map +0 -1
  511. package/dist/world2d/scene-capture-2d.js +0 -92
  512. package/dist/world2d/scene2d-loader.d.ts +0 -27
  513. package/dist/world2d/scene2d-loader.d.ts.map +0 -1
  514. package/dist/world2d/scene2d-loader.js +0 -275
  515. package/dist/world2d/schema/entity2d.d.ts +0 -102
  516. package/dist/world2d/schema/entity2d.d.ts.map +0 -1
  517. package/dist/world2d/schema/entity2d.js +0 -119
  518. package/dist/world2d/schema/physics2d.d.ts +0 -46
  519. package/dist/world2d/schema/physics2d.d.ts.map +0 -1
  520. package/dist/world2d/schema/physics2d.js +0 -45
  521. package/dist/world2d/schema/sprite.d.ts +0 -42
  522. package/dist/world2d/schema/sprite.d.ts.map +0 -1
  523. package/dist/world2d/schema/sprite.js +0 -63
  524. package/dist/world2d/schema/tilemap.d.ts +0 -15
  525. package/dist/world2d/schema/tilemap.d.ts.map +0 -1
  526. package/dist/world2d/schema/tilemap.js +0 -19
  527. package/dist/world2d/schema/tuples2d.d.ts +0 -20
  528. package/dist/world2d/schema/tuples2d.d.ts.map +0 -1
  529. package/dist/world2d/schema/tuples2d.js +0 -19
  530. package/dist/world2d/system-adapters-2d.d.ts +0 -16
  531. package/dist/world2d/system-adapters-2d.d.ts.map +0 -1
  532. package/dist/world2d/system-adapters-2d.js +0 -37
  533. package/dist/world2d/transform-writer-2d.d.ts +0 -16
  534. package/dist/world2d/transform-writer-2d.d.ts.map +0 -1
  535. package/dist/world2d/transform-writer-2d.js +0 -22
  536. package/dist/world2d/types.d.ts +0 -59
  537. package/dist/world2d/types.d.ts.map +0 -1
  538. package/dist/world2d/types.js +0 -1
@@ -1,741 +0,0 @@
1
- /**
2
- * Game root — T7.1 slice 1 ("introduce Game internally") + slice 2 ("world
3
- * registry + ordered frame algorithm"), extended in T7.3 slice 1 with real
4
- * `'pixijs'`-kind `WorldInstance` support (`stage`/`physics2d`/`collisions2d`,
5
- * a real `pixiRoot()`) so `world2d/pixi-game-adapter.ts` can register its
6
- * world onto a real `Game` instead of driving its own loop, and in T7.3
7
- * slice 2 with a construction-time stage check (symmetric with the
8
- * threejs/scene check) and the two-world (threejs + pixijs) proof
9
- * (`test/game-three-plus-pixi.test.ts`). T6.2 slice 1 adds real `'react'`-kind
10
- * `WorldInstance` support (`container`, a real `reactRoot()`) — the DOM-root
11
- * world surface `runtime/create-runtime.ts`'s roots path now mounts (see
12
- * `docs/REACT-WORLD-DESIGN.md` §1.B); react roots host no `ComponentManager`
13
- * (D8 — components attaching to a react-kind manager already throw,
14
- * `ecs/component-manager.ts`), so `physics`/`collisions`/`camera`/`frame`
15
- * stay `undefined` for them exactly like an opaque/foreign mount.
16
- *
17
- * See `docs/GAME-ROOT-DESIGN.md` (D6), particularly §4 (the frame algorithm)
18
- * and §8 stage 2, for the full target shape. This file holds the Game/
19
- * WorldInstance shell, the NEW game-scoped `SystemRunner`, and the
20
- * host-facing `runFrame` frame executor. The public surface is NOT frozen
21
- * yet — do not add these exports to a barrel/index; only the in-scope
22
- * runtime/adapter files import this module directly. The `gpu` per-world
23
- * cache is the one remaining slice-1 omission.
24
- */
25
- import { formatAudioGateMessage, formatLoopGateMessage } from '../adapter/loop-gate-report';
26
- import { createSeededRandom, DEFAULT_SEEDED_RANDOM_SEED, registerSeededRandom, } from '../core/seeded-random';
27
- import { createSystemRunner } from '../core/system-runner';
28
- import { PHASE_ORDER, SystemPhase } from '../core/types';
29
- import { createPerformanceProfiler } from '../dev/performance-profiler';
30
- import { createDebugRegistry, DebugError, registerDebugRegistry, } from './debug-registry';
31
- import { createGameplayRngTrap, registerGameplayRngTrapControl } from './gameplay-rng-trap';
32
- import { createStateBridge } from './state-bridge';
33
- /**
34
- * Build a `WorldInstance` whose kind-narrowed accessors throw descriptively
35
- * on kind mismatch (GAME-ROOT-DESIGN §3). This is the one place that builds
36
- * `threeRoot`/`pixiRoot`, so every world (however it's constructed, in this
37
- * slice or later ones) gets identical throw behavior.
38
- */
39
- export function createWorldInstance(init) {
40
- const { id, kind, pausable = true, adapter, mounted, scene, stage, container, physics, collisions, physics2d, collisions2d, camera, frame, } = init;
41
- // A threejs world with no scene has nothing for `threeRoot()` to return —
42
- // fail loudly HERE, at construction, rather than letting `threeRoot()`
43
- // throw its generic "not a threejs world" message later for a world whose
44
- // kind IS threejs (checklist item 5; a misleading error for this case).
45
- if (kind === 'threejs' && !scene) {
46
- throw new Error(`WorldInstance "${id}" (kind: threejs): a threejs world requires a scene — ` +
47
- 'pass `scene` in WorldInstanceInit.');
48
- }
49
- // Symmetric check for pixijs (T7.3 slice 2) — a pixijs world with no stage
50
- // has nothing for `pixiRoot()` to return; fail loudly here, at
51
- // construction, same as the threejs/scene check above.
52
- if (kind === 'pixijs' && !stage) {
53
- throw new Error(`WorldInstance "${id}" (kind: pixijs): a pixijs world requires a stage — ` +
54
- 'pass `stage` in WorldInstanceInit.');
55
- }
56
- // Symmetric check for react (T6.2 slice 1, docs/REACT-WORLD-DESIGN.md
57
- // §1.B) — a react world with no container has nothing for `reactRoot()`
58
- // to return; fail loudly here, at construction, same as the two checks
59
- // above.
60
- if (kind === 'react' && !container) {
61
- throw new Error(`WorldInstance "${id}" (kind: react): a react world requires a container — ` +
62
- 'pass `container` in WorldInstanceInit.');
63
- }
64
- // Disposed-world guard (GAME-ROOT-DESIGN §8 stage 3 / T7.1 slice 3). There
65
- // is no `unregisterWorld` (decision 4 — roots are manifest-declared; a
66
- // whole Game is disposed, not one world out of its registry), so a caller
67
- // that disposes ONE world's `mounted` directly (e.g. ending a sub-session)
68
- // leaves that `WorldInstance` sitting in `Game.roots` — and `runFrame`
69
- // would otherwise keep invoking its (now-torn-down) frame hooks every
70
- // subsequent frame. `MountedGame` has no public "am I disposed" flag to
71
- // read, so this wraps `mounted.dispose` in place (mutating the SAME mount
72
- // object every holder of `mounted` shares — calling `mounted.dispose()`
73
- // directly, exactly like calling `world.mounted.dispose()`, trips this)
74
- // to flip a private flag, and wraps the frame hooks so they silently no-op
75
- // once that flag is set. `runFrame` itself needs no knowledge of disposal
76
- // — a disposed world is skipped by construction from the next call
77
- // onward. (The opaque-world `mounted.update` fallback path is unaffected
78
- // by this guard — no opaque-mount two-world scenario exists yet to need it.)
79
- let disposed = false;
80
- const originalDispose = mounted.dispose.bind(mounted);
81
- mounted.dispose = () => {
82
- disposed = true;
83
- originalDispose();
84
- };
85
- const guardedFrame = frame
86
- ? {
87
- runPhase(phase, dt) {
88
- if (disposed)
89
- return;
90
- frame.runPhase(phase, dt);
91
- },
92
- endFrame() {
93
- if (disposed)
94
- return;
95
- frame.endFrame?.();
96
- },
97
- }
98
- : undefined;
99
- return {
100
- id,
101
- kind,
102
- pausable,
103
- adapter,
104
- mounted,
105
- physics,
106
- collisions,
107
- physics2d,
108
- collisions2d,
109
- camera,
110
- frame: guardedFrame,
111
- threeRoot() {
112
- if (kind !== 'threejs' || !scene) {
113
- throw new Error(`WorldInstance "${id}" (kind: ${kind}): threeRoot() requested but this world is not ` +
114
- 'a threejs world');
115
- }
116
- return scene;
117
- },
118
- pixiRoot() {
119
- // The `!stage` branch a pixijs world could hit here is now unreachable
120
- // (T7.3 slice 2): construction above throws for `kind === 'pixijs'`
121
- // with no `stage`, symmetric with `threeRoot()`'s `scene` guard.
122
- if (kind !== 'pixijs' || !stage) {
123
- throw new Error(`WorldInstance "${id}" (kind: ${kind}): pixiRoot() requested but this world is not ` +
124
- 'a pixijs world');
125
- }
126
- return stage;
127
- },
128
- reactRoot() {
129
- // The `!container` branch a react world could hit here is now
130
- // unreachable (T6.2 slice 1): construction above throws for
131
- // `kind === 'react'` with no `container`, symmetric with
132
- // `threeRoot()`/`pixiRoot()`'s guards.
133
- if (kind !== 'react' || !container) {
134
- throw new Error(`WorldInstance "${id}" (kind: ${kind}): reactRoot() requested but this world is not ` +
135
- 'a react world');
136
- }
137
- return container;
138
- },
139
- };
140
- }
141
- /**
142
- * Type guard for whether a `MountedGame` is a first-party
143
- * `VgaiSceneGameAdapter` mount (has a live `GameContext` at `.ctx`). Used to
144
- * decide whether a world's `physics`/`collisions`/`camera` (and, on `Game`,
145
- * `components`/`input`/`audio`) can be populated from it — an external
146
- * adapter's mount has none of these first-party handles.
147
- *
148
- * Checks the `firstParty: true` brand (checklist item 1), NOT `'ctx' in
149
- * mounted` — world2d's `MountedGame2D` (`world2d/pixi-game-adapter.ts`) also
150
- * has a `ctx` key (a `World2DContext`, unrelated to `GameContext`), so a
151
- * structural `'ctx' in mounted` check would misfire once T7.3 registers 2D
152
- * roots onto the same `Game`. The probe is a plain property read, not an
153
- * `instanceof`/value import of `vgai-scene-game-adapter.ts` — the
154
- * `VgaiMountedGame` import above stays type-only.
155
- */
156
- export function isFirstPartyMounted(mounted) {
157
- return mounted.firstParty === true;
158
- }
159
- function describeMismatch(handle, world) {
160
- return (`Game.${handle}: default world "${world.id}" (kind: ${world.kind}) is not a first-party ` +
161
- "mount — hoisting these to true Game ownership is a later slice's work; available only " +
162
- 'via a first-party default world today');
163
- }
164
- /**
165
- * Construct the (host-internal) Game shell. Callers: `createGameRuntime`
166
- * builds this BEFORE mounting its one adapter, then registers the default
167
- * threejs world once mount resolves (see `registerThreeWorld` in
168
- * `create-runtime.ts`).
169
- */
170
- export function createGame(opts) {
171
- const roots = [];
172
- const profiler = createPerformanceProfiler();
173
- const systems = createSystemRunner(profiler.systemObserver, 'game');
174
- const stateBridge = createStateBridge();
175
- // D15 (T-D15.1) — the game-scoped seeded-random surface every world's
176
- // `ctx.random` aliases (see `vgai-scene-game-adapter.ts`'s `ctx.random =
177
- // ...`, wired the same way `ctx.debug` is just below). Constructed
178
- // unconditionally (cheap — a handful of closures) regardless of whether
179
- // this project ever declares `determinism.seededRandom`; only the BOOT
180
- // SEED and the enforcement (the burn-down scan, the trap right below) are
181
- // conditional on that declaration.
182
- const seededRandom = createSeededRandom(opts.seed ?? DEFAULT_SEEDED_RANDOM_SEED);
183
- // D15 (T-D15.3) — the dev-mode `Math.random` phase trap. Constructed
184
- // unconditionally too (disabled by default: `rngTrapEnabled` starts
185
- // `false`, so `runFrameImpl`'s enable/disable calls below are no-ops) —
186
- // the manifest-aware boot path flips `rngTrapControl.setEnabled(true)`
187
- // once it resolves `manifest.determinism?.seededRandom` (mirrors
188
- // `debugRegistry.setRoomDeclared` being flipped post-hoc from the same
189
- // boot path for the very same "only the caller who read the manifest
190
- // knows" reason).
191
- const rngTrap = createGameplayRngTrap();
192
- let rngTrapEnabled = false;
193
- const rngTrapControl = {
194
- setEnabled(enabled) {
195
- rngTrapEnabled = enabled;
196
- },
197
- get enabled() {
198
- return rngTrapEnabled;
199
- },
200
- };
201
- // T1.2 (docs/SYNTHETIC-PLAYER-SPEC.md §3.1/§3.3): `tick` counts completed
202
- // fixed substeps, `simT` accumulates their `dt` — both game-scoped, bumped
203
- // ONLY where `stateBridge.bump()` is (guarded by `advanced`, `runFrame`'s
204
- // tail below), so a paused/frozen frame never advances either. The debug
205
- // registry reads them via suppliers (not by capturing the numbers now)
206
- // so its built-in `time` provider always sees the CURRENT values.
207
- let tick = 0;
208
- let simT = 0;
209
- const debugRegistry = createDebugRegistry({
210
- getTick: () => tick,
211
- getSimT: () => simT,
212
- // D15/T-D15.5 — "the manifest's first/default world" for the per-world
213
- // input-target resolution (`resolveInputWorldId`, `debug-registry.ts`):
214
- // the SAME "first threejs world, else first world" rule
215
- // `requireDefaultWorld` (declared just below — safe: this closure is
216
- // only ever CALLED later, once at least one world has mounted) already
217
- // defines for `Game.defaultWorld`/`Game.input` — so the debug bridge and
218
- // the editor relay resolve the exact same world `Game.input` would.
219
- getDefaultWorldId: () => (roots.length > 0 ? requireDefaultWorld().id : null),
220
- // Issue #175 — the built-in `time` provider's `loopLiveness` field reads
221
- // the REAL loop, not any UI-level play-state store: `opts.loop` is the
222
- // SAME `GameLoop` this `Game`'s own `.loop` field exposes, so this
223
- // registry can never disagree with `game.loop.liveness` about whether
224
- // the loop is actually ticking.
225
- getLoopLiveness: () => opts.loop.liveness,
226
- });
227
- function requireDefaultWorld() {
228
- if (roots.length === 0) {
229
- throw new Error('Game.defaultWorld: no roots registered yet');
230
- }
231
- return roots.find((w) => w.kind === 'threejs') ?? roots[0];
232
- }
233
- function requireFirstPartyCtx(handle) {
234
- const world = requireDefaultWorld();
235
- if (!isFirstPartyMounted(world.mounted)) {
236
- throw new Error(describeMismatch(handle, world));
237
- }
238
- return world.mounted.ctx;
239
- }
240
- // --- Game.systemAdapters aggregation (§7.1-3, probe1) --------------------
241
- // Warn-once-per-colliding-key state, scoped to this Game instance (a fresh
242
- // Game gets a fresh warn history) — deliberately NOT reset by anything
243
- // short of a new `createGame` call, matching `reportedGateShortfalls`
244
- // above's "once per game instance" idiom.
245
- const warnedSystemAdapterKeys = new Set();
246
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one cohesive merge-with-collision-report walk (per-world × per-key); splitting the collision-warn branch out would obscure that it's part of the same pass, not reduce real complexity
247
- function computeSystemAdapters() {
248
- // Debug is game-scoped: React hooks, probes, and the built-in time
249
- // provider all register with the one registry created above, regardless
250
- // of whether any mounted root happens to expose a `systems` object. A
251
- // root may still publish this SAME adapter (the first-party Three/Pixi
252
- // mounts do); the reference-equality branch below treats that as the
253
- // intentional shared registration it is.
254
- const result = { debug: debugRegistry.adapter };
255
- const ownerWorldId = new Map([['debug', '(game)']]);
256
- for (const world of roots) {
257
- const adapters = world.mounted.systems;
258
- if (!adapters)
259
- continue;
260
- for (const key of Object.keys(adapters)) {
261
- if (adapters[key] === undefined)
262
- continue;
263
- const existingOwner = ownerWorldId.get(key);
264
- if (existingOwner !== undefined) {
265
- // Reference-equality short-circuit: two roots sharing the ONE
266
- // game-scoped debug registry's adapter (T1.1) both expose the SAME
267
- // object under `systems.debug` — that is by design, not a
268
- // collision, so it must never warn.
269
- if (result[key] === adapters[key])
270
- continue;
271
- if (!warnedSystemAdapterKeys.has(key)) {
272
- warnedSystemAdapterKeys.add(key);
273
- // biome-ignore lint/suspicious/noConsole: structured, greppable — mirrors this file's own reportGateShortfallOnce's deliberate direct console.warn just above
274
- console.warn(`[game] systemAdapters: "${key}" is registered by both world "${existingOwner}" and ` +
275
- `world "${world.id}" — the FIRST registration ("${existingOwner}") wins; the later ` +
276
- 'one is shadowed (docs/GAME-ROOT-DESIGN.md §3: game-scoped system adapters).');
277
- }
278
- continue;
279
- }
280
- // biome-ignore lint/suspicious/noExplicitAny: SystemAdapters is a plain optional-field record; the per-key copy is correct by construction (same key on both sides), just not expressible without a cast
281
- result[key] = adapters[key];
282
- ownerWorldId.set(key, world.id);
283
- }
284
- }
285
- return result;
286
- }
287
- // --- D10/T7.6 play-state (Game.play) -------------------------------------
288
- let paused = false;
289
- // Dedupe loop-gate/audio-gate shortfall warnings to ONCE per (world, kind)
290
- // — `pause()` fans out over every world every call; without this a
291
- // multi-second play session would re-log the same "can't gate" shortfall
292
- // every time the user hits Pause.
293
- const reportedGateShortfalls = new Set();
294
- function reportGateShortfallOnce(kind, worldId, reason) {
295
- const key = `${kind}:${worldId}`;
296
- if (reportedGateShortfalls.has(key))
297
- return;
298
- reportedGateShortfalls.add(key);
299
- const message = kind === 'loop'
300
- ? formatLoopGateMessage({ worldId, reason })
301
- : formatAudioGateMessage({ worldId, reason });
302
- // Other native `console.warn`/`console.error` call sites in this file are
303
- // unsuppressed and already counted in the lint baseline (see `runFrame`'s
304
- // impl below); this one is a NEW site, so it's suppressed to keep this
305
- // task's diff at zero NEW warnings (same reasoning as `overlay-report.ts`'s
306
- // identical suppression).
307
- // biome-ignore lint/suspicious/noConsole: see comment above
308
- console.warn(message);
309
- }
310
- /** Fan out a loop-gate (self-driven roots) + audio-gate call over every
311
- * `pausable` world, reporting honestly (once) wherever the capability is
312
- * absent — shared by `pause()`/`resume()` below (same fan-out, opposite
313
- * boolean). */
314
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: fans out TWO independent capability gates (loop, audio) with the same "call it, else report once" shape per world — splitting the two gates into separate loops would duplicate the fan-out, not reduce real complexity
315
- function setWorldGates(next) {
316
- for (const world of roots) {
317
- if (!world.pausable)
318
- continue; // pausable:false roots are untouched by design
319
- if (world.mounted.drivesOwnLoop) {
320
- if (world.mounted.setPaused) {
321
- world.mounted.setPaused(next);
322
- }
323
- else if (next) {
324
- reportGateShortfallOnce('loop', world.id, 'self-driven world, adapter declares no setPaused capability');
325
- }
326
- }
327
- const audio = world.mounted.systems?.audio;
328
- if (audio) {
329
- audio.setMuted(next);
330
- }
331
- else if (next) {
332
- reportGateShortfallOnce('audio', world.id, 'no SystemAdapters.audio on this world');
333
- }
334
- }
335
- }
336
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: the frame algorithm (GAME-ROOT-DESIGN §4, now with D10's per-world pause gate + the onlyFrozen step()-only mode) is one cohesive nested loop over phases/roots — splitting it would obscure the ordering contract documented on GameInternal.runFrame
337
- function runFrameImpl(dt, frameOpts) {
338
- // D15 (T-D15.3) — brackets the ENTIRE frame body (every phase, every
339
- // world, both the `onlyFrozen` and normal branches below converge on the
340
- // single `profiler.endFrame()` at the tail) with zero reordering of the
341
- // phase algorithm itself — a no-op pair of calls while
342
- // `rngTrapEnabled` is false (the common case: most projects never
343
- // declare `determinism.seededRandom`).
344
- if (rngTrapEnabled)
345
- rngTrap.enable();
346
- profiler.beginFrame();
347
- const ignorePause = frameOpts?.ignorePause ?? false;
348
- // D15/T-D15.4: internal-only render-phase skip (not part of the public
349
- // `GameInternal.runFrame` signature — no external caller sets it, mirroring
350
- // `onlyFrozen` below) — `runTicks`'s `render: 'none'|'last'` fast-forward
351
- // mode sets this on every tick it doesn't want to paint. See `runTicks`'s
352
- // doc comment on `GameInternal` for the full contract.
353
- const skipRenderPhases = frameOpts?.skipRenderPhases ?? false;
354
- // `onlyFrozen` is internal-only (not part of the public `GameInternal.runFrame`
355
- // signature — no external caller sets it) — `Game.play.step()` below is the
356
- // one and only caller. It ticks EXACTLY the currently-frozen set (host-driven,
357
- // `pausable`, and `paused`) through every phase + `endFrame`, with the REAL
358
- // `dt` (not the render-phase's forced `0`), and touches no other world at all
359
- // — §7.1-2 fix, probe4: the previous `ignorePause` full-frame re-run ticked
360
- // EVERY host-driven world, double-ticking every already-running
361
- // `pausable: false` world (D10's ordinary loop never stops ticking them).
362
- const onlyFrozen = frameOpts?.onlyFrozen ?? false;
363
- // Checklist item 7: snapshot the world count ONCE at entry and iterate
364
- // by index in both loops below. A world registered mid-frame (e.g. from
365
- // a game-scoped system's side effect) joins at the NEXT `runFrame` call,
366
- // not this one — `for (const world of roots)` would otherwise pick up
367
- // a world pushed during this very frame. This also drops the two
368
- // per-phase `for...of` iterator allocations.
369
- const n = roots.length;
370
- // §7.1-11 fix (probe5): `stateBridge.bump()` must fire iff at least one
371
- // world actually advanced this call — not unconditionally. `advanced`
372
- // covers rule (a) below (host-driven roots this call actually ticked);
373
- // rule (b): a self-driven world that is RUNNING — which is every
374
- // self-driven world while not paused, and, while paused, the ones the
375
- // gate can't reach (`pausable: false`, or no `setPaused` capability) —
376
- // checked once, up front, over the same `roots` array (no extra
377
- // allocation, matching every other loop here). Rule (b) is skipped in
378
- // `onlyFrozen` mode: a `step()` call bumps iff it ticked a frozen world
379
- // — self-driven notifications belong to the loop's own `runFrame`s.
380
- let advanced = false;
381
- if (!onlyFrozen) {
382
- for (let i = 0; i < n; i++) {
383
- const world = roots[i];
384
- if (!world.mounted.drivesOwnLoop)
385
- continue;
386
- if (!paused || !world.pausable || !world.mounted.setPaused) {
387
- advanced = true;
388
- break;
389
- }
390
- }
391
- }
392
- if (onlyFrozen) {
393
- // step(): the frozen set is host-driven + pausable + currently paused.
394
- // While NOT paused this set is empty by construction, so this whole
395
- // branch is a natural no-op — `Game.play.step()`'s "no-op while
396
- // running" behavior falls straight out of this, no separate guard
397
- // needed.
398
- for (const phase of PHASE_ORDER) {
399
- profiler.beginPhase();
400
- for (let i = 0; i < n; i++) {
401
- const world = roots[i];
402
- if (world.mounted.drivesOwnLoop)
403
- continue;
404
- if (!(paused && world.pausable))
405
- continue; // only the frozen set
406
- try {
407
- world.frame?.runPhase(phase, dt);
408
- }
409
- catch (err) {
410
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) runPhase("${phase}") threw ` +
411
- '(step()):', err);
412
- }
413
- }
414
- profiler.endPhase(phase);
415
- }
416
- for (let i = 0; i < n; i++) {
417
- const world = roots[i];
418
- if (world.mounted.drivesOwnLoop)
419
- continue;
420
- if (!(paused && world.pausable))
421
- continue;
422
- advanced = true;
423
- if (world.frame) {
424
- try {
425
- world.frame.endFrame?.();
426
- }
427
- catch (err) {
428
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) endFrame() threw (step()):`, err);
429
- }
430
- }
431
- else {
432
- try {
433
- world.mounted.update?.(dt);
434
- }
435
- catch (err) {
436
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) update() threw (step()):`, err);
437
- }
438
- }
439
- }
440
- }
441
- else {
442
- for (const phase of PHASE_ORDER) {
443
- profiler.beginPhase();
444
- // D15/T-D15.4: `runTicks`'s fast-forward skip — `preRender`/`render`
445
- // are the ONLY phases ever skipped this way (every earlier gameplay
446
- // phase, and `endFrame` below, always run) — see `skipRenderPhases`'s
447
- // declaration above and `runTicks`'s doc comment on `GameInternal`.
448
- const skipThisPhase = skipRenderPhases && (phase === SystemPhase.PRE_RENDER || phase === SystemPhase.RENDER);
449
- if (!skipThisPhase) {
450
- systems.runPhase(phase, dt);
451
- for (let i = 0; i < n; i++) {
452
- const world = roots[i];
453
- if (world.mounted.drivesOwnLoop)
454
- continue;
455
- // D10/T7.6: a `pausable` world under an active (non-ignored) pause
456
- // skips every phase except `render` — its render still runs, every
457
- // substep, but with `dt` forced to `0` (deterministic: no
458
- // time-based render effect silently keeps animating a "frozen"
459
- // scene). A `pausable: false` world (or any world while
460
- // `ignorePause`) is unaffected.
461
- const frozen = !ignorePause && paused && world.pausable;
462
- if (frozen && phase !== SystemPhase.RENDER)
463
- continue;
464
- const phaseDt = frozen ? 0 : dt;
465
- // Checklist item 2: isolate each world's per-phase work — one
466
- // world's `runPhase` throwing must not starve sibling roots still
467
- // due this phase, nor abort the frame. Mirrors `runOne`'s style in
468
- // `core/system-runner.ts` (loud console.error, never swallowed).
469
- try {
470
- world.frame?.runPhase(phase, phaseDt);
471
- }
472
- catch (err) {
473
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) runPhase("${phase}") threw:`, err);
474
- }
475
- }
476
- }
477
- profiler.endPhase(phase);
478
- }
479
- for (let i = 0; i < n; i++) {
480
- const world = roots[i];
481
- if (world.mounted.drivesOwnLoop)
482
- continue;
483
- // A fully-frozen world gets no `endFrame`/opaque-`update` call either —
484
- // there is nothing to "end the frame" of when nothing ran this substep.
485
- const frozen = !ignorePause && paused && world.pausable;
486
- if (frozen)
487
- continue;
488
- advanced = true;
489
- if (world.frame) {
490
- try {
491
- world.frame.endFrame?.();
492
- }
493
- catch (err) {
494
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) endFrame() threw:`, err);
495
- }
496
- }
497
- else {
498
- // Checklist item 2: same isolation for the opaque-world fallback —
499
- // one foreign mount's `update` throwing must not starve its
500
- // siblings' `endFrame`/`update` calls this same loop.
501
- try {
502
- world.mounted.update?.(dt);
503
- }
504
- catch (err) {
505
- console.error(`[game] world "${world.id}" (kind: ${world.kind}) update() threw:`, err);
506
- }
507
- }
508
- }
509
- }
510
- // T7.4 slice 1 (REACT-STATE-BRIDGE.md §2): bump + notify LAST, after
511
- // every phase of every world and every world's endFrame/update above —
512
- // subscribers must only ever observe post-frame state. Bumped at most
513
- // once per completed `runFrame`/`step()` call, never per phase/world —
514
- // and, per §7.1-11's fix, only when `advanced` (see above) is true: a
515
- // fully-gated paused game produces no notifications at all.
516
- if (advanced) {
517
- stateBridge.bump();
518
- tick++;
519
- simT += dt;
520
- }
521
- profiler.endFrame();
522
- if (rngTrapEnabled)
523
- rngTrap.disable();
524
- }
525
- const gameInternal = {
526
- loop: opts.loop,
527
- assets: opts.assets,
528
- profiler,
529
- systems,
530
- get roots() {
531
- return roots;
532
- },
533
- world(id) {
534
- return roots.find((w) => w.id === id) ?? null;
535
- },
536
- get defaultWorld() {
537
- return requireDefaultWorld();
538
- },
539
- get systemAdapters() {
540
- return computeSystemAdapters();
541
- },
542
- get components() {
543
- return requireFirstPartyCtx('components').components;
544
- },
545
- get input() {
546
- return requireFirstPartyCtx('input').input;
547
- },
548
- get audio() {
549
- return requireFirstPartyCtx('audio').audio;
550
- },
551
- state: stateBridge,
552
- play: {
553
- get paused() {
554
- return paused;
555
- },
556
- pause() {
557
- if (paused)
558
- return;
559
- paused = true;
560
- setWorldGates(true);
561
- },
562
- resume() {
563
- if (!paused)
564
- return;
565
- paused = false;
566
- setWorldGates(false);
567
- },
568
- step(dt = 1 / 60) {
569
- // Self-driven pausable roots advance via their adapter's `step()`
570
- // capability — but only the ones that are actually FROZEN: the game
571
- // must be paused, and the world must have been gate-able in the
572
- // first place (`setPaused` present — a world the gate couldn't reach
573
- // never stopped, so "stepping" it would double-tick a still-running
574
- // loop, the same §7.1-2 class as the host-driven fix below). While
575
- // not paused, nothing here runs — step() is a whole-call no-op.
576
- if (paused) {
577
- for (const world of roots) {
578
- if (!world.pausable || !world.mounted.drivesOwnLoop)
579
- continue;
580
- if (!world.mounted.setPaused)
581
- continue; // never gated — still running
582
- if (world.mounted.step) {
583
- world.mounted.step();
584
- }
585
- else {
586
- reportGateShortfallOnce('loop', world.id, 'self-driven world, adapter declares no step capability');
587
- }
588
- }
589
- }
590
- // §7.1-2 fix (probe4): tick EXACTLY the frozen (host-driven, pausable,
591
- // paused) set — not `{ ignorePause: true }`, which re-ran a FULL
592
- // extra frame for every host-driven world (including already-running
593
- // `pausable: false` ones — a double-tick, since D10's ordinary loop
594
- // never stops ticking them). See `runFrameImpl`'s `onlyFrozen` mode.
595
- runFrameImpl(dt, { onlyFrozen: true });
596
- },
597
- },
598
- queryByComponent(cls, opts) {
599
- // Checklist item 8a: a `worldId` naming a world that doesn't exist is a
600
- // caller error (typo'd id, wrong manifest) — degrade loudly, matching
601
- // repo habit, rather than silently returning `[]`. A worldId that DOES
602
- // exist but isn't first-party legitimately answers "no components"
603
- // below (the loop's `!isFirstPartyMounted` `continue`), which stays
604
- // silent — that's a real, not a mistaken, empty result.
605
- if (opts?.worldId !== undefined && !roots.some((w) => w.id === opts.worldId)) {
606
- throw new Error(`Game.queryByComponent: unknown worldId "${opts.worldId}"`);
607
- }
608
- const result = [];
609
- for (const world of roots) {
610
- if (!isFirstPartyMounted(world.mounted))
611
- continue;
612
- if (opts?.worldId !== undefined && world.id !== opts.worldId)
613
- continue;
614
- if (opts?.kind !== undefined && world.kind !== opts.kind)
615
- continue;
616
- // Checklist item 8b: a plain for-loop push instead of
617
- // `result.push(...arr)` — spread-as-arguments can hit engine/runtime
618
- // argument-count limits once a world's instance count gets large.
619
- const instances = world.mounted.ctx.components.queryByComponent(cls);
620
- for (const inst of instances)
621
- result.push(inst);
622
- }
623
- return result;
624
- },
625
- registerWorld(world) {
626
- if (roots.some((w) => w.id === world.id)) {
627
- throw new Error(`Game.registerWorld: duplicate world id "${world.id}"`);
628
- }
629
- // Checklist item 6: the SAME `mounted` object registered under two
630
- // world ids would be double-ticked by `runFrame` (its `frame.runPhase`/
631
- // `endFrame` called once per registration) and double-dispose-wrapped
632
- // (`createWorldInstance` wraps `mounted.dispose` in place — a second
633
- // wrap would flip `disposed` and call through on ITS OWN wrapped
634
- // `originalDispose`, which is harmless today only by accident of
635
- // `VgaiSceneGameAdapter.dispose` being idempotent; a foreign adapter
636
- // has no such guarantee). Reject it outright instead.
637
- if (roots.some((w) => w.mounted === world.mounted)) {
638
- throw new Error(`Game.registerWorld: world "${world.id}" shares its \`mounted\` object with an ` +
639
- `already-registered world ("${roots.find((w) => w.mounted === world.mounted).id}") — ` +
640
- 'the same mount cannot be registered twice.');
641
- }
642
- roots.push(world);
643
- // Notify state-bridge subscribers THE INSTANT the world list changes —
644
- // not just at the next completed `runFrame`. Root-cause fix for the
645
- // "roots: " (empty) hang in `36-r3f-first-party.spec.ts` on CI
646
- // (docs/R3F-FIRST-PARTY-DESIGN.md W3, gate 4): `mountAllWorldSpecs`
647
- // (`create-runtime.ts`) mounts roots SEQUENTIALLY, and a react world's
648
- // `adapter.mount()` (`resolveDefaultReactAdapter`/`mountOneReactWorld`)
649
- // renders its tree — synchronously in some React builds, but React 19's
650
- // concurrent renderer does NOT guarantee a synchronous first commit
651
- // (see `r3f-adapter.tsx`'s own doc comment on `onCreated`) — BEFORE the
652
- // caller calls `registerWorld` for that very world. A `useGameState`
653
- // selector reading `g.roots` can therefore render for the first time
654
- // while `roots` is still missing entries that register moments later.
655
- // Previously the ONLY way such a subscriber ever saw the corrected
656
- // value was the state bridge's next `bump()`, which fires exclusively
657
- // from `GameInternal.runFrame`'s tail — i.e. only once the host's loop
658
- // has actually ticked (`started = true; loop.start()` in
659
- // `create-runtime.ts`, itself gated on EVERY world finishing its
660
- // mount). On a slow/contended host (CI's 4-core SwiftShader runners)
661
- // that first tick can be delayed well past a test's assertion window,
662
- // or — if the tab is ever backgrounded — not fire at all for a long
663
- // stretch; the subscriber's cached snapshot then sits on its stale
664
- // (possibly fully empty) first render for that whole time, matching
665
- // the observed CI symptom exactly ("the HUD element IS mounted; the
666
- // roots list is EMPTY"). Proven red-then-green by
667
- // `packages/engine/test/state-bridge.test.ts`'s "registerWorld notifies
668
- // subscribers immediately" case: a subscriber registered before a
669
- // world, with `runFrame` NEVER called, only saw the update after this
670
- // fix. `bump()` also advances `frameVersion` (the only invalidation
671
- // key `createFrameSelectorCache`/`useGameState` understand — see
672
- // `frame-selector-cache.ts`), so this doubles as "frameVersion is
673
- // bumped once per completed runFrame OR once per world registered",
674
- // documented on `GameStateBridge.frameVersion` below.
675
- stateBridge.bump();
676
- // T7.4 slice 2 (REACT-STATE-BRIDGE.md §4): a NON-first-party mount
677
- // (an ingested/foreign world — first-party mounts are exempt, they're
678
- // observed via `Game.state`/`useGameState` instead) with no `observe`
679
- // has no state bridge at all — react HUDs cannot subscribe to it, and
680
- // silently returning `undefined` forever would hide that. Report ONCE
681
- // per mount, at registration time, matching this file's existing
682
- // `[game] world "<id>" (kind: <kind>) ...` console idiom (see
683
- // `runFrame` below).
684
- //
685
- // §7.1-15: a `kind: 'react'` world is ALSO exempt — it has no `observe`
686
- // BY DESIGN (D8/REACT-WORLD-DESIGN.md: a react world's own mounted tree
687
- // reads state via `Game.state`/`useGameState`, the SAME first-party
688
- // bridge a threejs/pixijs world's HUD uses, never `WorldStateObserver`
689
- // — that hook is scoped to the ingested/foreign-world case). Without
690
- // this exemption every production react world logged a false-positive
691
- // "no state bridge" warning at registration (probe: every real react
692
- // world mount), eroding the signal for a genuinely un-observable
693
- // ingested world.
694
- if (!isFirstPartyMounted(world.mounted) && world.kind !== 'react' && !world.mounted.observe) {
695
- console.warn(`[game] world "${world.id}" (kind: ${world.kind}, adapter: "${world.adapter.id}"): ` +
696
- 'no state bridge — this mounted game has no `observe` (WorldStateObserver); ' +
697
- 'react HUDs/useWorldObservation cannot subscribe to its state (docs/REACT-STATE-BRIDGE.md §4).');
698
- }
699
- },
700
- runFrame(dt, frameOpts) {
701
- runFrameImpl(dt, frameOpts);
702
- },
703
- runTicks(n, ticksOpts) {
704
- if (!Number.isInteger(n) || n < 0) {
705
- throw new RangeError(`Game.runTicks: n must be a non-negative integer, got ${n}`);
706
- }
707
- // Refuse while paused (D15 §2.b): stepping the frozen set is
708
- // `Game.play.step()`'s contract, not this one's — see `runTicks`'s doc
709
- // comment on `GameInternal` above.
710
- if (paused) {
711
- throw new DebugError('RUN_TICKS_PAUSED', 'Game.runTicks: refused — Game.play.paused is true; stepping the frozen set is ' +
712
- "Game.play.step()'s contract, not runTicks' (docs/D15-DETERMINISM-DESIGN.md §2.b)");
713
- }
714
- const render = ticksOpts?.render ?? 'last';
715
- const fixedDt = opts.loop.fixedDt;
716
- for (let i = 0; i < n; i++) {
717
- const isFinalTick = i === n - 1;
718
- const skipRenderPhases = render === 'all' ? false : render === 'none' ? true : !isFinalTick;
719
- runFrameImpl(fixedDt, { skipRenderPhases });
720
- }
721
- },
722
- };
723
- // Filed AFTER the shell exists (the WeakMap keys on the Game object
724
- // itself) so `getDebugRegistry(game)` — the react hooks' and any later
725
- // consumer's reach-in — works from the moment `createGame` returns.
726
- registerDebugRegistry(gameInternal, debugRegistry);
727
- // D15/T-D15.4: wire the run-ticks target the instant the Game shell exists
728
- // (unlike `setVirtualInputTarget`, which waits for a per-world mount, a
729
- // Game's own `runTicks` needs nothing else) — this is what makes
730
- // `window.__vgai.runTicks` (`debug-bridge.ts`) and the editor relay's
731
- // `run-ticks` case reach the SAME implementation `game.runTicks` above is.
732
- debugRegistry.setRunTicksTarget({ runTicks: gameInternal.runTicks });
733
- // D15 (T-D15.1/.3) — same "file after the shell exists" ordering as the
734
- // debug registry above: `getSeededRandom(game)`/`getGameplayRngTrapControl
735
- // (game)` (per-world `ctx.random` wiring, and the manifest-aware boot
736
- // path's post-hoc `setEnabled` call) both work from the moment
737
- // `createGame` returns.
738
- registerSeededRandom(gameInternal, seededRandom);
739
- registerGameplayRngTrapControl(gameInternal, rngTrapControl);
740
- return gameInternal;
741
- }