@forgeax/engine-runtime 0.1.21 → 0.1.24

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 (410) hide show
  1. package/README.md +18 -9
  2. package/dist/__tests__/advance-animation-player.cases.unit.test.d.ts +2 -0
  3. package/dist/__tests__/advance-animation-player.cases.unit.test.d.ts.map +1 -0
  4. package/dist/__tests__/asset-registry-aabb.cases.unit.test.d.ts +2 -0
  5. package/dist/__tests__/asset-registry-aabb.cases.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/asset-registry-bootstrap.cases.unit.test.d.ts +2 -0
  7. package/dist/__tests__/asset-registry-bootstrap.cases.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/asset-registry-builtin-nineslice.cases.unit.test.d.ts +2 -0
  9. package/dist/__tests__/asset-registry-builtin-nineslice.cases.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.d.ts +2 -0
  11. package/dist/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/asset-registry-guid.cases.unit.test.d.ts +2 -0
  13. package/dist/__tests__/asset-registry-guid.cases.unit.test.d.ts.map +1 -0
  14. package/dist/__tests__/asset-registry-material-validate.cases.unit.test.d.ts +2 -0
  15. package/dist/__tests__/asset-registry-material-validate.cases.unit.test.d.ts.map +1 -0
  16. package/dist/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.d.ts +2 -0
  17. package/dist/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.d.ts.map +1 -0
  18. package/dist/__tests__/asset-registry-scene.cases.unit.test.d.ts +2 -0
  19. package/dist/__tests__/asset-registry-scene.cases.unit.test.d.ts.map +1 -0
  20. package/dist/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.d.ts +2 -0
  21. package/dist/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.d.ts.map +1 -0
  22. package/dist/__tests__/asset-renderer-assembly.cases.unit.test.d.ts +2 -0
  23. package/dist/__tests__/asset-renderer-assembly.cases.unit.test.d.ts.map +1 -0
  24. package/dist/__tests__/asset.cases.unit.test.d.ts +2 -0
  25. package/dist/__tests__/asset.cases.unit.test.d.ts.map +1 -0
  26. package/dist/__tests__/bloom-gating.cases.unit.test.d.ts +2 -0
  27. package/dist/__tests__/bloom-gating.cases.unit.test.d.ts.map +1 -0
  28. package/dist/__tests__/builtin-guid-ssot.cases.unit.test.d.ts +2 -0
  29. package/dist/__tests__/builtin-guid-ssot.cases.unit.test.d.ts.map +1 -0
  30. package/dist/__tests__/builtin-pack.cases.unit.test.d.ts +2 -0
  31. package/dist/__tests__/builtin-pack.cases.unit.test.d.ts.map +1 -0
  32. package/dist/__tests__/camera-antialias.cases.unit.test.d.ts +2 -0
  33. package/dist/__tests__/camera-antialias.cases.unit.test.d.ts.map +1 -0
  34. package/dist/__tests__/camera-bloom.cases.unit.test.d.ts +2 -0
  35. package/dist/__tests__/camera-bloom.cases.unit.test.d.ts.map +1 -0
  36. package/dist/__tests__/camera-clear-schema.cases.unit.test.d.ts +2 -0
  37. package/dist/__tests__/camera-clear-schema.cases.unit.test.d.ts.map +1 -0
  38. package/dist/__tests__/camera-ortho.cases.unit.test.d.ts +2 -0
  39. package/dist/__tests__/camera-ortho.cases.unit.test.d.ts.map +1 -0
  40. package/dist/__tests__/cluster-binner.cases.unit.test.d.ts +2 -0
  41. package/dist/__tests__/cluster-binner.cases.unit.test.d.ts.map +1 -0
  42. package/dist/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.d.ts +2 -0
  43. package/dist/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.d.ts.map +1 -0
  44. package/dist/__tests__/create-renderer-uniform-fallback.cases.unit.test.d.ts +2 -0
  45. package/dist/__tests__/create-renderer-uniform-fallback.cases.unit.test.d.ts.map +1 -0
  46. package/dist/__tests__/cubemap-upload.cases.unit.test.d.ts +2 -0
  47. package/dist/__tests__/cubemap-upload.cases.unit.test.d.ts.map +1 -0
  48. package/dist/__tests__/dev-import-transport.cases.unit.test.d.ts +2 -0
  49. package/dist/__tests__/dev-import-transport.cases.unit.test.d.ts.map +1 -0
  50. package/dist/__tests__/engine-metrics.cases.unit.test.d.ts +2 -0
  51. package/dist/__tests__/engine-metrics.cases.unit.test.d.ts.map +1 -0
  52. package/dist/__tests__/equirect-projection-error.cases.unit.test.d.ts +2 -0
  53. package/dist/__tests__/equirect-projection-error.cases.unit.test.d.ts.map +1 -0
  54. package/dist/__tests__/font-asset-load.cases.unit.test.d.ts +2 -0
  55. package/dist/__tests__/font-asset-load.cases.unit.test.d.ts.map +1 -0
  56. package/dist/__tests__/fxaa-intermediate-texture.cases.unit.test.d.ts +2 -0
  57. package/dist/__tests__/fxaa-intermediate-texture.cases.unit.test.d.ts.map +1 -0
  58. package/dist/__tests__/fxaa-pipeline.cases.unit.test.d.ts +2 -0
  59. package/dist/__tests__/fxaa-pipeline.cases.unit.test.d.ts.map +1 -0
  60. package/dist/__tests__/gpu-residency.cases.unit.test.d.ts +2 -0
  61. package/dist/__tests__/gpu-residency.cases.unit.test.d.ts.map +1 -0
  62. package/dist/__tests__/gpu-resource-release.cases.unit.test.d.ts +2 -0
  63. package/dist/__tests__/gpu-resource-release.cases.unit.test.d.ts.map +1 -0
  64. package/dist/__tests__/handle-quad.cases.unit.test.d.ts +2 -0
  65. package/dist/__tests__/handle-quad.cases.unit.test.d.ts.map +1 -0
  66. package/dist/__tests__/hdrp-bgl-slots.cases.unit.test.d.ts +2 -0
  67. package/dist/__tests__/hdrp-bgl-slots.cases.unit.test.d.ts.map +1 -0
  68. package/dist/__tests__/hdrp-grid-invalid.cases.unit.test.d.ts +2 -0
  69. package/dist/__tests__/hdrp-grid-invalid.cases.unit.test.d.ts.map +1 -0
  70. package/dist/__tests__/hdrp-index-list-overflow-once.cases.unit.test.d.ts +2 -0
  71. package/dist/__tests__/hdrp-index-list-overflow-once.cases.unit.test.d.ts.map +1 -0
  72. package/dist/__tests__/hdrp-light-budget.cases.unit.test.d.ts +2 -0
  73. package/dist/__tests__/hdrp-light-budget.cases.unit.test.d.ts.map +1 -0
  74. package/dist/__tests__/hdrp-pipeline-asset-config.cases.unit.test.d.ts +2 -0
  75. package/dist/__tests__/hdrp-pipeline-asset-config.cases.unit.test.d.ts.map +1 -0
  76. package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
  77. package/dist/__tests__/helpers/register-scene-components.d.ts.map +1 -1
  78. package/dist/__tests__/helpers/renderer-device-loss-dawn.d.ts +25 -0
  79. package/dist/__tests__/helpers/renderer-device-loss-dawn.d.ts.map +1 -0
  80. package/dist/__tests__/helpers/standard-material-manifest.d.ts +0 -1
  81. package/dist/__tests__/helpers/standard-material-manifest.d.ts.map +1 -1
  82. package/dist/__tests__/ibl-pipeline-cache.cases.unit.test.d.ts +2 -0
  83. package/dist/__tests__/ibl-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  84. package/dist/__tests__/lazy-catalog.cases.unit.test.d.ts +2 -0
  85. package/dist/__tests__/lazy-catalog.cases.unit.test.d.ts.map +1 -0
  86. package/dist/__tests__/load-by-guid-hdr.cases.unit.test.d.ts +2 -0
  87. package/dist/__tests__/load-by-guid-hdr.cases.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/load-by-guid-prod-material-parent.cases.unit.test.d.ts +2 -0
  89. package/dist/__tests__/load-by-guid-prod-material-parent.cases.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/load-by-guid-prod.cases.unit.test.d.ts +2 -0
  91. package/dist/__tests__/load-by-guid-prod.cases.unit.test.d.ts.map +1 -0
  92. package/dist/__tests__/loader-registry.cases.unit.test.d.ts +2 -0
  93. package/dist/__tests__/loader-registry.cases.unit.test.d.ts.map +1 -0
  94. package/dist/__tests__/m7-hdrp-demo-shape.cases.unit.test.d.ts +2 -0
  95. package/dist/__tests__/m7-hdrp-demo-shape.cases.unit.test.d.ts.map +1 -0
  96. package/dist/__tests__/mipmap-formula.cases.unit.test.d.ts +2 -0
  97. package/dist/__tests__/mipmap-formula.cases.unit.test.d.ts.map +1 -0
  98. package/dist/__tests__/mipmap-pipeline-cache.cases.unit.test.d.ts +2 -0
  99. package/dist/__tests__/mipmap-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  100. package/dist/__tests__/parse-asset-payload-material.cases.unit.test.d.ts +2 -0
  101. package/dist/__tests__/parse-asset-payload-material.cases.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/parse-asset-payload-texture.cases.unit.test.d.ts +2 -0
  103. package/dist/__tests__/parse-asset-payload-texture.cases.unit.test.d.ts.map +1 -0
  104. package/dist/__tests__/parse-scene-payload-refs.cases.unit.test.d.ts +2 -0
  105. package/dist/__tests__/parse-scene-payload-refs.cases.unit.test.d.ts.map +1 -0
  106. package/dist/__tests__/pass-selector.cases.unit.test.d.ts +2 -0
  107. package/dist/__tests__/pass-selector.cases.unit.test.d.ts.map +1 -0
  108. package/dist/__tests__/pipeline-builder.cases.unit.test.d.ts +2 -0
  109. package/dist/__tests__/pipeline-builder.cases.unit.test.d.ts.map +1 -0
  110. package/dist/__tests__/pipeline-cache-key-topology.cases.unit.test.d.ts +2 -0
  111. package/dist/__tests__/pipeline-cache-key-topology.cases.unit.test.d.ts.map +1 -0
  112. package/dist/__tests__/pipeline-vertex-stride-branch.cases.unit.test.d.ts +2 -0
  113. package/dist/__tests__/pipeline-vertex-stride-branch.cases.unit.test.d.ts.map +1 -0
  114. package/dist/__tests__/pipeline.cases.unit.test.d.ts +2 -0
  115. package/dist/__tests__/pipeline.cases.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/post-process-register.cases.unit.test.d.ts +2 -0
  117. package/dist/__tests__/post-process-register.cases.unit.test.d.ts.map +1 -0
  118. package/dist/__tests__/propagate-transforms.cases.unit.test.d.ts +2 -0
  119. package/dist/__tests__/propagate-transforms.cases.unit.test.d.ts.map +1 -0
  120. package/dist/__tests__/record-all-topology.cases.unit.test.d.ts +2 -0
  121. package/dist/__tests__/record-all-topology.cases.unit.test.d.ts.map +1 -0
  122. package/dist/__tests__/record-draw-branch.cases.unit.test.d.ts +2 -0
  123. package/dist/__tests__/record-draw-branch.cases.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/record-strip-index-format.cases.unit.test.d.ts +2 -0
  125. package/dist/__tests__/record-strip-index-format.cases.unit.test.d.ts.map +1 -0
  126. package/dist/__tests__/register-with-guid-rgba16float.cases.unit.test.d.ts +2 -0
  127. package/dist/__tests__/register-with-guid-rgba16float.cases.unit.test.d.ts.map +1 -0
  128. package/dist/__tests__/render-data.cases.unit.test.d.ts +2 -0
  129. package/dist/__tests__/render-data.cases.unit.test.d.ts.map +1 -0
  130. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
  131. package/dist/__tests__/render-query-regression.cases.unit.test.d.ts +2 -0
  132. package/dist/__tests__/render-query-regression.cases.unit.test.d.ts.map +1 -0
  133. package/dist/__tests__/render-system-record-submesh.cases.unit.test.d.ts +2 -0
  134. package/dist/__tests__/render-system-record-submesh.cases.unit.test.d.ts.map +1 -0
  135. package/dist/__tests__/render-system-record-warn-once.cases.unit.test.d.ts +2 -0
  136. package/dist/__tests__/render-system-record-warn-once.cases.unit.test.d.ts.map +1 -0
  137. package/dist/__tests__/renderer-device-loss-multi-world.integration.test.d.ts +2 -0
  138. package/dist/__tests__/renderer-device-loss-multi-world.integration.test.d.ts.map +1 -0
  139. package/dist/__tests__/renderer-device-loss-provider-feasibility.dawn.test.d.ts +2 -0
  140. package/dist/__tests__/renderer-device-loss-provider-feasibility.dawn.test.d.ts.map +1 -0
  141. package/dist/__tests__/renderer-device-loss-recovery.dawn.test.d.ts +2 -0
  142. package/dist/__tests__/renderer-device-loss-recovery.dawn.test.d.ts.map +1 -0
  143. package/dist/__tests__/renderer-draw-world.cases.unit.test.d.ts +2 -0
  144. package/dist/__tests__/renderer-draw-world.cases.unit.test.d.ts.map +1 -0
  145. package/dist/__tests__/renderer-recovery-consumer.integration.test.d.ts +2 -0
  146. package/dist/__tests__/renderer-recovery-consumer.integration.test.d.ts.map +1 -0
  147. package/dist/__tests__/renderstate-pipeline-cache.cases.unit.test.d.ts +2 -0
  148. package/dist/__tests__/renderstate-pipeline-cache.cases.unit.test.d.ts.map +1 -0
  149. package/dist/__tests__/resolve-scene-guids.cases.unit.test.d.ts +2 -0
  150. package/dist/__tests__/resolve-scene-guids.cases.unit.test.d.ts.map +1 -0
  151. package/dist/__tests__/shadow-skip-non-triangle.cases.unit.test.d.ts +2 -0
  152. package/dist/__tests__/shadow-skip-non-triangle.cases.unit.test.d.ts.map +1 -0
  153. package/dist/__tests__/skin-errors-kebab-case.cases.unit.test.d.ts +2 -0
  154. package/dist/__tests__/skin-errors-kebab-case.cases.unit.test.d.ts.map +1 -0
  155. package/dist/__tests__/skin-instances-coexist.cases.unit.test.d.ts +2 -0
  156. package/dist/__tests__/skin-instances-coexist.cases.unit.test.d.ts.map +1 -0
  157. package/dist/__tests__/skin-m2-extract-happy.cases.unit.test.d.ts +2 -0
  158. package/dist/__tests__/skin-m2-extract-happy.cases.unit.test.d.ts.map +1 -0
  159. package/dist/__tests__/skin-m2-extract-joint-error.cases.unit.test.d.ts +2 -0
  160. package/dist/__tests__/skin-m2-extract-joint-error.cases.unit.test.d.ts.map +1 -0
  161. package/dist/__tests__/skin-m2-extract-null-assets.cases.unit.test.d.ts +2 -0
  162. package/dist/__tests__/skin-m2-extract-null-assets.cases.unit.test.d.ts.map +1 -0
  163. package/dist/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.d.ts +2 -0
  164. package/dist/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.d.ts.map +1 -0
  165. package/dist/__tests__/skin-m3-record-cache.cases.unit.test.d.ts +2 -0
  166. package/dist/__tests__/skin-m3-record-cache.cases.unit.test.d.ts.map +1 -0
  167. package/dist/__tests__/skin-palette-extract.cases.unit.test.d.ts +2 -0
  168. package/dist/__tests__/skin-palette-extract.cases.unit.test.d.ts.map +1 -0
  169. package/dist/__tests__/skin-pipeline-routing.cases.unit.test.d.ts +2 -0
  170. package/dist/__tests__/skin-pipeline-routing.cases.unit.test.d.ts.map +1 -0
  171. package/dist/__tests__/skin.cases.unit.test.d.ts +2 -0
  172. package/dist/__tests__/skin.cases.unit.test.d.ts.map +1 -0
  173. package/dist/__tests__/skybox-extract.cases.unit.test.d.ts +2 -0
  174. package/dist/__tests__/skybox-extract.cases.unit.test.d.ts.map +1 -0
  175. package/dist/__tests__/skybox-shader-compile.cases.unit.test.d.ts +2 -0
  176. package/dist/__tests__/skybox-shader-compile.cases.unit.test.d.ts.map +1 -0
  177. package/dist/__tests__/skylight-bind-group.cases.unit.test.d.ts +2 -0
  178. package/dist/__tests__/skylight-bind-group.cases.unit.test.d.ts.map +1 -0
  179. package/dist/__tests__/skylight-component.cases.unit.test.d.ts +2 -0
  180. package/dist/__tests__/skylight-component.cases.unit.test.d.ts.map +1 -0
  181. package/dist/__tests__/skylight-fallback-path.cases.unit.test.d.ts +2 -0
  182. package/dist/__tests__/skylight-fallback-path.cases.unit.test.d.ts.map +1 -0
  183. package/dist/__tests__/skylight-pipeline-layout.cases.unit.test.d.ts +2 -0
  184. package/dist/__tests__/skylight-pipeline-layout.cases.unit.test.d.ts.map +1 -0
  185. package/dist/__tests__/skylight-solid-color-extract.cases.unit.test.d.ts +2 -0
  186. package/dist/__tests__/skylight-solid-color-extract.cases.unit.test.d.ts.map +1 -0
  187. package/dist/__tests__/sprite-animation-tick-boundary.cases.unit.test.d.ts +2 -0
  188. package/dist/__tests__/sprite-animation-tick-boundary.cases.unit.test.d.ts.map +1 -0
  189. package/dist/__tests__/sprite-animation-tick-clamp.cases.unit.test.d.ts +2 -0
  190. package/dist/__tests__/sprite-animation-tick-clamp.cases.unit.test.d.ts.map +1 -0
  191. package/dist/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.d.ts +2 -0
  192. package/dist/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.d.ts.map +1 -0
  193. package/dist/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.d.ts +2 -0
  194. package/dist/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.d.ts.map +1 -0
  195. package/dist/__tests__/sprite-animation-tick-loop.cases.unit.test.d.ts +2 -0
  196. package/dist/__tests__/sprite-animation-tick-loop.cases.unit.test.d.ts.map +1 -0
  197. package/dist/__tests__/sprite-animation-tick-override-probe.cases.unit.test.d.ts +2 -0
  198. package/dist/__tests__/sprite-animation-tick-override-probe.cases.unit.test.d.ts.map +1 -0
  199. package/dist/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.d.ts +2 -0
  200. package/dist/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.d.ts.map +1 -0
  201. package/dist/__tests__/storage-buffer-caps.cases.unit.test.d.ts +2 -0
  202. package/dist/__tests__/storage-buffer-caps.cases.unit.test.d.ts.map +1 -0
  203. package/dist/__tests__/systems.cases.unit.test.d.ts +2 -0
  204. package/dist/__tests__/systems.cases.unit.test.d.ts.map +1 -0
  205. package/dist/__tests__/tonemap-hdr-target.cases.unit.test.d.ts +2 -0
  206. package/dist/__tests__/tonemap-hdr-target.cases.unit.test.d.ts.map +1 -0
  207. package/dist/__tests__/tonemap-pipeline-split.cases.unit.test.d.ts +2 -0
  208. package/dist/__tests__/tonemap-pipeline-split.cases.unit.test.d.ts.map +1 -0
  209. package/dist/__tests__/tonemap.cases.unit.test.d.ts +2 -0
  210. package/dist/__tests__/tonemap.cases.unit.test.d.ts.map +1 -0
  211. package/dist/__tests__/transparent-sort-config-get.cases.unit.test.d.ts +2 -0
  212. package/dist/__tests__/transparent-sort-config-get.cases.unit.test.d.ts.map +1 -0
  213. package/dist/__tests__/transparent-sort-config-set.cases.unit.test.d.ts +2 -0
  214. package/dist/__tests__/transparent-sort-config-set.cases.unit.test.d.ts.map +1 -0
  215. package/dist/__tests__/transparent-sort.cases.unit.test.d.ts +2 -0
  216. package/dist/__tests__/transparent-sort.cases.unit.test.d.ts.map +1 -0
  217. package/dist/__tests__/upload-texture-consistency.cases.unit.test.d.ts +2 -0
  218. package/dist/__tests__/upload-texture-consistency.cases.unit.test.d.ts.map +1 -0
  219. package/dist/__tests__/verify-revisions.cases.unit.test.d.ts +2 -0
  220. package/dist/__tests__/verify-revisions.cases.unit.test.d.ts.map +1 -0
  221. package/dist/__tests__/wire-default-loaders.cases.unit.test.d.ts +2 -0
  222. package/dist/__tests__/wire-default-loaders.cases.unit.test.d.ts.map +1 -0
  223. package/dist/__tests__/zero-camera-clear-fallback.cases.unit.test.d.ts +2 -0
  224. package/dist/__tests__/zero-camera-clear-fallback.cases.unit.test.d.ts.map +1 -0
  225. package/dist/createRenderer.d.ts.map +1 -1
  226. package/dist/dev-import-transport.d.ts.map +1 -1
  227. package/dist/index.mjs +4 -3
  228. package/dist/index.mjs.map +1 -1
  229. package/dist/sprite-param-values.d.ts +1 -1
  230. package/package.json +30 -30
  231. package/src/__tests__/advance-animation-player.cases.unit.test.ts +1666 -0
  232. package/src/__tests__/animation-graph-asset-union.test-d.ts +2 -0
  233. package/src/__tests__/asset-brand-and-name-retirement.test.ts +4 -3
  234. package/src/__tests__/asset-registry-aabb.cases.unit.test.ts +676 -0
  235. package/src/__tests__/asset-registry-bootstrap.cases.unit.test.ts +472 -0
  236. package/src/__tests__/asset-registry-builtin-nineslice.cases.unit.test.ts +481 -0
  237. package/src/__tests__/asset-registry-d9-tile-sampler-soft-warn.cases.unit.test.ts +568 -0
  238. package/src/__tests__/asset-registry-guid.cases.unit.test.ts +500 -0
  239. package/src/__tests__/asset-registry-material-validate.cases.unit.test.ts +756 -0
  240. package/src/__tests__/asset-registry-mesh-fail-fast.cases.unit.test.ts +591 -0
  241. package/src/__tests__/asset-registry-scene.cases.unit.test.ts +501 -0
  242. package/src/__tests__/asset-registry-scene.test-d.ts +1 -0
  243. package/src/__tests__/asset-registry-sprite-slices-validate.cases.unit.test.ts +536 -0
  244. package/src/__tests__/asset-renderer-assembly.cases.unit.test.ts +496 -0
  245. package/src/__tests__/asset.cases.unit.test.ts +439 -0
  246. package/src/__tests__/bind-group-cache-keying.test.ts +6 -2
  247. package/src/__tests__/bloom-gating.cases.unit.test.ts +428 -0
  248. package/src/__tests__/builtin-guid-ssot.cases.unit.test.ts +472 -0
  249. package/src/__tests__/builtin-pack.cases.unit.test.ts +639 -0
  250. package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
  251. package/src/__tests__/camera-antialias.cases.unit.test.ts +372 -0
  252. package/src/__tests__/camera-bloom.cases.unit.test.ts +396 -0
  253. package/src/__tests__/camera-clear-schema.cases.unit.test.ts +391 -0
  254. package/src/__tests__/camera-ortho.cases.unit.test.ts +484 -0
  255. package/src/__tests__/cluster-binner.cases.unit.test.ts +817 -0
  256. package/src/__tests__/collect-scene-mount-collapse.test.ts +5 -1
  257. package/src/__tests__/collect-transient-roundtrip.test.ts +14 -3
  258. package/src/__tests__/components.test-d.ts +9 -6
  259. package/src/__tests__/components.unit.test.ts +23 -19
  260. package/src/__tests__/create-renderer-fallback-shader-manifest.cases.unit.test.ts +345 -0
  261. package/src/__tests__/create-renderer-uniform-fallback.cases.unit.test.ts +445 -0
  262. package/src/__tests__/cubemap-upload.cases.unit.test.ts +593 -0
  263. package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +184 -17
  264. package/src/__tests__/dawn/material-alpha.dawn.test.ts +17 -4
  265. package/src/__tests__/derive-bgl-integration.test.ts +8 -8
  266. package/src/__tests__/dev-import-transport.cases.unit.test.ts +503 -0
  267. package/src/__tests__/engine-metrics.cases.unit.test.ts +371 -0
  268. package/src/__tests__/equirect-projection-error.cases.unit.test.ts +416 -0
  269. package/src/__tests__/errors.unit.test.ts +3 -0
  270. package/src/__tests__/extract-frames-merge.test.ts +3 -0
  271. package/src/__tests__/font-asset-load.cases.unit.test.ts +510 -0
  272. package/src/__tests__/fxaa-intermediate-texture.cases.unit.test.ts +690 -0
  273. package/src/__tests__/fxaa-pipeline.cases.unit.test.ts +546 -0
  274. package/src/__tests__/gpu-residency.cases.unit.test.ts +479 -0
  275. package/src/__tests__/gpu-resource-release.cases.unit.test.ts +929 -0
  276. package/src/__tests__/handle-quad.cases.unit.test.ts +491 -0
  277. package/src/__tests__/hdrp-bgl-slots.cases.unit.test.ts +451 -0
  278. package/src/__tests__/hdrp-grid-invalid.cases.unit.test.ts +408 -0
  279. package/src/__tests__/hdrp-index-list-overflow-once.cases.unit.test.ts +405 -0
  280. package/src/__tests__/hdrp-light-budget.cases.unit.test.ts +483 -0
  281. package/src/__tests__/hdrp-pipeline-asset-config.cases.unit.test.ts +441 -0
  282. package/src/__tests__/helpers/register-runtime-components.ts +9 -1
  283. package/src/__tests__/helpers/register-scene-components.ts +9 -2
  284. package/src/__tests__/helpers/renderer-device-loss-dawn.ts +69 -0
  285. package/src/__tests__/helpers/standard-material-manifest.ts +11 -15
  286. package/src/__tests__/ibl-pipeline-cache.cases.unit.test.ts +415 -0
  287. package/src/__tests__/lazy-catalog.cases.unit.test.ts +848 -0
  288. package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +14 -15
  289. package/src/__tests__/light-snapshot.test-d.ts +27 -1
  290. package/src/__tests__/lights-preservation.fixup.test.ts +19 -21
  291. package/src/__tests__/lights.unit.test.ts +2076 -1
  292. package/src/__tests__/load-by-guid-hdr.cases.unit.test.ts +582 -0
  293. package/src/__tests__/load-by-guid-prod-material-parent.cases.unit.test.ts +1514 -0
  294. package/src/__tests__/load-by-guid-prod.cases.unit.test.ts +557 -0
  295. package/src/__tests__/loader-name-survival.test.ts +8 -9
  296. package/src/__tests__/loader-registry.cases.unit.test.ts +767 -0
  297. package/src/__tests__/m7-hdrp-demo-shape.cases.unit.test.ts +361 -0
  298. package/src/__tests__/material-texture-uv-scale.unit.test.ts +2 -2
  299. package/src/__tests__/materials.unit.test.ts +29 -10
  300. package/src/__tests__/mipmap-formula.cases.unit.test.ts +434 -0
  301. package/src/__tests__/mipmap-pipeline-cache.cases.unit.test.ts +490 -0
  302. package/src/__tests__/package-promotion.test.ts +7 -11
  303. package/src/__tests__/parse-asset-payload-material.cases.unit.test.ts +565 -0
  304. package/src/__tests__/parse-asset-payload-texture.cases.unit.test.ts +720 -0
  305. package/src/__tests__/parse-scene-payload-refs.cases.unit.test.ts +767 -0
  306. package/src/__tests__/pass-selector.cases.unit.test.ts +376 -0
  307. package/src/__tests__/pbr-pipeline.unit.test.ts +39 -21
  308. package/src/__tests__/pipeline-builder.cases.unit.test.ts +624 -0
  309. package/src/__tests__/pipeline-cache-key-topology.cases.unit.test.ts +807 -0
  310. package/src/__tests__/pipeline-vertex-stride-branch.cases.unit.test.ts +379 -0
  311. package/src/__tests__/pipeline.cases.unit.test.ts +370 -0
  312. package/src/__tests__/point-light-shadow.browser.test.ts +1 -0
  313. package/src/__tests__/point-light-shadow.unit.test.ts +18 -98
  314. package/src/__tests__/post-process-register.cases.unit.test.ts +405 -0
  315. package/src/__tests__/propagate-transforms.cases.unit.test.ts +502 -0
  316. package/src/__tests__/propagate-transforms.dawn.test.ts +34 -18
  317. package/src/__tests__/record-all-topology.cases.unit.test.ts +608 -0
  318. package/src/__tests__/record-draw-branch.cases.unit.test.ts +621 -0
  319. package/src/__tests__/record-strip-index-format.cases.unit.test.ts +419 -0
  320. package/src/__tests__/record-worldid-isolation.test.ts +16 -32
  321. package/src/__tests__/register-with-guid-rgba16float.cases.unit.test.ts +469 -0
  322. package/src/__tests__/render-data.cases.unit.test.ts +553 -0
  323. package/src/__tests__/render-error-exhaustive.test-d.ts +11 -0
  324. package/src/__tests__/render-query-regression.cases.unit.test.ts +531 -0
  325. package/src/__tests__/render-system-extract.test.ts +5 -5
  326. package/src/__tests__/render-system-record-multi-material-textureview.test.ts +1 -0
  327. package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +1 -0
  328. package/src/__tests__/render-system-record-submesh.cases.unit.test.ts +740 -0
  329. package/src/__tests__/render-system-record-warn-once.cases.unit.test.ts +418 -0
  330. package/src/__tests__/render-system-record.test.ts +15 -33
  331. package/src/__tests__/renderer-device-loss-multi-world.integration.test.ts +103 -0
  332. package/src/__tests__/renderer-device-loss-provider-feasibility.dawn.test.ts +124 -0
  333. package/src/__tests__/renderer-device-loss-recovery.dawn.test.ts +50 -0
  334. package/src/__tests__/renderer-draw-world.cases.unit.test.ts +514 -0
  335. package/src/__tests__/renderer-recovery-consumer.integration.test.ts +96 -0
  336. package/src/__tests__/renderer-surface.unit.test.ts +0 -2
  337. package/src/__tests__/renderstate-pipeline-cache.cases.unit.test.ts +631 -0
  338. package/src/__tests__/resolve-scene-guids.cases.unit.test.ts +1123 -0
  339. package/src/__tests__/resolveName-unified-entry.test.ts +6 -6
  340. package/src/__tests__/resolveName.test.ts +14 -2
  341. package/src/__tests__/shadow-caster-empty-schema.test.ts +1 -1
  342. package/src/__tests__/shadow-csm-cascade-loadop.test.ts +1 -0
  343. package/src/__tests__/shadow-csm-tile-consistency.test.ts +1 -0
  344. package/src/__tests__/shadow-csm-ubo.test.ts +3 -1
  345. package/src/__tests__/shadow-fields-observable.dawn.test.ts +15 -4
  346. package/src/__tests__/shadow-m1.dawn.test.ts +1 -1
  347. package/src/__tests__/shadow-skip-non-triangle.cases.unit.test.ts +681 -0
  348. package/src/__tests__/skin-errors-kebab-case.cases.unit.test.ts +475 -0
  349. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +5 -4
  350. package/src/__tests__/skin-instances-coexist.cases.unit.test.ts +375 -0
  351. package/src/__tests__/skin-m2-extract-happy.cases.unit.test.ts +592 -0
  352. package/src/__tests__/skin-m2-extract-joint-error.cases.unit.test.ts +619 -0
  353. package/src/__tests__/skin-m2-extract-null-assets.cases.unit.test.ts +569 -0
  354. package/src/__tests__/skin-m2-extract-skeleton-error.cases.unit.test.ts +585 -0
  355. package/src/__tests__/skin-m3-record-cache.cases.unit.test.ts +457 -0
  356. package/src/__tests__/skin-palette-extract.cases.unit.test.ts +635 -0
  357. package/src/__tests__/skin-parented-double-transform.test.ts +5 -5
  358. package/src/__tests__/skin-pipeline-routing.cases.unit.test.ts +411 -0
  359. package/src/__tests__/skin.cases.unit.test.ts +421 -0
  360. package/src/__tests__/skinned-shadow-mixed.dawn.test.ts +1 -6
  361. package/src/__tests__/skybox-extract.cases.unit.test.ts +511 -0
  362. package/src/__tests__/skybox-shader-compile.cases.unit.test.ts +437 -0
  363. package/src/__tests__/skylight-bind-group.cases.unit.test.ts +642 -0
  364. package/src/__tests__/skylight-component.cases.unit.test.ts +386 -0
  365. package/src/__tests__/skylight-fallback-path.cases.unit.test.ts +566 -0
  366. package/src/__tests__/skylight-lazy-projection.test.ts +35 -20
  367. package/src/__tests__/skylight-pipeline-layout.cases.unit.test.ts +506 -0
  368. package/src/__tests__/skylight-solid-color-extract.cases.unit.test.ts +399 -0
  369. package/src/__tests__/sprite-animation-tick-boundary.cases.unit.test.ts +521 -0
  370. package/src/__tests__/sprite-animation-tick-clamp.cases.unit.test.ts +453 -0
  371. package/src/__tests__/sprite-animation-tick-frame-duration-negative.cases.unit.test.ts +447 -0
  372. package/src/__tests__/sprite-animation-tick-frame-duration-zero.cases.unit.test.ts +395 -0
  373. package/src/__tests__/sprite-animation-tick-loop.cases.unit.test.ts +494 -0
  374. package/src/__tests__/sprite-animation-tick-override-probe.cases.unit.test.ts +439 -0
  375. package/src/__tests__/sprite-animation-tick-regions-mismatch.cases.unit.test.ts +466 -0
  376. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +16 -18
  377. package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
  378. package/src/__tests__/ssao-bgl.test.ts +2 -1
  379. package/src/__tests__/ssao-pipelines.test.ts +1 -1
  380. package/src/__tests__/storage-buffer-caps.cases.unit.test.ts +373 -0
  381. package/src/__tests__/systems.cases.unit.test.ts +425 -0
  382. package/src/__tests__/template-game-default-api-contract.test.ts +45 -23
  383. package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +1 -1
  384. package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +10 -4
  385. package/src/__tests__/tonemap-hdr-target.cases.unit.test.ts +670 -0
  386. package/src/__tests__/tonemap-pipeline-split.cases.unit.test.ts +867 -0
  387. package/src/__tests__/tonemap.cases.unit.test.ts +446 -0
  388. package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +2 -2
  389. package/src/__tests__/transparent-sort-config-get.cases.unit.test.ts +395 -0
  390. package/src/__tests__/transparent-sort-config-set.cases.unit.test.ts +424 -0
  391. package/src/__tests__/transparent-sort.cases.unit.test.ts +684 -0
  392. package/src/__tests__/upload-texture-consistency.cases.unit.test.ts +478 -0
  393. package/src/__tests__/verify-revisions.cases.unit.test.ts +619 -0
  394. package/src/__tests__/wire-default-loaders.cases.unit.test.ts +461 -0
  395. package/src/__tests__/zero-camera-clear-fallback.cases.unit.test.ts +374 -0
  396. package/src/collect-scene-asset.ts +1 -1
  397. package/src/components/__tests__/transform-vec-schema.test.ts +2 -2
  398. package/src/createRenderer.ts +1 -0
  399. package/src/dev-import-transport.ts +2 -1
  400. package/src/sprite-param-values.ts +1 -1
  401. package/dist/.tsbuildinfo +0 -1
  402. package/dist/__tests__/asset.unit.test.d.ts +0 -2
  403. package/dist/__tests__/asset.unit.test.d.ts.map +0 -1
  404. package/dist/__tests__/pipeline.unit.test.d.ts +0 -2
  405. package/dist/__tests__/pipeline.unit.test.d.ts.map +0 -1
  406. package/dist/__tests__/systems.unit.test.d.ts +0 -2
  407. package/dist/__tests__/systems.unit.test.d.ts.map +0 -1
  408. package/src/__tests__/asset.unit.test.ts +0 -7110
  409. package/src/__tests__/pipeline.unit.test.ts +0 -5283
  410. package/src/__tests__/systems.unit.test.ts +0 -9210
