@vgai/engine 0.5.5 → 0.5.7

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 (446) hide show
  1. package/dist/adapter/adapter-surface.d.ts +30 -0
  2. package/dist/adapter/adapter-surface.d.ts.map +1 -0
  3. package/dist/adapter/adapter-surface.js +18 -0
  4. package/dist/adapter/authoring.d.ts +597 -0
  5. package/dist/adapter/authoring.d.ts.map +1 -0
  6. package/dist/adapter/authoring.js +22 -0
  7. package/dist/adapter/colyseus-networking-adapter.d.ts +77 -0
  8. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
  9. package/dist/adapter/colyseus-networking-adapter.js +76 -0
  10. package/dist/adapter/first-party-systems.d.ts +23 -0
  11. package/dist/adapter/first-party-systems.d.ts.map +1 -0
  12. package/dist/adapter/first-party-systems.js +196 -0
  13. package/dist/adapter/host-context.d.ts +194 -0
  14. package/dist/adapter/host-context.d.ts.map +1 -0
  15. package/dist/adapter/host-context.js +80 -0
  16. package/dist/adapter/index.d.ts +33 -0
  17. package/dist/adapter/index.d.ts.map +1 -0
  18. package/dist/adapter/index.js +25 -0
  19. package/dist/adapter/ingest/game-contract.d.ts +53 -0
  20. package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
  21. package/dist/adapter/ingest/game-contract.js +30 -0
  22. package/dist/adapter/ingest/scene-capture.d.ts +121 -0
  23. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
  24. package/dist/adapter/ingest/scene-capture.js +270 -0
  25. package/dist/adapter/ingest/structural-ids.d.ts +64 -0
  26. package/dist/adapter/ingest/structural-ids.d.ts.map +1 -0
  27. package/dist/adapter/ingest/structural-ids.js +110 -0
  28. package/dist/adapter/ingest/upstream-pin.d.ts +44 -0
  29. package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
  30. package/dist/adapter/ingest/upstream-pin.js +47 -0
  31. package/dist/adapter/loop-gate-report.d.ts +34 -0
  32. package/dist/adapter/loop-gate-report.d.ts.map +1 -0
  33. package/dist/adapter/loop-gate-report.js +37 -0
  34. package/dist/adapter/rapier-physics-adapter.d.ts +69 -0
  35. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
  36. package/dist/adapter/rapier-physics-adapter.js +135 -0
  37. package/dist/adapter/root-adapter.d.ts +195 -0
  38. package/dist/adapter/root-adapter.d.ts.map +1 -0
  39. package/dist/adapter/root-adapter.js +25 -0
  40. package/dist/adapter/setup-three-root-adapter.d.ts +87 -0
  41. package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -0
  42. package/dist/adapter/setup-three-root-adapter.js +791 -0
  43. package/dist/adapter/system-adapter.d.ts +453 -0
  44. package/dist/adapter/system-adapter.d.ts.map +1 -0
  45. package/dist/adapter/system-adapter.js +13 -0
  46. package/dist/adapter/transform.d.ts +18 -0
  47. package/dist/adapter/transform.d.ts.map +1 -0
  48. package/dist/adapter/transform.js +1 -0
  49. package/dist/ai/navigation.d.ts +78 -0
  50. package/dist/ai/navigation.d.ts.map +1 -0
  51. package/dist/ai/navigation.js +152 -0
  52. package/dist/animation/anim-graph-types.d.ts +25 -0
  53. package/dist/animation/anim-graph-types.d.ts.map +1 -0
  54. package/dist/animation/anim-graph-types.js +1 -0
  55. package/dist/animation/animation-clock.d.ts +213 -0
  56. package/dist/animation/animation-clock.d.ts.map +1 -0
  57. package/dist/animation/animation-clock.js +301 -0
  58. package/dist/animation/blend-node.d.ts +22 -0
  59. package/dist/animation/blend-node.d.ts.map +1 -0
  60. package/dist/animation/blend-node.js +97 -0
  61. package/dist/animation/camera-ownership.d.ts +249 -0
  62. package/dist/animation/camera-ownership.d.ts.map +1 -0
  63. package/dist/animation/camera-ownership.js +169 -0
  64. package/dist/animation/cinematic-cues.d.ts +200 -0
  65. package/dist/animation/cinematic-cues.d.ts.map +1 -0
  66. package/dist/animation/cinematic-cues.js +213 -0
  67. package/dist/animation/clip-map.d.ts +12 -0
  68. package/dist/animation/clip-map.d.ts.map +1 -0
  69. package/dist/animation/clip-map.js +31 -0
  70. package/dist/animation/cubic-spline-interpolant.d.ts +54 -0
  71. package/dist/animation/cubic-spline-interpolant.d.ts.map +1 -0
  72. package/dist/animation/cubic-spline-interpolant.js +111 -0
  73. package/dist/animation/theatre-clock-binding.d.ts +89 -0
  74. package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
  75. package/dist/animation/theatre-clock-binding.js +29 -0
  76. package/dist/animation/theatre-director.d.ts +277 -0
  77. package/dist/animation/theatre-director.d.ts.map +1 -0
  78. package/dist/animation/theatre-director.js +248 -0
  79. package/dist/animation/theatre-object-binding.d.ts +305 -0
  80. package/dist/animation/theatre-object-binding.d.ts.map +1 -0
  81. package/dist/animation/theatre-object-binding.js +351 -0
  82. package/dist/animation/xstate-animation-binding.d.ts +119 -0
  83. package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
  84. package/dist/animation/xstate-animation-binding.js +349 -0
  85. package/dist/animation/xstate-animation-meta.d.ts +266 -0
  86. package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
  87. package/dist/animation/xstate-animation-meta.js +252 -0
  88. package/dist/asset-formats/camera.d.ts +15 -0
  89. package/dist/asset-formats/camera.d.ts.map +1 -0
  90. package/dist/asset-formats/camera.js +15 -0
  91. package/dist/asset-formats/collider.d.ts +21 -0
  92. package/dist/asset-formats/collider.d.ts.map +1 -0
  93. package/dist/asset-formats/collider.js +53 -0
  94. package/dist/asset-formats/index.d.ts +46 -0
  95. package/dist/asset-formats/index.d.ts.map +1 -0
  96. package/dist/asset-formats/index.js +36 -0
  97. package/dist/asset-formats/instances.d.ts +17 -0
  98. package/dist/asset-formats/instances.d.ts.map +1 -0
  99. package/dist/asset-formats/instances.js +31 -0
  100. package/dist/asset-formats/light.d.ts +21 -0
  101. package/dist/asset-formats/light.d.ts.map +1 -0
  102. package/dist/asset-formats/light.js +35 -0
  103. package/dist/asset-formats/material.d.ts +129 -0
  104. package/dist/asset-formats/material.d.ts.map +1 -0
  105. package/dist/asset-formats/material.js +88 -0
  106. package/dist/asset-formats/mesh.d.ts +22 -0
  107. package/dist/asset-formats/mesh.d.ts.map +1 -0
  108. package/dist/asset-formats/mesh.js +64 -0
  109. package/dist/asset-formats/parse.d.ts +20 -0
  110. package/dist/asset-formats/parse.d.ts.map +1 -0
  111. package/dist/asset-formats/parse.js +34 -0
  112. package/dist/asset-formats/particles.d.ts +1390 -0
  113. package/dist/asset-formats/particles.d.ts.map +1 -0
  114. package/dist/asset-formats/particles.js +319 -0
  115. package/dist/asset-formats/render-env.d.ts +387 -0
  116. package/dist/asset-formats/render-env.d.ts.map +1 -0
  117. package/dist/asset-formats/render-env.js +300 -0
  118. package/dist/asset-formats/tuples.d.ts +12 -0
  119. package/dist/asset-formats/tuples.d.ts.map +1 -0
  120. package/dist/asset-formats/tuples.js +14 -0
  121. package/dist/asset-loaders.d.ts +97 -0
  122. package/dist/asset-loaders.d.ts.map +1 -0
  123. package/dist/asset-loaders.js +209 -0
  124. package/dist/asset-parse-error.d.ts +24 -0
  125. package/dist/asset-parse-error.d.ts.map +1 -0
  126. package/dist/asset-parse-error.js +29 -0
  127. package/dist/asset-registry.d.ts +38 -0
  128. package/dist/asset-registry.d.ts.map +1 -0
  129. package/dist/asset-registry.js +66 -0
  130. package/dist/assets.d.ts +26 -0
  131. package/dist/assets.d.ts.map +1 -0
  132. package/dist/assets.js +55 -0
  133. package/dist/audio/wav-encode.d.ts +38 -0
  134. package/dist/audio/wav-encode.d.ts.map +1 -0
  135. package/dist/audio/wav-encode.js +97 -0
  136. package/dist/canvas-react/engine-bridge.d.ts +45 -0
  137. package/dist/canvas-react/engine-bridge.d.ts.map +1 -0
  138. package/dist/canvas-react/engine-bridge.js +45 -0
  139. package/dist/canvas-react/index.d.ts +42 -0
  140. package/dist/canvas-react/index.d.ts.map +1 -0
  141. package/dist/canvas-react/index.js +41 -0
  142. package/dist/canvas-react/pixi-primitive.d.ts +85 -0
  143. package/dist/canvas-react/pixi-primitive.d.ts.map +1 -0
  144. package/dist/canvas-react/pixi-primitive.js +181 -0
  145. package/dist/canvas-react/pixi-react-adapter.d.ts +71 -0
  146. package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -0
  147. package/dist/canvas-react/pixi-react-adapter.js +229 -0
  148. package/dist/canvas-react/pixi-react-root-factory.d.ts +56 -0
  149. package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -0
  150. package/dist/canvas-react/pixi-react-root-factory.js +73 -0
  151. package/dist/canvas-react/world-context.d.ts +88 -0
  152. package/dist/canvas-react/world-context.d.ts.map +1 -0
  153. package/dist/canvas-react/world-context.js +212 -0
  154. package/dist/config.d.ts +9 -0
  155. package/dist/config.d.ts.map +1 -0
  156. package/dist/config.js +8 -0
  157. package/dist/core/frame-pacing.d.ts +90 -0
  158. package/dist/core/frame-pacing.d.ts.map +1 -0
  159. package/dist/core/frame-pacing.js +89 -0
  160. package/dist/core/game-loop.d.ts +62 -0
  161. package/dist/core/game-loop.d.ts.map +1 -0
  162. package/dist/core/game-loop.js +189 -0
  163. package/dist/core/seeded-random.d.ts +69 -0
  164. package/dist/core/seeded-random.d.ts.map +1 -0
  165. package/dist/core/seeded-random.js +121 -0
  166. package/dist/core/sim-clock.d.ts +199 -0
  167. package/dist/core/sim-clock.d.ts.map +1 -0
  168. package/dist/core/sim-clock.js +291 -0
  169. package/dist/core/system-runner.d.ts +96 -0
  170. package/dist/core/system-runner.d.ts.map +1 -0
  171. package/dist/core/system-runner.js +253 -0
  172. package/dist/core/types.d.ts +111 -0
  173. package/dist/core/types.d.ts.map +1 -0
  174. package/dist/core/types.js +25 -0
  175. package/dist/data/data-asset.d.ts +101 -0
  176. package/dist/data/data-asset.d.ts.map +1 -0
  177. package/dist/data/data-asset.js +122 -0
  178. package/dist/data/data-check-core.d.ts +109 -0
  179. package/dist/data/data-check-core.d.ts.map +1 -0
  180. package/dist/data/data-check-core.js +177 -0
  181. package/dist/data/data-ref.d.ts +79 -0
  182. package/dist/data/data-ref.d.ts.map +1 -0
  183. package/dist/data/data-ref.js +130 -0
  184. package/dist/data/vite-plugin-data.d.ts +79 -0
  185. package/dist/data/vite-plugin-data.d.ts.map +1 -0
  186. package/dist/data/vite-plugin-data.js +217 -0
  187. package/dist/defaults.d.ts +233 -0
  188. package/dist/defaults.d.ts.map +1 -0
  189. package/dist/defaults.js +137 -0
  190. package/dist/dev/chrome-trace.d.ts +45 -0
  191. package/dist/dev/chrome-trace.d.ts.map +1 -0
  192. package/dist/dev/chrome-trace.js +114 -0
  193. package/dist/dev/console-bridge.d.ts +22 -0
  194. package/dist/dev/console-bridge.d.ts.map +1 -0
  195. package/dist/dev/console-bridge.js +71 -0
  196. package/dist/dev/debug-draw.d.ts +24 -0
  197. package/dist/dev/debug-draw.d.ts.map +1 -0
  198. package/dist/dev/debug-draw.js +73 -0
  199. package/dist/dev/instruments.d.ts +133 -0
  200. package/dist/dev/instruments.d.ts.map +1 -0
  201. package/dist/dev/instruments.js +231 -0
  202. package/dist/dev/logger.d.ts +30 -0
  203. package/dist/dev/logger.d.ts.map +1 -0
  204. package/dist/dev/logger.js +90 -0
  205. package/dist/dev/performance-profiler.d.ts +111 -0
  206. package/dist/dev/performance-profiler.d.ts.map +1 -0
  207. package/dist/dev/performance-profiler.js +215 -0
  208. package/dist/dev/render-debug-adapter.d.ts +57 -0
  209. package/dist/dev/render-debug-adapter.d.ts.map +1 -0
  210. package/dist/dev/render-debug-adapter.js +141 -0
  211. package/dist/dev/render-memory.d.ts +53 -0
  212. package/dist/dev/render-memory.d.ts.map +1 -0
  213. package/dist/dev/render-memory.js +190 -0
  214. package/dist/dev/webgl-frame-capture.d.ts +134 -0
  215. package/dist/dev/webgl-frame-capture.d.ts.map +1 -0
  216. package/dist/dev/webgl-frame-capture.js +270 -0
  217. package/dist/dev/webgl-gpu-timer.d.ts +8 -0
  218. package/dist/dev/webgl-gpu-timer.d.ts.map +1 -0
  219. package/dist/dev/webgl-gpu-timer.js +52 -0
  220. package/dist/ecs/scene-index.d.ts +179 -0
  221. package/dist/ecs/scene-index.d.ts.map +1 -0
  222. package/dist/ecs/scene-index.js +331 -0
  223. package/dist/ecs/scene-query.d.ts +6 -0
  224. package/dist/ecs/scene-query.d.ts.map +1 -0
  225. package/dist/ecs/scene-query.js +40 -0
  226. package/dist/ecs/user-data.d.ts +193 -0
  227. package/dist/ecs/user-data.d.ts.map +1 -0
  228. package/dist/ecs/user-data.js +145 -0
  229. package/dist/index.d.ts +35 -0
  230. package/dist/index.d.ts.map +1 -0
  231. package/dist/index.js +29 -0
  232. package/dist/input/input-manager.d.ts +944 -0
  233. package/dist/input/input-manager.d.ts.map +1 -0
  234. package/dist/input/input-manager.js +2209 -0
  235. package/dist/input/input-types.d.ts +174 -0
  236. package/dist/input/input-types.d.ts.map +1 -0
  237. package/dist/input/input-types.js +1 -0
  238. package/dist/input/prompt-labels.d.ts +21 -0
  239. package/dist/input/prompt-labels.d.ts.map +1 -0
  240. package/dist/input/prompt-labels.js +121 -0
  241. package/dist/input/rebind-controller.d.ts +59 -0
  242. package/dist/input/rebind-controller.d.ts.map +1 -0
  243. package/dist/input/rebind-controller.js +85 -0
  244. package/dist/input/schema.d.ts +16 -0
  245. package/dist/input/schema.d.ts.map +1 -0
  246. package/dist/input/schema.js +228 -0
  247. package/dist/loader.d.ts +76 -0
  248. package/dist/loader.d.ts.map +1 -0
  249. package/dist/loader.js +114 -0
  250. package/dist/manifest/editor-port.d.ts +53 -0
  251. package/dist/manifest/editor-port.d.ts.map +1 -0
  252. package/dist/manifest/editor-port.js +67 -0
  253. package/dist/manifest/filename.d.ts +14 -0
  254. package/dist/manifest/filename.d.ts.map +1 -0
  255. package/dist/manifest/filename.js +43 -0
  256. package/dist/manifest/index.d.ts +6 -0
  257. package/dist/manifest/index.d.ts.map +1 -0
  258. package/dist/manifest/index.js +9 -0
  259. package/dist/manifest/load-file.d.ts +7 -0
  260. package/dist/manifest/load-file.d.ts.map +1 -0
  261. package/dist/manifest/load-file.js +23 -0
  262. package/dist/manifest/load.d.ts +161 -0
  263. package/dist/manifest/load.d.ts.map +1 -0
  264. package/dist/manifest/load.js +269 -0
  265. package/dist/manifest/locate.d.ts +24 -0
  266. package/dist/manifest/locate.d.ts.map +1 -0
  267. package/dist/manifest/locate.js +48 -0
  268. package/dist/manifest/schema.d.ts +293 -0
  269. package/dist/manifest/schema.d.ts.map +1 -0
  270. package/dist/manifest/schema.js +633 -0
  271. package/dist/physics/collider-dimensions.d.ts +63 -0
  272. package/dist/physics/collider-dimensions.d.ts.map +1 -0
  273. package/dist/physics/collider-dimensions.js +98 -0
  274. package/dist/physics/collision-system.d.ts +41 -0
  275. package/dist/physics/collision-system.d.ts.map +1 -0
  276. package/dist/physics/collision-system.js +64 -0
  277. package/dist/physics/physics-registry.d.ts +45 -0
  278. package/dist/physics/physics-registry.d.ts.map +1 -0
  279. package/dist/physics/physics-registry.js +65 -0
  280. package/dist/physics/transform-writer.d.ts +16 -0
  281. package/dist/physics/transform-writer.d.ts.map +1 -0
  282. package/dist/physics/transform-writer.js +38 -0
  283. package/dist/pixi/authoring.d.ts +93 -0
  284. package/dist/pixi/authoring.d.ts.map +1 -0
  285. package/dist/pixi/authoring.js +207 -0
  286. package/dist/pixi/index.d.ts +16 -0
  287. package/dist/pixi/index.d.ts.map +1 -0
  288. package/dist/pixi/index.js +15 -0
  289. package/dist/pixi/ingest-iframe.d.ts +82 -0
  290. package/dist/pixi/ingest-iframe.d.ts.map +1 -0
  291. package/dist/pixi/ingest-iframe.js +166 -0
  292. package/dist/pixi/ingest.d.ts +97 -0
  293. package/dist/pixi/ingest.d.ts.map +1 -0
  294. package/dist/pixi/ingest.js +40 -0
  295. package/dist/pixi/physics-registry.d.ts +24 -0
  296. package/dist/pixi/physics-registry.d.ts.map +1 -0
  297. package/dist/pixi/physics-registry.js +38 -0
  298. package/dist/pixi/scene-capture.d.ts +43 -0
  299. package/dist/pixi/scene-capture.d.ts.map +1 -0
  300. package/dist/pixi/scene-capture.js +92 -0
  301. package/dist/pixi/system-adapters.d.ts +16 -0
  302. package/dist/pixi/system-adapters.d.ts.map +1 -0
  303. package/dist/pixi/system-adapters.js +37 -0
  304. package/dist/react/unmanaged-root-detector.d.ts +18 -0
  305. package/dist/react/unmanaged-root-detector.d.ts.map +1 -0
  306. package/dist/react/unmanaged-root-detector.js +70 -0
  307. package/dist/react/use-data.d.ts +60 -0
  308. package/dist/react/use-data.d.ts.map +1 -0
  309. package/dist/react/use-data.js +101 -0
  310. package/dist/react/use-selection.d.ts +54 -0
  311. package/dist/react/use-selection.d.ts.map +1 -0
  312. package/dist/react/use-selection.js +71 -0
  313. package/dist/react/world-state.d.ts +154 -0
  314. package/dist/react/world-state.d.ts.map +1 -0
  315. package/dist/react/world-state.js +220 -0
  316. package/dist/render/auto-batcher.d.ts +34 -0
  317. package/dist/render/auto-batcher.d.ts.map +1 -0
  318. package/dist/render/auto-batcher.js +140 -0
  319. package/dist/render/instance-mesh.d.ts +5 -0
  320. package/dist/render/instance-mesh.d.ts.map +1 -0
  321. package/dist/render/instance-mesh.js +19 -0
  322. package/dist/render/light-camera-factory.d.ts +24 -0
  323. package/dist/render/light-camera-factory.d.ts.map +1 -0
  324. package/dist/render/light-camera-factory.js +71 -0
  325. package/dist/render/lod.d.ts +13 -0
  326. package/dist/render/lod.d.ts.map +1 -0
  327. package/dist/render/lod.js +16 -0
  328. package/dist/render/material-factory.d.ts +15 -0
  329. package/dist/render/material-factory.d.ts.map +1 -0
  330. package/dist/render/material-factory.js +186 -0
  331. package/dist/render/mesh-shadow.d.ts +11 -0
  332. package/dist/render/mesh-shadow.d.ts.map +1 -0
  333. package/dist/render/mesh-shadow.js +19 -0
  334. package/dist/render/particles-factory.d.ts +99 -0
  335. package/dist/render/particles-factory.d.ts.map +1 -0
  336. package/dist/render/particles-factory.js +361 -0
  337. package/dist/render/render-batch-system.d.ts +33 -0
  338. package/dist/render/render-batch-system.d.ts.map +1 -0
  339. package/dist/render/render-batch-system.js +223 -0
  340. package/dist/render/render-features.d.ts +47 -0
  341. package/dist/render/render-features.d.ts.map +1 -0
  342. package/dist/render/render-features.js +105 -0
  343. package/dist/render/render-settings.d.ts +35 -0
  344. package/dist/render/render-settings.d.ts.map +1 -0
  345. package/dist/render/render-settings.js +51 -0
  346. package/dist/render/spark-renderer-lifecycle.d.ts +18 -0
  347. package/dist/render/spark-renderer-lifecycle.d.ts.map +1 -0
  348. package/dist/render/spark-renderer-lifecycle.js +57 -0
  349. package/dist/render/viewport-shading.d.ts +17 -0
  350. package/dist/render/viewport-shading.d.ts.map +1 -0
  351. package/dist/render/viewport-shading.js +87 -0
  352. package/dist/runtime/create-runtime.d.ts +259 -0
  353. package/dist/runtime/create-runtime.d.ts.map +1 -0
  354. package/dist/runtime/create-runtime.js +666 -0
  355. package/dist/runtime/debug-bridge.d.ts +288 -0
  356. package/dist/runtime/debug-bridge.d.ts.map +1 -0
  357. package/dist/runtime/debug-bridge.js +277 -0
  358. package/dist/runtime/debug-registry.d.ts +287 -0
  359. package/dist/runtime/debug-registry.d.ts.map +1 -0
  360. package/dist/runtime/debug-registry.js +528 -0
  361. package/dist/runtime/dev-layers.d.ts +34 -0
  362. package/dist/runtime/dev-layers.d.ts.map +1 -0
  363. package/dist/runtime/dev-layers.js +40 -0
  364. package/dist/runtime/frame-selector-cache.d.ts +41 -0
  365. package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
  366. package/dist/runtime/frame-selector-cache.js +65 -0
  367. package/dist/runtime/game.d.ts +576 -0
  368. package/dist/runtime/game.d.ts.map +1 -0
  369. package/dist/runtime/game.js +1003 -0
  370. package/dist/runtime/gameplay-rng-trap.d.ts +47 -0
  371. package/dist/runtime/gameplay-rng-trap.d.ts.map +1 -0
  372. package/dist/runtime/gameplay-rng-trap.js +95 -0
  373. package/dist/runtime/input-router.d.ts +78 -0
  374. package/dist/runtime/input-router.d.ts.map +1 -0
  375. package/dist/runtime/input-router.js +171 -0
  376. package/dist/runtime/mount-game.d.ts +126 -0
  377. package/dist/runtime/mount-game.d.ts.map +1 -0
  378. package/dist/runtime/mount-game.js +159 -0
  379. package/dist/runtime/mount-manifest.d.ts +174 -0
  380. package/dist/runtime/mount-manifest.d.ts.map +1 -0
  381. package/dist/runtime/mount-manifest.js +304 -0
  382. package/dist/runtime/presentation.d.ts +85 -0
  383. package/dist/runtime/presentation.d.ts.map +1 -0
  384. package/dist/runtime/presentation.js +92 -0
  385. package/dist/runtime/render-audio-control.d.ts +126 -0
  386. package/dist/runtime/render-audio-control.d.ts.map +1 -0
  387. package/dist/runtime/render-audio-control.js +116 -0
  388. package/dist/runtime/render-control.d.ts +347 -0
  389. package/dist/runtime/render-control.d.ts.map +1 -0
  390. package/dist/runtime/render-control.js +317 -0
  391. package/dist/runtime/render-seed.d.ts +56 -0
  392. package/dist/runtime/render-seed.d.ts.map +1 -0
  393. package/dist/runtime/render-seed.js +73 -0
  394. package/dist/runtime/state-bridge.d.ts +60 -0
  395. package/dist/runtime/state-bridge.d.ts.map +1 -0
  396. package/dist/runtime/state-bridge.js +62 -0
  397. package/dist/runtime/types.d.ts +285 -0
  398. package/dist/runtime/types.d.ts.map +1 -0
  399. package/dist/runtime/types.js +1 -0
  400. package/dist/runtime/unexported-game-trap.d.ts +36 -0
  401. package/dist/runtime/unexported-game-trap.d.ts.map +1 -0
  402. package/dist/runtime/unexported-game-trap.js +80 -0
  403. package/dist/setup/setup-audio.d.ts +20 -0
  404. package/dist/setup/setup-audio.d.ts.map +1 -0
  405. package/dist/setup/setup-audio.js +41 -0
  406. package/dist/setup/setup-particles.d.ts +17 -0
  407. package/dist/setup/setup-particles.d.ts.map +1 -0
  408. package/dist/setup/setup-particles.js +16 -0
  409. package/dist/setup/setup-physics.d.ts +25 -0
  410. package/dist/setup/setup-physics.d.ts.map +1 -0
  411. package/dist/setup/setup-physics.js +51 -0
  412. package/dist/setup/setup-renderer.d.ts +82 -0
  413. package/dist/setup/setup-renderer.d.ts.map +1 -0
  414. package/dist/setup/setup-renderer.js +381 -0
  415. package/dist/world3d-react/engine-bridge.d.ts +47 -0
  416. package/dist/world3d-react/engine-bridge.d.ts.map +1 -0
  417. package/dist/world3d-react/engine-bridge.js +48 -0
  418. package/dist/world3d-react/index.d.ts +47 -0
  419. package/dist/world3d-react/index.d.ts.map +1 -0
  420. package/dist/world3d-react/index.js +46 -0
  421. package/dist/world3d-react/r3f-adapter.d.ts +51 -0
  422. package/dist/world3d-react/r3f-adapter.d.ts.map +1 -0
  423. package/dist/world3d-react/r3f-adapter.js +368 -0
  424. package/dist/world3d-react/r3f-root-factory.d.ts +62 -0
  425. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -0
  426. package/dist/world3d-react/r3f-root-factory.js +79 -0
  427. package/dist/world3d-react/rapier-physics-bridge.d.ts +76 -0
  428. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -0
  429. package/dist/world3d-react/rapier-physics-bridge.js +120 -0
  430. package/dist/world3d-react/renderer-config.d.ts +58 -0
  431. package/dist/world3d-react/renderer-config.d.ts.map +1 -0
  432. package/dist/world3d-react/renderer-config.js +96 -0
  433. package/dist/world3d-react/world-context.d.ts +123 -0
  434. package/dist/world3d-react/world-context.d.ts.map +1 -0
  435. package/dist/world3d-react/world-context.js +204 -0
  436. package/dist-config/config.js +303 -0
  437. package/dist-config/config.js.map +7 -0
  438. package/package.json +14 -3
  439. package/src/adapter/rapier-physics-adapter.ts +77 -34
  440. package/src/config.ts +8 -0
  441. package/src/core/frame-pacing.ts +26 -0
  442. package/src/core/game-loop.ts +4 -3
  443. package/src/dev/instruments.ts +302 -0
  444. package/src/setup/setup-renderer.ts +2 -0
  445. package/src/world3d-react/index.ts +9 -0
  446. package/src/world3d-react/rapier-physics-bridge.tsx +137 -0
