Date: 2026-05-11
Time: 15:53
This module defines the ServerConfig dataclass and a load_config loader for ftl2-servercraft, a game server provisioning and management application built on FTL2. It provides the configuration layer that all other components (TUI, watchdog, provisioning scripts) use to understand what servers exist, how they're configured, and where their state lives. It supports both Minecraft/NeoForge and Terraria server types.
Configuration is loaded from a servers.yml file and returns a dictionary of named ServerConfig objects:
from config import load_config
servers = load_config("servers.yml")
server = servers["my-server"]
# Check server state
if server.is_provisioned():
ip = server.get_ip()
# List available world backups
backups = server.get_backups()
The servers.yml format maps server names to their config overrides:
servers:
my-server:
linode_type: g6-standard-2
minecraft_version: "1.20.4"
java_max_memory: "2048M"
ServerConfig fields:
| Field | Default | Purpose |
|-------|---------|---------|
| name | (required) | Server identifier, also used as FTL2 resource key |
| label | name | Display label (defaults to name) |
| admin_user | "ben" | SSH user for remote operations |
| script | "neoforge" | Provisioning script type ("neoforge", "terraria") |
| linode_type/image/region | various | Linode provisioning parameters |
| minecraftversion, serverurl, neoforge_url | "" | Server binary configuration |
| javamaxmemory/min_memory | "1024M" | JVM heap settings |
| grace_period | 1800 | Seconds before idle shutdown (watchdog) |
| poll_interval | 30 | Watchdog polling frequency in seconds |
| slack_channel | "#minecraft" | Notification channel |
| state_file | ".ftl2-state.json" | Path to FTL2 state file |
| inventory | "inventory.yml" | Path to FTL2 inventory |
| config_dir | "" | Directory for server config files (server.properties, etc.) |
| ddns_hostname | "" | Dynamic DNS hostname |
getip() and isprovisioned() read the FTL2 state file (.ftl2-state.json) to extract resource information. The server's name is used as the resource key in the state dict.get_backups() looks in ~/data/minecraft/backups/ or ~/data/terraria/backups/ depending on the script field, returning paths sorted newest-first by mtime.load_config returns an empty dict if the config file doesn't exist, and handles None values in YAML entries via **(values or {}).statepath, inventorypath, and configdirpath properties all call expanduser(), so ~ is valid in config values.servers.yml (YAML config), .ftl2-state.json (FTL2 runtime state)yaml for config parsing, json for state file parsing, stdlib dataclasses and pathlibinventory field points to the FTL2 inventory file used during provisioning.