redscript-mc 1.2.26 → 1.2.28

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 (243) hide show
  1. package/README.md +78 -9
  2. package/README.zh.md +72 -4
  3. package/dist/__tests__/cli.test.js +13 -13
  4. package/dist/__tests__/optimizer-advanced.test.js +4 -4
  5. package/dist/__tests__/stdlib-advanced.test.js +114 -0
  6. package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
  7. package/dist/__tests__/stdlib-bigint.test.js +428 -0
  8. package/dist/cli.js +13 -5
  9. package/dist/codegen/mcfunction/index.d.ts +4 -0
  10. package/dist/codegen/mcfunction/index.js +9 -4
  11. package/dist/compile.d.ts +4 -0
  12. package/dist/compile.js +9 -1
  13. package/dist/data/arena/function/__load.mcfunction +6 -0
  14. package/dist/data/arena/function/__tick.mcfunction +2 -0
  15. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
  16. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
  17. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
  18. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
  19. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
  20. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
  21. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
  22. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
  23. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
  24. package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
  25. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
  26. package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
  27. package/dist/data/arena/function/arena_tick.mcfunction +11 -0
  28. package/dist/data/counter/function/__load.mcfunction +5 -0
  29. package/dist/data/counter/function/__tick.mcfunction +2 -0
  30. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
  31. package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
  32. package/dist/data/counter/function/counter_tick.mcfunction +11 -0
  33. package/dist/data/gcd2/function/__load.mcfunction +3 -0
  34. package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
  35. package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
  36. package/dist/data/gcd2/function/abs.mcfunction +7 -0
  37. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
  38. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
  39. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
  40. package/dist/data/gcd2/function/gcd.mcfunction +14 -0
  41. package/dist/data/gcd3/function/__load.mcfunction +3 -0
  42. package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
  43. package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
  44. package/dist/data/gcd3/function/abs.mcfunction +7 -0
  45. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
  46. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
  47. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
  48. package/dist/data/gcd3/function/gcd.mcfunction +14 -0
  49. package/dist/data/gcd3/function/test.mcfunction +7 -0
  50. package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
  51. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
  52. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
  53. package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
  54. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
  55. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
  56. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
  57. package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
  58. package/dist/data/gcd3nm/function/test.mcfunction +7 -0
  59. package/dist/data/gcd_test/function/__load.mcfunction +3 -0
  60. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
  61. package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
  62. package/dist/data/gcd_test/function/abs.mcfunction +7 -0
  63. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
  64. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
  65. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
  66. package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
  67. package/dist/data/isqrttest/function/__load.mcfunction +6 -0
  68. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
  69. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
  70. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
  71. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
  72. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
  73. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
  74. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
  75. package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
  76. package/dist/data/isqrttest/function/test.mcfunction +6 -0
  77. package/dist/data/mathtest/function/__load.mcfunction +3 -0
  78. package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
  79. package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
  80. package/dist/data/mathtest/function/abs.mcfunction +6 -0
  81. package/dist/data/mathtest/function/test.mcfunction +5 -0
  82. package/dist/data/minecraft/tags/function/load.json +5 -0
  83. package/dist/data/minecraft/tags/function/tick.json +5 -0
  84. package/dist/data/mypack/function/__load.mcfunction +13 -0
  85. package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
  86. package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
  87. package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
  88. package/dist/data/mypack/function/abs.mcfunction +6 -0
  89. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
  90. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
  91. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
  92. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
  93. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
  94. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
  95. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
  96. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
  97. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
  98. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
  99. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
  100. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
  101. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
  102. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
  103. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
  104. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
  105. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
  106. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
  107. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
  108. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
  109. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
  110. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
  111. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
  112. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
  113. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
  114. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
  115. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
  116. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
  117. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
  118. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
  119. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
  120. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
  121. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
  122. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
  123. package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
  124. package/dist/data/mypack/function/my_game.mcfunction +10 -0
  125. package/dist/data/quiz/function/__load.mcfunction +16 -0
  126. package/dist/data/quiz/function/__tick.mcfunction +6 -0
  127. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
  128. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
  129. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
  130. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
  131. package/dist/data/quiz/function/answer_a.mcfunction +4 -0
  132. package/dist/data/quiz/function/answer_b.mcfunction +4 -0
  133. package/dist/data/quiz/function/answer_c.mcfunction +4 -0
  134. package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
  135. package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
  136. package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
  137. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
  138. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
  139. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
  140. package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
  141. package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
  142. package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
  143. package/dist/data/quiz/function/ask_question.mcfunction +7 -0
  144. package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
  145. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
  146. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
  147. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
  148. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
  149. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
  150. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
  151. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
  152. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
  153. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
  154. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
  155. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
  156. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
  157. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
  158. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
  159. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
  160. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
  161. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
  162. package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
  163. package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
  164. package/dist/data/reqtest/function/__load.mcfunction +4 -0
  165. package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
  166. package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
  167. package/dist/data/reqtest/function/use_table.mcfunction +4 -0
  168. package/dist/data/reqtest2/function/__load.mcfunction +3 -0
  169. package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
  170. package/dist/data/runtime/function/__load.mcfunction +5 -0
  171. package/dist/data/runtime/function/__tick.mcfunction +2 -0
  172. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
  173. package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
  174. package/dist/data/shop/function/__load.mcfunction +7 -0
  175. package/dist/data/shop/function/__tick.mcfunction +3 -0
  176. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
  177. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
  178. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
  179. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
  180. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
  181. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
  182. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
  183. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
  184. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
  185. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
  186. package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
  187. package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
  188. package/dist/data/swap_test/function/__load.mcfunction +3 -0
  189. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
  190. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
  191. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
  192. package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
  193. package/dist/data/turret/function/__load.mcfunction +5 -0
  194. package/dist/data/turret/function/__tick.mcfunction +4 -0
  195. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
  196. package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
  197. package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
  198. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
  199. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
  200. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
  201. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
  202. package/dist/data/turret/function/turret_tick.mcfunction +5 -0
  203. package/dist/gcd2.map.json +15 -0
  204. package/dist/gcd3.map.json +17 -0
  205. package/dist/gcd_test.map.json +15 -0
  206. package/dist/index.d.ts +4 -0
  207. package/dist/index.js +11 -6
  208. package/dist/isqrttest.map.json +15 -0
  209. package/dist/lowering/index.d.ts +3 -0
  210. package/dist/lowering/index.js +161 -64
  211. package/dist/mathtest.map.json +6 -0
  212. package/dist/mypack.map.json +27 -0
  213. package/dist/optimizer/commands.d.ts +1 -0
  214. package/dist/optimizer/commands.js +18 -11
  215. package/dist/optimizer/structure.d.ts +1 -0
  216. package/dist/optimizer/structure.js +6 -1
  217. package/dist/pack.mcmeta +6 -0
  218. package/dist/reqtest.map.json +4 -0
  219. package/dist/reqtest2.map.json +4 -0
  220. package/dist/runtime/index.js +26 -5
  221. package/dist/runtime.map.json +7 -0
  222. package/dist/swap_test.map.json +14 -0
  223. package/editors/vscode/package-lock.json +3 -3
  224. package/editors/vscode/package.json +1 -1
  225. package/examples/math-showcase.mcrs +146 -0
  226. package/examples/readme-demo.mcrs +92 -0
  227. package/examples/showcase.mcrs +505 -0
  228. package/package.json +1 -1
  229. package/src/__tests__/cli.test.ts +13 -13
  230. package/src/__tests__/optimizer-advanced.test.ts +4 -4
  231. package/src/__tests__/stdlib-advanced.test.ts +120 -0
  232. package/src/__tests__/stdlib-bigint.test.ts +427 -0
  233. package/src/cli.ts +14 -5
  234. package/src/codegen/mcfunction/index.ts +14 -5
  235. package/src/compile.ts +15 -2
  236. package/src/index.ts +17 -7
  237. package/src/lowering/index.ts +165 -63
  238. package/src/optimizer/commands.ts +18 -12
  239. package/src/optimizer/structure.ts +6 -2
  240. package/src/runtime/index.ts +27 -5
  241. package/src/stdlib/advanced.mcrs +81 -0
  242. package/src/stdlib/bigint.mcrs +205 -0
  243. package/src/stdlib/math.mcrs +19 -6
