Skip to content

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.

swoftlang
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

KeyTypeDefaultMeaning
auth:modeofflineauthentication mode — see below
host:String"0.0.0.0"bind address
port:integer25565bind port, 1–65535 (checked at compile time)
brand:Stringnonethe brand string clients see (F3 screen)
motd:Stringnoneserver-list MOTD (MiniMessage ok)
favicon:Stringnonepath to a 64×64 PNG, base64'd at boot for the server list
open_to_lan:booleanfalseannounce the server on the local network
lighting:booleantruecompute and send block/sky light — see lighting
http { ... }blockoffREST 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

ModeWrittenBoot behavior
Offlineauth: offlineno authentication (default)
Mojangauth: mojangonline-mode encryption + session validation (MojangAuth.init())
Velocityauth: velocity "forwarding-secret"modern forwarding from a Velocity proxy (VelocityProxy.enable(secret))
BungeeCordauth: bungeecordlegacy ip-forwarding from BungeeCord (BungeeCordProxy.enable())
swoftlang
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:

swoftlang
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:

FormEffect
set server motd to <string>statement — change the MOTD from any handler
server.motdread/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:

swoftlang
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):

swoftlang
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 script

Across 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:

  1. Compiles/loads every script (via swoftc or sidecars), resolving imports as it goes.
  2. Reads the single server block (or defaults).
  3. MinecraftServer.init(), applies the auth mode, sets the brand, reads the favicon, then start(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 ASTnull when no script declares one:

json
{
  "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.

swoftlang
storage {
  backend: files "data/swoftlang"
  flush: every 30 seconds
}

Backends:

BackendWrittenStorage
Files (default)backend: files "data/swoftlang"one JSON file per variable, atomic tmp+move writes
SQLitebackend: sqlite "data/swoftlang.db"table swoft_persist(var, key, value)
MySQLbackend: mysql { host: "localhost", port: 3306, database: "mc", user: "root", password: "..." }same schema
MongoDBbackend: 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.