Date: 2026-05-11
Time: 15:24
ftl2-servercraft is a full application built on FTL2 that manages game server lifecycles (Minecraft and Terraria) on Linode infrastructure. It demonstrates FTL2's use as an application infrastructure layer rather than just a scripting tool, combining provisioning automation with a live Textual TUI dashboard and automated watchdog teardown of idle servers.
provision, startserver, verifyserver, backupworld, getplayercount, saveand_stop, destroy), all receiving an ftl object as first parameterservers.yml with per-server settings for game type, Linode sizing, DDNS, grace periods, and external config directoriesconfig_dir, not inlineInstallation and launch:
uv pip install -e .
cp servers.yml.example servers.yml
ftl2-servercraft
Server definition (servers.yml):
servers:
minecraft-1:
label: "World 1 (NeoForge)"
script: neoforge # selects scripts/neoforge.py
admin_user: admin
world_name: world
linode_type: g6-standard-1
linode_region: us-east
config_dir: ~/git/server-configs/minecraft-world-1
ddns_hostname: world1.example.com
grace_period: 300 # seconds before idle teardown
poll_interval: 30 # seconds between player count checks
TUI keybindings: L (launch), R (reconfigure), V (verify), B (backup), S (stop+destroy), W (toggle watchdog), Q (quit)
Required environment variables: LINODETOKEN, LINODEROOTPASS, SLACKTOKEN
ftl object passed to script functions; this is the primary consumer example of FTL2's automation APIftl object is passed as the first argument to all script interface functions — this is the primary handle for FTL2 automation operations within an applicationprovision, startserver, verifyserver, restoreworld, backupworld, getplayercount, saveandstop, destroyverifyserver returns bool; getplayer_count returns int | None — the None case must be handled (server unreachable vs zero players)script field in servers.yml selects which Python module under scripts/ handles that server type