Use case · Game server

Core Keeper dedicated server on Linux: SteamCMD, _launch.sh and ServerConfig.json

A Core Keeper dedicated server is Pugstorm's free Steam tool, app 1963720, installed with SteamCMD's anonymous login next to the Steamworks SDK Redist (app 1007) and started on headless Linux by _launch.sh, which runs the server against a virtual X display. Players on Steam join with the Game ID the server writes to GameID.txt; since patch 1.1.2.3, players from other PC stores can connect by IP, port and password. Below: the install under a service account, the config file, a systemd unit, stopped-server backups with a guarded restore, and the machine to put it on.

See the game servers

What the server asks of the hardware

Pugstorm publishes no hardware figures for the dedicated server. Steam lists the client's: a 64-bit processor and OS, an Intel Core i5-2300 or AMD Ryzen 3 1200 as the minimum and an i5-8400 or Ryzen 7 2700X as recommended, with 8 GB of RAM on the Windows lines and Ubuntu 20.04 (minimum) or 22.04 (recommended) on the Linux lines. That machine also draws the game.

FactValueSource
Server app1963720, anonymous loginCore Keeper Wiki, Dedicated server
Extra app1007, Steamworks SDK RedistCore Keeper Wiki, Dedicated server
Player cap settingmaxNumberPlayers, 1 to 100Core Keeper Wiki, Server Config
Graphics stackXvfb plus Mesa OpenGLWiki, Red Hat steps
CPU loadcut by a third in 0.7.50.7.5 patch notes

On a box with no graphics card, note this: the wiki's Red Hat steps install Xvfb and Mesa's OpenGL libraries because the server uses OpenGL to generate terrain after the first world build, and since 1.0.0.14 the server log says more when the GPU or its graphics stack lacks a rendering feature the server needs. Our reading: no card is required, and headless, Mesa runs that work on the processor. Our working rule, not Pugstorm's: start from the recommended client CPU class and 8 GB, then watch load while players dig into new ground.

Which machine to rent

Use an x86-64 rack server or blade from the game server range. Valve's SteamCMD page lists Linux dependencies for x86-64 only, Steam ships the game for Windows and Linux, and we found no arm64 build, so both ARM lines we run (the X-Gene cartridge and the Ampere Altra) are out. Rack servers and blades carry an out-of-band controller (HPE iLO, Dell iDRAC or a Supermicro BMC): add a console login and a browser console reaches the box even after a bad ufw rule.

No neighbour competes for the cores Mesa uses to build terrain, you hold root, and nothing meters the port. Pick a city from our five locations. Ready servers go live about 30 minutes after the order is approved; a build to order takes 4 to 24 hours.

Installing SteamCMD and the server

The wiki's Debian and Ubuntu section creates a no-login system user, installs SteamCMD, then pulls apps 1007 and 1963720 into one folder with login anonymous. The block below follows it on Ubuntu 24.04 with changes of ours: ufw first (IPv6 rules on, SSH allowed, then enabled), SteamCMD from Valve's tarball in the user's home rather than the distribution package (no licence dialog mid-paste), xvfb installed up front with libgl1-mesa-dri and libxi6 as our Ubuntu equivalents of the Mesa and libXi packages in the wiki's Red Hat list, and /home/corekeeper/server as the install path. No game port is opened: the May 2022 launch post says port forwarding is no longer needed for Game ID joins.

sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw &&
sudo ufw allow OpenSSH &&
sudo ufw --force enable &&
sudo apt update && sudo apt install -y lib32gcc-s1 curl xvfb libgl1-mesa-dri libxi6 &&
{ id -u corekeeper > /dev/null 2>&1 || sudo useradd -mrU -s /usr/sbin/nologin corekeeper; } &&
sudo chmod 750 /home/corekeeper &&
sudo -u corekeeper bash -o pipefail -c 'cd /home/corekeeper && mkdir -p steamcmd && curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxf - -C steamcmd' &&
sudo -u corekeeper bash -c 'cd /home/corekeeper && steamcmd/steamcmd.sh +force_install_dir /home/corekeeper/server +login anonymous +app_update 1007 validate +app_update 1963720 validate +quit' &&
sudo test -f /home/corekeeper/server/_launch.sh && echo installed

