Use case · Game server

Soulmask dedicated server on Linux: SteamCMD install, UDP ports, launch flags and saves

A Soulmask dedicated server runs natively on Linux or Windows: SteamCMD installs it anonymously as app 3017300 (Linux) or 3017310 (Windows), and each game process needs two UDP ports open, 8777 for the game and 27015 for the Steam query. The developer's guide asks for at least 16 GB of memory and 2-4 CPU cores per process. This page follows that guide to a Linux install that runs as an unprivileged user under systemd, stops cleanly through the maintenance port and archives the world on every restart.

See the game server machines

What the developer's guide specifies

The reference is the Private Server tutorial on the Soulmask wiki, which a developer announced on the game's Steam forum as the team's own dedicated server tutorial; the page is edit-locked to administrators. It was last revised in August 2024, before the 1.0 release, so treat file sizes as approximate. The 1.0 FAQ on Steam confirms private server saves stay usable.

ItemGuide's value
Operating systemLinux or Windows; several game instances per machine are allowed
Per game processAt least 16 GB of memory and 2-4 CPU cores
BandwidthAbout 100 kbps per player, inbound and outbound
DiskPackage of 1-2 GB, about 20 GB free for operation
Steam apps3017300 (Linux), 3017310 (Windows), login anonymous
Ports-Port 8777 UDP, -QueryPort 27015 UDP, -EchoPort TCP (18888 in its examples)
SavesWS/Saved; log at WS/Saved/Logs/WS.log

Sizing the machine

Memory decides the box. The 16 GB floor is for the game process alone, so the operating system, SteamCMD and the backup job need room above it; 16 GB of RAM total leaves none. Two linked worlds mean two processes and twice the floor. The guide asks for 2-4 cores per process; in our reading, extra cores mostly add room for more worlds. The Intel processor list shows the clock speed of each chip we rent.

Bandwidth is small. At the guide's 100 kbps per player, a 50-slot server is about 5 Mbit/s each way by our arithmetic. Disk is small too: the guide's 20 GB covers the install; leave room for the backup archives this page sets up.

Install on Ubuntu as an unprivileged user

Valve's SteamCMD wiki calls running it as the root user a security risk and lists lib32gcc-s1 as the dependency on 64-bit Ubuntu and Debian. Run this as root on a fresh install. The firewall goes on first, with IPv6 rules enabled before any rule is added, so nothing listens unprotected:

apt update && apt install -y lib32gcc-s1 curl telnet ufw
useradd -m -s /usr/sbin/nologin soulmask
sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
ufw default deny incoming
ufw allow 22/tcp
ufw allow 8777/udp
ufw allow 27015/udp
ufw --force enable
sudo -u soulmask bash -c 'mkdir -p /home/soulmask/steamcmd && cd /home/soulmask/steamcmd && curl -sqL https://client-update.steamstatic.com/installer/steamcmd_linux.tar.gz | tar zxf - && ./steamcmd.sh +force_install_dir /home/soulmask/server +login anonymous +app_update 3017300 validate +quit'

force_install_dir comes before login, as Valve's wiki requires. The maintenance port is deliberately absent from the rules: the guide says it does not need to be open, and it documents no password for it, so anyone who reached it could shut the world down.

The systemd unit: update, archive, launch, clean stop

The guide's pattern is to start StartServer.sh and append your own parameters. The join and admin passwords exist only as launch parameters (-PSW, -adminpsw); the Engine.ini keys it documents do not include them. So keep them out of the unit file: create /etc/soulmask.env with install -m 600 /dev/null /etc/soulmask.env, open it in an editor, and add two lines, SM_PSW= and SM_ADMIN=, each followed by a password without spaces. The unit file goes at /etc/systemd/system/soulmask.service:

[Unit]
Description=Soulmask dedicated server
Wants=network-online.target
After=network-online.target

[Service]
User=soulmask
WorkingDirectory=/home/soulmask/server
EnvironmentFile=/etc/soulmask.env
ExecStartPre=-/bin/bash -c 'umask 077; mkdir -p /home/soulmask/backup; find /home/soulmask/backup -name "saved-*.tgz" -mtime +14 -delete; [ -d WS/Saved ] && tar czf /home/soulmask/backup/saved-$$(date +%%Y%%m%%d-%%H%%M).tgz WS/Saved'
ExecStartPre=-/home/soulmask/steamcmd/steamcmd.sh +force_install_dir /home/soulmask/server +login anonymous +app_update 3017300 +quit
ExecStart=/bin/bash /home/soulmask/server/StartServer.sh "-SteamServerName=Night Shift Tribe" -MaxPlayers=20 -pve -Port=8777 -QueryPort=27015 -EchoPort=18888 -PSW=${SM_PSW} -adminpsw=${SM_ADMIN}
ExecStop=/bin/bash -c '(sleep 1; echo "quit 10"; sleep 3) | telnet 127.0.0.1 18888; while kill -0 $MAINPID 2>/dev/null; do sleep 2; done'
TimeoutStartSec=1800
TimeoutStopSec=180
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • Both ExecStartPre lines start with -, so a failed archive or a Steam outage cannot block the start; the server simply runs one version behind. The - does not cover a timeout, though: systemd's default 90-second start limit includes every ExecStartPre, so TimeoutStartSec=1800 keeps a large SteamCMD update from being killed partway through.
  • The archive is taken before the update, while nothing is running, and copies older than 14 days are deleted.
  • ExecStop is our own wrapper around the guide's quit command: it pipes quit 10 into telnet on the maintenance port, then waits for the process to exit. The guide itself only shows typing quit by hand in a telnet session, and warns that killing the server outright can roll data back.
  • For an open server, delete -PSW=${SM_PSW} from the line. Use -pvp instead of -pve for a PvP world.

