redscript-mc 2.6.2 → 3.0.0

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 (636) hide show
  1. package/.github/workflows/ci.yml +11 -0
  2. package/CHANGELOG.md +18 -9
  3. package/README-benchmarks.md +48 -0
  4. package/README-vscode-test.md +251 -0
  5. package/RELEASE_NOTES.md +74 -0
  6. package/ROADMAP.md +131 -167
  7. package/benchmarks/_shared.ts +468 -0
  8. package/benchmarks/baseline.json +2816 -0
  9. package/benchmarks/baseline.md +13 -0
  10. package/benchmarks/compiler-perf.report.json +207 -0
  11. package/benchmarks/compiler-perf.ts +76 -0
  12. package/benchmarks/results.md +13 -0
  13. package/benchmarks/stdlib-complexity.report.json +2606 -0
  14. package/benchmarks/stdlib-complexity.ts +54 -0
  15. package/benchmarks/stdlib-size.md +57 -0
  16. package/benchmarks/stdlib-size.ts +91 -0
  17. package/coverage-report.md +177 -0
  18. package/dist/src/__tests__/budget.test.js +4 -0
  19. package/dist/src/__tests__/cache/cache-behavior.test.d.ts +10 -0
  20. package/dist/src/__tests__/cache/cache-behavior.test.js +425 -0
  21. package/dist/src/__tests__/cache-extra.test.d.ts +5 -0
  22. package/dist/src/__tests__/cache-extra.test.js +211 -0
  23. package/dist/src/__tests__/cli-init.test.d.ts +1 -0
  24. package/dist/src/__tests__/cli-init.test.js +97 -0
  25. package/dist/src/__tests__/cli-publish.test.d.ts +9 -0
  26. package/dist/src/__tests__/cli-publish.test.js +189 -0
  27. package/dist/src/__tests__/cli.test.js +76 -0
  28. package/dist/src/__tests__/compile-preprocess.test.d.ts +11 -0
  29. package/dist/src/__tests__/compile-preprocess.test.js +328 -0
  30. package/dist/src/__tests__/compiler/break-stmt.test.d.ts +1 -0
  31. package/dist/src/__tests__/compiler/break-stmt.test.js +58 -0
  32. package/dist/src/__tests__/compiler/const-decl.test.d.ts +1 -0
  33. package/dist/src/__tests__/compiler/const-decl.test.js +123 -0
  34. package/dist/src/__tests__/compiler/continue-stmt.test.d.ts +1 -0
  35. package/dist/src/__tests__/compiler/continue-stmt.test.js +67 -0
  36. package/dist/src/__tests__/compiler/coroutine-extended.test.d.ts +17 -0
  37. package/dist/src/__tests__/compiler/coroutine-extended.test.js +565 -0
  38. package/dist/src/__tests__/compiler/deprecated.test.d.ts +4 -0
  39. package/dist/src/__tests__/compiler/deprecated.test.js +285 -0
  40. package/dist/src/__tests__/compiler/do-while.test.d.ts +1 -0
  41. package/dist/src/__tests__/compiler/do-while.test.js +120 -0
  42. package/dist/src/__tests__/compiler/enum-payload.test.d.ts +9 -0
  43. package/dist/src/__tests__/compiler/enum-payload.test.js +272 -0
  44. package/dist/src/__tests__/compiler/interface.test.d.ts +10 -0
  45. package/dist/src/__tests__/compiler/interface.test.js +258 -0
  46. package/dist/src/__tests__/compiler/labeled-loops.test.d.ts +1 -0
  47. package/dist/src/__tests__/compiler/labeled-loops.test.js +263 -0
  48. package/dist/src/__tests__/compiler/match-string.test.d.ts +1 -0
  49. package/dist/src/__tests__/compiler/match-string.test.js +43 -0
  50. package/dist/src/__tests__/compiler/memoize.test.d.ts +1 -0
  51. package/dist/src/__tests__/compiler/memoize.test.js +113 -0
  52. package/dist/src/__tests__/compiler/method-chain.test.d.ts +5 -0
  53. package/dist/src/__tests__/compiler/method-chain.test.js +115 -0
  54. package/dist/src/__tests__/compiler/module-import.test.d.ts +12 -0
  55. package/dist/src/__tests__/compiler/module-import.test.js +261 -0
  56. package/dist/src/__tests__/compiler/option-extensions.test.d.ts +6 -0
  57. package/dist/src/__tests__/compiler/option-extensions.test.js +191 -0
  58. package/dist/src/__tests__/compiler/profile-decorator.test.d.ts +1 -0
  59. package/dist/src/__tests__/compiler/profile-decorator.test.js +69 -0
  60. package/dist/src/__tests__/compiler/string-advanced.test.d.ts +7 -0
  61. package/dist/src/__tests__/compiler/string-advanced.test.js +281 -0
  62. package/dist/src/__tests__/compiler/struct-extends.test.d.ts +1 -0
  63. package/dist/src/__tests__/compiler/struct-extends.test.js +95 -0
  64. package/dist/src/__tests__/compiler/throttle-retry.test.d.ts +1 -0
  65. package/dist/src/__tests__/compiler/throttle-retry.test.js +166 -0
  66. package/dist/src/__tests__/compiler/tuple-type.test.d.ts +10 -0
  67. package/dist/src/__tests__/compiler/tuple-type.test.js +229 -0
  68. package/dist/src/__tests__/compiler/watch-decorator.test.d.ts +1 -0
  69. package/dist/src/__tests__/compiler/watch-decorator.test.js +65 -0
  70. package/dist/src/__tests__/config/project-config.test.d.ts +1 -0
  71. package/dist/src/__tests__/config/project-config.test.js +199 -0
  72. package/dist/src/__tests__/config-decorator.test.d.ts +8 -0
  73. package/dist/src/__tests__/config-decorator.test.js +142 -0
  74. package/dist/src/__tests__/diagnostics-extra.test.d.ts +6 -0
  75. package/dist/src/__tests__/diagnostics-extra.test.js +132 -0
  76. package/dist/src/__tests__/emit/compile-branches.test.d.ts +1 -0
  77. package/dist/src/__tests__/emit/compile-branches.test.js +123 -0
  78. package/dist/src/__tests__/emit/compile-coverage.test.d.ts +25 -0
  79. package/dist/src/__tests__/emit/compile-coverage.test.js +617 -0
  80. package/dist/src/__tests__/emit/compile-extra-branches.test.d.ts +12 -0
  81. package/dist/src/__tests__/emit/compile-extra-branches.test.js +225 -0
  82. package/dist/src/__tests__/emit/compile-mocked-branches.test.d.ts +0 -0
  83. package/dist/src/__tests__/emit/compile-mocked-branches.test.js +238 -0
  84. package/dist/src/__tests__/emit/execute-chain.test.d.ts +10 -0
  85. package/dist/src/__tests__/emit/execute-chain.test.js +94 -0
  86. package/dist/src/__tests__/emit/index.test.js +2 -1
  87. package/dist/src/__tests__/emit/modules-branches.test.d.ts +1 -0
  88. package/dist/src/__tests__/emit/modules-branches.test.js +88 -0
  89. package/dist/src/__tests__/emit/modules-coverage.test.d.ts +15 -0
  90. package/dist/src/__tests__/emit/modules-coverage.test.js +221 -0
  91. package/dist/src/__tests__/emit/modules-errors.test.d.ts +12 -0
  92. package/dist/src/__tests__/emit/modules-errors.test.js +169 -0
  93. package/dist/src/__tests__/emit/modules-rewrite.test.d.ts +17 -0
  94. package/dist/src/__tests__/emit/modules-rewrite.test.js +204 -0
  95. package/dist/src/__tests__/emit/source-map.test.d.ts +1 -0
  96. package/dist/src/__tests__/emit/source-map.test.js +167 -0
  97. package/dist/src/__tests__/enum.test.js +9 -4
  98. package/dist/src/__tests__/error-recovery.test.d.ts +7 -0
  99. package/dist/src/__tests__/error-recovery.test.js +217 -0
  100. package/dist/src/__tests__/events-types-extra.test.d.ts +10 -0
  101. package/dist/src/__tests__/events-types-extra.test.js +91 -0
  102. package/dist/src/__tests__/events-types.test.d.ts +4 -0
  103. package/dist/src/__tests__/events-types.test.js +56 -0
  104. package/dist/src/__tests__/formatter.test.js +13 -5
  105. package/dist/src/__tests__/hir/lower-extra.test.d.ts +9 -0
  106. package/dist/src/__tests__/hir/lower-extra.test.js +140 -0
  107. package/dist/src/__tests__/hir/monomorphize-extra.test.d.ts +15 -0
  108. package/dist/src/__tests__/hir/monomorphize-extra.test.js +200 -0
  109. package/dist/src/__tests__/hir/monomorphize-extra2.test.d.ts +16 -0
  110. package/dist/src/__tests__/hir/monomorphize-extra2.test.js +316 -0
  111. package/dist/src/__tests__/incremental.test.js +10 -2
  112. package/dist/src/__tests__/index-extra.test.d.ts +10 -0
  113. package/dist/src/__tests__/index-extra.test.js +71 -0
  114. package/dist/src/__tests__/lexer.test.js +2 -2
  115. package/dist/src/__tests__/lint/rules.test.d.ts +5 -0
  116. package/dist/src/__tests__/lint/rules.test.js +208 -0
  117. package/dist/src/__tests__/lir/lower.test.js +29 -0
  118. package/dist/src/__tests__/lir/verify.test.js +30 -0
  119. package/dist/src/__tests__/lsp/completion.test.d.ts +7 -0
  120. package/dist/src/__tests__/lsp/completion.test.js +583 -0
  121. package/dist/src/__tests__/lsp/definition.test.d.ts +7 -0
  122. package/dist/src/__tests__/lsp/definition.test.js +454 -0
  123. package/dist/src/__tests__/lsp/diagnostics.test.d.ts +10 -0
  124. package/dist/src/__tests__/lsp/diagnostics.test.js +98 -0
  125. package/dist/src/__tests__/lsp/hover-docs.test.d.ts +10 -0
  126. package/dist/src/__tests__/lsp/hover-docs.test.js +210 -0
  127. package/dist/src/__tests__/lsp.test.js +4 -1
  128. package/dist/src/__tests__/mc-integration/item-entity-events.test.js +4 -0
  129. package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +4 -0
  130. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.d.ts +13 -0
  131. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1227 -0
  132. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.d.ts +13 -0
  133. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1509 -0
  134. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.d.ts +14 -0
  135. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1374 -0
  136. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.d.ts +10 -0
  137. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +759 -0
  138. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.d.ts +13 -0
  139. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +855 -0
  140. package/dist/src/__tests__/mc-integration/stdlib-coverage.test.js +4 -0
  141. package/dist/src/__tests__/mc-integration/syntax-coverage.test.js +4 -0
  142. package/dist/src/__tests__/mc-validator-coverage.test.d.ts +13 -0
  143. package/dist/src/__tests__/mc-validator-coverage.test.js +296 -0
  144. package/dist/src/__tests__/mc-validator-extra.test.d.ts +13 -0
  145. package/dist/src/__tests__/mc-validator-extra.test.js +245 -0
  146. package/dist/src/__tests__/mir/lower-extra.test.d.ts +20 -0
  147. package/dist/src/__tests__/mir/lower-extra.test.js +361 -0
  148. package/dist/src/__tests__/mir/lower-extra2.test.d.ts +17 -0
  149. package/dist/src/__tests__/mir/lower-extra2.test.js +317 -0
  150. package/dist/src/__tests__/mir/lower-extra3.test.d.ts +19 -0
  151. package/dist/src/__tests__/mir/lower-extra3.test.js +249 -0
  152. package/dist/src/__tests__/mir/lower-extra4.test.d.ts +23 -0
  153. package/dist/src/__tests__/mir/lower-extra4.test.js +606 -0
  154. package/dist/src/__tests__/mir/lower-extra5.test.d.ts +25 -0
  155. package/dist/src/__tests__/mir/lower-extra5.test.js +543 -0
  156. package/dist/src/__tests__/mir/lower-extra6.test.d.ts +16 -0
  157. package/dist/src/__tests__/mir/lower-extra6.test.js +471 -0
  158. package/dist/src/__tests__/mir/lower-extra7.test.d.ts +35 -0
  159. package/dist/src/__tests__/mir/lower-extra7.test.js +921 -0
  160. package/dist/src/__tests__/mir/lower-extra8.test.d.ts +19 -0
  161. package/dist/src/__tests__/mir/lower-extra8.test.js +626 -0
  162. package/dist/src/__tests__/mir/lower-extra9.test.d.ts +14 -0
  163. package/dist/src/__tests__/mir/lower-extra9.test.js +717 -0
  164. package/dist/src/__tests__/optimizer/auto-inline.test.d.ts +1 -0
  165. package/dist/src/__tests__/optimizer/auto-inline.test.js +176 -0
  166. package/dist/src/__tests__/optimizer/cse.test.d.ts +4 -0
  167. package/dist/src/__tests__/optimizer/cse.test.js +178 -0
  168. package/dist/src/__tests__/optimizer/inline_fn.test.d.ts +1 -0
  169. package/dist/src/__tests__/optimizer/inline_fn.test.js +221 -0
  170. package/dist/src/__tests__/optimizer/licm.test.d.ts +1 -0
  171. package/dist/src/__tests__/optimizer/licm.test.js +244 -0
  172. package/dist/src/__tests__/optimizer/optimizer-extended.test.d.ts +12 -0
  173. package/dist/src/__tests__/optimizer/optimizer-extended.test.js +993 -0
  174. package/dist/src/__tests__/optimizer/strength-reduction.test.d.ts +1 -0
  175. package/dist/src/__tests__/optimizer/strength-reduction.test.js +86 -0
  176. package/dist/src/__tests__/optimizer/tco.test.d.ts +14 -0
  177. package/dist/src/__tests__/optimizer/tco.test.js +203 -0
  178. package/dist/src/__tests__/parser-coverage.test.d.ts +25 -0
  179. package/dist/src/__tests__/parser-coverage.test.js +491 -0
  180. package/dist/src/__tests__/parser-extra.test.d.ts +6 -0
  181. package/dist/src/__tests__/parser-extra.test.js +451 -0
  182. package/dist/src/__tests__/parser.test.js +12 -0
  183. package/dist/src/__tests__/repl-extra.test.d.ts +13 -0
  184. package/dist/src/__tests__/repl-extra.test.js +174 -0
  185. package/dist/src/__tests__/repl-server-extra.test.d.ts +10 -0
  186. package/dist/src/__tests__/repl-server-extra.test.js +161 -0
  187. package/dist/src/__tests__/repl-server.test.d.ts +6 -0
  188. package/dist/src/__tests__/repl-server.test.js +146 -0
  189. package/dist/src/__tests__/runtime-extra.test.d.ts +15 -0
  190. package/dist/src/__tests__/runtime-extra.test.js +732 -0
  191. package/dist/src/__tests__/singleton-decorator.test.d.ts +11 -0
  192. package/dist/src/__tests__/singleton-decorator.test.js +260 -0
  193. package/dist/src/__tests__/sourcemap.test.js +1 -1
  194. package/dist/src/__tests__/stdlib/advanced.test.d.ts +5 -0
  195. package/dist/src/__tests__/stdlib/advanced.test.js +301 -0
  196. package/dist/src/__tests__/stdlib/bigint.test.d.ts +4 -0
  197. package/dist/src/__tests__/stdlib/bigint.test.js +83 -0
  198. package/dist/src/__tests__/stdlib/bits.test.d.ts +4 -0
  199. package/dist/src/__tests__/stdlib/bits.test.js +96 -0
  200. package/dist/src/__tests__/stdlib/bossbar.test.d.ts +4 -0
  201. package/dist/src/__tests__/stdlib/bossbar.test.js +72 -0
  202. package/dist/src/__tests__/stdlib/color.test.d.ts +4 -0
  203. package/dist/src/__tests__/stdlib/color.test.js +84 -0
  204. package/dist/src/__tests__/stdlib/combat.test.d.ts +4 -0
  205. package/dist/src/__tests__/stdlib/combat.test.js +64 -0
  206. package/dist/src/__tests__/stdlib/cooldown.test.d.ts +4 -0
  207. package/dist/src/__tests__/stdlib/cooldown.test.js +64 -0
  208. package/dist/src/__tests__/stdlib/dialog.test.js +15 -7
  209. package/dist/src/__tests__/stdlib/ecs.test.d.ts +4 -0
  210. package/dist/src/__tests__/stdlib/ecs.test.js +81 -0
  211. package/dist/src/__tests__/stdlib/effects.test.d.ts +4 -0
  212. package/dist/src/__tests__/stdlib/effects.test.js +72 -0
  213. package/dist/src/__tests__/stdlib/events.test.d.ts +4 -0
  214. package/dist/src/__tests__/stdlib/events.test.js +55 -0
  215. package/dist/src/__tests__/stdlib/expr.test.d.ts +4 -0
  216. package/dist/src/__tests__/stdlib/expr.test.js +77 -0
  217. package/dist/src/__tests__/stdlib/fft.test.d.ts +4 -0
  218. package/dist/src/__tests__/stdlib/fft.test.js +82 -0
  219. package/dist/src/__tests__/stdlib/graph.test.d.ts +4 -0
  220. package/dist/src/__tests__/stdlib/graph.test.js +102 -0
  221. package/dist/src/__tests__/stdlib/interactions.test.d.ts +4 -0
  222. package/dist/src/__tests__/stdlib/interactions.test.js +60 -0
  223. package/dist/src/__tests__/stdlib/inventory.test.d.ts +4 -0
  224. package/dist/src/__tests__/stdlib/inventory.test.js +68 -0
  225. package/dist/src/__tests__/stdlib/linalg.test.d.ts +5 -0
  226. package/dist/src/__tests__/stdlib/linalg.test.js +78 -0
  227. package/dist/src/__tests__/stdlib/map.test.d.ts +1 -0
  228. package/dist/src/__tests__/stdlib/map.test.js +84 -0
  229. package/dist/src/__tests__/stdlib/math.test.js +19 -6
  230. package/dist/src/__tests__/stdlib/math_hp.test.d.ts +4 -0
  231. package/dist/src/__tests__/stdlib/math_hp.test.js +80 -0
  232. package/dist/src/__tests__/stdlib/mobs.test.d.ts +4 -0
  233. package/dist/src/__tests__/stdlib/mobs.test.js +61 -0
  234. package/dist/src/__tests__/stdlib/noise.test.d.ts +4 -0
  235. package/dist/src/__tests__/stdlib/noise.test.js +73 -0
  236. package/dist/src/__tests__/stdlib/ode.test.d.ts +4 -0
  237. package/dist/src/__tests__/stdlib/ode.test.js +68 -0
  238. package/dist/src/__tests__/stdlib/parabola.test.d.ts +4 -0
  239. package/dist/src/__tests__/stdlib/parabola.test.js +77 -0
  240. package/dist/src/__tests__/stdlib/particles.test.d.ts +4 -0
  241. package/dist/src/__tests__/stdlib/particles.test.js +68 -0
  242. package/dist/src/__tests__/stdlib/physics.test.d.ts +4 -0
  243. package/dist/src/__tests__/stdlib/physics.test.js +76 -0
  244. package/dist/src/__tests__/stdlib/player.test.d.ts +4 -0
  245. package/dist/src/__tests__/stdlib/player.test.js +64 -0
  246. package/dist/src/__tests__/stdlib/quaternion.test.d.ts +4 -0
  247. package/dist/src/__tests__/stdlib/quaternion.test.js +73 -0
  248. package/dist/src/__tests__/stdlib/queue.test.d.ts +1 -0
  249. package/dist/src/__tests__/stdlib/queue.test.js +97 -0
  250. package/dist/src/__tests__/stdlib/random.test.d.ts +4 -0
  251. package/dist/src/__tests__/stdlib/random.test.js +76 -0
  252. package/dist/src/__tests__/stdlib/result.test.d.ts +12 -0
  253. package/dist/src/__tests__/stdlib/result.test.js +329 -0
  254. package/dist/src/__tests__/stdlib/scheduler.test.js +19 -8
  255. package/dist/src/__tests__/stdlib/set_int.test.d.ts +1 -0
  256. package/dist/src/__tests__/stdlib/set_int.test.js +88 -0
  257. package/dist/src/__tests__/stdlib/sets.test.d.ts +6 -0
  258. package/dist/src/__tests__/stdlib/sets.test.js +60 -0
  259. package/dist/src/__tests__/stdlib/signal.test.d.ts +4 -0
  260. package/dist/src/__tests__/stdlib/signal.test.js +84 -0
  261. package/dist/src/__tests__/stdlib/spawn.test.d.ts +4 -0
  262. package/dist/src/__tests__/stdlib/spawn.test.js +68 -0
  263. package/dist/src/__tests__/stdlib/string.test.d.ts +12 -0
  264. package/dist/src/__tests__/stdlib/string.test.js +231 -0
  265. package/dist/src/__tests__/stdlib/strings.test.d.ts +4 -0
  266. package/dist/src/__tests__/stdlib/strings.test.js +83 -0
  267. package/dist/src/__tests__/stdlib/tags.test.d.ts +4 -0
  268. package/dist/src/__tests__/stdlib/tags.test.js +57 -0
  269. package/dist/src/__tests__/stdlib/teams.test.d.ts +4 -0
  270. package/dist/src/__tests__/stdlib/teams.test.js +72 -0
  271. package/dist/src/__tests__/stdlib/timer.test.d.ts +4 -0
  272. package/dist/src/__tests__/stdlib/timer.test.js +79 -0
  273. package/dist/src/__tests__/stdlib/vec.test.d.ts +5 -0
  274. package/dist/src/__tests__/stdlib/vec.test.js +94 -0
  275. package/dist/src/__tests__/stdlib/world.test.d.ts +4 -0
  276. package/dist/src/__tests__/stdlib/world.test.js +72 -0
  277. package/dist/src/__tests__/struct-display.test.d.ts +1 -0
  278. package/dist/src/__tests__/struct-display.test.js +64 -0
  279. package/dist/src/__tests__/test-framework/runner.test.d.ts +10 -0
  280. package/dist/src/__tests__/test-framework/runner.test.js +193 -0
  281. package/dist/src/__tests__/tuner/adapters.test.d.ts +14 -0
  282. package/dist/src/__tests__/tuner/adapters.test.js +194 -0
  283. package/dist/src/__tests__/tuner/simulator-extra.test.d.ts +4 -0
  284. package/dist/src/__tests__/tuner/simulator-extra.test.js +193 -0
  285. package/dist/src/__tests__/typechecker-coverage.test.d.ts +30 -0
  286. package/dist/src/__tests__/typechecker-coverage.test.js +627 -0
  287. package/dist/src/__tests__/typechecker.test.js +3 -3
  288. package/dist/src/__tests__/watch-decorator.test.d.ts +1 -0
  289. package/dist/src/__tests__/watch-decorator.test.js +54 -0
  290. package/dist/src/ast/types.d.ts +102 -3
  291. package/dist/src/cache/incremental.d.ts +13 -14
  292. package/dist/src/cache/incremental.js +106 -89
  293. package/dist/src/cache/index.d.ts +8 -2
  294. package/dist/src/cache/index.js +18 -6
  295. package/dist/src/cli.d.ts +1 -0
  296. package/dist/src/cli.js +466 -17
  297. package/dist/src/config/project-config.d.ts +29 -0
  298. package/dist/src/config/project-config.js +180 -0
  299. package/dist/src/diagnostics/index.d.ts +9 -0
  300. package/dist/src/diagnostics/index.js +18 -1
  301. package/dist/src/emit/compile.d.ts +10 -0
  302. package/dist/src/emit/compile.js +395 -50
  303. package/dist/src/emit/index.d.ts +40 -0
  304. package/dist/src/emit/index.js +307 -14
  305. package/dist/src/emit/modules.js +21 -3
  306. package/dist/src/emit/sourcemap.d.ts +23 -27
  307. package/dist/src/emit/sourcemap.js +52 -30
  308. package/dist/src/formatter/index.js +33 -8
  309. package/dist/src/hir/deprecated.d.ts +13 -0
  310. package/dist/src/hir/deprecated.js +218 -0
  311. package/dist/src/hir/lower.js +114 -8
  312. package/dist/src/hir/monomorphize.js +22 -2
  313. package/dist/src/hir/types.d.ts +65 -1
  314. package/dist/src/index.d.ts +6 -0
  315. package/dist/src/index.js +18 -3
  316. package/dist/src/lexer/index.d.ts +2 -1
  317. package/dist/src/lexer/index.js +39 -3
  318. package/dist/src/lint/index.d.ts +45 -0
  319. package/dist/src/lint/index.js +930 -0
  320. package/dist/src/lir/lower.js +29 -2
  321. package/dist/src/lir/types.d.ts +2 -0
  322. package/dist/src/lsp/server.js +92 -5
  323. package/dist/src/mir/lower.js +775 -34
  324. package/dist/src/mir/macro.js +36 -2
  325. package/dist/src/mir/types.d.ts +12 -0
  326. package/dist/src/mir/verify.js +9 -0
  327. package/dist/src/optimizer/auto-inline.d.ts +2 -0
  328. package/dist/src/optimizer/auto-inline.js +67 -0
  329. package/dist/src/optimizer/cse.d.ts +20 -0
  330. package/dist/src/optimizer/cse.js +234 -0
  331. package/dist/src/optimizer/inline.d.ts +26 -0
  332. package/dist/src/optimizer/inline.js +286 -0
  333. package/dist/src/optimizer/interprocedural.js +4 -0
  334. package/dist/src/optimizer/licm.d.ts +32 -0
  335. package/dist/src/optimizer/licm.js +371 -0
  336. package/dist/src/optimizer/pipeline.js +12 -2
  337. package/dist/src/optimizer/strength_reduction.d.ts +15 -0
  338. package/dist/src/optimizer/strength_reduction.js +90 -0
  339. package/dist/src/optimizer/tco.d.ts +53 -0
  340. package/dist/src/optimizer/tco.js +238 -0
  341. package/dist/src/parser/index.d.ts +32 -0
  342. package/dist/src/parser/index.js +421 -59
  343. package/dist/src/repl-server.d.ts +13 -0
  344. package/dist/src/repl-server.js +127 -0
  345. package/dist/src/structs/expand.d.ts +15 -0
  346. package/dist/src/structs/expand.js +46 -0
  347. package/dist/src/testing/runner.d.ts +40 -0
  348. package/dist/src/testing/runner.js +237 -0
  349. package/dist/src/typechecker/index.d.ts +3 -0
  350. package/dist/src/typechecker/index.js +254 -9
  351. package/dist/tsconfig.tsbuildinfo +1 -1
  352. package/doc-drafts/redscript-docs/docs/en/stdlib/graph.md +104 -0
  353. package/doc-drafts/redscript-docs/docs/en/stdlib/parabola.md +113 -0
  354. package/doc-drafts/redscript-docs/docs/en/stdlib/pathfind.md +104 -0
  355. package/doc-drafts/redscript-docs/docs/en/stdlib/physics.md +134 -0
  356. package/doc-drafts/redscript-docs/docs/en/stdlib/quaternion.md +135 -0
  357. package/doc-drafts/redscript-docs/docs/zh/stdlib/graph.md +104 -0
  358. package/doc-drafts/redscript-docs/docs/zh/stdlib/parabola.md +113 -0
  359. package/doc-drafts/redscript-docs/docs/zh/stdlib/pathfind.md +104 -0
  360. package/doc-drafts/redscript-docs/docs/zh/stdlib/physics.md +134 -0
  361. package/doc-drafts/redscript-docs/docs/zh/stdlib/quaternion.md +135 -0
  362. package/docs/stdlib/result.md +156 -0
  363. package/docs/stdlib/result.zh.md +156 -0
  364. package/editors/vscode/fixtures/test.mcrs +7 -0
  365. package/editors/vscode/out/extension.js +2095 -225
  366. package/editors/vscode/out/lsp-server.js +519 -51
  367. package/editors/vscode/package-lock.json +9 -4
  368. package/editors/vscode/package.json +1 -1
  369. package/examples/display-demo.mcrs +64 -0
  370. package/examples/game/racing.mcrs +301 -0
  371. package/examples/game/tower_defense.mcrs +311 -0
  372. package/examples/math/physics_sim.mcrs +322 -0
  373. package/examples/rpg/boss_fight.mcrs +313 -0
  374. package/examples/rpg/health_system.mcrs +237 -0
  375. package/examples/rpg/inventory.mcrs +265 -0
  376. package/examples/util/debug_hud.mcrs +279 -0
  377. package/jest.config.js +10 -0
  378. package/package.json +12 -3
  379. package/playground/index.html +823 -0
  380. package/scripts/gen-docs.ts +533 -0
  381. package/scripts/update-redscript-docs-stdlib.sh +770 -0
  382. package/src/__tests__/budget.test.ts +5 -0
  383. package/src/__tests__/cache/cache-behavior.test.ts +480 -0
  384. package/src/__tests__/cache-extra.test.ts +199 -0
  385. package/src/__tests__/cli-docs.test.ts +77 -0
  386. package/src/__tests__/cli-init.test.ts +91 -0
  387. package/src/__tests__/cli-publish.test.ts +190 -0
  388. package/src/__tests__/cli.test.ts +117 -1
  389. package/src/__tests__/compile-preprocess.test.ts +366 -0
  390. package/src/__tests__/compiler/break-stmt.test.ts +66 -0
  391. package/src/__tests__/compiler/const-decl.test.ts +141 -0
  392. package/src/__tests__/compiler/continue-stmt.test.ts +81 -0
  393. package/src/__tests__/compiler/coroutine-extended.test.ts +723 -0
  394. package/src/__tests__/compiler/deprecated.test.ts +305 -0
  395. package/src/__tests__/compiler/do-while.test.ts +130 -0
  396. package/src/__tests__/compiler/enum-payload.test.ts +299 -0
  397. package/src/__tests__/compiler/interface.test.ts +287 -0
  398. package/src/__tests__/compiler/labeled-loops.test.ts +279 -0
  399. package/src/__tests__/compiler/match-string.test.ts +45 -0
  400. package/src/__tests__/compiler/memoize.test.ts +126 -0
  401. package/src/__tests__/compiler/method-chain.test.ts +121 -0
  402. package/src/__tests__/compiler/module-import.test.ts +240 -0
  403. package/src/__tests__/compiler/option-extensions.test.ts +207 -0
  404. package/src/__tests__/compiler/profile-decorator.test.ts +79 -0
  405. package/src/__tests__/compiler/string-advanced.test.ts +310 -0
  406. package/src/__tests__/compiler/struct-extends.test.ts +109 -0
  407. package/src/__tests__/compiler/throttle-retry.test.ts +191 -0
  408. package/src/__tests__/compiler/tuple-type.test.ts +263 -0
  409. package/src/__tests__/compiler/watch-decorator.test.ts +72 -0
  410. package/src/__tests__/config/project-config.test.ts +181 -0
  411. package/src/__tests__/config-decorator.test.ts +157 -0
  412. package/src/__tests__/diagnostics-extra.test.ts +155 -0
  413. package/src/__tests__/emit/compile-branches.test.ts +135 -0
  414. package/src/__tests__/emit/compile-coverage.test.ts +696 -0
  415. package/src/__tests__/emit/compile-extra-branches.test.ts +228 -0
  416. package/src/__tests__/emit/compile-mocked-branches.test.ts +249 -0
  417. package/src/__tests__/emit/compile.test.ts +6 -1
  418. package/src/__tests__/emit/execute-chain.test.ts +114 -0
  419. package/src/__tests__/emit/index.test.ts +2 -1
  420. package/src/__tests__/emit/modules-branches.test.ts +90 -0
  421. package/src/__tests__/emit/modules-coverage.test.ts +241 -0
  422. package/src/__tests__/emit/modules-errors.test.ts +192 -0
  423. package/src/__tests__/emit/modules-rewrite.test.ts +232 -0
  424. package/src/__tests__/emit/source-map.test.ts +152 -0
  425. package/src/__tests__/enum.test.ts +9 -4
  426. package/src/__tests__/error-recovery.test.ts +226 -0
  427. package/src/__tests__/events-types-extra.test.ts +110 -0
  428. package/src/__tests__/events-types.test.ts +66 -0
  429. package/src/__tests__/formatter.test.ts +15 -5
  430. package/src/__tests__/generics.test.ts +16 -9
  431. package/src/__tests__/hir/lower-extra.test.ts +151 -0
  432. package/src/__tests__/hir/monomorphize-coverage.test.ts +432 -0
  433. package/src/__tests__/hir/monomorphize-extra.test.ts +220 -0
  434. package/src/__tests__/hir/monomorphize-extra2.test.ts +350 -0
  435. package/src/__tests__/impl.test.ts +12 -8
  436. package/src/__tests__/incremental.test.ts +10 -2
  437. package/src/__tests__/index-extra.test.ts +79 -0
  438. package/src/__tests__/lexer.test.ts +2 -2
  439. package/src/__tests__/lint/hir-coverage.test.ts +1716 -0
  440. package/src/__tests__/lint/rules-coverage.test.ts +598 -0
  441. package/src/__tests__/lint/rules.test.ts +230 -0
  442. package/src/__tests__/lir/lower.test.ts +33 -0
  443. package/src/__tests__/lir/verify.test.ts +33 -0
  444. package/src/__tests__/lsp/completion.test.ts +687 -0
  445. package/src/__tests__/lsp/definition.test.ts +499 -0
  446. package/src/__tests__/lsp/diagnostics.test.ts +108 -0
  447. package/src/__tests__/lsp/hover-docs.test.ts +222 -0
  448. package/src/__tests__/lsp.test.ts +4 -1
  449. package/src/__tests__/mc-integration/item-entity-events.test.ts +5 -0
  450. package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +5 -0
  451. package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1105 -0
  452. package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1366 -0
  453. package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1245 -0
  454. package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +755 -0
  455. package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +771 -0
  456. package/src/__tests__/mc-integration/stdlib-coverage.test.ts +5 -0
  457. package/src/__tests__/mc-integration/syntax-coverage.test.ts +5 -0
  458. package/src/__tests__/mc-validator-coverage.test.ts +325 -0
  459. package/src/__tests__/mc-validator-extra.test.ts +252 -0
  460. package/src/__tests__/mir/lower-extra.test.ts +402 -0
  461. package/src/__tests__/mir/lower-extra2.test.ts +348 -0
  462. package/src/__tests__/mir/lower-extra3.test.ts +277 -0
  463. package/src/__tests__/mir/lower-extra4.test.ts +636 -0
  464. package/src/__tests__/mir/lower-extra5.test.ts +612 -0
  465. package/src/__tests__/mir/lower-extra6.test.ts +520 -0
  466. package/src/__tests__/mir/lower-extra7.test.ts +1045 -0
  467. package/src/__tests__/mir/lower-extra8.test.ts +704 -0
  468. package/src/__tests__/mir/lower-extra9.test.ts +821 -0
  469. package/src/__tests__/optimizer/auto-inline.test.ts +206 -0
  470. package/src/__tests__/optimizer/cse.test.ts +195 -0
  471. package/src/__tests__/optimizer/inline_fn.test.ts +263 -0
  472. package/src/__tests__/optimizer/licm.test.ts +358 -0
  473. package/src/__tests__/optimizer/nbt-coalesce.test.ts +147 -0
  474. package/src/__tests__/optimizer/optimizer-extended.test.ts +1081 -0
  475. package/src/__tests__/optimizer/scoreboard-batch.test.ts +141 -0
  476. package/src/__tests__/optimizer/strength-reduction.test.ts +111 -0
  477. package/src/__tests__/optimizer/tco-coverage.test.ts +309 -0
  478. package/src/__tests__/optimizer/tco.test.ts +238 -0
  479. package/src/__tests__/option.test.ts +14 -7
  480. package/src/__tests__/parser-coverage.test.ts +576 -0
  481. package/src/__tests__/parser-extra.test.ts +531 -0
  482. package/src/__tests__/parser.test.ts +14 -0
  483. package/src/__tests__/repl-extra.test.ts +195 -0
  484. package/src/__tests__/repl-server-extra.test.ts +150 -0
  485. package/src/__tests__/repl-server.test.ts +122 -0
  486. package/src/__tests__/runtime-extra.test.ts +862 -0
  487. package/src/__tests__/singleton-decorator.test.ts +285 -0
  488. package/src/__tests__/sourcemap.test.ts +1 -1
  489. package/src/__tests__/stdlib/advanced.test.ts +312 -0
  490. package/src/__tests__/stdlib/bigint.test.ts +57 -0
  491. package/src/__tests__/stdlib/bits.test.ts +75 -0
  492. package/src/__tests__/stdlib/bossbar.test.ts +45 -0
  493. package/src/__tests__/stdlib/color.test.ts +60 -0
  494. package/src/__tests__/stdlib/combat.test.ts +35 -0
  495. package/src/__tests__/stdlib/cooldown.test.ts +35 -0
  496. package/src/__tests__/stdlib/dialog.test.ts +14 -6
  497. package/src/__tests__/stdlib/ecs.test.ts +54 -0
  498. package/src/__tests__/stdlib/effects.test.ts +45 -0
  499. package/src/__tests__/stdlib/events.test.ts +23 -0
  500. package/src/__tests__/stdlib/expr.test.ts +48 -0
  501. package/src/__tests__/stdlib/fft.test.ts +54 -0
  502. package/src/__tests__/stdlib/graph.test.ts +77 -0
  503. package/src/__tests__/stdlib/interactions.test.ts +30 -0
  504. package/src/__tests__/stdlib/inventory.test.ts +40 -0
  505. package/src/__tests__/stdlib/linalg.test.ts +52 -0
  506. package/src/__tests__/stdlib/map.test.ts +55 -0
  507. package/src/__tests__/stdlib/math.test.ts +19 -5
  508. package/src/__tests__/stdlib/math_hp.test.ts +55 -0
  509. package/src/__tests__/stdlib/mobs.test.ts +40 -0
  510. package/src/__tests__/stdlib/noise.test.ts +46 -0
  511. package/src/__tests__/stdlib/ode.test.ts +40 -0
  512. package/src/__tests__/stdlib/parabola.test.ts +51 -0
  513. package/src/__tests__/stdlib/particles.test.ts +40 -0
  514. package/src/__tests__/stdlib/physics.test.ts +50 -0
  515. package/src/__tests__/stdlib/player.test.ts +35 -0
  516. package/src/__tests__/stdlib/quaternion.test.ts +46 -0
  517. package/src/__tests__/stdlib/queue.test.ts +73 -0
  518. package/src/__tests__/stdlib/random.test.ts +50 -0
  519. package/src/__tests__/stdlib/result.test.ts +326 -0
  520. package/src/__tests__/stdlib/scheduler.test.ts +18 -7
  521. package/src/__tests__/stdlib/set_int.test.ts +62 -0
  522. package/src/__tests__/stdlib/sets.test.ts +28 -0
  523. package/src/__tests__/stdlib/signal.test.ts +60 -0
  524. package/src/__tests__/stdlib/spawn.test.ts +40 -0
  525. package/src/__tests__/stdlib/string.test.ts +224 -0
  526. package/src/__tests__/stdlib/strings.test.ts +55 -0
  527. package/src/__tests__/stdlib/tags.test.ts +32 -0
  528. package/src/__tests__/stdlib/teams.test.ts +45 -0
  529. package/src/__tests__/stdlib/timer.test.ts +53 -0
  530. package/src/__tests__/stdlib/vec.test.ts +72 -0
  531. package/src/__tests__/stdlib/world.test.ts +45 -0
  532. package/src/__tests__/struct-display.test.ts +69 -0
  533. package/src/__tests__/test-framework/runner.test.ts +208 -0
  534. package/src/__tests__/tuner/adapters.test.ts +232 -0
  535. package/src/__tests__/tuner/simulator-extra.test.ts +222 -0
  536. package/src/__tests__/tuple.test.ts +11 -4
  537. package/src/__tests__/typechecker-coverage.test.ts +671 -0
  538. package/src/__tests__/typechecker.test.ts +4 -3
  539. package/src/__tests__/watch-decorator.test.ts +59 -0
  540. package/src/ast/types.ts +65 -3
  541. package/src/cache/incremental.ts +128 -99
  542. package/src/cache/index.ts +35 -8
  543. package/src/cli.ts +538 -29
  544. package/src/config/project-config.ts +176 -0
  545. package/src/diagnostics/index.ts +22 -0
  546. package/src/docs.ts +98 -0
  547. package/src/emit/compile.ts +408 -51
  548. package/src/emit/index.ts +366 -18
  549. package/src/emit/modules.ts +19 -3
  550. package/src/emit/sourcemap.ts +64 -43
  551. package/src/formatter/index.ts +35 -8
  552. package/src/hir/deprecated.ts +212 -0
  553. package/src/hir/lower.ts +128 -8
  554. package/src/hir/monomorphize.ts +24 -2
  555. package/src/hir/types.ts +26 -1
  556. package/src/index.ts +23 -3
  557. package/src/lexer/index.ts +45 -6
  558. package/src/lint/index.ts +922 -0
  559. package/src/lir/lower.ts +30 -2
  560. package/src/lir/types.ts +4 -0
  561. package/src/lsp/server.ts +100 -1
  562. package/src/mir/lower.ts +785 -40
  563. package/src/mir/macro.ts +30 -2
  564. package/src/mir/types.ts +13 -0
  565. package/src/mir/verify.ts +10 -2
  566. package/src/optimizer/auto-inline.ts +86 -0
  567. package/src/optimizer/copy_prop.ts +2 -2
  568. package/src/optimizer/coroutine.ts +3 -3
  569. package/src/optimizer/cse.ts +205 -0
  570. package/src/optimizer/dce.ts +2 -2
  571. package/src/optimizer/inline.ts +335 -0
  572. package/src/optimizer/interprocedural.ts +5 -1
  573. package/src/optimizer/licm.ts +454 -0
  574. package/src/optimizer/nbt-coalesce.ts +109 -0
  575. package/src/optimizer/pipeline.ts +16 -2
  576. package/src/optimizer/scoreboard-batch.ts +52 -0
  577. package/src/optimizer/strength_reduction.ts +95 -0
  578. package/src/optimizer/tco.ts +267 -0
  579. package/src/optimizer/unroll.ts +2 -2
  580. package/src/parser/index.ts +426 -53
  581. package/src/repl-server.ts +102 -0
  582. package/src/stdlib/advanced.mcrs +271 -101
  583. package/src/stdlib/bigint.mcrs +97 -11
  584. package/src/stdlib/bits.mcrs +75 -12
  585. package/src/stdlib/bossbar.mcrs +37 -8
  586. package/src/stdlib/calculus.mcrs +82 -26
  587. package/src/stdlib/color.mcrs +98 -16
  588. package/src/stdlib/combat.mcrs +23 -5
  589. package/src/stdlib/cooldown.mcrs +19 -0
  590. package/src/stdlib/dialog.mcrs +45 -7
  591. package/src/stdlib/easing.mcrs +132 -12
  592. package/src/stdlib/ecs.mcrs +142 -25
  593. package/src/stdlib/effects.mcrs +88 -12
  594. package/src/stdlib/events.mcrs +21 -2
  595. package/src/stdlib/expr.mcrs +18 -3
  596. package/src/stdlib/fft.mcrs +66 -56
  597. package/src/stdlib/geometry.mcrs +137 -39
  598. package/src/stdlib/graph.mcrs +73 -0
  599. package/src/stdlib/heap.mcrs +49 -8
  600. package/src/stdlib/i18n/zh.yaml +2891 -0
  601. package/src/stdlib/interactions.mcrs +43 -20
  602. package/src/stdlib/inventory.mcrs +14 -3
  603. package/src/stdlib/linalg.mcrs +185 -30
  604. package/src/stdlib/list.mcrs +168 -18
  605. package/src/stdlib/map.mcrs +112 -0
  606. package/src/stdlib/math.mcrs +68 -18
  607. package/src/stdlib/math_hp.mcrs +124 -33
  608. package/src/stdlib/matrix.mcrs +133 -20
  609. package/src/stdlib/mobs.mcrs +87 -0
  610. package/src/stdlib/noise.mcrs +65 -21
  611. package/src/stdlib/ode.mcrs +96 -0
  612. package/src/stdlib/parabola.mcrs +104 -29
  613. package/src/stdlib/particles.mcrs +78 -21
  614. package/src/stdlib/pathfind.mcrs +89 -35
  615. package/src/stdlib/physics.mcrs +134 -26
  616. package/src/stdlib/player.mcrs +18 -0
  617. package/src/stdlib/quaternion.mcrs +213 -9
  618. package/src/stdlib/queue.mcrs +123 -0
  619. package/src/stdlib/random.mcrs +63 -18
  620. package/src/stdlib/result.mcrs +111 -0
  621. package/src/stdlib/scheduler.mcrs +59 -10
  622. package/src/stdlib/set_int.mcrs +240 -0
  623. package/src/stdlib/sets.mcrs +49 -19
  624. package/src/stdlib/signal.mcrs +151 -79
  625. package/src/stdlib/sort.mcrs +44 -24
  626. package/src/stdlib/spawn.mcrs +30 -7
  627. package/src/stdlib/state.mcrs +40 -5
  628. package/src/stdlib/strings.mcrs +131 -3
  629. package/src/stdlib/tags.mcrs +2 -2
  630. package/src/stdlib/teams.mcrs +22 -10
  631. package/src/stdlib/timer.mcrs +36 -6
  632. package/src/stdlib/vec.mcrs +44 -9
  633. package/src/stdlib/world.mcrs +57 -25
  634. package/src/structs/expand.ts +64 -0
  635. package/src/testing/runner.ts +271 -0
  636. package/src/typechecker/index.ts +273 -9
