# Conan Exiles dedicated server module. # # Conan Exiles Dedicated Server (Steam app 443030) — Funcom rolled out the # UE5 "Enhanced" remaster as the default branch on 2026-05-05. The UE4 build # remains available indefinitely as Steam beta branch `conan-exiles-legacy` # (description: "UE4 version of Conan Exiles Dedicated Server"). Both ride # the same appid; only the branch differs. Default install pulls Enhanced. # # Hosting matrix as of 2026-05-10: # Enhanced (UE5, public branch) — NATIVE LINUX. Funcom shipped a real Linux # dedicated-server depot (443032, ~4.27 GiB) alongside the 2026-05-05 # Enhanced launch. Binary at # ConanSandbox/Binaries/Linux/ConanSandboxServer-Linux-Shipping. We run # it directly — no Wine, no Xvfb. Config dir is Config/LinuxServer/. # Legacy (UE4, conan-exiles-legacy beta) — STILL WINDOWS-ONLY. No Linux # depot exists for this branch; we keep the Wine + Xvfb path for it. # Binary at ConanSandbox/Binaries/Win64/ConanSandboxServer-Win64-Shipping.exe, # config dir Config/WindowsServer/. Same pattern as Empyrion / V Rising / # Sons of the Forest / Windrose. # The container ships with both runtimes (Wine + UE5 Linux deps) so a single # image can host either edition; entrypoint picks the launch mode from the # EDITION config_value. # # Memory footprint: Enhanced UE5 runs ~2-4x heavier than UE4 Legacy on # populated worlds. Defaults bumped accordingly (see `resources:` below). # # RCON is real Source-RCON on 25575/tcp — AMP's template, community # servers, and the rcon plugin that ships with Conan all speak it. We # surface it via our source_rcon adapter; the tracker's redial-on-EOF # logic covers any idle disconnects (same fix landed for Palworld). # # Reference: https://github.com/CubeCoders/AMPTemplates (conan-exiles.kvp, # conan-exilesports.json, conan-exilesupdates.json, conan-exilesconfig.json) # Reference: https://low.ms/knowledgebase/conan-exiles-enhanced-update id: conan-exiles name: "Conan Exiles" version: 0.3.0 authors: - panel contributors supported_modes: - docker runtime: docker: # Built locally from ./Dockerfile. Rebuild with: # docker build -t panel-conan-exiles:latest modules/conan-exiles image: panel-conan-exiles: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: "ServerSettings.ini, Game.ini, ConanSandbox/Saved/ world data" - name: "Game Files" path: /game hint: "ConanSandbox/Binaries/Linux/ for Enhanced (UE5 native), ConanSandbox/Binaries/Win64/ for Legacy (UE4 under Wine). Engine/, ConanSandbox/Mods/ (Workshop pak drops). Workshop downloads land at /game/steamapps/workshop/content/440900// via the shared volume mount." # Pre-declare every env key that any config_value below maps to. The # agent's resolve.go ONLY propagates config_values whose key is # already present in `docker.env` — keys not listed here get silently # filtered out. Defaults below are starting values for fresh instances; # operator edits in the panel's Config tab override per-instance. # Empty-string defaults mean "leave the INI alone" (entrypoint stamps # only non-empty values, so unset fields fall back to game defaults # or operator's manual ServerSettings.ini edits). env: # Steamworks client runtime init context — the dedicated-server app # (443030) reports itself to Steam as Conan Exiles (440900). AMP # sets this too; the server refuses to join the Steam master-server # listing without it. STEAM_APP_ID: "440900" # EDITION — see config_values block below. Default `enhanced` (UE5). # Pre-declared here so resolve.go propagates the operator's choice # into the container env (the agent's docker.env filter only forwards # config_values whose key already appears in this map). The entrypoint # logs it so operators can grep boot output to confirm what's running. EDITION: "enhanced" # --- Identity --- # All identity fields default to EMPTY. The entrypoint only stamps # non-empty values into [ServerSettings] of ServerSettings.ini, so a # recreate with empty env preserves whatever the operator set # previously via the Files tab. CLI-launch args have hardcoded # fallbacks in entrypoint.sh (e.g. ServerName falls back to # "panel Conan Exiles" for the Steam server-name flag only when # SERVER_NAME is genuinely unset). SERVER_NAME: "" SERVER_PASSWORD: "" ADMIN_PASSWORD: "" RCON_PASSWORD: "" MAX_PLAYERS: "" SERVER_REGION: "" MAX_NUDITY: "" SERVER_COMMUNITY: "" # --- Map --- # /Game/Maps/ConanSandbox/ConanSandbox = Exiled Lands (default) # /Game/DLC_EXT/DLC_Siptah/Maps/DLC_Isle_of_Siptah = Isle of Siptah # SERVER_MAP keeps a default because Conan REQUIRES a map URL on the # CLI; empty would mean "use last used", which is fine but surprising # for new instances. SERVER_MAP: "/Game/Maps/ConanSandbox/ConanSandbox" CUSTOM_MAP: "" # --- Anti-cheat --- # Empty means "leave INI default" (entrypoint skips stamping). Conan's # game default is BattlEye=False, VAC=True — same as ours used to be. ENABLE_BATTLEYE: "" ENABLE_VAC: "" # --- Persistence / online --- PVP_ENABLED: "" AVATARS_ENABLED: "" CONTAINERS_IGNORE_OWNERSHIP: "" CAN_DAMAGE_PLAYER_OWNED_STRUCTURES: "" DYNAMIC_BUILDING_DAMAGE: "" # --- Gameplay multipliers (empty = use game default) --- PLAYER_XP_RATE: "" PLAYER_XP_KILL: "" PLAYER_XP_HARVEST: "" PLAYER_XP_CRAFT: "" PLAYER_XP_TIME: "" PLAYER_DAMAGE_MULTIPLIER: "" PLAYER_DAMAGE_TAKEN: "" PLAYER_HEALTH_REGEN: "" PLAYER_STAMINA_COST: "" PLAYER_SPRINT_SPEED: "" PLAYER_MOVEMENT_SPEED: "" PLAYER_ENCUMBRANCE: "" NPC_DAMAGE_MULTIPLIER: "" NPC_DAMAGE_TAKEN: "" NPC_HEALTH_MULTIPLIER: "" NPC_RESPAWN_MULTIPLIER: "" NPC_MAX_SPAWN_CAP: "" STRUCTURE_DAMAGE_MULTIPLIER: "" STRUCTURE_HEALTH_MULTIPLIER: "" LANDCLAIM_RADIUS_MULTIPLIER: "" AVATAR_DOME_DURATION: "" AVATAR_DOME_DAMAGE: "" FRIENDLY_FIRE_DAMAGE: "" # --- Pre-declared so allocator-derived ports survive resolve.go's filter. --- GAME_PORT: "7777" PINGER_PORT: "7778" QUERY_PORT: "27015" RCON_PORT: "25575" 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" } # Shared Steam-Workshop content volume — exact same pattern as DayZ # (modules/dayz/module.yaml mounts panel-dayz-workshop at # /game/steamapps/workshop). Volume's root contains a flat # `content///` tree (no extra prefix); mounting at # /game/steamapps/workshop makes it appear as # /game/steamapps/workshop/content/440900//.pak # — under the /game declared root, so FsList/FsSymlink work without # extra browseable_roots. The SteamCMD sidecar uses a different deep # path on its end (/conan-workshop/steamapps/workshop) so its # +force_install_dir matches; see conanmods.go's # runSteamCMDConanWorkshopDownloadOnceStreaming for the args. Both # the sidecar and the game container are talking to the same volume, # they just label the mount point differently. - { type: volume, name: "panel-conan-workshop", container: "/game/steamapps/workshop" } # Conan Exiles ports (matches AMP template): # 7777/both (tcp+udp) — main game traffic + client mod downloads # 7778/udp — pinger (game+1 offset; server browser probe) # 27015/udp — Steam query # 25575/tcp — RCON (internal) ports: # Conan binds the game socket on UDP `-Port=N` and the pinger # (server-browser probe) on UDP N+1 — internally derived, no override # flag exists. The panel allocator scans the agent window per-port; with # no prior holes the first three rows land on consecutive numbers # N, N+1, N+2 — so PINGER_PORT == GAME_PORT+1 and Conan's auto-derived # pinger lands on the row we forward. # # `game` MUST be UDP — Conan's game socket is UDP-only. (AMP's template # historically listed it as tcp+udp because of optional in-game mod # downloads, but the dedicated-server depot never opens a TCP listener # on -Port; the opnfwd orchestrator forwards by declared proto, so a # tcp row here ends up forwarding a dead TCP port and leaves the real # UDP game socket unforwarded — players can't join, server doesn't # register on the master server.) - { name: game, proto: udp, default: 7777, required: true, env: GAME_PORT } - { name: pinger, proto: udp, default: 7778, required: true, env: PINGER_PORT } - { name: query, proto: udp, default: 27015, required: true, env: QUERY_PORT } - { name: rcon, proto: tcp, default: 25575, internal: true, env: RCON_PORT } resources: # Bumped for Enhanced UE5 (was 6144 / 12288 for UE4). Funcom + community # benchmarks have populated Enhanced worlds at 2-4x the UE4 footprint — # 8 GB minimum keeps a small server alive, 24 GB recommended for a # populated long-running build-heavy server. min_ram_mb: 8192 recommended_ram_mb: 24576 # Per-instance generated RCON secret — overrides env RCON_PASSWORD at # create so every instance gets a unique password (see pkg/module # GenerateSecrets). Operators can still override via the RCON Password # config field. secrets: - name: RCON_PASSWORD description: "Conan Exiles Source-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). password_literal: "panel_rcon" commands: # Conan's RCON commands. `listplayers` is the roster query; `broadcast` # sends an in-game message; `kick`/`ban` take a player # identifier. list: "listplayers" broadcast: "broadcast {msg}" kick: "kickplayer {player}" ban: "banplayer {player}" save: "saveworld" shutdown: "shutdown" state_sources: - type: rcon command: "listplayers" every: 60s # Log-line event patterns. AMP's template is the source of these regexes — # tested against real Conan Exiles boot output. Go regex = RE2; convert # `(?...)` → `(?P...)`. events: join: pattern: 'LogNet: Join succeeded: (?P.+?#\d+)' kind: join leave: pattern: 'LogNet: Player disconnected: (?P.+?#\d+)' kind: leave chat: pattern: 'ChatWindow: Character (?P.+?) said: (?P.+)' kind: chat # Two update branches on the same appid. Operator picks via the Update # button in the panel UI — `enhanced` is the default (UE5, public branch); # `legacy` pins to UE4 via the `conan-exiles-legacy` Steam beta branch # (Funcom's announced indefinite UE4 archive). update_providers: # `id` is also the user-facing label in the UI (no separate label field on # this struct yet; see pkg/module/manifest.go UpdateProvider). Choose # short ids that read well in the Update dropdown. - id: enhanced kind: steamcmd app_id: "443030" platform: linux # Enhanced (UE5) has a real Linux depot (443032, ~4.27 GiB) since 2026-05-05 — run native, no Wine. install_path: /game # Conan's `app_update 443030 validate` fails on empty volumes with # "Missing configuration" (4/4 retries). Plain `app_update 443030` # succeeds. Skip validate so first install just works; operators can # trigger a manual Update later to re-validate existing files. skip_validate: true - id: legacy kind: steamcmd app_id: "443030" beta: conan-exiles-legacy # confirmed branch name via app_info_print 2026-05-07 platform: windows # Legacy (UE4) has NO Linux depot — this is the only remaining Wine path in the module. install_path: /game skip_validate: true # UI-driven configuration. Each `key` here maps 1:1 to an env key declared # above; the entrypoint reads non-empty env values and stamps them into # [ServerSettings] in ServerSettings.ini at every boot (idempotent — same # value re-stamped is a no-op). Empty strings mean "leave the INI alone"; # operator edits via the Files tab to ServerSettings.ini are preserved for # any field whose corresponding config_value is left blank. # # The most-tuned fields are at the top (no advanced flag); niche / tuning # multipliers are tagged `advanced: true` so the basic Config tab stays # scannable on a phone. AMP's official template surfaces ~11 fields; we # expose a superset (~30) covering identity, anti-cheat, PvP, and the # common gameplay knobs — beyond that, edit ServerSettings.ini directly. config_values: # ===== Edition (UE4 vs UE5) ===== # Pick at create time. Drives: # 1. Which Steam branch downloads on first install (auto-update picks # the matching update_provider via dispatch.go's edition-aware # auto-update logic — `enhanced` → public branch, `legacy` → # `conan-exiles-legacy` Steam beta). # 2. Which Workshop mods the panel's Mods tab surfaces — Steam tags # every published item as either "Enhanced" or "Legacy"; the panel's # workshop search adds `requiredtags[]=Enhanced|Legacy` per the # instance's edition. UE5 servers don't see UE4-only mods (they # load silently as compatible-format files but don't actually run # because the .pak ABI changed). # Operators changing edition after creation: change this value, then # click Update (which now uses the matching branch). Existing world # data is preserved. - key: EDITION label: "Edition" description: "Conan Exiles version. Enhanced (UE5, 2026-05+) is Funcom's current default. Legacy (UE4) is the indefinitely-archived prior build — pick this only if your players need UE4 mods that haven't been ported yet. Switching after creation requires clicking Update; saves are preserved across editions." default: "enhanced" options: - { value: "enhanced", label: "Enhanced (UE5, default)" } - { value: "legacy", label: "Legacy (UE4 — Steam beta branch)" } # ===== Identity ===== - key: SERVER_NAME label: "Server Name" description: "Name shown in the server browser and steam community list." default: "panel Conan Exiles" - key: SERVER_PASSWORD label: "Server Password" description: "Password required to join the server. Leave blank for an open server." default: "" - key: ADMIN_PASSWORD label: "Admin Password" description: "Lets the operator open the in-game admin panel via 'Make Me Admin' on a logged-in client. Stamped into [ServerSettings] AdminPassword= on every restart. Leave blank to leave the existing INI value alone." default: "" - key: RCON_PASSWORD label: "RCON Password" description: "Source-RCON password used by the panel for player listing, broadcast, kick, ban, and saveworld. Avoid spaces or quotes. Leave blank to use the per-instance generated secret (recommended)." default: "" - key: MAX_PLAYERS label: "Max Players" description: "Player slot limit. Conan's official cap is 70; communities run 40-60 for most build densities." default: "40" - key: SERVER_REGION label: "Server Region" description: "Region tag used for server-browser filtering. Picks up the client's regional preferences." default: "1" options: - { value: "0", label: "Europe" } - { value: "1", label: "North America" } - { value: "2", label: "Asia" } - { value: "3", label: "Australia" } - { value: "4", label: "South America" } - { value: "5", label: "Japan" } # ===== Map ===== - key: SERVER_MAP label: "Map" description: "Map loaded at server start. For a custom map, choose 'Custom' and fill in the path below." default: "/Game/Maps/ConanSandbox/ConanSandbox" options: - { value: "/Game/Maps/ConanSandbox/ConanSandbox", label: "Exiled Lands (default)" } - { value: "/Game/DLC_EXT/DLC_Siptah/Maps/DLC_Isle_of_Siptah", label: "Isle of Siptah" } - { value: "{{CUSTOM_MAP}}", label: "Custom (use Custom Map below)" } - key: CUSTOM_MAP label: "Custom Map Path" description: "Path to a custom map's UE asset. Only used when Map is set to 'Custom'. Example: /Game/Mods/Savage_Wilds/Savage_Wilds" default: "" # ===== Anti-cheat ===== - key: ENABLE_BATTLEYE label: "Enable BattlEye" description: "BattlEye anti-cheat. Off by default — works under Wine but adds a startup handshake that occasionally races on cold boots." default: "False" options: - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: ENABLE_VAC label: "Enable Valve Anti-Cheat" description: "Steam VAC. Generally safe to leave on for public servers." default: "True" options: - { value: "True", label: "On" } - { value: "False", label: "Off" } # ===== PvP / world ===== - key: PVP_ENABLED label: "PvP Enabled" description: "Master toggle for player-vs-player damage. Time-window restrictions are configured in ServerSettings.ini directly (PVPRestrict* keys); this just flips the global switch." default: "" options: - { value: "", label: "(leave INI default)" } - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: AVATARS_ENABLED label: "Avatars Enabled" description: "Allow players to summon god avatars. Off in many private cluster setups to prevent griefing." default: "" options: - { value: "", label: "(leave INI default)" } - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: CONTAINERS_IGNORE_OWNERSHIP label: "Containers Ignore Ownership" description: "If true, players can open any container regardless of owner. Useful for co-op-friendly servers; disable for strict PvP." default: "" options: - { value: "", label: "(leave INI default)" } - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: CAN_DAMAGE_PLAYER_OWNED_STRUCTURES label: "Allow Building Damage" description: "Master toggle for player-owned structure damage. Combine with the dynamic decay setting for a softer PvP feel." default: "" options: - { value: "", label: "(leave INI default)" } - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: DYNAMIC_BUILDING_DAMAGE label: "Dynamic Building Damage" description: "Decays vacant structures over time. Helps clean up abandoned bases on long-running servers." default: "" options: - { value: "", label: "(leave INI default)" } - { value: "True", label: "On" } - { value: "False", label: "Off" } - key: FRIENDLY_FIRE_DAMAGE label: "Friendly Fire Damage Multiplier" description: "0.0–1.0+ multiplier on damage between clan members. Default 0.25." default: "" # ===== Niche knobs (advanced) ===== - key: MAX_NUDITY label: "Max Nudity" description: "0=none, 1=partial, 2=full. Affects the default character render plus what skins players can wear." default: "0" advanced: true options: - { value: "0", label: "None" } - { value: "1", label: "Partial" } - { value: "2", label: "Full" } - key: SERVER_COMMUNITY label: "Server Community" description: "0=Purist, 1=Relaxed, 2=Hard, 3=Hardcore, 4=Roleplaying, 5=Experimental. Just a tag in the server browser." default: "0" advanced: true options: - { value: "0", label: "Purist" } - { value: "1", label: "Relaxed" } - { value: "2", label: "Hard" } - { value: "3", label: "Hardcore" } - { value: "4", label: "Roleplaying" } - { value: "5", label: "Experimental" } # ===== XP rates (advanced) ===== - key: PLAYER_XP_RATE label: "XP — Overall Rate Multiplier" description: "Overall multiplier applied on top of every XP source. Default 1.0." default: "" advanced: true - key: PLAYER_XP_KILL label: "XP — Kill Multiplier" description: "XP multiplier per kill. Default 1.0." default: "" advanced: true - key: PLAYER_XP_HARVEST label: "XP — Harvest Multiplier" description: "XP multiplier per harvest tick. Default 1.0." default: "" advanced: true - key: PLAYER_XP_CRAFT label: "XP — Craft Multiplier" description: "XP multiplier per crafted item. Default 1.0." default: "" advanced: true - key: PLAYER_XP_TIME label: "XP — Time Multiplier" description: "Idle / time-based XP. Default 1.0." default: "" advanced: true # ===== Player tuning (advanced) ===== - key: PLAYER_DAMAGE_MULTIPLIER label: "Player Damage Output" description: "Damage dealt by players. Default 1.0." default: "" advanced: true - key: PLAYER_DAMAGE_TAKEN label: "Player Damage Taken" description: "Damage received by players. Lower = tougher players." default: "" advanced: true - key: PLAYER_HEALTH_REGEN label: "Player Health Regen Speed" description: "Default 1.0." default: "" advanced: true - key: PLAYER_STAMINA_COST label: "Player Stamina Cost" description: "Multiplier on stamina drained by sprint/jump/swim. Lower = forgiving." default: "" advanced: true - key: PLAYER_SPRINT_SPEED label: "Player Sprint Speed Scale" description: "Default 1.0. Bumping past 1.5 makes ranged combat awkward." default: "" advanced: true - key: PLAYER_MOVEMENT_SPEED label: "Player Movement Speed Scale" description: "Default 1.0." default: "" advanced: true - key: PLAYER_ENCUMBRANCE label: "Player Encumbrance Multiplier" description: "Carry weight cap multiplier. Default 1.0." default: "" advanced: true # ===== NPC tuning (advanced) ===== - key: NPC_DAMAGE_MULTIPLIER label: "NPC Damage Output" description: "Damage dealt by hostile NPCs. Default 1.0." default: "" advanced: true - key: NPC_DAMAGE_TAKEN label: "NPC Damage Taken" description: "Damage NPCs receive. Lower = bullet-sponge enemies." default: "" advanced: true - key: NPC_HEALTH_MULTIPLIER label: "NPC Health Multiplier" description: "Base HP scaling. Default 1.0." default: "" advanced: true - key: NPC_RESPAWN_MULTIPLIER label: "NPC Respawn Multiplier" description: "How fast world spawns refill. >1.0 = faster respawn." default: "" advanced: true - key: NPC_MAX_SPAWN_CAP label: "NPC Max Spawn Cap Multiplier" description: "Cap on simultaneous active world NPCs. Lower = less server CPU under load." default: "" advanced: true # ===== Structures / land claim (advanced) ===== - key: STRUCTURE_DAMAGE_MULTIPLIER label: "Structure Damage Multiplier" description: "Damage dealt to player-built structures. Default 1.0." default: "" advanced: true - key: STRUCTURE_HEALTH_MULTIPLIER label: "Structure Health Multiplier" description: "Base HP of placed pieces. >1.0 = sturdier bases." default: "" advanced: true - key: LANDCLAIM_RADIUS_MULTIPLIER label: "Landclaim Radius Multiplier" description: "How big the no-build bubble around each placeable is. <1.0 lets settlements pack tighter." default: "" advanced: true - key: AVATAR_DOME_DURATION label: "Avatar Dome Duration Multiplier" description: "How long avatar shields hold. Default 1.0." default: "" advanced: true - key: AVATAR_DOME_DAMAGE label: "Avatar Dome Damage Multiplier" description: "Damage vs. avatar shields. Default 1.0." default: "" advanced: true # --- 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: '/LogGameState: Match State Changed from WaitingToStart to InProgress/i' appearance: emoji: "⚔️" grad: "linear-gradient(135deg,#5a1a00,#c2410c)" art: "/game-art/conan-exiles.jpg" steam: "440900"