Hosting Guides

Core Keeper Headless Deployment and Port Forwarding via LinuxGSM

8 min readDebian 12LinuxGSMUnity
Once your server is online, jump to the Core Keeper command and config reference.

Core Keeper does not get the spotlight that other survival games get, but the dedicated server is one of the cleanest small Unity titles to host: anonymous SteamCMD, a single Mono binary, and a flat server.json for all gameplay settings. The catch is that the game shipped with a non standard relay handshake that confuses naive port forward setups, so half the troubleshooting threads online are people whose clients connect through the Steam relay instead of directly to the dedicated server. This guide deploys Core Keeper on Debian 12 with LinuxGSM, configures direct UDP, and locks down a private long term underground world.

Prerequisites

  • Debian 12 with 4 GB RAM and 2 CPU cores (the server is small).
  • A non root user with sudo access.
  • UDP 27015 and UDP 27016 open at the firewall and forwarded to the host.
  • A SteamID64 for the host of the world.

Step 1: System Preparation

user@host
sudo adduser --disabled-password --gecos "" ckuser
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y curl wget file tar bzip2 gzip unzip bsdmainutils \
python3 util-linux ca-certificates binutils bc jq tmux netcat-openbsd \
lib32gcc-s1 lib32stdc++6 xvfb

Step 2: Install LinuxGSM and the Server

user@host
sudo machinectl shell ckuser@
cd ~
wget -O linuxgsm.sh https://linuxgsm.sh
chmod +x linuxgsm.sh
bash linuxgsm.sh ckserver
./ckserver install

The egg pulls Core Keeper through anonymous SteamCMD (app id 1963720). LinuxGSM wraps the launch in xvfb-run automatically because the Unity server still spins up a tiny headless GL context.

Step 3: Open the Required UDP Ports

user@host
sudo ufw allow 27015/udp
sudo ufw allow 27016/udp
sudo ufw reload

Step 4: Configure server.json

serverfiles/CoreKeeperServer_Data/server.json
{
"serverName": "Vardoran Caverns",
"worldName": "primary",
"worldSeed": 1881204332,
"worldMode": "Normal",
"gameId": "",
"maxPlayers": 8,
"discoverable": false,
"directIp": "0.0.0.0",
"gamePort": 27015,
"queryPort": 27016,
"season": "None"
}

Setting discoverable to false and leaving gameId empty forces clients to connect by direct IP rather than the Steam relay. That is what you want for a private long term world.

Step 5: First Boot

user@host
./ckserver start
./ckserver console
# Expect: "Server listening on 0.0.0.0:27015"
# And: "Game ID = abcd-efgh-ijkl-mnop"

Copy the printed Game ID and share it with friends. They will paste it into the in client server browser, and the connection will skip the relay because directIp is set.

Step 6: Save and Restart Schedule

user@host
crontab -e
0 */4 * * * /home/ckuser/ckserver send "save"
0 5 * * * /home/ckuser/ckserver restart
0 5 * * 0 /home/ckuser/ckserver update

Performance and Tuning

  • Pin maxPlayers at 8 unless you have specifically tested higher counts. Core Keeper's chunk streamer is the bottleneck, not the CPU.
  • Back up ~/.config/unity3d/Pugstorm/Core Keeper/DedicatedServer/<world>, that is where the actual world data lives.
  • Keep discoverable at false for any non public server, the public browser is a constant target for griefers.

Conclusion

Core Keeper is small enough that the entire deployment fits in one LinuxGSM install plus a flat JSON file. Lock the discovery off, forward the two UDP ports correctly, and the world will run quietly for as long as the host stays up.