@forgeax/engine-runtime 0.1.4 → 0.1.6

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 (606) hide show
  1. package/README.md +49 -83
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts +2 -0
  4. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts.map +1 -0
  5. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts +2 -0
  6. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts.map +1 -0
  7. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts +2 -0
  8. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts.map +1 -0
  9. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts +11 -0
  10. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts.map +1 -0
  11. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts +2 -0
  12. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts.map +1 -0
  13. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts +2 -0
  14. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts.map +1 -0
  15. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts +2 -0
  16. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts.map +1 -0
  17. package/dist/__tests__/asset-registry-mounts.test.d.ts +2 -0
  18. package/dist/__tests__/asset-registry-mounts.test.d.ts.map +1 -0
  19. package/dist/__tests__/asset-registry.browser.test.d.ts +2 -0
  20. package/dist/__tests__/asset-registry.browser.test.d.ts.map +1 -0
  21. package/dist/__tests__/asset-registry.dawn.test.d.ts +2 -0
  22. package/dist/__tests__/asset-registry.dawn.test.d.ts.map +1 -0
  23. package/dist/__tests__/asset-registry.listCatalog.test.d.ts +2 -0
  24. package/dist/__tests__/asset-registry.listCatalog.test.d.ts.map +1 -0
  25. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts +2 -0
  26. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts.map +1 -0
  27. package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
  28. package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
  29. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts +2 -0
  30. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts.map +1 -0
  31. package/dist/__tests__/asset-registry.recursive.spec.d.ts +2 -0
  32. package/dist/__tests__/asset-registry.recursive.spec.d.ts.map +1 -0
  33. package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
  34. package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
  35. package/dist/__tests__/asset.unit.test.d.ts +2 -0
  36. package/dist/__tests__/asset.unit.test.d.ts.map +1 -0
  37. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts +2 -0
  38. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts.map +1 -0
  39. package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
  40. package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
  41. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts +2 -0
  42. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts.map +1 -0
  43. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts +2 -0
  44. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts.map +1 -0
  45. package/dist/__tests__/collect-scene-asset.test.d.ts +1 -2
  46. package/dist/__tests__/collect-scene-asset.test.d.ts.map +1 -1
  47. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts +2 -0
  48. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts.map +1 -0
  49. package/dist/__tests__/collect-transient-roundtrip.test.d.ts +1 -1
  50. package/dist/__tests__/collect-transient-roundtrip.test.d.ts.map +1 -1
  51. package/dist/__tests__/collect-transient-skip.test.d.ts +1 -2
  52. package/dist/__tests__/collect-transient-skip.test.d.ts.map +1 -1
  53. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts +2 -0
  54. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts.map +1 -0
  55. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts +2 -0
  56. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts.map +1 -0
  57. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts +2 -0
  58. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts.map +1 -0
  59. package/dist/__tests__/draw-published.d.ts +2 -2
  60. package/dist/__tests__/draw-published.d.ts.map +1 -1
  61. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
  62. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
  63. package/dist/__tests__/errors.unit.test.d.ts +2 -0
  64. package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
  65. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts +2 -0
  66. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts.map +1 -0
  67. package/dist/__tests__/fetch-binary-decompress.test.d.ts +2 -0
  68. package/dist/__tests__/fetch-binary-decompress.test.d.ts.map +1 -0
  69. package/dist/__tests__/four-path-compression.integration.test.d.ts +2 -0
  70. package/dist/__tests__/four-path-compression.integration.test.d.ts.map +1 -0
  71. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts +2 -0
  72. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts.map +1 -0
  73. package/dist/__tests__/guid-for-asset.unit.test.d.ts +2 -0
  74. package/dist/__tests__/guid-for-asset.unit.test.d.ts.map +1 -0
  75. package/dist/__tests__/handle-migration.test.d.ts +2 -0
  76. package/dist/__tests__/handle-migration.test.d.ts.map +1 -0
  77. package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
  78. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts +2 -0
  79. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts.map +1 -0
  80. package/dist/__tests__/host-custom-kind-contract.test.d.ts +2 -0
  81. package/dist/__tests__/host-custom-kind-contract.test.d.ts.map +1 -0
  82. package/dist/__tests__/inspect-name.test.d.ts +2 -0
  83. package/dist/__tests__/inspect-name.test.d.ts.map +1 -0
  84. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts +2 -0
  85. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts.map +1 -0
  86. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts +2 -0
  87. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts +2 -0
  89. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/loader-extract-graceful.test.d.ts +2 -0
  91. package/dist/__tests__/loader-extract-graceful.test.d.ts.map +1 -0
  92. package/dist/__tests__/loader-name-survival.test.d.ts +2 -0
  93. package/dist/__tests__/loader-name-survival.test.d.ts.map +1 -0
  94. package/dist/__tests__/mesh-bin-contract.test.d.ts +2 -0
  95. package/dist/__tests__/mesh-bin-contract.test.d.ts.map +1 -0
  96. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts +2 -0
  97. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts.map +1 -0
  98. package/dist/__tests__/mesh-bin.test.d.ts +2 -0
  99. package/dist/__tests__/mesh-bin.test.d.ts.map +1 -0
  100. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts +2 -0
  101. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/new-kind-refs-contract.test.d.ts +2 -0
  103. package/dist/__tests__/new-kind-refs-contract.test.d.ts.map +1 -0
  104. package/dist/__tests__/package-promotion.test.d.ts +2 -0
  105. package/dist/__tests__/package-promotion.test.d.ts.map +1 -0
  106. package/dist/__tests__/package-rename.test.d.ts +2 -0
  107. package/dist/__tests__/package-rename.test.d.ts.map +1 -0
  108. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts +1 -1
  109. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts.map +1 -1
  110. package/dist/__tests__/render-error-exhaustive.test-d.d.ts +1 -1
  111. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
  112. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts +10 -0
  113. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts.map +1 -0
  114. package/dist/__tests__/render-system-extract.unit.test.d.ts +2 -0
  115. package/dist/__tests__/render-system-extract.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/renderer-test-utils.d.ts +10 -0
  117. package/dist/__tests__/renderer-test-utils.d.ts.map +1 -0
  118. package/dist/__tests__/renderer.test-d.d.ts +2 -0
  119. package/dist/__tests__/renderer.test-d.d.ts.map +1 -0
  120. package/dist/__tests__/resolve-asset-handle-err.test.d.ts +2 -0
  121. package/dist/__tests__/resolve-asset-handle-err.test.d.ts.map +1 -0
  122. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
  123. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/resolveName-fallback.test.d.ts +2 -0
  125. package/dist/__tests__/resolveName-fallback.test.d.ts.map +1 -0
  126. package/dist/__tests__/resolveName-null-package.test.d.ts +2 -0
  127. package/dist/__tests__/resolveName-null-package.test.d.ts.map +1 -0
  128. package/dist/__tests__/resolveName-unified-entry.test.d.ts +2 -0
  129. package/dist/__tests__/resolveName-unified-entry.test.d.ts.map +1 -0
  130. package/dist/__tests__/resolveName.test.d.ts +2 -0
  131. package/dist/__tests__/resolveName.test.d.ts.map +1 -0
  132. package/dist/__tests__/roots-to-scene-asset.test.d.ts +1 -1
  133. package/dist/__tests__/roots-to-scene-asset.test.d.ts.map +1 -1
  134. package/dist/__tests__/roundtrip-primitive.test.d.ts +2 -0
  135. package/dist/__tests__/roundtrip-primitive.test.d.ts.map +1 -0
  136. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts +2 -0
  137. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts.map +1 -0
  138. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts +2 -0
  139. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts.map +1 -0
  140. package/dist/__tests__/scene-mount-fixed-point.test.d.ts +2 -0
  141. package/dist/__tests__/scene-mount-fixed-point.test.d.ts.map +1 -0
  142. package/dist/__tests__/scene-mount-roundtrip.test.d.ts +2 -0
  143. package/dist/__tests__/scene-mount-roundtrip.test.d.ts.map +1 -0
  144. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts +2 -0
  145. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts.map +1 -0
  146. package/dist/__tests__/scene-sugar-instantiate.test.d.ts +2 -0
  147. package/dist/__tests__/scene-sugar-instantiate.test.d.ts.map +1 -0
  148. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts +2 -0
  149. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts.map +1 -0
  150. package/dist/__tests__/serialize-scene-asset.test.d.ts +1 -1
  151. package/dist/__tests__/serialize-scene-asset.test.d.ts.map +1 -1
  152. package/dist/__tests__/template-game-default-api-contract.test.d.ts +2 -0
  153. package/dist/__tests__/template-game-default-api-contract.test.d.ts.map +1 -0
  154. package/dist/__tests__/tileset-asset-validate.test.d.ts +2 -0
  155. package/dist/__tests__/tileset-asset-validate.test.d.ts.map +1 -0
  156. package/dist/__tests__/transcode-fallback.unit.test.d.ts +2 -0
  157. package/dist/__tests__/transcode-fallback.unit.test.d.ts.map +1 -0
  158. package/dist/__tests__/transient-runtime-behavior.test.d.ts +2 -0
  159. package/dist/__tests__/transient-runtime-behavior.test.d.ts.map +1 -0
  160. package/dist/__tests__/video-loader-consumption.test.d.ts +2 -0
  161. package/dist/__tests__/video-loader-consumption.test.d.ts.map +1 -0
  162. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts +2 -0
  163. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts.map +1 -0
  164. package/dist/backend-selection.d.ts +13 -0
  165. package/dist/backend-selection.d.ts.map +1 -0
  166. package/dist/collect-scene-asset.d.ts +3 -3
  167. package/dist/collect-scene-asset.d.ts.map +1 -1
  168. package/dist/createRenderer.d.ts +14 -2
  169. package/dist/createRenderer.d.ts.map +1 -1
  170. package/dist/errors/environment.d.ts +1 -1
  171. package/dist/errors/environment.d.ts.map +1 -1
  172. package/dist/index.d.ts +19 -81
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.mjs +105 -108
  175. package/dist/index.mjs.map +1 -1
  176. package/dist/renderer-host.d.ts +9 -0
  177. package/dist/renderer-host.d.ts.map +1 -0
  178. package/dist/renderer-host.mjs +62 -0
  179. package/dist/renderer-host.mjs.map +1 -0
  180. package/dist/scene-instances/index.d.ts +2 -0
  181. package/dist/scene-instances/index.d.ts.map +1 -0
  182. package/dist/scene-utils/mount-override-fold.d.ts +1 -2
  183. package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
  184. package/dist/systems/sprite-animation-tick.d.ts +1 -1
  185. package/dist/systems/sprite-animation-tick.d.ts.map +1 -1
  186. package/dist/systems/transparent-sort.d.ts +1 -2
  187. package/dist/systems/transparent-sort.d.ts.map +1 -1
  188. package/dist/tilemap-register-validate.d.ts.map +1 -1
  189. package/package.json +34 -33
  190. package/src/__tests__/active-camera.unit.test.ts +19 -9
  191. package/src/__tests__/animation-graph-collect-roundtrip.test.ts +213 -0
  192. package/src/__tests__/animation-graph-serialize.unit.test.ts +171 -0
  193. package/src/__tests__/append-injection.test.ts +1 -1
  194. package/src/__tests__/asset-brand-and-name-retirement.test.ts +102 -0
  195. package/src/__tests__/asset-error-exhaustive.test-d.ts +62 -0
  196. package/src/__tests__/asset-registry-guid-reverse.test.ts +575 -0
  197. package/src/__tests__/asset-registry-hdr-equirect.test.ts +78 -0
  198. package/src/__tests__/asset-registry-mesh-pack-payload.dawn.test.ts +232 -0
  199. package/src/__tests__/asset-registry-mounts.test.ts +806 -0
  200. package/src/__tests__/asset-registry.browser.test.ts +81 -0
  201. package/src/__tests__/asset-registry.dawn.test.ts +94 -0
  202. package/src/__tests__/asset-registry.listCatalog.test.ts +170 -0
  203. package/src/__tests__/asset-registry.mesh-bin.test.ts +316 -0
  204. package/src/__tests__/asset-registry.pack-cache.test.ts +969 -0
  205. package/src/__tests__/asset-registry.raw-container-failfast.test.ts +225 -0
  206. package/src/__tests__/asset-registry.recursive.spec.ts +1397 -0
  207. package/src/__tests__/asset-registry.unit.test.ts +1030 -0
  208. package/src/__tests__/asset.unit.test.ts +7107 -0
  209. package/src/__tests__/audio-load-by-guid.unit.test.ts +126 -0
  210. package/src/__tests__/backend-selection.integration.test.ts +11 -0
  211. package/src/__tests__/basis-catalog-dispatch.integration.test.ts +320 -0
  212. package/src/__tests__/bind-group-cache-keying.test.ts +4 -4
  213. package/src/__tests__/block-upload-math.unit.test.ts +2 -2
  214. package/src/__tests__/builtin-asset-registry.unit.test.ts +112 -0
  215. package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
  216. package/src/__tests__/cache-false-eviction.test.ts +2 -1
  217. package/src/__tests__/cache-isolation-matrix.test.ts +2 -1
  218. package/src/__tests__/camera-clear-snapshot-equivalence.unit.test.ts +5 -6
  219. package/src/__tests__/clamp-to-last.e2e.browser.test.ts +29 -19
  220. package/src/__tests__/collect-scene-asset.test.ts +49 -52
  221. package/src/__tests__/collect-scene-mount-collapse.test.ts +391 -0
  222. package/src/__tests__/collect-subtree.unit.test.ts +1 -2
  223. package/src/__tests__/collect-transient-children-absent.test.ts +24 -10
  224. package/src/__tests__/collect-transient-roundtrip.test.ts +44 -20
  225. package/src/__tests__/collect-transient-skip.test.ts +24 -13
  226. package/src/__tests__/components.test-d.ts +1 -6
  227. package/src/__tests__/components.unit.test.ts +20 -19
  228. package/src/__tests__/composite-skybox-cross-world.browser.test.ts +59 -27
  229. package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +139 -0
  230. package/src/__tests__/create-renderer-assembly.integration.test.ts +42 -29
  231. package/src/__tests__/createRenderer-dispose.test.ts +35 -402
  232. package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +25 -30
  233. package/src/__tests__/createRenderer.unit.test.ts +1 -1
  234. package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +27 -63
  235. package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +56 -47
  236. package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +49 -29
  237. package/src/__tests__/dawn/instances-shadow.dawn.test.ts +26 -15
  238. package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +13 -14
  239. package/src/__tests__/dawn/material-alpha.dawn.test.ts +23 -31
  240. package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +0 -18
  241. package/src/__tests__/dawn/{mesh-update.dawn.test.ts → mesh-update-dawn.test.ts} +42 -134
  242. package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +14 -7
  243. package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +16 -28
  244. package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +23 -39
  245. package/src/__tests__/dawn/upload-texture.dawn.test.ts +198 -0
  246. package/src/__tests__/dawn/user-handle-mesh-render.dawn.test.ts +12 -14
  247. package/src/__tests__/dawn/user-mesh-upload.dawn.test.ts +27 -22
  248. package/src/__tests__/dawn/zero-manifest-mesh-fail.dawn.test.ts +25 -28
  249. package/src/__tests__/dawn/zero-manifest-ready.dawn.test.ts +10 -11
  250. package/src/__tests__/demo-sortscope-migration.unit.test.ts +5 -5
  251. package/src/__tests__/derive-bgl-integration.test.ts +34 -44
  252. package/src/__tests__/derive-render-data-skin.unit.test.ts +1 -1
  253. package/src/__tests__/draw-published.ts +11 -4
  254. package/src/__tests__/dynamic-texture-store.unit.test.ts +190 -0
  255. package/src/__tests__/equirect-bc6h.integration.test.ts +144 -21
  256. package/src/__tests__/errors.unit.test.ts +1203 -0
  257. package/src/__tests__/extract-frames-graceful-degradation.test.ts +3 -7
  258. package/src/__tests__/extract-frames-merge.test.ts +35 -22
  259. package/src/__tests__/extract-record-no-hardcoded-texture-fields.test.ts +5 -16
  260. package/src/__tests__/extract-skin-mismatch.unit.test.ts +322 -0
  261. package/src/__tests__/fetch-binary-decompress.test.ts +356 -0
  262. package/src/__tests__/four-path-compression.integration.test.ts +395 -0
  263. package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +1 -1
  264. package/src/__tests__/fullscreen-feature-host.dawn.test.ts +80 -0
  265. package/src/__tests__/fullscreen-post-bgl-depth.test.ts +4 -2
  266. package/src/__tests__/fullscreen-post-depth-params-arity.test.ts +3 -3
  267. package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +39 -23
  268. package/src/__tests__/fullscreen-post-process-pass.unit.test.ts +4 -2
  269. package/src/__tests__/fxaa-pixel-diff.dawn.test.ts +28 -17
  270. package/src/__tests__/fxaa-validation-and-resize.dawn.test.ts +29 -18
  271. package/src/__tests__/fxaa-zero-overhead.dawn.test.ts +16 -12
  272. package/src/__tests__/geometry.unit.test.ts +525 -159
  273. package/src/__tests__/glyph-tilemap-worldid.test.ts +1 -1
  274. package/src/__tests__/gpu-resource-cow-survivor.test.ts +6 -4
  275. package/src/__tests__/guid-for-asset.unit.test.ts +102 -0
  276. package/src/__tests__/handle-migration.test.ts +136 -0
  277. package/src/__tests__/helpers/register-runtime-components.ts +4 -2
  278. package/src/__tests__/helpers/register-scene-components.ts +1 -1
  279. package/src/__tests__/host-custom-kind-contract.test-d.ts +47 -0
  280. package/src/__tests__/host-custom-kind-contract.test.ts +578 -0
  281. package/src/__tests__/inspect-name.test.ts +139 -0
  282. package/src/__tests__/instances.test-d.ts +1 -1
  283. package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +112 -0
  284. package/src/__tests__/light-casters-9-light.browser.test.ts +73 -76
  285. package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +7 -10
  286. package/src/__tests__/light-snapshot.test-d.ts +2 -2
  287. package/src/__tests__/lights-vec-negative.unit.test.ts +1 -1
  288. package/src/__tests__/lights.unit.test.ts +16 -500
  289. package/src/__tests__/loadbyguid-payload.unit.test.ts +117 -0
  290. package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +213 -0
  291. package/src/__tests__/loader-extract-graceful.test.ts +146 -0
  292. package/src/__tests__/loader-name-survival.test.ts +213 -0
  293. package/src/__tests__/m3-vec-negative.unit.test.ts +3 -2
  294. package/src/__tests__/material-texture-uv-scale.unit.test.ts +101 -31
  295. package/src/__tests__/materials.unit.test.ts +10 -27
  296. package/src/__tests__/mesh-bin-contract.test.ts +28 -0
  297. package/src/__tests__/mesh-bin-skin-roundtrip.unit.test.ts +149 -0
  298. package/src/__tests__/mesh-bin.test.ts +38 -0
  299. package/src/__tests__/mesh-loader-skin-contract.unit.test.ts +120 -0
  300. package/src/__tests__/mesh-ssbo-grow.unit.test.ts +3 -3
  301. package/src/__tests__/mip-gate.unit.test.ts +1 -1
  302. package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +29 -68
  303. package/src/__tests__/new-kind-refs-contract.test.ts +132 -0
  304. package/src/__tests__/node-shims.d.ts +4 -6
  305. package/src/__tests__/package-promotion.test.ts +88 -0
  306. package/src/__tests__/package-rename.test.ts +103 -0
  307. package/src/__tests__/pass-selector.unit.test.ts +2 -2
  308. package/src/__tests__/pbr-pipeline.unit.test.ts +14 -21
  309. package/src/__tests__/pipeline-builder-msaa.unit.test.ts +6 -9
  310. package/src/__tests__/pipeline-cache-keying.unit.test.ts +6 -9
  311. package/src/__tests__/pipeline-spec.test.ts +16 -177
  312. package/src/__tests__/pipeline.unit.test.ts +154 -1693
  313. package/src/__tests__/point-light-shadow.dawn.test.ts +33 -42
  314. package/src/__tests__/point-light-shadow.unit.test.ts +19 -60
  315. package/src/__tests__/post-process-error-codes.unit.test.ts +4 -1
  316. package/src/__tests__/post-process-params-component.unit.test.ts +1 -1
  317. package/src/__tests__/post-process-params-extract.unit.test.ts +2 -5
  318. package/src/__tests__/postprocess-camera-consistency.test.ts +4 -7
  319. package/src/__tests__/profiler-assembly.integration.test.ts +1 -1
  320. package/src/__tests__/propagate-transforms.dawn.test.ts +12 -11
  321. package/src/__tests__/record-worldid-isolation.test.ts +7 -29
  322. package/src/__tests__/recover-error-exhaustive.test-d.ts +1 -1
  323. package/src/__tests__/render-error-exhaustive.test-d.ts +81 -71
  324. package/src/__tests__/render-feature-assembly.test-d.ts +20 -9
  325. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +8 -6
  326. package/src/__tests__/render-feature-prepared-graphics.browser.test.ts +60 -558
  327. package/src/__tests__/render-feature-prepared-graphics.dawn.test.ts +57 -544
  328. package/src/__tests__/render-feature-prepared-graphics.fixture.ts +104 -0
  329. package/src/__tests__/render-feature-prepared-graphics.integration.test.ts +40 -248
  330. package/src/__tests__/render-feature-prepared-graphics.regression.integration.test.ts +83 -340
  331. package/src/__tests__/render-feature-recover.integration.test.ts +9 -49
  332. package/src/__tests__/render-feature-runtime-surface.test-d.ts +17 -20
  333. package/src/__tests__/render-schema-consumer.integration.test.ts +20 -13
  334. package/src/__tests__/render-schema-owner-boundary.unit.test.ts +2 -6
  335. package/src/__tests__/render-system-cross-world-overlay-queue.test.ts +5 -5
  336. package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +16 -31
  337. package/src/__tests__/render-system-extract.test.ts +36 -51
  338. package/src/__tests__/render-system-extract.unit.test.ts +360 -0
  339. package/src/__tests__/render-system-fold-bucket.unit.test.ts +3 -5
  340. package/src/__tests__/render-system-fold-fallback.unit.test.ts +6 -3
  341. package/src/__tests__/render-system-fold-material.unit.test.ts +3 -5
  342. package/src/__tests__/render-system-fold-metrics.unit.test.ts +5 -5
  343. package/src/__tests__/render-system-fold-modegate.unit.test.ts +6 -6
  344. package/src/__tests__/render-system-fold.dawn.test.ts +7 -5
  345. package/src/__tests__/render-system-mega.test.ts +292 -190
  346. package/src/__tests__/render-system-owner-split-contract.test.ts +10 -32
  347. package/src/__tests__/render-system-record-multi-material-textureview.test.ts +59 -45
  348. package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +23 -29
  349. package/src/__tests__/render-system-record.test.ts +398 -235
  350. package/src/__tests__/render-system-record.unit.test.ts +25 -26
  351. package/src/__tests__/render-system-skin-bg.unit.test.ts +8 -12
  352. package/src/__tests__/renderer-consumer.test-d.ts +16 -3
  353. package/src/__tests__/renderer-health.unit.test.ts +26 -916
  354. package/src/__tests__/renderer-lifecycle.integration.test.ts +19 -6
  355. package/src/__tests__/renderer-recover.unit.test.ts +49 -1069
  356. package/src/__tests__/renderer-result.test-d.ts +19 -9
  357. package/src/__tests__/renderer-surface.unit.test.ts +3 -5
  358. package/src/__tests__/renderer-test-utils.ts +56 -0
  359. package/src/__tests__/renderer.test-d.ts +59 -0
  360. package/src/__tests__/resolve-asset-handle-err.test.ts +111 -0
  361. package/src/__tests__/resolve-asset-handle.unit.test.ts +64 -0
  362. package/src/__tests__/resolve-depth-only-view.test.ts +1 -1
  363. package/src/__tests__/resolveName-fallback.test.ts +64 -0
  364. package/src/__tests__/resolveName-null-package.test.ts +38 -0
  365. package/src/__tests__/resolveName-unified-entry.test.ts +65 -0
  366. package/src/__tests__/resolveName.test.ts +64 -0
  367. package/src/__tests__/rhi-null-command-flow.unit.test.ts +43 -261
  368. package/src/__tests__/rhi-null-renderer-lifecycle.unit.test.ts +41 -169
  369. package/src/__tests__/roots-to-scene-asset.test.ts +199 -93
  370. package/src/__tests__/roundtrip-primitive.test.ts +351 -0
  371. package/src/__tests__/scene-bare-guid-refs-instantiate.test.ts +123 -0
  372. package/src/__tests__/scene-equirect-roundtrip.test.ts +103 -16
  373. package/src/__tests__/scene-instance-authoring.integration.test.ts +8 -0
  374. package/src/__tests__/scene-instance-bridge.integration.test.ts +1 -1
  375. package/src/__tests__/scene-instance-component.test.ts +1 -1
  376. package/src/__tests__/scene-mount-fixed-point.test.ts +257 -0
  377. package/src/__tests__/scene-mount-roundtrip.test.ts +987 -0
  378. package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +202 -0
  379. package/src/__tests__/scene-sugar-instantiate.test.ts +324 -0
  380. package/src/__tests__/serialize-mounts-roundtrip.test.ts +533 -0
  381. package/src/__tests__/serialize-scene-asset.test.ts +219 -22
  382. package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -3
  383. package/src/__tests__/shadow-csm-cascade-loadop.test.ts +37 -17
  384. package/src/__tests__/shadow-csm-component.test.ts +3 -5
  385. package/src/__tests__/shadow-csm-extract.test.ts +2 -100
  386. package/src/__tests__/shadow-csm-orthoz.test.ts +2 -16
  387. package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +19 -14
  388. package/src/__tests__/shadow-csm-tile-consistency.test.ts +32 -26
  389. package/src/__tests__/shadow-csm-ubo.dawn.test.ts +8 -49
  390. package/src/__tests__/shadow-csm-ubo.test.ts +3 -25
  391. package/src/__tests__/shadow-csm-viewport.browser.test.ts +1 -1
  392. package/src/__tests__/shadow-fields-observable.dawn.test.ts +67 -56
  393. package/src/__tests__/shadow-m1.dawn.test.ts +8 -9
  394. package/src/__tests__/shadow-mesh-ssbo-order.test.ts +11 -27
  395. package/src/__tests__/skin-errors.unit.test.ts +1 -1
  396. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +7 -5
  397. package/src/__tests__/skylight-lazy-projection.test.ts +36 -15
  398. package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +5 -5
  399. package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +47 -64
  400. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +12 -11
  401. package/src/__tests__/sprite-lit-extract-branch.test.ts +1 -1
  402. package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
  403. package/src/__tests__/ssao-bgl.test.ts +16 -9
  404. package/src/__tests__/ssao-buffers.test.ts +2 -2
  405. package/src/__tests__/ssao-data.test.ts +2 -2
  406. package/src/__tests__/ssao-errors.test.ts +1 -1
  407. package/src/__tests__/ssao-passes.test.ts +64 -392
  408. package/src/__tests__/ssao-pipelines.test.ts +1 -1
  409. package/src/__tests__/ssao-uniform-layout.test.ts +8 -6
  410. package/src/__tests__/stencil-outline-pixel.dawn.test.ts +25 -17
  411. package/src/__tests__/swap-chain-format.unit.test.ts +5 -7
  412. package/src/__tests__/systems.unit.test.ts +536 -1326
  413. package/src/__tests__/template-game-default-api-contract.test.ts +362 -0
  414. package/src/__tests__/text.unit.test.ts +56 -33
  415. package/src/__tests__/tilemap-childed-despawn.test.ts +8 -14
  416. package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +8 -12
  417. package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +2 -1
  418. package/src/__tests__/tilemap-chunk-extract.test.ts +13 -17
  419. package/src/__tests__/tilemap-dirty-rebuild.test.ts +7 -11
  420. package/src/__tests__/tilemap-material-cache.test.ts +8 -13
  421. package/src/__tests__/tilemap-multi-atlas.test.ts +12 -32
  422. package/src/__tests__/tilemap-owner-boundary.unit.test.ts +5 -2
  423. package/src/__tests__/tilemap-region-pack.test.ts +8 -12
  424. package/src/__tests__/tilemap-spawn-flip-pivot.test.ts +8 -12
  425. package/src/__tests__/tilemap-uv-inset.test.ts +11 -14
  426. package/src/__tests__/tilemap-validate.test.ts +1 -1
  427. package/src/__tests__/tileset-asset-validate.test.ts +638 -0
  428. package/src/__tests__/transcode-fallback.unit.test.ts +207 -0
  429. package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +36 -28
  430. package/src/__tests__/transient-fields-collect.test.ts +28 -21
  431. package/src/__tests__/transient-runtime-behavior.test.ts +227 -0
  432. package/src/__tests__/transparent-sort-tilemap-sprite-interleave.test.ts +4 -4
  433. package/src/__tests__/variant-selection.unit.test.ts +1 -1
  434. package/src/__tests__/video-extract-bindgroup.dawn.test.ts +89 -136
  435. package/src/__tests__/video-loader-consumption.test.ts +86 -0
  436. package/src/__tests__/video-loader-smoke.dawn.test.ts +60 -0
  437. package/src/__tests__/view-ubo-layout.browser.test.ts +0 -22
  438. package/src/__tests__/world-entity-key.test.ts +1 -1
  439. package/src/__tests__/world-scene-despawn.test.ts +1 -1
  440. package/src/__tests__/world-scene-instantiate.test.ts +2 -36
  441. package/src/__tests__/world-scene-nested.test.ts +1 -1
  442. package/src/__tests__/world-scene-override.test.ts +1 -1
  443. package/src/backend-selection.ts +69 -0
  444. package/src/collect-scene-asset.ts +28 -23
  445. package/src/components/__tests__/camera.test-d.ts +1 -1
  446. package/src/components/__tests__/camera.test.ts +1 -1
  447. package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
  448. package/src/components/__tests__/tile-layer.test-d.ts +1 -1
  449. package/src/components/__tests__/tile-layer.unit.test.ts +2 -2
  450. package/src/createRenderer.ts +24 -36
  451. package/src/errors/environment.ts +1 -1
  452. package/src/index.ts +47 -113
  453. package/src/renderer-host.ts +33 -0
  454. package/src/scene-instances/__tests__/post-spawn-resolve-joints.unit.test.ts +1 -1
  455. package/src/scene-instances/index.ts +4 -0
  456. package/src/scene-utils/mount-override-fold.ts +3 -7
  457. package/src/systems/__tests__/transparent-sort.bench.ts +3 -3
  458. package/src/systems/sprite-animation-tick.ts +1 -1
  459. package/src/systems/transparent-sort.ts +38 -38
  460. package/src/tilemap-register-validate.ts +4 -4
  461. package/dist/__tests__/bind-group-cache-binding.test.d.ts +0 -2
  462. package/dist/__tests__/bind-group-cache-binding.test.d.ts.map +0 -1
  463. package/dist/__tests__/bind-group-cache-frame.test.d.ts +0 -2
  464. package/dist/__tests__/bind-group-cache-frame.test.d.ts.map +0 -1
  465. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts +0 -2
  466. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts.map +0 -1
  467. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts +0 -2
  468. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts.map +0 -1
  469. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts +0 -2
  470. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts.map +0 -1
  471. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts +0 -2
  472. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts.map +0 -1
  473. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts +0 -2
  474. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts.map +0 -1
  475. package/dist/__tests__/fog-producer-manifest.d.ts +0 -131
  476. package/dist/__tests__/fog-producer-manifest.d.ts.map +0 -1
  477. package/dist/__tests__/fog-producer-pixel-probe.d.ts +0 -42
  478. package/dist/__tests__/fog-producer-pixel-probe.d.ts.map +0 -1
  479. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts +0 -2
  480. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts.map +0 -1
  481. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts +0 -2
  482. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts.map +0 -1
  483. package/dist/__tests__/fog-producer-real-fixture.d.ts +0 -5
  484. package/dist/__tests__/fog-producer-real-fixture.d.ts.map +0 -1
  485. package/dist/__tests__/fog-producer-vfx-effect.d.ts +0 -3
  486. package/dist/__tests__/fog-producer-vfx-effect.d.ts.map +0 -1
  487. package/dist/__tests__/fog-scene-asset.integration.test.d.ts +0 -2
  488. package/dist/__tests__/fog-scene-asset.integration.test.d.ts.map +0 -1
  489. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts +0 -2
  490. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts.map +0 -1
  491. package/dist/__tests__/gpu-resource.test.d.ts +0 -2
  492. package/dist/__tests__/gpu-resource.test.d.ts.map +0 -1
  493. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts +0 -2
  494. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts.map +0 -1
  495. package/dist/__tests__/hdrp-buffers.unit.test.d.ts +0 -2
  496. package/dist/__tests__/hdrp-buffers.unit.test.d.ts.map +0 -1
  497. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts +0 -2
  498. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts.map +0 -1
  499. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts +0 -2
  500. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts.map +0 -1
  501. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts +0 -2
  502. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts.map +0 -1
  503. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts +0 -2
  504. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts.map +0 -1
  505. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts +0 -2
  506. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts.map +0 -1
  507. package/dist/__tests__/helpers/primitive-world.d.ts +0 -8
  508. package/dist/__tests__/helpers/primitive-world.d.ts.map +0 -1
  509. package/dist/__tests__/helpers/render-asset-port.d.ts +0 -15
  510. package/dist/__tests__/helpers/render-asset-port.d.ts.map +0 -1
  511. package/dist/__tests__/helpers/scene-asset-port.d.ts +0 -9
  512. package/dist/__tests__/helpers/scene-asset-port.d.ts.map +0 -1
  513. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts +0 -2
  514. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts.map +0 -1
  515. package/dist/__tests__/pipeline-layout-selection.test.d.ts +0 -2
  516. package/dist/__tests__/pipeline-layout-selection.test.d.ts.map +0 -1
  517. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts +0 -2
  518. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts.map +0 -1
  519. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts +0 -2
  520. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts.map +0 -1
  521. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts +0 -2
  522. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts.map +0 -1
  523. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts +0 -2
  524. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts.map +0 -1
  525. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts +0 -2
  526. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts.map +0 -1
  527. package/dist/__tests__/shadow-csm-pssm.test.d.ts +0 -2
  528. package/dist/__tests__/shadow-csm-pssm.test.d.ts.map +0 -1
  529. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts +0 -2
  530. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts.map +0 -1
  531. package/dist/__tests__/shadow-csm-viewport.test.d.ts +0 -2
  532. package/dist/__tests__/shadow-csm-viewport.test.d.ts.map +0 -1
  533. package/dist/__tests__/shadow-m2.dawn.test.d.ts +0 -2
  534. package/dist/__tests__/shadow-m2.dawn.test.d.ts.map +0 -1
  535. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts +0 -2
  536. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts.map +0 -1
  537. package/dist/__tests__/shadow-m3-calibrate.d.ts +0 -83
  538. package/dist/__tests__/shadow-m3-calibrate.d.ts.map +0 -1
  539. package/dist/__tests__/shadow-m3.dawn.test.d.ts +0 -2
  540. package/dist/__tests__/shadow-m3.dawn.test.d.ts.map +0 -1
  541. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts +0 -2
  542. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts.map +0 -1
  543. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts +0 -2
  544. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts.map +0 -1
  545. package/dist/__tests__/temporal-off-path.unit.test.d.ts +0 -2
  546. package/dist/__tests__/temporal-off-path.unit.test.d.ts.map +0 -1
  547. package/dist/__tests__/video-cache-regression.unit.test.d.ts +0 -2
  548. package/dist/__tests__/video-cache-regression.unit.test.d.ts.map +0 -1
  549. package/dist/asset-kind.d.ts +0 -4
  550. package/dist/asset-kind.d.ts.map +0 -1
  551. package/dist/errors/sprite-animation.d.ts +0 -3
  552. package/dist/errors/sprite-animation.d.ts.map +0 -1
  553. package/dist/scene-asset-port.d.ts +0 -17
  554. package/dist/scene-asset-port.d.ts.map +0 -1
  555. package/dist/scene-collect-errors.d.ts +0 -22
  556. package/dist/scene-collect-errors.d.ts.map +0 -1
  557. package/dist/shadow-m3-calibrate.d.ts +0 -40
  558. package/dist/shadow-m3-calibrate.d.ts.map +0 -1
  559. package/src/__tests__/bind-group-cache-binding.test.ts +0 -2513
  560. package/src/__tests__/bind-group-cache-frame.test.ts +0 -1511
  561. package/src/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.ts +0 -204
  562. package/src/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.ts +0 -297
  563. package/src/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.ts +0 -271
  564. package/src/__tests__/dispatch-fullscreen-pass-params.unit.test.ts +0 -321
  565. package/src/__tests__/fog-producer-manifest.ts +0 -162
  566. package/src/__tests__/fog-producer-pixel-probe.ts +0 -263
  567. package/src/__tests__/fog-producer-pixel.browser.test.ts +0 -26
  568. package/src/__tests__/fog-producer-pixel.dawn.test.ts +0 -55
  569. package/src/__tests__/fog-producer-real-fixture.ts +0 -805
  570. package/src/__tests__/fog-producer-vfx-effect.ts +0 -272
  571. package/src/__tests__/fog-scene-asset.integration.test.ts +0 -123
  572. package/src/__tests__/gpu-resource-store-cubemap-status.test.ts +0 -207
  573. package/src/__tests__/gpu-resource.test.ts +0 -1206
  574. package/src/__tests__/hdrp-bgl-slots.browser.test.ts +0 -50
  575. package/src/__tests__/hdrp-buffers.unit.test.ts +0 -70
  576. package/src/__tests__/hdrp-execute-filter.unit.test.ts +0 -200
  577. package/src/__tests__/hdrp-gbuffer-attachments.browser.test.ts +0 -64
  578. package/src/__tests__/hdrp-pipeline-asset-type.test-d.ts +0 -139
  579. package/src/__tests__/hdrp-ssao-boundary.test.ts +0 -237
  580. package/src/__tests__/hdrp-ssao-falsification.test.ts +0 -289
  581. package/src/__tests__/helpers/primitive-world.ts +0 -91
  582. package/src/__tests__/helpers/render-asset-port.ts +0 -65
  583. package/src/__tests__/helpers/scene-asset-port.ts +0 -23
  584. package/src/__tests__/material-derived-coordinates.integration.test.ts +0 -100
  585. package/src/__tests__/pipeline-layout-selection.test.ts +0 -298
  586. package/src/__tests__/post-process-reads-narrowing.test-d.ts +0 -52
  587. package/src/__tests__/post-process-register-roundtrip.dawn.test.ts +0 -230
  588. package/src/__tests__/render-feature-zero-feature.browser.test.ts +0 -152
  589. package/src/__tests__/render-pipeline-trivial.dawn.test.ts +0 -525
  590. package/src/__tests__/shadow-csm-caster-membership.test.ts +0 -232
  591. package/src/__tests__/shadow-csm-pssm.test.ts +0 -142
  592. package/src/__tests__/shadow-csm-temporal.browser.test.ts +0 -145
  593. package/src/__tests__/shadow-csm-viewport.test.ts +0 -74
  594. package/src/__tests__/shadow-m2.dawn.test.ts +0 -394
  595. package/src/__tests__/shadow-m3-calibrate-run.dawn.test.ts +0 -248
  596. package/src/__tests__/shadow-m3-calibrate.ts +0 -203
  597. package/src/__tests__/shadow-m3.dawn.test.ts +0 -288
  598. package/src/__tests__/shadow-probe-control-flow.dawn.test.ts +0 -264
  599. package/src/__tests__/shadow-quality-metrics.dawn.test.ts +0 -324
  600. package/src/__tests__/temporal-off-path.unit.test.ts +0 -69
  601. package/src/__tests__/video-cache-regression.unit.test.ts +0 -186
  602. package/src/asset-kind.ts +0 -7
  603. package/src/errors/sprite-animation.ts +0 -5
  604. package/src/scene-asset-port.ts +0 -32
  605. package/src/scene-collect-errors.ts +0 -30
  606. package/src/shadow-m3-calibrate.ts +0 -171