@@ -0,0 +1,502 @@
1
+ // @ts-nocheck — merged file: indexed-access checks cascade across noUncheckedIndexedAccess for blocks originally outside src/ rootDir
2
+ // Consolidated by feat-20260609-test-pool-startup-reduction-merge-tiny-test-files
3
+ // biome-ignore-all lint/complexity/noUselessLoneBlockStatements: block-scope isolation between merged source files (consolidation paradigm)
4
+ //
5
+ // Source files (N=44):
6
+ // - packages/runtime/__tests__/antialias-from-f32.test.ts
7
+ // - packages/runtime/src/__tests__/bloom-gating.test.ts
8
+ // - packages/runtime/src/__tests__/camera-antialias.test.ts
9
+ // - packages/runtime/src/__tests__/camera-bloom.test.ts
10
+ // - packages/runtime/src/__tests__/camera-clear-schema.test.ts
11
+ // - packages/runtime/src/__tests__/camera-ortho.test.ts
12
+ // - packages/runtime/src/__tests__/fxaa-intermediate-texture.test.ts
13
+ // - packages/runtime/src/__tests__/fxaa-pipeline.test.ts
14
+ // - packages/runtime/src/__tests__/ibl-pipeline-cache.test.ts
15
+ // - packages/runtime/src/__tests__/ibl-runtime-probe.test.ts
16
+ // - packages/runtime/src/__tests__/render-system-record-warn-once.test.ts
17
+ // - packages/runtime/src/__tests__/shadow-skip-non-triangle.test.ts
18
+ // - packages/runtime/src/__tests__/skin-errors-kebab-case.test.ts
19
+ // - packages/runtime/src/__tests__/skybox-error.test.ts
20
+ // - packages/runtime/src/__tests__/skybox-shader-compile.test.ts
21
+ // - packages/runtime/src/__tests__/skylight-bind-group.test.ts
22
+ // - packages/runtime/src/__tests__/skylight-component.test.ts
23
+ // - packages/runtime/src/__tests__/skylight-fallback-path.test.ts
24
+ // - packages/runtime/src/__tests__/skylight-pipeline-layout.test.ts
25
+ // - packages/runtime/src/__tests__/tonemap-hdr-target.test.ts
26
+ // - packages/runtime/src/__tests__/tonemap-pipeline-split.test.ts
27
+ // - packages/runtime/src/__tests__/zero-camera-clear-fallback.test.ts
28
+ // - packages/runtime/src/components/__tests__/skin.test.ts
29
+ // - packages/runtime/src/systems/__tests__/advance-animation-player.test.ts
30
+ // - packages/runtime/src/systems/__tests__/graph-skybox.test.ts
31
+ // - packages/runtime/src/systems/__tests__/propagate-transforms.test.ts
32
+ // - packages/runtime/src/systems/__tests__/skin-cap-gate.test.ts
33
+ // - packages/runtime/src/systems/__tests__/skin-instances-coexist.test.ts
34
+ // - packages/runtime/src/systems/__tests__/skin-palette-extract.test.ts
35
+ // - packages/runtime/src/systems/__tests__/skin-pipeline-routing.test.ts
36
+ // - packages/runtime/src/systems/__tests__/skybox-extract.test.ts
37
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-boundary.test.ts
38
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-clamp.test.ts
39
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-frame-duration-negative.test.ts
40
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-frame-duration-zero.test.ts
41
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-loop.test.ts
42
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-override-probe.test.ts
43
+ // - packages/runtime/src/systems/__tests__/sprite-animation-tick-regions-mismatch.test.ts
44
+ // - packages/runtime/src/systems/__tests__/tonemap.test.ts
45
+ // - packages/runtime/src/systems/__tests__/transparent-sort-config-get.test.ts
46
+ // - packages/runtime/src/systems/__tests__/transparent-sort-config-set.test.ts
47
+ // - packages/runtime/src/systems/__tests__/transparent-sort.test.ts
48
+ // - packages/runtime/src/__tests__/render-system-multi-material.test.ts
49
+ // - packages/runtime/src/__tests__/render-system-record-submesh.test.ts
50
+ //
51
+ // Paradigm: each block-scope wraps a source file. ancestorTitles[0] is the
52
+ // source-preserved inner describe (NOT the source filename for these 3 files
53
+ // — recovery path: vitest report ancestorTitles -> grep this file -> upstream
54
+ // `// ─── from <name>.test.ts ───` block separator -> source filename).
55
+ // Top-level imports merged + deduped.
56
+
57
+ import { readFileSync } from 'node:fs';
58
+ import { resolve } from 'node:path';
59
+ import { fileURLToPath } from 'node:url';
60
+ import { AnimationPlayer } from '@forgeax/engine-animation';
61
+ import type { AssetRuntimeErrorCode } from '@forgeax/engine-assets-runtime';
62
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
63
+ import type { EntityHandle, World as WorldType } from '@forgeax/engine-ecs';
64
+ import { ENTITY_NULL_RAW, World } from '@forgeax/engine-ecs';
65
+ import { SpriteAnimationInvalidError } from '@forgeax/engine-ecs/projection';
66
+ import { mat4, vec3 } from '@forgeax/engine-math';
67
+ import type { RenderErrorCode, Renderer as RendererType } from '@forgeax/engine-render';
68
+ import {
69
+ ANTIALIAS_FXAA,
70
+ ANTIALIAS_NONE,
71
+ BLOOM_DISABLED,
72
+ BLOOM_ENABLED,
73
+ CAMERA_PROJECTION_ORTHOGRAPHIC,
74
+ CAMERA_PROJECTION_PERSPECTIVE,
75
+ Camera,
76
+ MeshFilter,
77
+ MeshRenderer,
78
+ SkyboxBackground,
79
+ Skylight,
80
+ } from '@forgeax/engine-render';
81
+ import type { BindGroupEntry, Buffer, Sampler, Texture, TextureView } from '@forgeax/engine-rhi';
82
+ import { ok as rhiOk } from '@forgeax/engine-rhi';
83
+ import {
84
+ ChildOf,
85
+ GlobalTransform,
86
+ Name,
87
+ propagateTransforms,
88
+ Transform,
89
+ } from '@forgeax/engine-scene';
90
+ import { TONEMAP_LUMINANCE_EPSILON } from '@forgeax/engine-shader';
91
+ import type { SkinErrorCode } from '@forgeax/engine-skinning';
92
+ import {
93
+ Skin,
94
+ SkinInstancesCoexistForbiddenError,
95
+ SkinJointCountExceededError,
96
+ SkinJointDespawnedError,
97
+ SkinJointPathUnresolvedError,
98
+ } from '@forgeax/engine-skinning';
99
+ import type {
100
+ Handle,
101
+ MaterialAsset,
102
+ MeshAsset,
103
+ SkeletonAsset,
104
+ TextureFormat,
105
+ } from '@forgeax/engine-types';
106
+ import { toShared } from '@forgeax/engine-types';
107
+ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
108
+ import { worldInternal } from '../../../ecs/src/world-internal';
109
+ import {
110
+ SPRITE_PLAYBACK_MODE_CLAMP,
111
+ SPRITE_PLAYBACK_MODE_LOOP,
112
+ SpriteAnimation,
113
+ SpriteRegionOverride,
114
+ } from '../../../render/src/components';
115
+ import {
116
+ type CameraProjection,
117
+ cameraProjectionFromF32,
118
+ } from '../../../render/src/components/camera';
119
+ import {
120
+ assembleMaterialWithSkylightEntries,
121
+ createSkylightFallback,
122
+ mergeSkylightIntoMaterialBgl,
123
+ } from '../../../render/src/ibl/skylight-bind-group';
124
+ import { buildPbrPipelineLayouts, buildUnlitMaterialBgl } from '../../../render/src/pbr-pipeline';
125
+ import { INSTANCE_STORAGE_STRIDE_FLOATS } from '../../../render/src/record/mesh-ssbo';
126
+ import { selectSwapChainFormat } from '../../../render/src/render-system';
127
+ import { createSkinPaletteAllocator } from '../../../render/src/systems/skin-palette-allocator';
128
+ import type { TransparentEntry } from '../../../render/src/systems/transparent-sort-config';
129
+ import { standardMaterialShaderVariants } from './helpers/standard-material-manifest';
130
+ import { drawWithOwners } from './renderer-test-utils';
131
+
132
+ function componentFieldType(component: { fields: Record<string, { type: string }> }, name: string) {
133
+ return component.fields[name]?.type;
134
+ }
135
+
136
+ function componentFieldDefault(
137
+ component: { fields: Record<string, { default?: unknown }> },
138
+ name: string,
139
+ ) {
140
+ return component.fields[name]?.default;
141
+ }
142
+
143
+ function componentSchemaTypes(component: { fields: Record<string, { type: string }> }) {
144
+ return Object.fromEntries(
145
+ Object.entries(component.fields).map(([name, field]) => [name, field.type]),
146
+ );
147
+ }
148
+
149
+ afterEach(() => vi.restoreAllMocks());
150
+
151
+ type RendererErrorObservation = {
152
+ readonly code: string;
153
+ readonly detail?: unknown;
154
+ readonly hint?: string;
155
+ };
156
+
157
+ function unwrapRendererError(value: unknown): RendererErrorObservation {
158
+ let current = value as RendererErrorObservation;
159
+ while (
160
+ current.detail !== undefined &&
161
+ typeof current.detail === 'object' &&
162
+ current.detail !== null
163
+ ) {
164
+ const cause = (current.detail as { cause?: unknown }).cause;
165
+ if (
166
+ cause === undefined ||
167
+ typeof cause !== 'object' ||
168
+ cause === null ||
169
+ typeof (cause as { code?: unknown }).code !== 'string'
170
+ ) {
171
+ break;
172
+ }
173
+ current = cause as RendererErrorObservation;
174
+ }
175
+ return current;
176
+ }
177
+
178
+ function subscribeRendererErrors(
179
+ renderer: RendererType,
180
+ listener: (error: RendererErrorObservation) => void,
181
+ ): () => void {
182
+ return renderer.subscribe((event) => {
183
+ if (event.kind === 'error') listener(unwrapRendererError(event.error));
184
+ });
185
+ }
186
+
187
+ function drawPublished(renderer: RendererType, world: WorldType) {
188
+ const attached = renderer.attach(world);
189
+ if (!attached.ok) throw attached.error;
190
+ world.update().unwrap();
191
+ return drawWithOwners(renderer, world);
192
+ }
193
+
194
+ // feat-20260704-runtime-tier1-decomposition M2 / w12: reconstitute the
195
+ // eliminated top-level RuntimeErrorCode aggregate union (D-3) as a test-local
196
+ // alias so the exhaustive-switch bodies below stay byte-identical (AC-09).
197
+ type RuntimeLayerErrorCode = RenderErrorCode | AssetRuntimeErrorCode | SkinErrorCode;
198
+
199
+ import {
200
+ AnimationTargetId,
201
+ bindAnimationTargets,
202
+ advanceAnimationPlayer as canonicalAdvanceAnimationPlayer,
203
+ } from '@forgeax/engine-animation';
204
+ import { deriveAnimationTargetId } from '@forgeax/engine-animation/target-id';
205
+ import { DeviceScope } from '../../../render/src/device/device-scope';
206
+ import { GpuBuffer } from '../../../render/src/gpu-resource';
207
+ import { getOrCreateIblCache, hasIblCache } from '../../../render/src/ibl/IblPipelineCache';
208
+ import {
209
+ disposeInstanceBuffers,
210
+ type InstanceBufferCacheEntry,
211
+ } from '../../../render/src/instance-buffer-cache';
212
+ import { standardPipeline as urpPipeline } from '../../../render/src/pipeline/standard-pipeline';
213
+ import { ZERO_CAMERA_CLEAR_FALLBACK } from '../../../render/src/record/frame-snapshot';
214
+ import {
215
+ warnMultiLightDirectional,
216
+ warnMultiLightPoint,
217
+ warnMultiLightSpot,
218
+ } from '../../../render/src/record/helpers';
219
+ import type { CameraSnapshot } from '../../../render/src/render-contract';
220
+ import {
221
+ type ExtractedLights,
222
+ extractFrame,
223
+ extractFrames,
224
+ prepareExtractContext,
225
+ } from '../../../render/src/render-system-extract';
226
+ import {
227
+ getTransparentSortConfig,
228
+ setTransparentSortConfig,
229
+ TRANSPARENT_SORT_CONFIG_KEY,
230
+ TRANSPARENT_SORT_MODE_LAYER_Y,
231
+ TRANSPARENT_SORT_MODE_LAYER_YZ,
232
+ TRANSPARENT_SORT_MODE_LAYER_Z,
233
+ } from '../../../render/src/systems/transparent-sort-config';
234
+ import { spriteAnimationTickSystem } from '../systems/sprite-animation-tick';
235
+ import { REC709_LUMA_WEIGHTS, tonemapReinhardLuminance } from '../systems/tonemap';
236
+ import { transparentSortEntries } from '../systems/transparent-sort';
237
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
238
+
239
+ void [
240
+ ANTIALIAS_FXAA,
241
+ ANTIALIAS_NONE,
242
+ AnimationPlayer,
243
+ AnimationTargetId,
244
+ AssetRegistry,
245
+ BLOOM_DISABLED,
246
+ BLOOM_ENABLED,
247
+ CAMERA_PROJECTION_ORTHOGRAPHIC,
248
+ CAMERA_PROJECTION_PERSPECTIVE,
249
+ Camera,
250
+ ChildOf,
251
+ DeviceScope,
252
+ ENTITY_NULL_RAW,
253
+ GpuBuffer,
254
+ INSTANCE_STORAGE_STRIDE_FLOATS,
255
+ MeshFilter,
256
+ MeshRenderer,
257
+ Name,
258
+ REC709_LUMA_WEIGHTS,
259
+ SPRITE_PLAYBACK_MODE_CLAMP,
260
+ SPRITE_PLAYBACK_MODE_LOOP,
261
+ Skin,
262
+ SkinInstancesCoexistForbiddenError,
263
+ SkinJointCountExceededError,
264
+ SkinJointDespawnedError,
265
+ SkinJointPathUnresolvedError,
266
+ SkyboxBackground,
267
+ Skylight,
268
+ SpriteAnimation,
269
+ SpriteAnimationInvalidError,
270
+ SpriteRegionOverride,
271
+ TONEMAP_LUMINANCE_EPSILON,
272
+ TRANSPARENT_SORT_CONFIG_KEY,
273
+ TRANSPARENT_SORT_MODE_LAYER_Y,
274
+ TRANSPARENT_SORT_MODE_LAYER_YZ,
275
+ TRANSPARENT_SORT_MODE_LAYER_Z,
276
+ Transform,
277
+ World,
278
+ ZERO_CAMERA_CLEAR_FALLBACK,
279
+ afterEach,
280
+ assembleMaterialWithSkylightEntries,
281
+ beforeAll,
282
+ beforeEach,
283
+ bindAnimationTargets,
284
+ buildPbrPipelineLayouts,
285
+ buildUnlitMaterialBgl,
286
+ cameraProjectionFromF32,
287
+ canonicalAdvanceAnimationPlayer,
288
+ componentFieldDefault,
289
+ componentFieldType,
290
+ componentSchemaTypes,
291
+ createSkinPaletteAllocator,
292
+ createSkylightFallback,
293
+ deriveAnimationTargetId,
294
+ describe,
295
+ disposeInstanceBuffers,
296
+ drawPublished,
297
+ drawWithOwners,
298
+ expect,
299
+ extractFrame,
300
+ extractFrames,
301
+ fileURLToPath,
302
+ getOrCreateIblCache,
303
+ getTransparentSortConfig,
304
+ hasIblCache,
305
+ it,
306
+ makeMockShaderRegistry,
307
+ mat4,
308
+ mergeSkylightIntoMaterialBgl,
309
+ prepareExtractContext,
310
+ propagateTransforms,
311
+ readFileSync,
312
+ resolve,
313
+ rhiOk,
314
+ selectSwapChainFormat,
315
+ setTransparentSortConfig,
316
+ spriteAnimationTickSystem,
317
+ standardMaterialShaderVariants,
318
+ subscribeRendererErrors,
319
+ toShared,
320
+ tonemapReinhardLuminance,
321
+ transparentSortEntries,
322
+ unwrapRendererError,
323
+ urpPipeline,
324
+ vec3,
325
+ vi,
326
+ warnMultiLightDirectional,
327
+ warnMultiLightPoint,
328
+ warnMultiLightSpot,
329
+ worldInternal,
330
+ ];
331
+ type __MergedKeep =
332
+ | AssetRuntimeErrorCode
333
+ | BindGroupEntry
334
+ | Buffer
335
+ | CameraProjection
336
+ | CameraSnapshot
337
+ | EntityHandle
338
+ | ExtractedLights
339
+ | Handle
340
+ | InstanceBufferCacheEntry
341
+ | MaterialAsset
342
+ | MeshAsset
343
+ | RenderErrorCode
344
+ | RendererErrorObservation
345
+ | RendererType
346
+ | RuntimeLayerErrorCode
347
+ | Sampler
348
+ | SkeletonAsset
349
+ | SkinErrorCode
350
+ | Texture
351
+ | TextureFormat
352
+ | TextureView
353
+ | TransparentEntry
354
+ | WorldType;
355
+
356
+ {
357
+ // --- from propagate-transforms.test.ts ---
358
+
359
+ interface LocalTrs {
360
+ pos: number[];
361
+ quat: number[];
362
+ scale: number[];
363
+ }
364
+
365
+ function trs(overrides: Partial<LocalTrs> = {}): LocalTrs {
366
+ return {
367
+ pos: [0, 0, 0],
368
+ quat: [0, 0, 0, 1],
369
+ scale: [1, 1, 1],
370
+ ...overrides,
371
+ };
372
+ }
373
+
374
+ /** Independent reference compose(local.TRS) for in-test expectation. */
375
+ function composeLocal(t: LocalTrs): Float32Array {
376
+ const out = mat4.create();
377
+ mat4.compose(out, t.pos, t.quat, t.scale);
378
+ return out;
379
+ }
380
+
381
+ function readWorld(world: World, entity: EntityHandle): Float32Array {
382
+ return world.get(entity, GlobalTransform).unwrap().world as Float32Array;
383
+ }
384
+
385
+ function expectMatClose(actual: Float32Array, expected: Float32Array): void {
386
+ for (let i = 0; i < 16; i++) {
387
+ expect(actual[i]).toBeCloseTo(expected[i] as number, 5);
388
+ }
389
+ }
390
+
391
+ describe('w7 - propagate writes GlobalTransform.world mat4 (AC-05 / AC-06)', () => {
392
+ it('root: world == compose(local.TRS) element-wise epsilon<=1e-5 (AC-06)', () => {
393
+ const world = new World();
394
+ const local = trs({ pos: [3, 4, 5], scale: [2, 2, 2] });
395
+ const root = world.spawn({ component: Transform, data: local }).unwrap();
396
+
397
+ const r = propagateTransforms(world);
398
+ expect(r.ok).toBe(true);
399
+
400
+ const view = readWorld(world, root);
401
+ expectMatClose(view, composeLocal(local));
402
+ });
403
+
404
+ it('flat (no ChildOf, no extra component): world == compose(local) without registering anything (AC-06)', () => {
405
+ const world = new World();
406
+ // 90deg rotation about +Z: quat (0, 0, sin45, cos45) = (0, 0, SQRT1_2, SQRT1_2).
407
+ const local = trs({ pos: [0, 7, 0], quat: [0, 0, Math.SQRT1_2, Math.SQRT1_2] });
408
+ const flat = world.spawn({ component: Transform, data: local }).unwrap();
409
+
410
+ const r = propagateTransforms(world);
411
+ expect(r.ok).toBe(true);
412
+
413
+ const view = readWorld(world, flat);
414
+ expectMatClose(view, composeLocal(local));
415
+ });
416
+
417
+ it('child: world == parent.world x compose(local) element-wise epsilon<=1e-5 (AC-05)', () => {
418
+ const world = new World();
419
+ const parentLocal = trs({ pos: [10, 0, 0], scale: [2, 2, 2] });
420
+ const childLocal = trs({ pos: [2, 3, 0] });
421
+ const parent = world.spawn({ component: Transform, data: parentLocal }).unwrap();
422
+ const child = world
423
+ .spawn({ component: Transform, data: childLocal }, { component: ChildOf, data: { parent } })
424
+ .unwrap();
425
+
426
+ const r = propagateTransforms(world);
427
+ expect(r.ok).toBe(true);
428
+
429
+ // parent.world = compose(parentLocal); child.world = parent.world x compose(childLocal).
430
+ const expectedParent = composeLocal(parentLocal);
431
+ const expectedChild = mat4.create();
432
+ mat4.multiply(expectedChild, expectedParent, composeLocal(childLocal));
433
+
434
+ expectMatClose(readWorld(world, parent), expectedParent);
435
+ expectMatClose(readWorld(world, child), expectedChild);
436
+
437
+ // Sanity on the composed translation: parent scales child local pos by 2,
438
+ // adds parent translation -> (10 + 2*2, 0 + 2*3, 0) = (14, 6, 0).
439
+ const cv = readWorld(world, child);
440
+ expect(cv[12]).toBeCloseTo(14, 5);
441
+ expect(cv[13]).toBeCloseTo(6, 5);
442
+ expect(cv[14]).toBeCloseTo(0, 5);
443
+ });
444
+
445
+ it('deep chain grandparent -> parent -> child: world stacks left-multiplied (AC-05)', () => {
446
+ const world = new World();
447
+ const gpLocal = trs({ pos: [1, 0, 0] });
448
+ const pLocal = trs({ pos: [2, 0, 0] });
449
+ const cLocal = trs({ pos: [4, 0, 0] });
450
+ const gp = world.spawn({ component: Transform, data: gpLocal }).unwrap();
451
+ const p = world
452
+ .spawn({ component: Transform, data: pLocal }, { component: ChildOf, data: { parent: gp } })
453
+ .unwrap();
454
+ const c = world
455
+ .spawn({ component: Transform, data: cLocal }, { component: ChildOf, data: { parent: p } })
456
+ .unwrap();
457
+
458
+ const r = propagateTransforms(world);
459
+ expect(r.ok).toBe(true);
460
+
461
+ const gpWorld = composeLocal(gpLocal);
462
+ const pWorld = mat4.create();
463
+ mat4.multiply(pWorld, gpWorld, composeLocal(pLocal));
464
+ const cWorld = mat4.create();
465
+ mat4.multiply(cWorld, pWorld, composeLocal(cLocal));
466
+
467
+ expectMatClose(readWorld(world, gp), gpWorld);
468
+ expectMatClose(readWorld(world, p), pWorld);
469
+ expectMatClose(readWorld(world, c), cWorld);
470
+
471
+ // 1 + 2 + 4 = 7 along x.
472
+ expect(readWorld(world, c)[12]).toBeCloseTo(7, 5);
473
+ });
474
+
475
+ it('ChildOf referencing a despawned parent: hierarchy-broken (existing missing-parent semantics)', () => {
476
+ const world = new World();
477
+ const ghost = world.spawn({ component: Transform, data: trs() }).unwrap();
478
+ world.despawn(ghost).unwrap();
479
+ const parent = world.spawn({ component: Transform, data: trs() }).unwrap();
480
+ const child = world
481
+ .spawn({ component: Transform, data: trs() }, { component: ChildOf, data: { parent } })
482
+ .unwrap();
483
+
484
+ // Public relationship writes reject stale targets. Deliberately corrupt
485
+ // only the source column through the package-internal seam to preserve
486
+ // this diagnostic regression for malformed imported/editor state.
487
+ const archetype = world[worldInternal].getEntityArchetype(child);
488
+ const record = world[worldInternal].getRecords()[child & 0xffffff];
489
+ if (archetype === undefined || record === undefined) throw new Error('child row missing');
490
+ const tableRow = archetype.rows[record.archetypeRow];
491
+ if (tableRow === undefined) throw new Error('child table row missing');
492
+ world[worldInternal].writeRow(archetype, ChildOf, tableRow, { parent: ghost });
493
+
494
+ const r = propagateTransforms(world);
495
+ expect(r.ok).toBe(false);
496
+ if (r.ok) return;
497
+ expect(r.error.code).toBe('hierarchy-broken');
498
+ expect(r.error.hint.length).toBeGreaterThan(0);
499
+ expect(r.error.expected.length).toBeGreaterThan(0);
500
+ });
501
+ });
502
+ }
@@ -5,13 +5,12 @@
5
5
  // Environment: node + setupFiles ./vitest.setup-webgpu.ts injects
