Server Config
SwoftLang scripts don't just run on a server — they can be the server. A server block configures how the embedded Minestom server boots: authentication, bind address, branding, the HTTP listener, permissions, and LAN discovery. No YAML, no properties files.
server {
auth: offline
host: "0.0.0.0"
port: 25565
brand: "SwoftLang"
motd: "<green>A SwoftLang server"
favicon: "server-icon.png"
open_to_lan: false
http {
port: 8080
bind: "127.0.0.1"
}
permissions {
"Swofty": ["swoftlang.admin", "swoftlang.teleport"]
"Notch": ["swoftlang.teleport"]
}
}Keys
| Key | Type | Default | Meaning |
|---|---|---|---|
auth: | mode | offline | authentication mode — see below |
host: | String | "0.0.0.0" | bind address |
port: | integer | 25565 | bind port, 1–65535 (checked at compile time) |
brand: | String | none | the brand string clients see (F3 screen) |
motd: | String | none | server-list MOTD (MiniMessage ok) |
favicon: | String | none | path to a 64×64 PNG, base64'd at boot for the server list |
open_to_lan: | boolean | false | announce the server on the local network |
lighting: | boolean | true | compute and send block/sky light — see lighting |
http { ... } | block | off | REST listener — see the HTTP API reference |
permissions { ... } | block | {} | default permission grants — see permissions |
All keys are optional — server {} is a valid offline server on the default port.
Auth modes
| Mode | Written | Boot behavior |
|---|---|---|
| Offline | auth: offline | no authentication (default) |
| Mojang | auth: mojang | online-mode encryption + session validation (MojangAuth.init()) |
| Velocity | auth: velocity "forwarding-secret" | modern forwarding from a Velocity proxy (VelocityProxy.enable(secret)) |
| BungeeCord | auth: bungeecord | legacy ip-forwarding from BungeeCord (BungeeCordProxy.enable()) |
server {
auth: velocity "hunter2-forwarding-secret"
port: 25566
}Proxy modes trust the proxy
velocity and bungeecord disable direct authentication — the proxy vouches for players. Never expose a proxy-mode server's port to the public internet; keep it reachable only from the proxy.
Permissions
Command permission: keys and has_permission(...) both ask the runtime's permission provider. The default provider reads the permissions { } map — usernames to permission lists:
server {
permissions {
"Swofty": ["swoftlang.admin", "swoftlang.teleport"]
}
}
command "sudo" {
permission: "swoftlang.admin"
execute {
send "<red>with great power..." to sender
}
}The provider is a pluggable interface on the Java side — a host server embedding SwoftLang can replace it with its own rank system, and the permissions { } block stops mattering. With neither a block nor a custom provider, everything is allowed (and logged).
Dynamic MOTD
The motd: key is the static server-list text. Two runtime surfaces make it dynamic:
| Form | Effect |
|---|---|
set server motd to <string> | statement — change the MOTD from any handler |
server.motd | read/write property, same thing as an lvalue |
event ServerPing { } | per-ping rewrite — MOTD and player counts |
ServerPing fires for each server-list ping, with motd, online, and max all writable — dynamic MOTDs and fake player counts, per ping:
event ServerPing {
execute {
set event.motd to "<green>${length(all_players())} heroes online right now"
set event.max to 1000
}
}Lighting
lighting: toggles the engine's light engine — the per-chunk sky- and block-light computation the server runs and ships to clients. It defaults to true. Setting it false skips that work entirely, which trims CPU on servers that don't need accurate shadows (minigame lobbies, fully-lit builds):
server {
auth: offline
motd: "<green>No lighting"
lighting: false
}It must be a true/false literal — anything else is a parse error:
bad_lighting.sw:3:5: error: Expected 'true' or 'false' after 'lighting:', found identifier 'maybe'The key is additive in the JSON AST: it is emitted only when set to false, so a script that never touches lighting produces byte-identical output.
One block per server
At most one server block is allowed. Two in the same file is a compile error:
e_dupserver.sw:4:1: error: duplicate 'server' block; only one server block is allowed per scriptAcross multiple script files the check moves to load time: the first server block wins and extras are reported and ignored.
Boot order
At startup the engine:
- Compiles/loads every script (via
swoftcor sidecars), resolving imports as it goes. - Reads the single
serverblock (or defaults). MinecraftServer.init(), applies the auth mode, sets the brand, reads the favicon, thenstart(host, port)— and starts the HTTP listener if configured.
Commands, events, GUIs, scoreboards, tablists, items, mobs, api routes, and schedulers from all loaded scripts (and their imported addons) are registered before the first player can connect.
JSON shape
The block compiles to the top-level "server" key of the JSON AST — null when no script declares one:
{
"auth": { "kind": "offline", "secret": null },
"host": "0.0.0.0",
"port": 25565,
"brand": "SwoftLang",
"motd": "<green>A SwoftLang server",
"http": { "port": 8080, "bind": "127.0.0.1" },
"favicon": "server-icon.png",
"permissions": { "Swofty": ["swoftlang.admin"] }
}auth.kind is one of offline, mojang, velocity (with secret), bungeecord. The phase-6 keys (http, favicon, permissions, open_to_lan) are additive and only present when used — older scripts emit byte-identical JSON.
Storage
storage is the server-block sibling for persistent variables: at most one per server, configuring where persistent declarations live and how often dirty values flush.
storage {
backend: files "data/swoftlang"
flush: every 30 seconds
}Backends:
| Backend | Written | Storage |
|---|---|---|
| Files (default) | backend: files "data/swoftlang" | one JSON file per variable, atomic tmp+move writes |
| SQLite | backend: sqlite "data/swoftlang.db" | table swoft_persist(var, key, value) |
| MySQL | backend: mysql { host: "localhost", port: 3306, database: "mc", user: "root", password: "..." } | same schema |
| MongoDB | backend: mongodb "mongodb://localhost:27017/swoftlang" | collection swoft_persist |
With no storage block, persistence defaults to files "swoftlang-data". Reads and writes always hit an in-memory cache; a background task flushes dirty entries on the flush: cadence (default 30 seconds) and on shutdown — script execution never blocks on IO.
The same backend syntax also feeds polar_storage_loader(...), so whole worlds can live in the database next to your variables.