Skip to content

Server Configuration

One of the biggest draws of dedicated servers is the freedom for players, community admins, and hosting platforms to customize settings. How you structure your configuration files determines whether this is straightforward or a constant source of frustration.

JSON, YAML, or TOML are the right choices. They are:

  • Human-readable and editable
  • Supported by every programming language and automation tool
  • Easy to validate against a schema
  • Parseable without custom code

Pick one and use it consistently across all your config files.

Custom config formats (custom key=value syntax, INI variants with nonstandard escaping, engine-specific serialization) may feel simpler during development. But for anyone running your server outside your studio, they create real problems:

  • Hosting platforms cannot parse them without custom code written specifically for your game
  • Automation tools (deployment scripts, config generators, web panels) cannot read or modify them
  • Typos and formatting errors are harder to detect without validation tooling
  • Documentation is non-existent outside your own docs
  • Lack proper line/config comments

If your engine uses a custom format internally, consider adding support for a JSON or YAML override file that takes precedence. This gives you engine compatibility during development and a standard interface for everyone else.

Another common pitfall is to use a low level programming language like Lua to handle configuration. This can feel like a feature to a developer or a server owner wanting to add highly configurable options and overrides. The drawback is that server hosting platforms can struggle to holistically parse and format these files, often requiring a tree-shaking approach with significantly more resources to apply simple control panel options.

Keep your server’s file organization predictable. Hosting platforms and server admins expect to find things in consistent locations.

Recommended layout:

  • Directoryserver/
    • serverExecutable Server binary
    • Directoryconfig/
      • server.json Main server config
    • Directoryworlds/
      • Directorymy_world/
        • world.json World-specific settings/manifest
        • …world data files
    • Directorymaps/
      • arena_01.map
      • capture_02.map
    • Directorymods/
      • Directorysome_mod/
        • mod.json Mod manifest (name, version, etc.)
        • …mod files
    • Directorylogs/
      • server.log
    • Directorylibraries/ Additional dependencies

Key principles:

  • Config at the root or in /config: Don’t bury config files three directories deep or scatter them across multiple locations.
  • World data in /worlds: Each world or save gets its own subdirectory with a manifest file describing its settings.
  • Maps separate from worlds: If your game has pre-built maps, keep them separate from player-generated world data.
  • Mods in /mods: Each mod in its own directory with a manifest. See Mod and Plugin Support for details.

Many engines have their own internal config systems. Rather than fighting this, add a layer on top: let your server accept runtime overrides that take precedence over file-based config.

Priority order (highest to lowest):

  1. Command-line arguments (-port 27015)
  2. Environment variables (SERVER_PORT=27015)
  3. Config file values ("port": 27015)
  4. Default values compiled into the server

This layered approach lets developers use config files during development, hosting platforms inject settings via arguments or ENV vars, and defaults work out of the box for first-time setup.

Your server should validate its config at startup and fail clearly when something is wrong.

  • Check required fields are present
  • Validate types (a string where a number is expected should not silently become 0)
  • Enforce value ranges (max players should not accept -1 or 999999)
  • Report which file, which field, and what’s wrong in the error message

A server that crashes 30 seconds into startup with an unrelated error because of a bad config value wastes hours of debugging time. A server that says Error: config/server.json: "max_players" must be between 1 and 128, got 0 saves everyone time.

Every config option should be documented somewhere accessible:

  • What the field is called
  • What it does
  • What type it expects (string, integer, boolean, enum)
  • What the valid range is
  • What the default value is

This can live in your game’s documentation, in a README alongside the config file, or as comments in the config file itself (if your format supports it; JSON does not, YAML and TOML do).

Hosting platforms build UI panels based on your config documentation. If a field is undocumented, it either gets skipped or configured incorrectly.

When you release game updates that change the config format (adding fields, renaming fields, changing defaults), plan for servers that are still running the old config.

Practical approaches:

  • Version field: Add a "config_version": 2 field. Your server checks this at startup and either migrates the config automatically or tells the admin what changed.
  • Additive changes only: New fields get defaults. Old fields keep working. Don’t rename or remove fields unless absolutely necessary.
  • Migration on startup: If you must change the config structure, have your server detect the old format, migrate it, and write the updated file.

Avoid breaking changes to config format in minor updates. If a player updates their server and it won’t start because a field was renamed, that’s a support ticket you didn’t need to create.