RedScript v3.0 — match Expressions, For-Each Iteration, and Major stdlib Expansion
RedScript v3.0 — match Expressions, For-Each Iteration, and Major stdlib Expansion
RedScript v3.0 is officially released. This release focuses on making code feel more natural—less boilerplate and clearer intent expression.
match expressions
Say goodbye to long if/else chains. match makes branch logic immediately readable:
match player_state {
STATE_IDLE => { start_walking(p) }
STATE_WALKING => { check_destination(p) }
STATE_COMBAT => { update_combat(p) }
_ => { }
}
Wildcard _ handles all unlisted cases, and the compiler will prompt you if branches are missing.
match also supports parenthesized form, and match (v) { } is fully equivalent to match v { }—choose whichever style you prefer.
Option pattern matching
Together with if let, handling possibly empty values becomes clean:
let opt: Option<int> = find_target(p)
if let Some(target_id) = opt {
attack(p, target_id)
}
No more manual checks for -1 or magic sentinel values.
for item in array
v3.0 supports direct iteration over array elements without manual indexing:
// Old style
for i in 0..items.len() {
process(items[i])
}
// New style
for item in items {
process(item)
}
It is shorter and less prone to out-of-bounds mistakes.
Three new stdlib modules
state.mcrs — player state machine
Use integers to bind player states; state storage is managed uniformly by stdlib:
set_state(p, STATE_COMBAT)
let s: Option<int> = get_state(p)
get_state returns Option<int> and is None when unset; it pairs best with if let.
dialog.mcrs — dialog and UI
Three lines to set up dungeon intro prompts:
dialog_say(p, "Welcome to the dungeon!")
dialog_title(p, "Chapter 1", "City of the Lost")
dialog_actionbar(p, "§eHP: 100 / 100")
dialog_say uses chat, dialog_title uses title + subtitle, and dialog_actionbar uses action bar, covering three MC UI channels.
scheduler.mcrs — delayed task scheduling
No need to maintain custom timer scoreboards anymore:
task_schedule(p, 0, 100) // trigger task 0 after 100 ticks
// Check in @tick function
if (task_ready(p, 0) == 1) {
spawn_boss(p)
}
Each player can schedule multiple tasks independently (distinguished by task ID), and scheduler_tick() advances timing.
Combined example: dungeon opening sequence
Putting the three modules together, a dungeon intro with a waiting state only needs:
import "stdlib/state"
import "stdlib/dialog"
import "stdlib/scheduler"
const STATE_WAITING: int = 0
const STATE_STARTING: int = 1
const STATE_ACTIVE: int = 2
@on(PlayerJoin)
fn on_join(p: Player) {
set_state(p, STATE_WAITING)
dialog_title(p, "§6Doom Dungeon", "§7Waiting for more players...")
}
@tick
fn game_tick() {
scheduler_tick()
}
Player joins → sets waiting state → displays title. Later, game_tick can check player count, and once threshold is reached call task_schedule for countdown start, then dispatch phase logic with match—no extra scoreboard scaffolding needed.
Upgrade guide
Upgrading from v2.x to v3.0 is non-breaking; existing code works directly. New features are fully backward compatible:
matchis an incremental syntax addition and does not affect existingif/else.for item in arris syntax sugar forfor i in 0..n; both coexist.- The three new stdlib modules are imported as needed, with zero overhead when not used.
📖 Full docs: redscript-docs.pages.dev
Previous: RedScript 2.6: stdlib expansion, event system, and MC integration testing