Hosting a Sauerbraten Server
Intro
Cube 2: Sauerbraten is an old-school first-person shooter game that feels very similar to Quake and Unreal Tournament. While it’s easy to get the game up and running as a client/player, running a game server is non-trivial, thanks to the awful documentation. Truely, it is one of the worst documented systems I’ve had to work with, ever.
This blog post serves as my way of documenting for myself how I got this running, and hopefully will be helpful to the 13 other people in the world that still play this game. As I learn more about hosting Sauerbraten servers (and explore different modded server setups), I’ll update this blog post (and maybe tweet if I do, who knows. No promises).
System Requirements
Runing a Sauerbraten server takes minimal compute, which is fun. I did my testing in a Docker container on a Digital Ocean droplet that had 1 CPU and 1 GB of RAM, so just about any average potato can host a Sauerbraten server. In terms of network requirements, you’ll need to expose a pair of TCP and UDP ports (via firewall/port forwarding/etc.) if you want other people not on your network to play on the server, and/or if you want it in the master server list.
Downloading the Server Binaries
The server binaries are distributed as apart of the tarball that contains the client binaries/assets/etc. Unfortunately, the license for Sauerbraten does not allow redistributing partial archives, only the full archive or the source code, so you have to download the full ~1 GB archive to get the server binaries. Download the latest version from their official SourceForge project for your platform.
(you can also use a pre-made Docker environment, click here for details)
Configuring the Server
The server settings are stored in a file called server-init.cfg
, which is located at the root of the Sauerbraten directory (from the tarball downloaded above).
root@7c93bc65eca8:/srv/sauerbraten# tree -L 1
.
|-- README.html
|-- bin_unix
|-- data
|-- docs
|-- packages
|-- sauerbraten_unix
|-- server-init.cfg
`-- src
You can view a reference copy of the config here.
To the Sauerbraten developers' credit, the config options in server-init.cfg
have (fairly) good comments. Sometimes it’s not super obvious the impact that specific values will have, but the comments provide a good starting point to experiment from.
There are a few options you’ll probably need to set:
serverip
andserverport
to make sure the network settings are correct and it can be accessible. I have theserverip
set to0.0.0.0
so it binds to all interfaces (makes things easier in Docker), and the default28785
forserverport
.publicserver
controls how the server can be accessed and managed in-game.- A value of
0
allows for anyone to claim master on the server, and it shows as “open” in the server browser. - A value of
1
requires players to auth to claim master, and it shows as “auth” in the server browser - A value of
2
is the same as0
, but disables a master from setting the server as “Private” (details below). - You probably want
0
or1
, most likely1
.
- A value of
serverdesc
controls the description for the server, which is shown in the server browser. This is objectively the most important configuration option, make sure you pick a good one.servermotd
allows you to set a message that is shown to players when they connect to your server. This is probably the second most important option, have fun with it.
Server Authentication
There are different types of mastermode on a server:
- Open: Any player can claim master on the server
- Veto: Not sure what this does, I’ve never seen it on a server. Probably affects map voting or something.
- Locked: Only players with the proper authentication can claim master, and people joining the server are put into spectate mode until a master puts them on a team
- Private: Only players with the proper authentication can connect to the server.
When a server’s publicserver
setting is 1
, you have to authenticate to the server in order to claim master. Similarily, if the server is private, you have to authenticate in order to connect. Historically, this could be done using a pre-shared key/password, but that functionality appears to be broken in the current version (at least, I couldn’t figure out how to make it work).
The preferred mode of authentication is to use a challenge-response scheme that relies on public/private keypairs generated by the user. The only documentation I found for this was in the docs for Remod, a Sauerbraten server mod, so here is my documentation of how to do this in a bit more detail than Remod has it.
Client Setup
First, you have to generate a keypair. Open Sauerbraten, and press T
to bring up the chat input. Type /genauthkey [password]
(e.g., /genauthkey goodpass123
) and press Enter, which will show a keypair in the log. Luckily, this gets logged on disk so you don’t need to manually transcribe those numbers.
Exit the game, and go to the $SB_DATA
directory. This is a variable I have invented (you’re welcome), and this is it’s corresponding value on the different operating systems:
- Windows:
C:\Users\yourusernamehere\Documents\My Games\Sauerbraten
- macOS:
~/Library/Application Support/Sauerbraten
- Linux:
~/.sauerbraten
(this may vary, I tested on Ubuntu 18.04)
In the $SB_DATA
directory, there will be a log.txt
file that has the game console output for the most recent execution. This file gets overwritten everytime you run the game, so be aware of that. Save the public and private keys that it shows for future use.
Next, create a file in the $SB_DATA
directory called autoexec.cfg
. Here, you will add your private key, along with a couple other pieces of information:
authkey "ingameusername" "123privatekey123" "authdomain.lan"
- The
ingameusername
should match the username you set for yourself in Sauerbraten - The
123privatekey123
should be the long private key number fromlog.txt
- The
authdomain.lan
should be a domain that you share with the server owner (probably yourself) that needs to be set in the server config. It doesn’t have to actually be a valid DNS record, but a username + domain combination needs to be unique (I think…)
This autoexec.cfg
can also be edited in-game, if you click on “options..” in the main menu, and go to “cfg” on the far right.
Server Setup
There are a couple things that have to be set in the server’s server-init.cfg
. First, set the serverauth
variable to the same domain that is used on the client (e.g., “authdomain.lan”). Second, add a new line to the end of the file that looks like this:
adduser ingameusername authdomain.lan 123publickey123 3
- The
ingameusername
should be your/the player’s username that they set in the client menu - The
authdomain.lan
should be the same value that the client has in theirautoexec.cfg
and the server has in theserverauth
field - The
123publickey123
should be replaced with the long public key number from the client’slog.txt
output - The
3
denotes the permissions associated with that user.2
is for master (shown in green on the scoreboard),3
is for admin (shown in purple).
Note that it may not be required for the adduser
/authkey
domain to be the same as the serverauth
domain, but it is the easiest way to make sure there aren’t any issues.
Authenticating to the Server
When you connect to the server, you can do /auth authdomain.lan
(replacing authdomain.lan
with the proper domain), which should respond with a message about you successfully authenticating to the server, and your name should be in green or purple on the scoreboard now (depending on the permissions set for your user above)
Starting the Server
Manually
Go into the root Sauerbraten directory (it should have the server-init.cfg
file), and run ./bin_unix/linux_64_server
(or the corresponding path for other operating systems) to start the server.
Docker
To simplify things, I put together a Dockerfile and accompanying docker-compose.yml
that makes it a bit easier to run the server. You can view it on Docker Hub and GitHub.
Create this docker-compose.yml
and do docker-compose up
to start the server (assuming you have your finished server-init.cfg
in the current directory):
version: '3'
services:
srv:
image: captaingeech/cube2srv:latest
ports:
- "28785:28785/tcp"
- "28785:28785/udp"
- "28786:28786/tcp"
- "28786:28786/udp"
volumes:
- ${PWD}/server-init.cfg:/srv/sauerbraten/server-init.cfg
Closing Thoughts
Overall, it’s pretty easy to run a Sauerbraten server once you figure out how, but my goodness the documentation is awful. Hopefully this helps, if I got anything wrong, get in touch with me and I will update this.