6
6
  // globalThis.navigator.gpu (provided by dawn.node native binding).
7
7
  //
8
- // feat-20260601 M4: GlobalTransform is retired. propagateTransforms now writes
9
- // the resolved world mat4 into the `Transform.world` column (column-major 16
10
- // floats). Tests read that column via the ECS array view and assert the
11
- // translation column (m[12,13,14]).
8
+ // The derived world mat4 lives in the paired `GlobalTransform.world` column
9
+ // (column-major 16 floats). Tests read that column via the ECS array view and
10
+ // assert the translation column (m[12,13,14]).
12
11
  //
13
12
  // Scope (w6 acceptanceCheck):
14
- // (a) root-only entity: Transform.world translation = local translation
13
+ // (a) root-only entity: GlobalTransform.world translation = local translation
15
14
  // (b) 2-level hierarchy: child.world = parent.world x child local
16
15
  // (c) stale ChildOf ref: Result.err(RhiError({ code: 'hierarchy-broken' }))
17
16
  // (d) N=3 deep chain: composition stacks correctly
@@ -24,8 +23,9 @@
24
23
  import type { EntityHandle } from '@forgeax/engine-ecs';
25
24
  import { World } from '@forgeax/engine-ecs';
26
25
  import { readRenderArrayView } from '@forgeax/engine-ecs/projection';