@@ -0,0 +1,428 @@
1
+ "use strict";
2
+ /**
3
+ * stdlib/bigint.mcrs — runtime behavioural tests
4
+ *
5
+ * Tests basic BigInt operations (base 10000, 8 limbs = 32 decimal digits).
6
+ * All arithmetic validated against known values.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const compile_1 = require("../compile");
45
+ const runtime_1 = require("../runtime");
46
+ const MATH_SRC = fs.readFileSync(path.join(__dirname, '../../src/stdlib/math.mcrs'), 'utf-8');
47
+ const BIGINT_SRC = fs.readFileSync(path.join(__dirname, '../../src/stdlib/bigint.mcrs'), 'utf-8');
48
+ function run(driver) {
49
+ const result = (0, compile_1.compile)(driver, {
50
+ namespace: 'bitest',
51
+ librarySources: [MATH_SRC, BIGINT_SRC],
52
+ });
53
+ if (!result.success)
54
+ throw new Error(result.error?.message ?? 'compile failed');
55
+ const rt = new runtime_1.MCRuntime('bitest');
56
+ for (const file of result.files ?? []) {
57
+ if (!file.path.endsWith('.mcfunction'))
58
+ continue;
59
+ const match = file.path.match(/data\/([^/]+)\/function\/(.+)\.mcfunction$/);
60
+ if (!match)
61
+ continue;
62
+ rt.loadFunction(`${match[1]}:${match[2]}`, file.content.split('\n'));
63
+ }
64
+ rt.load();
65
+ return rt;
66
+ }
67
+ function sc(rt, key) {
68
+ return rt.getScore('out', `bitest.${key}`) ?? 0;
69
+ }
70
+ // ── storage_set_int roundtrip ─────────────────────────────────────────────────
71
+ describe('storage_set_int roundtrip', () => {
72
+ it('static index: write 99 to arr[2], read back', () => {
73
+ const rt = run(`fn test() {
74
+ storage_set_array("rs:t", "arr", "[10,20,30,40]");
75
+ storage_set_int("rs:t", "arr", 2, 99);
76
+ scoreboard_set("out", "r", storage_get_int("rs:t", "arr", 2));
77
+ }`);
78
+ rt.execFunction('test');
79
+ expect(sc(rt, 'r')).toBe(99);
80
+ });
81
+ it('runtime index: write 777 to arr[idx], read back', () => {
82
+ const rt = run(`fn test() {
83
+ storage_set_array("rs:t", "arr", "[1,2,3,4,5]");
84
+ let idx: int = 3;
85
+ storage_set_int("rs:t", "arr", idx, 777);
86
+ scoreboard_set("out", "r", storage_get_int("rs:t", "arr", idx));
87
+ }`);
88
+ rt.execFunction('test');
89
+ expect(sc(rt, 'r')).toBe(777);
90
+ });
91
+ it('loop write: fill arr[0..3] with 10,20,30,40', () => {
92
+ const rt = run(`fn test() {
93
+ storage_set_array("rs:t", "arr", "[0,0,0,0]");
94
+ let i: int = 0;
95
+ while (i < 4) {
96
+ storage_set_int("rs:t", "arr", i, (i + 1) * 10);
97
+ i = i + 1;
98
+ }
99
+ scoreboard_set("out", "a", storage_get_int("rs:t", "arr", 0));
100
+ scoreboard_set("out", "b", storage_get_int("rs:t", "arr", 1));
101
+ scoreboard_set("out", "c", storage_get_int("rs:t", "arr", 2));
102
+ scoreboard_set("out", "d", storage_get_int("rs:t", "arr", 3));
103
+ }`);
104
+ rt.execFunction('test');
105
+ expect(sc(rt, 'a')).toBe(10);
106
+ expect(sc(rt, 'b')).toBe(20);
107
+ expect(sc(rt, 'c')).toBe(30);
108
+ expect(sc(rt, 'd')).toBe(40);
109
+ });
110
+ });
111
+ // ── bigint_init + from_int ────────────────────────────────────────────────────
112
+ describe('bigint init and load', () => {
113
+ it('bigint_init zeros registers', () => {
114
+ const rt = run(`fn test() {
115
+ bigint_init();
116
+ scoreboard_set("out", "r", bigint_get_a(0));
117
+ }`);
118
+ rt.execFunction('test');
119
+ expect(sc(rt, 'r')).toBe(0);
120
+ });
121
+ it('bigint_from_int_a(12345678): limb0=5678, limb1=1234', () => {
122
+ const rt = run(`fn test() {
123
+ bigint_init();
124
+ bigint_from_int_a(12345678);
125
+ scoreboard_set("out", "l0", bigint_get_a(0));
126
+ scoreboard_set("out", "l1", bigint_get_a(1));
127
+ scoreboard_set("out", "l2", bigint_get_a(2));
128
+ }`);
129
+ rt.execFunction('test');
130
+ expect(sc(rt, 'l0')).toBe(5678);
131
+ expect(sc(rt, 'l1')).toBe(1234);
132
+ expect(sc(rt, 'l2')).toBe(0);
133
+ });
134
+ it('bigint_from_int_a(2000000000): limb0=0, limb1=0, limb2=20', () => {
135
+ // 2000000000 = 20 × 10000^2 (not 2000: 20 × 10^8 = 2×10^9 ✓)
136
+ const rt = run(`fn test() {
137
+ bigint_init();
138
+ bigint_from_int_a(2000000000);
139
+ scoreboard_set("out", "l0", bigint_get_a(0));
140
+ scoreboard_set("out", "l1", bigint_get_a(1));
141
+ scoreboard_set("out", "l2", bigint_get_a(2));
142
+ }`);
143
+ rt.execFunction('test');
144
+ expect(sc(rt, 'l0')).toBe(0);
145
+ expect(sc(rt, 'l1')).toBe(0);
146
+ expect(sc(rt, 'l2')).toBe(20);
147
+ });
148
+ });
149
+ // ── bigint_add ────────────────────────────────────────────────────────────────
150
+ describe('bigint_add', () => {
151
+ it('1 + 1 = 2 (simple)', () => {
152
+ const rt = run(`fn test() {
153
+ bigint_init();
154
+ bigint_from_int_a(1);
155
+ bigint_from_int_b(1);
156
+ bigint_add();
157
+ scoreboard_set("out", "r", bigint_get_c(0));
158
+ }`);
159
+ rt.execFunction('test');
160
+ expect(sc(rt, 'r')).toBe(2);
161
+ });
162
+ it('9999 + 1 = 10000: carry across limb boundary', () => {
163
+ // a=[9999,0,...] + b=[1,0,...] = c=[0,1,0,...] (carry to limb1)
164
+ const rt = run(`fn test() {
165
+ bigint_init();
166
+ bigint_from_int_a(9999);
167
+ bigint_from_int_b(1);
168
+ bigint_add();
169
+ scoreboard_set("out", "l0", bigint_get_c(0));
170
+ scoreboard_set("out", "l1", bigint_get_c(1));
171
+ }`);
172
+ rt.execFunction('test');
173
+ expect(sc(rt, 'l0')).toBe(0);
174
+ expect(sc(rt, 'l1')).toBe(1);
175
+ });
176
+ it('99990000 + 10000 = 100000000: multi-limb carry', () => {
177
+ // a=[0,9999,...] + b=[0,1,...] = c=[0,0,1,...] (carry to limb2)
178
+ const rt = run(`fn test() {
179
+ bigint_init();
180
+ bigint_from_int_a(99990000);
181
+ bigint_from_int_b(10000);
182
+ bigint_add();
183
+ scoreboard_set("out", "l0", bigint_get_c(0));
184
+ scoreboard_set("out", "l1", bigint_get_c(1));
185
+ scoreboard_set("out", "l2", bigint_get_c(2));
186
+ }`);
187
+ rt.execFunction('test');
188
+ expect(sc(rt, 'l0')).toBe(0);
189
+ expect(sc(rt, 'l1')).toBe(0);
190
+ expect(sc(rt, 'l2')).toBe(1);
191
+ });
192
+ it('large add: 999999999 + 999999999', () => {
193
+ // 999999999 = [9999, 9999, 9, 0, ...]
194
+ // + same = [9998, 9999, 18, 0, ...] after carry
195
+ // = 1999999998: l0=9998, l1=9999, l2=19 (carry: 9+9=18, no carry from l2)
196
+ // Wait: l0=9999+9999=19998, carry=1, l0=9998
197
+ // l1=9999+9999+1=19999, carry=1, l1=9999
198
+ // l2=9+9+1=19, carry=0, l2=19
199
+ const rt = run(`fn test() {
200
+ bigint_init();
201
+ bigint_from_int_a(999999999);
202
+ bigint_from_int_b(999999999);
203
+ bigint_add();
204
+ scoreboard_set("out", "l0", bigint_get_c(0));
205
+ scoreboard_set("out", "l1", bigint_get_c(1));
206
+ scoreboard_set("out", "l2", bigint_get_c(2));
207
+ }`);
208
+ rt.execFunction('test');
209
+ expect(sc(rt, 'l0')).toBe(9998); // 1999999998 % 10000 = 9998
210
+ expect(sc(rt, 'l1')).toBe(9999); // floor(1999999998 / 10000) % 10000 = 9999
211
+ expect(sc(rt, 'l2')).toBe(19); // floor(1999999998 / 100000000) = 19
212
+ });
213
+ });
214
+ // ── bigint_sub ────────────────────────────────────────────────────────────────
215
+ describe('bigint_sub', () => {
216
+ it('10 - 3 = 7', () => {
217
+ const rt = run(`fn test() {
218
+ bigint_init();
219
+ bigint_from_int_a(10);
220
+ bigint_from_int_b(3);
221
+ bigint_sub();
222
+ scoreboard_set("out", "r", bigint_get_c(0));
223
+ }`);
224
+ rt.execFunction('test');
225
+ expect(sc(rt, 'r')).toBe(7);
226
+ });
227
+ it('10000 - 1 = 9999: borrow across limb boundary', () => {
228
+ // a=[0,1,...] - b=[1,0,...] = c=[9999,0,...] (borrow from limb1)
229
+ const rt = run(`fn test() {
230
+ bigint_init();
231
+ bigint_from_int_a(10000);
232
+ bigint_from_int_b(1);
233
+ bigint_sub();
234
+ scoreboard_set("out", "l0", bigint_get_c(0));
235
+ scoreboard_set("out", "l1", bigint_get_c(1));
236
+ }`);
237
+ rt.execFunction('test');
238
+ expect(sc(rt, 'l0')).toBe(9999);
239
+ expect(sc(rt, 'l1')).toBe(0);
240
+ });
241
+ });
242
+ // ── bigint_compare ────────────────────────────────────────────────────────────
243
+ describe('bigint_compare', () => {
244
+ it('1 == 1 → 0', () => {
245
+ const rt = run(`fn test() {
246
+ bigint_init();
247
+ bigint_from_int_a(1);
248
+ bigint_from_int_b(1);
249
+ scoreboard_set("out", "r", bigint_compare());
250
+ }`);
251
+ rt.execFunction('test');
252
+ expect(sc(rt, 'r')).toBe(0);
253
+ });
254
+ it('2 > 1 → 1', () => {
255
+ const rt = run(`fn test() {
256
+ bigint_init();
257
+ bigint_from_int_a(2);
258
+ bigint_from_int_b(1);
259
+ scoreboard_set("out", "r", bigint_compare());
260
+ }`);
261
+ rt.execFunction('test');
262
+ expect(sc(rt, 'r')).toBe(1);
263
+ });
264
+ it('1 < 2 → -1', () => {
265
+ const rt = run(`fn test() {
266
+ bigint_init();
267
+ bigint_from_int_a(1);
268
+ bigint_from_int_b(2);
269
+ scoreboard_set("out", "r", bigint_compare());
270
+ }`);
271
+ rt.execFunction('test');
272
+ expect(sc(rt, 'r')).toBe(-1);
273
+ });
274
+ });
275
+ // ── bigint_mul_small ──────────────────────────────────────────────────────────
276
+ describe('bigint_mul_small', () => {
277
+ it('12345 * 2 = 24690', () => {
278
+ const rt = run(`fn test() {
279
+ bigint_init();
280
+ bigint_from_int_a(12345);
281
+ bigint_mul_small(2);
282
+ scoreboard_set("out", "l0", bigint_get_c(0));
283
+ scoreboard_set("out", "l1", bigint_get_c(1));
284
+ }`);
285
+ rt.execFunction('test');
286
+ expect(sc(rt, 'l0')).toBe(4690);
287
+ expect(sc(rt, 'l1')).toBe(2);
288
+ });
289
+ it('9999 * 9999 = 99980001: carry', () => {
290
+ // c[0] = 99980001 % 10000 = 1
291
+ // c[1] = floor(99980001 / 10000) = 9998
292
+ const rt = run(`fn test() {
293
+ bigint_init();
294
+ bigint_from_int_a(9999);
295
+ bigint_mul_small(9999);
296
+ scoreboard_set("out", "l0", bigint_get_c(0));
297
+ scoreboard_set("out", "l1", bigint_get_c(1));
298
+ }`);
299
+ rt.execFunction('test');
300
+ expect(sc(rt, 'l0')).toBe(1); // 99980001 % 10000 = 1 (actually 0001)
301
+ expect(sc(rt, 'l1')).toBe(9998); // 9998
302
+ });
303
+ });
304
+ // ── bigint_mul ────────────────────────────────────────────────────────────────
305
+ describe('bigint_mul', () => {
306
+ it('3 * 4 = 12', () => {
307
+ const rt = run(`fn test() {
308
+ bigint_init();
309
+ bigint_from_int_a(3);
310
+ bigint_from_int_b(4);
311
+ bigint_mul();
312
+ scoreboard_set("out", "r", bigint_get_c(0));
313
+ }`);
314
+ rt.execFunction('test');
315
+ expect(sc(rt, 'r')).toBe(12);
316
+ });
317
+ it('9999 * 9999 = 99980001', () => {
318
+ const rt = run(`fn test() {
319
+ bigint_init();
320
+ bigint_from_int_a(9999);
321
+ bigint_from_int_b(9999);
322
+ bigint_mul();
323
+ scoreboard_set("out", "l0", bigint_get_c(0));
324
+ scoreboard_set("out", "l1", bigint_get_c(1));
325
+ }`);
326
+ rt.execFunction('test');
327
+ expect(sc(rt, 'l0')).toBe(1);
328
+ expect(sc(rt, 'l1')).toBe(9998);
329
+ });
330
+ it('100000 * 100000 = 10^10: spans 3 limbs', () => {
331
+ // 10^10 = [0, 0, 0, 1, 0, ...] in base 10000 (1 * 10000^3 = 10^12? no)
332
+ // 10^10 / 10000^0 % 10000 = 0
333
+ // 10^10 / 10000^1 % 10000 = 0
334
+ // 10^10 / 10000^2 % 10000 = 10000 → wait: 10^10 / 10^8 = 100, 100 % 10000 = 100
335
+ // Actually: 10^10 = 100 * 10^8 = 100 * (10^4)^2
336
+ // l0 = 10^10 % 10^4 = 0
337
+ // l1 = floor(10^10 / 10^4) % 10^4 = floor(10^6) % 10000 = 0
338
+ // l2 = floor(10^10 / 10^8) % 10^4 = 100 % 10000 = 100
339
+ const rt = run(`fn test() {
340
+ bigint_init();
341
+ bigint_from_int_a(100000);
342
+ bigint_from_int_b(100000);
343
+ bigint_mul();
344
+ scoreboard_set("out", "l0", bigint_get_c(0));
345
+ scoreboard_set("out", "l1", bigint_get_c(1));
346
+ scoreboard_set("out", "l2", bigint_get_c(2));
347
+ }`);
348
+ rt.execFunction('test');
349
+ expect(sc(rt, 'l0')).toBe(0);
350
+ expect(sc(rt, 'l1')).toBe(0);
351
+ expect(sc(rt, 'l2')).toBe(100);
352
+ });
353
+ });
354
+ // ── bigint_fib ────────────────────────────────────────────────────────────────
355
+ describe('bigint_fib', () => {
356
+ it('F(0) = 0', () => {
357
+ const rt = run(`fn test() {
358
+ bigint_fib(0);
359
+ scoreboard_set("out", "r", bigint_get_a(0));
360
+ }`);
361
+ rt.execFunction('test');
362
+ expect(sc(rt, 'r')).toBe(0);
363
+ });
364
+ it('F(1) = 1', () => {
365
+ const rt = run(`fn test() {
366
+ bigint_fib(1);
367
+ scoreboard_set("out", "r", bigint_get_a(0));
368
+ }`);
369
+ rt.execFunction('test');
370
+ expect(sc(rt, 'r')).toBe(1);
371
+ });
372
+ it('F(10) = 55', () => {
373
+ const rt = run(`fn test() {
374
+ bigint_fib(10);
375
+ scoreboard_set("out", "r", bigint_get_a(0));
376
+ }`);
377
+ rt.execFunction('test');
378
+ expect(sc(rt, 'r')).toBe(55);
379
+ });
380
+ it('F(20) = 6765', () => {
381
+ const rt = run(`fn test() {
382
+ bigint_fib(20);
383
+ scoreboard_set("out", "r", bigint_get_a(0));
384
+ }`);
385
+ rt.execFunction('test');
386
+ expect(sc(rt, 'r')).toBe(6765);
387
+ });
388
+ it('F(50) = 12586269025: limb0=9025, limb1=8626, limb2=125', () => {
389
+ // F(50) = 12,586,269,025
390
+ // 12586269025 % 10000 = 9025
391
+ // floor(12586269025 / 10000) % 10000 = 1258626 % 10000 = 8626
392
+ // floor(12586269025 / 10^8) = 125
393
+ const rt = run(`fn test() {
394
+ bigint_fib(50);
395
+ scoreboard_set("out", "l0", bigint_get_a(0));
396
+ scoreboard_set("out", "l1", bigint_get_a(1));
397
+ scoreboard_set("out", "l2", bigint_get_a(2));
398
+ }`);
399
+ rt.execFunction('test');
400
+ expect(sc(rt, 'l0')).toBe(9025);
401
+ expect(sc(rt, 'l1')).toBe(8626);
402
+ expect(sc(rt, 'l2')).toBe(125);
403
+ });
404
+ it('F(100) low limbs check', () => {
405
+ // F(100) = 354224848179261915075
406
+ // % 10000 = 5075
407
+ // floor / 10000 % 10000 = floor(35422484817926191.5075) % 10000 = ...
408
+ // Let's compute:
409
+ // 354224848179261915075 % 10000 = 5075
410
+ // floor(354224848179261915075 / 10000) = 35422484817926191507 (JS BigInt)
411
+ // 35422484817926191507 % 10000 = 1507
412
+ // floor(35422484817926191507 / 10000) = 3542248481792619 (roughly)
413
+ // % 10000 = 2619
414
+ const rt = run(`fn test() {
415
+ bigint_fib(100);
416
+ scoreboard_set("out", "l0", bigint_get_a(0));
417
+ scoreboard_set("out", "l1", bigint_get_a(1));
418
+ scoreboard_set("out", "l2", bigint_get_a(2));
419
+ }`);
420
+ rt.execFunction('test');
421
+ const f100 = BigInt('354224848179261915075');
422
+ const b = BigInt(10000);
423
+ expect(sc(rt, 'l0')).toBe(Number(f100 % b));
424
+ expect(sc(rt, 'l1')).toBe(Number((f100 / b) % b));
425
+ expect(sc(rt, 'l2')).toBe(Number((f100 / b / b) % b));
426
+ });
427
+ });
428
+ //# sourceMappingURL=stdlib-bigint.test.js.map
package/dist/cli.js CHANGED
@@ -60,7 +60,7 @@ function printUsage() {
60
60
  RedScript Compiler
61
61
 
62
62
  Usage:
63
- redscript compile <file> [-o <out>] [--output-nbt <file>] [--namespace <ns>] [--target <target>] [--no-dce]
63
+ redscript compile <file> [-o <out>] [--output-nbt <file>] [--namespace <ns>] [--scoreboard <obj>] [--target <target>] [--no-dce]
64
64
  redscript watch <dir> [-o <outdir>] [--namespace <ns>] [--hot-reload <url>]
65
65
  redscript check <file>
66
66
  redscript fmt <file.mcrs> [file2.mcrs ...]
@@ -85,6 +85,9 @@ Options:
85
85
  --target <target> Output target: datapack (default), cmdblock, or structure
86
86
  --no-dce Disable AST dead code elimination
87
87
  --no-mangle Disable variable name mangling (use readable names)
88
+ --scoreboard <obj> Scoreboard objective for variables (default: namespace).
89
+ Each datapack automatically uses its namespace as the objective
90
+ so multiple datapacks can coexist without collisions.
88
91
  --stats Print optimizer statistics
89
92
  --hot-reload <url> After each successful compile, POST to <url>/reload
90
93
  (use with redscript-testharness; e.g. http://localhost:25561)
@@ -218,6 +221,10 @@ function parseArgs(args) {
218
221
  result.mangle = false;
219
222
  i++;
220
223
  }
224
+ else if (arg === '--scoreboard') {
225
+ result.scoreboardObjective = args[++i];
226
+ i++;
227
+ }
221
228
  else if (arg === '--hot-reload') {
222
229
  result.hotReload = args[++i];
223
230
  i++;
@@ -271,7 +278,7 @@ function printOptimizationStats(stats) {
271
278
  console.log(` constant folding: ${stats.constantFolds} constants folded`);
272
279
  console.log(` Total mcfunction commands: ${stats.totalCommandsBefore} -> ${stats.totalCommandsAfter} (${formatReduction(stats.totalCommandsBefore, stats.totalCommandsAfter)} reduction)`);
273
280
  }
274
- function compileCommand(file, output, namespace, target = 'datapack', showStats = false, dce = true, mangle = true) {
281
+ function compileCommand(file, output, namespace, target = 'datapack', showStats = false, dce = true, mangle = true, scoreboardObjective = undefined) {
275
282
  // Read source file
276
283
  if (!fs.existsSync(file)) {
277
284
  console.error(`Error: File not found: ${file}`);
@@ -280,7 +287,7 @@ function compileCommand(file, output, namespace, target = 'datapack', showStats
280
287
  const source = fs.readFileSync(file, 'utf-8');
281
288
  try {
282
289
  if (target === 'cmdblock') {
283
- const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle });
290
+ const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle, scoreboardObjective });
284
291
  printWarnings(result.warnings);
285
292
  // Generate command block JSON
286
293
  const hasTick = result.files.some(f => f.path.includes('__tick.mcfunction'));
@@ -309,7 +316,7 @@ function compileCommand(file, output, namespace, target = 'datapack', showStats
309
316
  }
310
317
  }
311
318
  else {
312
- const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle });
319
+ const result = (0, index_1.compile)(source, { namespace, filePath: file, dce, mangle, scoreboardObjective });
313
320
  printWarnings(result.warnings);
314
321
  // Default: generate datapack
315
322
  // Create output directory
@@ -483,7 +490,8 @@ async function main() {
483
490
  const output = target === 'structure'
484
491
  ? (parsed.outputNbt ?? parsed.output ?? `./${namespace}.nbt`)
485
492
  : (parsed.output ?? './dist');
486
- compileCommand(parsed.file, output, namespace, target, parsed.stats, parsed.dce, parsed.mangle);
493
+ compileCommand(parsed.file, output, namespace, target, parsed.stats, parsed.dce, parsed.mangle, parsed.scoreboardObjective // undefined = derive from namespace in compile()
494
+ );
487
495
  }
488
496
  break;
489
497
  case 'watch':
@@ -30,6 +30,10 @@ export interface DatapackGenerationResult {
30
30
  export interface DatapackGenerationOptions {
31
31
  optimizeCommands?: boolean;
32
32
  mangle?: boolean;
33
+ /** Scoreboard objective used for all scoreboard variables.
34
+ * Defaults to 'rs'. Override per-datapack to avoid collisions
35
+ * when multiple RedScript datapacks are loaded simultaneously. */
36
+ scoreboardObjective?: string;
33
37
  }
