# Factorio — panel-native dedicated server module. # # Native Linux binary. Factorio has two install sources: SteamCMD app 427520 # (only if you own Factorio on Steam) OR direct download from factorio.com. # We go direct: no Steam auth needed, and headless versions ship unzipped # tar.xz archives. Users can swap to SteamCMD if they prefer. # # RCON: Factorio ships a source-compatible RCON server (same wire protocol # as Valve's). Enabled via --rcon-port + --rcon-password flags. # # Reference: https://github.com/CubeCoders/AMPTemplates (Factorio.kvp) id: factorio name: "Factorio" version: 0.1.0 authors: - panel contributors supported_modes: - docker runtime: docker: image: panel-factorio:latest # Host networking -- container shares the host net namespace, so # any port the game/mod binds is directly on the LAN. AMP-like # model. Multi-instance safety comes from env-driven per-instance # ports (panel allocator + env: mapping on each ports entry). network_mode: host browseable_root: /game-saves browseable_roots: - name: "Saves & Configs" path: /game-saves hint: "Save games + server-settings.json + mod-list.json" - name: "Game Files" path: /game hint: "Binaries, mods/, data/" env: RCON_PASSWORD: "panel_rcon" FACTORIO_VERSION: "stable" # "stable" or "latest" (experimental) # Pre-declared so the agent's resolve.go filter lets the panel-allocated # port through to the container env (only keys ALREADY in docker.env get # overridden by config_values). GAME_PORT: "34197" RCON_PORT: "27015" volumes: - { type: volume, name: "panel-$INSTANCE_ID-saves", container: "/game-saves" } - { type: volume, name: "panel-$INSTANCE_ID-game", container: "/game" } - { target: "$DATA_PATH/logs", container: "/game-saves/logs" } ports: - { name: game, proto: udp, default: 34197, required: true, env: GAME_PORT } - { name: rcon, proto: tcp, default: 27015, internal: true, env: RCON_PORT } resources: min_ram_mb: 1024 recommended_ram_mb: 4096 # mods + big bases # Per-instance generated RCON secret. The agent generates a random # 24-byte token at create time (pkg/module GenerateSecrets), which # overrides the env default for RCON_PASSWORD below — so every instance # gets a unique password. The weak env default only applies to # containers launched outside the panel. secrets: - name: RCON_PASSWORD description: "Factorio RCON password — generated per instance" generated: true rcon: adapter: source_rcon host_port: rcon auth: source_rcon_login password_secret: RCON_PASSWORD # Legacy fallback only (pre-generated-secret instances). New instances # always get the generated RCON_PASSWORD secret above. password_literal: "panel_rcon" commands: list: "/players online" save: "/server-save" say: "{msg}" # Factorio treats non-/ input as chat to all players kick: "/kick {player} {reason}" ban: "/ban {player} {reason}" state_sources: - type: rcon command: "/players online count" every: 60s parse: kind: regex pattern: 'Online players \((?P\d+)\)' fields: players_online: count events: join: pattern: "\\[JOIN\\] (?P\\S+) joined the game" kind: join leave: pattern: "\\[LEAVE\\] (?P\\S+) left the game" kind: leave chat: pattern: "\\[CHAT\\] (?P\\S+): (?P.*)" kind: chat update_providers: - id: stable kind: direct url: "https://factorio.com/get-download/stable/headless/linux64" target_path: /game - id: experimental kind: direct url: "https://factorio.com/get-download/latest/headless/linux64" target_path: /game # --- Manifest-driven UI metadata (WI-07) -------------------------- # Consumed by the CONTROLLER/dashboard only (the controller loads its # own ./modules copy at startup); the agent ignores these at runtime. # ready_pattern is a JavaScript regex (slash-delimited when it needs # flags) moved verbatim from the dashboard's READY_PATTERNS map. ready_pattern: '/Hosting game at IP ADDR|changing state from\(CreatingGame\) to\(InGame\)/i' appearance: emoji: "🏭" grad: "linear-gradient(135deg,#8c6239,#d4a373)" art: "/game-art/factorio.jpg" steam: "427520"