@@ -0,0 +1,368 @@
1
+ /**
2
+ * `createR3FAdapter` — wraps a react-three-fiber tree as a first-party
3
+ * `RootAdapter` so an R3F scene mounts as an ordinary `kind: "three"`
4
+ * world: the engine hands `mount()` a `ThreeHostContext` (ITS OWN renderer +
5
+ * canvas + gated loop, per `../adapter/host-context.ts`); this returns a
6
+ * `MountedThreeRoot` (`../adapter/root-adapter.ts`) whose `scene`/`camera`
7
+ * are fiber's REAL `THREE.Scene`/`THREE.Camera` instances.
8
+ *
9
+ * Upstreamed from `examples/r3f-first-party/src/r3f-adapter.tsx` (R4 — the
10
+ * `@engine/world3d-react` opt-in module, mirroring how `pixi/` is the
11
+ * PixiJS surface's opt-in home). The mount semantics
12
+ * are byte-for-byte the example's live-proven Phase-1 bridge. External adopters
13
+ * (alien-stories-style) keep the exact same calling contract.
14
+ *
15
+ * three.js identity: this module never imports `three` itself for scene objects
16
+ * — fiber's internal `import * as THREE from 'three'` must resolve to the SAME
17
+ * instance the engine's `ThreeHostContext.three` points at, which the importing
18
+ * project guarantees via its Vite `resolve.dedupe: ['three', 'react',
19
+ * 'react-dom']` (see `examples/r3f-first-party/vite.config.ts`).
20
+ */
21
+ import { advance, createRoot, extend, events as pointerEvents, } from '@react-three/fiber';
22
+ import { createElement } from 'react';
23
+ import { WorldProvider } from '../react/world-state';
24
+ import { EngineBridge } from './engine-bridge';
25
+ import { applyWorldRendererConfig } from './renderer-config';
26
+ import { createR3FRootContext } from './world-context';
27
+ /**
28
+ * Build a `RootAdapter` that mounts `options.content` through
29
+ * react-three-fiber, gated entirely by the host's own loop and rendering
30
+ * through the host's own `WebGLRenderer` — never a second renderer, never a
31
+ * second `requestAnimationFrame` loop (design §1.C).
32
+ */
33
+ export function createR3FAdapter(options) {
34
+ const { id, content, inputMapPath, renderer: rendererConfig } = options;
35
+ return {
36
+ id,
37
+ async mount(host) {
38
+ // Headless honesty — every `mount()` must work headless: the
39
+ // conformance kit / CI
40
+ // runs `mount()` in Node — no canvas, no WebGL, no fiber reconciler.
41
+ // Guard the ENTIRE fiber mount behind `!host.headless` and return a
42
+ // bare, real scene + camera instead (still `instanceof
43
+ // host.three.Scene` / `.Camera` — the identity rule holds even here,
44
+ // since this uses the host's own `three` instance, not a fresh
45
+ // import). Residual: the hierarchy is empty under headless
46
+ // conformance — recorded as design O2, not hidden; a react-nil-style
47
+ // headless reconciler mount is the known fix, out of scope for v1.
48
+ if (host.headless) {
49
+ const scene = new host.three.Scene();
50
+ const camera = new host.three.PerspectiveCamera();
51
+ return {
52
+ kind: 'three',
53
+ scene,
54
+ camera,
55
+ drivesOwnLoop: false,
56
+ dispose() {
57
+ /* nothing was ever mounted */
58
+ },
59
+ };
60
+ }
61
+ // Fiber v9 made the THREE catalogue tree-shakeable: `<Canvas>` calls
62
+ // `extend(THREE)` for you, a bare `createRoot` does NOT — without this,
63
+ // the FIRST three intrinsic in the tree (`<color>`, `<ambientLight>`,
64
+ // …) throws "X is not part of the THREE namespace! Did you forget to
65
+ // extend?" at reconcile time. Extending with `host.three` (not a fresh
66
+ // `import * as THREE`) keeps the catalogue on the host's deduped three
67
+ // instance — the same identity rule the returned scene/camera rely on.
68
+ // `extend` merges into a module-global catalogue, so calling it once
69
+ // per mount is idempotent.
70
+ extend(host.three);
71
+ // The engine runtime this world OWNS: a real SystemRunner,
72
+ // provided to the R3F tree via `EngineBridge`.
73
+ // `update(dt)` below runs the phases under the host loop, so registered
74
+ // systems tick in engine phase order and freeze under
75
+ // pause exactly like `useFrame` work does.
76
+ //
77
+ // HONESTY NOTE: the manager's ctx is an `R3FGameContext`, not the full
78
+ // `GameContext`. The shared game-scoped subsystems are REAL
79
+ // classic-adapter parity (`./world-context.ts`):
80
+ // `ctx.debug`/`ctx.random`/`ctx.game`/`ctx.roots`, and `ctx.input` (the
81
+ // game-owned InputManager, with this world's virtual-input/actions/trace
82
+ // debug seams registered and the project's input map loaded). The
83
+ // subsystems an R3F world genuinely does not build (Rapier, composer,
84
+ // audio, particles, debugDraw) are absent from that TYPE, so reaching
85
+ // for one is a compile error rather than anything that can happen at
86
+ // runtime. `scene`/`camera` are backfilled right after fiber's first
87
+ // commit resolves them, before any tick can run.
88
+ const runtime = createR3FRootContext(host, { id, inputMapPath });
89
+ const { systems } = runtime;
90
+ // `ctx` rides the bridge so ordinary components can reach engine
91
+ // services through `useGameContext()`.
92
+ const bridge = { ctx: runtime.ctx };
93
+ // Actions must exist before any component's init()/first frame reads
94
+ // them — wait for the (never-rejecting) input-map load before the first
95
+ // commit.
96
+ await runtime.inputMapReady;
97
+ // The world's own colour pipeline. Applied AFTER `root.configure()` below — see the comment
98
+ // at its call site for why "before" is the version that silently does nothing.
99
+ let restoreRendererConfig = () => { };
100
+ const canvas = host.surface.canvas;
101
+ const root = createRoot(canvas);
102
+ // `RootState` (the live scene/camera/gl fiber built) only arrives via
103
+ // the `onCreated` callback — `root.render()`'s return value is
104
+ // TECHNICALLY the same store, but `onCreated` is the hook the design
105
+ // doc's §1.C sketch names, and waiting for it (rather than assuming
106
+ // the first commit already ran synchronously) is the honest choice
107
+ // under React 19's concurrent renderer, which does not guarantee a
108
+ // synchronous first commit the way legacy ReactDOM.render did.
109
+ let resolveState;
110
+ const statePromise = new Promise((resolve) => {
111
+ resolveState = resolve;
112
+ });
113
+ // `root.configure()` is ASYNC in fiber v9 (`Promise<ReconcilerRoot>`)
114
+ // — the design doc's §1.C sketch shows it called synchronously; the
115
+ // real v9 API (verified against
116
+ // `node_modules/@react-three/fiber/dist/declarations/src/core/index.d.ts`)
117
+ // requires awaiting it before `render()`.
118
+ await root.configure({
119
+ // The engine's renderer, not a second one (design §1.C) — fiber
120
+ // renders THROUGH `host.renderer` instead of constructing its own
121
+ // `WebGLRenderer`.
122
+ gl: host.renderer,
123
+ // …and the host's shadow map, not fiber's.
124
+ //
125
+ // `configure()` runs `gl.shadowMap.enabled = !!shadows`
126
+ // UNCONDITIONALLY, against its own default of `false`. Passing nothing
127
+ // therefore does not mean "leave it alone" — it means "turn shadows
128
+ // off on the renderer the host just configured". Every three root
129
+ // silently did that (FX-5): `applyRendererSettings` sets
130
+ // `shadowMap.enabled` from the `shadows` render feature, which
131
+ // defaults ON, and the setting had no surviving reader on this path —
132
+ // so `castShadow`/`receiveShadow` all over a world produced nothing
133
+ // and the scene read flat, with no error anywhere.
134
+ //
135
+ // Reading it back off the renderer is exactly "don't clobber": a
136
+ // boolean also pins `shadowMap.type` to `PCFSoftShadowMap`, which is
137
+ // what `createHostRenderer` already sets, so the round trip is
138
+ // lossless and the HOST stays the one deciding.
139
+ //
140
+ // Optional-chained even though `WebGLRenderer.shadowMap` is not
141
+ // optional: a headless/stub host renderer is a real shape in this
142
+ // repo's tests, and fiber's own `if (gl.shadowMap)` guard means the
143
+ // value it reads there is ignored anyway.
144
+ shadows: host.renderer.shadowMap?.enabled ?? false,
145
+ // The engine's gated loop is the ONLY loop — fiber must never run
146
+ // its own rAF (that would defeat editor pause; design §1.C's
147
+ // `drivesOwnLoop: false` contract, guide §2's loop-model note).
148
+ frameloop: 'never',
149
+ // `RenderProps.size` types as the FULL `Size` (width/height/top/left),
150
+ // not `Partial<Size>` — the design sketch's `{ width, height }` alone
151
+ // does not satisfy fiber v9's real type, so `top`/`left` are pinned
152
+ // to 0 (this bridge always fills its whole canvas; no offset
153
+ // viewport in v1).
154
+ size: { width: host.surface.width, height: host.surface.height, top: 0, left: 0 },
155
+ // Fiber's pointer-event manager, passed EXPLICITLY.
156
+ //
157
+ // This comment used to say `events` was "deliberately left at fiber's
158
+ // default (binds to `gl.domElement`)". That was false, and it cost
159
+ // every R3F world in this engine its mesh-level pointer props —
160
+ // `onClick`, `onPointerOver`, `onPointerMissed` were dead everywhere.
161
+ // There IS no default for a bare `createRoot`: the
162
+ // `events = createPointerEvents` default lives in the `<Canvas>`
163
+ // COMPONENT, which this bridge does not use, and `configure` gates on
164
+ // `if (events && !state.events.handlers)`. With `events` undefined the
165
+ // store kept its initial `{ priority, enabled, connected: false }` —
166
+ // no handlers, nothing bound to the canvas, no error.
167
+ //
168
+ // Found by the WO-P6 builder, whose control experiment isolated the
169
+ // variable properly: the same stub renderer, the same
170
+ // `frameloop: 'never'`, the same jsdom canvas and pointer sequence,
171
+ // differing ONLY in passing `events` — and `onClick` fired. Fiber is
172
+ // fine under a host-driven loop; we omitted one property.
173
+ //
174
+ // (Design O1's open question about a delegating multi-canvas input
175
+ // router still only matters for a shell+net composite; this bridge is
176
+ // the single-canvas world O1 says is unaffected.)
177
+ events: pointerEvents,
178
+ onCreated: (state) => resolveState(state),
179
+ });
180
+ // THE WORLD'S OWN COLOUR PIPELINE — and it must land HERE, after `configure()`.
181
+ //
182
+ // `configure()` writes `outputColorSpace` and `toneMapping` onto the renderer
183
+ // UNCONDITIONALLY, from its own `linear`/`flat` props whose defaults are `false`/`false` —
184
+ // i.e. sRGB output and ACES. That is the SAME trap as the `shadows` note above, and it is
185
+ // silent: applying a world's config before `configure()` leaves every field set and every
186
+ // pixel unchanged (measured on the squash-the-creeps Godot port — the ground stayed at byte
187
+ // 138 with `toneMapping: 'none'` declared and applied).
188
+ //
189
+ // Applying it here is still before any frame: `advance()` only runs from `update()` below,
190
+ // and `render()` on the next line merely reconciles.
191
+ if (rendererConfig !== undefined) {
192
+ restoreRendererConfig = applyWorldRendererConfig(host.three, host.renderer, rendererConfig);
193
+ }
194
+ // No `<StrictMode>` (design §1.C: "no StrictMode: host mounts once")
195
+ // — this bridge mounts exactly once per `mount()` call; StrictMode's
196
+ // deliberate double-invoke of effects would double-subscribe
197
+ // `useFrame` callbacks against a host loop that only ticks once per
198
+ // frame. The `EngineBridge` provider threads the component runtime
199
+ // (above) into the tree (W3), where `useGameContext()` reads it.
200
+ // R3F IS React, so the React seam every dom root already has —
201
+ // `useWorldState`, `useDebugProvider`/`useDebugCommand`/`useDebugEmit`
202
+ // (`../react/world-state`) — should work identically inside a three root.
203
+ // Without this provider a behavior-as-a-hook could only reach the debug
204
+ // registry by destructuring `useGameContext()` and calling
205
+ // `debug?.registerStateProvider(...)` by hand, which has no unmount
206
+ // story: the template's follow-camera hook leaked a provider per remount
207
+ // until this landed. `host.game` is genuinely absent in bare/headless
208
+ // hosts, so the provider is conditional and those hooks stay the inert
209
+ // no-ops they already document themselves to be.
210
+ const game = runtime.ctx.game;
211
+ root.render(createElement(EngineBridge.Provider, { value: bridge }, game ? createElement(WorldProvider, { game }, content) : content));
212
+ // A reconcile-time crash (e.g. a missing `extend` catalogue entry)
213
+ // surfaces as an uncaught window error and `onCreated` never fires —
214
+ // without this guard, `mount()` would await `statePromise` FOREVER and
215
+ // silently wedge every world declared after this one (roots mount
216
+ // sequentially). Convert that class of failure into a loud mount error.
217
+ const state = await new Promise((resolve, reject) => {
218
+ const onError = (event) => {
219
+ cleanup();
220
+ root.unmount();
221
+ runtime.dispose();
222
+ restoreRendererConfig();
223
+ reject(new Error(`r3f-adapter: fiber crashed before its first commit — ${event.message} ` +
224
+ '(mount() fails loudly instead of hanging on onCreated)'));
225
+ };
226
+ const timer = setTimeout(() => {
227
+ cleanup();
228
+ root.unmount();
229
+ runtime.dispose();
230
+ restoreRendererConfig();
231
+ reject(new Error('r3f-adapter: onCreated did not fire within 10s — the R3F tree never reached ' +
232
+ 'its first commit (mount() fails loudly instead of hanging)'));
233
+ }, 10_000);
234
+ const cleanup = () => {
235
+ clearTimeout(timer);
236
+ window.removeEventListener('error', onError);
237
+ };
238
+ window.addEventListener('error', onError);
239
+ void statePromise.then((s) => {
240
+ cleanup();
241
+ resolve(s);
242
+ });
243
+ });
244
+ // Clock hardening (field-proven by the first external adopter,
245
+ // alien-stories' proto): fiber's internal `update()` calls
246
+ // `state.clock.getDelta()` BEFORE its `frameloop:'never'` branch, and a
247
+ // RUNNING (or autoStart) `THREE.Clock` accumulates WALL time into
248
+ // `elapsedTime` as a side effect — skewing the deltas the 'never'
249
+ // branch derives from the game timestamps `update(dt)` feeds below.
250
+ // Stopped + autoStart=false makes `getDelta()` a pure no-op, so
251
+ // `useFrame` deltas come from game time alone.
252
+ state.clock.autoStart = false;
253
+ state.clock.stop();
254
+ // Backfill the component runtime's ctx with fiber's real scene/camera
255
+ // (W3 — see the HONESTY NOTE above). This happens before the first
256
+ // `update(dt)` tick, so no component ever observes them missing.
257
+ runtime.setSceneCamera(state.scene, state.camera);
258
+ // THE STORE IS THE TRUTH, NOT THE `onCreated` SNAPSHOT.
259
+ //
260
+ // `state` is one immutable zustand snapshot: fiber's store is
261
+ // `create<RootState>()`, and every `set(...)` produces a NEW state
262
+ // object rather than mutating this one. So a world that legitimately
263
+ // REPLACES the default camera — `useThree(s => s.set)({ camera })`,
264
+ // which is exactly what drei's `makeDefault` does — never reaches
265
+ // anything read off `state` directly.
266
+ //
267
+ // That is not cosmetic: fiber's own `update()` renders
268
+ // `state.gl.render(state.scene, state.camera)` off the state object it
269
+ // is HANDED, so `advance(t, true, state)` below pinned the render
270
+ // camera to fiber's default `PerspectiveCamera` at (0, 0, 5) forever.
271
+ // Measured on the squash-the-creeps Godot port (WO-G14): the world set
272
+ // its authored `OrthographicCamera` and the frame still rendered from
273
+ // (0, 0, 5) — a point INSIDE that game's 60x2x60 ground box, so every
274
+ // ground polygon was back-facing, was culled, and the "ground" was the
275
+ // cleared canvas. Nothing anywhere reported an error; edit mode looked
276
+ // right because the editor renders with its own camera.
277
+ //
278
+ // `state.get()` is fiber's own `StoreApi.getState`, carried on
279
+ // `RootState` for precisely this reason, so reading it per frame is the
280
+ // supported way to see the live root. It is a plain map read.
281
+ const live = () => state.get();
282
+ // The engine drives every `useFrame` through the mounted world's
283
+ // `update(dt)` hook, never off a raw host-loop callback. That is the
284
+ // whole pause story: `runFrameImpl` (`runtime/game.ts`) calls
285
+ // `mounted.update?.(dt)` per substep for a host-driven
286
+ // (`drivesOwnLoop: false`) world and SKIPS it while that world is
287
+ // frozen, and `Game.play.step()` ticks it exactly once — whereas any
288
+ // callback run outside `game.runFrame`'s gate would fire
289
+ // unconditionally, pause or not. Advancing fiber from such a callback
290
+ // LOOKS right and silently breaks acceptance gate 2 — proven by the
291
+ // 36-r3f-first-party e2e, whose paused instance-matrix samples kept
292
+ // moving until this moved to `update`. (The former `ThreeHostContext.loop`
293
+ // seam that made the wrong path reachable was deleted, zero consumers.)
294
+ //
295
+ // `advance(timestamp, runGlobalEffects, state)`'s `timestamp` is
296
+ // consumed as `THREE.Clock.elapsedTime` DIRECTLY when
297
+ // `frameloop:'never'` (verified against fiber's `update()`
298
+ // implementation, not just its `.d.ts` — the declared signature alone
299
+ // doesn't say this): `delta = timestamp - clock.elapsedTime;
300
+ // clock.elapsedTime = timestamp`. So `timestamp` must be a
301
+ // monotonically increasing SECONDS value — GAME time, not wall time:
302
+ // `update` simply isn't called while this world is frozen, so
303
+ // accumulating its `dt` (seconds; the loop runs a fixed 1/60 timestep)
304
+ // means fiber's clock does not advance across a pause. Wall clock
305
+ // (`performance.now()`) would leak the pause duration into the first
306
+ // resumed frame as one giant `useFrame` delta — the exact "time passed
307
+ // while frozen" illusion acceptance gate 2 forbids.
308
+ let elapsed = 0;
309
+ /** The camera `ctx` was last backfilled with — see `update()`. */
310
+ let backfilledCamera = state.camera;
311
+ return {
312
+ kind: 'three',
313
+ // Fiber's REAL `THREE.Scene`/`THREE.Camera`. Checkout development
314
+ // dedupes `three`; a registry-installed project and the prebundled
315
+ // editor can legitimately have distinct constructor identities, so
316
+ // editor boundaries recognize Three's stable structural brands
317
+ // (`isScene`, `isCamera`) rather than relying only on `instanceof`.
318
+ // `state.camera`'s type (`Camera = (OrthographicCamera |
319
+ // PerspectiveCamera) & { manual?: boolean }`) is a structural subtype
320
+ // of `THREE.Camera`, so no cast is needed.
321
+ //
322
+ // Both are GETTERS over the live store, not snapshot fields: the host
323
+ // and the editor must see the camera the world actually renders
324
+ // through, including one the world swapped in after the first commit
325
+ // (see `live` above).
326
+ get scene() {
327
+ return live().scene;
328
+ },
329
+ get camera() {
330
+ return live().camera;
331
+ },
332
+ drivesOwnLoop: false,
333
+ // Adapter surface: `debug` pre-seeded (the shared game registry's
334
+ // adapter); game code adds capabilities via
335
+ // `ctx.registerSystemAdapter` exactly as in a classic world.
336
+ systems: runtime.systemAdapters,
337
+ update(dt) {
338
+ elapsed += dt;
339
+ const current = live();
340
+ // A world that swapped the default camera gets it onto `ctx` too —
341
+ // `ctx.camera` and the rendered camera are the same fact, and a
342
+ // component reading one while the frame uses the other is the
343
+ // silent kind of wrong. Identity-gated, so this is one comparison
344
+ // per frame in the overwhelmingly common no-swap case.
345
+ if (current.camera !== backfilledCamera) {
346
+ backfilledCamera = current.camera;
347
+ runtime.setSceneCamera(current.scene, current.camera);
348
+ }
349
+ // Engine phases FIRST (registered systems mutate transforms),
350
+ // then fiber's advance (useFrame callbacks + the actual render see
351
+ // the fresh state). Both are host-gated: neither runs while frozen.
352
+ systems.run(dt);
353
+ advance(elapsed, true, current);
354
+ },
355
+ resize(width, height) {
356
+ live().setSize(width, height);
357
+ },
358
+ dispose() {
359
+ // Unmount FIRST so component effect cleanups run, then tear the
360
+ // runtime down (scoped debug-registry strip).
361
+ root.unmount();
362
+ runtime.dispose();
363
+ restoreRendererConfig();
364
+ },
365
+ };
366
+ },
367
+ };
368
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `r3fRootFactory` — mount a `three` root whose entry module DEFAULT-EXPORTS a
3
+ * React component.
4
+ *
5
+ * The idiomatic-shape fix (D26). A model asked for an R3F world writes:
6
+ *
7
+ * ```tsx
8
+ * export default function World() {
9
+ * return <><ambientLight /><mesh>…</mesh></>;
10
+ * }
11
+ * ```
12
+ *
13
+ * It does NOT write `export const adapter = createR3FAdapter({ id, content })`.
14
+ * That export is pure vgai ceremony wrapped around a component the author
15
+ * already wrote, and it is the second-largest non-idiomatic thing left in a
16
+ * world file (the largest is the missing `<Canvas>`, which is a separate
17
+ * question about who owns the canvas — see D26).
18
+ *
19
+ * The `dom` root already settled this convention: its factory reads
20
+ * `entryModule.default` and wraps it. This is the same contract for three
21
+ * roots, so both surfaces answer "what do I export?" the same way.
22
+ *
23
+ * ## Why this is NOT in `mount-game.ts`
24
+ *
25
+ * `defaultThreeAdapterFactory` lives beside the registry, and the registry
26
+ * module is deliberately dependency-free: its own doc notes threejs is safe to
27
+ * ship there because `three` is already an unconditional engine dependency.
28
+ * `@react-three/fiber` is NOT — it is the PROJECT's dependency, and
29
+ * `world3d-react` is the opt-in module that owns it. Putting this factory
30
+ * there would make R3F unconditional for every game, including ones with no
31
+ * React at all.
32
+ *
33
+ * ## Compatibility
34
+ *
35
+ * An `adapter` export still wins, so existing worlds are untouched and a game
36
+ * needing full control over its own `RootAdapter` keeps it.
37
+ */
38
+ import type { RootAdapter } from '../adapter/root-adapter';
39
+ import type { AdapterSurfaceFactory } from '../runtime/mount-game';
40
+ /**
41
+ * What a three entry module MEANS, in one place.
42
+ *
43
+ * Two callers need this answer and must never disagree about it: the runtime
44
+ * mount ({@link r3fRootFactory}, below) and the EDITOR's design session
45
+ * (`packages/editor/src/authoring/r3f-design-session.ts`), which design-mounts
46
+ * the same entry so edit mode authors the live fiber scene. When only the
47
+ * runtime knew about the default-export shape, the converted starter played
48
+ * fine under `npm run game` and edit mode showed "(no scene loaded)".
49
+ *
50
+ * Returns `null` when the module is neither shape — the callers differ on what
51
+ * to do about that (the factory throws, the design session declines the world
52
+ * and leaves existing paths alone).
53
+ */
54
+ export declare function resolveR3FEntryAdapter(entryModule: unknown, rootId: string): RootAdapter | null;
55
+ /**
56
+ * Register with `registerAdapter('three', r3fRootFactory)`.
57
+ *
58
+ * Resolution order mirrors `defaultThreeAdapterFactory`'s (explicit adapter
59
+ * wins) and then accepts the default-exported component.
60
+ */
61
+ export declare const r3fRootFactory: AdapterSurfaceFactory;
62
+ //# sourceMappingURL=r3f-root-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"r3f-root-factory.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-root-factory.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAUnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAU/F;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,qBAQ5B,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * `r3fRootFactory` — mount a `three` root whose entry module DEFAULT-EXPORTS a
3
+ * React component.
4
+ *
5
+ * The idiomatic-shape fix (D26). A model asked for an R3F world writes:
6
+ *
7
+ * ```tsx
8
+ * export default function World() {
9
+ * return <><ambientLight /><mesh>…</mesh></>;
10
+ * }
11
+ * ```
12
+ *
13
+ * It does NOT write `export const adapter = createR3FAdapter({ id, content })`.
14
+ * That export is pure vgai ceremony wrapped around a component the author
15
+ * already wrote, and it is the second-largest non-idiomatic thing left in a
16
+ * world file (the largest is the missing `<Canvas>`, which is a separate
17
+ * question about who owns the canvas — see D26).
18
+ *
19
+ * The `dom` root already settled this convention: its factory reads
20
+ * `entryModule.default` and wraps it. This is the same contract for three
21
+ * roots, so both surfaces answer "what do I export?" the same way.
22
+ *
23
+ * ## Why this is NOT in `mount-game.ts`
24
+ *
25
+ * `defaultThreeAdapterFactory` lives beside the registry, and the registry
26
+ * module is deliberately dependency-free: its own doc notes threejs is safe to
27
+ * ship there because `three` is already an unconditional engine dependency.
28
+ * `@react-three/fiber` is NOT — it is the PROJECT's dependency, and
29
+ * `world3d-react` is the opt-in module that owns it. Putting this factory
30
+ * there would make R3F unconditional for every game, including ones with no
31
+ * React at all.
32
+ *
33
+ * ## Compatibility
34
+ *
35
+ * An `adapter` export still wins, so existing worlds are untouched and a game
36
+ * needing full control over its own `RootAdapter` keeps it.
37
+ */
38
+ import { createElement } from 'react';
39
+ import { createR3FAdapter } from './r3f-adapter';
40
+ /**
41
+ * What a three entry module MEANS, in one place.
42
+ *
43
+ * Two callers need this answer and must never disagree about it: the runtime
44
+ * mount ({@link r3fRootFactory}, below) and the EDITOR's design session
45
+ * (`packages/editor/src/authoring/r3f-design-session.ts`), which design-mounts
46
+ * the same entry so edit mode authors the live fiber scene. When only the
47
+ * runtime knew about the default-export shape, the converted starter played
48
+ * fine under `npm run game` and edit mode showed "(no scene loaded)".
49
+ *
50
+ * Returns `null` when the module is neither shape — the callers differ on what
51
+ * to do about that (the factory throws, the design session declines the world
52
+ * and leaves existing paths alone).
53
+ */
54
+ export function resolveR3FEntryAdapter(entryModule, rootId) {
55
+ const mod = entryModule;
56
+ if (mod?.adapter)
57
+ return mod.adapter;
58
+ if (typeof mod?.default === 'function') {
59
+ return createR3FAdapter({
60
+ id: rootId,
61
+ content: createElement(mod.default),
62
+ });
63
+ }
64
+ return null;
65
+ }
66
+ /**
67
+ * Register with `registerAdapter('three', r3fRootFactory)`.
68
+ *
69
+ * Resolution order mirrors `defaultThreeAdapterFactory`'s (explicit adapter
70
+ * wins) and then accepts the default-exported component.
71
+ */
72
+ export const r3fRootFactory = (root, ctx) => {
73
+ const adapter = resolveR3FEntryAdapter(ctx.entryModule, root.id);
74
+ if (adapter)
75
+ return { kind: 'three', adapter };
76
+ throw new Error(`r3fRootFactory: entry module "${root.entry ?? '(none)'}" for root "${root.id}" must ` +
77
+ 'default-export a React component (`export default function World() { … }`) — or export ' +
78
+ 'an `adapter` for full control.');
79
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * `<RapierPhysicsBridge>` — the one line that makes an R3F world's
3
+ * `@react-three/rapier` physics VISIBLE to the engine's editor/dev seams.
4
+ *
5
+ * WHY IT EXISTS. `SystemAdapters.physics` is what the editor's transform
6
+ * coordination (`freeze → apply → unfreeze`) and the dev menu's universal
7
+ * "Colliders drawn" instrument (`@engine/dev/instruments`) read. The
8
+ * first-party imperative three root registers one from
9
+ * `../adapter/setup-three-root-adapter.ts`; an R3F world builds no first-party
10
+ * Rapier runtime at all (see `R3FGameContext`'s doc comment) — it does physics
11
+ * with `@react-three/rapier` INSIDE the fiber tree, where nothing engine-side
12
+ * can see it. Result, before this: the colliders instrument read `null` (an
13
+ * em-dash) and its toggle threw "no physics adapter" in every shipped example
14
+ * and every scaffolded game.
15
+ *
16
+ * NOT A WRAPPER. This registers an adapter and gets out of the way: the world
17
+ * still writes `<Physics>` itself, with the library's own props, and every
18
+ * `<RigidBody>`/collider call stays `@react-three/rapier`'s own API. The one
19
+ * thing it cannot do for you is flip the library's debug rendering, because
20
+ * `@react-three/rapier@2` exposes that ONLY as the `debug` boolean PROP on
21
+ * `<Physics>` (its `<Debug>` component is internal and unexported). A prop is
22
+ * the parent's to own, so the world holds the state and this bridge hands the
23
+ * setter to the instrument — which is why `onDebugChange` is required:
24
+ *
25
+ * ```tsx
26
+ * const [physicsDebug, setPhysicsDebug] = useState(false);
27
+ * // …
28
+ * <Physics debug={physicsDebug}>
29
+ * <RapierPhysicsBridge onDebugChange={setPhysicsDebug} />
30
+ * …
31
+ * </Physics>
32
+ * ```
33
+ *
34
+ * Nothing draws colliders here: the wireframes are the library's own
35
+ * `world.debugRender()` output, rendered by its own component.
36
+ *
37
+ * ANTI-SHIM. `debugDraw()` and `contactPoints()` are OMITTED, not stubbed —
38
+ * the library owns its debug line segments inside the tree and hands out no
39
+ * handle to them, so claiming the capability would be a fabrication. Absence
40
+ * is how a `SystemAdapters` member says "not supported".
41
+ *
42
+ * ── RESOURCE OWNERSHIP, STATED ONCE ─────────────────────────────────────────
43
+ * OWNER: this component owns exactly ONE `SystemAdapters.physics` registration,
44
+ * on the R3F root it is mounted in. It allocates nothing else — no timers, no
45
+ * subscriptions, no per-frame work (see the phase note below), and no Rapier
46
+ * objects: the bodies it edits belong to `<Physics>`.
47
+ * SHARERS: every reader of `game.systemAdapters.physics` — the dev menu's
48
+ * colliders instrument, the editor's transform coordination. They read; they
49
+ * never dispose.
50
+ * TEARDOWN: the effect's cleanup, and nothing else — it clears the SAME key it
51
+ * set (`registerSystemAdapter('physics', undefined)`, which
52
+ * `Game.computeSystemAdapters` skips), so a play stop/start, a hot restart, or
53
+ * a world that unmounts `<Physics>` leaves no stale adapter behind. Two
54
+ * bridges in one root would fight over that one key; mount exactly one.
55
+ *
56
+ * PHASE ORDERING: none to respect — this component registers pull-only
57
+ * callbacks and runs no per-frame work. Every method it exposes is invoked
58
+ * BETWEEN frames, by an editor gesture or a dev-menu command, never from a
59
+ * phase.
60
+ */
61
+ export interface RapierPhysicsBridgeProps {
62
+ /**
63
+ * Set the `debug` prop of the SAME `<Physics>` this bridge is mounted in.
64
+ * The dev menu's "Colliders drawn" toggle calls it; the world's own state is
65
+ * what `<Physics debug={…}>` reads, so the library's debug rendering is the
66
+ * only thing that ever draws a collider.
67
+ */
68
+ readonly onDebugChange: (debug: boolean) => void;
69
+ }
70
+ /**
71
+ * Register this R3F world's `@react-three/rapier` physics as the game's
72
+ * `SystemAdapters.physics`. Mount it once, INSIDE `<Physics>` (it reads
73
+ * `useRapier()`). Renders nothing.
74
+ */
75
+ export declare function RapierPhysicsBridge({ onDebugChange }: RapierPhysicsBridgeProps): null;
76
+ //# sourceMappingURL=rapier-physics-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rapier-physics-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/rapier-physics-bridge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAYH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,aAAa,EAAE,EAAE,wBAAwB,GAAG,IAAI,CAkDrF"}