@forgeax/engine-runtime 0.1.4 → 0.1.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 (606) hide show
  1. package/README.md +65 -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 +7 -4
  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 +20 -82
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.mjs +107 -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 +608 -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 +24 -9
  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 +1227 -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 +31 -511
  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 +21 -25
  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 +117 -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 +65 -559
  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 +61 -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 +56 -260
  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 +15 -14
  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 +68 -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 +35 -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 +51 -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
@@ -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', () => {
@@ -1,49 +1,119 @@
1
+ import { World } from '@forgeax/engine-ecs';
1
2
  import { vec3 } from '@forgeax/engine-math';
3
+ import { describe, expect, it } from 'vitest';
2
4
  import {
5
+ applyMaterialTextureUvScales,
6
+ BUILTIN_USER_REGION_TEXTURE_FIELDS,
7
+ buildPbrMaterialUboPayload,
8
+ materialTextureUvScale,
3
9
  userRegionTextureFieldOrder,
4
- writeMaterialSnapshotPayload,
5
- } from '@forgeax/engine-render/internal';
6
- import { derive } from '@forgeax/engine-types';
7
- import { describe, expect, it } from 'vitest';
10
+ } from '../../../render/src/record/main-pass-material';
8
11
 
9
- describe('derived material texture coordinates (w29)', () => {
10
- it('uses only the effective schema for texture field order', () => {
11
- expect(userRegionTextureFieldOrder(derive([]))).toEqual([]);
12
- expect(userRegionTextureFieldOrder(derive([{ name: 'albedo', type: 'texture2d' }]))).toEqual([
13
- 'albedo',
14
- ]);
12
+ describe('material texture UV scale [w37]', () => {
13
+ it('maps a non-aligned BC7 logical edge below padded physical storage', () => {
14
+ const scale = materialTextureUvScale({ width: 2085, height: 1573, format: 'bc7-rgba-unorm' });
15
+ expect(scale).toEqual([2085 / 2088, 1573 / 1576]);
16
+ expect(scale[0]).toBeLessThan(1);
17
+ expect(scale[1]).toBeLessThan(1);
18
+ });
19
+
20
+ it('uses identity scale for uncompressed and fallback texture bindings', () => {
21
+ expect(materialTextureUvScale(undefined)).toEqual([1, 1]);
22
+ expect(materialTextureUvScale({ width: 17, height: 9, format: 'rgba8unorm' })).toEqual([1, 1]);
15
23
  });
16
24
 
17
- it('writes coordinate records from the typed projection without fixed offsets', () => {
18
- const result = writeMaterialSnapshotPayload({
25
+ it('keeps builtin texture slots when compatibility param schemas are empty or numeric-only', () => {
26
+ expect(userRegionTextureFieldOrder([])).toEqual(BUILTIN_USER_REGION_TEXTURE_FIELDS);
27
+ expect(userRegionTextureFieldOrder([{ name: 'baseColor', type: 'color' }])).toEqual(
28
+ BUILTIN_USER_REGION_TEXTURE_FIELDS,
29
+ );
30
+ });
31
+
32
+ it('writes each slot set and transform into the builtin PBR payload', () => {
33
+ const payload = buildPbrMaterialUboPayload({
19
34
  baseColor: vec3.create(1, 1, 1),
20
35
  metallic: 0,
21
36
  roughness: 0.5,
22
- materialParamSchema: [
23
- { name: 'baseColorTexture', type: 'texture2d' },
24
- { name: 'normalTexture', type: 'texture2d' },
25
- ],
37
+ materialShaderId: 'forgeax::default-standard-pbr',
26
38
  textureCoordinates: new Map([
27
39
  [
28
40
  'baseColorTexture',
29
- {
30
- set: 1,
31
- transform: { offset: [0.125, 0.25], scale: [2, 3], rotation: 0.5 },
32
- physicalUvScale: [0.9, 0.8],
33
- },
34
- ],
35
- [
36
- 'normalTexture',
37
- {
38
- set: 0,
39
- transform: { offset: [0.75, 0.25], scale: [4, 5], rotation: 0 },
40
- physicalUvScale: [1, 1],
41
- },
41
+ { set: 1, transform: { offset: [0.125, 0.25], scale: [2, 3], rotation: 0.5 } },
42
42
  ],
43
+ ['normalTexture', { set: 0, transform: { offset: [0.75, 0.25], scale: [4, 5] } }],
43
44
  ]),
44
45
  });
46
+ applyMaterialTextureUvScales(
47
+ payload,
48
+ {
49
+ baseColor: vec3.create(1, 1, 1),
50
+ metallic: 0,
51
+ roughness: 0.5,
52
+ materialShaderId: 'forgeax::default-standard-pbr',
53
+ textureCoordinates: new Map([
54
+ [
55
+ 'baseColorTexture',
56
+ { set: 1, transform: { offset: [0.125, 0.25], scale: [2, 3], rotation: 0.5 } },
57
+ ],
58
+ ['normalTexture', { set: 0, transform: { offset: [0.75, 0.25], scale: [4, 5] } }],
59
+ ]),
60
+ },
61
+ new World(),
62
+ );
63
+ const f32 = new Float32Array(payload.buffer, payload.byteOffset, payload.byteLength / 4);
64
+ expect(Array.from(f32.slice(24, 32))).toEqual([0.125, 0.25, 2, 3, 1, 0.5, 1, 1]);
65
+ expect(Array.from(f32.slice(40, 48))).toEqual([0.75, 0.25, 4, 5, 0, 0, 1, 1]);
66
+ });
67
+
68
+ it('keeps identity UV records for metadata-free standard and builtin schema materials', () => {
69
+ const standard = buildPbrMaterialUboPayload({
70
+ baseColor: vec3.create(1, 1, 1),
71
+ metallic: 0,
72
+ roughness: 0.5,
73
+ materialShaderId: 'forgeax::default-standard-pbr',
74
+ });
75
+ applyMaterialTextureUvScales(
76
+ standard,
77
+ {
78
+ baseColor: vec3.create(1, 1, 1),
79
+ metallic: 0,
80
+ roughness: 0.5,
81
+ materialShaderId: 'forgeax::default-standard-pbr',
82
+ },
83
+ new World(),
84
+ );
85
+ expect(
86
+ Array.from(
87
+ new Float32Array(standard.buffer, standard.byteOffset, standard.byteLength / 4).slice(
88
+ 24,
89
+ 72,
90
+ ),
91
+ ),
92
+ ).toEqual([
93
+ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
94
+ 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
95
+ ]);
45
96
 
46
- expect(result.ok).toBe(true);
47
- if (result.ok) expect(result.value.byteLength).toBeGreaterThan(0);
97
+ const unlit = buildPbrMaterialUboPayload({
98
+ baseColor: vec3.create(1, 1, 1),
99
+ metallic: 0,
100
+ roughness: 0.5,
101
+ materialShaderId: 'forgeax::default-unlit',
102
+ });
103
+ applyMaterialTextureUvScales(
104
+ unlit,
105
+ {
106
+ baseColor: vec3.create(1, 1, 1),
107
+ metallic: 0,
108
+ roughness: 0.5,
109
+ materialShaderId: 'forgeax::default-unlit',
110
+ },
111
+ new World(),
112
+ );
113
+ expect(
114
+ Array.from(
115
+ new Float32Array(unlit.buffer, unlit.byteOffset, unlit.byteLength / 4).slice(8, 16),
116
+ ),
117
+ ).toEqual([0, 0, 1, 1, 0, 0, 1, 1]);
48
118
  });
49
119
  });
@@ -16,7 +16,7 @@
16
16
  // Grep gate: passKind:'deferred' / passKind:'forward' / passKind:'shadow-caster'
17
17
  // each hit >=1 in packages/runtime/src/materials.ts
18
18
 
19
- import { Materials, routeMaterialPipeline } from '@forgeax/engine-render/internal';
19
+ import { Materials } from '@forgeax/engine-render';
20
20
  import type { PassKind } from '@forgeax/engine-types';
21
21
  import { describe, expect, it } from 'vitest';
22
22
 
@@ -183,8 +183,8 @@ describe('Materials.standard multi-pass (w14)', () => {
183
183
  });
184
184
  expect(mat.values?.emissive).toEqual([0.1, 0.2, 0.3]);
185
185
  expect(mat.values?.emissiveIntensity).toBe(2);
186
- expect(mat.values?.baseColorTexture).toEqual({ texture: 42 });
187
- expect(mat.values?.occlusionTexture).toEqual({ texture: 84 });
186
+ expect(mat.values?.baseColorTexture).toBe(42);
187
+ expect(mat.values?.occlusionTexture).toBe(84);
188
188
  expect(mat.values?.occlusionStrength).toBe(0.75);
189
189
  });
190
190
 
@@ -242,30 +242,13 @@ describe('Materials.unlit forward-only (w14)', () => {
242
242
  const mat = Materials.unlit([1, 1, 1, 1], { alphaCutoff: 0.1 });
243
243
  expect(mat.values?.alphaCutoff).toBe(0.1);
244
244
  });
245
- });
246
-
247
- describe('material pipeline stop-draw routing (w28)', () => {
248
- it('returns the closed specialization error without a fallback pipeline', () => {
249
- const result = routeMaterialPipeline({
250
- projection: {
251
- materialGuid: 'material-slot',
252
- specializationKey: 'stale-specialization',
253
- artifactHash: 'sha256:missing',
254
- layoutIdentity: 'sha256:layout',
255
- passes: [],
256
- runtimeValues: {},
257
- staticSelection: ['useNormalMap'],
258
- },
259
- lookupArtifact: () => undefined,
260
- });
261
245
 
262
- expect(result).toMatchObject({
263
- kind: 'error',
264
- error: {
265
- code: 'material-specialization-not-cooked',
266
- detail: { material: 'material-slot', staticSelection: ['useNormalMap'] },
267
- },
268
- });
269
- expect(result).not.toHaveProperty('artifact');
246
+ it('keeps unlit numeric fields before texture coordinates in shader ABI order', () => {
247
+ const mat = Materials.unlit([1, 1, 1, 1]);
248
+ expect(mat.parameters).toEqual([
249
+ { name: 'baseColor', type: 'color' },
250
+ { name: 'alphaCutoff', type: 'f32', optional: true },
251
+ { name: 'baseColorTexture', type: 'texture', optional: true },
252
+ ]);
270
253
  });
271
254
  });
@@ -0,0 +1,28 @@
1
+ import { unpackMeshBinV4 } from '@forgeax/engine-assets-runtime';
2
+ import { describe, expect, it } from 'vitest';
3
+
4
+ describe('mesh-bin v4 closed error contract', () => {
5
+ it.each([
6
+ new Uint8Array(10),
7
+ new Uint8Array([2, 0, 0, 0]),
8
+ new Uint8Array([3, 0, 0, 0]),
9
+ ])('rejects malformed or legacy bytes with structured recovery', (bytes) => {
10
+ const result = unpackMeshBinV4(bytes, 'runtime://contract');
11
+ expect(result.ok).toBe(false);
12
+ if (result.ok) return;
13
+ expect(result.error.subject).toBe('mesh-bin');
14
+ expect(result.error.sourceKey).toBe('runtime://contract');
15
+ expect(result.error.expected).toContain('v4');
16
+ expect(result.error.recovery).toContain('re-cook');
17
+ const detail = result.error.detail;
18
+ expect(detail).toBeDefined();
19
+ if (
20
+ detail === undefined ||
21
+ !('code' in detail) ||
22
+ detail.code !== 'mesh-bin-contract-violation'
23
+ )
24
+ return;
25
+ expect(detail.sourceKey).toBe('runtime://contract');
26
+ expect(detail.actual.byteLength).toBe(bytes.byteLength);
27
+ });
28
+ });
@@ -0,0 +1,149 @@
1
+ // mesh-bin-skin-roundtrip.unit.test.ts -- feat-20260611 (w17-b)
2
+ //
3
+ // Roundtrip tests for the skinIndex / skinWeight payload extension to the
4
+ // mesh.bin binary sidecar format. The pre-feat layout (16-byte header +
5
+ // vertices + indices + JSON tail) intentionally dropped per-stream
6
+ // typed-array attributes since position / normal / uv / tangent duplicate
7
+ // the interleaved buffer. Skin attributes are an exception: the runtime
8
+ // pbr-skin VBO layout reads `attributes.skinIndex` / `attributes.skinWeight`
9
+ // directly (parallel to the interleaved 18F stride), so the .bin must
10
+ // preserve them or skinned meshes render black.
11
+ //
12
+ // Coverage:
13
+ // (A) skinned mesh -- skinIndex (Uint16Array) + skinWeight (Float32Array)
14
+ // survive packMeshBin -> unpackMeshBin with byte-exact values.
15
+ // (B) back-compat -- unskinned mesh produces a .bin with no skin streams;
16
+ // unpackMeshBin returns no skinIndex / skinWeight keys.
17
+ // (C) edge -- vertex count zero (empty mesh, empty skin streams) does
18
+ // not panic and unpacks to a vertex-less mesh with no skin streams.
19
+
20
+ import { unpackMeshBinV4 } from '@forgeax/engine-assets-runtime';
21
+ import { packMeshBinV4 } from '@forgeax/engine-import';
22
+ import { describe, expect, it } from 'vitest';
23
+
24
+ const FLOATS_PER_VERTEX_18 = 18;
25
+ const FLOATS_PER_VERTEX_12 = 12;
26
+
27
+ describe('mesh-bin skinIndex / skinWeight roundtrip (feat-20260611 w17-b)', () => {
28
+ it('preserves skinIndex (Uint16Array) and skinWeight (Float32Array) through pack -> unpack', () => {
29
+ const vertexCount = 4;
30
+ const vertices = new Float32Array(vertexCount * FLOATS_PER_VERTEX_18);
31
+ for (let i = 0; i < vertices.length; i++) vertices[i] = i * 0.5;
32
+ const indices = new Uint16Array([0, 1, 2, 0, 2, 3]);
33
+ const skinIndex = new Uint16Array(vertexCount * 4);
34
+ const skinWeight = new Float32Array(vertexCount * 4);
35
+ for (let i = 0; i < skinIndex.length; i++) {
36
+ skinIndex[i] = i;
37
+ skinWeight[i] = i / skinIndex.length;
38
+ }
39
+
40
+ const packed = packMeshBinV4(
41
+ {
42
+ vertices,
43
+ indices,
44
+ attributes: {
45
+ position: new Float32Array(vertexCount * 3),
46
+ normal: new Float32Array(vertexCount * 3),
47
+ uv: new Float32Array(vertexCount * 2),
48
+ tangent: new Float32Array(vertexCount * 4),
49
+ skinIndex,
50
+ skinWeight,
51
+ },
52
+ },
53
+ 'runtime://skin-roundtrip',
54
+ );
55
+ expect(packed.ok).toBe(true);
56
+ if (!packed.ok) return;
57
+ const unpacked = unpackMeshBinV4(packed.value, 'runtime://skin-roundtrip');
58
+ expect(unpacked.ok).toBe(true);
59
+ if (!unpacked.ok) return;
60
+
61
+ expect(unpacked.value.vertices).toBeInstanceOf(Float32Array);
62
+ expect(unpacked.value.vertices.length).toBe(vertices.length);
63
+ expect(unpacked.value.vertices.length).toBe(vertices.length);
64
+
65
+ expect(unpacked.value.indices).toBeInstanceOf(Uint16Array);
66
+ expect(Array.from(unpacked.value.indices ?? [])).toEqual(Array.from(indices));
67
+
68
+ const decodedSkinIndex = unpacked.value.attributes.skinIndex;
69
+ expect(decodedSkinIndex).toBeInstanceOf(Uint16Array);
70
+ if (!(decodedSkinIndex instanceof Uint16Array)) return;
71
+ expect(decodedSkinIndex.length).toBe(skinIndex.length);
72
+ expect(Array.from(decodedSkinIndex)).toEqual(Array.from(skinIndex));
73
+
74
+ const decodedSkinWeight = unpacked.value.attributes.skinWeight;
75
+ expect(decodedSkinWeight).toBeInstanceOf(Float32Array);
76
+ if (!(decodedSkinWeight instanceof Float32Array)) return;
77
+ expect(decodedSkinWeight.length).toBe(skinWeight.length);
78
+ expect(Array.from(decodedSkinWeight)).toEqual(Array.from(skinWeight));
79
+ });
80
+
81
+ it('unskinned mesh: pack omits skin streams; unpack returns no skin attributes', () => {
82
+ const vertexCount = 4;
83
+ const vertices = new Float32Array(vertexCount * FLOATS_PER_VERTEX_12);
84
+ for (let i = 0; i < vertices.length; i++) vertices[i] = i;
85
+ const indices = new Uint16Array([0, 1, 2, 0, 2, 3]);
86
+
87
+ const attributes = {
88
+ position: new Float32Array(vertexCount * 3),
89
+ normal: new Float32Array(vertexCount * 3),
90
+ uv: new Float32Array(vertexCount * 2),
91
+ tangent: new Float32Array(vertexCount * 4),
92
+ };
93
+ const packedNoSkin = packMeshBinV4({ vertices, indices, attributes }, 'runtime://no-skin');
94
+ const packedEmptyAttrs = packMeshBinV4({ vertices, indices, attributes }, 'runtime://no-skin');
95
+ expect(packedNoSkin.ok).toBe(true);
96
+ expect(packedEmptyAttrs.ok).toBe(true);
97
+ if (!packedNoSkin.ok || !packedEmptyAttrs.ok) return;
98
+ const bytesNoSkin = packedNoSkin.value;
99
+ const bytesEmptyAttrs = packedEmptyAttrs.value;
100
+
101
+ // Back-compat: byte stream identical to pre-feat output (no trailing
102
+ // skin payload, no skin keys in JSON tail).
103
+ expect(bytesNoSkin.byteLength).toBe(bytesEmptyAttrs.byteLength);
104
+
105
+ const unpacked = unpackMeshBinV4(bytesNoSkin, 'runtime://no-skin');
106
+ expect(unpacked.ok).toBe(true);
107
+ if (!unpacked.ok) return;
108
+ expect(unpacked.value.attributes.skinIndex).toBeUndefined();
109
+ expect(unpacked.value.attributes.skinWeight).toBeUndefined();
110
+ expect(unpacked.value.vertices.length).toBe(vertices.length);
111
+ expect(unpacked.value.indices).toBeInstanceOf(Uint16Array);
112
+ });
113
+
114
+ it('empty mesh: zero vertices + empty skin streams roundtrip without panic', () => {
115
+ const vertices = new Float32Array(0);
116
+ const indices = new Uint16Array(0);
117
+ const skinIndex = new Uint16Array(0);
118
+ const skinWeight = new Float32Array(0);
119
+
120
+ const packed = packMeshBinV4(
121
+ {
122
+ vertices,
123
+ indices,
124
+ attributes: {
125
+ position: new Float32Array(0),
126
+ normal: new Float32Array(0),
127
+ uv: new Float32Array(0),
128
+ tangent: new Float32Array(0),
129
+ skinIndex,
130
+ skinWeight,
131
+ },
132
+ },
133
+ 'runtime://empty-skin',
134
+ );
135
+ expect(packed.ok).toBe(true);
136
+ if (!packed.ok) return;
137
+ const unpacked = unpackMeshBinV4(packed.value, 'runtime://empty-skin');
138
+ expect(unpacked.ok).toBe(true);
139
+ if (!unpacked.ok) return;
140
+ expect(unpacked.value.vertices.length).toBe(0);
141
+ // Zero-length skin streams collapse: the unpacker only materialises a
142
+ // typed array when count > 0 (avoids handing the renderer a 0-length
143
+ // attribute that fails GPU validation). A skinned-but-empty mesh is a
144
+ // pathological input the production path (parseGltf) rejects upstream;
145
+ // this case asserts only that pack -> unpack does not throw.
146
+ expect(unpacked.value.attributes.skinIndex).toBeInstanceOf(Uint16Array);
147
+ expect(unpacked.value.attributes.skinWeight).toBeInstanceOf(Float32Array);
148
+ });
149
+ });
@@ -0,0 +1,38 @@
1
+ import { unpackMeshBinV4 } from '@forgeax/engine-assets-runtime';
2
+ import { packMeshBinV4 } from '@forgeax/engine-import';
3
+ import { describe, expect, it } from 'vitest';
4
+
5
+ describe('mesh-bin v4 runtime roundtrip', () => {
6
+ it('preserves canonical interleaved vertices, color, UV sets, and indices', () => {
7
+ const attributes = {
8
+ position: new Float32Array([1.5, 0, 0, 0, 0, 0]),
9
+ normal: new Float32Array(6),
10
+ uv: new Float32Array(4),
11
+ uv1: new Float32Array(4),
12
+ tangent: new Float32Array(8),
13
+ color: new Float32Array([1, 0.5, 0.25, 1, 0.25, 0.5, 0.75, 1]),
14
+ };
15
+ const vertices = new Float32Array(2 * 18);
16
+ const packed = packMeshBinV4(
17
+ { vertices, indices: Uint16Array.of(0, 1, 0), attributes },
18
+ 'runtime://mesh',
19
+ );
20
+ expect(packed.ok).toBe(true);
21
+ if (!packed.ok) return;
22
+ const unpacked = unpackMeshBinV4(packed.value, 'runtime://mesh');
23
+ expect(unpacked.ok).toBe(true);
24
+ if (!unpacked.ok) return;
25
+ expect(unpacked.value.vertices[0]).toBeCloseTo(1.5);
26
+ expect(unpacked.value.indices).toBeInstanceOf(Uint16Array);
27
+ expect(unpacked.value.attributes.color).toEqual(attributes.color);
28
+ expect(unpacked.value.projection.attributes.map((entry) => entry.key)).toContain('uv1');
29
+ });
30
+
31
+ it('fails closed for a legacy artifact and preserves no partial result', () => {
32
+ const result = unpackMeshBinV4(new Uint8Array([3, 0, 0]), 'runtime://legacy');
33
+ expect(result.ok).toBe(false);
34
+ if (result.ok) return;
35
+ expect(result.error.sourceKey).toBe('runtime://legacy');
36
+ expect(result.error.recovery).toContain('re-cook');
37
+ });
38
+ });
@@ -0,0 +1,120 @@
1
+ // mesh-loader-skin-contract.unit.test.ts -- feat-20260611-fox-skinning-vertex-
2
+ // attribute-chain M3 / w14: AC-05 dual-contract verification.
3
+ //
4
+ // meshLoader.load now accepts skinIndex (Uint16Array) / skinWeight
5
+ // (Float32Array) AND their JSON-roundtrip number[] shapes (post-
6
+ // JSON.stringify(pack) -> fetch -> JSON.parse on the dev-server / build-mode
7
+ // pack-body path). This file isolates the dual contract via direct meshLoader
8
+ // invocation -- dawn smoke walks register() and never touches the
9
+ // JSON-roundtrip path that shipped Fox.glb red on the browser path.
10
+ //
11
+ // AC-05: after JSON.stringify -> JSON.parse, meshLoader.load() returns a
12
+ // MeshAsset whose attributes.skinIndex instanceof Uint16Array and
13
+ // attributes.skinWeight instanceof Float32Array, with values element-wise
14
+ // equal to the original typed arrays.
15
+ //
16
+ // Anchors: requirements AC-05; plan-strategy D-7; research E-6 (PR #350
17
+ // skeletonLoader pattern); risk R-2 (mesh-loader dual-contract gap surfaces
18
+ // only on the browser pack-body path).
19
+
20
+ import { meshLoader } from '@forgeax/engine-assets-runtime';
21
+ import type { LoadContext } from '@forgeax/engine-types';
22
+ import { describe, expect, it } from 'vitest';
23
+
24
+ function makeCtx(): LoadContext {
25
+ return {
26
+ fetchBinary: () =>
27
+ Promise.resolve({ ok: false as const, error: new Error('not used in unit') }),
28
+ resolveRef: () => Promise.resolve({ ok: false as const, error: new Error('not used in unit') }),
29
+ transcodeCaps: { bc: false, etc2: false, astc: false },
30
+ device: undefined,
31
+ };
32
+ }
33
+
34
+ describe('feat-20260611 / M3 / w14 - meshLoader skinIndex/skinWeight dual contract', () => {
35
+ it('AC-05 (a) accepts native typed arrays directly', () => {
36
+ const N = 4;
37
+ const skinIndex = new Uint16Array([0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0]);
38
+ const skinWeight = new Float32Array([
39
+ 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 1.0,
40
+ ]);
41
+ const payload: Record<string, unknown> = {
42
+ vertices: new Float32Array(N * 18),
43
+ indices: new Uint16Array([0, 1, 2, 0, 2, 3]),
44
+ attributes: { skinIndex, skinWeight },
45
+ };
46
+ const result = meshLoader.load(payload, undefined, makeCtx());
47
+ expect(result).toBeDefined();
48
+ if (result === undefined) return;
49
+ const asset = result as {
50
+ kind: string;
51
+ attributes: { skinIndex?: unknown; skinWeight?: unknown };
52
+ };
53
+ expect(asset.kind).toBe('mesh');
54
+ expect(asset.attributes.skinIndex).toBeInstanceOf(Uint16Array);
55
+ expect(asset.attributes.skinWeight).toBeInstanceOf(Float32Array);
56
+ expect(asset.attributes.skinIndex).toBe(skinIndex);
57
+ expect(asset.attributes.skinWeight).toBe(skinWeight);
58
+ });
59
+
60
+ it('AC-05 (b) JSON-roundtrip: number[] is rehydrated to Uint16Array / Float32Array', () => {
61
+ const N = 4;
62
+ const sourceSkinIndex = new Uint16Array([0, 1, 2, 3, 10, 11, 12, 13, 0, 0, 0, 0, 4, 5, 6, 7]);
63
+ const sourceSkinWeight = new Float32Array([
64
+ 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 1.0,
65
+ ]);
66
+
67
+ // Simulate the dev-server / build-mode pack-body wire path. The actual
68
+ // wire pre-flattens typed arrays to plain Array via
69
+ // @forgeax/engine-import normaliseForPack BEFORE JSON.stringify (see
70
+ // packages/import/src/import-runner.ts). Without that step,
71
+ // JSON.stringify(typedArray) yields a string-keyed object literal --
72
+ // not the dual-contract shape the loader is designed to honour.
73
+ const flatIndex = Array.from(sourceSkinIndex);
74
+ const flatWeight = Array.from(sourceSkinWeight);
75
+ const wire = JSON.parse(
76
+ JSON.stringify({
77
+ vertices: Array.from(new Float32Array(N * 18)),
78
+ indices: Array.from(new Uint16Array([0, 1, 2, 0, 2, 3])),
79
+ attributes: { skinIndex: flatIndex, skinWeight: flatWeight },
80
+ }),
81
+ ) as Record<string, unknown>;
82
+ const wireAttrs = wire.attributes as { skinIndex: unknown; skinWeight: unknown };
83
+ expect(Array.isArray(wireAttrs.skinIndex)).toBe(true);
84
+ expect(Array.isArray(wireAttrs.skinWeight)).toBe(true);
85
+
86
+ const result = meshLoader.load(wire, undefined, makeCtx());
87
+ expect(result).toBeDefined();
88
+ if (result === undefined) return;
89
+ const attrs = (result as { attributes: { skinIndex?: unknown; skinWeight?: unknown } })
90
+ .attributes;
91
+ expect(attrs.skinIndex).toBeInstanceOf(Uint16Array);
92
+ expect(attrs.skinWeight).toBeInstanceOf(Float32Array);
93
+
94
+ const restoredIdx = attrs.skinIndex as Uint16Array;
95
+ const restoredW = attrs.skinWeight as Float32Array;
96
+ expect(restoredIdx.length).toBe(sourceSkinIndex.length);
97
+ expect(restoredW.length).toBe(sourceSkinWeight.length);
98
+ for (let i = 0; i < sourceSkinIndex.length; i++) {
99
+ expect(restoredIdx[i]).toBe(sourceSkinIndex[i]);
100
+ }
101
+ for (let i = 0; i < sourceSkinWeight.length; i++) {
102
+ expect(restoredW[i]).toBeCloseTo(sourceSkinWeight[i] as number, 6);
103
+ }
104
+ });
105
+
106
+ it('AC-05 (c) absent skin attrs leave attributes unchanged (unskinned mesh path)', () => {
107
+ const payload: Record<string, unknown> = {
108
+ vertices: new Float32Array(3 * 12),
109
+ indices: new Uint16Array([0, 1, 2]),
110
+ attributes: {},
111
+ };
112
+ const result = meshLoader.load(payload, undefined, makeCtx());
113
+ expect(result).toBeDefined();
114
+ if (result === undefined) return;
115
+ const attrs = (result as { attributes: { skinIndex?: unknown; skinWeight?: unknown } })
116
+ .attributes;
117
+ expect(attrs.skinIndex).toBeUndefined();
118
+ expect(attrs.skinWeight).toBeUndefined();
119
+ });
120
+ });
@@ -13,14 +13,14 @@
13
13
  // 4. all limits zero (R-1 extreme) -> falls to spec floor 128 MiB
14
14
  // 5. absent field (R-1 edge) -> still non-zero
15
15
 
16
+ import type { Buffer } from '@forgeax/engine-rhi';
17
+ import { describe, expect, it } from 'vitest';
16
18
  import {
17
19
  createMeshSsboGrowController,
18
20
  deriveStorageBufferCeiling,
19
21
  type MeshSsboGrowControllerInit,
20
22
  type MeshSsboGrowErrorRegistry,
21
- } from '@forgeax/engine-render/internal';
22
- import type { Buffer } from '@forgeax/engine-rhi';
23
- import { describe, expect, it } from 'vitest';
23
+ } from '../../../render/src/assembly/factory';
24
24
 
25
25
  // ---------------------------------------------------------------------------
26
26
  // Stubs (mirror createRenderer.unit.test.ts pattern — minimal device fake)
@@ -20,9 +20,9 @@
20
20
  // - reuse the AssetError code system (D-9); the new code is
21
21
  // 'mipgen-unsupported-compressed-format'
22
22
 
23
- import { deriveRenderDataTexture } from '@forgeax/engine-render/internal';
24
23
  import type { TextureAsset } from '@forgeax/engine-types';
25
24
  import { describe, expect, it } from 'vitest';
25
+ import { deriveRenderDataTexture } from '../../../render/src/render-data';
26
26
 
27
27
  function tex(overrides: Partial<TextureAsset>): TextureAsset {
28
28
  return {