Run systemctl daemon-reload, then systemctl enable --now soulmask. The first start takes a while as the update runs. Stop and restart only through systemctl: a quit typed by hand ends the process cleanly, and Restart=on-failure leaves it down. The unit assumes StartServer.sh stays in the foreground until the server exits, which is how $MAINPID keeps tracking it. If the world dies a few seconds after each start, look at systemctl status soulmask: a start script that passes the game to the background and returns makes systemd treat the service as done and kill every process it launched, the game too, with no clean quit.

The passwords stay out of the unit file and out of shell history, but once the server runs they are part of its command line, which ps shows to any account on the machine. The guide offers no other place for them, so limit shell accounts on this box to those who may hold the admin password anyway.

Settings, admin rights and the invite code

Beyond the command line, the guide documents WS/Saved/Config/LinuxServer/Engine.ini. Its example, with the default ports and save intervals:

[URL]
Port=8777

[OnlineSubsystemSteam]
GameServerQueryPort=27015

[Dedicated.Settings]
SteamServerName=UNNAMED_SERVER
MaxPlayers=20
pvp=False
backup=900
saving=600
  • backup is how often, in seconds, the game database is written to disk; saving is how often game objects are written to that database. Both exist as launch flags too.
  • -initbackup backs up the saves at startup; -backupinterval sets an automatic world backup every so many minutes.
  • -MULTIHOME= sets the listening address: 0.0.0.0, or one of the machine's own addresses.
  • Admin: in the game client, open the console with ~ and type gm key followed by the admin password. The GM panel opens; enter the password there to become admin.
  • Ban with AddServerPermissionList 1 plus the player's SteamID, unban with RemoveServerPermissionList 1; list 4 mutes. gm BaoCun saves the world on demand.
  • The invite code is a 25-character ID the server prints on first run: search WS.log for SERVER UNIQUE ID. Players can find the server with it.

When it does not show up

The guide traces most failed starts to Steam initialisation. In WS/Saved/Logs/WS.log, a good start reports the game server API initialised for app 2646460; a failed one reports app 0 and a warning that Steam could not initialise. Its listed causes are a missing steam_appid.txt (one line: 2646460) and a game or query port that is already in use. A server that starts but is missing from the list usually means 8777 or 27015 is blocked: check ufw status and that no second instance holds the same ports.

Running it on our machines

Our machines for game servers are physical servers leased whole: the world simulation shares no core and no memory with another customer. Each has an unmetered port, 1 Gbps on 10 of the 18 configurable lines and 500 Mbps on the other 8, and one IPv4 address; IPv6 is added at checkout at no charge. Nothing counts the traffic.

  • Rack servers and blades carry an out-of-band controller (HPE iLO, Dell iDRAC or a Supermicro BMC) with a browser console, published in the dashboard once you add a console login. It still reaches the machine after a bad ufw rule locks out SSH.
  • A racked machine is live about 30 minutes after the order is approved; a build to order takes 4-24 hours.
  • Five cities, New York, Miami, San Francisco, Amsterdam and Bucharest, on our own network, AS19624. Pick the one nearest your tribe on the locations page.

The backup folder sits on the same disks as the world. On a schedule, pull those archives to a different host yourself. Windows Server is an option too, with the guide's StartServer.bat and a telnet client; whether a machine offers it depends on its line, it is a paid licence billed monthly, and no ARM line runs it. For another Unreal-based survival world set up from its own documentation, see our Conan Exiles build.

Outside this page: cross-map play, which links a Cloud Mist Forest world with Shifting Sands worlds, has its own private-server setup guide on the official Discord, linked from the developers' pre-launch notes on Steam. Each map is a separate process, so plan memory for every one.

Questions

Does the Soulmask server run on Linux?

Yes. The developer's guide lists Linux and Windows as supported, with a separate SteamCMD app for each: 3017300 for Linux and 3017310 for Windows. On Linux you start StartServer.sh and append your parameters, the same pattern the guide shows for the Windows batch file.

Which ports must be reachable from the internet?

Two UDP ports per game process: the game port, 8777 unless -Port changes it, and the Steam query port, 27015 unless -QueryPort changes it. The maintenance port set by -EchoPort is TCP and, per the guide, does not need to be open; keep it closed, since it accepts commands such as quit.

How much memory does one world need?

The guide states at least 16 GB of memory and 2-4 CPU cores for a single game process. That is for the process, so choose a machine with more than 16 GB to leave room for the operating system. Each extra world, such as a second map, is another process with the same floor.

Where are the saves, and how do I back them up?

Under WS/Saved in the install folder, which also holds Engine.ini and WS.log. The unit on this page archives that folder before every start, while the server is down. Moving those archives off the box is your job; the game's own -initbackup and -backupinterval flags are an extra layer, not an off-site copy.

What gives a player admin rights on the server?

Start the server with -adminpsw set. In the game, press ~, type gm key and the password, and the GM panel opens; enter the password there to take admin rights. From then on GM commands such as bans and manual saves work for you.

Give the world its own machine

Settle on the nearest city to your players and a line with memory to spare above the guide's 16 GB, then work through this page as root.

See the game server machines

Related on Server Room

Other use cases