Each step, the final check included, is chained with &&; a re-run skips useradd. No installed line means: fix the first error, paste again. Per the wiki, _launch.sh checks a requirements list with dpkg and installs what is missing with apt-get, which a no-login account cannot do. Read the list with sudo grep -n requirements /home/corekeeper/server/_launch.sh and install those packages yourself. Then start it once by hand to build the world: sudo -u corekeeper bash -c 'cd /home/corekeeper/server && bash _launch.sh'. Once GameID.txt shows up in the install folder, press Ctrl+C, wait for your prompt, and confirm pgrep -u corekeeper prints nothing before writing or enabling the unit below. Should the Steam client library fail to load, the wiki suggests copying steamclient.so from SteamCMD's linux64 folder into the service user's ~/.steam/sdk64/.

ServerConfig.json and launch arguments

The world, its settings and the server's data folder live in /home/corekeeper/.config/unity3d/Pugstorm/Core Keeper/DedicatedServer/, the Ubuntu path the wiki's Server Config page gives for the user who runs the server. Edit ServerConfig.json there while the server is stopped, with sudoedit so the file keeps its owner.

  • gameId: the ID Steam players type to join. The wiki says one that is too short is replaced with a random string; patch 1.1.2.3 lowered the minimum to 15 characters.
  • world: the wiki leaves it undescribed; our reading is that it picks the world slot. worldName and worldSeed name and seed the world. Since 1.0.0.6 the seed accepts general text, as in the game's own world menu.
  • maxNumberPlayers: 1 to 100, per the wiki's table.
  • seasonOverride forces a seasonal event (-1 for none). worldMode is not described on the wiki either; we take it to be the game mode.
  • Launch flags are forwarded by the script (0.4.0 notes). -activateallcontent (1.1.2.4) switches on new content bundles after each update; our unit passes it, so drop it if you prefer to pick bundles yourself. -datapath sets the save folder (0.7.0.1 notes). ARGUMENTS.txt (1.1.0) lists the rest, and README.txt covers custom world generation (1.0.0.6) and direct connections.

After a start, GameID.txt and the log CoreKeeperServerLog.txt sit in the install folder (1.1.2.4 notes). Since 1.1.2.4 the server labels that value the Steam GameID, because only the Steam client can join with it. Epic, GOG and Microsoft Store players use a direct connection by IP, port and password, which README.txt explains how to enable. If you turn it on, open the port README names with ufw, using the protocol it gives.

systemd unit and nightly save archive

The wiki's unit runs _launch.sh as the service user with KillMode=process and restarts on failure. Ours keeps KillMode=process and adds a SteamCMD update before each start, Restart=always, the -activateallcontent flag and a backup script. Paste it only after the hand-run server is gone: the block writes nothing if a corekeeper process is alive or _launch.sh is missing. We found no official statement on how the Linux server saves when systemd stops it, so the script will not archive while any process of the account survives the stop, and it does not restart either: the server stays down until you have checked it.

if sudo test -f /home/corekeeper/server/_launch.sh && ! pgrep -u corekeeper > /dev/null; then
sudo tee /etc/systemd/system/corekeeper.service > /dev/null <<'EOF' &&
[Unit]
Description=Core Keeper dedicated server
Wants=network-online.target
After=network-online.target

[Service]
User=corekeeper
WorkingDirectory=/home/corekeeper/server
ExecStartPre=-/home/corekeeper/steamcmd/steamcmd.sh +force_install_dir /home/corekeeper/server +login anonymous +app_update 1007 +app_update 1963720 +quit
ExecStart=/bin/bash /home/corekeeper/server/_launch.sh -activateallcontent
KillMode=process
TimeoutStartSec=1800
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
sudo install -d -m 700 /var/backups/corekeeper &&
sudo tee /usr/local/sbin/ck-backup.sh > /dev/null <<'EOF' &&
D="/home/corekeeper/.config/unity3d/Pugstorm/Core Keeper"
F="/var/backups/corekeeper/ck-$(date +%F-%H%M).tar.gz"
systemctl stop corekeeper || exit 1
if pgrep -u corekeeper > /dev/null; then echo "still running: not backing up, not restarting"; exit 1; fi
tar -czf "$F" -C "$D" DedicatedServer; rc=$?
[ "$rc" -eq 0 ] || rm -f "$F"
systemctl start corekeeper
[ "$rc" -eq 0 ] && tar -tzf "$F" > /dev/null && find /var/backups/corekeeper -name 'ck-*.tar.gz' -mtime +14 -delete
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now corekeeper
else echo "no install, or a corekeeper process still runs: nothing written"; fi
  • The - before ExecStartPre lets the server start when SteamCMD exits with an error. It does not cover an update that hangs: TimeoutStartSec=1800, our margin, ends that attempt and Restart=always tries again.
  • Extra flags belong after -activateallcontent on that line. Each edit of the unit needs sudo systemctl daemon-reload before sudo systemctl restart corekeeper picks it up.
  • A failed tar removes its partial archive. Archives older than 14 days are deleted only after the new one was written and reads back cleanly.
  • Schedule it with a root cron file, /etc/cron.d/corekeeper-backup, holding one line: 30 5 * * * root bash /usr/local/sbin/ck-backup.sh > /var/log/ck-backup.log 2>&1. The hour is ours; pick one when nobody plays, since the stop disconnects everyone.
  • Copy the archives off this machine yourself, with plain rsync -a or scp to a box you control. Never rsync --delete: an emptied source would empty the copies.