34
38
  export declare function countMcfunctionCommands(files: DatapackFile[]): number;
35
39
  export declare function generateDatapackWithStats(module: IRModule, options?: DatapackGenerationOptions): DatapackGenerationResult;
@@ -26,7 +26,8 @@ const var_allocator_1 = require("../var-allocator");
26
26
  // ---------------------------------------------------------------------------
27
27
  // Utilities
28
28
  // ---------------------------------------------------------------------------
29
- const OBJ = 'rs'; // scoreboard objective name
29
+ // Default scoreboard objective overridden per-compilation via DatapackGenerationOptions.scoreboardObjective
30
+ let OBJ = 'rs';
30
31
  function operandToScore(op, alloc) {
31
32
  if (op.kind === 'var')
32
33
  return `${alloc.alloc(op.name)} ${OBJ}`;
@@ -335,7 +336,11 @@ function preAllocTerm(term, alloc) {
335
336
  }
336
337
  }
337
338
  function generateDatapackWithStats(module, options = {}) {
338
- const { optimizeCommands = true, mangle = false } = options;
339
+ const { optimizeCommands = true, mangle = false, scoreboardObjective = 'rs' } = options;
340
+ // Set module-level OBJ so all helper functions in this module use the correct objective.
341
+ // This is safe because compilation is synchronous.
342
+ OBJ = scoreboardObjective;
343
+ (0, commands_1.setOptimizerObjective)(scoreboardObjective);
339
344
  const alloc = new var_allocator_1.VarAllocator(mangle);
340
345
  const files = [];
341
346
  const advancements = [];
@@ -375,10 +380,10 @@ function generateDatapackWithStats(module, options = {}) {
375
380
  for (const eventType of eventTypes) {
376
381
  const detection = types_1.EVENT_TYPES[eventType].detection;
377
382
  if (eventType === 'PlayerDeath') {
378
- loadLines.push('scoreboard objectives add rs.deaths deathCount');
383
+ loadLines.push(`scoreboard objectives add ${OBJ}.deaths deathCount`);
379
384
  }
380
385
  else if (eventType === 'EntityKill') {
381
- loadLines.push('scoreboard objectives add rs.kills totalKillCount');
386
+ loadLines.push(`scoreboard objectives add ${OBJ}.kills totalKillCount`);
382
387
  }
383
388
  else if (eventType === 'ItemUse') {
384
389
  loadLines.push('# ItemUse detection requires a project-specific objective/tag setup');
package/dist/compile.d.ts CHANGED
@@ -13,6 +13,10 @@ export interface CompileOptions {
13
13
  optimize?: boolean;
14
14
  dce?: boolean;
15
15
  mangle?: boolean;
16
+ /** Scoreboard objective used for all variable slots.
17
+ * Defaults to 'rs'. Set to a unique value (e.g. 'mypack_rs') when loading
18
+ * multiple RedScript datapacks simultaneously to avoid variable collisions. */
19
+ scoreboardObjective?: string;
16
20
  /** Additional source files that should be treated as *library* code.
17
21
  * Functions in these files are DCE-eligible: they are only compiled into
18
22
  * the datapack when actually called from user code. Each string is parsed
package/dist/compile.js CHANGED
@@ -209,6 +209,11 @@ function compile(source, options = {}) {
209
209
  }
210
210
  const dceResult = shouldRunDce ? (0, dce_1.eliminateDeadCode)(parsedAst) : { program: parsedAst, warnings: [] };
211
211
  const ast = dceResult.program;
212
+ // Configure scoreboard objective for this compilation.
213
+ // Default: use the datapack namespace so each datapack gets its own objective
214
+ // automatically, preventing variable collisions when multiple datapacks coexist.
215
+ const scoreboardObj = options.scoreboardObjective ?? namespace;
216
+ (0, lowering_1.setScoreboardObjective)(scoreboardObj);
212
217
  // Lowering
213
218
  const ir = new lowering_1.Lowering(namespace, preprocessed.ranges).lower(ast);
214
219
  // Optimization
@@ -217,7 +222,10 @@ function compile(source, options = {}) {
217
222
  : ir;
218
223
  // Code generation — mangle=true by default to prevent cross-function
219
224
  // scoreboard variable collisions in the global MC scoreboard namespace.
220
- const generated = (0, mcfunction_1.generateDatapackWithStats)(optimized, { mangle: options.mangle ?? true });
225
+ const generated = (0, mcfunction_1.generateDatapackWithStats)(optimized, {
226
+ mangle: options.mangle ?? true,
227
+ scoreboardObjective: scoreboardObj,
228
+ });
221
229
  return {
222
230
  success: true,
223
231
  files: [...generated.files, ...generated.advancements],
@@ -0,0 +1,6 @@
1
+ # RedScript runtime init
2
+ scoreboard objectives add rs dummy
3
+ scoreboard players set $const_1 rs 1
4
+ scoreboard players set $const_200 rs 200
5
+ scoreboard players set $const_0 rs 0
6
+ scoreboard players set $const_0 rs 0
@@ -0,0 +1,2 @@
1
+ # RedScript tick dispatcher
2
+ function arena:arena_tick
@@ -0,0 +1,3 @@
1
+ # block: else_1
2
+ say Arena update: no PvP kills yet.
3
+ function arena:announce_leaders/merge_2
@@ -0,0 +1,3 @@
1
+ # block: then_0
2
+ scoreboard players operation $top_kills rs = $kills rs
3
+ function arena:announce_leaders/foreach_0/merge_2
@@ -0,0 +1,7 @@
1
+ # block: entry
2
+ execute store result score $t0 rs run scoreboard players get @s kills
3
+ scoreboard players operation $kills rs = $t0 rs
4
+ scoreboard players set $t1 rs 0
5
+ execute if score $t0 rs > $top_kills rs run scoreboard players set $t1 rs 1
6
+ execute if score $t1 rs matches 1.. run function arena:announce_leaders/foreach_0/then_0
7
+ execute if score $t1 rs matches ..0 run function arena:announce_leaders/foreach_0/merge_2
@@ -0,0 +1,4 @@
1
+ # block: then_0
2
+ tellraw @s {"text":"You are leading the arena right now."}
3
+ title @s title {"text":"Arena Leader"}
4
+ function arena:announce_leaders/foreach_1/merge_2
@@ -0,0 +1,6 @@
1
+ # block: entry
2
+ execute store result score $t0 rs run scoreboard players get @s kills
3
+ scoreboard players set $t1 rs 0
4
+ execute if score $t0 rs = $top_kills rs run scoreboard players set $t1 rs 1
5
+ execute if score $t1 rs matches 1.. run function arena:announce_leaders/foreach_1/then_0
6
+ execute if score $t1 rs matches ..0 run function arena:announce_leaders/foreach_1/merge_2
@@ -0,0 +1,4 @@
1
+ # block: then_0
2
+ say Arena update: current leader check complete.
3
+ execute as @a run function arena:announce_leaders/foreach_1
4
+ function arena:announce_leaders/merge_2
@@ -0,0 +1,6 @@
1
+ # block: entry
2
+ execute as @a run function arena:announce_leaders/foreach_0
3
+ scoreboard players set $t0 rs 0
4
+ execute if score $const_0 rs > $const_0 rs run scoreboard players set $t0 rs 1
5
+ execute if score $t0 rs matches 1.. run function arena:announce_leaders/then_0
6
+ execute if score $t0 rs matches ..0 run function arena:announce_leaders/else_1
@@ -0,0 +1 @@
1
+ # block: merge_2
@@ -0,0 +1,4 @@
1
+ # block: then_0
2
+ function arena:announce_leaders
3
+ scoreboard players operation $t5 rs = $ret rs
4
+ function arena:arena_tick/merge_2