redscript-mc 1.2.26 → 1.2.27

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 (219) hide show
  1. package/README.md +67 -9
  2. package/README.zh.md +61 -4
  3. package/dist/__tests__/stdlib-advanced.test.js +114 -0
  4. package/dist/__tests__/stdlib-bigint.test.d.ts +7 -0
  5. package/dist/__tests__/stdlib-bigint.test.js +428 -0
  6. package/dist/data/arena/function/__load.mcfunction +6 -0
  7. package/dist/data/arena/function/__tick.mcfunction +2 -0
  8. package/dist/data/arena/function/announce_leaders/else_1.mcfunction +3 -0
  9. package/dist/data/arena/function/announce_leaders/foreach_0/merge_2.mcfunction +1 -0
  10. package/dist/data/arena/function/announce_leaders/foreach_0/then_0.mcfunction +3 -0
  11. package/dist/data/arena/function/announce_leaders/foreach_0.mcfunction +7 -0
  12. package/dist/data/arena/function/announce_leaders/foreach_1/merge_2.mcfunction +1 -0
  13. package/dist/data/arena/function/announce_leaders/foreach_1/then_0.mcfunction +4 -0
  14. package/dist/data/arena/function/announce_leaders/foreach_1.mcfunction +6 -0
  15. package/dist/data/arena/function/announce_leaders/merge_2.mcfunction +1 -0
  16. package/dist/data/arena/function/announce_leaders/then_0.mcfunction +4 -0
  17. package/dist/data/arena/function/announce_leaders.mcfunction +6 -0
  18. package/dist/data/arena/function/arena_tick/merge_2.mcfunction +1 -0
  19. package/dist/data/arena/function/arena_tick/then_0.mcfunction +4 -0
  20. package/dist/data/arena/function/arena_tick.mcfunction +11 -0
  21. package/dist/data/counter/function/__load.mcfunction +5 -0
  22. package/dist/data/counter/function/__tick.mcfunction +2 -0
  23. package/dist/data/counter/function/counter_tick/merge_2.mcfunction +1 -0
  24. package/dist/data/counter/function/counter_tick/then_0.mcfunction +3 -0
  25. package/dist/data/counter/function/counter_tick.mcfunction +11 -0
  26. package/dist/data/gcd2/function/__load.mcfunction +3 -0
  27. package/dist/data/gcd2/function/abs/merge_2.mcfunction +3 -0
  28. package/dist/data/gcd2/function/abs/then_0.mcfunction +5 -0
  29. package/dist/data/gcd2/function/abs.mcfunction +7 -0
  30. package/dist/data/gcd2/function/gcd/loop_body_1.mcfunction +7 -0
  31. package/dist/data/gcd2/function/gcd/loop_check_0.mcfunction +5 -0
  32. package/dist/data/gcd2/function/gcd/loop_exit_2.mcfunction +3 -0
  33. package/dist/data/gcd2/function/gcd.mcfunction +14 -0
  34. package/dist/data/gcd3/function/__load.mcfunction +3 -0
  35. package/dist/data/gcd3/function/abs/merge_2.mcfunction +3 -0
  36. package/dist/data/gcd3/function/abs/then_0.mcfunction +5 -0
  37. package/dist/data/gcd3/function/abs.mcfunction +7 -0
  38. package/dist/data/gcd3/function/gcd/loop_body_1.mcfunction +7 -0
  39. package/dist/data/gcd3/function/gcd/loop_check_0.mcfunction +5 -0
  40. package/dist/data/gcd3/function/gcd/loop_exit_2.mcfunction +3 -0
  41. package/dist/data/gcd3/function/gcd.mcfunction +14 -0
  42. package/dist/data/gcd3/function/test.mcfunction +7 -0
  43. package/dist/data/gcd3nm/function/__load.mcfunction +3 -0
  44. package/dist/data/gcd3nm/function/abs/merge_2.mcfunction +3 -0
  45. package/dist/data/gcd3nm/function/abs/then_0.mcfunction +5 -0
  46. package/dist/data/gcd3nm/function/abs.mcfunction +7 -0
  47. package/dist/data/gcd3nm/function/gcd/loop_body_1.mcfunction +7 -0
  48. package/dist/data/gcd3nm/function/gcd/loop_check_0.mcfunction +5 -0
  49. package/dist/data/gcd3nm/function/gcd/loop_exit_2.mcfunction +3 -0
  50. package/dist/data/gcd3nm/function/gcd.mcfunction +14 -0
  51. package/dist/data/gcd3nm/function/test.mcfunction +7 -0
  52. package/dist/data/gcd_test/function/__load.mcfunction +3 -0
  53. package/dist/data/gcd_test/function/abs/merge_2.mcfunction +3 -0
  54. package/dist/data/gcd_test/function/abs/then_0.mcfunction +5 -0
  55. package/dist/data/gcd_test/function/abs.mcfunction +7 -0
  56. package/dist/data/gcd_test/function/gcd/loop_body_1.mcfunction +7 -0
  57. package/dist/data/gcd_test/function/gcd/loop_check_0.mcfunction +5 -0
  58. package/dist/data/gcd_test/function/gcd/loop_exit_2.mcfunction +3 -0
  59. package/dist/data/gcd_test/function/gcd.mcfunction +14 -0
  60. package/dist/data/isqrttest/function/__load.mcfunction +6 -0
  61. package/dist/data/isqrttest/function/isqrt/loop_body_4.mcfunction +12 -0
  62. package/dist/data/isqrttest/function/isqrt/loop_check_3.mcfunction +5 -0
  63. package/dist/data/isqrttest/function/isqrt/loop_exit_5.mcfunction +3 -0
  64. package/dist/data/isqrttest/function/isqrt/merge_2.mcfunction +4 -0
  65. package/dist/data/isqrttest/function/isqrt/merge_8.mcfunction +6 -0
  66. package/dist/data/isqrttest/function/isqrt/then_0.mcfunction +3 -0
  67. package/dist/data/isqrttest/function/isqrt/then_6.mcfunction +3 -0
  68. package/dist/data/isqrttest/function/isqrt.mcfunction +7 -0
  69. package/dist/data/isqrttest/function/test.mcfunction +6 -0
  70. package/dist/data/mathtest/function/__load.mcfunction +3 -0
  71. package/dist/data/mathtest/function/abs/merge_2.mcfunction +3 -0
  72. package/dist/data/mathtest/function/abs/then_0.mcfunction +5 -0
  73. package/dist/data/mathtest/function/abs.mcfunction +6 -0
  74. package/dist/data/mathtest/function/test.mcfunction +5 -0
  75. package/dist/data/minecraft/tags/function/load.json +5 -0
  76. package/dist/data/minecraft/tags/function/tick.json +5 -0
  77. package/dist/data/mypack/function/__load.mcfunction +13 -0
  78. package/dist/data/mypack/function/_atan_init.mcfunction +2 -0
  79. package/dist/data/mypack/function/abs/merge_2.mcfunction +3 -0
  80. package/dist/data/mypack/function/abs/then_0.mcfunction +5 -0
  81. package/dist/data/mypack/function/abs.mcfunction +6 -0
  82. package/dist/data/mypack/function/atan2_fixed/__sgi_1.mcfunction +2 -0
  83. package/dist/data/mypack/function/atan2_fixed/else_34.mcfunction +3 -0
  84. package/dist/data/mypack/function/atan2_fixed/loop_body_31.mcfunction +19 -0
  85. package/dist/data/mypack/function/atan2_fixed/loop_check_30.mcfunction +5 -0
  86. package/dist/data/mypack/function/atan2_fixed/loop_exit_32.mcfunction +6 -0
  87. package/dist/data/mypack/function/atan2_fixed/merge_11.mcfunction +6 -0
  88. package/dist/data/mypack/function/atan2_fixed/merge_14.mcfunction +3 -0
  89. package/dist/data/mypack/function/atan2_fixed/merge_17.mcfunction +6 -0
  90. package/dist/data/mypack/function/atan2_fixed/merge_2.mcfunction +5 -0
  91. package/dist/data/mypack/function/atan2_fixed/merge_20.mcfunction +5 -0
  92. package/dist/data/mypack/function/atan2_fixed/merge_23.mcfunction +5 -0
  93. package/dist/data/mypack/function/atan2_fixed/merge_26.mcfunction +6 -0
  94. package/dist/data/mypack/function/atan2_fixed/merge_29.mcfunction +4 -0
  95. package/dist/data/mypack/function/atan2_fixed/merge_38.mcfunction +5 -0
  96. package/dist/data/mypack/function/atan2_fixed/merge_41.mcfunction +5 -0
  97. package/dist/data/mypack/function/atan2_fixed/merge_44.mcfunction +5 -0
  98. package/dist/data/mypack/function/atan2_fixed/merge_47.mcfunction +5 -0
  99. package/dist/data/mypack/function/atan2_fixed/merge_5.mcfunction +5 -0
  100. package/dist/data/mypack/function/atan2_fixed/merge_8.mcfunction +3 -0
  101. package/dist/data/mypack/function/atan2_fixed/then_0.mcfunction +5 -0
  102. package/dist/data/mypack/function/atan2_fixed/then_12.mcfunction +3 -0
  103. package/dist/data/mypack/function/atan2_fixed/then_15.mcfunction +5 -0
  104. package/dist/data/mypack/function/atan2_fixed/then_18.mcfunction +5 -0
  105. package/dist/data/mypack/function/atan2_fixed/then_21.mcfunction +3 -0
  106. package/dist/data/mypack/function/atan2_fixed/then_24.mcfunction +3 -0
  107. package/dist/data/mypack/function/atan2_fixed/then_27.mcfunction +6 -0
  108. package/dist/data/mypack/function/atan2_fixed/then_3.mcfunction +3 -0
  109. package/dist/data/mypack/function/atan2_fixed/then_33.mcfunction +5 -0
  110. package/dist/data/mypack/function/atan2_fixed/then_36.mcfunction +5 -0
  111. package/dist/data/mypack/function/atan2_fixed/then_39.mcfunction +5 -0
  112. package/dist/data/mypack/function/atan2_fixed/then_42.mcfunction +3 -0
  113. package/dist/data/mypack/function/atan2_fixed/then_45.mcfunction +5 -0
  114. package/dist/data/mypack/function/atan2_fixed/then_6.mcfunction +3 -0
  115. package/dist/data/mypack/function/atan2_fixed/then_9.mcfunction +5 -0
  116. package/dist/data/mypack/function/atan2_fixed.mcfunction +7 -0
  117. package/dist/data/mypack/function/my_game.mcfunction +10 -0
  118. package/dist/data/quiz/function/__load.mcfunction +16 -0
  119. package/dist/data/quiz/function/__tick.mcfunction +6 -0
  120. package/dist/data/quiz/function/__trigger_quiz_a_dispatch.mcfunction +4 -0
  121. package/dist/data/quiz/function/__trigger_quiz_b_dispatch.mcfunction +4 -0
  122. package/dist/data/quiz/function/__trigger_quiz_c_dispatch.mcfunction +4 -0
  123. package/dist/data/quiz/function/__trigger_quiz_start_dispatch.mcfunction +4 -0
  124. package/dist/data/quiz/function/answer_a.mcfunction +4 -0
  125. package/dist/data/quiz/function/answer_b.mcfunction +4 -0
  126. package/dist/data/quiz/function/answer_c.mcfunction +4 -0
  127. package/dist/data/quiz/function/ask_question/else_1.mcfunction +5 -0
  128. package/dist/data/quiz/function/ask_question/else_4.mcfunction +5 -0
  129. package/dist/data/quiz/function/ask_question/else_7.mcfunction +4 -0
  130. package/dist/data/quiz/function/ask_question/merge_2.mcfunction +1 -0
  131. package/dist/data/quiz/function/ask_question/merge_5.mcfunction +2 -0
  132. package/dist/data/quiz/function/ask_question/merge_8.mcfunction +2 -0
  133. package/dist/data/quiz/function/ask_question/then_0.mcfunction +4 -0
  134. package/dist/data/quiz/function/ask_question/then_3.mcfunction +4 -0
  135. package/dist/data/quiz/function/ask_question/then_6.mcfunction +4 -0
  136. package/dist/data/quiz/function/ask_question.mcfunction +7 -0
  137. package/dist/data/quiz/function/finish_quiz.mcfunction +6 -0
  138. package/dist/data/quiz/function/handle_answer/else_1.mcfunction +5 -0
  139. package/dist/data/quiz/function/handle_answer/else_10.mcfunction +3 -0
  140. package/dist/data/quiz/function/handle_answer/else_16.mcfunction +3 -0
  141. package/dist/data/quiz/function/handle_answer/else_4.mcfunction +3 -0
  142. package/dist/data/quiz/function/handle_answer/else_7.mcfunction +5 -0
  143. package/dist/data/quiz/function/handle_answer/merge_11.mcfunction +2 -0
  144. package/dist/data/quiz/function/handle_answer/merge_14.mcfunction +2 -0
  145. package/dist/data/quiz/function/handle_answer/merge_17.mcfunction +2 -0
  146. package/dist/data/quiz/function/handle_answer/merge_2.mcfunction +8 -0
  147. package/dist/data/quiz/function/handle_answer/merge_5.mcfunction +2 -0
  148. package/dist/data/quiz/function/handle_answer/merge_8.mcfunction +2 -0
  149. package/dist/data/quiz/function/handle_answer/then_0.mcfunction +5 -0
  150. package/dist/data/quiz/function/handle_answer/then_12.mcfunction +5 -0
  151. package/dist/data/quiz/function/handle_answer/then_15.mcfunction +6 -0
  152. package/dist/data/quiz/function/handle_answer/then_3.mcfunction +6 -0
  153. package/dist/data/quiz/function/handle_answer/then_6.mcfunction +5 -0
  154. package/dist/data/quiz/function/handle_answer/then_9.mcfunction +6 -0
  155. package/dist/data/quiz/function/handle_answer.mcfunction +11 -0
  156. package/dist/data/quiz/function/start_quiz.mcfunction +5 -0
  157. package/dist/data/reqtest/function/__load.mcfunction +4 -0
  158. package/dist/data/reqtest/function/_table_init.mcfunction +2 -0
  159. package/dist/data/reqtest/function/no_trig.mcfunction +3 -0
  160. package/dist/data/reqtest/function/use_table.mcfunction +4 -0
  161. package/dist/data/reqtest2/function/__load.mcfunction +3 -0
  162. package/dist/data/reqtest2/function/no_trig.mcfunction +3 -0
  163. package/dist/data/runtime/function/__load.mcfunction +5 -0
  164. package/dist/data/runtime/function/__tick.mcfunction +2 -0
  165. package/dist/data/runtime/function/counter_tick/then_0.mcfunction +3 -0
  166. package/dist/data/runtime/function/counter_tick.mcfunction +13 -0
  167. package/dist/data/shop/function/__load.mcfunction +7 -0
  168. package/dist/data/shop/function/__tick.mcfunction +3 -0
  169. package/dist/data/shop/function/__trigger_shop_buy_dispatch.mcfunction +4 -0
  170. package/dist/data/shop/function/complete_purchase/else_1.mcfunction +5 -0
  171. package/dist/data/shop/function/complete_purchase/else_4.mcfunction +5 -0
  172. package/dist/data/shop/function/complete_purchase/else_7.mcfunction +3 -0
  173. package/dist/data/shop/function/complete_purchase/merge_2.mcfunction +2 -0
  174. package/dist/data/shop/function/complete_purchase/merge_5.mcfunction +2 -0
  175. package/dist/data/shop/function/complete_purchase/merge_8.mcfunction +2 -0
  176. package/dist/data/shop/function/complete_purchase/then_0.mcfunction +4 -0
  177. package/dist/data/shop/function/complete_purchase/then_3.mcfunction +4 -0
  178. package/dist/data/shop/function/complete_purchase/then_6.mcfunction +4 -0
  179. package/dist/data/shop/function/complete_purchase.mcfunction +7 -0
  180. package/dist/data/shop/function/handle_shop_trigger.mcfunction +3 -0
  181. package/dist/data/swap_test/function/__load.mcfunction +3 -0
  182. package/dist/data/swap_test/function/gcd_old/loop_body_1.mcfunction +7 -0
  183. package/dist/data/swap_test/function/gcd_old/loop_check_0.mcfunction +5 -0
  184. package/dist/data/swap_test/function/gcd_old/loop_exit_2.mcfunction +3 -0
  185. package/dist/data/swap_test/function/gcd_old.mcfunction +8 -0
  186. package/dist/data/turret/function/__load.mcfunction +5 -0
  187. package/dist/data/turret/function/__tick.mcfunction +4 -0
  188. package/dist/data/turret/function/__trigger_deploy_turret_dispatch.mcfunction +4 -0
  189. package/dist/data/turret/function/deploy_turret.mcfunction +8 -0
  190. package/dist/data/turret/function/turret_tick/at_1.mcfunction +2 -0
  191. package/dist/data/turret/function/turret_tick/foreach_0.mcfunction +2 -0
  192. package/dist/data/turret/function/turret_tick/foreach_2.mcfunction +2 -0
  193. package/dist/data/turret/function/turret_tick/tick_body.mcfunction +3 -0
  194. package/dist/data/turret/function/turret_tick/tick_skip.mcfunction +1 -0
  195. package/dist/data/turret/function/turret_tick.mcfunction +5 -0
  196. package/dist/gcd2.map.json +15 -0
  197. package/dist/gcd3.map.json +17 -0
  198. package/dist/gcd_test.map.json +15 -0
  199. package/dist/isqrttest.map.json +15 -0
  200. package/dist/lowering/index.js +71 -4
  201. package/dist/mathtest.map.json +6 -0
  202. package/dist/mypack.map.json +27 -0
  203. package/dist/pack.mcmeta +6 -0
  204. package/dist/reqtest.map.json +4 -0
  205. package/dist/reqtest2.map.json +4 -0
  206. package/dist/runtime/index.js +26 -5
  207. package/dist/runtime.map.json +7 -0
  208. package/dist/swap_test.map.json +14 -0
  209. package/editors/vscode/package-lock.json +2 -2
  210. package/editors/vscode/package.json +1 -1
  211. package/examples/showcase.mcrs +505 -0
  212. package/package.json +1 -1
  213. package/src/__tests__/stdlib-advanced.test.ts +120 -0
  214. package/src/__tests__/stdlib-bigint.test.ts +427 -0
  215. package/src/lowering/index.ts +75 -4
  216. package/src/runtime/index.ts +27 -5
  217. package/src/stdlib/advanced.mcrs +81 -0
  218. package/src/stdlib/bigint.mcrs +205 -0
  219. package/src/stdlib/math.mcrs +19 -6
