Skip to content
Ironlark is in closed pre-alpha. Join the Discord for access.

Configuration

An instance is configured by one file, config/server.toml, beside the install. Sections inside it, never a file per topic. If you have never written one, that is fine — a missing file is ordinary, and every key below has a default.

Every section this file can carry, each with a value you might actually write:

[session]
mods = ["ironlark:echo", "acme:janitor"]
gamemode = "ironlark:freeroam"
map = "ironlark:badgrass"
[content]
root = "/srv/ironlark/content"
[[grants.rule]]
to = "acme:janitor"
verbs = ["read", "remove"]
over = "owner:*"
[limits]
memory_mb = 256
[audio]
enabled = true
muted_mods = ["acme:janitor"]
device = "pipewire"
[audio.gain]
effects = 1.0
environment = 1.0
music = 0.8
interface = 1.0
voice = 1.0
[mods."ironlark:echo"]
disabled-hooks = ["echo"]

Every key is optional. A missing file is ordinary — somebody who installed the game and pressed Host has never written one. A file that exists and does not parse is an error and stops the process: you wrote it and meant it, and running a different configuration than you asked for is worse than refusing to start.

Mods are named by their full two-segment id, author:mod — ironlark:freeroam, acme:janitor. See Mod identity.

What this instance runs: the content it enables, and the selections it makes from that content.

Key Type Meaning
mods list of ids Mods to enable. Typically the roots you want; each mod’s own requirements pull the rest in. Enabled mods is the full story.
gamemode id Which mod holds the gamemode role — the session’s baseline rule layer.
map id Map to load. Absent means ironlark:badgrass, which ships with the game.

mods has three states, and they are three different intentions:

Written Means
key absent nobody has curated this install; everything installed runs
mods = [] curated down to the baseline alone
mods = [...] the baseline plus exactly these and what they need

The list’s order is only the tiebreak between mods neither of which needs the other — load order is derived from what mods declare they need, and Enabled mods explains both.

gamemode unset resolves to the only installed candidate. With none installed, the session runs bare on the host’s own spawn. With several and no choice made, the session refuses to start and names them — the host will not guess which rules you meant.

Key Type Meaning
root path Directory holding workshop/. Absent means the install’s own assets/.

Content is deployed unlike anything else here: the same mods back many instances, the directory can be read-only, and one copy can sit behind several instances at once. That is why it is its own section and its own path.

Authority over entities a mod did not create, one [[grants.rule]] row per grant. Absent means nothing is granted, which is what a machine that has never stated a policy has decided. If you run no cleanup or moderation mod, you never write this section — Grants covers the rows, the scope grammar and the log lines that confirm what was resolved.

Key Type Meaning
memory_mb integer Memory ceiling per mod, in MiB. Absent means 128.

The ceiling applies to each mod’s linear memory and its garbage-collected heap separately, so a mod that ships an interpreter pays for both. A mod that grows past it is stopped by name and taken out of the session rather than restarted, because a fresh copy would hit the same ceiling.

This is the one resource limit that is yours to set, because it is the one where you know something the host cannot: whether this instance is a small container or a machine expected to carry a heavy scripting pack. A value below 2 refuses to start — no shipped mod can instantiate under it.

Like [grants], this section is read only by the host; nothing here is ever handed to a mod.

The one section that belongs to whoever is sitting at this machine rather than to the deployment. The host decides what is offered; what is heard is decided here. A headless build reads the same file without complaint, so an operator’s file is never refused over a section the server will not use.

Key Type Meaning
enabled boolean Whether mod sound is played at all. Absent means yes.
muted_mods list of ids Mods whose sound this machine drops, each author:mod.
device string The output to play through. Absent takes the machine’s default.

[audio.gain] carries one multiplier per bus — effects, environment, music, interface, voice — each between 0.0 and 2.0, absent meaning 1.0. A value outside that range refuses to start and names the key.

Turning enabled off, or a bus’s gain to zero, is the guarantee. Muting a mod by name is a convenience: two mods that cooperate can play each other’s sounds and get around it, which is why the bus and global controls exist above it.

device is the escape hatch, and you should not normally need it. The game prefers a sound server that is already running; failing that it takes the machine’s default, and failing that every other output in turn. It logs the one it took either way. default is the one value that is not an output — it asks for whatever the game would have chosen on its own, which is how this key is undone without deleting it. On Linux, where this matters most, the log is also where the names you could write instead appear.

Settings of one named mod, keyed by its full id — today, which of its own hooks this deployment runs it without:

[mods."ironlark:echo"]
disabled-hooks = ["echo"]

A sibling of [session] rather than a key inside it: enabling a mod is the session’s shape, while these are settings of one named mod. The whole switch is Per-mod settings.

Precedence is defaults, then the file, then the command line:

Flag Overrides
--config <path> which file is read at all
--content <dir> [content] root
--map <id> [session] map
--gamemode <id> [session] gamemode

A scripted or one-off run can override a deployment without editing it. Every flag is on Command line.

Hosting today means running the game as the host, and the session ends when you leave. A dedicated server — a host with no player attached — is planned and not built; see the roadmap.

What you write now is not throwaway, and this is checkable rather than promised: --config names the file, so it does not have to sit beside the install, and [content] root names the content directory separately, so one read-only copy of workshop/ can serve several instances. A dedicated server changes which process reads this file, not the file.