# Empyrion — Galactic Survival dedicated server module.
#
# Same panel-native pattern as 7dtd: a minimal image we own
# (panel-empyrion:latest, Debian 12 + Wine + tini), with game files
# populated by the generic SteamCMD updater sidecar into a named volume.
#
# Empyrion's dedicated server is shipped as a Windows binary only, so the
# updater is told to pretend SteamCMD is running on Windows
# (`platform: windows` → +@sSteamCmdForcePlatformType windows), and the
# entrypoint runs the exe under Wine under Xvfb (Unity server still touches
# X even in -batchmode).
#
# First-run flow:
#   - Create instance             → container spec + empty volumes
#   - Click "Update"              → SteamCMD downloads ~3.5 GB Windows build
#   - Click "Start"               → entrypoint boots Wine + EmpyrionDedicated.exe
#
# Notes for operators:
#   - The game server ports must be UDP; Empyrion uses a handful of them.
#   - Main config file is dedicated.yaml, lives under /game-saves after
#     first boot (entrypoint copies the shipped default on first run).
#   - No in-game RCON: Empyrion's admin console is in-process only. The
#     "Empyrion Web Admin" (EWA) third-party tool can be layered on top
#     later via a plugin; not wired for v1.

id: empyrion
name: "Empyrion - Galactic Survival"
version: 0.1.0
authors:
  - panel contributors

supported_modes:
  - docker

runtime:
  docker:
    # Built locally from ./Dockerfile. Rebuild with:
    #   docker build -t panel-empyrion:latest modules/empyrion
    image: panel-empyrion: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: "Saves/, dedicated.yaml, admin files"
      - name: "Game Files"
        path: /game
        hint: "Binaries, Content/, Mods/ — drop mod folders here"
    # Pre-declare the port env keys so the agent's resolve filter lets the
    # panel-allocated values flow through to the container env (resolve.go
    # only overrides keys already present in docker.env). Defaults match
    # the manifest port defaults below; agent overrides at create time.
    env:
      SRV_PORT: "30000"
      QUERY_PORT: "30001"
      CLIENT_PORT: "30002"
      EAC_PORT: "30003"
      CSW_PORT: "30004"
      EAH_API_PORT: "30007"           # Empyrion's Mod API TCP port (used by EAH/EPM and our future bridge)
      # SCENARIO is declared empty here so the agent's resolver passes the
      # config_values.SCENARIO override into the container env. Without
      # this pre-declaration, resolve.go would silently drop the value
      # (it only overrides keys already in docker.env), the entrypoint
      # would see SCENARIO="" and skip the dedicated.yaml patch, and
      # Empyrion would fall back to "Default Multiplayer" no matter what
      # the operator picked in the dropdown.
      SCENARIO: ""
    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" }

# Empyrion port reference:
#   Srv_Port      (UDP) — main game traffic       default 30000
#   Srv_Port+1    (UDP) — Steam query              default 30001
#   Srv_Port+2    (UDP) — client connect          default 30002
#   EAC_Port      (UDP) — EasyAntiCheat            default 30003
#   CSWApi_Port   (TCP) — CSW API (remote admin)  default 30004   (internal)
ports:
  - { name: game,   proto: udp, default: 30000, required: true,  env: SRV_PORT }
  - { name: query,  proto: udp, default: 30001, required: true,  env: QUERY_PORT }   # Empyrion derives query from Srv_Port + 1; we still allocate it for tracking
  - { name: client, proto: udp, default: 30002, required: true,  env: CLIENT_PORT }  # Srv_Port + 2 by convention
  - { name: eac,    proto: udp, default: 30003, required: true,  env: EAC_PORT }
  - { name: csw,    proto: tcp, default: 30004, internal: true, env: CSW_PORT }
  # Empyrion's native Mod API TCP port. EPM mod listens on this; EAH GUI
  # and our future panel-empyrion-bridge will connect here. Public so
  # remote EAH GUIs work; auth model not yet validated, see
  # panel/memory/research_eah_integration.md before exposing externally.
  - { name: eah-api, proto: tcp, default: 30007, required: true, env: EAH_API_PORT }

resources:
  min_ram_mb: 4096
  recommended_ram_mb: 8192

# Operator-tunable knobs. Panel renders these as a config form; the entrypoint
# reads them from env on every boot.
config_values:
  - key: SCENARIO
    label: "Scenario"
    description: "Folder name under Content/Scenarios/. Leave blank for game default. Reforged Eden 2 needs the workshop content (ID 3041847672) dropped into Content/Scenarios/Reforged Eden 2/ first — use the Files tab."
    default: ""
    options:
      - { value: "",                   label: "Default Random (vanilla)" }
      - { value: "Reforged Eden 2",    label: "Reforged Eden 2 (workshop)" }
      - { value: "Reforged Eden",      label: "Reforged Eden (legacy)" }
      - { value: "Default Akua",       label: "Default Akua (vanilla)" }
      - { value: "Default Multiplayer Survival", label: "Default Multiplayer Survival" }
  - key: EAH_API_PORT
    label: "EAH/Mod API port"
    description: "TCP port the EPM mod listens on for the panel-empyrion-bridge sidecar. Auto-allocated by panel; rarely needs manual override."
    default: ""
    advanced: true
# Log-derived player events. Regexes converted from CubeCoders'
# AMPTemplates (empyrion-galactic-survival.kvp) — .NET (?<n>) syntax -> Go (?P<n>).
# Sourced-from-template; not yet exercised against a live client.
events:
  join:
    pattern: '-LOG-.*Player (?P<id>.+?)/''(?P<name>[^'']+)'' login ok'
    kind: join
  leave:
    pattern: '-LOG-.*, (?P<id>.+?)/=/''(?P<name>[^'']+)'' disconnected$'
    kind: leave


update_providers:
  - id: stable
    kind: steamcmd
    app_id: "530870"
    platform: windows          # force Windows depot on Linux hosts — server is Windows-only
    install_path: /game
  - id: experimental
    kind: steamcmd
    app_id: "530870"
    beta: experimental
    platform: windows
    install_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: '/Server started listening on port|Dedi is ready|Ready for connections/i'
appearance:
  emoji: "🚀"
  grad: "linear-gradient(135deg,#0b2545,#5c7cfa)"
  art: "/game-art/empyrion.jpg"
  steam: "383120"
