Call of Duty 1 shipped in 2003 and its Linux dedicated server, cod_lnxded, is a 32-bit
binary from November 2004. It still runs fine on a current distribution, but only once you
have solved two problems the original readme never mentions: 32-bit runtime libraries, and
the fact that the community is split between patch 1.1 and patch 1.5, which are not
wire-compatible with each other.
This guide covers both.
What you need
| Item | Notes |
|---|---|
| Game paks | pak0.pk3 … pakb.pk3 plus localized_english_pak*.pk3 from a legitimate install |
| Dedicated binary | cod_lnxded (Linux) or CoDMP.exe -dedicated (Windows) |
| Patch | 1.5 patch is the community standard for the plain game |
| Ports | UDP 28960 inbound (configurable via net_port) |
| RAM | ~64 MB per server instance. This is a 2003 engine. |
The full 1.5 patch is on the war24.net download page, together with the CoD RCON tool.
1.1 or 1.5?
Pick before you build anything, because clients cannot cross-connect.
| 1.1 | 1.5 | |
|---|---|---|
| Network protocol | 1 |
6 |
| Community convention | sv_pure 0 (~99% of servers) |
sv_pure 1 |
| Client autodownload | needs CodExtended, see below | works out of the box |
| GSC builtins | no getGuid(), no setBackgroundColor() |
full 1.5 set |
Mismatched clients are rejected with EXE_SERVER_IS_DIFFERENT_VER1.X. Most public servers
today run 1.5; the 1.1 scene survives mainly around the AWE mod and CodExtended.
Directory layout
/opt/cod1/
├── cod_lnxded
└── main/
├── pak0.pk3 … pakb.pk3
├── localized_english_pak0.pk3 …
├── server.cfg
└── zz_yourmod.pk3 # optional
Note the localized paks run localized_english_pak0, 1, 2, 3, 5 — there is no
localized_english_pak4. That gap is normal, not a missing file.
32-bit libraries on a modern distro
cod_lnxded is i386. On a 64-bit Debian or Ubuntu:
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y libc6:i386 libgcc-s1:i386 lib32stdc++6 libstdc++5:i386
libstdc++5 is the one people miss. Without it the binary dies immediately with
error while loading shared libraries: libstdc++.so.5.
server.cfg
Put this in main/server.cfg:
seta sv_hostname "^3My ^7CoD1 Server"
set g_gametype "dm"
set sv_maxclients 20
set rconpassword "change-me"
set sv_pure 1 // set to 0 if you run a mod pk3
set sv_allowDownload 1 // let clients pull missing paks
set sv_maxRate 25000
set sv_fps 20
set sv_timeout 60
set g_allowVote 1
set g_antilag 1
set scr_friendlyfire "0"
set scr_killcam "1"
set g_deadChat "1"
set logfile 0
set g_log "games_mp.log"
set g_logsync 0
set scr_dm_timelimit "10" // MINUTES, not seconds
set scr_dm_scorelimit "150"
set sv_mapRotation "gametype dm map mp_harbor map mp_chateau map mp_depot"
map_rotate
Two traps in that file:
rconpasswordis one word on CoD1 and CoD:UO. CoD2 and later renamed it torcon_password. Using the wrong one silently leaves rcon disabled.scr_dm_timelimitis in minutes, and any non-zero value is clamped to 1440.0means unlimited and is not clamped. Setting it to1while you are testing will restart the map underneath connecting clients mid-download.
The full list is on the CoD server cvar reference, and you can build a config without typing it by hand with the server.cfg generator.
Starting the server
cd /opt/cod1
./cod_lnxded \
+set fs_basepath /opt/cod1 \
+set fs_homepath /opt/cod1 \
+set dedicated 2 \
+set net_port 28960 \
+set sv_maxclients 20 \
+set rconpassword "change-me" \
+exec server.cfg \
+map mp_harbor
dedicated 2 means "internet server, send heartbeats to the master". dedicated 1 is
LAN only and will never appear in the public browser.
On a 64-bit kernel wrap the call in setarch i386 -R to disable address-space
randomisation. The 2004 binary predates ASLR and occasionally faults without it:
setarch i386 -R ./cod_lnxded +set dedicated 2 ...
Healthy startup log
Sys_LoadDll(/opt/cod1/main/game.mp.i386.so)... ok
Sys_LoadDll(game) succeeded!
------- Game Initialization -------
gamename: Call of Duty
gamedate: Nov 15 2004
COD MP 1.5 build linux-i386 Nov 15 2004
30172 files in pk3 files is the normal handle count for stock paks plus one mod pak.
systemd unit
[Unit]
Description=Call of Duty 1 dedicated server
After=network-online.target
[Service]
Type=simple
User=cod
WorkingDirectory=/opt/cod1
ExecStart=/usr/bin/setarch i386 -R /opt/cod1/cod_lnxded \
+set fs_basepath /opt/cod1 +set fs_homepath /opt/cod1 \
+set dedicated 2 +set net_port 28960 \
+exec server.cfg +map mp_harbor
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
If you would rather not install 32-bit libraries on the host at all, see running Call of Duty servers in Docker.
Getting listed in the server browser
CoD1's Activision master, codmaster.activision.com:20510, is still answering in 2026 and
is what the in-game and Steam browsers query. Leave sv_master1 alone and it is used
automatically. The heartbeat's source IP becomes the advertised address, which means the
listing works through port-preserving NAT but not through a proxy that rewrites the source.
cod.pm runs a community master and a web server list, useful as a cross-check when you are not sure whether your heartbeat is landing.
To suppress master registration entirely (private or LAN server):
set sv_master1 ""
set sv_master2 ""
set sv_master3 ""
set sv_master4 ""
set sv_master5 ""
Map rotation
sv_mapRotation is a flat token list, not a JSON array:
set sv_mapRotation "gametype dm map mp_harbor map mp_chateau gametype tdm map mp_carentan"
Valid tokens are gametype, map, exec, allow_jeeps, allow_tanks. The engine
consumes sv_mapRotationCurrent from the front as it advances. Details and the
force-next-map trick are in the map rotation guide.
The 16 stock map codes are listed on the Call of Duty map list.
Installing a mod
CoD1 mods are .pk3 archives (plain zip files) dropped into main/.
- The extension must be
.pk3. The 1.5 engine only scans*.pk3in the gamedir..iwdis CoD2 and later; a correctly built.iwdwill sit there being ignored. - Paks load alphabetically and the last one wins for duplicate paths. Prefix your mod
zz_so it overridespak0…pakb. - On 1.1, use
zzz_orzzzz_instead. The 1.1 server does not load azz_-prefixed pak. Identical bytes namedzzzz_load fine. This one costs people hours. - Set
sv_pure 0whenever you ship a mod pak, unless you have specifically tested the pure-checksum path.
Full details in installing Call of Duty mods, and the download-to-client side in fast download.
Client autodownload on 1.1
1.5 clients download missing paks over UDP as soon as sv_allowDownload 1 is set. 1.1
clients default to cl_allowDownload "0", so an out-of-the-box client refuses.
CodExtended works around this by registering cl_allowDownload with the
CVAR_SYSTEMINFO flag, so the server's value propagates into the client's systeminfo and
its local copy flips to 1. With CEx loaded:
set sv_pure 0
set sv_allowDownload 1
set sv_fastDownload 1 // CEx only: 2 KB -> 8 KB UDP blocks, ~4x faster
set cl_allowDownload 1 // CEx flags this CVAR_SYSTEMINFO so it reaches clients
Load CEx by preloading the shared object:
LD_PRELOAD=/opt/cod1/codextended.so ./cod_lnxded +set dedicated 2 ...
A stock 1.1 server cannot do this. Without CEx your only options are asking players to set
cl_allowDownload 1 themselves, distributing the pak out of band, or writing the mod so
it needs no client-side files at all.
Remote administration
rcon <password> status
rcon <password> map mp_carentan
rcon <password> kick <playername>
CoD's rcon runs behind flood protection: two commands inside roughly 500 ms collapse, and
the second comes back as Bad rconpassword. or an empty reply, which is indistinguishable
from a wrong password. Space commands 600 ms apart and read cvars back after setting them.
The rcon guide has the wire format and a working Python snippet.
