A typed language that compiles to Minecraft datapacks.
Write clean code. Get vanilla datapacks. No mods required.
Minecraft datapacks are powerful but painful to write:
# Vanilla: Check if player has 100+ score and give reward
execute as @a[scores={points=100..}] run scoreboard players add @s rewards 1
execute as @a[scores={points=100..}] run scoreboard players set @s points 0
execute as @a[scores={points=100..}] run give @s minecraft:diamond 1
execute as @a[scores={points=100..}] run tellraw @s {"text":"Reward claimed!"}// RedScript: Same logic, readable
@tick fn check_rewards() {
foreach (p in @a) {
if (scoreboard_get(p, #points) >= 100) {
scoreboard_add(p, #rewards, 1);
scoreboard_set(p, #points, 0);
give(p, "minecraft:diamond", 1);
tell(p, "Reward claimed!");
}
}
}→ redscript-ide.pages.dev — Write code, download datapack.
npm install -g redscript-mc// hello.mcrs
@load fn init() {
say("Hello from RedScript!");
}
@tick fn game_loop() {
foreach (p in @a[tag=playing]) {
effect(p, "minecraft:speed", 1, 0, true);
}
}redscript build hello.mcrs -o ./my-datapackDrop my-datapack/ into your world's datapacks/ folder, run /reload. Done.
| Feature | Example |
|---|---|
| Variables | let x: int = 42; |
| Functions | fn damage(target: selector, amount: int) { ... } |
| Control flow | if, else, for, while, foreach, match |
| Structs | struct Player { score: int, alive: bool } |
| Enums | enum State { Lobby, Playing, Ended } |
| Option type | let item: Option<int> = Some(5); |
| Result type | let r: Result<int, string> = Ok(42); |
| F-strings | say(f"Score: {points}"); |
| Modules | import math; math::sin(45); |
// Decorators for game events
@tick fn every_tick() { }
@tick(rate=20) fn every_second() { }
@load fn on_datapack_load() { }
@on(PlayerJoin) fn welcome(p: Player) { }
// Entity selectors work naturally
foreach (zombie in @e[type=zombie, distance=..10]) {
kill(zombie);
}
// Execute subcommands
foreach (p in @a) at @s positioned ~ ~2 ~ {
particle("minecraft:flame", ~0, ~0, ~0, 0.1, 0.1, 0.1, 0.01, 10);
}
// Coroutines for heavy work (spread across ticks)
@coroutine(batch=100)
fn process_all() {
for (let i = 0; i < 10000; i = i + 1) {
// Won't lag — runs 100 iterations per tick
}
}- 15 optimizer passes — Dead code elimination, constant folding, inlining, etc.
- LSP — Hover docs, go-to-definition, auto-complete, diagnostics
- VSCode Extension — Full syntax highlighting and snippets
- 50 stdlib modules — Math, vectors, pathfinding, particles, and more
redscript build <file> # Compile with optimizations
redscript compile <file> # Compile without optimizations
redscript check <file> # Type check only
redscript fmt <file> # Format code
redscript lint <file> # Static analysis
redscript test <file> # Run @test functions
redscript watch <dir> # Watch mode with hot reload
redscript docs [module] # Open stdlib docs50 modules covering math, data structures, game systems, and MC-specific helpers:
import math; // sin, cos, sqrt, pow, abs
import vec; // 2D/3D vectors, dot, cross, normalize
import random; // LCG/PCG random generators
import pathfind; // A* pathfinding
import particles; // Particle helpers
import inventory; // Slot manipulation
import scheduler; // Delayed execution
import ecs; // Entity-component system
// ... and 42 moreFull list: Stdlib Documentation
| File | Description |
|---|---|
loops-demo.mcrs |
All loop constructs |
showcase.mcrs |
Full feature tour |
More in the examples/ directory.
- Getting Started — Installation and first project
- Language Reference — Complete syntax guide
- Stdlib Reference — All 50 modules documented
- CLI Reference — Command line options
MIT License · bkmashiro