SwoftLang is a scripting language for Minecraft servers. You write .sw files in an English-flavored syntax; the swoftc compiler parses and typechecks them; a Minestom-based runtime executes them on a live server. The compiler is the point: missing-value bugs, property typos, and threading mistakes are compile errors before the server boots — this guide shows you real ones at every step.
The course
16 steps · one concept each · ending runnableset … to, inferred locals, and the core type set.05Control FlowConditions, loops, brace-free single statements.06Functions & LambdasDeclarations, returns, first-class functions.07Options — No More Nulloptional<T>, exists, and otherwise.08Player & World PropertiesThe checked property table, reads and writes.09Asyncwait, spawn, virtual threads, and coloring.10PersistencePersistent state keyed by player, saved across restarts.11GUIsDeclarative inventories and click handlers.12Items & MobsDeclare custom items and mobs and place them.13Modules & Addonsimport, export, and shared module state.14Build an RPG Item SystemA capstone tying items, events, and state together.15Offline PlayersThe OfflinePlayer type and the seen-store.16Ship ItAuth, MOTD, config — take the server live.Install Java 25
The server runs on Java 25 — Minestom tracks the latest Minecraft, which is Java-25 bytecode. Grab a JDK 25 build from Adoptium (or your package manager) and confirm:
$ java -version
openjdk version "25" ...That's the only thing you install. The swoftc compiler is baked into the server jar and extracted automatically at boot — there's no toolchain to set up and nothing to build from source.
Download the server
Grab the latest swoftlang-server.jar from the Releases page and drop it in a fresh folder. Everything lives next to the jar:
my-server/
├── swoftlang-server.jar
└── scripts/
└── hello.swWrite your first script
The server loads every .sw file in the scripts/ folder beside the jar. Create scripts/hello.sw:
command "hello" {
description: "Sends a friendly greeting"
execute {
send "<lime>Hello from SwoftLang!" to sender
}
}Run the server
java -jar swoftlang-server.jarOn boot the server compiles every script in scripts/ — any mistake surfaces as file:line:col: error: message with a caret pointing at your code, before the world loads — then starts a Minestom server on 0.0.0.0:25565 (offline mode by default; you'll configure auth, MOTD, and the rest in Step 16) and registers what it found. Join with a current Minecraft client and type /hello:
Hello from SwoftLang! — in lime green.
That's the whole loop: edit a .sw file, restart the server. Prefer save-and-see? Run with --debug:
java -jar swoftlang-server.jar --debug # tracer + hot reload on ws port 25580
java -jar swoftlang-server.jar --debug 9000 # pick the port--debug turns on two dev-workflow features:
- Hot reload on save. The server watches
scripts/and, the moment you save a.sw, recompiles just that file withswoftc. On a clean compile it applies a tick-safe reload: every declaration is re-registered from scratch — commands, event handlers, scoreboards, tablists, bossbars, GUIs, mobs, items, holograms, NPCs, block handlers — while running schedules are cancelled and script-spawned entities are torn down so nothing leaks across the swap. No JVM restart, no reconnect. If the recompile fails, the old handlers keep running and theswoftcerror is streamed to the tracer instead — a broken save never takes the server down. Persistent variables and their storage backend survive a reload untouched. - Live execution tracer. A small WebSocket server (default port
25580) streams handler enter/exit and per-statement execution events. It is best-effort and lossy under load — the tick thread never blocks on it — and costs a normal (non---debug) server nothing. This is what the VS Code extension connects to.
Editor support
Install the SwoftLang VS Code extension for syntax highlighting, inline type errors as you type, and — with --debug — a live tracer that highlights each line as it runs.
Reload is not a live migration
A reload re-runs registration, not your handlers' past effects. State held only in local variables or entity tags is rebuilt from whatever the new script does on the next event — put anything that must outlive an edit in a persistent variable.
Next: that command block, taken seriously.