{
    "_comment": "Generated by tools/egg/make-egg-pterodactyl.py in the osmium repo (from tools/egg/make-egg.py); edit that, not this file.",
    "meta": {
        "version": "PTDL_v2",
        "update_url": null
    },
    "exported_at": "2026-10-17T00:00:00+00:00",
    "name": "Rust (Osmium)",
    "author": "support@cynic-hosting.com",
    "description": "Rust dedicated server with Osmium (https://osmiummod.com), a Rust server modding framework that runs Oxide and Carbon plugins as they are. Hook sites are woven into the game assemblies before start. Rust is updated only to builds Osmium has a release for, usually within minutes of a Rust update. Osmium installs and updates itself from its public release server (https://releases.osmiummod.com); every release is signed, and the signature and each file's checksum are checked before anything is used. Accept the Osmium Terms of Use (https://osmiummod.com/terms) with the Accept Osmium Terms option before the first start. Osmium credits itself without changing the game: one line \"Powered by Osmium - osmiummod.com\" under your description in the server browser, the tag osmium, and one small chat line for each player once per wipe. It is on by default; set the Osmium credit option to 0 to switch it off.",
    "features": null,
    "docker_images": {
        "Rust": "ghcr.io/pterodactyl/games:rust"
    },
    "file_denylist": [],
    "startup": "bash osmium/egg/start.sh ./RustDedicated -batchmode +server.port {{SERVER_PORT}} +server.queryport {{QUERY_PORT}} +server.identity \"rust\" +rcon.port {{RCON_PORT}} +rcon.web true +server.hostname \\\"\\$SERVER_HOSTNAME\\\" +server.level \\\"\\$LEVEL\\\" +server.description \\\"\\$DESCRIPTION\\\" +server.url \\\"\\$SERVER_URL\\\" +server.headerimage \\\"\\$SERVER_IMG\\\" +server.logoimage \\\"\\$SERVER_LOGO\\\" +server.maxplayers {{MAX_PLAYERS}} +rcon.password \\\"\\$RCON_PASS\\\" +server.saveinterval {{SAVEINTERVAL}} +app.port {{APP_PORT}}  $( [ -z ${MAP_URL} ] && printf %s \"+server.worldsize \\\"{{WORLD_SIZE}}\\\" +server.seed \\\"{{WORLD_SEED}}\\\"\" || printf %s \"+server.levelurl \\\"{{MAP_URL}}\\\"\" ) {{ADDITIONAL_ARGS}}",
    "config": {
        "files": "{}",
        "startup": "{\n    \"done\": \"Server startup complete\"\n}",
        "logs": "{}",
        "stop": "quit"
    },
    "scripts": {
        "installation": {
            "script": "#!/bin/bash\n\nOSM_PUBKEY='-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEATSBighUcQgkSCE24uRGVXsr9U/CvF3IWURg5tyNwJVA=\n-----END PUBLIC KEY-----'\n\nosm_log() { echo \"[Osmium] $*\"; }\n\nosm_sha() { sha256sum \"$1\" | cut -d' ' -f1; }\n\nosm_get() {\n  if [[ ! $1 =~ ^[A-Za-z0-9][A-Za-z0-9._/+-]*$ || $1 == *..* ]]; then osm_log \"refusing remote path '$1'\"; return 1; fi\n  local url=\"${OSMIUM_DIST_URL:-https://releases.osmiummod.com}/$1\"\n  local -a opts=(-fsS --connect-timeout 5 --max-time 900 --max-filesize \"${3:-1048576}\" -o \"$2\")\n  if [[ -z ${OSMIUM_DIST_TOKEN:-} ]]; then\n    curl \"${opts[@]}\" \"$url\"\n  elif [[ $OSMIUM_DIST_TOKEN =~ ^[A-Za-z0-9]+$ ]]; then\n    printf 'header = \"Authorization: Bearer %s\"\\n' \"$OSMIUM_DIST_TOKEN\" | curl -K - \"${opts[@]}\" \"$url\"\n  else\n    osm_log \"OSMIUM_DIST_TOKEN is not alphanumeric: not sent\"\n    curl \"${opts[@]}\" \"$url\"\n  fi\n}\n\nosm_verify() {\n  local pub; pub=$(mktemp) || return 1\n  printf '%s\\n' \"$OSM_PUBKEY\" > \"$pub\"\n  openssl pkeyutl -verify -pubin -inkey \"$pub\" -rawin -in \"$1\" -sigfile \"$2\" >/dev/null 2>&1\n  local rc=$?\n  rm -f \"$pub\"\n  [[ $rc == 0 && $(head -1 \"$1\") == \"${3:-osmium-release 1}\" ]]\n}\n\nosm_field() { awk -v k=\"$2\" -v n=\"${3:-2}\" '$1==k {print $n; exit}' \"$1\"; }\n\nosm_release() {\n  local dir=$1 ver=${OSMIUM_VERSION:-latest} chan=${OSMIUM_CHANNEL:-stable} remote\n  [[ -n $ver ]] || ver=latest\n  if [[ $ver == latest ]]; then remote=\"channels/$chan.release\"; else remote=\"releases/$ver.release\"; fi\n  if ! osm_get \"$remote\" \"$dir/release\" || ! osm_get \"$remote.sig\" \"$dir/release.sig\"; then\n    osm_log \"cannot fetch $remote from the Osmium release server (${OSMIUM_DIST_URL:-https://releases.osmiummod.com})\"\n    return 1\n  fi\n  if ! osm_verify \"$dir/release\" \"$dir/release.sig\"; then\n    osm_log \"SIGNATURE CHECK FAILED for $remote: nothing from it is installed\"\n    return 1\n  fi\n  if [[ $ver == latest && $(osm_field \"$dir/release\" channel) != \"$chan\" ]] || [[ $ver != latest && $(osm_field \"$dir/release\" version) != \"$ver\" ]]; then\n    osm_log \"$remote does not describe what was asked for (channel $chan, version $ver)\"\n    return 1\n  fi\n}\n\nosm_download() {\n  local part=\"$4.part\"\n  rm -f \"$part\"\n  [[ $3 =~ ^[0-9]+$ ]] || { osm_log \"$1: no size in the signed descriptor\"; return 1; }\n  osm_get \"$1\" \"$part\" \"$3\" || { osm_log \"download of $1 failed\"; rm -f \"$part\"; return 1; }\n  if [[ $(stat -c %s \"$part\") != \"$3\" || $(osm_sha \"$part\") != \"$2\" ]]; then\n    osm_log \"$1: size or sha256 does not match the signed descriptor; discarded\"\n    rm -f \"$part\"\n    return 1\n  fi\n  mv -f \"$part\" \"$4\"\n}\n\nosm_stamp() {\n  local u; u=$(osm_field \"$1\" updated)\n  [[ $u =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]] && printf '%s' \"${u//[^0-9]/}\"\n}\n\nosm_support() {\n  local egg=\"$1/osmium/egg\" chan=${OSMIUM_CHANNEL:-stable} tmp new old\n  tmp=$(mktemp -d) || return 1\n  if osm_get \"channels/$chan.support\" \"$tmp/s\" 2>/dev/null && osm_get \"channels/$chan.support.sig\" \"$tmp/s.sig\" 2>/dev/null \\\n     && osm_verify \"$tmp/s\" \"$tmp/s.sig\" \"osmium-support 1\" && [[ $(osm_field \"$tmp/s\" channel) == \"$chan\" ]]; then\n    new=$(osm_stamp \"$tmp/s\")\n    if [[ -f $egg/support ]] && osm_verify \"$egg/support\" \"$egg/support.sig\" \"osmium-support 1\" \\\n       && [[ $(osm_field \"$egg/support\" channel) == \"$chan\" ]] && old=$(osm_stamp \"$egg/support\") \\\n       && [[ -n $old ]] && { [[ -z $new ]] || (( 10#$new < 10#$old )); }; then\n      osm_log \"!! the release server sent a support list from $(osm_field \"$tmp/s\" updated), older than the one this server has ($(osm_field \"$egg/support\" updated)): ignored, using the newer one\"\n    else\n      mkdir -p \"$egg\" && mv -f \"$tmp/s\" \"$egg/support\" && mv -f \"$tmp/s.sig\" \"$egg/support.sig\"\n    fi\n  elif [[ -f $egg/support ]] && osm_verify \"$egg/support\" \"$egg/support.sig\" \"osmium-support 1\"; then\n    [[ ${2:-} == quiet ]] || osm_log \"cannot fetch the support list from the release server: using the one from $(osm_field \"$egg/support\" updated)\"\n  else\n    rm -rf \"$tmp\"\n    [[ ${2:-} == quiet ]] || osm_log \"no support list from the release server (${OSMIUM_DIST_URL:-https://releases.osmiummod.com})\"\n    return 1\n  fi\n  rm -rf \"$tmp\"\n}\n\nosm_support_version() {\n  awk -v b=\"$2\" '$1==\"build\" && $2==b {v=$4} END {if (v != \"\") print v}' \"$1/osmium/egg/support\" 2>/dev/null\n}\n\nosm_update() {\n  local game=$1 egg=\"$1/osmium/egg\" tmp rc=0\n  mkdir -p \"$egg\" || return 1\n  tmp=$(mktemp -d) || return 1\n  if osm_release \"$tmp\"; then\n    local r=\"$tmp/release\" ver\n    ver=$(osm_field \"$r\" version)\n    if [[ ! -x $egg/osmium || $(osm_sha \"$egg/osmium\") != \"$(osm_field \"$r\" cli 3)\" ]]; then\n      if osm_download \"$(osm_field \"$r\" cli)\" \"$(osm_field \"$r\" cli 3)\" \"$(osm_field \"$r\" cli 4)\" \"$tmp/osmium\"; then\n        chmod 755 \"$tmp/osmium\" && mv -f \"$tmp/osmium\" \"$egg/osmium\" && osm_log \"osmium CLI $ver installed\"\n      else\n        rc=1\n      fi\n    fi\n    if [[ $rc == 0 && $(cat \"$egg/bundle.sha256\" 2>/dev/null) != \"$(osm_field \"$r\" bundle 3)\" ]]; then\n      osm_log \"installing Osmium $ver ...\"\n      if osm_download \"$(osm_field \"$r\" bundle)\" \"$(osm_field \"$r\" bundle 3)\" \"$(osm_field \"$r\" bundle 4)\" \"$tmp/bundle.tar.zst\" \\\n         && \"$egg/osmium\" egg install --game \"$game\" --bundle \"$tmp/bundle.tar.zst\"; then\n        cp -f \"$r\" \"$egg/release\" && cp -f \"$r.sig\" \"$egg/release.sig\"\n      else\n        osm_log \"Osmium $ver was NOT installed\"\n        rc=1\n      fi\n    elif [[ $rc == 0 ]]; then\n      osm_log \"Osmium $ver is current\"\n      cp -f \"$r\" \"$egg/release\" && cp -f \"$r.sig\" \"$egg/release.sig\"\n    fi\n  else\n    rc=1\n  fi\n  rm -rf \"$tmp\"\n  return $rc\n}\n\nosm_stage() {\n  local game=$1 egg=\"$1/osmium/egg\" tmp rc=0 want=${2:-latest}\n  if ! \"$egg/osmium\" egg stage --help >/dev/null 2>&1; then\n    osm_log \"the installed osmium CLI predates update policies: updating like policy auto\"\n    OSMIUM_VERSION=$want osm_update \"$game\"\n    return\n  fi\n  tmp=$(mktemp -d) || return 1\n  if OSMIUM_VERSION=$want osm_release \"$tmp\"; then\n    local r=\"$tmp/release\" sha\n    sha=$(osm_field \"$r\" bundle 3)\n    if [[ $(cat \"$egg/bundle.sha256\" 2>/dev/null) == \"$sha\" ]] \\\n       || [[ -f $egg/staged/$(osm_field \"$r\" version)/.ok && $(cat \"$egg/staged/$(osm_field \"$r\" version)/bundle.sha256\" 2>/dev/null) == \"$sha\" ]]; then\n      \"$egg/osmium\" egg decide --game \"$game\" --descriptor \"$r\" >/dev/null || rc=1\n    elif osm_download \"$(osm_field \"$r\" bundle)\" \"$sha\" \"$(osm_field \"$r\" bundle 4)\" \"$tmp/bundle.tar.zst\" \\\n         && osm_download \"$(osm_field \"$r\" cli)\" \"$(osm_field \"$r\" cli 3)\" \"$(osm_field \"$r\" cli 4)\" \"$tmp/osmium\"; then\n      \"$egg/osmium\" egg stage --game \"$game\" --descriptor \"$r\" --signature \"$r.sig\" --bundle \"$tmp/bundle.tar.zst\" --cli \"$tmp/osmium\" >/dev/null || rc=1\n    else\n      rc=1\n    fi\n  else\n    rc=1\n  fi\n  rm -rf \"$tmp\"\n  return $rc\n}\n\nosm_gate() {\n  local game=$1 egg=\"$1/osmium/egg\" name=${OSMIUM_GATE_EXTENSION:-} url=${OSMIUM_GATE_PACKAGE_URL:-}\n  local pin prev=\"\" prev_sha=\"\" pkg=\"\" kv rc\n  local -a args opts\n  pin=$(printf %s \"${OSMIUM_GATE_PACKAGE_SHA256:-}\" | tr 'A-F' 'a-f')\n  [[ -f $egg/gate ]] && read -r prev prev_sha < \"$egg/gate\"\n  if [[ -z $name ]]; then\n    [[ -z $prev ]] || \"$egg/osmium\" egg extension disable --game \"$game\" --name \"$prev\"\n    return\n  fi\n  args=(egg extension install --game \"$game\" --name \"$name\" --address \"${OSMIUM_GATE_ADDRESS:-}\" --credentials-env OSMIUM_GATE_CREDENTIALS)\n\n  [[ ${OSMIUM_TRANSFER_WITH_GATE:-0} =~ ^(1|true|yes|on)$ ]] && args+=(--transfer-with-gate)\n  if [[ ! $pin =~ ^[0-9a-f]{64}$ ]]; then\n    osm_log \"!! gate extension $name: OSMIUM_GATE_PACKAGE_SHA256 must be the package's sha256 (64 hex digits); nothing is downloaded\"\n  else\n    args+=(--sha256 \"$pin\")\n    if [[ $name != \"$prev\" || $pin != \"$prev_sha\" || ! -f $game/osmium/extensions/$name/extension.json ]]; then\n      if [[ ! $url =~ ^https?:// ]]; then\n        osm_log \"!! gate extension $name: OSMIUM_GATE_PACKAGE_URL must be an http(s) URL\"\n      else\n        pkg=$(mktemp \"$egg/.gate-package.XXXXXX\") || return 1\n        if curl -fsSL --proto '=http,https' --connect-timeout 10 --max-time 600 -o \"$pkg\" \"$url\" && [[ $(osm_sha \"$pkg\") == \"$pin\" ]]; then\n          args+=(--package \"$pkg\")\n        else\n          osm_log \"!! gate extension $name: no package matching the pinned sha256 could be downloaded; keeping the installed one\"\n        fi\n      fi\n    fi\n  fi\n  IFS=',' read -ra opts <<< \"${OSMIUM_GATE_OPTIONS:-}\"\n  for kv in \"${opts[@]}\"; do\n    [[ $kv =~ ^[[:space:]]*$ ]] && continue\n    if [[ $kv =~ ^[[:space:]]*([^=[:space:]][^=]*[^=[:space:]]|[^=[:space:]])[[:space:]]*=[[:space:]]*(.*[^[:space:]]|)[[:space:]]*$ ]]; then\n      args+=(--option \"${BASH_REMATCH[1]}=${BASH_REMATCH[2]}\")\n    else\n      osm_log \"!! OSMIUM_GATE_OPTIONS: '$kv' is not key=value; ignored\"\n    fi\n  done\n  \"$egg/osmium\" \"${args[@]}\"\n  rc=$?\n  [[ -z $pkg ]] || rm -f \"$pkg\"\n  return $rc\n}\n\nif [[ -x /mnt/server/RustDedicated ]] && { compgen -G \"/mnt/server/RustDedicated_Data/Managed/Oxide.*.dll\" > /dev/null \\\n   || [[ -d /mnt/server/carbon/managed || -f /mnt/server/libdoorstop.so ]] || compgen -G \"/mnt/server/HarmonyMods/Carbon*.dll\" > /dev/null; }; then\n    osm_pre=$(mktemp -d)\n    if osm_release \"$osm_pre\" && osm_download \"$(osm_field \"$osm_pre/release\" cli)\" \"$(osm_field \"$osm_pre/release\" cli 3)\" \"$(osm_field \"$osm_pre/release\" cli 4)\" \"$osm_pre/osmium\"; then\n        chmod 755 \"$osm_pre/osmium\"\n        \"$osm_pre/osmium\" adopt run --egg --game /mnt/server | grep -v '^need-validate$' \\\n            || echo \"[Osmium] !! taking over the other framework failed here; the first start tries again\"\n    else\n        echo \"[Osmium] !! could not fetch the osmium CLI to take over the other framework before SteamCMD; the first start takes it over (Oxide's patched assemblies are then not kept for a rollback)\"\n    fi\n    rm -rf \"$osm_pre\"\nfi\n\nif [ \"${STEAM_USER}\" == \"\" ]; then\n    STEAM_USER=anonymous\n    STEAM_PASS=\"\"\n    STEAM_AUTH=\"\"\nfi\ncd /tmp\nmkdir -p /mnt/server/steamcmd\ncurl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz\ntar -xzf steamcmd.tar.gz -C /mnt/server/steamcmd\nmkdir -p /mnt/server/steamapps\ncd /mnt/server/steamcmd\n\nosm_owner=$(stat -c %u:%g /mnt/server 2>/dev/null)\nchown -R root:root /mnt\nexport HOME=/mnt/server\n./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +app_update ${SRCDS_APPID} $( [[ -z ${SRCDS_BETAID} ]] || printf %s \"-beta ${SRCDS_BETAID}\" ) validate +quit\nmkdir -p /mnt/server/.steam/sdk32 /mnt/server/.steam/sdk64\ncp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so\ncp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so\nif [ ! -x /mnt/server/RustDedicated ]; then\n    echo \"SteamCMD did not install RustDedicated\"\n    exit 1\nfi\n\ncd /mnt/server\nmkdir -p osmium/egg\n\nbuild=$(awk -F'\"' '$2==\"buildid\" {print $4; exit}' steamapps/appmanifest_258550.acf 2>/dev/null)\nif [[ ${OSMIUM_VERSION:-latest} == latest ]] && osm_support /mnt/server && v=$(osm_support_version /mnt/server \"$build\") && [[ -n $v ]]; then\n    export OSMIUM_VERSION=$v\nfi\nif ! osm_update /mnt/server; then\n    echo \"[Osmium] install FAILED (see above). The release server is ${OSMIUM_DIST_URL:-https://releases.osmiummod.com}.\"\n    exit 1\nfi\necho \"[Osmium] installed; the first start weaves the hooks into this Rust build\"\n\nosmium/egg/osmium adopt run --egg --game /mnt/server 2>/dev/null | grep -v '^need-validate$'\n\nif [[ -n $osm_owner && $osm_owner != 0:0 ]]; then\n    chown -R \"$osm_owner\" /mnt/server && echo \"[Osmium] server files owned by $osm_owner again\"\nfi\ntrue\n",
            "container": "ghcr.io/pterodactyl/installers:debian",
            "entrypoint": "bash"
        }
    },
    "variables": [
        {
            "name": "Server Name",
            "description": "The name of your server in the public server list.",
            "env_variable": "SERVER_HOSTNAME",
            "default_value": "A Rust Server",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|max:60",
            "field_type": "text"
        },
        {
            "name": "Osmium Channel",
            "description": "Release channel Osmium installs from (checked on every start).",
            "env_variable": "OSMIUM_CHANNEL",
            "default_value": "public",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|regex:/^[a-z0-9][a-z0-9-]*$/|max:32",
            "field_type": "text"
        },
        {
            "name": "Update Policy",
            "description": "How Osmium updates: when-needed = prepared in the background, applied only when really needed (new Rust build, security fix, changed hooks your plugins use), restarting when the server is empty or in the Update Window; staged = prepared in the background, applied at your next restart, never restarts on its own; auto = newest release at every start; manual = never; pinned:<version> = exactly that version.",
            "env_variable": "OSMIUM_UPDATE_POLICY",
            "default_value": "when-needed",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|regex:/^[a-z][a-z-]*(:[A-Za-z0-9][A-Za-z0-9._+-]*)?$/|max:72",
            "field_type": "text"
        },
        {
            "name": "Update Window",
            "description": "UTC time window (HH:MM-HH:MM, e.g. 05:00-06:00) in which when-needed may restart a server with players on it, after in-game warnings. Empty = only restart when nobody is online.",
            "env_variable": "OSMIUM_UPDATE_WINDOW",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|regex:/^[0-2][0-9]:[0-5][0-9]-[0-2][0-9]:[0-5][0-9]$/",
            "field_type": "text"
        },
        {
            "name": "Osmium Version",
            "description": "Older setting: an exact version pins it like Update Policy pinned:<version>. \"latest\" = use the Update Policy.",
            "env_variable": "OSMIUM_VERSION",
            "default_value": "latest",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|regex:/^[A-Za-z0-9][A-Za-z0-9._+-]*$/|max:64",
            "field_type": "text"
        },
        {
            "name": "Osmium Mode",
            "description": "woven = hooks baked into the game assemblies before start (all 841, no patch cost); runtime = patched at runtime (fallback, some hooks need the weave).",
            "env_variable": "OSMIUM_MODE",
            "default_value": "woven",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:woven,runtime",
            "field_type": "text"
        },
        {
            "name": "Rust Update",
            "description": "What a start does when Steam has a newer Rust build. Osmium only runs on builds it has a release for (one usually follows a Rust update within minutes). hold = update only to a build with a release, else start the installed build; wait = update at once and wait (offline) for the release, then start by itself; off = never update Rust; empty = wait for Update Policy auto, hold for every other policy.",
            "env_variable": "OSMIUM_GAME_UPDATE",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|in:hold,wait,off",
            "field_type": "text"
        },
        {
            "name": "Osmium Framework Update",
            "description": "Older setting: 0 = never update (like Update Policy manual); 1 = use the Update Policy.",
            "env_variable": "OSMIUM_FRAMEWORK_UPDATE",
            "default_value": "1",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:0,1",
            "field_type": "text"
        },
        {
            "name": "Description",
            "description": "The description under your server title. Commonly used for rules & info. Use \\n for newlines.",
            "env_variable": "DESCRIPTION",
            "default_value": "Powered by Osmium",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string",
            "field_type": "text"
        },
        {
            "name": "Level",
            "description": "The world file for Rust to use.",
            "env_variable": "LEVEL",
            "default_value": "Procedural Map",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|max:20",
            "field_type": "text"
        },
        {
            "name": "URL",
            "description": "The URL for your server. This is what comes up when clicking the \"Visit Website\" button.",
            "env_variable": "SERVER_URL",
            "default_value": "http://example.com",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|url",
            "field_type": "text"
        },
        {
            "name": "World Size",
            "description": "The world size for a procedural map.",
            "env_variable": "WORLD_SIZE",
            "default_value": "3000",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "World Seed",
            "description": "The seed for a procedural map.",
            "env_variable": "WORLD_SEED",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string",
            "field_type": "text"
        },
        {
            "name": "Max Players",
            "description": "The maximum amount of players allowed in the server at once.",
            "env_variable": "MAX_PLAYERS",
            "default_value": "40",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "Server Image",
            "description": "The header image for the top of your server listing.",
            "env_variable": "SERVER_IMG",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|url",
            "field_type": "text"
        },
        {
            "name": "Query Port",
            "description": "Server Query Port. Can't be the same as Game's primary port.",
            "env_variable": "QUERY_PORT",
            "default_value": "27017",
            "user_viewable": true,
            "user_editable": false,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "RCON Port",
            "description": "Port for RCON connections.",
            "env_variable": "RCON_PORT",
            "default_value": "28016",
            "user_viewable": true,
            "user_editable": false,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "RCON Password",
            "description": "RCON access password.",
            "env_variable": "RCON_PASS",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|regex:/^[\\w.-]*$/|max:64",
            "field_type": "text"
        },
        {
            "name": "Save Interval",
            "description": "Sets the server's auto-save interval in seconds.",
            "env_variable": "SAVEINTERVAL",
            "default_value": "60",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "Additional Arguments",
            "description": "Add additional startup parameters to the server.",
            "env_variable": "ADDITIONAL_ARGS",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string",
            "field_type": "text"
        },
        {
            "name": "App Port",
            "description": "Port for the Rust+ App. -1 to disable.",
            "env_variable": "APP_PORT",
            "default_value": "28082",
            "user_viewable": true,
            "user_editable": false,
            "rules": "required|integer",
            "field_type": "text"
        },
        {
            "name": "Server Logo",
            "description": "The circular server logo for the Rust+ app.",
            "env_variable": "SERVER_LOGO",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|url",
            "field_type": "text"
        },
        {
            "name": "Custom Map URL",
            "description": "Overwrites the map with the one from the direct download URL. Invalid URLs will cause the server to crash.",
            "env_variable": "MAP_URL",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|url",
            "field_type": "text"
        },
        {
            "name": "Auto Update",
            "description": "Leave 0: Osmium's start script updates Rust itself, and only to builds Osmium has a release for (see Rust Update). 1 = the image updates Rust before Osmium can check, so the server cannot be held on a supported build.",
            "env_variable": "AUTO_UPDATE",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": false,
            "rules": "nullable|string|max:20",
            "field_type": "text"
        },
        {
            "name": "Steam Beta Branch",
            "description": "Leave empty (public): Osmium releases are made for Rust's public branch only, and a server on another branch does not start.",
            "env_variable": "SRCDS_BETAID",
            "default_value": "",
            "user_viewable": true,
            "user_editable": false,
            "rules": "nullable|string|max:20",
            "field_type": "text"
        },
        {
            "name": "App ID",
            "description": "",
            "env_variable": "SRCDS_APPID",
            "default_value": "258550",
            "user_viewable": false,
            "user_editable": false,
            "rules": "required|string|in:258550",
            "field_type": "text"
        },
        {
            "name": "Osmium Release Server",
            "description": "Osmium's public release server. Every release it serves is signed; the signature and each file's checksum are checked before use.",
            "env_variable": "OSMIUM_DIST_URL",
            "default_value": "https://releases.osmiummod.com",
            "user_viewable": false,
            "user_editable": false,
            "rules": "required|string|regex:/^https?:\\/\\/[A-Za-z0-9.:\\[\\]-]+$/|max:128",
            "field_type": "text"
        },
        {
            "name": "Osmium Node Token",
            "description": "Not used by the public release server; leave it empty.",
            "env_variable": "OSMIUM_DIST_TOKEN",
            "default_value": "",
            "user_viewable": false,
            "user_editable": false,
            "rules": "nullable|string|regex:/^[A-Za-z0-9]{32,128}$/",
            "field_type": "text"
        },
        {
            "name": "Gate Extension",
            "description": "Join this server to a gate: the name of the extension the gate operator gave you. Empty = not joined (emptying it disables the extension on the next start).",
            "env_variable": "OSMIUM_GATE_EXTENSION",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|regex:/^[a-z0-9][a-z0-9._-]*$/|max:64",
            "field_type": "text"
        },
        {
            "name": "Gate Package URL",
            "description": "Where the extension package (.tar.zst or .tar.gz) is downloaded from.",
            "env_variable": "OSMIUM_GATE_PACKAGE_URL",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|regex:/^https?:\\/\\/\\S+$/|max:512",
            "field_type": "text"
        },
        {
            "name": "Gate Package SHA-256",
            "description": "The package's sha256 (64 hex digits). Required: a download that does not match is refused.",
            "env_variable": "OSMIUM_GATE_PACKAGE_SHA256",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|regex:/^[A-Fa-f0-9]{64}$/",
            "field_type": "text"
        },
        {
            "name": "Gate Address",
            "description": "Given by the gate operator; passed to the extension as is.",
            "env_variable": "OSMIUM_GATE_ADDRESS",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|max:1024",
            "field_type": "text"
        },
        {
            "name": "Gate Credentials",
            "description": "Given by the gate operator; passed to the extension as is, and removed from the game's environment before it starts.",
            "env_variable": "OSMIUM_GATE_CREDENTIALS",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|max:4096",
            "field_type": "text"
        },
        {
            "name": "Gate Options",
            "description": "Extra settings for the extension, as key=value,key=value.",
            "env_variable": "OSMIUM_GATE_OPTIONS",
            "default_value": "",
            "user_viewable": true,
            "user_editable": true,
            "rules": "nullable|string|max:2048",
            "field_type": "text"
        },
        {
            "name": "Transfers Alongside Gate",
            "description": "1 = keep Osmium's own server transfers on while this server is joined to a gate. Off (0) by default: the gate owns travel, and both moving the same player risks duplicates.",
            "env_variable": "OSMIUM_TRANSFER_WITH_GATE",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|boolean",
            "field_type": "boolean"
        },
        {
            "name": "Accept Osmium Terms",
            "description": "Osmium's Terms of Use (https://osmiummod.com/terms). Set to 1 to accept the version this release carries; the server does not start until you do (0). Accepting registers your acceptance with us once and activates a perpetual licence; after that no further contact is ever needed. If a later release materially changes the Terms, Osmium loads no plugins until you accept again on the server: set this to that version (for example 2026-10-18, shown in the console) or run osmium.terms accept. Every category of data collection is off by default, and you can turn any category on or off later (the Send ... variables below). Player names, SteamIDs, IP addresses and chat are never collected.",
            "env_variable": "OSMIUM_ACCEPT_TERMS",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|string|regex:/^[0-9]([0-9]{3}-[0-9]{2}-[0-9]{2})?$/",
            "field_type": "text"
        },
        {
            "name": "Grace hours",
            "description": "Hours an unactivated server keeps running Osmium before it stops loading plugins and modules (the game server itself keeps running). Default 72. 0 = stop loading at once if activation cannot complete.",
            "env_variable": "OSMIUM_GRACE_HOURS",
            "default_value": "72",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|integer|min:0|max:8760",
            "field_type": "text"
        },
        {
            "name": "Send error reports",
            "description": "Off by default. 1 = send exceptions from Osmium and your plugins, and plugin load failures, scrubbed of player names, SteamIDs, IP addresses and chat.",
            "env_variable": "OSMIUM_TELEMETRY_ERRORS",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:0,1",
            "field_type": "text"
        },
        {
            "name": "Send performance detail",
            "description": "Off by default. 1 = send the performance-detail summary (uptime, player counts, frame time, plugin timings and memory, log warnings and errors), scrubbed.",
            "env_variable": "OSMIUM_TELEMETRY_PERFORMANCE",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:0,1",
            "field_type": "text"
        },
        {
            "name": "Upload plugins and configuration",
            "description": "Off by default. 1 = upload your plugin and configuration files (secrets redacted). Not built yet on this build; it does nothing for now.",
            "env_variable": "OSMIUM_TELEMETRY_UPLOAD",
            "default_value": "0",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:0,1",
            "field_type": "text"
        },
        {
            "name": "Osmium credit",
            "description": "On (1) by default: the server browser shows one line \"Powered by Osmium - osmiummod.com\" under your description, the server's tags include osmium, and each player gets one small grey chat line \"This server runs Osmium - osmiummod.com\" once per wipe. Nothing in the game changes. 0 = off from the next start. Each part can be switched in osmium/config/modules/advert.json or with osmium.module advert.",
            "env_variable": "OSMIUM_ADVERT",
            "default_value": "1",
            "user_viewable": true,
            "user_editable": true,
            "rules": "required|in:0,1",
            "field_type": "text"
        }
    ]
}
