Server Configuration

Configure a hosted server, including the global server config and per-session server profiles.

This guide covers how to configure a hosted server, including the global server config file and per-session server profiles, and how to run a dedicated (headless) server.


Running a Dedicated Server

creation_server is the headless server: the same server the game runs when you host from the menu, without the game attached. It has no window and needs no GPU, so it runs on a plain Linux or Windows machine.

Run it from a folder laid out like the game’s — it reads saves/, instances/, server_config/, server_profiles/ and certs/ from the working directory and writes to logs/:

creation_server --save <name> [--port <n>] [--profile <name>] [--upnp]
OptionMeaning
--save <name>The save under saves/ to host. Required; create the world in the game first.
--port <n>TCP port to listen on. Defaults to 42069, the port the in-game host menu uses.
--profile <name>The server profile under server_profiles/ to apply (see Server Profiles).
--upnpOpen the port on your router with UPnP and listen on the machine’s LAN address. Without it the server listens on every interface and port forwarding is up to you.

Players join with the machine’s address and port from the Join via IP menu. Steam P2P hosting and the host’s automatic operator status are game-only: on a dedicated server, operators come from server_config.yaml and the profile.

Stop it with Ctrl-C. The server finishes saving every world before it exits, the same as closing a hosted game.

The Steam library

The server links the Steam API (it validates session tickets under auth-mode: steam), so the Steam library has to sit next to the binary:

PlatformFile
Windowssteam_api64.dll beside creation_server.exe
Linuxlibsteam_api.so beside creation_server

Both ship in the server download. If you build from source instead, copy the library out of the build output (target/<profile>/steam_api64.dll on Windows; on Linux it is written to target/<profile>/build/steamworks-sys-*/out/libsteam_api.so). The Linux binary carries an $ORIGIN runpath, so a copy beside it is found with no LD_LIBRARY_PATH to set.

On the first launch of a save the server writes a self-signed certificate to certs/server/, and logs a couple of “Failed to read server data file” / “Error loading biome IDs” errors while it generates the world for the first time. Both are expected on a brand-new save.


Global Server Config

File: server_config/server_config.yaml

This file sets the default behaviour for every server session. Any value here can be overridden on a per-profile basis (see Server Profiles below).


Authentication Mode

auth-mode: steam

Controls how the server verifies player identity at login.

ValueBehaviour
steamPlayers must be logged into Steam. The server verifies their identity using a Steam session ticket. Player saves are tied to the player’s Steam account.
offlineNo verification — the server trusts whatever name the client provides. Suitable for private LAN sessions or local testing only.

Note: In steam mode, operator permissions (see below) must use the player’s Steam ID, not their display name. Steam IDs appear in the server log when a player connects.


Operators

operators:
  - 76561198000000000
  - 76561198000000001

A list of player IDs that have operator-level permission. Operators can use privileged chat commands such as /kick, /ban, /mute, and /teleport.

  • In steam mode: use the player’s Steam ID (a 17-digit number shown in the server log on login).
  • In offline mode: use the player’s login ID (the save ID sent at login, shown in the server log) — not the display name, which can be changed freely and is never used for permission checks.

Operator lists from profiles are added to this list — they never replace it. A player in either list has operator access.

Security: operator commands are disabled by default under offline auth, because offline mode does not verify identity — any connecting player could claim a configured operator’s login ID and gain operator powers. On a public server, use steam auth so operator identity is verified. See Offline Operators below to re-enable them on a trusted private server.


Automatic Operators

You do not have to list yourself here to be an operator on a server you run:

  • The player who hosts the server is automatically granted operator for that session. This is resolved from your own identity when you start hosting and is not stored in the save or the profile — so it applies whichever profile you host under, and hosting a world you downloaded from someone else grants operator to nobody but you. It is subject to the same rules above: under offline auth it still requires allow-offline-operators (see below), and under steam auth it just works.
  • In singleplayer, the local player is always an operator; no configuration is needed.

To grant operator to other people persistently (co-admins), add them to the operators: list here or in a profile, as described above.


Offline Operators

allow-offline-operators: false
ValueBehaviour
false (default)Under offline auth, all operator commands are refused — even for configured operators — because player identity cannot be verified. Has no effect under steam auth, where operators always work.
trueHonor the operators: list under offline auth. Only enable this on a trusted LAN/private server where you control who can connect, since a malicious client can impersonate any operator’s login ID.

When operators are configured but disabled by this default, the server logs a warning at startup explaining how to enable them or switch to Steam auth.


Chat

chat:
  log-messages: true
  slowdown-ms: 500
  announce-player-connections: true
  history-size: 20
  max-message-chars: 256
