@cimplify/sdk 0.108.0 → 0.110.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (608) hide show
  1. package/LICENSE +21 -0
  2. package/dist/advanced.d.mts +4 -3
  3. package/dist/advanced.d.ts +4 -3
  4. package/dist/advanced.js +24 -24
  5. package/dist/advanced.mjs +5 -5
  6. package/dist/animation-4EXBXRVX.js +27 -0
  7. package/dist/animation-6DICNWUP.mjs +6 -0
  8. package/dist/audio-DhvyjqdA.d.mts +249 -0
  9. package/dist/audio-m0w8cnxq.d.ts +249 -0
  10. package/dist/avatars.d.mts +110 -0
  11. package/dist/avatars.d.ts +110 -0
  12. package/dist/avatars.js +82 -0
  13. package/dist/avatars.mjs +5 -0
  14. package/dist/backend-gUCzs5Kg.d.mts +3866 -0
  15. package/dist/backend-gUCzs5Kg.d.ts +3866 -0
  16. package/dist/{catalogue-B4eLL8Mi.d.ts → catalogue-CPTMyBUz.d.mts} +109 -221
  17. package/dist/catalogue-DzrTXP3v.d.mts +541 -0
  18. package/dist/catalogue-DzrTXP3v.d.ts +541 -0
  19. package/dist/{catalogue-OT89_Ifs.d.mts → catalogue-OTuS5zp-.d.ts} +109 -221
  20. package/dist/chunk-22BD3RHN.mjs +1809 -0
  21. package/dist/chunk-25T4JHEA.mjs +21 -0
  22. package/dist/chunk-2AQ237Y4.js +508 -0
  23. package/dist/chunk-2IC4H6OV.mjs +48 -0
  24. package/dist/chunk-2LHLG4OB.mjs +71 -0
  25. package/dist/chunk-2O2CG465.js +1709 -0
  26. package/dist/chunk-2Q4DTHXK.js +316 -0
  27. package/dist/chunk-2QTQ6BUH.mjs +46 -0
  28. package/dist/chunk-2UN4SFLR.mjs +100 -0
  29. package/dist/chunk-2V75I7K3.js +454 -0
  30. package/dist/chunk-2V7IL4HC.js +10 -0
  31. package/dist/chunk-34XBXUMW.js +296 -0
  32. package/dist/chunk-3C4C654I.js +71 -0
  33. package/dist/chunk-3DAD2LDF.mjs +72 -0
  34. package/dist/chunk-3GXH2NFD.mjs +4 -0
  35. package/dist/chunk-3O47ZFW3.js +961 -0
  36. package/dist/chunk-3OY3VYNF.mjs +11 -0
  37. package/dist/chunk-3S6WPBZL.js +2936 -0
  38. package/dist/chunk-3TUOUP5T.js +399 -0
  39. package/dist/chunk-3VEH23I5.mjs +1380 -0
  40. package/dist/chunk-3ZYSAW2T.mjs +263 -0
  41. package/dist/chunk-4ANVF274.js +103 -0
  42. package/dist/chunk-4C7I3ELN.js +388 -0
  43. package/dist/chunk-4DYKAYFO.mjs +8 -0
  44. package/dist/chunk-4ZDR72SG.js +329 -0
  45. package/dist/chunk-52YS45RR.js +1066 -0
  46. package/dist/chunk-5325XSCH.js +107 -0
  47. package/dist/chunk-5AD5X6AV.js +13 -0
  48. package/dist/chunk-5BYDGGWO.mjs +197 -0
  49. package/dist/chunk-5C3C7VDM.mjs +55 -0
  50. package/dist/chunk-5HFMY3D7.js +660 -0
  51. package/dist/chunk-5LH2QN3T.js +1862 -0
  52. package/dist/chunk-5PJEXSOW.js +44 -0
  53. package/dist/chunk-5SXDH3Y7.js +90 -0
  54. package/dist/chunk-5YFBGGCK.mjs +502 -0
  55. package/dist/chunk-5YWN6H5Q.mjs +133 -0
  56. package/dist/chunk-66QP3SMN.js +402 -0
  57. package/dist/chunk-6DAEZKIG.mjs +385 -0
  58. package/dist/chunk-6DATW7TB.mjs +420 -0
  59. package/dist/{chunk-JRGK3NXR.mjs → chunk-6ETDAU62.mjs} +72 -212
  60. package/dist/chunk-6H254EVP.mjs +178 -0
  61. package/dist/chunk-6PFNJPBJ.mjs +820 -0
  62. package/dist/chunk-6PJWXIFX.mjs +357 -0
  63. package/dist/chunk-6SWKWCMS.js +80 -0
  64. package/dist/chunk-6VVXXX7S.js +808 -0
  65. package/dist/chunk-6WUBSMTX.js +1403 -0
  66. package/dist/chunk-73SGZLAQ.mjs +35 -0
  67. package/dist/chunk-76L2V6KD.mjs +4 -0
  68. package/dist/chunk-7AAIAVAA.js +1531 -0
  69. package/dist/chunk-7ARSJPV3.mjs +93 -0
  70. package/dist/chunk-7BHW5GTC.mjs +1234 -0
  71. package/dist/chunk-7DQSDKDU.js +6 -0
  72. package/dist/chunk-7IQQQENP.mjs +401 -0
  73. package/dist/chunk-7KFTYENS.js +11357 -0
  74. package/dist/chunk-7SM6XSPZ.js +3171 -0
  75. package/dist/chunk-7SXOHAIR.mjs +28 -0
  76. package/dist/chunk-A2MAX6S4.js +90 -0
  77. package/dist/chunk-A33OORT7.mjs +1530 -0
  78. package/dist/{chunk-U6ACF76H.mjs → chunk-A36JRXXH.mjs} +1075 -1845
  79. package/dist/chunk-A7BU3BK4.js +52 -0
  80. package/dist/chunk-A7MQSN2V.mjs +77 -0
  81. package/dist/chunk-A7V4L2IT.mjs +416 -0
  82. package/dist/chunk-AABEK6XU.js +226 -0
  83. package/dist/chunk-AGV33FWC.mjs +5005 -0
  84. package/dist/chunk-AHNR3BXI.js +108 -0
  85. package/dist/chunk-AQ5RLBU2.mjs +286 -0
  86. package/dist/chunk-AQOE6WCG.js +1270 -0
  87. package/dist/chunk-ATAWRACV.mjs +62 -0
  88. package/dist/chunk-ATCURNUV.js +14 -0
  89. package/dist/chunk-AWPV33OO.js +6 -0
  90. package/dist/chunk-AYJPHKYV.js +337 -0
  91. package/dist/chunk-AZ5BGWHB.js +162 -0
  92. package/dist/chunk-AZAXD44P.js +1373 -0
  93. package/dist/chunk-BBGKQIJJ.mjs +406 -0
  94. package/dist/chunk-BP4JLSUA.js +1453 -0
  95. package/dist/{chunk-SUCE7FWA.mjs → chunk-BTUSVHIE.mjs} +539 -978
  96. package/dist/chunk-BU6OK542.mjs +818 -0
  97. package/dist/chunk-CVSRWM6W.js +418 -0
  98. package/dist/chunk-CYBMFMJD.mjs +247 -0
  99. package/dist/chunk-DDJLDOUX.mjs +217 -0
  100. package/dist/{chunk-V32BCG7M.js → chunk-DFZWHNRG.js} +75 -215
  101. package/dist/chunk-DJ2C7AVG.js +644 -0
  102. package/dist/chunk-DS2VU4WW.mjs +102 -0
  103. package/dist/chunk-DSAG7T5P.js +7290 -0
  104. package/dist/chunk-E2QPPH7I.js +327 -0
  105. package/dist/chunk-E65WCTIG.mjs +1187 -0
  106. package/dist/{chunk-33VCYWVL.mjs → chunk-E6QQKDNE.mjs} +30 -42
  107. package/dist/chunk-ECDK6QBF.mjs +981 -0
  108. package/dist/chunk-EIB4OWVQ.mjs +620 -0
  109. package/dist/chunk-EQUZYCGO.js +250 -0
  110. package/dist/chunk-F3UJ6ZRM.mjs +313 -0
  111. package/dist/chunk-F63N2ZTQ.js +7023 -0
  112. package/dist/chunk-F6XRYEM3.mjs +26 -0
  113. package/dist/chunk-FE6VCE4K.js +5030 -0
  114. package/dist/chunk-FLWD6GRR.js +1372 -0
  115. package/dist/chunk-FQBFWJBS.mjs +110 -0
  116. package/dist/chunk-FXVJ2HFU.js +26 -0
  117. package/dist/chunk-FZMQMQBW.js +312 -0
  118. package/dist/chunk-G3EEC44R.js +53 -0
  119. package/dist/{chunk-KG3WT4PR.mjs → chunk-GCKWKLZF.mjs} +73 -104
  120. package/dist/chunk-GCX7TY4D.mjs +6826 -0
  121. package/dist/chunk-GDB6TCSD.js +450 -0
  122. package/dist/chunk-GDCV4IWO.mjs +21 -0
  123. package/dist/chunk-GDZT5LZ5.js +170 -0
  124. package/dist/chunk-GHPUYD4I.mjs +213 -0
  125. package/dist/chunk-GHS6MIL6.mjs +1432 -0
  126. package/dist/chunk-GPS2THCL.mjs +11 -0
  127. package/dist/{chunk-EV2EVOYS.js → chunk-GTJWQAGU.js} +31 -42
  128. package/dist/chunk-GVTI6UJQ.mjs +130 -0
  129. package/dist/chunk-GXKI64OT.mjs +1138 -0
  130. package/dist/chunk-GYDYF2WX.js +275 -0
  131. package/dist/chunk-GYLP6UG4.mjs +705 -0
  132. package/dist/chunk-H3OQKK6X.js +1158 -0
  133. package/dist/chunk-H5DFSCJ6.js +40 -0
  134. package/dist/chunk-HAGEIC2L.mjs +186 -0
  135. package/dist/chunk-HAJ4JRFO.js +293 -0
  136. package/dist/chunk-HDR72GB6.js +188 -0
  137. package/dist/chunk-HF5HPS4T.mjs +40 -0
  138. package/dist/chunk-HK6LOFDS.js +218 -0
  139. package/dist/chunk-HMWYTXCY.mjs +143 -0
  140. package/dist/chunk-HPCSRCMA.js +89 -0
  141. package/dist/chunk-HSEO6TPU.js +247 -0
  142. package/dist/chunk-I5FOHCLH.js +132 -0
  143. package/dist/chunk-IDLW4NWA.mjs +85 -0
  144. package/dist/chunk-IIDZ5WUX.js +61 -0
  145. package/dist/chunk-IR74FJHU.js +2332 -0
  146. package/dist/chunk-IRVFYAKP.mjs +100 -0
  147. package/dist/{chunk-XBL3TMPC.mjs → chunk-IZDWAL53.mjs} +1795 -3287
  148. package/dist/chunk-J2KZXIU3.js +51 -0
  149. package/dist/chunk-J2U6PJSO.js +91 -0
  150. package/dist/chunk-J5AJNY2N.js +283 -0
  151. package/dist/chunk-J6KQZ4FO.mjs +821 -0
  152. package/dist/{chunk-OWW5GUSB.js → chunk-JGBCIKJV.js} +7 -6
  153. package/dist/chunk-JKGTBMU7.mjs +25 -0
  154. package/dist/chunk-JR3TNEQC.js +422 -0
  155. package/dist/chunk-JURRXY2J.mjs +29 -0
  156. package/dist/chunk-K3HW5I2A.mjs +317 -0
  157. package/dist/chunk-K46SMZ66.mjs +103 -0
  158. package/dist/chunk-K4UDGE3Z.mjs +6 -0
  159. package/dist/chunk-KDQOR4QQ.mjs +350 -0
  160. package/dist/chunk-KDTVOLHI.mjs +288 -0
  161. package/dist/chunk-KGHJH5KJ.mjs +35 -0
  162. package/dist/chunk-KIZOA5LX.mjs +140 -0
  163. package/dist/chunk-KK6HYVBI.mjs +242 -0
  164. package/dist/chunk-KMKWGXMK.js +856 -0
  165. package/dist/chunk-KPA6K5IB.js +80 -0
  166. package/dist/chunk-KU7O4IXU.mjs +260 -0
  167. package/dist/chunk-KVFNRJOR.mjs +11142 -0
  168. package/dist/chunk-KZJRSXHK.js +2432 -0
  169. package/dist/chunk-LHWPRUJL.js +79 -0
  170. package/dist/chunk-LIV3KXJG.mjs +369 -0
  171. package/dist/chunk-LKV4LACG.js +21 -0
  172. package/dist/chunk-LUY45X3U.mjs +263 -0
  173. package/dist/chunk-LYEZZEEF.mjs +17 -0
  174. package/dist/chunk-M5EXQZYY.mjs +1519 -0
  175. package/dist/chunk-ME6HGG4I.mjs +1338 -0
  176. package/dist/chunk-MEXP6DA6.js +31 -0
  177. package/dist/chunk-MG52AW3H.js +902 -0
  178. package/dist/chunk-MIPO6F72.js +334 -0
  179. package/dist/{chunk-5QW7CQBA.js → chunk-MKIJQL5Q.js} +211 -321
  180. package/dist/chunk-MN3YETVN.mjs +17 -0
  181. package/dist/chunk-MOBSBXVE.mjs +2391 -0
  182. package/dist/chunk-MOMOZEUM.mjs +88 -0
  183. package/dist/chunk-MRFUNRAP.js +62 -0
  184. package/dist/chunk-MTIHEW2M.js +433 -0
  185. package/dist/chunk-N4RGGDEL.mjs +73 -0
  186. package/dist/chunk-NH654HAT.js +10 -0
  187. package/dist/chunk-NHJUGZUR.mjs +253 -0
  188. package/dist/chunk-NMQT4HG3.mjs +757 -0
  189. package/dist/chunk-NPSYB6DC.mjs +906 -0
  190. package/dist/chunk-NW2GPMSO.js +857 -0
  191. package/dist/chunk-NXKQOQ6L.js +76 -0
  192. package/dist/chunk-NXLAZIJZ.js +309 -0
  193. package/dist/chunk-NYWNA5CF.js +148 -0
  194. package/dist/chunk-NZTKLY2W.js +1442 -0
  195. package/dist/chunk-O2ICABUD.js +36 -0
  196. package/dist/chunk-OIVVQQ22.js +862 -0
  197. package/dist/chunk-OKC2B4O3.mjs +312 -0
  198. package/dist/chunk-OLWFPDBK.js +2220 -0
  199. package/dist/chunk-OMTVH334.js +3779 -0
  200. package/dist/chunk-OQRVEM56.mjs +362 -0
  201. package/dist/chunk-OXMIBOD4.js +337 -0
  202. package/dist/chunk-PBL6YL5L.mjs +288 -0
  203. package/dist/chunk-PDOELNNQ.js +97 -0
  204. package/dist/chunk-PDQJY2GZ.js +136 -0
  205. package/dist/chunk-PKOZXD2Q.js +1274 -0
  206. package/dist/chunk-PPF2BYFL.mjs +2191 -0
  207. package/dist/chunk-PQTQKNKD.js +539 -0
  208. package/dist/chunk-PRSR4FAV.mjs +81 -0
  209. package/dist/chunk-PTRNO5UD.js +95 -0
  210. package/dist/chunk-Q2Y3VMKH.js +2000 -0
  211. package/dist/chunk-QCZOE65N.js +96 -0
  212. package/dist/chunk-QDYFLATW.mjs +52 -0
  213. package/dist/chunk-QQABGCMM.js +22 -0
  214. package/dist/chunk-QS6TRHMR.js +345 -0
  215. package/dist/chunk-R56P64LB.mjs +208 -0
  216. package/dist/chunk-RCQ2MPBV.js +428 -0
  217. package/dist/chunk-RFVRPYR2.mjs +856 -0
  218. package/dist/chunk-RKBLPGPV.js +11521 -0
  219. package/dist/chunk-RM2V4IND.mjs +327 -0
  220. package/dist/chunk-RQXN5A34.mjs +613 -0
  221. package/dist/chunk-RUVGVNOF.mjs +2687 -0
  222. package/dist/chunk-SAFJIGYB.mjs +165 -0
  223. package/dist/chunk-SKQFLBDD.js +263 -0
  224. package/dist/chunk-SMK6JU2F.mjs +2092 -0
  225. package/dist/{chunk-UVRPC2P7.js → chunk-SNNEOS5Z.js} +1984 -3476
  226. package/dist/chunk-SPCRQ6NO.mjs +1246 -0
  227. package/dist/chunk-SWX4SALA.mjs +19 -0
  228. package/dist/{chunk-JVODCGFP.mjs → chunk-SYEO2WV4.mjs} +128 -238
  229. package/dist/chunk-T2QQMX2N.js +10 -0
  230. package/dist/chunk-T3AFF3L7.mjs +57 -0
  231. package/dist/chunk-T6Z2EXYL.js +712 -0
  232. package/dist/chunk-T7LOXGYX.js +118 -0
  233. package/dist/chunk-TJCAE7RC.mjs +1315 -0
  234. package/dist/chunk-TJI3K6RP.js +137 -0
  235. package/dist/chunk-TL2SVO4P.mjs +55 -0
  236. package/dist/chunk-TM63CYGN.mjs +399 -0
  237. package/dist/chunk-TU5RYTYU.mjs +13 -0
  238. package/dist/chunk-TVJZ4GPS.js +1553 -0
  239. package/dist/chunk-TWM6DLYF.js +371 -0
  240. package/dist/chunk-U63OC4TQ.js +30 -0
  241. package/dist/{chunk-L5GKVQVJ.js → chunk-U6BVSJZ6.js} +25 -57
  242. package/dist/chunk-U6UVWEAK.mjs +792 -0
  243. package/dist/chunk-UCEPNO6N.mjs +11048 -0
  244. package/dist/{chunk-ANT574FD.js → chunk-UCR5HRYM.js} +74 -105
  245. package/dist/chunk-UG5BTOTF.mjs +334 -0
  246. package/dist/chunk-UGH37BQW.mjs +157 -0
  247. package/dist/chunk-V7ZRH3PY.mjs +271 -0
  248. package/dist/chunk-VBGHBL3E.mjs +1394 -0
  249. package/dist/chunk-VRBDAS5I.js +920 -0
  250. package/dist/chunk-VVE3Y76O.js +230 -0
  251. package/dist/chunk-W65JIRI4.mjs +1182 -0
  252. package/dist/chunk-WHYKAT7G.js +62 -0
  253. package/dist/{chunk-YOIVZ6OA.mjs → chunk-WIZRUIZB.mjs} +25 -57
  254. package/dist/chunk-WKWTDZS7.js +385 -0
  255. package/dist/chunk-WLMINRC4.mjs +78 -0
  256. package/dist/chunk-WOF3AD3J.js +22 -0
  257. package/dist/chunk-WWKMOA76.js +1262 -0
  258. package/dist/chunk-X5A5FOWW.js +615 -0
  259. package/dist/chunk-X6CN6KQF.mjs +192 -0
  260. package/dist/chunk-XD2PMH46.mjs +517 -0
  261. package/dist/chunk-XJA2NGTI.mjs +88 -0
  262. package/dist/chunk-XJIHN3BY.mjs +8 -0
  263. package/dist/chunk-XK6UDWJS.js +203 -0
  264. package/dist/chunk-XPG3N5CF.mjs +415 -0
  265. package/dist/chunk-XVZ2NKSU.mjs +74 -0
  266. package/dist/chunk-XYP45OLE.js +117 -0
  267. package/dist/chunk-XZSDGZX6.mjs +301 -0
  268. package/dist/chunk-Y2EMGN4T.mjs +120 -0
  269. package/dist/chunk-Y3XWP5XW.mjs +298 -0
  270. package/dist/chunk-Y4K22JL6.js +228 -0
  271. package/dist/chunk-Y65LXQGA.mjs +3164 -0
  272. package/dist/chunk-Y66WVMO5.mjs +87 -0
  273. package/dist/chunk-Y7JWLB25.mjs +7280 -0
  274. package/dist/chunk-YCDXAJKU.js +175 -0
  275. package/dist/chunk-YRDQCCIS.js +152 -0
  276. package/dist/chunk-YV52DGSA.js +111 -0
  277. package/dist/chunk-YXGZQPUD.js +94 -0
  278. package/dist/chunk-Z3A3AFVU.mjs +102 -0
  279. package/dist/chunk-ZCY6YKKP.mjs +475 -0
  280. package/dist/chunk-ZEQHXVU5.js +215 -0
  281. package/dist/chunk-ZF7JCXCI.js +284 -0
  282. package/dist/chunk-ZJBRUH6V.js +29 -0
  283. package/dist/chunk-ZMIL4ZOA.js +365 -0
  284. package/dist/chunk-ZR5ULMN2.mjs +337 -0
  285. package/dist/chunk-ZXREOYOW.js +87 -0
  286. package/dist/{client-BSP9U1O1.d.mts → client-CX_WR0-J.d.mts} +2 -2
  287. package/dist/client-Dytx_ZTC.d.ts +230 -0
  288. package/dist/{client-B878xeAP.d.ts → client-dqOhP9Nc.d.ts} +2 -2
  289. package/dist/client-hTKbCuhG.d.mts +230 -0
  290. package/dist/clock-B-UAjkKa.d.mts +5 -0
  291. package/dist/clock-B-UAjkKa.d.ts +5 -0
  292. package/dist/config-BlXQluJR.d.mts +36 -0
  293. package/dist/config-BlXQluJR.d.ts +36 -0
  294. package/dist/courier-Cnn-edJ4.d.ts +95 -0
  295. package/dist/courier-FmGfkvIN.d.mts +95 -0
  296. package/dist/crowd-DdHFbqKK.d.ts +186 -0
  297. package/dist/crowd-hOVSAmA3.d.mts +186 -0
  298. package/dist/danfo-BEBapFlX.d.mts +146 -0
  299. package/dist/danfo-UQ_PTIIx.d.ts +146 -0
  300. package/dist/{elements-Bty6Qs_N.d.mts → elements-DdsRig-2.d.mts} +1548 -257
  301. package/dist/{elements-Bty6Qs_N.d.ts → elements-DdsRig-2.d.ts} +1548 -257
  302. package/dist/engines/godot.d.mts +56 -0
  303. package/dist/engines/godot.d.ts +56 -0
  304. package/dist/engines/godot.js +28 -0
  305. package/dist/engines/godot.mjs +3 -0
  306. package/dist/engines/wasm.d.mts +11 -0
  307. package/dist/engines/wasm.d.ts +11 -0
  308. package/dist/engines/wasm.js +178 -0
  309. package/dist/engines/wasm.mjs +176 -0
  310. package/dist/fallback-CrG_lTFk.d.mts +270 -0
  311. package/dist/fallback-CrG_lTFk.d.ts +270 -0
  312. package/dist/fallback-KDB4Y2CE.mjs +6 -0
  313. package/dist/fallback-Y26TQENE.js +19 -0
  314. package/dist/features-CZB4rmcD.d.mts +118 -0
  315. package/dist/features-CZB4rmcD.d.ts +118 -0
  316. package/dist/fit-BWiE7rgA.d.mts +44 -0
  317. package/dist/fit-DK0oT7zO.d.ts +44 -0
  318. package/dist/five-a-side-Bv1AOUy3.d.mts +115 -0
  319. package/dist/five-a-side-EC51SJY1.d.ts +115 -0
  320. package/dist/fluid-ARr0qUIL.d.ts +939 -0
  321. package/dist/fluid-DLlEj2cs.d.mts +939 -0
  322. package/dist/game/conformance.d.mts +84 -0
  323. package/dist/game/conformance.d.ts +84 -0
  324. package/dist/game/conformance.js +1025 -0
  325. package/dist/game/conformance.mjs +994 -0
  326. package/dist/game/heap.d.mts +40 -0
  327. package/dist/game/heap.d.ts +40 -0
  328. package/dist/game/heap.js +48 -0
  329. package/dist/game/heap.mjs +7 -0
  330. package/dist/game/kit/canvas.d.mts +240 -0
  331. package/dist/game/kit/canvas.d.ts +240 -0
  332. package/dist/game/kit/canvas.js +3566 -0
  333. package/dist/game/kit/canvas.mjs +1039 -0
  334. package/dist/game/kit/courier.d.mts +17 -0
  335. package/dist/game/kit/courier.d.ts +17 -0
  336. package/dist/game/kit/courier.js +66 -0
  337. package/dist/game/kit/courier.mjs +49 -0
  338. package/dist/game/kit/danfo.d.mts +11 -0
  339. package/dist/game/kit/danfo.d.ts +11 -0
  340. package/dist/game/kit/danfo.js +109 -0
  341. package/dist/game/kit/danfo.mjs +44 -0
  342. package/dist/game/kit/engine.d.mts +29 -0
  343. package/dist/game/kit/engine.d.ts +29 -0
  344. package/dist/game/kit/engine.js +183 -0
  345. package/dist/game/kit/engine.mjs +30 -0
  346. package/dist/game/kit/five-a-side.d.mts +11 -0
  347. package/dist/game/kit/five-a-side.d.ts +11 -0
  348. package/dist/game/kit/five-a-side.js +86 -0
  349. package/dist/game/kit/five-a-side.mjs +41 -0
  350. package/dist/game/kit/frontier.d.mts +344 -0
  351. package/dist/game/kit/frontier.d.ts +344 -0
  352. package/dist/game/kit/frontier.js +435 -0
  353. package/dist/game/kit/frontier.mjs +14 -0
  354. package/dist/game/kit/genesis.d.mts +752 -0
  355. package/dist/game/kit/genesis.d.ts +752 -0
  356. package/dist/game/kit/genesis.js +380 -0
  357. package/dist/game/kit/genesis.mjs +15 -0
  358. package/dist/game/kit/ludo.d.mts +15 -0
  359. package/dist/game/kit/ludo.d.ts +15 -0
  360. package/dist/game/kit/ludo.js +87 -0
  361. package/dist/game/kit/ludo.mjs +42 -0
  362. package/dist/game/kit/runner.d.mts +12 -0
  363. package/dist/game/kit/runner.d.ts +12 -0
  364. package/dist/game/kit/runner.js +83 -0
  365. package/dist/game/kit/runner.mjs +46 -0
  366. package/dist/game/kit/shootout.d.mts +13 -0
  367. package/dist/game/kit/shootout.d.ts +13 -0
  368. package/dist/game/kit/shootout.js +122 -0
  369. package/dist/game/kit/shootout.mjs +57 -0
  370. package/dist/game/kit/slots.d.mts +392 -0
  371. package/dist/game/kit/slots.d.ts +392 -0
  372. package/dist/game/kit/slots.js +215 -0
  373. package/dist/game/kit/slots.mjs +6 -0
  374. package/dist/game/kit/tycoon.d.mts +16 -0
  375. package/dist/game/kit/tycoon.d.ts +16 -0
  376. package/dist/game/kit/tycoon.js +145 -0
  377. package/dist/game/kit/tycoon.mjs +44 -0
  378. package/dist/game/kit/word.d.mts +11 -0
  379. package/dist/game/kit/word.d.ts +11 -0
  380. package/dist/game/kit/word.js +78 -0
  381. package/dist/game/kit/word.mjs +41 -0
  382. package/dist/game/kit/worlds.d.mts +18 -0
  383. package/dist/game/kit/worlds.d.ts +18 -0
  384. package/dist/game/kit/worlds.js +74 -0
  385. package/dist/game/kit/worlds.mjs +49 -0
  386. package/dist/game/kit.d.mts +53 -0
  387. package/dist/game/kit.d.ts +53 -0
  388. package/dist/game/kit.js +2610 -0
  389. package/dist/game/kit.mjs +101 -0
  390. package/dist/game/prepared.d.mts +14 -0
  391. package/dist/game/prepared.d.ts +14 -0
  392. package/dist/game/prepared.js +81 -0
  393. package/dist/game/prepared.mjs +32 -0
  394. package/dist/game-Bx8onkhX.d.mts +1451 -0
  395. package/dist/game-fgQy2YIm.d.ts +1451 -0
  396. package/dist/game-theme-CBTw1b_d.d.mts +35 -0
  397. package/dist/game-theme-Dg-ict5A.d.ts +35 -0
  398. package/dist/game.d.mts +3546 -0
  399. package/dist/game.d.ts +3546 -0
  400. package/dist/game.js +4455 -0
  401. package/dist/game.mjs +50 -0
  402. package/dist/graphics-C6YjWYvP.d.ts +5 -0
  403. package/dist/graphics-Dk2yQnYN.d.mts +5 -0
  404. package/dist/guest-DrsA00XD.d.mts +732 -0
  405. package/dist/guest-wIdfoT05.d.ts +732 -0
  406. package/dist/hit-stop-BKkVwTq7.d.mts +43 -0
  407. package/dist/hit-stop-D-8pPYnM.d.ts +43 -0
  408. package/dist/hot-Crn9XpHJ.d.ts +29 -0
  409. package/dist/hot-DH3nOhQD.d.mts +29 -0
  410. package/dist/{index-CQStGb3B.d.mts → index-6gkHMGAq.d.mts} +2 -2
  411. package/dist/index-B8ybCKJI.d.ts +41 -0
  412. package/dist/{index-DJwXmoaP.d.ts → index-B98Xac8e.d.ts} +2 -2
  413. package/dist/{index-B7oA_1XI.d.ts → index-B_ByTtIT.d.ts} +2 -2
  414. package/dist/index-DHjNHb1c.d.mts +41 -0
  415. package/dist/{index-DhUSTAhT.d.mts → index-DbAN_VQE.d.mts} +2 -2
  416. package/dist/index.d.mts +134 -24
  417. package/dist/index.d.ts +134 -24
  418. package/dist/index.js +407 -248
  419. package/dist/index.mjs +184 -58
  420. package/dist/interactives-authoring.d.mts +231 -0
  421. package/dist/interactives-authoring.d.ts +231 -0
  422. package/dist/interactives-authoring.js +1743 -0
  423. package/dist/interactives-authoring.mjs +1704 -0
  424. package/dist/interactives-canvas.global.js +148 -0
  425. package/dist/interactives-guest.d.mts +20 -0
  426. package/dist/interactives-guest.d.ts +20 -0
  427. package/dist/interactives-guest.js +63 -0
  428. package/dist/interactives-guest.json +1 -0
  429. package/dist/interactives-guest.mjs +61 -0
  430. package/dist/interactives-jsc.global.js +9357 -0
  431. package/dist/interactives-meters.d.mts +93 -0
  432. package/dist/interactives-meters.d.ts +93 -0
  433. package/dist/interactives-meters.js +252 -0
  434. package/dist/interactives-meters.mjs +68 -0
  435. package/dist/interactives-production.d.mts +430 -0
  436. package/dist/interactives-production.d.ts +430 -0
  437. package/dist/interactives-production.js +1231 -0
  438. package/dist/interactives-production.mjs +1170 -0
  439. package/dist/interactives-record.d.mts +112 -0
  440. package/dist/interactives-record.d.ts +112 -0
  441. package/dist/interactives-record.js +302 -0
  442. package/dist/interactives-record.mjs +295 -0
  443. package/dist/interactives-runtime.d.mts +61 -0
  444. package/dist/interactives-runtime.d.ts +61 -0
  445. package/dist/interactives-runtime.js +442 -0
  446. package/dist/interactives-runtime.mjs +25 -0
  447. package/dist/interactives-studio-kernel.global.js +1 -0
  448. package/dist/interactives-studio.d.mts +806 -0
  449. package/dist/interactives-studio.d.ts +806 -0
  450. package/dist/interactives-studio.js +5741 -0
  451. package/dist/interactives-studio.mjs +5651 -0
  452. package/dist/interactives-tick.d.mts +90 -0
  453. package/dist/interactives-tick.d.ts +90 -0
  454. package/dist/interactives-tick.js +203 -0
  455. package/dist/interactives-tick.mjs +6 -0
  456. package/dist/interactives-web.d.mts +762 -0
  457. package/dist/interactives-web.d.ts +762 -0
  458. package/dist/interactives-web.js +5000 -0
  459. package/dist/interactives-web.mjs +4628 -0
  460. package/dist/interactives.d.mts +2430 -0
  461. package/dist/interactives.d.ts +2430 -0
  462. package/dist/interactives.js +5723 -0
  463. package/dist/interactives.mjs +4333 -0
  464. package/dist/juice-CoHxlpKA.d.ts +42 -0
  465. package/dist/juice-DQztFS43.d.mts +42 -0
  466. package/dist/launch-T2f4_Di4.d.mts +151 -0
  467. package/dist/launch-d6oreMzR.d.ts +151 -0
  468. package/dist/library-DXYaMFhi.d.mts +69 -0
  469. package/dist/library-DXYaMFhi.d.ts +69 -0
  470. package/dist/link-BUTqGmyi.d.mts +38 -0
  471. package/dist/link-BUTqGmyi.d.ts +38 -0
  472. package/dist/lint.js +104 -204
  473. package/dist/lint.mjs +103 -203
  474. package/dist/local-D8_I6UeL.d.mts +6967 -0
  475. package/dist/local-VZkqsCzR.d.ts +6967 -0
  476. package/dist/lockstep-BLf6dglI.d.mts +321 -0
  477. package/dist/lockstep-D50Ia0JW.d.ts +321 -0
  478. package/dist/ludo-B8ClkDqr.d.ts +205 -0
  479. package/dist/ludo-BOuohQ-M.d.mts +205 -0
  480. package/dist/mock/cli.mjs +200 -56
  481. package/dist/mock/library.js +200 -56
  482. package/dist/mock/library.mjs +200 -56
  483. package/dist/mock/msw.js +200 -56
  484. package/dist/mock/msw.mjs +200 -56
  485. package/dist/native-BodxSh03.d.mts +16 -0
  486. package/dist/native-DUHMT8gA.d.ts +16 -0
  487. package/dist/network-ZXLD7l1b.d.mts +19 -0
  488. package/dist/network-ZXLD7l1b.d.ts +19 -0
  489. package/dist/online-XeymeM9s.d.ts +381 -0
  490. package/dist/online-d7W_Al9a.d.mts +381 -0
  491. package/dist/params-DxFb5G_U.d.mts +155 -0
  492. package/dist/params-DxFb5G_U.d.ts +155 -0
  493. package/dist/play-BRRlfLhX.d.ts +940 -0
  494. package/dist/play-ClrMd_e8.d.mts +940 -0
  495. package/dist/policy-CCw8tXLm.d.mts +3078 -0
  496. package/dist/policy-CMqOSQIu.d.ts +3078 -0
  497. package/dist/ports-B_0v_P3A.d.mts +13 -0
  498. package/dist/ports-CGU_3e_0.d.ts +13 -0
  499. package/dist/prefetch-BHnicOQj.d.ts +117 -0
  500. package/dist/prefetch-CBXgYacv.d.mts +117 -0
  501. package/dist/{price-CSztR02F.d.mts → price-BOzexBww.d.mts} +1 -1
  502. package/dist/{price-C_vasx9A.d.ts → price-C1h9sPxE.d.ts} +1 -1
  503. package/dist/protocol-C8qbpUbT.d.mts +242 -0
  504. package/dist/protocol-C8qbpUbT.d.ts +242 -0
  505. package/dist/rapier-AZHT4YI7.js +7886 -0
  506. package/dist/rapier-ODEPCQA6.mjs +7792 -0
  507. package/dist/react.d.mts +157 -15
  508. package/dist/react.d.ts +157 -15
  509. package/dist/react.js +5564 -5904
  510. package/dist/react.mjs +5451 -5808
  511. package/dist/runner-CQcLL7By.d.ts +189 -0
  512. package/dist/runner-D46Yj-wE.d.mts +189 -0
  513. package/dist/runtime-BRWfkf_q.d.mts +51 -0
  514. package/dist/runtime-DyuBMkKM.d.ts +51 -0
  515. package/dist/scheduling-D2ajXpMC.d.ts +224 -0
  516. package/dist/scheduling-DSRbbaZb.d.mts +224 -0
  517. package/dist/schema-BrWxzKp6.d.mts +63 -0
  518. package/dist/schema-BrWxzKp6.d.ts +63 -0
  519. package/dist/server/evict.js +34 -37
  520. package/dist/server/evict.mjs +34 -37
  521. package/dist/server/tanstack.d.mts +49 -3
  522. package/dist/server/tanstack.d.ts +49 -3
  523. package/dist/server/tanstack.js +169 -117
  524. package/dist/server/tanstack.mjs +166 -118
  525. package/dist/{server-Dckg4Vdr.d.ts → server-D29IIuDV.d.ts} +136 -130
  526. package/dist/{server-B6dW7-Lj.d.mts → server-DQMWPnc8.d.mts} +136 -130
  527. package/dist/server.d.mts +45 -5
  528. package/dist/server.d.ts +45 -5
  529. package/dist/server.js +171 -227
  530. package/dist/server.mjs +165 -225
  531. package/dist/session-grant-CJ27DwrT.d.mts +19 -0
  532. package/dist/session-grant-CJ27DwrT.d.ts +19 -0
  533. package/dist/shootout-BJZeX6FG.d.ts +140 -0
  534. package/dist/shootout-tcZd1Rxt.d.mts +140 -0
  535. package/dist/state-replica-stMtdkVD.d.mts +42 -0
  536. package/dist/state-replica-stMtdkVD.d.ts +42 -0
  537. package/dist/studio-CowqWqez.d.mts +14 -0
  538. package/dist/studio-CowqWqez.d.ts +14 -0
  539. package/dist/styles.css +1 -1
  540. package/dist/template-AhCdB1kW.d.mts +190 -0
  541. package/dist/template-BkEGVTQj.d.ts +190 -0
  542. package/dist/terrain-BMxEc6Oc.d.ts +429 -0
  543. package/dist/terrain-C-XC1Oui.d.mts +429 -0
  544. package/dist/testing/msw.d.mts +28 -4
  545. package/dist/testing/msw.d.ts +28 -4
  546. package/dist/testing/msw.js +15 -21
  547. package/dist/testing/msw.mjs +15 -21
  548. package/dist/testing/suite.d.mts +6 -5
  549. package/dist/testing/suite.d.ts +6 -5
  550. package/dist/testing/suite.js +89 -124
  551. package/dist/testing/suite.mjs +81 -116
  552. package/dist/testing.d.mts +27 -1227
  553. package/dist/testing.d.ts +27 -1227
  554. package/dist/testing.js +127 -131
  555. package/dist/testing.mjs +19 -23
  556. package/dist/tick-transport-C8QEh8Uw.d.mts +50 -0
  557. package/dist/tick-transport-UjHY3xK1.d.ts +50 -0
  558. package/dist/timeline-protocol-hp6e8zFB.d.mts +47 -0
  559. package/dist/timeline-protocol-hp6e8zFB.d.ts +47 -0
  560. package/dist/tokens-DhanQRQS.d.mts +21 -0
  561. package/dist/tokens-K8yxwd6G.d.ts +21 -0
  562. package/dist/tree-C-Io2Hbx.d.mts +35 -0
  563. package/dist/tree-CP_qSW4H.d.ts +35 -0
  564. package/dist/tycoon-B5KHk2Xx.d.mts +255 -0
  565. package/dist/tycoon-hmHo-3HX.d.ts +255 -0
  566. package/dist/types-BQkxPwZP.d.mts +219 -0
  567. package/dist/types-D_f6UUxM.d.ts +219 -0
  568. package/dist/ui-DwHicuFv.d.mts +563 -0
  569. package/dist/ui-hi7S2YcH.d.ts +563 -0
  570. package/dist/{sign-in-DQlIdqsi.d.mts → url-52ndUruG.d.mts} +15 -1
  571. package/dist/{sign-in-DQlIdqsi.d.ts → url-52ndUruG.d.ts} +15 -1
  572. package/dist/utils.d.mts +3 -3
  573. package/dist/utils.d.ts +3 -3
  574. package/dist/utils.js +37 -37
  575. package/dist/utils.mjs +4 -4
  576. package/dist/vars-Dc_PrhBK.d.mts +511 -0
  577. package/dist/vars-Dc_PrhBK.d.ts +511 -0
  578. package/dist/vm-IUARFFAI.mjs +63 -0
  579. package/dist/vm-N7L6MGGH.js +65 -0
  580. package/dist/weave-delivery-CW-Kstut.d.mts +360 -0
  581. package/dist/weave-delivery-CW-Kstut.d.ts +360 -0
  582. package/dist/web-Dss74a7v.d.ts +883 -0
  583. package/dist/web-f9ZQPoyw.d.mts +883 -0
  584. package/dist/web-transport-C7MkBL0a.d.ts +19 -0
  585. package/dist/web-transport-aYEqXMd9.d.mts +19 -0
  586. package/dist/weight-CPGjsgjV.d.ts +92 -0
  587. package/dist/weight-tF1ODR1p.d.mts +92 -0
  588. package/dist/word-BcX9Jcmv.d.mts +70 -0
  589. package/dist/word-C7sVPLHm.d.ts +70 -0
  590. package/dist/world-PvILHDR1.d.ts +2285 -0
  591. package/dist/world-qekkXjJv.d.mts +2285 -0
  592. package/dist/worlds-Br2Pb0Cs.d.ts +109 -0
  593. package/dist/worlds-D5ydYr7d.d.mts +109 -0
  594. package/engines/c/cimplify.h +108 -0
  595. package/engines/c/cimplify.lib.js +11 -0
  596. package/engines/godot/addons/cimplify/cimplify.gd +97 -0
  597. package/engines/rust/interactives-ctx/Cargo.toml +9 -0
  598. package/engines/rust/interactives-ctx/src/lib.rs +189 -0
  599. package/package.json +189 -3
  600. package/vendor/rapier3d-compat/LICENSE +201 -0
  601. package/vendor/rapier3d-compat/PATCHES.md +61 -0
  602. package/dist/chunk-2P4KXFB6.js +0 -274
  603. package/dist/chunk-3G6RQLXK.mjs +0 -21
  604. package/dist/chunk-3V4DVXV3.mjs +0 -254
  605. package/dist/chunk-EDK3LNM6.js +0 -2436
  606. package/dist/chunk-F7J3HK27.js +0 -4549
  607. package/dist/chunk-U4MW6PYU.mjs +0 -23
  608. package/dist/chunk-XREIZ56K.js +0 -26