@@ -0,0 +1,213 @@
1
+ // tweak-20260627-model-loading-smoke-build-perf M4: regression test for the
2
+ // loadByGuid per-frame texture re-upload bug.
3
+ //
4
+ // SYMPTOM: a MaterialAsset loaded via loadByGuid keeps its texture/sampler
5
+ // values as embedded GUID strings (dash-form). The extract stage
6
+ // (render-system-extract.ts) re-resolved each GUID to a column handle EVERY
7
+ // frame by calling `world.allocSharedRef`, which mints a NEW monotonically-
8
+ // increasing slot id per call. The GPU residency cache
9
+ // (GpuResidencyCache.textureGpuHandles) is keyed on handleSlot(handle), so a
10
+ // fresh slot every frame meant the residency check ALWAYS missed -> all
11
+ // textures re-uploaded to the GPU every frame, GPU memory unbounded, per-frame
12
+ // draw time grew linearly until SIGKILL.
13
+ //
14
+ // FIX: the GUID-string -> column-handle resolution is interned per World, so a
15
+ // given (world, guid, brand) mints EXACTLY ONE stable handle reused across
16
+ // frames (architecture-principle §6 idempotency). This file asserts that
17
+ // invariant directly: resolving the same texture GUID across two extract
18
+ // frames yields the SAME handle, and `world.allocSharedRef` is NOT called again
19
+ // on the second frame's resolution.
20
+
21
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
22
+ import { World } from '@forgeax/engine-ecs';
23
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
24
+ import { Camera, MeshFilter, MeshRenderer } from '@forgeax/engine-render';
25
+ import { propagateTransforms, Transform } from '@forgeax/engine-scene';
26
+ import type { Handle, MaterialAsset, MeshAsset, TextureAsset } from '@forgeax/engine-types';
27
+ import { describe, expect, it, vi } from 'vitest';
28
+ import { extractFrame, prepareExtractContext } from '../../../render/src/render-system-extract';
29
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
30
+
31
+ function identityTx() {
32
+ return {
33
+ pos: [0, 0, 0],
34
+ quat: [0, 0, 0, 1],
35
+ scale: [1, 1, 1],
36
+ };
37
+ }
38
+
39
+ function registerQuadMesh(world: World): Handle<'MeshAsset', 'shared'> {
40
+ const positions = new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]);
41
+ return world.allocSharedRef<'MeshAsset', MeshAsset>('MeshAsset', {
42
+ kind: 'mesh',
43
+ vertices: new Float32Array([
44
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
45
+ 1, 0, 0, 0, 0,
46
+ ]),
47
+ indices: new Uint16Array([0, 1, 2]),
48
+ attributes: { position: positions },
49
+ aabb: new Float32Array([0, 0, 0, 1, 1, 1]),
50
+ submeshes: [
51
+ {
52
+ indexOffset: 0,
53
+ indexCount: 3,
54
+ vertexCount: 36,
55
+ topology: 'triangle-list',
56
+ materialSlot: 0,
57
+ },
58
+ ],
59
+
60
+ materialSlots: [{ slotName: 'Default' }],
61
+ });
62
+ }
63
+
64
+ function textureAsset(red = 255): TextureAsset {
65
+ return {
66
+ kind: 'texture',
67
+ width: 1,
68
+ height: 1,
69
+ format: 'rgba8unorm',
70
+ data: new Uint8Array([red, 255, 255, 255]),
71
+ colorSpace: 'linear',
72
+ mipmap: false,
73
+ } as unknown as TextureAsset;
74
+ }
75
+
76
+ // Build a loadByGuid-shaped scene: the material's baseColorTexture paramValue is
77
+ // an embedded GUID STRING (not a pre-minted numeric handle), catalogued to a
78
+ // texture payload. This is exactly the shape Sponza materials have after
79
+ // loadByGuid, and the shape that triggered the per-frame re-upload bug.
80
+ function spawnTexturedRenderable(world: World, assets: AssetRegistry): { textureGuidStr: string } {
81
+ const mesh = registerQuadMesh(world);
82
+
83
+ // Catalog the texture under a GUID; the material references it by GUID string.
84
+ // The embedded ref must be the EXACT dash-form string that
85
+ // AssetRegistry.lookup keys on (AssetGuid.format, lowercased) -- the same
86
+ // shape loadByGuid leaves in a MaterialAsset's values (D-19).
87
+ const textureGuid = AssetGuid.random();
88
+ const textureGuidStr = AssetGuid.format(textureGuid);
89
+ assets.catalog(textureGuid, textureAsset());
90
+
91
+ const matHandle = world.allocSharedRef<'MaterialAsset', MaterialAsset>('MaterialAsset', {
92
+ kind: 'material',
93
+ passes: [{ name: 'Forward', program: { module: 'forgeax::default-unlit' } }],
94
+ values: {
95
+ baseColor: [1, 1, 1],
96
+ // Embedded GUID string -- the loadByGuid texture-ref shape (D-19).
97
+ baseColorTexture: textureGuidStr,
98
+ },
99
+ } as unknown as MaterialAsset);
100
+
101
+ world
102
+ .spawn(
103
+ { component: Transform, data: { ...identityTx(), pos: [0, 0, 5] } },
104
+ {
105
+ component: Camera,
106
+ data: {
107
+ fov: Math.PI / 4,
108
+ aspect: 1,
109
+ near: 0.1,
110
+ far: 100,
111
+ projection: 0,
112
+ left: -1,
113
+ right: 1,
114
+ bottom: -1,
115
+ top: 1,
116
+ },
117
+ },
118
+ )
119
+ .unwrap();
120
+ world
121
+ .spawn(
122
+ { component: Transform, data: identityTx() },
123
+ { component: MeshFilter, data: { assetHandle: mesh } },
124
+ { component: MeshRenderer, data: { materials: [matHandle] } },
125
+ )
126
+ .unwrap();
127
+ propagateTransforms(world);
128
+
129
+ return { textureGuidStr };
130
+ }
131
+
132
+ function baseColorHandleFromFrame(world: World, assets: AssetRegistry): number | undefined {
133
+ const frame = extractFrame(world, prepareExtractContext(world, { assets, pipelineState: null }));
134
+ const renderable = frame.renderables.find(
135
+ (r) => r.material.materialShaderId === 'forgeax::default-unlit',
136
+ );
137
+ const snap = renderable?.material as
138
+ | { readonly baseColorTexture?: Handle<'TextureAsset', 'shared'> }
139
+ | undefined;
140
+ return snap?.baseColorTexture as unknown as number | undefined;
141
+ }
142
+
143
+ describe('M4 loadByGuid texture handle interning (per-frame re-upload regression)', () => {
144
+ it('resolves the same texture GUID to the SAME column handle across two extract frames', () => {
145
+ const world = new World();
146
+ const assets = new AssetRegistry(makeMockShaderRegistry());
147
+ spawnTexturedRenderable(world, assets);
148
+
149
+ const handleFrame1 = baseColorHandleFromFrame(world, assets);
150
+ const handleFrame2 = baseColorHandleFromFrame(world, assets);
151
+
152
+ expect(handleFrame1).toBeDefined();
153
+ expect(handleFrame2).toBeDefined();
154
+ // The whole fix: a stable handle across frames so handleSlot(handle) is
155
+ // stable and the GPU residency cache hits instead of re-uploading.
156
+ expect(handleFrame2).toBe(handleFrame1);
157
+ });
158
+
159
+ it('does NOT call world.allocSharedRef again when re-resolving the same GUID on a later frame', () => {
160
+ const world = new World();
161
+ const assets = new AssetRegistry(makeMockShaderRegistry());
162
+ spawnTexturedRenderable(world, assets);
163
+
164
+ // Warm the intern cache (frame 1 mints the texture handle exactly once).
165
+ baseColorHandleFromFrame(world, assets);
166
+
167
+ // Frame 2: spy on allocSharedRef and confirm the GUID resolution is served
168
+ // from the intern cache -- zero new allocations for the cached texture GUID.
169
+ const allocSpy = vi.spyOn(world, 'allocSharedRef');
170
+ const handleFrame2 = baseColorHandleFromFrame(world, assets);
171
+ expect(handleFrame2).toBeDefined();
172
+
173
+ const textureAllocCalls = allocSpy.mock.calls.filter((c) => c[0] === 'TextureAsset');
174
+ expect(textureAllocCalls.length).toBe(0);
175
+ allocSpy.mockRestore();
176
+ });
177
+
178
+ it('retires the cached allocation grant when the GUID is re-catalogued', () => {
179
+ const world = new World();
180
+ const assets = new AssetRegistry(makeMockShaderRegistry());
181
+ const { textureGuidStr } = spawnTexturedRenderable(world, assets);
182
+
183
+ const oldHandle = baseColorHandleFromFrame(world, assets);
184
+ expect(oldHandle).toBeDefined();
185
+ const replacement = textureAsset(127);
186
+ assets.catalog(textureGuidStr, replacement);
187
+
188
+ const newHandle = baseColorHandleFromFrame(world, assets);
189
+ expect(newHandle).toBeDefined();
190
+ expect(newHandle).not.toBe(oldHandle);
191
+ expect(
192
+ world.sharedRefs.resolve(newHandle as unknown as Handle<'TextureAsset', 'shared'>),
193
+ ).toMatchObject({ ok: true, value: replacement });
194
+ expect(
195
+ world.sharedRefs.refcount(oldHandle as unknown as Handle<'TextureAsset', 'shared'>),
196
+ ).toBe(0);
197
+ });
198
+
199
+ it('drops the cached allocation grant when the GUID is invalidated', () => {
200
+ const world = new World();
201
+ const assets = new AssetRegistry(makeMockShaderRegistry());
202
+ const { textureGuidStr } = spawnTexturedRenderable(world, assets);
203
+
204
+ const handle = baseColorHandleFromFrame(world, assets);
205
+ expect(handle).toBeDefined();
206
+ assets.invalidate(textureGuidStr);
207
+
208
+ expect(baseColorHandleFromFrame(world, assets)).toBeUndefined();
209
+ expect(world.sharedRefs.refcount(handle as unknown as Handle<'TextureAsset', 'shared'>)).toBe(
210
+ 0,
211
+ );
212
+ });
213
+ });
@@ -0,0 +1,146 @@
1
+ // loader-extract-graceful.test.ts -- M4 / w24 integration test for the
2
+ // paramSchema-driven loader/extract handoff.
3
+ //
4
+ // feat-20260613-material-paramschema-driven-binding M4 / w24.
5
+ //
6
+ // Decision anchors (plan-strategy section 2 + section 5.3):
7
+ // - D-5 loader does not pre-filter texture fields by hardcoded name; the
8
+ // paramSchema-derived textureFieldNames is the SSOT. Cross-worktree
9
+ // shader-late-register falls back to "try every int paramValue"
10
+ // gracefully; the extract layer's paramSchema validation catches
11
+ // misclassifications and routes through MISSING_TEXTURE_HANDLE.
12
+ // - R-4 shader-late-register risk: material loaded before its shader is
13
+ // registered. The graceful fallback keeps the load path live.
14
+ //
15
+ // Four scenarios (plan-strategy section 5.3 acceptance), updated for
16
+ // feat-20260614 M8 (D-19): the loader no longer resolves a texture-typed
17
+ // paramValue to a runtime handle. It maps the refs[] index to the embedded
18
+ // sub-asset GUID string; the ECS/render side resolves GUID -> column handle
19
+ // at use time (world.allocSharedRef). `LoadContext.resolveRefSync` is gone.
20
+ // (1) shader registered + texture-typed paramValue + valid refs[] index
21
+ // -> loader rewrites the field to the refs[] GUID string.
22
+ // (2) shader registered + texture-typed paramValue + index out of range
23
+ // -> loader drops the field; record stage falls back to MISSING_TEXTURE_HANDLE.
24
+ // (3) shader NOT registered yet (cross-worktree R-4) + int paramValue
25
+ // -> graceful fallback resolves every in-range int to its refs[] GUID.
26
+ // (4) shader registered + scalar-typed paramValue (metallic = 0) whose
27
+ // value happens to land in [0, refs.length) -> paramSchema-aware path
28
+ // skips it; the field stays as the original int.
29
+
30
+ import { materialLoader } from '@forgeax/engine-assets-runtime';
31
+ import type { LoadContext, ParamSchemaEntry } from '@forgeax/engine-types';
32
+ import { derive } from '@forgeax/engine-types';
33
+ import { describe, expect, it } from 'vitest';
34
+
35
+ function makeCtx(opts: {
36
+ shaderTextureFieldNames?: (shaderId: string) => ReadonlySet<string> | undefined;
37
+ }): LoadContext {
38
+ const ctx: LoadContext = {
39
+ fetchBinary: async () => ({ ok: false as const, error: new Error('no binary') }),
40
+ resolveRef: async () => ({ ok: false as const, error: new Error('no ref') }),
41
+ transcodeCaps: { bc: false, etc2: false, astc: false },
42
+ device: undefined,
43
+ };
44
+ if (opts.shaderTextureFieldNames) {
45
+ ctx.getMaterialShaderTextureFieldNames = opts.shaderTextureFieldNames;
46
+ }
47
+ return ctx;
48
+ }
49
+
50
+ const standardPbrSchema: readonly ParamSchemaEntry[] = [
51
+ { name: 'baseColor', type: 'color', default: [1, 1, 1, 1] },
52
+ { name: 'metallic', type: 'f32', default: 0 },
53
+ { name: 'roughness', type: 'f32', default: 0.5 },
54
+ { name: 'baseColorTexture', type: 'texture2d' },
55
+ { name: 'normalTexture', type: 'texture2d' },
56
+ ];
57
+
58
+ describe('loader-extract graceful handoff (M4 w24)', () => {
59
+ it('(1) shader registered + valid texture refs[] index resolves to a structured texture value', () => {
60
+ const textureFields = derive(standardPbrSchema).textureFieldNames;
61
+ const ctx = makeCtx({
62
+ shaderTextureFieldNames: (id) =>
63
+ id === 'forgeax::default-standard-pbr' ? textureFields : undefined,
64
+ });
65
+ const out = materialLoader.load(
66
+ {
67
+ passes: [{ program: { module: 'forgeax::default-standard-pbr' } }],
68
+ values: { baseColorTexture: 0, metallic: 0.5 },
69
+ },
70
+ ['tex-bc-guid'],
71
+ ctx,
72
+ );
73
+ expect(out).toMatchObject({ kind: 'material' });
74
+ const pv = (out as { values: Record<string, unknown> }).values;
75
+ // D-19: texture field rewritten to the structured asset value (not a handle).
76
+ expect(pv.baseColorTexture).toEqual({ texture: 'tex-bc-guid' });
77
+ // Scalar field unchanged.
78
+ expect(pv.metallic).toBe(0.5);
79
+ });
80
+
81
+ it('(2) shader registered + texture refs[] index out of range -> field dropped', () => {
82
+ const textureFields = derive(standardPbrSchema).textureFieldNames;
83
+ const ctx = makeCtx({
84
+ shaderTextureFieldNames: (id) =>
85
+ id === 'forgeax::default-standard-pbr' ? textureFields : undefined,
86
+ });
87
+ const out = materialLoader.load(
88
+ {
89
+ passes: [{ program: { module: 'forgeax::default-standard-pbr' } }],
90
+ // index 5 is out of range for refs.length=1 -> dropped.
91
+ values: { baseColorTexture: 5 },
92
+ },
93
+ ['tex-bc-guid'],
94
+ ctx,
95
+ );
96
+ expect(out).toMatchObject({ kind: 'material' });
97
+ const pv = (out as { values: Record<string, unknown> }).values;
98
+ // Loader drops the field; record stage falls back to MISSING_TEXTURE_HANDLE.
99
+ expect('baseColorTexture' in pv).toBe(false);
100
+ });
101
+
102
+ it('(3) shader NOT registered (R-4 cross-worktree) -> graceful "try every int" fallback', () => {
103
+ // No paramSchema lookup available -> getMaterialShaderTextureFieldNames
104
+ // returns undefined for every shader id.
105
+ const ctx = makeCtx({
106
+ shaderTextureFieldNames: () => undefined,
107
+ });
108
+ const out = materialLoader.load(
109
+ {
110
+ passes: [{ program: { module: 'forgeax::user-defined' } }],
111
+ values: { customTexture: 0 },
112
+ },
113
+ ['tex-guid'],
114
+ ctx,
115
+ );
116
+ expect(out).toMatchObject({ kind: 'material' });
117
+ const pv = (out as { values: Record<string, unknown> }).values;
118
+ // Graceful fallback resolves any in-range int to its refs[] GUID string.
119
+ expect(pv.customTexture).toBe('tex-guid');
120
+ });
121
+
122
+ it('(4) shader registered + scalar paramValue with refs[] index in range -> NOT misclassified', () => {
123
+ const textureFields = derive(standardPbrSchema).textureFieldNames;
124
+ const ctx = makeCtx({
125
+ shaderTextureFieldNames: (id) =>
126
+ id === 'forgeax::default-standard-pbr' ? textureFields : undefined,
127
+ });
128
+ const out = materialLoader.load(
129
+ {
130
+ passes: [{ program: { module: 'forgeax::default-standard-pbr' } }],
131
+ // metallic = 0 is an int in [0, refs.length=1) — would misclassify
132
+ // under a naive "try every int" loader. paramSchema-aware path
133
+ // declares metallic as 'f32', so it skips resolution.
134
+ values: { baseColorTexture: 0, metallic: 0 },
135
+ },
136
+ ['tex-bc-guid'],
137
+ ctx,
138
+ );
139
+ expect(out).toMatchObject({ kind: 'material' });
140
+ const pv = (out as { values: Record<string, unknown> }).values;
141
+ // Texture field still resolves to the structured asset value.
142
+ expect(pv.baseColorTexture).toEqual({ texture: 'tex-bc-guid' });
143
+ // Scalar field unchanged: metallic stays 0.
144
+ expect(pv.metallic).toBe(0);
145
+ });
146
+ });
@@ -0,0 +1,213 @@
1
+ // loader name survival through JSON roundtrip — AC-08 (feat-20260618 w20).
2
+ //
3
+ // Red-first: written before w15 wires entry.name -> registerPackage.
4
+ //
5
+ // dawn smoke walks the in-memory register path and skips the
6
+ // JSON.stringify -> fetch -> JSON.parse pack-body path (AGENTS.md smoke gate +
7
+ // memory typed-array-json-roundtrip-asymmetric-loader-contract). This test
8
+ // drives the prod loadByGuid path with a JSON-roundtripped pack-index so a name
9
+ // that does not survive the roundtrip is caught here.
10
+ //
11
+ // Coverage:
12
+ // AC-08 sync — two meshes sharing a .pack.json, each with a pack-index name;
13
+ // after loadByGuid (parseAssetPayload sync branch) resolveName
14
+ // returns each stored name.
15
+ // AC-08 async — a texture in its own (single-asset) package; after loadByGuid
16
+ // (texture upstream async branch) resolveName returns the
17
+ // basename derived from its package path. Without the entry ->
18
+ // Package wiring the texture would land in a null package and
19
+ // resolveName would be '' -- so basename here still proves the
20
+ // async load path registered the package post-roundtrip.
21
+ // FALSIFY — the same pack with the entry name stripped degrades to
22
+ // basename(path), proving the assertion is name-sensitive (not
23
+ // a tautology). The FALSIFY block does not gate CI; it documents
24
+ // discriminating power.
25
+
26
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
27
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
28
+ import type { MeshAsset as TypesMeshAsset } from '@forgeax/engine-types';
29
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
30
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
31
+
32
+ const MESH_A = '70000000-0000-4000-7000-000000000001';
33
+ const MESH_B = '70000000-0000-4000-7000-000000000002';
34
+ const TEX = '70000000-0000-4000-7000-0000000000aa';
35
+ const SHARED_PACK_URL = '/packs/char.pack.json';
36
+ const TEX_URL = '/assets/diffuse.pack.json';
37
+
38
+ function parseGuid(s: string): AssetGuid {
39
+ const r = AssetGuid.parse(s);
40
+ if (!r.ok) throw new Error(`invalid test GUID: ${s}`);
41
+ return r.value;
42
+ }
43
+
44
+ function makeRegistry(): AssetRegistry {
45
+ return new AssetRegistry(makeMockShaderRegistry());
46
+ }
47
+
48
+ const MESH_PAYLOAD_A = {
49
+ vertices: [
50
+ -0.5, 0, 0.5, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0.5, 0, 0.5, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0.5, 0, -0.5,
51
+ 0, 1, 0, 1, 1, 1, 0, 0, 1,
52
+ ],
53
+ indices: [0, 1, 2],
54
+ attributes: {},
55
+ submeshes: [{ indexOffset: 0, indexCount: 3, vertexCount: 3, topology: 'triangle-list' }],
56
+ };
57
+ const MESH_PAYLOAD_B = {
58
+ vertices: [
59
+ 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
60
+ 1, 1, 0, 0,
61
+ ],
62
+ indices: [1, 0, 2],
63
+ attributes: {},
64
+ submeshes: [{ indexOffset: 0, indexCount: 3, vertexCount: 3, topology: 'triangle-list' }],
65
+ };
66
+
67
+ function makeSharedPack(): unknown {
68
+ return {
69
+ schemaVersion: '2.0.0',
70
+ kind: 'internal-text-package',
71
+ assets: [
72
+ { guid: MESH_A, kind: 'mesh', payload: MESH_PAYLOAD_A, refs: [], artifacts: {} },
73
+ { guid: MESH_B, kind: 'mesh', payload: MESH_PAYLOAD_B, refs: [], artifacts: {} },
74
+ ],
75
+ };
76
+ }
77
+
78
+ const TEX_METADATA = {
79
+ kind: 'texture',
80
+ width: 1,
81
+ height: 1,
82
+ format: 'rgba8unorm',
83
+ colorSpace: 'srgb',
84
+ mipmap: false,
85
+ };
86
+
87
+ // `includeNames=false` is the FALSIFY variant (entry.name stripped).
88
+ function makePackIndex(includeNames: boolean): unknown[] {
89
+ const named = (n: string) => (includeNames ? { name: n } : {});
90
+ return [
91
+ {
92
+ guid: MESH_A,
93
+ packageUrl: SHARED_PACK_URL,
94
+ kind: 'mesh',
95
+ sourcePath: 'char.glb',
96
+ ...named('Body'),
97
+ },
98
+ {
99
+ guid: MESH_B,
100
+ packageUrl: SHARED_PACK_URL,
101
+ kind: 'mesh',
102
+ sourcePath: 'char.glb',
103
+ ...named('Head'),
104
+ },
105
+ {
106
+ guid: TEX,
107
+ packageUrl: TEX_URL,
108
+ kind: 'texture',
109
+ sourcePath: 'diffuse.png',
110
+ ...named('Diffuse'),
111
+ },
112
+ ];
113
+ }
114
+
115
+ // Roundtrip every fetched body through JSON.stringify -> JSON.parse, mirroring
116
+ // the dev-server pack-body transport that dawn smoke skips.
117
+ function jsonRoundtrip(value: unknown): unknown {
118
+ return JSON.parse(JSON.stringify(value));
119
+ }
120
+
121
+ function installFetch(includeNames: boolean): void {
122
+ const packIndex = jsonRoundtrip(makePackIndex(includeNames));
123
+ const sharedPack = jsonRoundtrip(makeSharedPack());
124
+ const texBytes = new Uint8Array(1 * 1 * 4).fill(200);
125
+ globalThis.fetch = vi.fn(async (url: string | URL) => {
126
+ const u = String(url);
127
+ if (u.includes('pack-index.json')) {
128
+ return new Response(JSON.stringify(packIndex), { status: 200 });
129
+ }
130
+ if (u === SHARED_PACK_URL) {
131
+ return new Response(JSON.stringify(sharedPack), { status: 200 });
132
+ }
133
+ if (u === TEX_URL) {
134
+ return new Response(
135
+ JSON.stringify({
136
+ schemaVersion: '2.0.0',
137
+ kind: 'internal-text-package',
138
+ assets: [
139
+ {
140
+ guid: TEX,
141
+ kind: 'texture',
142
+ payload: TEX_METADATA,
143
+ refs: [],
144
+ artifacts: {
145
+ body: { path: 'diffuse.bin', mediaType: 'application/x-forgeax-rgba8' },
146
+ },
147
+ },
148
+ ],
149
+ }),
150
+ { status: 200 },
151
+ );
152
+ }
153
+ if (u === '/assets/diffuse.bin') {
154
+ return new Response(texBytes, { status: 200 });
155
+ }
156
+ return new Response('', { status: 404 });
157
+ }) as unknown as typeof globalThis.fetch;
158
+ }
159
+
160
+ describe('loader name survival (AC-08)', () => {
161
+ let originalFetch: typeof globalThis.fetch | undefined;
162
+ beforeEach(() => {
163
+ originalFetch = globalThis.fetch;
164
+ });
165
+ afterEach(() => {
166
+ if (originalFetch !== undefined) globalThis.fetch = originalFetch;
167
+ vi.restoreAllMocks();
168
+ });
169
+
170
+ it('sync branch: multi-asset mesh names survive the JSON roundtrip', async () => {
171
+ installFetch(true);
172
+ const reg = makeRegistry();
173
+ reg.configurePackIndex('/pack-index.json');
174
+
175
+ const rA = await reg.loadByGuid<TypesMeshAsset>(parseGuid(MESH_A));
176
+ const rB = await reg.loadByGuid<TypesMeshAsset>(parseGuid(MESH_B));
177
+ expect(rA.ok).toBe(true);
178
+ expect(rB.ok).toBe(true);
179
+
180
+ expect(reg.resolveName(MESH_A)).toBe('Body');
181
+ expect(reg.resolveName(MESH_B)).toBe('Head');
182
+ });
183
+
184
+ it('async branch: texture package resolves via the async load path post-roundtrip', async () => {
185
+ installFetch(true);
186
+ const reg = makeRegistry();
187
+ reg.configurePackIndex('/pack-index.json');
188
+
189
+ const r = await reg.loadByGuid(parseGuid(TEX));
190
+ expect(r.ok).toBe(true);
191
+ // Single-asset texture package -> basename(path) (AC-01). The wiring is what
192
+ // makes this non-empty: without entry -> Package the texture lands in a null
193
+ // package and resolveName would be ''.
194
+ expect(reg.resolveName(TEX)).toBe('diffuse.pack.json');
195
+ });
196
+
197
+ it('FALSIFY: stripped entry.name degrades to basename, proving name-sensitivity', async () => {
198
+ installFetch(false);
199
+ const reg = makeRegistry();
200
+ reg.configurePackIndex('/pack-index.json');
201
+
202
+ const rA = await reg.loadByGuid<TypesMeshAsset>(parseGuid(MESH_A));
203
+ const rB = await reg.loadByGuid<TypesMeshAsset>(parseGuid(MESH_B));
204
+ expect(rA.ok).toBe(true);
205
+ expect(rB.ok).toBe(true);
206
+
207
+ // Multi-asset package with no stored names -> basename(cooked packageUrl),
208
+ // NOT the original 'Body' / 'Head'. If the assertion still
209
+ // saw 'Body', the name path would be a tautology.
210
+ expect(reg.resolveName(MESH_A)).toBe('char.pack.json');
211
+ expect(reg.resolveName(MESH_B)).toBe('char.pack.json');
212
+ });
213
+ });
@@ -11,9 +11,10 @@
11
11
  // unused-directive error and turn this file red.
12
12
 
13
13
  import { World } from '@forgeax/engine-ecs';
14
- import { GlyphText, Tilemap } from '@forgeax/engine-render/authoring';
15
- import { Camera } from '@forgeax/engine-render/internal';
14
+ import { Camera } from '@forgeax/engine-render';
16
15
  import { describe, it } from 'vitest';
16
+ import { GlyphText } from '../../../render/src/components/glyph-text';
17
+ import { Tilemap } from '../../../render/src/components/tilemap';
17
18
 
18
19
  describe('w12 -- residual per-axis M3 keys are compile errors (AC-04)', () => {
19
20
  it('Camera rejects residual clearR at spawn call-site', () => {