27
- import { ChildOf, propagateTransforms, Transform } from '@forgeax/engine-scene';
26
+ import { ChildOf, GlobalTransform, propagateTransforms, Transform } from '@forgeax/engine-scene';
28
27
  import { describe, expect, it } from 'vitest';
28
+ import { worldInternal } from '../../../ecs/src/world-internal';
29
29
  import { TileLayer, Tilemap } from '../../../render/src/components';
30
30
 
31
31
  function identityTransformData() {
@@ -36,16 +36,17 @@ function identityTransformData() {
36
36
  };
37
37
  }
38
38
 
39
- // Read the resolved world mat4 (column-major 16 floats) from the Transform
40
- // world column array view. Translation lives in column 3 (m[12,13,14]).
39
+ // Read the resolved world mat4 (column-major 16 floats) from the
40
+ // GlobalTransform world column array view. Translation lives in column 3
41
+ // (m[12,13,14]).
41
42
  function worldOf(world: World, entity: EntityHandle): Float32Array {
42
- const view = readRenderArrayView(world, entity, Transform, 'world');
43
- if (view === undefined) throw new Error('Transform.world view missing');
43
+ const view = readRenderArrayView(world, entity, GlobalTransform, 'world');
44
+ if (view === undefined) throw new Error('GlobalTransform.world view missing');
44
45
  return view as Float32Array;
45
46
  }