@@ -130,6 +130,7 @@ const BUILTINS = {
130
130
  clearInterval: () => null, // Special handling
131
131
  storage_get_int: () => null, // Special handling (dynamic NBT array read via macro)
132
132
  storage_set_array: () => null, // Special handling (write literal NBT array to storage)
133
+ storage_set_int: () => null, // Special handling (dynamic NBT array write via macro)
133
134
  };
134
135
  function getSpan(node) {
135
136
  return node?.span;
@@ -339,12 +340,30 @@ class Lowering {
339
340
  }
340
341
  preScanExpr(expr, paramNames, macroParams) {
341
342
  if (expr.kind === 'call' && BUILTINS[expr.fn] !== undefined) {
342
- // All ident args to macro-aware builtins that are params → macro params
343
- for (const arg of expr.args) {
344
- if (arg.kind === 'ident' && paramNames.has(arg.name)) {
345
- macroParams.add(arg.name);
343
+ // Only trigger macro param detection for builtins that actually emit
344
+ // MC commands with $(param) inline in the current function body.
345
+ // Special-handled builtins (storage_get_int / storage_set_int / etc.) are
346
+ // declared as `() => null` — they create their own sub-functions for macro
347
+ // indirection and do NOT require the surrounding function to be a macro.
348
+ const handler = BUILTINS[expr.fn];
349
+ const isSpecialHandled = (() => {
350
+ try {
351
+ return handler() === null;
352
+ }
353
+ catch {
354
+ return false;
355
+ }
356
+ })();
357
+ if (!isSpecialHandled) {
358
+ for (const arg of expr.args) {
359
+ if (arg.kind === 'ident' && paramNames.has(arg.name)) {
360
+ macroParams.add(arg.name);
361
+ }
346
362
  }
347
363
  }
364
+ // Always recurse into args for nested calls/expressions
365
+ for (const arg of expr.args)
366
+ this.preScanExpr(arg, paramNames, macroParams);
348
367
  return;
349
368
  }
350
369
  // Recurse into sub-expressions for other call types
@@ -2289,6 +2308,54 @@ class Lowering {
2289
2308
  this.builder.emitRaw(`data modify storage ${storageNs} ${arrayKey} set value ${nbtLiteral}`);
2290
2309
  return { kind: 'const', value: 0 };
2291
2310
  }
2311
+ // storage_set_int(storage_ns, array_key, index, value) -> void
2312
+ // Writes one integer element into an NBT int-array stored in data storage.
2313
+ // storage_ns : e.g. "rs:bigint"
2314
+ // array_key : e.g. "a"
2315
+ // index : element index (const or runtime)
2316
+ // value : integer value to write (const or runtime)
2317
+ //
2318
+ // Const index + const value:
2319
+ // execute store result storage <ns> <key>[N] int 1 run scoreboard players set $const_V rs V
2320
+ // Runtime index or value: macro sub-function via rs:heap
2321
+ if (name === 'storage_set_int') {
2322
+ const storageNs = this.exprToString(args[0]);
2323
+ const arrayKey = this.exprToString(args[1]);
2324
+ const indexOperand = this.lowerExpr(args[2]);
2325
+ const valueOperand = this.lowerExpr(args[3]);
2326
+ if (indexOperand.kind === 'const') {
2327
+ // Static index — use execute store result to write to the fixed slot
2328
+ const valVar = valueOperand.kind === 'var'
2329
+ ? valueOperand.name
2330
+ : this.operandToVar(valueOperand);
2331
+ this.builder.emitRaw(`execute store result storage ${storageNs} ${arrayKey}[${indexOperand.value}] int 1 run scoreboard players get ${valVar} rs`);
2332
+ }
2333
+ else {
2334
+ // Runtime index: we need a macro sub-function.
2335
+ // Store index + value into rs:heap, call macro that does:
2336
+ // $data modify storage <ns> <key>[$(idx_key)] set value $(val_key)
2337
+ const macroIdxKey = `__ssi_i_${this.foreachCounter++}`;
2338
+ const macroValKey = `__ssi_v_${this.foreachCounter++}`; // kept to pin valVar in optimizer
2339
+ const subFnName = `${this.currentFn}/__ssi_${this.foreachCounter++}`;
2340
+ const indexVar = indexOperand.kind === 'var'
2341
+ ? indexOperand.name
2342
+ : this.operandToVar(indexOperand);
2343
+ const valVar = valueOperand.kind === 'var'
2344
+ ? valueOperand.name
2345
+ : this.operandToVar(valueOperand);
2346
+ this.builder.emitRaw(`execute store result storage rs:heap ${macroIdxKey} int 1 run scoreboard players get ${indexVar} rs`);
2347
+ // Pin valVar in the optimizer's read-set so the assignment is not dead-code-eliminated.
2348
+ // The value is stored to rs:heap but NOT used by the macro (the macro reads the scoreboard
2349
+ // slot directly to avoid the MC 'data modify set value $(n)' macro substitution bug).
2350
+ this.builder.emitRaw(`execute store result storage rs:heap ${macroValKey} int 1 run scoreboard players get ${valVar} rs`);
2351
+ this.builder.emitRaw(`function ${this.namespace}:${subFnName} with storage rs:heap`);
2352
+ // Use execute store result (not 'data modify set value $(val)') to avoid MC macro
2353
+ // substitution bugs with numeric values. The scoreboard slot ${valVar} is hardcoded
2354
+ // into the macro sub-function at compile time — only the array index is macro-substituted.
2355
+ this.emitRawSubFunction(subFnName, `\x01execute store result storage ${storageNs} ${arrayKey}[$(${macroIdxKey})] int 1 run scoreboard players get ${valVar} rs`);
2356
+ }
2357
+ return { kind: 'const', value: 0 };
2358
+ }
2292
2359
  // data_merge(target, nbt) — merge NBT into entity/block/storage
2293
2360
  // data_merge(@s, { Invisible: 1b, Silent: 1b })
2294
2361
  if (name === 'data_merge') {
@@ -0,0 +1,6 @@
1
+ {
2
+ "$b": "x",
3
+ "$a": "const:0",
4
+ "$c": "internal:p0",
5
+ "$f": "internal:ret"
6
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$o": "x",
3
+ "$r": "execute",
4
+ "$u": "y",
5
+ "$aa": "ax",
6
+ "$ad": "ay",
7
+ "$ai": "swapped",
8
+ "$ak": "tmp",
9
+ "$al": "lo",
10
+ "$am": "hi",
11
+ "$ar": "mid",
12
+ "$as": "t",
13
+ "$ax": "theta",
14
+ "$a": "const:0",
15
+ "$b": "const:1",
16
+ "$c": "const:2",
17
+ "$d": "const:45",
18
+ "$e": "const:90",
19
+ "$f": "const:180",
20
+ "$g": "const:270",
21
+ "$h": "const:360",
22
+ "$i": "const:1000",
23
+ "$j": "const:46340",
24
+ "$k": "internal:ret",
25
+ "$n": "internal:p0",
26
+ "$t": "internal:p1"
27
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "pack": {
3
+ "pack_format": 26,
4
+ "description": "mypack datapack — compiled by redscript"
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "$a": "const:42",
3
+ "$b": "internal:ret"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "$a": "const:42",
3
+ "$b": "internal:ret"
4
+ }
@@ -647,17 +647,27 @@ class MCRuntime {
647
647
  condition = condition && entities.length === 0;
648
648
  continue;
649
649
  }
650
- // Handle 'store result storage <ns:path> <field> <type> <scale>'
650
+ // Handle 'store result storage <ns:path> <field>[<idx>] <type> <scale>' (array element)
651
651
  if (rest.startsWith('store result storage ')) {
652
- rest = rest.slice(21);
653
- // format: <ns:path> <field> <type> <scale> <run-cmd>
654
- const storageParts = rest.match(/^(\S+)\s+(\S+)\s+(\S+)\s+([\d.]+)\s+(.*)$/);
652
+ const sliced = rest.slice(21);
653
+ // Try array-index form first: <ns:path> <field>[<idx>] <type> <scale> <run-cmd>
654
+ // Use [^\[\s]+ for field (no brackets or spaces) so that \[ matches correctly.
655
+ const arrParts = sliced.match(/^(\S+)\s+([^\[\s]+)\[(\d+)\]\s+(\S+)\s+([\d.]+)\s+(.*)$/);
656
+ if (arrParts) {
657
+ const [, storagePath, field, indexStr, , , remaining] = arrParts;
658
+ storeTarget = { storagePath, field: `${field}[${indexStr}]`, type: 'result' };
659
+ rest = remaining.trim();
660
+ continue;
661
+ }
662
+ // Plain form: <ns:path> <field> <type> <scale> <run-cmd>
663
+ const storageParts = sliced.match(/^(\S+)\s+(\S+)\s+(\S+)\s+([\d.]+)\s+(.*)$/);
655
664
  if (storageParts) {
656
665
  const [, storagePath, field, , , remaining] = storageParts;
657
666
  storeTarget = { storagePath, field, type: 'result' };
658
667
  rest = remaining.trim();
659
668
  continue;
660
669
  }
670
+ rest = sliced;
661
671
  }
662
672
  // Handle 'store result score <player> <obj>'
663
673
  if (rest.startsWith('store result score ')) {
@@ -771,8 +781,19 @@ class MCRuntime {
771
781
  }
772
782
  return true;
773
783
  }
784
+ // data modify storage <ns:path> <field>[<index>] set value <val> (array element write)
785
+ const setArrMatch = cmd.match(/^data modify storage (\S+) ([^\[\s]+)\[(\d+)\] set value (.+)$/);
786
+ if (setArrMatch) {
787
+ const [, storagePath, field, indexStr, valueStr] = setArrMatch;
788
+ const arr = this.getStorageField(storagePath, field);
789
+ const idx = parseInt(indexStr, 10);
790
+ if (Array.isArray(arr) && idx >= 0 && idx < arr.length) {
791
+ arr[idx] = this.parseDataValue(valueStr);
792
+ }
793
+ return true;
794
+ }
774
795
  // data get storage <ns:path> <field>[<index>] [scale] (array element access)
775
- const getArrMatch = cmd.match(/^data get storage (\S+) (\S+)\[(\d+)\](?:\s+[\d.]+)?$/);
796
+ const getArrMatch = cmd.match(/^data get storage (\S+) ([^\[\s]+)\[(\d+)\](?:\s+[\d.]+)?$/);
776
797
  if (getArrMatch) {
777
798
  const [, storagePath, field, indexStr] = getArrMatch;
778
799
  const arr = this.getStorageField(storagePath, field);
@@ -0,0 +1,7 @@
1
+ {
2
+ "$d": "ticks",
3
+ "$a": "const:0",
4
+ "$b": "const:1",
5
+ "$c": "const:100",
6
+ "$i": "internal:ret"
7
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$b": "a",
3
+ "$d": "b",
4
+ "$f": "p0",
5
+ "$g": "p1",
6
+ "$h": "x",
7
+ "$i": "y",
8
+ "$k": "tmp",
9
+ "$n": "m",
10
+ "$a": "const:0",
11
+ "$c": "internal:p0",
12
+ "$e": "internal:p1",
13
+ "$m": "internal:ret"
14
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "redscript-vscode",
3
- "version": "1.0.28",
3
+ "version": "1.0.31",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "redscript-vscode",
9
- "version": "1.0.28",
9
+ "version": "1.0.31",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "redscript": "file:../../"
@@ -2,7 +2,7 @@
2
2
  "name": "redscript-vscode",
3
3
  "displayName": "RedScript for Minecraft",
4
4
  "description": "Syntax highlighting, error diagnostics, and language support for RedScript — a compiler targeting Minecraft Java Edition",
5
- "version": "1.0.28",
5
+ "version": "1.0.31",
6
6
  "publisher": "bkmashiro",
7
7
  "icon": "icon.png",
8
8
  "license": "MIT",