A typed language and toolchain for building vanilla Minecraft datapacks.
Write structured code. Compile to .mcfunction. Ship without mods.
Minecraft datapacks are powerful, but real projects quickly become piles of selectors, scoreboards, generated functions, and fragile command glue.
RedScript gives you a typed language, optimizer, CLI, LSP, formatter, stdlib, and Minecraft-aware validation loop while still emitting plain vanilla datapacks.
# Vanilla mcfunction: repeat the selector and command plumbing everywhere
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: keep the game 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 in the browser and download a 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 compile hello.mcrs -o ./my-datapackDrop my-datapack/ into your world's datapacks/ folder and run /reload.
RedScript can drive live Minecraft effects from regular typed code. This demo computes a moving sine ribbon at runtime, then lowers the math into vanilla scoreboard and macro commands for particle rendering.
import "../src/stdlib/math.mcrs"
let phase: int = 0;
let running: bool = false;
fn draw_point(y: fixed) {
particle("minecraft:end_rod", ^0, ^y, ^6, 0.02, 0.02, 0.02, 0.0, 6);
}
@tick fn draw_wave() {
if (!running) { return; }
phase = (phase + 4) % 360;
foreach (p in @a) at @s {
let y: int = sin_fixed(phase) * 25;
draw_point(y as fixed);
}
}Run the full version locally:
redscript compile examples/hero-demo.mcrs -o /tmp/redscript-hero --namespace rsdemo/reload
/function rsdemo:startIt demonstrates runtime sin_fixed / cos_fixed math, fixed-point macro parameters, local-coordinate particles, @load, @tick, functions, globals, selectors, and stdlib imports — all compiled into a compact vanilla datapack.
| Feature | Example |
|---|---|
| Variables | let x: int = 42; |
| Functions | fn damage(target: selector, amount: int) { ... } |
| Control flow | if, else, for, while, foreach, match |
| Structs / impls | struct Player { score: int, alive: bool } |
| Enums | enum State { Lobby, Playing, Ended } |
| Option / Result | Some(5), Ok(42) |
| F-strings | say(f"Score: {points}"); |
| Modules | import math; math::sin(45); |
@load fn on_reload() {
say("Datapack loaded.");
}
@tick(rate=20) fn every_second() {
foreach (p in @a[tag=playing]) {
title(p, "§aReady", "§7RedScript tick handler");
}
}
fn clear_nearby_zombies() {
foreach (zombie in @e[type=zombie, distance=..10]) {
kill(zombie);
}
}
@tick fn flame_trail() {
foreach (p in @a) at @s positioned ~ ~2 ~ {
particle("minecraft:flame", ~0, ~0, ~0, 0.1, 0.1, 0.1, 0.01, 10);
}
}- Compiler pipeline — parser, type checker, HIR/MIR/LIR lowering, optimizers, and datapack emitter.
- Minecraft-aware validation — static command checks plus optional Paper/TestHarness integration tests; static diagnostics, not live Paper proof.
- Typed resource/package DX — typed
resource<particle>/resource<effect>checks, contextualnamespace:pathliterals, generated.d.mcrsdeclaration surfaces, and project-owned JSON/NBT contributions through a validated artifact graph. - LSP + VSCode extension — hover docs, go-to-definition, completion, diagnostics, snippets, and syntax highlighting.
- Formatter / linter / test runner — project tooling for maintaining larger datapacks.
- Stdlib — math, vectors, particles, inventory, scheduling, data structures, ECS-style helpers, and more.
- Numeric tuner — helper-level
.mcrsoverlay generation with reviewable manifests.
Typed tag resources can be authored directly while strict JSON/NBT remains available as an escape hatch:
resource item_tag bakery:foods {
policy merge;
value minecraft:bread;
optional tag bakery:seasonal_foods;
}
resource recipe bakery:toast from "recipes/toast.json";
resource dimension bakery:moon from "dimensions/moon.json";Typed and from-file contributions share the same versioned artifact registry, collision checks, deterministic directory/ZIP projection, and target capability boundary. The package API also exports selective, runtime-validated builders for common recipes, advancements, predicates, loot tables, and item modifiers; unknown or modded schemas stay on the from route. Paper 1.21.4 lifecycle evidence classifies normal resources and structure NBT as reloadable, while dimension / dimension_type require a world reopen.
redscript compile <file> # Compile to a datapack
redscript check <file> # Type check only
redscript fmt <file> # Format code
redscript declarations <file> --out <file.d.mcrs> # Generate package declaration surface
redscript lint <file> # Static analysis
redscript test <file> # Run @test functions
redscript watch <dir> # Watch mode with hot reload
redscript docs [module] # Open stdlib docs
redscript tune --adapter sqrt-newton --range 10000:400000 --samples 128 --out tuned.mcrs --manifest-out tuned.tune.jsonredscript tune is helper-level numeric tooling: it writes a reviewable .mcrs overlay plus an optional .tune.json manifest for the sample range, metrics, overflow report, and regeneration command. It does not change the language-level fixed scale or silently rewrite checked-in stdlib files.
RedScript ships with stdlib modules for math, data structures, game systems, and MC-specific helpers:
import math; // sin, cos, sqrt, interpolation, fixed-scale helpers
import math_hp; // higher-precision numeric helpers
import vec; // 2D/3D vectors, dot, cross, normalize
import random; // random generators
import particles; // particle helpers
import inventory; // slot manipulation
import scheduler; // delayed execution
import ecs; // entity-component style helpersFull list: Stdlib Documentation
Attribution: The
bigintmodule's multi-precision arithmetic approach was inspired by kaer-3058/large_number.
| File | Description |
|---|---|
hero-demo.mcrs |
Live particle ribbon demo |
readme-demo.mcrs |
Compact real-time sine wave |
showcase.mcrs |
Larger feature tour |
loops-demo.mcrs |
Loop constructs |
More examples live in examples/.
- Getting Started — installation and first project
- Language Reference — syntax and semantics
- Stdlib Reference — generated stdlib docs
- CLI Reference — command-line options
npm install
npm run build
npm run test:unit # pure TS/unit tests, parallel
npm run test:integration # mc-integration project, serial
npm run test:mc-lifecycle # managed Paper gate; explicit [SKIP] when unavailable
MC_P9_TEMPLATE_DIR=~/mc-test-server npm run test:mc-lifecycle:live # strict stable proof
MC_P9_VERSION_CHANNEL=paper-26.2 MC_P9_TEMPLATE_DIR=~/mc-test-server-26.2 npm run test:mc-lifecycle:live # strict 26.2 proof
npm run gate:full # heavyweight release-style gateThe managed lifecycle gate creates a disposable air-only minecraft:the_void world, applies version-correct deterministic rules through TestHarness, and restores/verifies a smooth-stone floor at y=63. The template world is never reused or modified.
See AGENTS.md and compiler hardening roadmap for current architecture and verification notes.
MIT License · bkmashiro