46
47
 
47
48
  describe('propagate-transforms.dawn - root-down DFS + stale ChildOf fail-fast (AC-04)', () => {
48
- it('root entity: Transform.world translation = local translation (identity chain)', () => {
49
+ it('root entity: GlobalTransform.world translation = local translation (identity chain)', () => {
49
50
  const world = new World();
50
51
  const root = world
51
52
  .spawn({
@@ -153,7 +154,7 @@ describe('propagate-transforms.dawn - root-down DFS + stale ChildOf fail-fast (A
153
154
 
154
155
  // AC-07 (tweak-20260714-tilemap-layer-childed-render-entities M5): TileLayer
155
156
  // as an identity middle node must be transparent to propagateTransforms -- the
156
- // layer's Transform.world (16 f32) must equal its Tilemap parent's world mat4
157
+ // layer's GlobalTransform.world (16 f32) must equal its Tilemap parent's world mat4
157
158
  // byte-for-byte. This proves M1's coAttach injection produces a genuinely
158
159
  // identity TRS (pos=[0,0,0], quat=[0,0,0,1], scale=[1,1,1]) and the compose
159
160
  // (parent.world x identity) is a no-op in mat4 form.
@@ -165,7 +166,7 @@ describe('propagate-transforms.dawn - root-down DFS + stale ChildOf fail-fast (A
165
166
  // asserted here because the M1 contract is precisely "identity default,
166
167
  // callers may override" -- the interesting invariant is transparency in the
167
168
  // default case.
168
- it('AC-07: identity TileLayer middle node -> Transform.world byte-identical to Tilemap parent', () => {
169
+ it('AC-07: identity TileLayer middle node -> GlobalTransform.world byte-identical to Tilemap parent', () => {
169
170
  const world = new World();
170
171
  for (const component of [ChildOf, TileLayer, Tilemap, Transform]) {
171
172
  world.components.register(component).unwrap();
@@ -189,9 +190,8 @@ describe('propagate-transforms.dawn - root-down DFS + stale ChildOf fail-fast (A
189
190
  },
190
191
  )
191
192
  .unwrap();
192
- // TileLayer carries an explicit identity Transform in the current ECS
193
- // component vocabulary. This mirrors the demo spawn pattern in
194
- // apps/hello/tilemap/** and keeps the hierarchy contract explicit.
193
+ // TileLayer carries an identity Transform; the generic Transform requirement
194
+ // materializes its GlobalTransform world column at the structural boundary.
195
195
  const layer = world
196
196
  .spawn(
197
197
  {
@@ -234,16 +234,32 @@ describe('propagate-transforms.dawn - root-down DFS + stale ChildOf fail-fast (A
234
234
  })
235
235
  .unwrap();
236
236
  world.despawn(ghost).unwrap();
237
+ const parent = world
238
+ .spawn({
239
+ component: Transform,
240
+ data: identityTransformData(),
241
+ })
242
+ .unwrap();
237
243
  const orphan = world
238
244
  .spawn(
239
245
  {
240
246
  component: Transform,
241
247
  data: identityTransformData(),
242
248
  },
243
- { component: ChildOf, data: { parent: ghost } },
249
+ { component: ChildOf, data: { parent } },
244
250
  )
245
251
  .unwrap();
246
- void orphan;
252
+
253
+ // Public relationship writes reject stale targets. Deliberately corrupt
254
+ // only the source column through the package-internal seam to preserve
255
+ // this diagnostic regression for malformed imported/editor state.
256
+ const archetype = world[worldInternal].getEntityArchetype(orphan);
257
+ const record = world[worldInternal].getRecords()[orphan & 0xffffff];
258
+ if (archetype === undefined || record === undefined) throw new Error('orphan row missing');
259
+ const tableRow = archetype.rows[record.archetypeRow];
260
+ if (tableRow === undefined) throw new Error('orphan table row missing');
261
+ world[worldInternal].writeRow(archetype, ChildOf, tableRow, { parent: ghost });
262
+
247
263
  const r = propagateTransforms(world);
248
264
  expect(r.ok).toBe(false);
249
265
  if (r.ok) return;