FieldDefaultDescription
log-messagestrueWrite chat messages to the server log file.
slowdown-ms500Minimum time in milliseconds a player must wait between chat messages. Defaults to 500 (about two messages/second) to curb flooding; set 0 to disable the limit.
announce-player-connectionstrueBroadcast a message to all players when someone joins or leaves.
history-size20Number of recent messages sent to a player when they join mid-session. 0 disables replay.
max-message-chars256Maximum character length of a single chat message. Maximum allowed value is 4096.

Friendly Fire

pvp:
  friendly-fire: false
FieldDefaultDescription
friendly-firefalseWhether players can damage each other, and each other’s tamed creatures.

Every player in a world counts as an ally of every other one — there is no party to join and nothing to invite anyone to, the world is the team — and a tamed creature is an ally of its owner. With friendly-fire: false, no player-sourced damage reaches an ally: melee swings, arrows and other projectiles, thrown flasks and every other AoE zone, granted combat verbs, and damage dealt from a mod’s Lua script are all covered by the same rule.

Ambient hazards are unaffected either way. Lava, rot gas, an ash storm and any other hazard that belongs to the world rather than to a player still hurt everyone standing in it.

Operators can flip the setting for the rest of the session with /pvp <on|off>, which overrides the value here until the server restarts.


Rate Limiting

rate-limiting:
  packets-per-second: 150
  burst-size: 50
  chunk-packets-per-second: 1000
  chunk-burst-size: 1024
  violation-limit: 1000

Controls how aggressively the server throttles clients that send packets too quickly. These defaults are suitable for normal play and generally do not need to be changed.

Chunk requests get their own, looser token bucket (chunk-*) because a client legitimately requests one chunk per position in its render distance all at once while a world loads — a burst the general limit would reject. The server also validates that each requested chunk is near the player’s actual position, so a looser chunk bucket does not expose the server to far-away chunk-flooding.

FieldDefaultDescription
packets-per-second150Sustained packet rate a client is allowed to send.
burst-size50How many extra packets a client can send in a short burst before throttling begins.
chunk-packets-per-second1000Sustained chunk-request (code 300) rate a client is allowed to send, on a separate bucket from the general limit.
chunk-burst-size1024How many chunk requests a client can send in a short burst — sized to cover a full render-distance initial load.
violation-limit1000Number of throttled (excess) packets allowed before the client is disconnected.

Connection Limits

connection-limits:
  max-connections: 256
  max-connections-per-ip: 8
  handshake-timeout-seconds: 30
  idle-timeout-seconds: 120

Bounds how many clients may connect and how long a silent connection is tolerated, so a flood of connections or stalled peers can’t exhaust server resources. These defaults suit normal play and rarely need changing. Unlike the chat and rate-limiting blocks, connection-limits is a global-only setting — it is not a profile override.

FieldDefaultDescription
max-connections256Maximum concurrent client connections. Peers beyond this are dropped immediately after the TCP accept, before the TLS handshake. Set to 0 to disable the cap.
max-connections-per-ip8Maximum concurrent connections from a single source, so one client can’t fill every slot. On a direct (TCP/TLS) server that source is the peer’s IP address; on a Steam P2P server it is the connecting Steam account. Set to 0 to disable.
handshake-timeout-seconds30Seconds a freshly connected client may stay silent before sending its login request (code 600) before being disconnected.
idle-timeout-seconds120Seconds an in-game client may stay silent before being disconnected. In-game clients send movement packets ~60×/second, so this only reaps dead/stalled connections.

Mob Limits

mob-limits:
  - spawn-group: Neutral
    limit: 50
  - spawn-group: Hostile
    limit: 50

Sets a cap on how many mobs of each group can exist in the world at once, and doubles as the allow-list for natural spawning: a mob whose spawn-group has no entry here is never chosen by the natural spawner, so it will not spawn on its own (it can still be summoned or spawned by scripts/structures). The spawn-group value is matched against a mob’s own spawn-group case-insensitivelyHostile, hostile, and HOSTILE are the same group. Neutral and Npc always exist as groups even with no entry here, but still need an entry to spawn naturally. You can add as many entries as needed — one per spawn group.

The shipped roster uses three naturally-spawning groups — Neutral, Hostile, and Elite. The example ships Neutral and Hostile; Elite is intentionally held out until an elite mob is authored, because the spawner picks a group uniformly and an empty group wastes the spawn attempt. Boss and Npc are deliberately left out: a group with no entry is never drawn by the spawner, which is what a placed boss set-piece and a one-time authored NPC want (leaving them in would make the world randomly spawn bosses and named NPCs). When a mob declares a spawn-group (and spawn-rules) with no matching mob-limits entry, the server logs a warning at load naming the group, since it will otherwise silently never spawn.

An entry takes exactly spawn-group and limit; any other key fails that entry at load with a named error. A bad entry skips only itself, so the rest of your limits still apply — but a skipped entry means that group never spawns naturally, so read the log if a mob stops appearing.

