redscript-mc 1.2.9 → 1.2.11
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.
- package/README.md +35 -33
- package/README.zh.md +35 -33
- package/demo.gif +0 -0
- package/dist/__tests__/mc-integration.test.js +85 -0
- package/dist/ast/types.d.ts +84 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lexer/index.d.ts +1 -1
- package/dist/lexer/index.js +2 -0
- package/dist/lowering/index.d.ts +3 -0
- package/dist/lowering/index.js +119 -11
- package/dist/optimizer/dce.js +6 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.js +171 -18
- package/package.json +1 -1
- package/src/__tests__/fixtures/array-test.mcrs +30 -0
- package/src/__tests__/fixtures/break-continue-test.mcrs +46 -0
- package/src/__tests__/fixtures/enum-test.mcrs +37 -0
- package/src/__tests__/fixtures/foreach-at-test.mcrs +33 -0
- package/src/__tests__/fixtures/match-range-test.mcrs +45 -0
- package/src/__tests__/fixtures/struct-test.mcrs +34 -0
- package/src/__tests__/mc-integration.test.ts +97 -0
- package/src/ast/types.ts +24 -1
- package/src/index.ts +1 -1
- package/src/lexer/index.ts +3 -1
- package/src/lowering/index.ts +123 -11
- package/src/optimizer/dce.ts +6 -0
- package/src/parser/index.ts +159 -18
- package/test-datapacks/README.md +67 -0
- package/test-datapacks/test_control_flow/data/minecraft/tags/function/load.json +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/__load.mcfunction +41 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/run_control_flow_tests.mcfunction +21 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/else_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/else_8.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/for_body_1.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/for_check_0.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/for_continue_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/for_exit_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/for_exit_3.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/merge_5.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/merge_6.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/merge_8.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/merge_9.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/then_3.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/then_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/then_6.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break/then_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_break.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/else_1.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/else_10.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/else_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/else_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/merge_11.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/merge_2.mcfunction +9 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/merge_5.mcfunction +7 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/merge_8.mcfunction +13 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/then_0.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/then_3.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/then_6.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions/then_9.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_complex_conditions.mcfunction +12 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/else_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/else_8.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/for_body_1.mcfunction +7 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/for_check_0.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/for_continue_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/for_exit_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/for_exit_3.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/merge_5.mcfunction +8 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/merge_6.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/merge_8.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/merge_9.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/then_3.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/then_4.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/then_6.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue/then_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_continue.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/else_13.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/else_16.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/else_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/else_5.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_body_1.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_body_10.mcfunction +8 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_body_12.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_body_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_body_8.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_check_0.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_check_11.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_check_6.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_check_7.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_check_9.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_continue_13.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_continue_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_continue_9.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_10.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_11.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_14.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_3.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/for_exit_8.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/merge_14.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/merge_17.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/merge_5.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/merge_6.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/then_12.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/then_15.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/then_3.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop/then_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_for_loop.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_at/foreach_0.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_at.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_selector/else_1.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_selector/foreach_0.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_selector/merge_2.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_selector/then_0.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_foreach_selector.mcfunction +11 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/else_1.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/else_13.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/else_16.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/else_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_11.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_14.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_17.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_5.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/merge_8.mcfunction +6 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_0.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_12.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_15.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_3.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_6.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else/then_9.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_if_else.mcfunction +6 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_0.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_1.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_2.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_3.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_5.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_6.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_7.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_8.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match/match_9.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_match.mcfunction +15 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/else_13.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/else_4.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_body_1.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_body_7.mcfunction +8 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_check_0.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_check_6.mcfunction +4 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_exit_2.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/loop_exit_8.mcfunction +5 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/merge_11.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/merge_14.mcfunction +1 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/merge_5.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/then_12.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/then_3.mcfunction +3 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop/then_9.mcfunction +2 -0
- package/test-datapacks/test_control_flow/data/test_control_flow/function/test_while_loop.mcfunction +3 -0
- package/test-datapacks/test_control_flow/pack.mcmeta +6 -0
- package/test-datapacks/test_control_flow.mcrs +242 -0
- package/test-datapacks/test_decorators/data/minecraft/tags/function/load.json +5 -0
- package/test-datapacks/test_decorators/data/minecraft/tags/function/tick.json +5 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/__load.mcfunction +20 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/__tick.mcfunction +3 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/merge_2.mcfunction +9 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/merge_5.mcfunction +1 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/then_0.mcfunction +1 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/then_3.mcfunction +4 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/tick_body.mcfunction +6 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second/tick_skip.mcfunction +1 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/every_second.mcfunction +5 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_load.mcfunction +2 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_test_trigger.mcfunction +2 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/merge_2.mcfunction +10 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/merge_5.mcfunction +5 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/merge_8.mcfunction +1 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/then_0.mcfunction +1 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/then_3.mcfunction +3 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick/then_6.mcfunction +4 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/on_tick.mcfunction +5 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/run_decorator_tests.mcfunction +7 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/setup_trigger_test.mcfunction +4 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/start_slow_tick_test.mcfunction +4 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/start_tick_test.mcfunction +4 -0
- package/test-datapacks/test_decorators/data/test_decorators/function/stop_tick_test.mcfunction +3 -0
- package/test-datapacks/test_decorators/pack.mcmeta +6 -0
- package/test-datapacks/test_decorators.mcrs +81 -0
- package/test-datapacks/test_events/data/minecraft/tags/function/load.json +5 -0
- package/test-datapacks/test_events/data/test_events/advancements/on_death_on_player_death.json +10 -0
- package/test-datapacks/test_events/data/test_events/function/__load.mcfunction +3 -0
- package/test-datapacks/test_events/data/test_events/function/on_player_death.mcfunction +3 -0
- package/test-datapacks/test_events/data/test_events/function/run_event_tests.mcfunction +5 -0
- package/test-datapacks/test_events/data/test_events/function/setup_events.mcfunction +3 -0
- package/test-datapacks/test_events/data/test_events/function/spawn_test_entity.mcfunction +3 -0
- package/test-datapacks/test_events/data/test_events/function/test_advancement_event.mcfunction +4 -0
- package/test-datapacks/test_events/pack.mcmeta +6 -0
- package/test-datapacks/test_events.mcrs +37 -0
- package/test-datapacks/test_fstrings/data/minecraft/tags/function/load.json +5 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/__load.mcfunction +10 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/run_fstring_tests.mcfunction +15 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_actionbar_fstring.mcfunction +4 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_announce.mcfunction +3 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_multi_var_fstring.mcfunction +9 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_say_fstring.mcfunction +4 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_tell.mcfunction +3 -0
- package/test-datapacks/test_fstrings/data/test_fstrings/function/test_title_fstring.mcfunction +4 -0
- package/test-datapacks/test_fstrings/pack.mcmeta +6 -0
- package/test-datapacks/test_fstrings.mcrs +58 -0
- package/test-datapacks/test_timers/data/minecraft/tags/function/load.json +5 -0
- package/test-datapacks/test_timers/data/test_timers/function/__interval_0.mcfunction +3 -0
- package/test-datapacks/test_timers/data/test_timers/function/__interval_body_0.mcfunction +5 -0
- package/test-datapacks/test_timers/data/test_timers/function/__load.mcfunction +5 -0
- package/test-datapacks/test_timers/data/test_timers/function/__timeout_0.mcfunction +2 -0
- package/test-datapacks/test_timers/data/test_timers/function/run_timer_tests.mcfunction +5 -0
- package/test-datapacks/test_timers/data/test_timers/function/test_set_interval.mcfunction +5 -0
- package/test-datapacks/test_timers/data/test_timers/function/test_set_timeout.mcfunction +3 -0
- package/test-datapacks/test_timers/pack.mcmeta +6 -0
- package/test-datapacks/test_timers.mcrs +35 -0
package/README.md
CHANGED
|
@@ -20,55 +20,56 @@ Write clean game logic. RedScript handles the scoreboard spaghetti.
|
|
|
20
20
|
|
|
21
21
|
### 🚀 [Try it online — no install needed!](https://redscript-ide.pages.dev)
|
|
22
22
|
|
|
23
|
+
<img src="./demo.gif" alt="RedScript Demo" width="400" />
|
|
24
|
+
|
|
25
|
+
*↑ Particles spawning at player position every tick — 100% vanilla, no mods! Just 30 lines of RedScript with full control flow: `if`, `foreach`, `@tick`, f-strings, and more.*
|
|
26
|
+
|
|
23
27
|
</div>
|
|
24
28
|
|
|
25
29
|
---
|
|
26
30
|
|
|
27
31
|
### What is RedScript?
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
RedScript is a typed scripting language that compiles to vanilla Minecraft datapacks. Write clean code with variables, functions, loops, and events — RedScript handles the scoreboard commands and `.mcfunction` files for you.
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
**The demo above?** Just 30 lines:
|
|
32
36
|
|
|
33
37
|
```rs
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
let counter: int = 0;
|
|
39
|
+
let running: bool = false;
|
|
40
|
+
|
|
41
|
+
@tick fn demo_tick() {
|
|
42
|
+
if (!running) { return; }
|
|
43
|
+
counter = counter + 1;
|
|
44
|
+
|
|
45
|
+
foreach (p in @a) at @s {
|
|
46
|
+
particle("minecraft:end_rod", ~0, ~1, ~0, 0.5, 0.5, 0.5, 0.1, 5);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (counter % 20 == 0) {
|
|
50
|
+
say(f"Running for {counter} ticks");
|
|
46
51
|
}
|
|
47
|
-
|
|
48
|
-
scoreboard_set(#game, #timer, time - 1);
|
|
49
|
-
actionbar(@a, "⏱ ${time}s remaining");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
fn start_game() {
|
|
53
|
-
scoreboard_set(#game, #timer, GAME_TIME);
|
|
54
|
-
scoreboard_set(#game, #running, 1);
|
|
55
|
-
title(@a, "Fight!", "Game started");
|
|
56
|
-
tp(@a, (0, 64, 0));
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
fn
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
@keep fn start() {
|
|
55
|
+
running = true;
|
|
56
|
+
counter = 0;
|
|
57
|
+
say(f"Demo started!");
|
|
63
58
|
}
|
|
64
59
|
|
|
65
|
-
@
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
@keep fn stop() {
|
|
61
|
+
running = false;
|
|
62
|
+
say(f"Demo stopped at {counter} ticks.");
|
|
68
63
|
}
|
|
69
64
|
```
|
|
70
65
|
|
|
71
|
-
|
|
66
|
+
**What you get:**
|
|
67
|
+
- ✅ `let` / `const` variables (no more `scoreboard players set`)
|
|
68
|
+
- ✅ `if` / `else` / `for` / `foreach` control flow
|
|
69
|
+
- ✅ `@tick` / `@load` / `@on(Event)` decorators
|
|
70
|
+
- ✅ `foreach (p in @a) at @s` — iterate entities with execute context
|
|
71
|
+
- ✅ f-strings like `f"Score: {points}"` for dynamic output
|
|
72
|
+
- ✅ One file → ready-to-use datapack
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
@@ -199,7 +200,8 @@ if (hp <= 0) {
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
for (let i: int = 0; i < 10; i = i + 1) {
|
|
202
|
-
|
|
203
|
+
say(f"Spawning wave {i}");
|
|
204
|
+
summon("minecraft:zombie", ~0, ~0, ~0);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
foreach (player in @a) {
|
package/README.zh.md
CHANGED
|
@@ -20,55 +20,56 @@
|
|
|
20
20
|
|
|
21
21
|
### 🚀 [在线试用 — 无需安装!](https://redscript-ide.pages.dev)
|
|
22
22
|
|
|
23
|
+
<img src="./demo.gif" alt="RedScript Demo" width="400" />
|
|
24
|
+
|
|
25
|
+
*↑ 每 tick 在玩家位置生成粒子 — 纯原版,无需 MOD!仅 30 行 RedScript,包含完整控制流:`if`、`foreach`、`@tick`、f-strings 等。*
|
|
26
|
+
|
|
23
27
|
</div>
|
|
24
28
|
|
|
25
29
|
---
|
|
26
30
|
|
|
27
31
|
### RedScript 是什么?
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
RedScript 是一门编译到原版 Minecraft 数据包的脚本语言。用变量、函数、循环、事件写代码,RedScript 帮你生成记分板命令和 `.mcfunction` 文件。
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
**上面的演示?** 只有 30 行:
|
|
32
36
|
|
|
33
37
|
```rs
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
let counter: int = 0;
|
|
39
|
+
let running: bool = false;
|
|
40
|
+
|
|
41
|
+
@tick fn demo_tick() {
|
|
42
|
+
if (!running) { return; }
|
|
43
|
+
counter = counter + 1;
|
|
44
|
+
|
|
45
|
+
foreach (p in @a) at @s {
|
|
46
|
+
particle("minecraft:end_rod", ~0, ~1, ~0, 0.5, 0.5, 0.5, 0.1, 5);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (counter % 20 == 0) {
|
|
50
|
+
say(f"已运行 {counter} ticks");
|
|
46
51
|
}
|
|
47
|
-
|
|
48
|
-
scoreboard_set(#game, #timer, time - 1);
|
|
49
|
-
actionbar(@a, "⏱ 剩余 ${time} 秒");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
fn start_game() {
|
|
53
|
-
scoreboard_set(#game, #timer, GAME_TIME);
|
|
54
|
-
scoreboard_set(#game, #running, 1);
|
|
55
|
-
title(@a, "开始战斗!", "游戏已开始");
|
|
56
|
-
tp(@a, (0, 64, 0));
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
fn
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
@keep fn start() {
|
|
55
|
+
running = true;
|
|
56
|
+
counter = 0;
|
|
57
|
+
say(f"Demo 已启动!");
|
|
63
58
|
}
|
|
64
59
|
|
|
65
|
-
@
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
@keep fn stop() {
|
|
61
|
+
running = false;
|
|
62
|
+
say(f"Demo 已停止,共运行 {counter} ticks。");
|
|
68
63
|
}
|
|
69
64
|
```
|
|
70
65
|
|
|
71
|
-
|
|
66
|
+
**你得到:**
|
|
67
|
+
- ✅ `let` / `const` 变量(告别 `scoreboard players set`)
|
|
68
|
+
- ✅ `if` / `else` / `for` / `foreach` 完整控制流
|
|
69
|
+
- ✅ `@tick` / `@load` / `@on(Event)` 装饰器
|
|
70
|
+
- ✅ `foreach (p in @a) at @s` — 遍历实体并设置执行上下文
|
|
71
|
+
- ✅ f-strings 如 `f"分数: {points}"` 动态输出
|
|
72
|
+
- ✅ 一个文件 → 可直接使用的 datapack
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
@@ -199,7 +200,8 @@ if (hp <= 0) {
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
for (let i: int = 0; i < 10; i = i + 1) {
|
|
202
|
-
|
|
203
|
+
say(f"生成第 {i} 波");
|
|
204
|
+
summon("minecraft:zombie", ~0, ~0, ~0);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
foreach (player in @a) {
|
package/demo.gif
ADDED
|
Binary file
|
|
@@ -731,4 +731,89 @@ describe('MC Integration - New Features', () => {
|
|
|
731
731
|
expect(tickResult.ok).toBe(true);
|
|
732
732
|
});
|
|
733
733
|
});
|
|
734
|
+
describe('MC Integration - Extended Coverage', () => {
|
|
735
|
+
test('struct-test.mcrs: struct instantiation and field access', async () => {
|
|
736
|
+
if (!serverOnline)
|
|
737
|
+
return;
|
|
738
|
+
writeFixtureFile('struct-test.mcrs', 'struct_test');
|
|
739
|
+
await mc.reload();
|
|
740
|
+
await mc.command('/function struct_test:__load').catch(() => { });
|
|
741
|
+
await mc.command('/function struct_test:test_struct');
|
|
742
|
+
await mc.ticks(5);
|
|
743
|
+
expect(await mc.scoreboard('#struct_x', 'rs')).toBe(10);
|
|
744
|
+
expect(await mc.scoreboard('#struct_y', 'rs')).toBe(64);
|
|
745
|
+
expect(await mc.scoreboard('#struct_z', 'rs')).toBe(-5);
|
|
746
|
+
expect(await mc.scoreboard('#struct_x2', 'rs')).toBe(15); // 10+5
|
|
747
|
+
expect(await mc.scoreboard('#struct_z2', 'rs')).toBe(-10); // -5*2
|
|
748
|
+
expect(await mc.scoreboard('#struct_alive', 'rs')).toBe(1);
|
|
749
|
+
expect(await mc.scoreboard('#struct_score', 'rs')).toBe(100);
|
|
750
|
+
});
|
|
751
|
+
test('enum-test.mcrs: enum values and match', async () => {
|
|
752
|
+
if (!serverOnline)
|
|
753
|
+
return;
|
|
754
|
+
writeFixtureFile('enum-test.mcrs', 'enum_test');
|
|
755
|
+
await mc.reload();
|
|
756
|
+
await mc.command('/function enum_test:__load').catch(() => { });
|
|
757
|
+
await mc.command('/function enum_test:test_enum');
|
|
758
|
+
await mc.ticks(5);
|
|
759
|
+
expect(await mc.scoreboard('#enum_phase', 'rs')).toBe(2); // Playing=2
|
|
760
|
+
expect(await mc.scoreboard('#enum_match', 'rs')).toBe(2); // matched Playing
|
|
761
|
+
expect(await mc.scoreboard('#enum_rank', 'rs')).toBe(10); // Diamond=10
|
|
762
|
+
expect(await mc.scoreboard('#enum_high', 'rs')).toBe(1); // Diamond > Gold
|
|
763
|
+
});
|
|
764
|
+
test('array-test.mcrs: array operations', async () => {
|
|
765
|
+
if (!serverOnline)
|
|
766
|
+
return;
|
|
767
|
+
writeFixtureFile('array-test.mcrs', 'array_test');
|
|
768
|
+
await mc.reload();
|
|
769
|
+
await mc.command('/function array_test:__load').catch(() => { });
|
|
770
|
+
await mc.command('/function array_test:test_array');
|
|
771
|
+
await mc.ticks(5);
|
|
772
|
+
expect(await mc.scoreboard('#arr_0', 'rs')).toBe(10);
|
|
773
|
+
expect(await mc.scoreboard('#arr_2', 'rs')).toBe(30);
|
|
774
|
+
expect(await mc.scoreboard('#arr_4', 'rs')).toBe(50);
|
|
775
|
+
expect(await mc.scoreboard('#arr_len', 'rs')).toBe(5);
|
|
776
|
+
expect(await mc.scoreboard('#arr_sum', 'rs')).toBe(150); // 10+20+30+40+50
|
|
777
|
+
expect(await mc.scoreboard('#arr_push', 'rs')).toBe(4); // [1,2,3,4].len
|
|
778
|
+
expect(await mc.scoreboard('#arr_pop', 'rs')).toBe(4); // popped value
|
|
779
|
+
});
|
|
780
|
+
test('break-continue-test.mcrs: break and continue statements', async () => {
|
|
781
|
+
if (!serverOnline)
|
|
782
|
+
return;
|
|
783
|
+
writeFixtureFile('break-continue-test.mcrs', 'break_continue_test');
|
|
784
|
+
await mc.reload();
|
|
785
|
+
await mc.command('/function break_continue_test:__load').catch(() => { });
|
|
786
|
+
await mc.command('/function break_continue_test:test_break_continue');
|
|
787
|
+
await mc.ticks(10);
|
|
788
|
+
expect(await mc.scoreboard('#break_at', 'rs')).toBe(5);
|
|
789
|
+
expect(await mc.scoreboard('#sum_evens', 'rs')).toBe(20); // 0+2+4+6+8
|
|
790
|
+
expect(await mc.scoreboard('#while_break', 'rs')).toBe(7);
|
|
791
|
+
expect(await mc.scoreboard('#nested_break', 'rs')).toBe(3); // outer completes 3 times
|
|
792
|
+
});
|
|
793
|
+
test('match-range-test.mcrs: match with range patterns', async () => {
|
|
794
|
+
if (!serverOnline)
|
|
795
|
+
return;
|
|
796
|
+
writeFixtureFile('match-range-test.mcrs', 'match_range_test');
|
|
797
|
+
await mc.reload();
|
|
798
|
+
await mc.command('/function match_range_test:__load').catch(() => { });
|
|
799
|
+
await mc.command('/function match_range_test:test_match_range');
|
|
800
|
+
await mc.ticks(5);
|
|
801
|
+
expect(await mc.scoreboard('#grade', 'rs')).toBe(4); // score=85 → B
|
|
802
|
+
expect(await mc.scoreboard('#boundary_59', 'rs')).toBe(1); // 59 matches 0..59
|
|
803
|
+
expect(await mc.scoreboard('#boundary_60', 'rs')).toBe(2); // 60 matches 60..100
|
|
804
|
+
expect(await mc.scoreboard('#neg_range', 'rs')).toBe(1); // -5 matches ..0
|
|
805
|
+
});
|
|
806
|
+
test('foreach-at-test.mcrs: foreach with at @s context', async () => {
|
|
807
|
+
if (!serverOnline)
|
|
808
|
+
return;
|
|
809
|
+
writeFixtureFile('foreach-at-test.mcrs', 'foreach_at_test');
|
|
810
|
+
await mc.reload();
|
|
811
|
+
await mc.fullReset({ clearArea: false, killEntities: true, resetScoreboards: false });
|
|
812
|
+
await mc.command('/function foreach_at_test:setup').catch(() => { });
|
|
813
|
+
await mc.command('/function foreach_at_test:test_foreach_at');
|
|
814
|
+
await mc.ticks(10);
|
|
815
|
+
expect(await mc.scoreboard('#foreach_count', 'rs')).toBe(3);
|
|
816
|
+
expect(await mc.scoreboard('#foreach_at_count', 'rs')).toBe(3);
|
|
817
|
+
});
|
|
818
|
+
});
|
|
734
819
|
//# sourceMappingURL=mc-integration.test.js.map
|
package/dist/ast/types.d.ts
CHANGED
|
@@ -247,6 +247,45 @@ export type ExecuteSubcommand = {
|
|
|
247
247
|
} | {
|
|
248
248
|
kind: 'at';
|
|
249
249
|
selector: EntitySelector;
|
|
250
|
+
} | {
|
|
251
|
+
kind: 'positioned';
|
|
252
|
+
x: string;
|
|
253
|
+
y: string;
|
|
254
|
+
z: string;
|
|
255
|
+
} | {
|
|
256
|
+
kind: 'positioned_as';
|
|
257
|
+
selector: EntitySelector;
|
|
258
|
+
} | {
|
|
259
|
+
kind: 'rotated';
|
|
260
|
+
yaw: string;
|
|
261
|
+
pitch: string;
|
|
262
|
+
} | {
|
|
263
|
+
kind: 'rotated_as';
|
|
264
|
+
selector: EntitySelector;
|
|
265
|
+
} | {
|
|
266
|
+
kind: 'facing';
|
|
267
|
+
x: string;
|
|
268
|
+
y: string;
|
|
269
|
+
z: string;
|
|
270
|
+
} | {
|
|
271
|
+
kind: 'facing_entity';
|
|
272
|
+
selector: EntitySelector;
|
|
273
|
+
anchor: 'eyes' | 'feet';
|
|
274
|
+
} | {
|
|
275
|
+
kind: 'anchored';
|
|
276
|
+
anchor: 'eyes' | 'feet';
|
|
277
|
+
} | {
|
|
278
|
+
kind: 'align';
|
|
279
|
+
axes: string;
|
|
280
|
+
} | {
|
|
281
|
+
kind: 'in';
|
|
282
|
+
dimension: string;
|
|
283
|
+
} | {
|
|
284
|
+
kind: 'on';
|
|
285
|
+
relation: string;
|
|
286
|
+
} | {
|
|
287
|
+
kind: 'summon';
|
|
288
|
+
entity: string;
|
|
250
289
|
} | {
|
|
251
290
|
kind: 'if_entity';
|
|
252
291
|
selector?: EntitySelector;
|
|
@@ -258,8 +297,45 @@ export type ExecuteSubcommand = {
|
|
|
258
297
|
varName?: string;
|
|
259
298
|
filters?: SelectorFilter;
|
|
260
299
|
} | {
|
|
261
|
-
kind: '
|
|
262
|
-
|
|
300
|
+
kind: 'if_block';
|
|
301
|
+
pos: [string, string, string];
|
|
302
|
+
block: string;
|
|
303
|
+
} | {
|
|
304
|
+
kind: 'unless_block';
|
|
305
|
+
pos: [string, string, string];
|
|
306
|
+
block: string;
|
|
307
|
+
} | {
|
|
308
|
+
kind: 'if_score';
|
|
309
|
+
target: string;
|
|
310
|
+
targetObj: string;
|
|
311
|
+
op: string;
|
|
312
|
+
source: string;
|
|
313
|
+
sourceObj: string;
|
|
314
|
+
} | {
|
|
315
|
+
kind: 'unless_score';
|
|
316
|
+
target: string;
|
|
317
|
+
targetObj: string;
|
|
318
|
+
op: string;
|
|
319
|
+
source: string;
|
|
320
|
+
sourceObj: string;
|
|
321
|
+
} | {
|
|
322
|
+
kind: 'if_score_range';
|
|
323
|
+
target: string;
|
|
324
|
+
targetObj: string;
|
|
325
|
+
range: string;
|
|
326
|
+
} | {
|
|
327
|
+
kind: 'unless_score_range';
|
|
328
|
+
target: string;
|
|
329
|
+
targetObj: string;
|
|
330
|
+
range: string;
|
|
331
|
+
} | {
|
|
332
|
+
kind: 'store_result';
|
|
333
|
+
target: string;
|
|
334
|
+
targetObj: string;
|
|
335
|
+
} | {
|
|
336
|
+
kind: 'store_success';
|
|
337
|
+
target: string;
|
|
338
|
+
targetObj: string;
|
|
263
339
|
};
|
|
264
340
|
export type Stmt = {
|
|
265
341
|
kind: 'let';
|
|
@@ -275,6 +351,12 @@ export type Stmt = {
|
|
|
275
351
|
kind: 'return';
|
|
276
352
|
value?: Expr;
|
|
277
353
|
span?: Span;
|
|
354
|
+
} | {
|
|
355
|
+
kind: 'break';
|
|
356
|
+
span?: Span;
|
|
357
|
+
} | {
|
|
358
|
+
kind: 'continue';
|
|
359
|
+
span?: Span;
|
|
278
360
|
} | {
|
|
279
361
|
kind: 'if';
|
|
280
362
|
cond: Expr;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Main entry point for programmatic usage.
|
|
5
5
|
*/
|
|
6
|
-
export declare const version = "1.2.
|
|
6
|
+
export declare const version = "1.2.11";
|
|
7
7
|
import type { Warning } from './lowering';
|
|
8
8
|
import { DatapackFile } from './codegen/mcfunction';
|
|
9
9
|
import type { IRModule } from './ir/types';
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.MCCommandValidator = exports.generateDatapack = exports.optimize = expor
|
|
|
9
9
|
exports.compile = compile;
|
|
10
10
|
exports.check = check;
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
-
exports.version = '1.2.
|
|
12
|
+
exports.version = '1.2.11';
|
|
13
13
|
const lexer_1 = require("./lexer");
|
|
14
14
|
const parser_1 = require("./parser");
|
|
15
15
|
const typechecker_1 = require("./typechecker");
|
package/dist/lexer/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Handles special cases like entity selectors vs decorators,
|
|
6
6
|
* range literals, and raw commands.
|
|
7
7
|
*/
|
|
8
|
-
export type TokenKind = 'fn' | 'let' | 'const' | 'if' | 'else' | 'while' | 'for' | 'foreach' | 'match' | 'return' | 'as' | 'at' | 'in' | 'is' | 'struct' | 'impl' | 'enum' | 'trigger' | 'namespace' | 'execute' | 'run' | 'unless' | 'int' | 'bool' | 'float' | 'string' | 'void' | 'BlockPos' | 'true' | 'false' | 'selector' | 'decorator' | 'int_lit' | 'float_lit' | 'byte_lit' | 'short_lit' | 'long_lit' | 'double_lit' | 'string_lit' | 'f_string' | 'range_lit' | 'rel_coord' | 'local_coord' | '+' | '-' | '*' | '/' | '%' | '~' | '^' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '!' | '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ';' | ':' | '::' | '->' | '=>' | '.' | 'ident' | 'mc_name' | 'raw_cmd' | 'eof';
|
|
8
|
+
export type TokenKind = 'fn' | 'let' | 'const' | 'if' | 'else' | 'while' | 'for' | 'foreach' | 'match' | 'return' | 'break' | 'continue' | 'as' | 'at' | 'in' | 'is' | 'struct' | 'impl' | 'enum' | 'trigger' | 'namespace' | 'execute' | 'run' | 'unless' | 'int' | 'bool' | 'float' | 'string' | 'void' | 'BlockPos' | 'true' | 'false' | 'selector' | 'decorator' | 'int_lit' | 'float_lit' | 'byte_lit' | 'short_lit' | 'long_lit' | 'double_lit' | 'string_lit' | 'f_string' | 'range_lit' | 'rel_coord' | 'local_coord' | '+' | '-' | '*' | '/' | '%' | '~' | '^' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '!' | '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '{' | '}' | '(' | ')' | '[' | ']' | ',' | ';' | ':' | '::' | '->' | '=>' | '.' | 'ident' | 'mc_name' | 'raw_cmd' | 'eof';
|
|
9
9
|
export interface Token {
|
|
10
10
|
kind: TokenKind;
|
|
11
11
|
value: string;
|
package/dist/lexer/index.js
CHANGED
package/dist/lowering/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export declare class Lowering {
|
|
|
45
45
|
private varTypes;
|
|
46
46
|
private floatVars;
|
|
47
47
|
private worldObjCounter;
|
|
48
|
+
private loopStack;
|
|
48
49
|
constructor(namespace: string, sourceRanges?: SourceRange[]);
|
|
49
50
|
lower(program: Program): IRModule;
|
|
50
51
|
private lowerFn;
|
|
@@ -54,6 +55,8 @@ export declare class Lowering {
|
|
|
54
55
|
private lowerStmt;
|
|
55
56
|
private lowerLetStmt;
|
|
56
57
|
private lowerReturnStmt;
|
|
58
|
+
private lowerBreakStmt;
|
|
59
|
+
private lowerContinueStmt;
|
|
57
60
|
private lowerIfStmt;
|
|
58
61
|
private lowerIsCheckIfStmt;
|
|
59
62
|
private lowerWhileStmt;
|