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:
serveripandserverportto make sure the network settings are correct and it can be accessible. I have theserveripset to0.0.0.0so it binds to all interfaces (makes things easier in Docker), and the default28785forserverport.publicservercontrols how the server can be accessed and managed in-game.- A value of
0allows for anyone to claim master on the server, and it shows as “open” in the server browser. - A value of
1requires players to auth to claim master, and it shows as “auth” in the server browser - A value of
2is the same as0, but disables a master from setting the server as “Private” (details below). - You probably want
0or1, most likely1.
- A value of
serverdesccontrols 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.servermotdallows 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
ingameusernameshould match the username you set for yourself in Sauerbraten - The
123privatekey123should be the long private key number fromlog.txt - The
authdomain.lanshould 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
ingameusernameshould be your/the player’s username that they set in the client menu - The
authdomain.lanshould be the same value that the client has in theirautoexec.cfgand the server has in theserverauthfield - The
123publickey123should be replaced with the long public key number from the client’slog.txtoutput - The
3denotes the permissions associated with that user.2is for master (shown in green on the scoreboard),3is 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.