Restoring a world, with a way back

Patch 1.2.0.6 fixed characters losing inventory when a world was copied from one server or host to another, so moving a save between machines is a supported path. Set A to the archive you want. The block checks it reads, refuses if a DedicatedServer.old is already there, stops the server, makes sure nothing of the account is still running, moves the current folder aside (when there is one), unpacks, fixes ownership and starts. Run it as a user with sudo.

A=/var/backups/corekeeper/ck-YYYY-MM-DD-HHMM.tar.gz
D="/home/corekeeper/.config/unity3d/Pugstorm/Core Keeper"
if ! sudo tar -tzf "$A" > /dev/null; then echo "archive unreadable, nothing changed"
elif sudo test -e "$D/DedicatedServer.old"; then echo "DedicatedServer.old exists, move it away first"
else sudo systemctl stop corekeeper &&
  { ! pgrep -u corekeeper > /dev/null || { echo still running; false; }; } &&
  sudo mkdir -p "$D" &&
  { ! sudo test -e "$D/DedicatedServer" || sudo mv "$D/DedicatedServer" "$D/DedicatedServer.old"; } &&
  sudo tar -xzf "$A" -C "$D" &&
  sudo chown -R corekeeper:corekeeper /home/corekeeper/.config &&
  sudo systemctl start corekeeper && echo restored
fi

Join and check the world before you delete anything. To roll back, with D still set to its absolute path: `sudo test -d "$D/DedicatedServer.old" && sudo systemctl stop corekeeper && ! pgrep -u corekeeper > /dev/null && sudo rm -rf "$D/DedicatedServer" && sudo mv "$D/DedicatedServer.old" "$D/DedicatedServer" && sudo systemctl start corekeeper && echo rolled back. It works whether or not the backup was unpacked, as long as the current world was moved aside. When you are satisfied, remove the old copy with sudo rm -rf "$D/DedicatedServer.old"`.

When this is the wrong setup

Console players cannot join: the 1.1.2.4 notes say the game does not support crossplay between PC and consoles. A group that plays only now and then can use the in-game host option for free. A rented box pays off when the cavern must be reachable with its creator offline, the job Pugstorm released the tool for in May 2022. Same pattern, other games: the Necesse server guide and the Terraria one.

Questions

Which SteamCMD app IDs does the Core Keeper server use?

1963720 is the Core Keeper Dedicated Server tool, and the wiki also installs 1007, the Steamworks SDK Redist, into the same folder. Both download with login anonymous; no Steam account that owns the game is involved.

Where are the world files on a Linux server?

Under the running user's ~/.config/unity3d/Pugstorm/Core Keeper/DedicatedServer/, together with ServerConfig.json, per the wiki's Server Config page. The -datapath argument (0.7.0.1 notes) moves it. Back up the whole folder with the server stopped.

Do I need to open ports for friends to join?

Not for Steam players joining by Game ID: the 2022 launch announcement says port forwarding is no longer required. Direct connections by IP, port and password, which non-Steam PC players use, need the port you configure per README.txt opened in the firewall.

Does the Core Keeper server need a graphics card?

Our reading is no: the wiki's Linux setups run the server on Xvfb, and its Red Hat steps add Mesa's OpenGL libraries because world generation uses OpenGL. Without a GPU we expect that work to run on the CPU, so leave headroom while players explore.

How many players can one server hold?

The wiki lists maxNumberPlayers with values from 1 to 100 in ServerConfig.json. Pugstorm publishes no CPU or memory figure per player, so size from the client requirements and measure your own world.

Put the world on its own machine

Take an x86 rack server close to your group, install Ubuntu 24.04 and run the steps above.

See the game servers

Related on Server Room

Other use cases