CPMA Dedicated Server Guide with CNQ3 on Linux

First, we will assume you have a working x64 Linux system and the credentials needed.

Optionally, having libunwind8 installed will help CNQ3 generate better crash reports.

Terminal multiplexers

If you already know what a terminal multiplexer is and are familiar with one (e.g. Screen or tmux), you can safely skip this section and the following one.

When you SSH into your server, you only have the one terminal instance. If you start the Quake 3 server without a terminal multiplexer from it, you can either:

  1. Run it in the current terminal instance (./cnq3-server-x64), meaning you can now interact with the Quake 3 server but not with the terminal itself to type new commands until you kill or shut down the server.
  2. Run it detached (./cnq3-server-x64 &), meaning you can continue to interact with the terminal instance but can't interact with the Quake 3 server.

As you can see, this is not ideal.

Terminal multiplexers allow you to create virtual terminal instances that you can attach to and detach from at will.

In this guide, I will use Screen to achieve this.

Quick tour of Screen

First, you'll want to install it on your system. If you have APT (Debian, Ubuntu), you can run apt-get install screen with root privileges to install it.

Action Command
Start detached session screen -A -m -d -S sessionnamehere command [arguments]
Attach to a session screen -r sessionnamehere
Detach from a session ctrl+a d
Kill a session screen -S sessionnamehere -X quit
Check if a session is running screen -S sessionnamehere -X select
Returns 0 when it exists and 1 otherwise.
Option Meaning
-A Adapt window sizes to size of display.
-m Always create a new screen session.
-d Create detached.
-S Name session.
-r Attach to session.
-X Send the specified command to a running screen session.

CPMA server directory structure

This assumes you already have the following directories:

Directory Files
baseq3 id's pak0-8.pk3 and CPMA's map_cpm*.pk3 (CPMA maps only)
cpma z-cpma-pak1XX.pk3 (CPMA without the maps)

Download the following .zip files and extract them at the root of your Quake 3 directory:

Download the following .cfg file and put it in the cpma directory:

At the root of your Quake server directory, you should now see the following:

Entry Type Purpose
baseq3 Directory Contains pak0-8.pk3, map_cpm*.pk3 and maybe other map paks.
cpma Directory The CPMA directory. Contains server.cfg.
cnq3-server-x64 Executable The CNQ3 dedicated server. Shell script Lists all running instances of CNQ3, their process ID, uptime and CPU/memory usage. Shell script Starts server #1 if not already running. Shell script Starts server #2 if not already running. Shell script Stop server #1 if running. Shell script Stop server #2 if running.

Interacting with the servers

Now that everything is in place, we can use the scripts to start/stop servers and check their statuses.

To interact with a server directly, we want to attach to its virtual terminal first.

  • To attach to server #1: screen -r q1
  • To attach to server #2: screen -r q2
  • To detach: ctrl+a d

The parent/child process system

When you run ./cnq3-server-x64, the executable will create a new instance of itself (i.e. a fork), meaning there will be 2 processes per server instance. The parent process checks to see how the child ends (crash, timed reboot, etc) to decide if it needs to start another child process or just quit.

When you see 1 CNQ3 instance with super low CPU/memory usage and 1 with higher CPU/memory usage, you'll know it's normal.

The scripts and configs

These may not be as up-to-date as the files linked above but are here for convenience/reference.

screen -S q1 -X select . > /dev/null 2>&1
if [ $? -eq 1 ]; then
    screen -A -m -d -S q1 \
        ./cnq3-server-x64 \
        +set dedicated 2 \
        +set sv_master1 \
        +set sv_master2 \
        +set sv_master3 \
        +set sv_master4 \
        +set sv_master5 \
        +set fs_game cpma \
        +set net_port 27960 \
        +set ttycon 1 \
        +set developer 0 \
        +exec server.cfg \
        +map cpm3a

screen -S q1 -X quit

echo "PID   COMMAND                      UPTIME      CPU"
ps -eo pid,command,etime,pcpu | grep cnq3-server
smem -k -P cnq3-server


// make sure to update these!
sets .admin.        "yournickname"      // server browser info
sets .location      "serverlocation"    // server browser info
set sv_hostname     "yourservername"    // server browser info
set ref_password    "none"              // "none" means referee/admin access is disabled
set rconPassword    ""                  // "" means rcon access is disabled

// more useful settings:
set sv_pure                 "1"         // *always* set to 1 for online servers
set snaps                   "30"        // leave at 30
set sv_strictAuth           "0"         // enables CD-key checks
set server_record           "0"         // bitmask - forces players to record demos, take screenshots, etc
set server_chatfloodprotect "0"         // max. chat messages per second, 0 means no limit
set sv_maxrate              "30000"     // good range for players is 25k to 30k
set sv_allowDownload        "0"         // enables id's super slow download system
set server_gameplay         "CPM"       // only change if you want your server to be lame
set server_maxpacketsmin    "100"       // ideally cl_maxPackets 125, but allow a bit lower
set server_maxpacketsmax    "125"       // ideally cl_maxPackets 125
set server_ratemin          "25000"     // good range for players is 25k to 30k
set server_optimisebw       "1"         // reduces bandwidth a lot but can't see players through portals
set log_pergame             "0"         // opens a new timestamped log file for each game
set match_readypercent      "100"       // min. % of players that must be ready for a match to start
set g_gametype              "1"         // 1 is duel
set sv_maxclients           "24"        // max. player count
set mode_start              "1v1"       // game mode to start with
set sv_privateClients       "0"         // number of private slots reserved
set sv_privatePassword      ""          // password for the private slots
set sv_restartDelay         "2"         // number of hours before reboot - won't reboot as long as humans are still connected!