@@ -0,0 +1,994 @@
1
+ import { collectYoung, measureAllocations, warmUp, measureSteadyAllocations, profileAllocationSites } from '../chunk-6H254EVP.mjs';
2
+ export { collectGarbage, createNodeHeapMeter, measureAllocations, profileAllocationSites, warmUp } from '../chunk-6H254EVP.mjs';
3
+ import { kitPublicationGates } from '../chunk-XZSDGZX6.mjs';
4
+ import '../chunk-3DAD2LDF.mjs';
5
+ import '../chunk-4DYKAYFO.mjs';
6
+ import { createTemplateHarness } from '../chunk-KGHJH5KJ.mjs';
7
+ import { checkGameSources } from '../chunk-R56P64LB.mjs';
8
+ import { sphereGeometry, boxGeometry } from '../chunk-GHPUYD4I.mjs';
9
+ import { createGame, World } from '../chunk-KVFNRJOR.mjs';
10
+ import { Ease, Repeat, TweenTarget } from '../chunk-KDTVOLHI.mjs';
11
+ import { quantized, LoopbackTransport, MessageWriter, SnapshotBuffer } from '../chunk-RM2V4IND.mjs';
12
+ import '../chunk-22BD3RHN.mjs';
13
+ import { defineComponent } from '../chunk-ME6HGG4I.mjs';
14
+ import '../chunk-5BYDGGWO.mjs';
15
+ import { emptyClipState } from '../chunk-7ARSJPV3.mjs';
16
+ import '../chunk-RUVGVNOF.mjs';
17
+ import { RayHit, RayQuery, CharacterMove } from '../chunk-HF5HPS4T.mjs';
18
+ import { Vec3, Quat } from '../chunk-XPG3N5CF.mjs';
19
+ import { mat4ComposeArrays, mat4Compose, quatSlerpArrays } from '../chunk-KIZOA5LX.mjs';
20
+ import '../chunk-7SXOHAIR.mjs';
21
+ import '../chunk-ATAWRACV.mjs';
22
+ import '../chunk-T3AFF3L7.mjs';
23
+ import { createGpuStats, GPU_PASS_NAMES } from '../chunk-TL2SVO4P.mjs';
24
+ import { FRAME_NOW_MS_SLOT, FrameTime, FRAME_ALPHA_SLOT, FRAME_STEP_SECONDS_SLOT } from '../chunk-IDLW4NWA.mjs';
25
+ import '../chunk-73SGZLAQ.mjs';
26
+ import '../chunk-M5EXQZYY.mjs';
27
+ import '../chunk-TU5RYTYU.mjs';
28
+ import '../chunk-EIB4OWVQ.mjs';
29
+ import '../chunk-PBL6YL5L.mjs';
30
+ import '../chunk-E65WCTIG.mjs';
31
+ import '../chunk-5YFBGGCK.mjs';
32
+ import '../chunk-K4UDGE3Z.mjs';
33
+ import '../chunk-MOBSBXVE.mjs';
34
+ import '../chunk-SMK6JU2F.mjs';
35
+ import '../chunk-JURRXY2J.mjs';
36
+ import '../chunk-GHS6MIL6.mjs';
37
+ import '../chunk-GDCV4IWO.mjs';
38
+ import '../chunk-Y66WVMO5.mjs';
39
+ import '../chunk-A33OORT7.mjs';
40
+ import '../chunk-LYEZZEEF.mjs';
41
+ import '../chunk-HAGEIC2L.mjs';
42
+ import '../chunk-K46SMZ66.mjs';
43
+ import '../chunk-OQRVEM56.mjs';
44
+ import '../chunk-SPCRQ6NO.mjs';
45
+ import '../chunk-V7ZRH3PY.mjs';
46
+ import '../chunk-MOMOZEUM.mjs';
47
+ import '../chunk-N4RGGDEL.mjs';
48
+ import { GameError } from '../chunk-XJIHN3BY.mjs';
49
+ import '../chunk-25T4JHEA.mjs';
50
+ import { describe, it, expect } from 'vitest';
51
+ import { execFileSync } from 'child_process';
52
+ import { mkdtempSync, writeFileSync, readFileSync, rmSync, mkdirSync } from 'fs';
53
+ import { tmpdir } from 'os';
54
+ import { join } from 'path';
55
+
56
+ // src/game/conformance/harness.ts
57
+ var SUSTAINED_BODIES = 48, SUSTAINED_INSTANCES = 512, SUSTAINED_SEED = 9, BOB_RATE = 0.05, KEY_TOGGLE_PERIOD = 7, FRAMES_PER_STAMP_CYCLE = 3, MS_PER_STAMP_CYCLE = 50, INSTANCE_POSITION = 0, INSTANCE_ROTATION = 3, INSTANCE_SCALE = 7, INSTANCE_POSE = 10, INSTANCE_ROW = 32, BODY_ROW = 8, GROUND_HALF_EXTENT = 50, SilentUiHost = class {
58
+ constructor() {
59
+ this.publishes = 0;
60
+ }
61
+ declareHud(_layout) {
62
+ }
63
+ publishHud(_numbers, _texts, _dirty, _dirtyCount) {
64
+ this.publishes++;
65
+ }
66
+ showPanel(_panel, _props) {
67
+ }
68
+ hidePanel(_panel) {
69
+ }
70
+ haptic(_pattern) {
71
+ }
72
+ };
73
+ function frameStamp(frame) {
74
+ return frame * (50) / (3) | 0;
75
+ }
76
+ function spawnAt(game, x, y, z) {
77
+ let e = game.world.spawn();
78
+ return game.transforms.add(e, x, y, z), e;
79
+ }
80
+ async function createSustainedHarness(backend, vendorQueries) {
81
+ let game = await createGame({ backend, seed: (9), ui: new SilentUiHost() }), floor = spawnAt(game, 0, -0.5, 0);
82
+ game.physics.addCollider(floor, { shape: { kind: "cuboid", halfExtents: [(50), 0.5, (50)] } });
83
+ let gfx = game.graphics, geometry = gfx.createGeometry(sphereGeometry(0.25, 8, 6)), material = gfx.createMaterial({ kind: "standard" }), camera = spawnAt(game, 0, 3, 10);
84
+ gfx.camera(camera), game.audio.setListener(camera);
85
+ let bodies = [], bodyKind = vendorQueries ? "dynamic" : "kinematic";
86
+ for (let i = 0; i < (48); i++) {
87
+ let e = spawnAt(game, i % (8) - (8) / 2, 1 + Math.floor(i / (8)), 0);
88
+ game.physics.addBody(e, { kind: bodyKind, canSleep: false }), game.physics.addCollider(e, { shape: { kind: "ball", radius: 0.25 }, restitution: 0.9 }), gfx.mesh(e, geometry, material), bodies.push(e);
89
+ }
90
+ let positions = game.transforms.store.fields.position, kinematic = spawnAt(game, 0, 0.6, 3);
91
+ game.physics.addBody(kinematic, { kind: "kinematic" });
92
+ let kinematicCollider = game.physics.addCollider(kinematic, { shape: { kind: "capsule", halfHeight: 0.3, radius: 0.3 } }), controller = game.physics.createCharacterController({ snapToGround: 0.2 }), batch = gfx.instanced({ geometry, material, capacity: (512), colors: true }), jump = game.input.defineButton("jump", [{ device: "key", code: "Space" }]), move = game.input.defineAxis("move", [{ device: "keys", negative: "KeyA", positive: "KeyD" }]), score = game.ui.hudNumber("score"), pulse = game.animation.createValue(0);
93
+ game.animation.tweenValue(pulse, 1, 0.5, Ease.InOutSine, 0, Repeat.PingPong), game.animation.tween(bodies[0], TweenTarget.ScaleUniform, 1.5, 0.75, Ease.OutBack, 0, Repeat.Loop);
94
+ let Pos = game.net.defineMessage("pos", {
95
+ id: "u16",
96
+ x: quantized(-50, 50, 16),
97
+ y: quantized(-50, 50, 16),
98
+ z: quantized(-50, 50, 16)
99
+ }), [local, remote] = LoopbackTransport.pair();
100
+ game.net.connect(local), remote.open("state", "latest");
101
+ let channel = game.net.channel("state", "latest"), reader = game.net.reader(), writer = new MessageWriter(), fx = Pos.field("x"), fy = Pos.field("y"), fz = Pos.field("z"), fid = Pos.field("id"), hit = new RayHit(), ray = new RayQuery().set(0, 10, 0, 0, -1, 0, 20), characterMove = new CharacterMove(), desired = new Vec3(), hop = new Vec3(0, 2, 0), position = new Vec3(), sound = await game.audio.load({ bytes: new ArrayBuffer(8) }), emitter = game.audio.playAt(bodies[1], sound, game.audio.effects, 1, 1, true), query = game.world.query(game.transforms.store.type), instance = new Float32Array((10));
102
+ instance[(3) + 3] = 1, instance[(7)] = 1, instance[(7) + 1] = 1, instance[(7) + 2] = 1;
103
+ let sink = new Float64Array(1), bob = (g) => {
104
+ for (let i = 0; i < (48); i++) {
105
+ let row = g.transforms.row(bodies[i]);
106
+ positions[row * 3 + 1] = 1 + Math.sin(g.tick * (0.05) + i);
107
+ }
108
+ }, vendor = (g) => {
109
+ let dt = g.clock[FRAME_STEP_SECONDS_SLOT];
110
+ g.input.justPressed(jump) && g.physics.applyImpulse(bodies[g.tick % (48)], hop), g.physics.moveCharacter(controller, kinematicCollider, desired.set(g.input.value(move) * dt, -dt, 0), characterMove), g.physics.raycast(ray, hit) && (sink[0] += hit.distance);
111
+ for (let i = 0; i < g.physics.contactCount(); i++) sink[0] += g.physics.contactColliderA(i);
112
+ };
113
+ game.addSystem({
114
+ fixedUpdate: vendorQueries ? vendor : bob,
115
+ update: (g) => {
116
+ let m = batch.matrices;
117
+ instance[(0) + 1] = g.animation.value(pulse);
118
+ for (let i = 0; i < (512); i++)
119
+ instance[(0)] = i % (32), instance[(0) + 2] = i / (32) | 0, mat4ComposeArrays(m, i * 16, instance, (0), instance, (3), instance, (7));
120
+ for (g.graphics.setInstanceCount(batch, (512)), g.graphics.markInstancesDirty(batch), g.ui.setNumber(score, g.tick), g.transforms.position(bodies[2], position), writer.begin(Pos).set(fid, 2).setVec3(fx, fy, fz, position), channel.send(writer), remote.send(0, writer.buffer, writer.length); channel.receive(reader); ) sink[0] += reader.get(fy);
121
+ sink[0] += query.update(), sink[0] += g.audio.isPlaying(emitter) ? 1 : 0;
122
+ }
123
+ });
124
+ let keys = ["Space", "KeyD", "KeyA"];
125
+ return {
126
+ game,
127
+ frame(index) {
128
+ let key = keys[index % keys.length];
129
+ index % (7) === 0 ? game.input.keyEvent(key, true, index) : index % (7) === 1 && game.input.keyEvent(key, false, index), game.clock[FRAME_NOW_MS_SLOT] = frameStamp(index), game.runFrame();
130
+ },
131
+ sink() {
132
+ return sink[0];
133
+ }
134
+ };
135
+ }
136
+
137
+ // src/game/conformance/load.ts
138
+ var OS_MODULE = "node:os";
139
+ var TIMING_BUDGETS_ENV = "CIMPLIFY_TIMING_BUDGETS", ADVISORY_TIMING_BUDGETS = "advisory";
140
+ function timingBudgetsAdvisory() {
141
+ return globalThis.process?.env?.[TIMING_BUDGETS_ENV] === ADVISORY_TIMING_BUDGETS;
142
+ }
143
+ function isOs(value) {
144
+ let os = value;
145
+ return typeof os?.availableParallelism == "function" && typeof os.loadavg == "function";
146
+ }
147
+ async function busyMachine() {
148
+ let os;
149
+ try {
150
+ os = await import(
151
+ /* @vite-ignore */
152
+ OS_MODULE
153
+ );
154
+ } catch {
155
+ return null;
156
+ }
157
+ if (!isOs(os)) return null;
158
+ let cores = os.availableParallelism(), load = os.loadavg()[0];
159
+ return timingBudgetsAdvisory() ? { load, cores, advisory: true } : load > cores ? { load, cores, advisory: false } : null;
160
+ }
161
+ function loadSkipNotice(busy) {
162
+ return busy.advisory ? `::warning::timing budget is advisory on this runner (${TIMING_BUDGETS_ENV}=${ADVISORY_TIMING_BUDGETS}, 1-minute load ${busy.load.toFixed(2)} on ${busy.cores} cores); compare the measured numbers against the budgets` : `budget gate skipped: 1-minute load average ${busy.load.toFixed(2)} exceeds ${busy.cores} cores; rerun on a quiet machine`;
163
+ }
164
+
165
+ // src/game/conformance/microbench.ts
166
+ var DEFAULT_MICROBENCH_BUDGETS_NS = {
167
+ mat4Compose: 50,
168
+ slerp: 200,
169
+ transformPerEntity: 200,
170
+ queryPerEntity: 30,
171
+ codecField: 100,
172
+ raycast: 5e3,
173
+ physicsStepPerBody: 1e4
174
+ }, MATH_ITERATIONS = 5e5, FIELD_ITERATIONS = 5e5, ENTITY_PASSES = 100, RAYCASTS = 2e3, STEP_BODIES = 256, STEP_PASSES = 120, STEP_SETTLE = 60, STEP_ROW = 16, STEP_LAYERS = 3, STEP_SPACING = 1.1, STEP_BASE_HEIGHT = 0.6, STEP_RADIUS = 0.5, STEP_GROUND_HALF_EXTENT = 100, ENTITIES = 1e3, WARMUP_PASSES = 2, WARMUP_MIN_MS = 200, WARMUP_MAX_MS = 3e3, SETTLED_RATIO = 0.95, SAMPLED_PASSES = 4, MIN_SAMPLES = 64, SAMPLE_TARGET_NS = 1e5, SAMPLING_MIN_MS = 300, SAMPLING_MAX_MS = 2e3, NS_PER_MS = 1e6, POSE = [1, 2, 3, 0, 0, 0, 1, 1, 1, 1], ROTATIONS = [0, 0, 0, 1, 0, Math.SQRT1_2, 0, Math.SQRT1_2];
175
+ function time(iterations, body) {
176
+ let i = 0, probe = Number.POSITIVE_INFINITY, warmupStart = performance.now();
177
+ for (let pass = 0; ; pass++) {
178
+ let passStart = performance.now();
179
+ for (let k = 0; k < iterations; k++) body(i++);
180
+ let now = performance.now(), perIteration = (now - passStart) * (1e6) / iterations, improving = perIteration < probe * (0.95);
181
+ perIteration < probe && (probe = perIteration);
182
+ let warm = now - warmupStart;
183
+ if (warm >= (3e3) || pass + 1 >= (2) && warm >= (200) && !improving) break;
184
+ }
185
+ let batch = Math.min(iterations, Math.max(1, Math.ceil((1e5) / Math.max(probe, Number.MIN_VALUE)))), samples = Math.max((64), Math.ceil((4) * iterations / batch)), floor = Number.POSITIVE_INFINITY, samplingStart = performance.now();
186
+ for (let sample = 0; ; sample++) {
187
+ let start = performance.now();
188
+ for (let k = 0; k < batch; k++) body(i++);
189
+ let end = performance.now(), perIteration = (end - start) * (1e6) / batch;
190
+ perIteration < floor && (floor = perIteration);
191
+ let sampled = end - samplingStart;
192
+ if (sampled >= (2e3) || sample + 1 >= samples && sampled >= (300)) break;
193
+ }
194
+ return floor;
195
+ }
196
+ async function runMicrobench(createBackend) {
197
+ let out = new Float32Array(64), pose = Float32Array.from(POSE), rotations = Float32Array.from(ROTATIONS), weight = new Float64Array([0.5]), mat4Compose2 = time((5e5), (i) => mat4ComposeArrays(out, (i & 3) * 16, pose, 0, pose, 3, pose, 7)), slerp = time((5e5), (i) => quatSlerpArrays(out, (i & 3) * 4, rotations, 0, rotations, 4, weight, 0)), game = await createGame({ backend: createBackend() }), ground2 = game.world.spawn();
198
+ game.transforms.add(ground2, 0, -0.5, 0), game.physics.addCollider(ground2, { shape: { kind: "cuboid", halfExtents: [50, 0.5, 50] } });
199
+ for (let i = 0; i < (1e3); i++) {
200
+ let e = game.world.spawn();
201
+ game.transforms.add(e, i, 0, 0);
202
+ }
203
+ let frame = new FrameTime();
204
+ frame.values[FRAME_ALPHA_SLOT] = 0.5;
205
+ let transformPerEntity = time((100), () => game.transforms.computeRender(frame)) / (1e3), query = game.world.query(game.transforms.store.type), queryPerEntity = time((100), () => query.update()) / (1e3), message = game.net.defineMessage("bench", { x: quantized(-10, 10, 12) }), writer = new MessageWriter();
206
+ writer.begin(message);
207
+ let field = message.field("x"), codecField = time((5e5), (i) => writer.set(field, (i & 15) - 8));
208
+ game.advance(1);
209
+ let hit = new RayHit(), ray = new RayQuery().set(0, 5, 0, 0, -1, 0, 10), raycast = time((2e3), () => game.physics.raycast(ray, hit));
210
+ game.dispose();
211
+ let physicsStepPerBody = await stepCost(createBackend);
212
+ return { mat4Compose: mat4Compose2, slerp, transformPerEntity, queryPerEntity, codecField, raycast, physicsStepPerBody };
213
+ }
214
+ async function stepCost(createBackend) {
215
+ let game = await createGame({ backend: createBackend() }), ground2 = game.world.spawn();
216
+ game.transforms.add(ground2, 0, -0.5, 0), game.physics.addCollider(ground2, { shape: { kind: "cuboid", halfExtents: [(100), 0.5, (100)] } });
217
+ for (let i = 0; i < (256); i++) {
218
+ let e = game.world.spawn();
219
+ game.transforms.add(e, i % (16) * (1.1), (0.6) + i % (3) * (1.1), (i / (16) | 0) * (1.1)), game.physics.addBody(e, { kind: "dynamic", canSleep: false }), game.physics.addCollider(e, { shape: { kind: "ball", radius: (0.5) } });
220
+ }
221
+ for (let i = 0; i < (60); i++) game.physics.step();
222
+ let perBody = time((120), () => game.physics.step()) / (256);
223
+ return game.dispose(), perBody;
224
+ }
225
+
226
+ // src/game/conformance/suite.ts
227
+ async function measureSustainedAllocation(createBackend, heap, vendorQueries, sustainedFrames = (6e3), freshIsolate = false) {
228
+ let meter = await heap();
229
+ if (!meter) return null;
230
+ let harness = await createSustainedHarness(createBackend(), vendorQueries), start = (3e4);
231
+ if (freshIsolate) {
232
+ for (let i = 0; i < (3e4); i++) harness.frame(i);
233
+ collectYoung();
234
+ for (let block = 0; block < (8); block++) {
235
+ let settled = await measureAllocations(meter, (3e3), (i) => harness.frame(start + i));
236
+ if (start += (3e3), settled.bytes === 0) break;
237
+ }
238
+ collectYoung();
239
+ } else await warmUp((3e4), (i) => harness.frame(i));
240
+ let report = await measureAllocations(meter, sustainedFrames, (i) => harness.frame(start + i)), longer = await measureAllocations(meter, sustainedFrames * 2, (i) => harness.frame(start + sustainedFrames + i));
241
+ if (meter.dispose(), harness.game.dispose(), !Number.isFinite(harness.sink())) throw new Error("the sustained harness produced a non-finite sink");
242
+ return [report, longer];
243
+ }
244
+ var DEFAULT_SUSTAINED_FRAMES = 6e3, WARMUP_FRAMES = 3e4, QUIESCE_BLOCKS = 8, QUIESCE_BLOCK_FRAMES = 3e3, QUIESCE_PAST_V8_FRAME_CHAIN_TIER_UP = true, FRAME_MS = 1e3 / 60, RESIDUE_BYTES_PER_FRAME = 1, MICROBENCH_TIMEOUT_MS = 12e4, RecordingUiHost = class {
245
+ constructor() {
246
+ this.layout = [];
247
+ this.publishes = 0;
248
+ this.lastDirty = 0;
249
+ this.panels = [];
250
+ this.haptics = [];
251
+ }
252
+ declareHud(layout) {
253
+ this.layout = layout;
254
+ }
255
+ publishHud(_numbers, _texts, _dirty, dirtyCount) {
256
+ this.publishes++, this.lastDirty = dirtyCount;
257
+ }
258
+ showPanel(panel) {
259
+ this.panels.push(panel);
260
+ }
261
+ hidePanel(panel) {
262
+ this.panels.splice(this.panels.indexOf(panel), 1);
263
+ }
264
+ haptic(pattern) {
265
+ this.haptics.push(pattern);
266
+ }
267
+ };
268
+ function emptyStats() {
269
+ return { nodes: 0, geometries: 0, materials: 0, textures: 0, renderTargets: 0, postChains: 0, renderPasses: 0, frames: 0 };
270
+ }
271
+ function spawnAt2(game, x, y, z) {
272
+ let e = game.world.spawn();
273
+ return game.transforms.add(e, x, y, z), e;
274
+ }
275
+ function ground(game) {
276
+ let e = spawnAt2(game, 0, -0.5, 0);
277
+ return game.physics.addCollider(e, { shape: { kind: "cuboid", halfExtents: [50, 0.5, 50] } }), e;
278
+ }
279
+ function hostClocks() {
280
+ let clocks = [];
281
+ for (let scope of [globalThis, Reflect.get(globalThis, "self"), Reflect.get(globalThis, "window")]) {
282
+ if (typeof scope != "object" || scope === null) continue;
283
+ let clock = Reflect.get(scope, "performance");
284
+ clock instanceof Object && clocks.indexOf(clock) < 0 && clocks.push(clock);
285
+ }
286
+ return clocks;
287
+ }
288
+ function withFrozenHostClock(run2) {
289
+ let clocks = hostClocks(), saved = clocks.map((clock) => Object.getOwnPropertyDescriptor(clock, "now"));
290
+ for (let clock of clocks) Object.defineProperty(clock, "now", { configurable: true, writable: true, value: frozenNow });
291
+ return run2().finally(() => {
292
+ for (let i = 0; i < clocks.length; i++) {
293
+ let own = saved[i];
294
+ own ? Object.defineProperty(clocks[i], "now", own) : Reflect.deleteProperty(clocks[i], "now");
295
+ }
296
+ });
297
+ }
298
+ function defineGameConformanceSuite(options) {
299
+ let make = (seed = 1, ui = null) => createGame({ backend: options.createBackend(), seed, ui });
300
+ describe(`game API conformance: ${options.name}`, () => {
301
+ describe("entities and components", () => {
302
+ it("reuses indices with new generations and invalidates stale handles", () => {
303
+ let world = new World(8), a = world.spawn();
304
+ expect(world.despawn(a)).toBe(true);
305
+ let b = world.spawn();
306
+ expect(b).not.toBe(a), expect(world.isAlive(a)).toBe(false), expect(world.isAlive(b)).toBe(true), expect(world.despawn(a)).toBe(false);
307
+ }), it("stores fields as structure of arrays and swap-removes", () => {
308
+ let Health = defineComponent("conformance-health", { hp: "f32", armor: ["u8", 2] }), world = new World(16), store = world.register(Health), e = [];
309
+ for (let i = 0; i < 4; i++) {
310
+ e.push(world.spawn());
311
+ let row = world.add(e[i], Health);
312
+ store.fields.hp[row] = i * 10, store.fields.armor[row * 2 + 1] = i;
313
+ }
314
+ world.remove(e[1], Health), expect(store.count).toBe(3);
315
+ let moved = store.row(e[3]);
316
+ expect(store.fields.hp[moved]).toBe(30), expect(store.fields.armor[moved * 2 + 1]).toBe(3), expect(store.has(e[1])).toBe(false);
317
+ }), it("queries the intersection of components", () => {
318
+ let A = defineComponent("conformance-a", { v: "i32" }), B = defineComponent("conformance-b", { v: "i32" }), world = new World(32), q = world.query(A, B);
319
+ for (let i = 0; i < 10; i++) {
320
+ let e = world.spawn();
321
+ world.add(e, A), i % 2 === 0 && world.add(e, B);
322
+ }
323
+ expect(q.update()).toBe(5);
324
+ for (let i = 0; i < q.count; i++) expect(world.has(q.entityAt(i), B)).toBe(true);
325
+ }), it("refuses growth past declared capacity", () => {
326
+ let world = new World(2);
327
+ world.spawn(), world.spawn(), expect(() => world.spawn()).toThrow(GameError);
328
+ });
329
+ }), describe("loop, scenes and transforms", () => {
330
+ it("runs fixed steps with interpolation and clamps runaway frames", async () => {
331
+ let game = await make();
332
+ game.frame(0), game.frame(FRAME_MS * 2.5), expect(game.tick).toBe(2), expect(game.alpha).toBeCloseTo(0.5, 5), game.frame(FRAME_MS * 2.5 + 1e4), expect(game.tick).toBe(2 + game.loop.maxSubsteps), game.dispose();
333
+ }), it("switches scenes at step boundaries with enter and exit", async () => {
334
+ let game = await make(), log = [];
335
+ game.addScene({ name: "a", enter: () => log.push("enter a"), exit: () => log.push("exit a") }), game.addScene({ name: "b", enter: () => log.push("enter b"), fixedUpdate: () => log.push("step b") }), game.start("a"), game.scenes.switchTo("b"), game.advance(1), expect(log).toEqual(["enter a", "exit a", "enter b", "step b"]), game.dispose();
336
+ }), it("interpolates render matrices and composes hierarchies", async () => {
337
+ let game = await make(), parent = spawnAt2(game, 0, 0, 0), child = spawnAt2(game, 1, 0, 0);
338
+ game.transforms.setParent(child, parent), game.advance(1), game.transforms.snapshot(), game.transforms.setPosition(parent, 10, 0, 0), game.transforms.computeRender(halfway());
339
+ let out = new Vec3();
340
+ expect(game.transforms.renderPosition(parent, out).x).toBeCloseTo(5, 5), expect(game.transforms.renderPosition(child, out).x).toBeCloseTo(6, 5), game.dispose();
341
+ });
342
+ }), describe("graphics", () => {
343
+ it("creates every resource family and mirrors entity matrices onto nodes", async () => {
344
+ let game = await make(), gfx = game.graphics, geometry = gfx.createGeometry(boxGeometry(1, 2, 3)), material = gfx.createMaterial({ kind: "standard", color: 16711680, roughness: 0.5 }), e = spawnAt2(game, 1, 2, 3), node = gfx.mesh(e, geometry, material), camera = spawnAt2(game, 0, 1, 5);
345
+ gfx.camera(camera);
346
+ let light = spawnAt2(game, 0, 5, 0);
347
+ gfx.create(light, { kind: "light", light: "directional", intensity: 2 }), gfx.create(spawnAt2(game, 0, 0, 0), { kind: "light", light: "point", intensity: 1, distance: 10 }), gfx.create(spawnAt2(game, 0, 0, 0), { kind: "group" }), gfx.setEnvironment({ background: { color: 1052688 }, toneMapping: "aces", exposure: 1 }), game.advance(1);
348
+ let m = new Float32Array(16);
349
+ gfx.readNodeMatrix(node, m), expect(m[12]).toBeCloseTo(1, 5), expect(m[13]).toBeCloseTo(2, 5), expect(m[14]).toBeCloseTo(3, 5);
350
+ let stats = emptyStats();
351
+ gfx.stats(stats), expect(stats.nodes).toBeGreaterThanOrEqual(5), expect(stats.frames).toBeGreaterThan(0), game.world.despawn(e), gfx.stats(stats), expect(stats.nodes).toBeGreaterThanOrEqual(4), game.dispose();
352
+ }), it("updates custom vertex buffers and instance buffers in place", async () => {
353
+ let game = await make(), gfx = game.graphics, positions = new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]), geometry = gfx.createGeometry({ attributes: { position: { data: positions, itemSize: 3, dynamic: true } } });
354
+ expect(gfx.geometryAttribute(geometry, "position")).toBe(positions), positions[0] = 5, gfx.markGeometryDirty(geometry, "position", 0, 3);
355
+ let material = gfx.createMaterial({ kind: "unlit", color: 16777215 }), batch = gfx.instanced({ geometry: gfx.createGeometry(sphereGeometry(0.5, 8, 4)), material, capacity: 16, colors: true });
356
+ expect(batch.matrices.length).toBe(256), expect(batch.colors?.length).toBe(48);
357
+ for (let i = 0; i < 4; i++) mat4Compose(batch.matrices, i * 16, i, 0, 0, 0, 0, 0, 1, 1, 1, 1);
358
+ gfx.setInstanceCount(batch, 4), gfx.markInstancesDirty(batch), expect(() => gfx.setInstanceCount(batch, 17)).toThrow(GameError), game.dispose();
359
+ }), it("drives morph targets and skeletons", async () => {
360
+ let game = await make(), gfx = game.graphics, base = new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]), geometry = gfx.createGeometry({
361
+ attributes: {
362
+ position: { data: base, itemSize: 3 },
363
+ skinIndex: { data: new Uint16Array(12), itemSize: 4 },
364
+ skinWeight: { data: new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]), itemSize: 4 }
365
+ },
366
+ morphTargets: [{ name: "smile", position: new Float32Array([0, 0.1, 0, 0, 0.1, 0, 0, 0.1, 0]) }]
367
+ }), material = gfx.createMaterial({ kind: "standard" }), morphNode = gfx.mesh(spawnAt2(game, 0, 0, 0), geometry, material), weights = gfx.morphWeights(morphNode);
368
+ expect(weights.length).toBe(1), weights[0] = 0.5, gfx.markMorphWeightsDirty(morphNode);
369
+ let bindPose = new Float32Array(20);
370
+ bindPose[6] = 1, bindPose[7] = 1, bindPose[8] = 1, bindPose[9] = 1, bindPose[11] = 1, bindPose[16] = 1, bindPose[17] = 1, bindPose[18] = 1, bindPose[19] = 1;
371
+ let skinned = gfx.create(spawnAt2(game, 0, 0, 0), {
372
+ kind: "skinned",
373
+ geometry,
374
+ material,
375
+ skeleton: { parents: new Int16Array([-1, 0]), bindPose }
376
+ }), pose = gfx.skeletonPose(skinned);
377
+ expect(pose.length).toBe(20), pose[11] = 2, gfx.markSkeletonDirty(skinned), game.advance(1), game.dispose();
378
+ }), it("compiles shader materials through the backend's shader language", async () => {
379
+ let game = await make(), gfx = game.graphics, wgslOnly = { wgsl: { fragment: "@fragment fn main() -> @location(0) vec4f { return vec4f(1.0); }" } };
380
+ gfx.capabilities.shaderLanguages.indexOf("wgsl") < 0 && expect(() => gfx.createMaterial({ kind: "shader", shader: wgslOnly })).toThrow(GameError);
381
+ let material = gfx.createMaterial({
382
+ kind: "shader",
383
+ shader: {
384
+ wgsl: wgslOnly.wgsl,
385
+ glsl: {
386
+ vertex: "void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }",
387
+ fragment: "uniform float glow; uniform vec3 tint; void main() { gl_FragColor = vec4(tint * glow, 1.0); }"
388
+ }
389
+ },
390
+ uniforms: { glow: { type: "f32", value: 1 }, tint: { type: "vec3", value: new Float32Array([1, 0, 0]) } }
391
+ });
392
+ gfx.setUniform(material, "glow", 2), gfx.setUniformVector(material, "tint", new Float32Array([0, 1, 0])), expect(() => gfx.setUniform(material, "missing", 1)).toThrow(GameError), game.dispose();
393
+ }), it("builds render targets, passes and post-processing chains", async () => {
394
+ let game = await make(), gfx = game.graphics, camera = spawnAt2(game, 0, 0, 5), cameraNode = gfx.camera(camera), target = gfx.createRenderTarget({ width: 128, height: 128, format: "rgba16f" }), texture = gfx.renderTargetTexture(target);
395
+ expect(texture).toBeGreaterThan(0);
396
+ let pass = gfx.createRenderPass({ camera: cameraNode, target, layers: 1, clearColor: 0, order: -1 });
397
+ gfx.setRenderPassEnabled(pass, false);
398
+ let chain = gfx.createPostChain({
399
+ effects: [{ kind: "bloom", strength: 0.8 }, { kind: "fxaa" }, { kind: "vignette" }, { kind: "color_grade", contrast: 1.1 }]
400
+ });
401
+ gfx.setPostChain(chain), gfx.setPostUniform(chain, 3, "contrast", 1.2), game.advance(1);
402
+ let stats = emptyStats();
403
+ gfx.stats(stats), expect(stats.renderTargets).toBe(1), expect(stats.postChains).toBe(1), expect(stats.renderPasses).toBe(1), expect(gfx.gpu === null).toBe(!gfx.capabilities.compute), game.dispose();
404
+ }), it("expresses toon, matcap, anisotropy, fat lines, area and probe lights, LOD, sky and GPU stats", async () => {
405
+ let game = await make(), gfx = game.graphics, caps = gfx.capabilities, geometry = gfx.createGeometry(boxGeometry(1, 1, 1)), ramp = gfx.createTexture({ source: { kind: "pixels", width: 2, height: 1, data: new Uint8Array([64, 64, 64, 255, 255, 255, 255, 255]) } }), toon = gfx.createMaterial({ kind: "toon", color: 3385941, gradientMap: ramp }), matcap = gfx.createMaterial({ kind: "matcap", matcap: ramp }), brushed = gfx.createMaterial({ kind: "physical", metalness: 1, roughness: 0.3, anisotropy: 0.8, anisotropyRotation: 0.5 });
406
+ gfx.setMaterialTexture(toon, "gradientMap", ramp);
407
+ let near = gfx.mesh(spawnAt2(game, 0, 0, -2), geometry, toon), far = gfx.mesh(spawnAt2(game, 0, 0, -2), geometry, matcap);
408
+ gfx.mesh(spawnAt2(game, 2, 0, -2), geometry, brushed), gfx.lodLevels([
409
+ { node: near, distance: 0 },
410
+ { node: far, distance: 20 }
411
+ ]);
412
+ let line = gfx.createGeometry({ attributes: { position: { data: new Float32Array([0, 0, 0, 1, 0, 0, 1, 1, 0]), itemSize: 3 } } });
413
+ gfx.create(spawnAt2(game, 0, 0, 0), { kind: "lines", geometry: line, material: gfx.createMaterial({ kind: "lines", width: 3, dashSize: 0.1, gapSize: 0.05 }) }), gfx.create(spawnAt2(game, 0, 3, 0), { kind: "light", light: "rectArea", width: 2, height: 1, intensity: 4 }), gfx.create(spawnAt2(game, 0, 0, 0), { kind: "light", light: "probe", sh: new Float32Array(27).fill(0.1) }), gfx.create(spawnAt2(game, 0, 4, 0), {
414
+ kind: "light",
415
+ light: "directional",
416
+ castShadow: true,
417
+ shadow: { type: "pcss", cascades: 2 }
418
+ }), gfx.camera(spawnAt2(game, 0, 1, 5)), gfx.setEnvironment({ sky: { turbidity: 6, clouds: { coverage: 0.5 } }, background: { sky: true }, toneMapping: "agx" }), gfx.setTimeOfDay(17, 30, 120), game.advance(2);
419
+ let stats = createGpuStats();
420
+ gfx.gpuStats(stats), expect(stats.passNs.length).toBe(GPU_PASS_NAMES.length), expect(typeof caps.lod).toBe("boolean");
421
+ let counts = emptyStats();
422
+ gfx.stats(counts), expect(counts.materials).toBeGreaterThanOrEqual(4), game.dispose();
423
+ }), it("loads glTF models, finds nodes and plays their clips", async () => {
424
+ let game = await make(), gfx = game.graphics, model = await gfx.loadModel({ bytes: buildTriangleGlb() });
425
+ expect(model.nodeNames).toContain("Tri"), expect(model.clipNames).toEqual(["spin"]), expect(model.materialNames).toEqual(["Grass"]), expect(model.materials).toHaveLength(1);
426
+ let grass = model.materials[0];
427
+ gfx.setMaterialColor(grass, 3368473), gfx.setMaterialState(grass, { envMapIntensity: 0 });
428
+ let root = gfx.instantiate(spawnAt2(game, 0, 0, 0), model.id), tri = gfx.findNode(root, "Tri");
429
+ expect(tri).not.toBeNull();
430
+ let action = gfx.playClip(root, "spin", true);
431
+ game.advance(30);
432
+ let m = new Float32Array(16);
433
+ gfx.readNodeMatrix(tri, m), expect(Math.abs(m[0] - 1)).toBeGreaterThan(1e-3), gfx.stopClip(action), game.dispose();
434
+ });
435
+ }), describe("clip animation", () => {
436
+ let rig = async () => {
437
+ let game = await make(), gfx = game.graphics;
438
+ if (!gfx.hasClipAnimation)
439
+ return game.dispose(), null;
440
+ let model = await gfx.loadModel({ bytes: buildRigGlb() }), root = gfx.instantiate(spawnAt2(game, 0, 0, 0), model.id);
441
+ return { game, gfx, clips: gfx.clips, root, model, step: game.loop.stepSeconds };
442
+ }, hipsX = (gfx, root) => {
443
+ let m = new Float32Array(16);
444
+ return gfx.readNodeMatrix(gfx.findNode(root, RIG_HIPS), m), m[12];
445
+ };
446
+ it("reports clip info and seeks actions", async () => {
447
+ let r = await rig();
448
+ if (r === null) return;
449
+ let info = r.clips.clipInfo(r.root, "run");
450
+ expect(info.duration).toBeCloseTo(2, 5), expect(info.tracks).toBe(1);
451
+ let action = r.gfx.playClip(r.root, "run", true);
452
+ r.clips.setClipTime(action, 0.5), r.game.advance(1);
453
+ let state = emptyClipState();
454
+ r.clips.readClipState(action, state), expect(Math.abs(state.time - (0.5 + r.step))).toBeLessThan(1e-3), expect(state.running).toBe(true), r.game.dispose();
455
+ }), it("cross fades weights linearly", async () => {
456
+ let r = await rig();
457
+ if (r === null) return;
458
+ let low = r.gfx.playClip(r.root, "low", true), high = r.gfx.playClip(r.root, "high", true);
459
+ r.clips.crossFade(low, high, 1, false), r.game.advance(30);
460
+ let a = emptyClipState(), b = emptyClipState();
461
+ r.clips.readClipState(low, a), r.clips.readClipState(high, b), expect(Math.abs(a.weight - 0.5)).toBeLessThan(0.05), expect(Math.abs(b.weight - 0.5)).toBeLessThan(0.05), r.game.dispose();
462
+ }), it("fires clip events in order with loop notifications", async () => {
463
+ let r = await rig();
464
+ if (r === null) return;
465
+ r.clips.setClipEvents(r.root, "walk", [
466
+ { time: 0.75, id: 9 },
467
+ { time: 0.25, id: 7 }
468
+ ]), r.gfx.playClip(r.root, "walk", true);
469
+ let buffer = [], ids = [], loops = 0;
470
+ for (let frame = 0; frame < 19; frame++) {
471
+ r.game.advance(6);
472
+ let count = r.clips.readClipEvents(buffer);
473
+ for (let i = 0; i < count; i++)
474
+ buffer[i].kind === "event" && ids.push(buffer[i].id), buffer[i].kind === "loop" && loops++;
475
+ }
476
+ expect(ids).toEqual([7, 9, 7, 9]), expect(loops).toBe(1), r.game.dispose();
477
+ }), it("keeps synced clips of different length in phase", async () => {
478
+ let r = await rig();
479
+ if (r === null) return;
480
+ let walk = r.gfx.playClip(r.root, "walk", true), run2 = r.gfx.playClip(r.root, "run", true);
481
+ r.clips.setClipSync(walk, 3), r.clips.setClipSync(run2, 3), r.gfx.setClipWeight(walk, 0.5), r.gfx.setClipWeight(run2, 0.5);
482
+ let a = emptyClipState(), b = emptyClipState();
483
+ for (let frame = 0; frame < 8; frame++)
484
+ r.game.advance(7), r.clips.readClipState(walk, a), r.clips.readClipState(run2, b), expect(Math.abs(a.time - b.time / 2)).toBeLessThan(1e-3);
485
+ expect(a.time).toBeGreaterThan(0), r.game.dispose();
486
+ }), it("weights 1D blend space members at a midpoint", async () => {
487
+ let r = await rig();
488
+ if (r === null) return;
489
+ let low = r.gfx.playClip(r.root, "low", true), high = r.gfx.playClip(r.root, "high", true), space = r.clips.createBlendSpace(r.root, {
490
+ kind: "1d",
491
+ members: [
492
+ { action: low, x: 0 },
493
+ { action: high, x: 1 }
494
+ ]
495
+ });
496
+ r.clips.setBlendParameter(space, 0.5, 0, 1), r.game.advance(1);
497
+ let a = emptyClipState(), b = emptyClipState();
498
+ r.clips.readClipState(low, a), r.clips.readClipState(high, b), expect(Math.abs(a.weight - 0.5)).toBeLessThan(1e-3), expect(Math.abs(b.weight - 0.5)).toBeLessThan(1e-3), expect(Math.abs(hipsX(r.gfx, r.root) - 2)).toBeLessThan(1e-3), r.game.dispose();
499
+ }), it("maps Mixamo style names to the humanoid rig", async () => {
500
+ let r = await rig();
501
+ if (r === null) return;
502
+ let map = r.clips.humanoid(r.root);
503
+ expect(map.hips).toBe(RIG_HIPS), expect(map.spine).toBe("mixamorig_Spine"), expect(map.chest).toBe("mixamorig_Spine1"), r.game.dispose();
504
+ }), it("extracts root motion across loops", async () => {
505
+ let r = await rig();
506
+ if (r === null) return;
507
+ r.gfx.playClip(r.root, "walk", true);
508
+ let motion = r.clips.enableRootMotion(r.root, { bone: RIG_HIPS }), delta = new Float32Array(4), travelled = 0;
509
+ for (let frame = 0; frame < 25; frame++)
510
+ r.game.advance(3), r.clips.readRootMotion(motion, delta, 0), travelled += delta[0];
511
+ expect(Math.abs(travelled - 75 * r.step * (2))).toBeLessThan(0.01), expect(Math.abs(hipsX(r.gfx, r.root))).toBeLessThan(1e-4), r.game.dispose();
512
+ }), it("scales masked bones by fractional mask weights", async () => {
513
+ let r = await rig();
514
+ if (r === null) return;
515
+ let action = r.gfx.playClip(r.root, "high", true), mask = r.clips.createClipMask(r.root, { [RIG_HIPS]: 0.5 });
516
+ r.clips.setClipMask(action, mask), r.game.advance(2), expect(Math.abs(hipsX(r.gfx, r.root) - 2)).toBeLessThan(1e-3), r.clips.setClipMask(action, null), r.game.advance(2), expect(Math.abs(hipsX(r.gfx, r.root) - 4)).toBeLessThan(1e-3), r.game.dispose();
517
+ }), it("keeps cubic splines exact inside clip ranges", async () => {
518
+ let r = await rig();
519
+ if (r === null) return;
520
+ let other = r.gfx.instantiate(spawnAt2(r.game, 0, 0, 0), r.model.id), whole = r.gfx.playClip(r.root, "curve", true), ranged = r.gfx.playClip(other, "curve", true);
521
+ r.clips.setClipRange(ranged, 0.3, 1.7), r.clips.setClipPaused(whole, true), r.clips.setClipPaused(ranged, true);
522
+ for (let time2 of [0.3, 0.5, 1.2, 1.7])
523
+ r.clips.setClipTime(whole, time2), r.clips.setClipTime(ranged, time2), r.game.advance(1), expect(Math.abs(hipsX(r.gfx, r.root) - hipsX(r.gfx, other))).toBeLessThan(1e-4);
524
+ r.game.dispose();
525
+ });
526
+ }), describe("input", () => {
527
+ it("maps keys, gamepad and virtual controls to actions with step edges", async () => {
528
+ let game = await make(), input = game.input, jump = input.defineButton("jump", [{ device: "key", code: "Space" }, { device: "gamepad", button: 0 }]), move = input.defineAxis("move", [
529
+ { device: "keys", negative: "KeyA", positive: "KeyD" },
530
+ { device: "gamepad", axis: 0 },
531
+ { device: "virtual", control: "stick-x" }
532
+ ]);
533
+ input.keyEvent("Space", true, 0), input.keyEvent("Space", false, 1), input.keyEvent("KeyD", true, 2);
534
+ let pressedSeen = 0;
535
+ game.addSystem({ fixedUpdate: (g) => {
536
+ pressedSeen += g.input.justPressed(jump) ? 1 : 0;
537
+ } }), game.advance(2), expect(pressedSeen).toBe(1), expect(input.value(move)).toBe(1), input.gamepadAxisEvent(0, -0.9, 3), input.keyEvent("KeyD", false, 3), game.advance(1), expect(input.value(move)).toBeLessThan(-0.8), input.gamepadAxisEvent(0, 0, 4), input.virtualEvent("stick-x", 0.4, 4), game.advance(1), expect(input.value(move)).toBeCloseTo(0.4, 5), game.dispose();
538
+ }), it("recognises swipes with curl and taps", async () => {
539
+ let game = await make(), input = game.input;
540
+ input.pointerEvent("down", 3, 0.5, 0.9, 0), input.pointerEvent("move", 3, 0.6, 0.6, 80), input.pointerEvent("up", 3, 0.5, 0.3, 160);
541
+ let swipes = 0, curl = 0;
542
+ game.addSystem({
543
+ fixedUpdate: (g) => {
544
+ g.input.swipe.ready && (swipes++, curl = g.input.swipe.curl);
545
+ }
546
+ }), game.advance(3), expect(swipes).toBe(1), expect(Math.abs(curl)).toBeGreaterThan(0.1), input.pointerEvent("down", 4, 0.2, 0.2, 200), input.pointerEvent("up", 4, 0.2, 0.2, 260);
547
+ let taps = 0;
548
+ game.addSystem({ fixedUpdate: (g) => {
549
+ taps += g.input.tap.ready ? 1 : 0;
550
+ } }), game.advance(2), expect(taps).toBe(1), game.dispose();
551
+ });
552
+ }), describe("physics", () => {
553
+ it("rests dynamic bodies on the ground and responds to impulses", async () => {
554
+ let game = await make();
555
+ ground(game);
556
+ let ball = spawnAt2(game, 0, 3, 0);
557
+ game.physics.addBody(ball, { kind: "dynamic" }), game.physics.addCollider(ball, { shape: { kind: "ball", radius: 0.5 } }), game.advance(180);
558
+ let p = game.transforms.position(ball, new Vec3());
559
+ expect(p.y).toBeCloseTo(0.5, 1), game.physics.applyImpulse(ball, new Vec3(0, 0, -5)), game.advance(10);
560
+ let v = game.physics.linearVelocity(ball, new Vec3());
561
+ expect(v.z).toBeLessThan(-0.5), game.dispose();
562
+ }), it("casts rays with distances and surface normals", async () => {
563
+ let game = await make();
564
+ ground(game);
565
+ let box = spawnAt2(game, 0, 1, -5);
566
+ game.transforms.setRotationQuat(box, new Quat().setEuler(0, 0.5, 0)), game.physics.addCollider(box, { shape: { kind: "cuboid", halfExtents: [1, 1, 1] } });
567
+ let mesh = spawnAt2(game, 10, 0.5, 0);
568
+ game.physics.addCollider(mesh, {
569
+ shape: {
570
+ kind: "trimesh",
571
+ vertices: new Float32Array([-1, 0, -1, 1, 0, -1, 0, 0, 1]),
572
+ indices: new Uint32Array([0, 2, 1])
573
+ }
574
+ }), game.advance(1);
575
+ let hit = new RayHit(), ray = new RayQuery();
576
+ expect(game.physics.raycast(ray.set(0, 5, 0, 0, -1, 0, 10), hit)).toBe(true), expect(hit.distance).toBeCloseTo(5, 3), expect(hit.normalY).toBeCloseTo(1, 3), expect(game.physics.raycast(ray.set(0, 1, 5, 0, 0, -1, 20), hit)).toBe(true), expect(game.physics.entityOfCollider(hit.collider)).toBe(box), expect(hit.normalZ).toBeGreaterThan(0.5), expect(game.physics.raycast(ray.set(10, 3, 0, 0, -1, 0, 10), hit)).toBe(true), expect(game.physics.entityOfCollider(hit.collider)).toBe(mesh), expect(hit.normalY).toBeCloseTo(1, 2), expect(game.physics.raycast(ray.set(0, 5, 0, 0, 1, 0, 10), hit)).toBe(false), game.dispose();
577
+ }), it("reports sensor and contact events", async () => {
578
+ let game = await make();
579
+ ground(game);
580
+ let zone = spawnAt2(game, 0, 1, 0);
581
+ game.physics.addCollider(zone, { shape: { kind: "cuboid", halfExtents: [1, 1, 1] }, sensor: true });
582
+ let ball = spawnAt2(game, 0, 4, 0);
583
+ game.physics.addBody(ball, { kind: "dynamic" }), game.physics.addCollider(ball, { shape: { kind: "ball", radius: 0.25 }, events: true });
584
+ let entered = false;
585
+ game.addSystem({
586
+ fixedUpdate: (g) => {
587
+ for (let i = 0; i < g.physics.contactCount(); i++) {
588
+ let a = g.physics.contactEntityA(i), b = g.physics.contactEntityB(i);
589
+ g.physics.contactStarted(i) && (a === zone || b === zone) && (entered = true);
590
+ }
591
+ }
592
+ }), game.advance(120), expect(entered).toBe(true), game.dispose();
593
+ }), it("constrains bodies with joints", async () => {
594
+ let game = await make(), anchor = spawnAt2(game, 0, 5, 0);
595
+ game.physics.addBody(anchor, { kind: "fixed" }), game.physics.addCollider(anchor, { shape: { kind: "ball", radius: 0.1 } });
596
+ let bob = spawnAt2(game, 2, 5, 0);
597
+ game.physics.addBody(bob, { kind: "dynamic" }), game.physics.addCollider(bob, { shape: { kind: "ball", radius: 0.2 } }), game.physics.joint(anchor, bob, { kind: "spherical", anchorA: [0, 0, 0], anchorB: [-2, 0, 0] }), game.advance(90);
598
+ let p = game.transforms.position(bob, new Vec3());
599
+ expect(Math.hypot(p.x, p.y - 5, p.z)).toBeCloseTo(2, 1), expect(p.y).toBeLessThan(5), game.dispose();
600
+ }), it("walks a character controller, stays grounded and slides along walls", async () => {
601
+ let game = await make();
602
+ ground(game);
603
+ let wall = spawnAt2(game, 2, 1, 0);
604
+ game.physics.addCollider(wall, { shape: { kind: "cuboid", halfExtents: [0.1, 1, 5] } });
605
+ let hero = spawnAt2(game, 0, 0.9, 0);
606
+ game.physics.addBody(hero, { kind: "kinematic" });
607
+ let collider = game.physics.addCollider(hero, { shape: { kind: "capsule", halfHeight: 0.5, radius: 0.3 } }), controller = game.physics.createCharacterController({ snapToGround: 0.3, maxSlopeClimbDegrees: 45 }), move = new CharacterMove(), desired = new Vec3(), grounded = false;
608
+ game.advance(1), game.addSystem({
609
+ fixedUpdate: (g) => {
610
+ let dt = g.stepSeconds;
611
+ g.physics.moveCharacter(controller, collider, desired.set(2 * dt, -9.81 * dt, dt), move), grounded = move.grounded;
612
+ }
613
+ }), game.advance(120);
614
+ let p = game.transforms.position(hero, new Vec3());
615
+ expect(p.x).toBeGreaterThan(1.4), expect(p.x).toBeLessThan(1.65), expect(p.z).toBeGreaterThan(1.5), expect(p.y).toBeCloseTo(0.81, 1), expect(grounded).toBe(true), game.dispose();
616
+ });
617
+ }), describe("animation", () => {
618
+ it("tweens transforms and values with easing, delay and repeat", async () => {
619
+ let game = await make(), e = spawnAt2(game, 0, 0, 0), anim = game.animation, t = anim.tween(e, TweenTarget.PositionY, 3, 0.5, Ease.OutQuad), slot = anim.createValue(0);
620
+ anim.tweenValue(slot, 1, 0.25, Ease.Linear, 0.25);
621
+ let loop = anim.createValue(0);
622
+ anim.tweenValue(loop, 1, 0.5, Ease.Linear, 0, Repeat.PingPong), game.advance(15), expect(anim.value(slot)).toBeCloseTo(0, 5), game.advance(15), expect(game.transforms.position(e, new Vec3()).y).toBeCloseTo(3, 4), expect(anim.isActive(t)).toBe(false), expect(anim.value(slot)).toBeCloseTo(1, 4), game.advance(15), expect(anim.value(loop)).toBeCloseTo(0.5, 1), game.dispose();
623
+ }), it("samples keyframe clips including rotation", async () => {
624
+ let { Clip } = await import('../animation-6DICNWUP.mjs'), game = await make(), e = spawnAt2(game, 0, 0, 0), half = Math.SQRT1_2, clip = new Clip({
625
+ duration: 1,
626
+ tracks: [
627
+ { target: TweenTarget.PositionX, times: new Float32Array([0, 1]), values: new Float32Array([0, 10]) },
628
+ { target: TweenTarget.Rotation, times: new Float32Array([0, 1]), values: new Float32Array([0, 0, 0, 1, 0, half, 0, half]) }
629
+ ]
630
+ });
631
+ game.animation.playClip(e, clip), game.advance(30), expect(game.transforms.position(e, new Vec3()).x).toBeCloseTo(5, 0), game.advance(60);
632
+ let q = game.transforms.rotation(e, new Quat());
633
+ expect(q.y).toBeCloseTo(half, 3), game.dispose();
634
+ });
635
+ }), describe("audio and game UI", () => {
636
+ it("plays voices on buses and tracks spatial voices", async () => {
637
+ let game = await make(), sound = await game.audio.load({ bytes: new ArrayBuffer(8) }), voice = game.audio.play(sound, game.audio.effects, 0.5, 1, true);
638
+ expect(game.audio.isPlaying(voice)).toBe(true), game.audio.setBusGain(game.audio.music, 0.2), game.audio.duck(game.audio.music, 0.5, 0.1, 0.05);
639
+ let emitter = spawnAt2(game, 3, 0, 0), spatial = game.audio.playAt(emitter, sound, game.audio.effects, 1, 1, true);
640
+ game.advance(10), game.audio.stop(voice), expect(game.audio.isPlaying(voice)).toBe(false), expect(game.audio.isPlaying(spatial)).toBe(true), game.dispose();
641
+ }), it("batches HUD updates to the native host once per frame", async () => {
642
+ let host = new RecordingUiHost(), game = await make(1, host), score = game.ui.hudNumber("score"), label = game.ui.hudText("label", "Go");
643
+ game.advance(1), expect(host.layout.map((s) => s.name)).toEqual(["score", "label"]);
644
+ let before = host.publishes;
645
+ game.ui.setNumber(score, 1), game.ui.setNumber(score, 2), game.ui.setText(label, "Goal"), game.advance(1), expect(host.publishes).toBe(before + 1), expect(host.lastDirty).toBe(2), game.advance(1), expect(host.publishes).toBe(before + 1);
646
+ let restart = game.ui.defineAction("restart");
647
+ expect(game.ui.dispatch("restart")).toBe(true), expect(game.ui.pollAction()).toBe(restart), game.ui.show("pause", { score: 2 }), game.ui.haptic("success"), expect(host.panels).toEqual(["pause"]), expect(host.haptics).toEqual(["success"]), game.dispose();
648
+ });
649
+ }), describe("networking", () => {
650
+ it("bit-packs messages and decodes them in place", async () => {
651
+ let game = await make(), Move = game.net.defineMessage("move", {
652
+ seq: "u16",
653
+ dx: quantized(-1, 1, 10),
654
+ jump: "bool",
655
+ yaw: "f32",
656
+ tick: "u32",
657
+ delta: "i16"
658
+ });
659
+ expect(Move.bytes).toBe(Math.ceil(115 / 8));
660
+ let writer = new MessageWriter();
661
+ writer.begin(Move).set(Move.field("seq"), 513).set(Move.field("dx"), -0.25).setBool(Move.field("jump"), true).set(Move.field("yaw"), 1.5).set(Move.field("tick"), 4e9).set(Move.field("delta"), -300);
662
+ let [a, b] = LoopbackTransport.pair();
663
+ game.net.connect(a);
664
+ let peer = await make();
665
+ peer.net.defineMessage("move", { seq: "u16", dx: quantized(-1, 1, 10), jump: "bool", yaw: "f32", tick: "u32", delta: "i16" }), peer.net.connect(b);
666
+ let inbound = peer.net.channel("inputs", "reliable");
667
+ game.net.channel("inputs", "reliable").send(writer);
668
+ let reader = peer.net.reader();
669
+ expect(inbound.receive(reader)).toBe(true), expect(reader.get(Move.field("seq"))).toBe(513), expect(reader.get(Move.field("dx"))).toBeCloseTo(-0.25, 2), expect(reader.getBool(Move.field("jump"))).toBe(true), expect(reader.get(Move.field("yaw"))).toBeCloseTo(1.5, 6), expect(reader.get(Move.field("tick"))).toBe(4e9), expect(reader.get(Move.field("delta"))).toBe(-300), expect(inbound.receive(reader)).toBe(false), game.dispose(), peer.dispose();
670
+ }), it("keeps only the newest message on latest-value channels", async () => {
671
+ let game = await make(), Pos = game.net.defineMessage("pos", { x: "f32" }), [a, b] = LoopbackTransport.pair();
672
+ game.net.connect(a);
673
+ let peer = await make();
674
+ peer.net.defineMessage("pos", { x: "f32" }), peer.net.connect(b);
675
+ let inbound = peer.net.channel("state", "latest"), outbound = game.net.channel("state", "latest"), writer = new MessageWriter();
676
+ for (let i = 0; i < 5; i++) outbound.send(writer.begin(Pos).set(Pos.field("x"), i));
677
+ let reader = peer.net.reader();
678
+ expect(inbound.receive(reader)).toBe(true), expect(reader.get(Pos.field("x"))).toBe(4), expect(inbound.receive(reader)).toBe(false), game.dispose(), peer.dispose();
679
+ }), it("interpolates remote snapshots", () => {
680
+ let buffer = new SnapshotBuffer(2, 8), identity = new Float32Array([0, 0, 0, 1]);
681
+ buffer.push(1, 10, new Float32Array([0, 0, 0]), 0, identity, 0), buffer.push(1, 12, new Float32Array([4, 0, 0]), 0, identity, 0);
682
+ let p = new Float32Array(3), r = new Float32Array(4);
683
+ expect(buffer.sample(1, 11, p, 0, r, 0)).toBe(true), expect(p[0]).toBeCloseTo(2, 5), expect(buffer.sample(0, 11, p, 0, r, 0)).toBe(false);
684
+ });
685
+ }), describe("determinism", () => {
686
+ let simulate = async (seed) => {
687
+ let game = await make(seed);
688
+ ground(game);
689
+ let bodies = [];
690
+ for (let i = 0; i < 12; i++) {
691
+ let e = spawnAt2(game, game.random.range(-3, 3), 2 + i * 0.6, game.random.range(-3, 3));
692
+ game.physics.addBody(e, { kind: "dynamic" }), game.physics.addCollider(e, { shape: i % 2 === 0 ? { kind: "ball", radius: 0.3 } : { kind: "cuboid", halfExtents: [0.3, 0.3, 0.3] } }), bodies.push(e);
693
+ }
694
+ let kick = new Vec3();
695
+ game.addSystem({
696
+ fixedUpdate: (g) => {
697
+ if (g.tick % 20 !== 0) return;
698
+ let target = bodies[g.random.int(0, bodies.length - 1)];
699
+ g.physics.applyImpulse(target, kick.set(g.random.range(-1, 1), g.random.range(0, 2), g.random.range(-1, 1)));
700
+ }
701
+ }), game.advance(240);
702
+ let out = Float32Array.from(game.transforms.store.fields.position.subarray(0, game.transforms.store.count * 3));
703
+ return game.dispose(), out;
704
+ };
705
+ it("reproduces identical state from the same seed", async () => {
706
+ let a = await simulate(42), b = await simulate(42);
707
+ expect(sameBits(a, b)).toBe(true);
708
+ }), it("diverges for a different seed", async () => {
709
+ let a = await simulate(42), c = await simulate(43);
710
+ expect(sameBits(a, c)).toBe(false);
711
+ });
712
+ }), describe("frame-loop allocation", () => {
713
+ let measure = (vendorQueries) => options.allocation ? options.allocation(vendorQueries) : measureSustainedAllocation(
714
+ options.createBackend,
715
+ options.heap,
716
+ vendorQueries,
717
+ options.sustainedFrames,
718
+ (true)
719
+ ), withClock = (run2) => options.hostClock === "frozen" ? withFrozenHostClock(run2) : run2();
720
+ it("allocates nothing and never collects garbage across a sustained headless run", async () => {
721
+ let result = await withClock(() => measure(false));
722
+ if (!result) return;
723
+ let [report, longer] = result;
724
+ options.report?.("sustained", report), options.report?.("sustained-2x", longer), expect(report.collections).toBe(0), expect(longer.collections).toBe(0), expect(report.bytesPerFrame).toBeLessThan((1)), expect(longer.bytesPerFrame).toBeLessThan((1));
725
+ }, 12e4), it("keeps physics queries and dynamic body readback within the backend's declared boundary budget", async () => {
726
+ let result = await withClock(() => measure(true));
727
+ if (!result) return;
728
+ let [report, longer] = result;
729
+ options.report?.("physics-queries", report), options.report?.("physics-queries-2x", longer);
730
+ let budget = options.physicsBoundaryBudget ?? NO_BOUNDARY_BUDGET, perFrame = (48) * budget.bytesPerAwakeBodyStep + budget.bytesPerRaycast + budget.bytesPerCharacterMove;
731
+ expect(report.bytesPerFrame).toBeLessThanOrEqual(perFrame + (1)), expect(longer.bytesPerFrame).toBeLessThanOrEqual(perFrame + (1)), perFrame === 0 && expect(longer.collections).toBe(0);
732
+ }, 12e4);
733
+ }), describe("hot-path microbenchmarks", () => {
734
+ it("keeps math, transform, query, codec and raycast calls within their nanosecond budgets", async (context) => {
735
+ let results = await (options.microbench ?? (() => runMicrobench(options.createBackend)))();
736
+ options.reportMicrobench?.(results);
737
+ let busy = await busyMachine();
738
+ busy !== null && (console.info(`${loadSkipNotice(busy)}: ${JSON.stringify(results, (_key, value) => typeof value == "number" ? Math.round(value * 10) / 10 : value)}`), context.skip());
739
+ for (let name of Object.keys(results)) {
740
+ let budget = options.microbenchBudgetsNs?.[name] ?? DEFAULT_MICROBENCH_BUDGETS_NS[name];
741
+ expect(results[name], `${name} ${results[name].toFixed(1)}ns`).toBeLessThan(budget);
742
+ }
743
+ }, (12e4));
744
+ });
745
+ });
746
+ }
747
+ var FROZEN_HOST_TIME = 0;
748
+ function frozenNow() {
749
+ return (0);
750
+ }
751
+ var NO_BOUNDARY_BUDGET = { bytesPerAwakeBodyStep: 0, bytesPerRaycast: 0, bytesPerCharacterMove: 0 };
752
+ function halfway() {
753
+ let time2 = new FrameTime();
754
+ return time2.values[FRAME_ALPHA_SLOT] = 0.5, time2;
755
+ }
756
+ function sameBits(a, b) {
757
+ if (a.length !== b.length) return false;
758
+ let x = new Uint32Array(a.buffer, a.byteOffset, a.length), y = new Uint32Array(b.buffer, b.byteOffset, b.length);
759
+ for (let i = 0; i < x.length; i++) if (x[i] !== y[i]) return false;
760
+ return true;
761
+ }
762
+ var GLB_MAGIC = 1179937895, GLB_VERSION = 2, GLB_CHUNK_JSON = 1313821514, GLB_CHUNK_BIN = 5130562, GLB_HEADER_BYTES = 12, GLB_CHUNK_HEADER_BYTES = 8, GLB_ALIGN = 4, SPACE = 32, RIG_HIPS = "mixamorig_Hips", RIG_WALK_SPEED = 2;
763
+ function glbFrom(json, bin) {
764
+ let text = new TextEncoder().encode(JSON.stringify(json)), jsonLength = Math.ceil(text.length / (4)) * (4), binLength = Math.ceil(bin.length / (4)) * (4), total = (12) + (8) * 2 + jsonLength + binLength, out = new ArrayBuffer(total), view = new DataView(out), bytes = new Uint8Array(out);
765
+ view.setUint32(0, (1179937895), true), view.setUint32(4, (2), true), view.setUint32(8, total, true);
766
+ let o = (12);
767
+ return view.setUint32(o, jsonLength, true), view.setUint32(o + 4, (1313821514), true), o += (8), bytes.fill((32), o, o + jsonLength), bytes.set(text, o), o += jsonLength, view.setUint32(o, binLength, true), view.setUint32(o + 4, (5130562), true), o += (8), bytes.set(bin, o), out;
768
+ }
769
+ function buildRigGlb() {
770
+ let streams = [
771
+ new Float32Array([0, 1]),
772
+ new Float32Array([0, 2]),
773
+ new Float32Array([0, 0, 0, (2), 0, 0]),
774
+ new Float32Array([0, 0, 0, (2) * 2, 0, 0]),
775
+ new Float32Array([0, 0, 0, 0, 0, 0]),
776
+ new Float32Array([4, 0, 0, 4, 0, 0]),
777
+ new Float32Array([0, 1, 2]),
778
+ new Float32Array([0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 3, 0, 0, -1, 0, 0, 0.5, 0, 0, 1, 0, 0, 0, 0, 0])
779
+ ], bin = new Uint8Array(streams.reduce((sum, s) => sum + s.byteLength, 0)), bufferViews = [], offset = 0;
780
+ for (let stream of streams)
781
+ bin.set(new Uint8Array(stream.buffer), offset), bufferViews.push({ buffer: 0, byteOffset: offset, byteLength: stream.byteLength }), offset += stream.byteLength;
782
+ let clip = (name, input, output, interpolation = "LINEAR") => ({
783
+ name,
784
+ samplers: [{ input, output, interpolation }],
785
+ channels: [{ sampler: 0, target: { node: 0, path: "translation" } }]
786
+ });
787
+ return glbFrom(
788
+ {
789
+ asset: { version: "2.0" },
790
+ scene: 0,
791
+ scenes: [{ nodes: [0] }],
792
+ nodes: [
793
+ { name: RIG_HIPS, children: [1] },
794
+ { name: "mixamorig_Spine", translation: [0, 0.2, 0], children: [2] },
795
+ { name: "mixamorig_Spine1", translation: [0, 0.2, 0] }
796
+ ],
797
+ buffers: [{ byteLength: bin.byteLength }],
798
+ bufferViews,
799
+ accessors: [
800
+ { bufferView: 0, componentType: 5126, count: 2, type: "SCALAR", min: [0], max: [1] },
801
+ { bufferView: 1, componentType: 5126, count: 2, type: "SCALAR", min: [0], max: [2] },
802
+ { bufferView: 2, componentType: 5126, count: 2, type: "VEC3" },
803
+ { bufferView: 3, componentType: 5126, count: 2, type: "VEC3" },
804
+ { bufferView: 4, componentType: 5126, count: 2, type: "VEC3" },
805
+ { bufferView: 5, componentType: 5126, count: 2, type: "VEC3" },
806
+ { bufferView: 6, componentType: 5126, count: 3, type: "SCALAR", min: [0], max: [2] },
807
+ { bufferView: 7, componentType: 5126, count: 9, type: "VEC3" }
808
+ ],
809
+ animations: [
810
+ clip("walk", 0, 2),
811
+ clip("run", 1, 3),
812
+ clip("low", 0, 4),
813
+ clip("high", 0, 5),
814
+ clip("curve", 6, 7, "CUBICSPLINE")
815
+ ]
816
+ },
817
+ bin
818
+ );
819
+ }
820
+ function buildTriangleGlb() {
821
+ let positions = new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]), times = new Float32Array([0, 1]), rotations = new Float32Array([0, 0, 0, 1, 0, 0.7071068, 0, 0.7071068]), bin = new Uint8Array(positions.byteLength + times.byteLength + rotations.byteLength);
822
+ bin.set(new Uint8Array(positions.buffer), 0), bin.set(new Uint8Array(times.buffer), positions.byteLength), bin.set(new Uint8Array(rotations.buffer), positions.byteLength + times.byteLength);
823
+ let json = new TextEncoder().encode(triangleJson(bin.length, positions.byteLength, times.byteLength, rotations.byteLength)), jsonLength = Math.ceil(json.length / (4)) * (4), binLength = Math.ceil(bin.length / (4)) * (4), total = (12) + (8) * 2 + jsonLength + binLength, out = new ArrayBuffer(total), view = new DataView(out), bytes = new Uint8Array(out);
824
+ view.setUint32(0, (1179937895), true), view.setUint32(4, (2), true), view.setUint32(8, total, true);
825
+ let o = (12);
826
+ return view.setUint32(o, jsonLength, true), view.setUint32(o + 4, (1313821514), true), o += (8), bytes.fill((32), o, o + jsonLength), bytes.set(json, o), o += jsonLength, view.setUint32(o, binLength, true), view.setUint32(o + 4, (5130562), true), o += (8), bytes.set(bin, o), out;
827
+ }
828
+ function triangleJson(byteLength, positionBytes, timeBytes, rotationBytes) {
829
+ return JSON.stringify({
830
+ asset: { version: "2.0" },
831
+ scene: 0,
832
+ scenes: [{ nodes: [0] }],
833
+ nodes: [{ name: "Tri", mesh: 0 }],
834
+ meshes: [{ primitives: [{ attributes: { POSITION: 0 }, material: 0 }] }],
835
+ materials: [{ name: "Grass", pbrMetallicRoughness: { baseColorFactor: [0, 1, 0, 1], roughnessFactor: 0.5 } }],
836
+ buffers: [{ byteLength }],
837
+ bufferViews: [
838
+ { buffer: 0, byteOffset: 0, byteLength: positionBytes },
839
+ { buffer: 0, byteOffset: positionBytes, byteLength: timeBytes },
840
+ { buffer: 0, byteOffset: positionBytes + timeBytes, byteLength: rotationBytes }
841
+ ],
842
+ accessors: [
843
+ { bufferView: 0, componentType: 5126, count: 3, type: "VEC3", min: [0, 0, 0], max: [1, 1, 0] },
844
+ { bufferView: 1, componentType: 5126, count: 2, type: "SCALAR", min: [0], max: [1] },
845
+ { bufferView: 2, componentType: 5126, count: 2, type: "VEC4" }
846
+ ],
847
+ animations: [
848
+ {
849
+ name: "spin",
850
+ samplers: [{ input: 1, output: 2, interpolation: "LINEAR" }],
851
+ channels: [{ sampler: 0, target: { node: 0, path: "rotation" } }]
852
+ }
853
+ ]
854
+ });
855
+ }
856
+ var LOCK_DIR = join(tmpdir(), "cimplify-engine-measurement.lock"), OWNER_FILE = join(LOCK_DIR, "owner"), POLL_MS = 5, NO_SIGNAL = 0, pause = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
857
+ function alive(pid) {
858
+ try {
859
+ return process.kill(pid, (0)), !0;
860
+ } catch {
861
+ return false;
862
+ }
863
+ }
864
+ function owner() {
865
+ try {
866
+ return Number(readFileSync(OWNER_FILE, "utf8"));
867
+ } catch {
868
+ return Number.NaN;
869
+ }
870
+ }
871
+ function acquire() {
872
+ for (; ; )
873
+ try {
874
+ mkdirSync(LOCK_DIR), writeFileSync(OWNER_FILE, String(process.pid));
875
+ return;
876
+ } catch {
877
+ let pid = owner();
878
+ Number.isInteger(pid) && !alive(pid) ? rmSync(LOCK_DIR, { recursive: true, force: true }) : Atomics.wait(pause, 0, 0, (5));
879
+ }
880
+ }
881
+ function exclusiveMeasurement(run2) {
882
+ acquire();
883
+ try {
884
+ return run2();
885
+ } finally {
886
+ rmSync(LOCK_DIR, { recursive: true, force: true });
887
+ }
888
+ }
889
+
890
+ // src/game/conformance/isolated.ts
891
+ var ISOLATED_RESULT_PREFIX = "isolated-result:", ISOLATED_TIMEOUT_MS = 6e5, CHILD_BUFFER_BYTES = 1 << 24, ISOLATION_FLAGS = ["--expose-gc", "--no-concurrent-recompilation", "--no-concurrent-osr", "--no-concurrent-sparkplug"], NUMERIC_VAR = /^var ([A-Za-z_$][\w$]*) = (-?(?:0x[0-9a-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?));$/gm, REGEX_SPECIAL = /[$]/g, bundles = /* @__PURE__ */ new Map();
892
+ function writes(code, name) {
893
+ let id = name.replace(REGEX_SPECIAL, "\\$&"), assigned = new RegExp(`(?<![\\w$.])${id}\\s*(?:[-+*/%&|^]|\\*\\*|<<|>>>?|\\?\\?|&&|\\|\\|)?=(?!=)`, "g"), stepped = new RegExp(`(?:\\+\\+|--)\\s*${id}(?![\\w$])|(?<![\\w$.])${id}\\s*(?:\\+\\+|--)`, "g");
894
+ return (code.match(assigned)?.length ?? 0) + (code.match(stepped)?.length ?? 0);
895
+ }
896
+ function restoreConstants(code) {
897
+ return code.replace(NUMERIC_VAR, (line, name, value) => writes(code, name) === 1 ? `const ${name} = ${value};` : line);
898
+ }
899
+ function bundle(key, write) {
900
+ let known = bundles.get(key);
901
+ if (known !== void 0) return known;
902
+ let dir = mkdtempSync(join(tmpdir(), "cimplify-isolated-")), entry = write(dir), outfile = join(dir, "isolated.mjs");
903
+ return execFileSync("bun", ["build", entry, "--target=node", "--format=esm", "--outfile", outfile], { stdio: "pipe" }), writeFileSync(outfile, restoreConstants(readFileSync(outfile, "utf8"))), bundles.set(key, outfile), outfile;
904
+ }
905
+ function run(script, args) {
906
+ let output = exclusiveMeasurement(
907
+ () => execFileSync("node", [...ISOLATION_FLAGS, script, ...args], { encoding: "utf8", maxBuffer: CHILD_BUFFER_BYTES, timeout: (6e5) })
908
+ ), line = output.split(`
909
+ `).find((l) => l.startsWith(ISOLATED_RESULT_PREFIX));
910
+ if (!line) throw new Error(`the isolated measurement produced no result: ${output}`);
911
+ return JSON.parse(line.slice(ISOLATED_RESULT_PREFIX.length));
912
+ }
913
+ function isolatedModule(source, args) {
914
+ return run(
915
+ bundle(source, (dir) => {
916
+ let entry = join(dir, "entry.ts");
917
+ return writeFileSync(entry, source), entry;
918
+ }),
919
+ args
920
+ );
921
+ }
922
+
923
+ // src/game/conformance/template-suite.ts
924
+ var FILE_PROTOCOL = "file:";
925
+ function sourcePath(relative, base) {
926
+ let url = new URL(relative, base), pathname = decodeURIComponent(url.pathname), host = globalThis.process;
927
+ return url.protocol === FILE_PROTOCOL || host === void 0 ? pathname : `${host.cwd()}${pathname}`;
928
+ }
929
+ var TEMPLATE_ALLOCATION_MODULE = sourcePath("./template-allocation.ts", import.meta.url); sourcePath("../backends/prepared.ts", import.meta.url);
930
+ function isolatedSource(isolated) {
931
+ return [
932
+ `import { runTemplateAllocationChild } from ${JSON.stringify(TEMPLATE_ALLOCATION_MODULE)};`,
933
+ `import { ${isolated.exportName} as template } from ${JSON.stringify(isolated.module)};`,
934
+ `import { ${isolated.backendExport} as createBackend } from ${JSON.stringify(isolated.backendModule)};`,
935
+ "await runTemplateAllocationChild(template, createBackend);",
936
+ ""
937
+ ].join(`
938
+ `);
939
+ }
940
+ var FS_MODULE = "node:fs", UTF8 = "utf8", DEFAULT_SEED = 11, DEFAULT_WARMUP_FRAMES = 3e4, DEFAULT_SUSTAINED_FRAMES2 = 6e3, RESIDUE_BYTES_PER_FRAME2 = 1, SUSTAINED_TIMEOUT_MS = 12e4;
941
+ function defineTemplateConformance(options) {
942
+ let template = options.template, seed = options.seed ?? (11), play = async (frames, runSeed) => {
943
+ let h = await createTemplateHarness(template, options.createBackend(), runSeed);
944
+ for (let i = 0; i < frames; i++) h.frame(i);
945
+ let result = [template.progress(h.scene), template.digest(h.scene, h.game)];
946
+ return h.game.dispose(), result;
947
+ };
948
+ describe(`genre template conformance: ${template.id}`, () => {
949
+ it("uses only the game API", async () => {
950
+ let fs = await import(
951
+ /* @vite-ignore */
952
+ FS_MODULE
953
+ ), root = options.sourceRoot ?? "", files = template.sources.map((path) => ({ path, source: fs.readFileSync(root + path, UTF8) })), result = checkGameSources({ profile: "game_api" }, files);
954
+ expect(result.violations).toEqual([]);
955
+ }), it("passes the kit publication gates", () => {
956
+ let failed = kitPublicationGates(template.economy).filter((g) => !g.passed);
957
+ expect(failed).toEqual([]);
958
+ }), it("reaches its progress condition under the playtest bot", async () => {
959
+ let [progress] = await play(options.playtestFrames, seed);
960
+ expect(progress).toBeGreaterThanOrEqual(options.progressTarget);
961
+ }), it("replays identically from the same seed and inputs", async () => {
962
+ let a = await play(options.playtestFrames, seed), b = await play(options.playtestFrames, seed);
963
+ expect(b).toEqual(a);
964
+ }), it(
965
+ "allocates nothing and never collects garbage on the frame path across a sustained run",
966
+ async () => {
967
+ let isolated = options.isolated;
968
+ if (isolated !== void 0) {
969
+ let warmup = options.warmupFrames ?? (3e4), frames = options.sustainedFrames ?? (6e3), boundary = options.boundaryBytesPerFrame ?? 0, budget = boundary + (1), { report, sites } = isolatedModule(isolatedSource(isolated), [String(seed), String(warmup), String(frames), String(budget)]);
970
+ options.report?.(template.id, report);
971
+ let busy = await busyMachine();
972
+ busy !== null && console.info(`${template.id}: collection count ${loadSkipNotice(busy)}`), boundary === 0 && busy === null && expect(report.collections).toBe(0), expect(report.bytesPerFrame, `allocation sites:${sites}`).toBeLessThan(budget);
973
+ return;
974
+ }
975
+ await withFrozenHostClock(async () => {
976
+ let meter = await options.heap();
977
+ if (!meter) return;
978
+ let h = await createTemplateHarness(template, options.createBackend(), seed), warmup = options.warmupFrames ?? (3e4);
979
+ await warmUp(warmup, (i) => h.frame(i));
980
+ let frames = options.sustainedFrames ?? (6e3), report = await measureSteadyAllocations(meter, frames, (i) => h.frame(warmup + i));
981
+ meter.dispose(), options.report?.(template.id, report);
982
+ let boundary = options.boundaryBytesPerFrame ?? 0, budget = boundary + (1), sites = "";
983
+ report.bytesPerFrame >= budget && (sites = (await profileAllocationSites(frames, (i) => h.frame(warmup + frames + i)) ?? []).map((s) => `
984
+ ${s.bytes} B ${s.stack}`).join("")), h.game.dispose();
985
+ let busy = await busyMachine();
986
+ busy !== null && console.info(`${template.id}: collection count ${loadSkipNotice(busy)}`), boundary === 0 && busy === null && expect(report.collections).toBe(0), expect(report.bytesPerFrame, `allocation sites:${sites}`).toBeLessThan(budget);
987
+ });
988
+ },
989
+ options.isolated === void 0 ? (12e4) : (6e5)
990
+ );
991
+ });
992
+ }
993
+
994
+ export { DEFAULT_MICROBENCH_BUDGETS_NS, busyMachine, createSustainedHarness, defineGameConformanceSuite, defineTemplateConformance, frameStamp, loadSkipNotice, measureSustainedAllocation, runMicrobench, withFrozenHostClock };