Installing Call of Duty server mods: pk3, iwd and fs_game

Updated 2026-07-25

Call of Duty mods are zip archives that overlay the stock game files. There is no installer and no manifest — the rules are entirely about filename and load order, which is why a mod that is "installed" can sit there doing nothing with no error message anywhere.

Archive extension per game

Game Extension
Call of Duty 1 .pk3
Call of Duty: United Offensive .pk3
Call of Duty 2 .iwd
Call of Duty 4 .iwd
World at War .iwd

Both are plain zip files. unzip -l mymod.pk3 works on either. But the engine only scans its own extension: a correctly built .iwd in a CoD1 gamedir is ignored completely, and so is a .pk3 in a CoD2 gamedir. No warning is printed.

This is the first thing to check when a mod does nothing.

Load order: alphabetical, last wins

The engine scans the gamedir, sorts the archives by filename, and loads them in order. For any file path present in more than one archive, the archive that sorts last wins.

Stock paks are named pak0pakb on CoD1 and iw_00 upwards on CoD2+. So a mod named mymod.pk3 sorts before pak0.pk3 and loses every conflict.

The convention is to prefix mods so they sort last:

zz_mymod.pk3

Call of Duty 1 patch 1.1 exception: the 1.1 server does not load a zz_-prefixed pak at all. The identical bytes named zzz_ or zzzz_ load fine. This is verified behaviour, not folklore, and it costs people entire evenings. On 1.1, use zzz_ or zzzz_.

Two ways to install

1. Drop into the gamedir

/opt/cod2/main/zz_mymod.iwd

Simple, and the mod applies to every gametype. It also means every connecting client is offered the pak for download, and unloading the mod means moving the file and restarting.

2. A mod directory via fs_game

/opt/cod2/mods/zpam336/z_svr_zpam336.iwd
set fs_game "mods/zpam336"

With fs_game set, the engine mounts that directory on top of main/. This is how the serious mods ship, because it keeps main/ clean and lets you switch mods by changing one cvar.

fs_game must be set before the config is executed, so put it on the command line:

./cod2_lnxded +set fs_game mods/zpam336 +set dedicated 2 +exec server.cfg +map mp_toujane

Setting fs_game inside server.cfg is too late for some engine generations and produces a server that half-loads the mod.

sv_pure

Set sv_pure 0 when you load a mod pak, unless you have specifically tested the pure checksum path with real clients. sv_pure 1 makes the server audit the checksums of what each client has loaded and kick on mismatch, which is easy to get wrong in ways that only show up as clients being unable to join.

On Call of Duty 1 patch 1.1, sv_pure 1 is effectively unusable with any modded client because of a client-side checksum bug. The full explanation is in the fast download guide.

Getting the mod to clients

A mod that only changes server-side script needs nothing on the client. A mod that adds maps, models, sounds or menus does.

set sv_allowDownload 1
set sv_wwwDownload 1                                // CoD2 and later
set sv_wwwBaseURL "http://files.example.com/cod2"

Without HTTP, the engine's UDP download path runs at roughly 5–10 KB/s and a 20 MB mod is not a realistic join. See fast download.

Files you should not ship to clients

Vanilla Call of Duty has no way to mark a pak server-only — any referenced pak is offered for download. CodExtended adds one on CoD1: a pak whose basename contains srv, svr or server is excluded from the download list.

The file this matters most for is playeranim.script. It parses into a parse-order-indexed animation table and the server networks indices into it. A client that downloads a re-ordered or trimmed table from your server will then crash with an "animation error" when it joins a stock server. Never put a non-stock playeranim.script in a downloadable pak.

Inspecting a mod before you trust it

A pak is a zip, so you can read it:

unzip -l zz_mymod.pk3                          # what is inside
unzip -p zz_mymod.pk3 maps/mp/gametypes/dm.gsc # read a script
unzip -l zz_mymod.pk3 | grep playeranim        # check for the dangerous file

Worth doing for anything you downloaded from a forum in 2009.

Verifying the mod actually loaded

Start the server and read the console. It prints every archive it loads, and a total file count:

30172 files in pk3 files

If your pak is not in that list, the extension or the filename sort order is wrong. If it is in the list but the mod does nothing, the mod's scripts are not being reached — usually a fs_game or gametype problem rather than a packaging one.

Mod directory

Common server mods for the classic titles:

Game Mod Purpose
CoD1 AWE Gamemode pack: mapvote, gungame, jump, anticamp
CoD1 PAM / rPAM Match mod
CoD1 1.1 CodExtended Engine extension: anticheat, extra GSC builtins, faster downloads
CoD:UO PAM Match mod
CoD2 zPAM 3.36 Current standard match mod
CoD2 ePAM / PAMD Older match mods, still on public servers
CoD2 CoDJumper Jump gametype and maps
CoD4 Promod LIVE / PML Competitive standard
CoD4 CoD4X Replacement server binary with its own master

Frequently asked

Why is my Call of Duty mod being ignored with no error?

Almost always the extension or the sort order. CoD1 and UO only scan .pk3, CoD2 and later only scan .iwd. Paks load alphabetically and the last one wins, so a mod must sort after the stock paks, which is what the zz_ prefix is for.

What is fs_game and where do I set it?

fs_game names a directory mounted on top of main/, which is how mods like zPAM and Promod ship. Set it on the command line before the config is executed, not inside server.cfg.

Do CoD1 mods use zz_ or zzz_ prefixes?

zz_ on patch 1.5. On patch 1.1 the server will not load a zz_-prefixed pak at all, so use zzz_ or zzzz_ there.