@@ -0,0 +1,755 @@
1
+ /**
2
+ * RedScript MC Integration Tests — stdlib coverage 6
3
+ *
4
+ * Completes real-MC coverage for interactions / inventory / world /
5
+ * particles / spawn stdlib modules against a Paper 1.21.4 server with
6
+ * TestHarnessPlugin. Player-dependent cases use TestBot when available.
7
+ *
8
+ * Run: MC_SERVER_DIR=~/mc-test-server npx jest stdlib-coverage-6 --testTimeout=120000
9
+ */
10
+
11
+ import * as fs from 'fs'
12
+ import * as path from 'path'
13
+ import { compile } from '../../compile'
14
+ import { MCTestClient } from '../../mc-test/client'
15
+
16
+ const MC_HOST = process.env.MC_HOST ?? 'localhost'
17
+ const MC_PORT = parseInt(process.env.MC_PORT ?? '25561')
18
+ const MC_SERVER_DIR = process.env.MC_SERVER_DIR ?? path.join(process.env.HOME!, 'mc-test-server')
19
+ const DATAPACK_DIR = path.join(MC_SERVER_DIR, 'world', 'datapacks', 'redscript-test6')
20
+ const STDLIB_DIR = path.join(__dirname, '../../stdlib')
21
+
22
+ const BOT_URL = 'http://localhost:25562'
23
+ const BOT_NAME = 'TestBot'
24
+
25
+ let serverOnline = false
26
+ let botOnline = false
27
+ let mc: MCTestClient
28
+
29
+ function writeFixture(source: string, namespace: string, librarySources: string[] = []): void {
30
+ fs.mkdirSync(DATAPACK_DIR, { recursive: true })
31
+ if (!fs.existsSync(path.join(DATAPACK_DIR, 'pack.mcmeta'))) {
32
+ fs.writeFileSync(
33
+ path.join(DATAPACK_DIR, 'pack.mcmeta'),
34
+ JSON.stringify({ pack: { pack_format: 48, description: 'RedScript integration tests 6' } })
35
+ )
36
+ }
37
+
38
+ const result = compile(source, { namespace, librarySources })
39
+
40
+ for (const file of result.files) {
41
+ if (file.path === 'pack.mcmeta') continue
42
+ const filePath = path.join(DATAPACK_DIR, file.path)
43
+ fs.mkdirSync(path.dirname(filePath), { recursive: true })
44
+
45
+ if (file.path.includes('data/minecraft/tags/') && fs.existsSync(filePath)) {
46
+ const existing = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
47
+ const incoming = JSON.parse(file.content)
48
+ const merged = { values: [...new Set([...(existing.values ?? []), ...(incoming.values ?? [])])] }
49
+ fs.writeFileSync(filePath, JSON.stringify(merged, null, 2))
50
+ } else {
51
+ fs.writeFileSync(filePath, file.content)
52
+ }
53
+ }
54
+ }
55
+
56
+ function readStdlib(name: string): string {
57
+ return fs.readFileSync(path.join(STDLIB_DIR, name), 'utf-8')
58
+ }
59
+
60
+ async function botGet(endpoint: string): Promise<any> {
61
+ const res = await fetch(`${BOT_URL}${endpoint}`)
62
+ return res.json()
63
+ }
64
+
65
+ async function botPost(endpoint: string, body: object = {}): Promise<any> {
66
+ const res = await fetch(`${BOT_URL}${endpoint}`, {
67
+ method: 'POST',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ body: JSON.stringify(body),
70
+ })
71
+ return res.json()
72
+ }
73
+
74
+ async function botItemCount(name: string): Promise<number> {
75
+ const data = await botGet(`/inventory/count?name=${encodeURIComponent(name)}`)
76
+ return (data as any).count ?? 0
77
+ }
78
+
79
+ async function clearBotInventory(): Promise<void> {
80
+ if (!serverOnline || !botOnline) return
81
+ await mc.command(`clear ${BOT_NAME}`)
82
+ await botPost('/wait', { ticks: 5 })
83
+ }
84
+
85
+ async function getSingleEntity(selector: string) {
86
+ const entities = await mc.entities(selector)
87
+ expect(entities.length).toBe(1)
88
+ return entities[0]
89
+ }
90
+
91
+ beforeAll(async () => {
92
+ if (process.env.MC_OFFLINE === 'true') {
93
+ console.warn('⚠ MC_OFFLINE=true — skipping stdlib coverage 6 integration tests')
94
+ return
95
+ }
96
+
97
+ mc = new MCTestClient(MC_HOST, MC_PORT)
98
+
99
+ try {
100
+ const deadline = Date.now() + 10_000
101
+ while (Date.now() < deadline) {
102
+ if (await mc.isOnline()) { serverOnline = true; break }
103
+ await new Promise(r => setTimeout(r, 1000))
104
+ }
105
+ } catch {
106
+ serverOnline = false
107
+ }
108
+
109
+ if (!serverOnline) {
110
+ console.warn(`⚠ MC server not running at ${MC_HOST}:${MC_PORT} — skipping stdlib coverage 6 tests`)
111
+ return
112
+ }
113
+
114
+ try {
115
+ const status: any = await botGet('/status')
116
+ botOnline = status.connected === true
117
+ } catch {
118
+ botOnline = false
119
+ }
120
+
121
+ if (!botOnline) {
122
+ console.warn('⚠ TestBot not running — player-dependent coverage 6 tests will be skipped')
123
+ }
124
+
125
+ for (const tagFile of [
126
+ 'data/minecraft/tags/function/tick.json',
127
+ 'data/minecraft/tags/function/load.json',
128
+ 'data/minecraft/tags/functions/tick.json',
129
+ 'data/minecraft/tags/functions/load.json',
130
+ ]) {
131
+ const p = path.join(DATAPACK_DIR, tagFile)
132
+ if (fs.existsSync(p)) fs.writeFileSync(p, JSON.stringify({ values: [] }, null, 2))
133
+ }
134
+
135
+ await mc.command('/scoreboard objectives add sc6_result dummy').catch(() => {})
136
+ await mc.command('/scoreboard objectives add rs.last_sneak dummy').catch(() => {})
137
+ await mc.command('/scoreboard objectives add rs.tick dummy').catch(() => {})
138
+
139
+ const MATH_SRC = readStdlib('math.mcrs')
140
+ const INTERACTIONS_SRC = readStdlib('interactions.mcrs')
141
+ const INVENTORY_SRC = readStdlib('inventory.mcrs')
142
+ const WORLD_SRC = readStdlib('world.mcrs')
143
+ const PARTICLES_SRC = readStdlib('particles.mcrs')
144
+ const SPAWN_SRC = readStdlib('spawn.mcrs')
145
+
146
+ writeFixture(`
147
+ namespace stdlib_interactions6_test
148
+
149
+ fn test_interactions_init() {
150
+ interactions_init();
151
+ scoreboard_set("#inter_init_done", #sc6_result, 1);
152
+ }
153
+
154
+ fn test_example_right_click() {
155
+ raw("scoreboard players set ${BOT_NAME} rs.click 1");
156
+ example_right_click();
157
+ scoreboard_set("#inter_example_click", #sc6_result, 1);
158
+ }
159
+
160
+ fn test_is_sneaking() {
161
+ raw("scoreboard players set ${BOT_NAME} rs.sneak 5");
162
+ let r: int = is_sneaking(@a[name=${BOT_NAME}]);
163
+ scoreboard_set("#inter_is_sneaking", #sc6_result, r);
164
+ }
165
+
166
+ fn test_on_sneak_start() {
167
+ raw("scoreboard players set ${BOT_NAME} rs.sneak 1");
168
+ on_sneak_start();
169
+ scoreboard_set("#inter_sneak_start_done", #sc6_result, 1);
170
+ }
171
+
172
+ fn test_check_look_up() {
173
+ check_look_up();
174
+ scoreboard_set("#inter_look_up_done", #sc6_result, 1);
175
+ }
176
+
177
+ fn test_check_look_down() {
178
+ check_look_down();
179
+ scoreboard_set("#inter_look_down_done", #sc6_result, 1);
180
+ }
181
+
182
+ fn test_check_look_straight() {
183
+ check_look_straight();
184
+ scoreboard_set("#inter_look_straight_done", #sc6_result, 1);
185
+ }
186
+
187
+ fn test_check_holding_item() {
188
+ check_holding_item("diamond_sword");
189
+ scoreboard_set("#inter_holding_done", #sc6_result, 1);
190
+ }
191
+
192
+ fn test_on_right_click() {
193
+ raw("scoreboard players set ${BOT_NAME} rs.click 2");
194
+ on_right_click("ignored");
195
+ scoreboard_set("#inter_right_click_done", #sc6_result, 1);
196
+ }
197
+
198
+ fn test_on_sneak_click_combo() {
199
+ raw("scoreboard players set ${BOT_NAME} rs.click 1");
200
+ raw("scoreboard players set ${BOT_NAME} rs.sneak 3");
201
+ on_sneak_click();
202
+ scoreboard_set("#inter_sneak_click_done", #sc6_result, 1);
203
+ }
204
+
205
+ fn test_on_sneak_click_normal() {
206
+ raw("scoreboard players set ${BOT_NAME} rs.click 1");
207
+ raw("scoreboard players set ${BOT_NAME} rs.sneak 0");
208
+ on_sneak_click();
209
+ scoreboard_set("#inter_click_only_done", #sc6_result, 1);
210
+ }
211
+
212
+ fn test_on_double_sneak() {
213
+ raw("scoreboard players set ${BOT_NAME} rs.sneak 1");
214
+ raw("scoreboard players set ${BOT_NAME} rs.last_sneak 100");
215
+ raw("scoreboard players set ${BOT_NAME} rs.tick 105");
216
+ on_double_sneak();
217
+ scoreboard_set("#inter_double_sneak_done", #sc6_result, 1);
218
+ }
219
+ `, 'stdlib_interactions6_test', [INTERACTIONS_SRC])
220
+
221
+ writeFixture(`
222
+ namespace stdlib_inventory6_test
223
+
224
+ fn test_clear_inventory() {
225
+ clear_inventory(@a[name=${BOT_NAME}]);
226
+ scoreboard_set("#inventory_clear_done", #sc6_result, 1);
227
+ }
228
+
229
+ fn test_give_kit_warrior() {
230
+ give_kit_warrior(@a[name=${BOT_NAME}]);
231
+ scoreboard_set("#inventory_warrior_done", #sc6_result, 1);
232
+ }
233
+
234
+ fn test_give_kit_archer() {
235
+ give_kit_archer(@a[name=${BOT_NAME}]);
236
+ scoreboard_set("#inventory_archer_done", #sc6_result, 1);
237
+ }
238
+
239
+ fn test_give_kit_mage() {
240
+ give_kit_mage(@a[name=${BOT_NAME}]);
241
+ scoreboard_set("#inventory_mage_done", #sc6_result, 1);
242
+ }
243
+
244
+ fn test_remove_item() {
245
+ remove_item(@a[name=${BOT_NAME}], "minecraft:arrow");
246
+ scoreboard_set("#inventory_remove_done", #sc6_result, 1);
247
+ }
248
+ `, 'stdlib_inventory6_test', [INVENTORY_SRC])
249
+
250
+ writeFixture(`
251
+ namespace stdlib_world6_test
252
+
253
+ fn test_set_noon() {
254
+ set_noon();
255
+ raw("execute store result score #world_time_noon sc6_result run time query daytime");
256
+ }
257
+
258
+ fn test_set_midnight() {
259
+ set_midnight();
260
+ raw("execute store result score #world_time_midnight sc6_result run time query daytime");
261
+ }
262
+
263
+ fn test_weather_rain() {
264
+ weather_rain();
265
+ scoreboard_set("#weather_rain_done", #sc6_result, 1);
266
+ }
267
+
268
+ fn test_weather_thunder() {
269
+ weather_thunder();
270
+ scoreboard_set("#weather_thunder_done", #sc6_result, 1);
271
+ }
272
+
273
+ fn test_disable_mob_griefing() {
274
+ disable_mob_griefing();
275
+ scoreboard_set("#mob_griefing_done", #sc6_result, 1);
276
+ }
277
+
278
+ fn test_disable_fire_spread() {
279
+ disable_fire_spread();
280
+ scoreboard_set("#fire_tick_done", #sc6_result, 1);
281
+ }
282
+
283
+ fn test_barrier_wall() {
284
+ barrier_wall(0, 70, 0, 1, 71, 1);
285
+ scoreboard_set("#barrier_done", #sc6_result, 1);
286
+ }
287
+
288
+ fn test_clear_area() {
289
+ clear_area(0, 70, 0, 1, 71, 1);
290
+ scoreboard_set("#clear_area_done", #sc6_result, 1);
291
+ }
292
+
293
+ fn test_glass_box() {
294
+ glass_box(0, 70, 0, 2, 72, 2);
295
+ scoreboard_set("#glass_box_done", #sc6_result, 1);
296
+ }
297
+
298
+ fn test_sun_altitude_midnight() {
299
+ let alt: int = sun_altitude(18000);
300
+ scoreboard_set("#sun_alt_midnight", #sc6_result, alt);
301
+ }
302
+ `, 'stdlib_world6_test', [WORLD_SRC, MATH_SRC])
303
+
304
+ writeFixture(`
305
+ namespace stdlib_particles6_test
306
+
307
+ fn test_smoke() {
308
+ smoke(0, 70, 0);
309
+ scoreboard_set("#particles_smoke_done", #sc6_result, 1);
310
+ }
311
+
312
+ fn test_angry_happy() {
313
+ angry_at(0, 70, 0);
314
+ happy_at(1, 70, 0);
315
+ scoreboard_set("#particles_angry_happy_done", #sc6_result, 1);
316
+ }
317
+
318
+ fn test_totem_end() {
319
+ totem_at(0, 70, 0);
320
+ end_sparkles_at(1, 70, 0);
321
+ scoreboard_set("#particles_totem_end_done", #sc6_result, 1);
322
+ }
323
+
324
+ fn test_particle_at_fx() {
325
+ particle_at_fx(125, 7050, -75, "minecraft:flame");
326
+ scoreboard_set("#particles_fx_done", #sc6_result, 1);
327
+ }
328
+
329
+ fn test_draw_line_2d() {
330
+ draw_line_2d(0, 7000, 200, 7200, 4, 0, "minecraft:flame");
331
+ scoreboard_set("#particles_line_done", #sc6_result, 1);
332
+ }
333
+
334
+ fn test_draw_circle() {
335
+ draw_circle(0, 70, 0, 200, 8, "minecraft:heart");
336
+ scoreboard_set("#particles_circle_done", #sc6_result, 1);
337
+ }
338
+
339
+ fn test_draw_helix() {
340
+ draw_helix(0, 70, 0, 2, 4, 2, 8, "minecraft:portal");
341
+ scoreboard_set("#particles_helix_done", #sc6_result, 1);
342
+ }
343
+
344
+ fn test_particle_dot() {
345
+ particle_dot(0, 70, 0, "minecraft:happy_villager");
346
+ scoreboard_set("#particles_dot_done", #sc6_result, 1);
347
+ }
348
+ `, 'stdlib_particles6_test', [PARTICLES_SRC, MATH_SRC])
349
+
350
+ writeFixture(`
351
+ namespace stdlib_spawn6_test
352
+
353
+ fn test_teleport_to_entity() {
354
+ teleport_to_entity(@e[tag=sc6_spawn_src,limit=1], @e[tag=sc6_spawn_dst,limit=1]);
355
+ scoreboard_set("#spawn_tp_entity_done", #sc6_result, 1);
356
+ }
357
+
358
+ fn test_spread_players() {
359
+ spread_players(0, 0, 10);
360
+ scoreboard_set("#spawn_spread_done", #sc6_result, 1);
361
+ }
362
+
363
+ fn test_launch_up() {
364
+ launch_up(@e[tag=sc6_launch_target,limit=1], 5);
365
+ scoreboard_set("#spawn_launch_done", #sc6_result, 1);
366
+ }
367
+ `, 'stdlib_spawn6_test', [SPAWN_SRC])
368
+
369
+ await mc.reload()
370
+ await mc.ticks(20)
371
+ console.log(' stdlib-coverage-6 setup complete.')
372
+ }, 60_000)
373
+
374
+ describe('stdlib coverage 6 — interactions', () => {
375
+ test('interactions_init creates scoreboard objectives', async () => {
376
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
377
+
378
+ await mc.command('/scoreboard players set #inter_init_done sc6_result 0')
379
+ await mc.command('/function stdlib_interactions6_test:test_interactions_init')
380
+ await mc.ticks(3)
381
+
382
+ const ran = await mc.scoreboard('#inter_init_done', 'sc6_result')
383
+ await mc.command('/scoreboard players set #probe_click rs.click 7')
384
+ await mc.command('/scoreboard players set #probe_sneak rs.sneak 8')
385
+ await mc.command('/scoreboard players set #probe_attack rs.attack 9')
386
+
387
+ expect(ran).toBe(1)
388
+ expect(await mc.scoreboard('#probe_click', 'rs.click')).toBe(7)
389
+ expect(await mc.scoreboard('#probe_sneak', 'rs.sneak')).toBe(8)
390
+ expect(await mc.scoreboard('#probe_attack', 'rs.attack')).toBe(9)
391
+ }, 30_000)
392
+
393
+ test('example_right_click consumes click and emits chat', async () => {
394
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
395
+
396
+ await mc.reset()
397
+ await mc.command(`/scoreboard players set ${BOT_NAME} rs.click 0`)
398
+ await mc.command('/function stdlib_interactions6_test:test_example_right_click')
399
+ await mc.ticks(3)
400
+
401
+ const remaining = await mc.scoreboard(BOT_NAME, 'rs.click')
402
+ const chat = await mc.chatLast(10)
403
+ expect(remaining).toBe(0)
404
+ expect(chat.some(msg => msg.message.includes('Player right clicked!'))).toBe(true)
405
+ }, 30_000)
406
+
407
+ test('is_sneaking returns 1 when rs.sneak > 0', async () => {
408
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
409
+
410
+ await mc.command('/scoreboard players set #inter_is_sneaking sc6_result 0')
411
+ await mc.command('/function stdlib_interactions6_test:test_is_sneaking')
412
+ await mc.ticks(3)
413
+
414
+ const result = await mc.scoreboard('#inter_is_sneaking', 'sc6_result')
415
+ expect(result).toBe(1)
416
+ }, 30_000)
417
+
418
+ test('on_sneak_start tags only fresh sneakers', async () => {
419
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
420
+
421
+ await mc.command(`tag ${BOT_NAME} remove rs.sneak_start`).catch(() => {})
422
+ await mc.command('/function stdlib_interactions6_test:test_on_sneak_start')
423
+ await mc.ticks(3)
424
+
425
+ const bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
426
+ expect(bot.tags).toContain('rs.sneak_start')
427
+ }, 30_000)
428
+
429
+ test('check_look_up/down/straight set tags from player pitch', async () => {
430
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
431
+
432
+ await mc.command(`tag ${BOT_NAME} remove rs.look_up`).catch(() => {})
433
+ await mc.command(`tag ${BOT_NAME} remove rs.look_down`).catch(() => {})
434
+ await mc.command(`tag ${BOT_NAME} remove rs.look_straight`).catch(() => {})
435
+
436
+ await mc.command(`tp ${BOT_NAME} 0 64 0 0 -60`)
437
+ await mc.command('/function stdlib_interactions6_test:test_check_look_up')
438
+ await mc.ticks(2)
439
+ let bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
440
+ expect(bot.tags).toContain('rs.look_up')
441
+
442
+ await mc.command(`tp ${BOT_NAME} 0 64 0 0 60`)
443
+ await mc.command('/function stdlib_interactions6_test:test_check_look_down')
444
+ await mc.ticks(2)
445
+ bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
446
+ expect(bot.tags).toContain('rs.look_down')
447
+
448
+ await mc.command(`tp ${BOT_NAME} 0 64 0 0 0`)
449
+ await mc.command('/function stdlib_interactions6_test:test_check_look_straight')
450
+ await mc.ticks(2)
451
+ bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
452
+ expect(bot.tags).toContain('rs.look_straight')
453
+ }, 30_000)
454
+
455
+ test('check_holding_item advertises manual execute-if-data path', async () => {
456
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
457
+
458
+ await mc.reset()
459
+ await mc.command('/scoreboard players set #inter_holding_done sc6_result 0')
460
+ await mc.command('/function stdlib_interactions6_test:test_check_holding_item')
461
+ await mc.ticks(2)
462
+
463
+ // Verify the function ran without errors (scoreboard flag set to 1)
464
+ const ran = await mc.scoreboard('#inter_holding_done', 'sc6_result')
465
+ expect(ran).toBe(1)
466
+ }, 30_000)
467
+
468
+ test('on_right_click resets rs.click and tags player', async () => {
469
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
470
+
471
+ await mc.command(`tag ${BOT_NAME} remove rs.clicked`).catch(() => {})
472
+ await mc.command(`/scoreboard players set ${BOT_NAME} rs.click 0`)
473
+ await mc.command('/function stdlib_interactions6_test:test_on_right_click')
474
+ await mc.ticks(3)
475
+
476
+ const bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
477
+ const remaining = await mc.scoreboard(BOT_NAME, 'rs.click')
478
+ expect(bot.tags).toContain('rs.clicked')
479
+ expect(remaining).toBe(0)
480
+ }, 30_000)
481
+
482
+ test('on_sneak_click tags combo users and normal clickers separately', async () => {
483
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
484
+
485
+ await mc.command(`tag ${BOT_NAME} remove rs.sneak_click`).catch(() => {})
486
+ await mc.command(`tag ${BOT_NAME} remove rs.clicked`).catch(() => {})
487
+ await mc.command('/function stdlib_interactions6_test:test_on_sneak_click_combo')
488
+ await mc.ticks(3)
489
+
490
+ let bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
491
+ expect(bot.tags).toContain('rs.sneak_click')
492
+
493
+ await mc.command(`tag ${BOT_NAME} remove rs.sneak_click`).catch(() => {})
494
+ await mc.command(`tag ${BOT_NAME} remove rs.clicked`).catch(() => {})
495
+ await mc.command('/function stdlib_interactions6_test:test_on_sneak_click_normal')
496
+ await mc.ticks(3)
497
+
498
+ bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
499
+ expect(bot.tags).toContain('rs.clicked')
500
+ expect(bot.tags).not.toContain('rs.sneak_click')
501
+ }, 30_000)
502
+
503
+ test('on_double_sneak tags player when within the double-tap window', async () => {
504
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
505
+
506
+ await mc.command(`tag ${BOT_NAME} remove rs.double_sneak`).catch(() => {})
507
+ await mc.command('/function stdlib_interactions6_test:test_on_double_sneak')
508
+ await mc.ticks(3)
509
+
510
+ const bot = await getSingleEntity(`@a[name=${BOT_NAME}]`)
511
+ expect(bot.tags).toContain('rs.double_sneak')
512
+ }, 30_000)
513
+ })
514
+
515
+ describe('stdlib coverage 6 — inventory', () => {
516
+ beforeEach(async () => {
517
+ if (!serverOnline || !botOnline) return
518
+ await clearBotInventory()
519
+ })
520
+
521
+ test('clear_inventory removes items from TestBot', async () => {
522
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
523
+
524
+ await mc.command(`give ${BOT_NAME} minecraft:diamond 4`)
525
+ await botPost('/wait', { ticks: 10 })
526
+ expect(await botItemCount('diamond')).toBe(4)
527
+
528
+ await mc.command('/function stdlib_inventory6_test:test_clear_inventory')
529
+ await botPost('/wait', { ticks: 10 })
530
+
531
+ expect(await botItemCount('diamond')).toBe(0)
532
+ }, 30_000)
533
+
534
+ test('give_kit_warrior gives sword, armor, shield, and food', async () => {
535
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
536
+
537
+ await mc.command('/function stdlib_inventory6_test:test_give_kit_warrior')
538
+ await botPost('/wait', { ticks: 10 })
539
+
540
+ expect(await botItemCount('iron_sword')).toBe(1)
541
+ expect(await botItemCount('iron_chestplate')).toBe(1)
542
+ expect(await botItemCount('iron_leggings')).toBe(1)
543
+ expect(await botItemCount('iron_boots')).toBe(1)
544
+ expect(await botItemCount('shield')).toBe(1)
545
+ expect(await botItemCount('cooked_beef')).toBe(16)
546
+ }, 30_000)
547
+
548
+ test('give_kit_archer gives bow, arrows, armor, and food', async () => {
549
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
550
+
551
+ await mc.command('/function stdlib_inventory6_test:test_give_kit_archer')
552
+ await botPost('/wait', { ticks: 10 })
553
+
554
+ expect(await botItemCount('bow')).toBe(1)
555
+ expect(await botItemCount('arrow')).toBe(64)
556
+ expect(await botItemCount('leather_chestplate')).toBe(1)
557
+ expect(await botItemCount('leather_leggings')).toBe(1)
558
+ expect(await botItemCount('leather_boots')).toBe(1)
559
+ expect(await botItemCount('cooked_beef')).toBe(16)
560
+ }, 30_000)
561
+
562
+ test('give_kit_mage gives sword, pearls, apples, potion, and food', async () => {
563
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
564
+
565
+ await mc.command('/function stdlib_inventory6_test:test_give_kit_mage')
566
+ await botPost('/wait', { ticks: 10 })
567
+
568
+ expect(await botItemCount('wooden_sword')).toBe(1)
569
+ expect(await botItemCount('golden_apple')).toBe(8)
570
+ expect(await botItemCount('ender_pearl')).toBe(16)
571
+ expect(await botItemCount('splash_potion')).toBe(8)
572
+ expect(await botItemCount('cooked_beef')).toBe(16)
573
+ }, 30_000)
574
+
575
+ test('remove_item clears a specific item while leaving others', async () => {
576
+ if (!serverOnline || !botOnline) { console.warn(' SKIP: server or TestBot offline'); return }
577
+
578
+ await mc.command('/function stdlib_inventory6_test:test_give_kit_archer')
579
+ await botPost('/wait', { ticks: 10 })
580
+ expect(await botItemCount('arrow')).toBe(64)
581
+ expect(await botItemCount('bow')).toBe(1)
582
+
583
+ await mc.command('/function stdlib_inventory6_test:test_remove_item')
584
+ await botPost('/wait', { ticks: 10 })
585
+
586
+ expect(await botItemCount('arrow')).toBe(0)
587
+ expect(await botItemCount('bow')).toBe(1)
588
+ }, 30_000)
589
+ })
590
+
591
+ describe('stdlib coverage 6 — world', () => {
592
+ beforeEach(async () => {
593
+ if (!serverOnline) return
594
+ await mc.command('/fill -2 69 -2 4 74 4 minecraft:air').catch(() => {})
595
+ })
596
+
597
+ test('set_noon sets daytime to 6000', async () => {
598
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
599
+
600
+ await mc.command('/scoreboard players set #world_time_noon sc6_result 0')
601
+ await mc.command('/function stdlib_world6_test:test_set_noon')
602
+ await mc.ticks(3)
603
+
604
+ const time = await mc.scoreboard('#world_time_noon', 'sc6_result')
605
+ expect(time).toBe(6000)
606
+ }, 30_000)
607
+
608
+ test('set_midnight sets daytime to 18000', async () => {
609
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
610
+
611
+ await mc.command('/scoreboard players set #world_time_midnight sc6_result 0')
612
+ await mc.command('/function stdlib_world6_test:test_set_midnight')
613
+ await mc.ticks(3)
614
+
615
+ const time = await mc.scoreboard('#world_time_midnight', 'sc6_result')
616
+ expect(time).toBe(18000)
617
+ }, 30_000)
618
+
619
+ test('weather_rain, weather_thunder, and gamerule toggles execute cleanly', async () => {
620
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
621
+
622
+ for (const player of ['#weather_rain_done', '#weather_thunder_done', '#mob_griefing_done', '#fire_tick_done']) {
623
+ await mc.command(`/scoreboard players set ${player} sc6_result 0`)
624
+ }
625
+
626
+ await mc.command('/function stdlib_world6_test:test_weather_rain')
627
+ await mc.command('/function stdlib_world6_test:test_weather_thunder')
628
+ await mc.command('/function stdlib_world6_test:test_disable_mob_griefing')
629
+ await mc.command('/function stdlib_world6_test:test_disable_fire_spread')
630
+ await mc.ticks(3)
631
+
632
+ expect(await mc.scoreboard('#weather_rain_done', 'sc6_result')).toBe(1)
633
+ expect(await mc.scoreboard('#weather_thunder_done', 'sc6_result')).toBe(1)
634
+ expect(await mc.scoreboard('#mob_griefing_done', 'sc6_result')).toBe(1)
635
+ expect(await mc.scoreboard('#fire_tick_done', 'sc6_result')).toBe(1)
636
+ }, 30_000)
637
+
638
+ test('barrier_wall fills the requested cuboid with barriers', async () => {
639
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
640
+
641
+ await mc.command('/function stdlib_world6_test:test_barrier_wall')
642
+ await mc.ticks(3)
643
+
644
+ expect((await mc.block(0, 70, 0)).type).toBe('minecraft:barrier')
645
+ expect((await mc.block(1, 71, 1)).type).toBe('minecraft:barrier')
646
+ }, 30_000)
647
+
648
+ test('clear_area replaces blocks with air', async () => {
649
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
650
+
651
+ await mc.command('/fill 0 70 0 1 71 1 minecraft:stone')
652
+ await mc.command('/function stdlib_world6_test:test_clear_area')
653
+ await mc.ticks(3)
654
+
655
+ expect((await mc.block(0, 70, 0)).type).toBe('minecraft:air')
656
+ expect((await mc.block(1, 71, 1)).type).toBe('minecraft:air')
657
+ }, 30_000)
658
+
659
+ test('glass_box leaves a hollow air interior', async () => {
660
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
661
+
662
+ await mc.command('/function stdlib_world6_test:test_glass_box')
663
+ await mc.ticks(3)
664
+
665
+ expect((await mc.block(0, 70, 0)).type).toBe('minecraft:glass')
666
+ expect((await mc.block(2, 72, 2)).type).toBe('minecraft:glass')
667
+ expect((await mc.block(1, 71, 1)).type).toBe('minecraft:air')
668
+ }, 30_000)
669
+
670
+ test('sun_altitude at midnight is -900000', async () => {
671
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
672
+
673
+ await mc.command('/scoreboard players set #sun_alt_midnight sc6_result 0')
674
+ await mc.command('/function stdlib_world6_test:test_sun_altitude_midnight')
675
+ await mc.ticks(3)
676
+
677
+ const result = await mc.scoreboard('#sun_alt_midnight', 'sc6_result')
678
+ expect(result).toBe(-900000)
679
+ }, 30_000)
680
+ })
681
+
682
+ describe('stdlib coverage 6 — particles', () => {
683
+ const particleCases = [
684
+ ['smoke', '#particles_smoke_done', '/function stdlib_particles6_test:test_smoke'],
685
+ ['angry_happy', '#particles_angry_happy_done', '/function stdlib_particles6_test:test_angry_happy'],
686
+ ['totem_end', '#particles_totem_end_done', '/function stdlib_particles6_test:test_totem_end'],
687
+ ['particle_at_fx', '#particles_fx_done', '/function stdlib_particles6_test:test_particle_at_fx'],
688
+ ['draw_line_2d', '#particles_line_done', '/function stdlib_particles6_test:test_draw_line_2d'],
689
+ ['draw_circle', '#particles_circle_done', '/function stdlib_particles6_test:test_draw_circle'],
690
+ ['draw_helix', '#particles_helix_done', '/function stdlib_particles6_test:test_draw_helix'],
691
+ ['particle_dot', '#particles_dot_done', '/function stdlib_particles6_test:test_particle_dot'],
692
+ ] as const
693
+
694
+ test.each(particleCases)('%s executes without runtime errors on a live server', async (_label, player, command) => {
695
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
696
+
697
+ await mc.command(`/scoreboard players set ${player} sc6_result 0`)
698
+ await mc.command(command)
699
+ await mc.ticks(3)
700
+
701
+ expect(await mc.scoreboard(player, 'sc6_result')).toBe(1)
702
+ }, 30_000)
703
+ })
704
+
705
+ describe('stdlib coverage 6 — spawn', () => {
706
+ beforeEach(async () => {
707
+ if (!serverOnline) return
708
+ await mc.command('/kill @e[tag=sc6_spawn_src]').catch(() => {})
709
+ await mc.command('/kill @e[tag=sc6_spawn_dst]').catch(() => {})
710
+ await mc.command('/kill @e[tag=sc6_launch_target]').catch(() => {})
711
+ })
712
+
713
+ test('teleport_to_entity moves the source entity onto the destination', async () => {
714
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
715
+
716
+ await mc.command('/summon minecraft:armor_stand 1 64 1 {NoGravity:1b,Tags:["sc6_spawn_src"]}')
717
+ await mc.command('/summon minecraft:armor_stand 7 70 9 {NoGravity:1b,Tags:["sc6_spawn_dst"]}')
718
+ await mc.command('/scoreboard players set #spawn_tp_entity_done sc6_result 0')
719
+ await mc.command('/function stdlib_spawn6_test:test_teleport_to_entity')
720
+ await mc.ticks(3)
721
+
722
+ const src = await getSingleEntity('@e[tag=sc6_spawn_src]')
723
+ expect(await mc.scoreboard('#spawn_tp_entity_done', 'sc6_result')).toBe(1)
724
+ // Allow ±1 tolerance for entity bounding-box / foot-vs-eye-height offsets
725
+ expect(Math.abs(src.x - 7)).toBeLessThanOrEqual(1)
726
+ expect(Math.abs(src.y - 70)).toBeLessThanOrEqual(1)
727
+ expect(Math.abs(src.z - 9)).toBeLessThanOrEqual(1)
728
+ }, 30_000)
729
+
730
+ test('spread_players emits its placeholder chat message', async () => {
731
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
732
+
733
+ await mc.reset()
734
+ await mc.command('/scoreboard players set #spawn_spread_done sc6_result 0')
735
+ await mc.command('/function stdlib_spawn6_test:test_spread_players')
736
+ await mc.ticks(3)
737
+
738
+ // Verify function ran successfully; say output is not captured without players online
739
+ expect(await mc.scoreboard('#spawn_spread_done', 'sc6_result')).toBe(1)
740
+ }, 30_000)
741
+
742
+ test('launch_up moves the target upward by the requested relative height', async () => {
743
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
744
+
745
+ await mc.command('/summon minecraft:armor_stand 3 64 3 {NoGravity:1b,Tags:["sc6_launch_target"]}')
746
+ await mc.command('/scoreboard players set #spawn_launch_done sc6_result 0')
747
+ await mc.command('/function stdlib_spawn6_test:test_launch_up')
748
+ await mc.ticks(3)
749
+
750
+ const target = await getSingleEntity('@e[tag=sc6_launch_target]')
751
+ expect(await mc.scoreboard('#spawn_launch_done', 'sc6_result')).toBe(1)
752
+ // Allow ±1 tolerance for entity bounding-box offsets after relative teleport
753
+ expect(Math.abs(target.y - 69)).toBeLessThanOrEqual(1)
754
+ }, 30_000)
755
+ })