Renamed in this version. This key was type: in earlier versions. An un-migrated server_config.yaml logs an error naming the old key and skips that entry (which silently disables natural spawning for that group), so rename it when you upgrade.


Required Client Mods

required-client-mods:
  - SomeTexturePack
  - AnotherClientMod

A list of client-only mod names (e.g. a texture pack marked side: client) that a connecting client must have installed, even though the server itself never loads them. They are advertised to the client during the connection handshake and reuse the same mod-compatibility warning dialog as the instance check. Defaults to empty (no extra client mods required).


Server Profiles

Server profiles let you save different server configurations and switch between them when hosting a session. This is useful if you host the same world for different audiences — for example, a private session for friends and a public session — without editing the global config each time.

Each profile is a folder inside server_profiles/:

server_profiles/
  my_profile/
    config.yaml   ← settings that override server_config.yaml
    data.yaml     ← auto-managed: muted and banned players

Profiles are created automatically when you select a new profile name in the host menu.


Profile Config (config.yaml)

A profile’s config.yaml overrides specific values from server_config/server_config.yaml. Any field you omit is inherited from the global config — you only need to specify what you want to change.

All available overrides:

# Override authentication mode for this profile.
# "steam" or "offline". Inherits global value if omitted.
auth-mode: steam

# Additional operators for this profile. These are added to (not replacing)
# the global operators list in server_config.yaml.
operators:
  - 76561198000000000

chat:
  log-messages: true
  slowdown-ms: 500
  announce-player-connections: true
  history-size: 20
  max-message-chars: 256

rate-limiting:
  packets-per-second: 150
  burst-size: 50
  chunk-packets-per-second: 1000
  chunk-burst-size: 1024
  violation-limit: 1000

All fields are optional. A completely empty config.yaml is valid — it simply inherits everything from the global config.


Profile Data (data.yaml)

This file is managed automatically by the server. It stores the list of muted and banned players for this profile. You should not edit it by hand unless you need to manually remove a ban or clear a muted player list when the server is offline.

muted-players:
  - 76561198000000000

banned-players:
  76561198000000001: 'Reason for ban'

Bans and mutes are profile-scoped — banning a player under one profile does not ban them under a different profile.


Example: Public vs. Private Profiles

server_profiles/public/config.yaml

auth-mode: steam

chat:
  slowdown-ms: 2000
  max-message-chars: 128

server_profiles/private/config.yaml

auth-mode: offline

chat:
  announce-player-connections: false

Both profiles share the global operator list. The public profile adds chat rate limiting and Steam auth. The private profile uses offline mode and skips join/leave announcements. Note that allow-offline-operators is a global server_config.yaml setting, not a profile override — set it there (see above), not in a profile’s config.yaml, where it would be ignored.


Operator Commands Reference

Operators can run the following commands in chat:

CommandDescription
/kick <player>Disconnect a player from the server.
/ban <player> [reason]Permanently ban a player from the current session’s profile.
/unban <player>Remove a ban from the current profile.
/mute <player>Prevent a player from sending chat messages.
/unmute <player>Restore a player’s chat access.
/pvp <on|off>Toggle friendly fire for the session — whether players can damage each other and each other’s tamed creatures, across every damage source. Overrides pvp: friendly-fire: until the server restarts.
/teleport <player> (alias /tp)Teleport to another player.
/noclipToggle noclip movement for yourself.
/capability (alias /cap)Show a player’s capabilities and where each one comes from. /capability grant <name> [player] and /capability revoke <name> [player] add or remove a persistent grant — useful for testing capability-gated content such as the double_jump and air_dash movement verbs without first authoring the gear that grants them.
/rollcatch [count]Roll the fishing catch table for the water you are standing in and report a tally of what came up, without granting anything. Content tool for tuning catch tables — see Fish Configuration.
/listShow all currently connected players.
/seedShow this world’s numeric seed (read-only). It reproduces a world only at the same game version and mod set; a new seed is a new world.
/helpShow available commands.

Operator status is granted through the operators: list and the automatic host grant described above — there is no in-chat /op or /deop command. /list, /seed and /help are available to everyone, not just operators.

Player arguments can be the player’s display name or their player ID. In steam auth mode, the player’s display name is their Steam persona name.

A <player> argument is matched against player IDs first (the verified, unique key), then against display names. Display names are unique per server — a login is refused if its display name is already in use (compared case-insensitively) — so a name resolves to at most one player. Matching the verified key first means a player cannot receive a command aimed at someone’s player ID by taking that ID as their display name. If an argument still matches more than one online player, the command fails and lists the candidates instead of guessing; target them by their exact player ID. /mute, /unmute, /ban and /unban also accept a bare player ID so offline players can be targeted.

Last updated