Skip to content

Instantly share code, notes, and snippets.

@simi
Last active July 17, 2026 11:45
Show Gist options
  • Select an option

  • Save simi/11703283038bb6b3a57a2d0d4c374087 to your computer and use it in GitHub Desktop.

Select an option

Save simi/11703283038bb6b3a57a2d0d4c374087 to your computer and use it in GitHub Desktop.

Using custom mods in CWR

CWR loads classic OFP/CWA addons from mod folders. A downloaded ZIP, 7z, or RAR archive is not itself a mod: extract it and arrange its PBO files below one mod folder.

Read the mod's own documentation before enabling it. Older mods often require other addons or a particular load order.

Contents

Quick start with the MODS screen

Open CWR once, then place the extracted mod in the local Mods directory:

Platform Local Mods directory
Windows Cold War Assault\Mods inside the user's actual Documents folder
Linux ${XDG_DATA_HOME:-$HOME/.local/share}/Cold War Assault/Mods

The folder immediately below Mods must contain the mod's content directories. For a normal addon PBO, the layout is:

Mods/
└── @MyMod/
    ├── AddOns/
    │   └── my_addon.pbo
    └── README.txt

The leading @ is conventional but optional.

Start CWR and select MODS on the main menu. Find the local mod, click the checkbox at the left of its row, then select Apply. Clicking the rest of the row only selects it; it does not tick the checkbox. CWR reloads the game content and returns to the main menu without restarting the process. Reopen MODS to see it in the Active state.

If the MODS screen was already open when files were copied, close and reopen it to scan the directory again. Untick a mod and select Apply to unload it.

The selected set lasts for the current process only. Use a command-line launch or shortcut when the same mods should be enabled every time.

Apply replaces the complete active mod set. A command-line mod outside the local or Workshop scan roots is not shown in the table and will be unloaded if a set from this screen is applied.

Tested example

This procedure was tested on CWR 3.03 with Kegetys' Editor Addon 1.11 from the OFP Is Not Dead file mirror. Its archive contains a PBO and readme rather than a ready-made mod directory, so install it as:

Mods/
└── @KegetysEditorAddon111/
    ├── AddOns/
    │   └── editorupdate102.pbo
    └── kegeditorad_readme.txt

The MODS screen detected and applied this folder. A fresh command-line launch also mounted it, and the addon's real CfgPatches/editorupdate102 configuration was present after loading. This verifies the packaging and loading path; it is not a compatibility guarantee for every old addon.

Mod folder contents

A directory is recognized as a mod when it directly contains at least one of these, matched without regard to case:

  • AddOns/ for addon PBOs;
  • Dta/ for data overrides;
  • Bin/ for configuration or resource overrides;
  • Campaigns/; or
  • mod.json.

Only immediate children of the Mods directory are scanned. These layouts are wrong:

Mods/my_addon.pbo                   # PBO is one level too high
Mods/MyMod.zip                      # archive was not extracted
Mods/MyMod/DownloadedFolder/AddOns # extra wrapper directory

Move the directory that actually contains AddOns, Dta, Bin, or Campaigns directly below Mods. A loose Missions/ or MPMissions/ directory alone is not a mod marker.

An enabled mod may supply multiplayer missions in MPMissions/, but those missions must be packed PBOs. A mission-only mod can add mod.json so the MODS screen recognizes its folder.

Addon configuration

A normal addon keeps config.cpp or config.bin at the root of its PBO in AddOns/. Its CfgPatches classes identify the addons it provides; requiredAddons[] names addon dependencies and requiredVersion sets the minimum game version. CWR checks these after mounting all selected mods and reports missing requirements or conflicting addon definitions.

The top-level Bin/ directory has a different purpose: it overrides or extends the game's global configuration and UI resources. Do not move an addon's PBO-internal configuration there.

Starting a mod from the command line

The following examples use a mods directory inside the game installation. The Linux game directory is /opt/cwr; the Windows example uses C:\CWR.

On Linux:

cd /opt/cwr
./PoseidonGame --mods-dir mods --mod '@MyMod'

In PowerShell on Windows:

cd C:\CWR
.\PoseidonGame.exe --mods-dir mods --mod '@MyMod'

--mods-dir names the parent directory. --mod names the folder below it and actually enables the mod. The relative --mods-dir itself is resolved from the directory where the process starts; the examples start in the game directory, so mods means <game directory>/mods. It may instead be an absolute path.

Use one quoted, semicolon-separated list for multiple mods:

./PoseidonGame --mods-dir mods --mod '@Foundation;@Units;@Gameplay'

The order is preserved and matters. Follow the order required by the mod authors; dependencies normally precede the content that extends them. Do not repeat --mod for each folder.

The MODS screen uses the table's current sort order, so sorting its columns can change override priority. Use an explicit --mod list for an order-sensitive combination.

Absolute mod paths can mix different storage locations without --mods-dir:

./PoseidonGame --mod '/mnt/cwr-mods/@Foundation;/srv/shared-mods/@Units'

The legacy -mod and -mod= forms remain accepted, but new shortcuts and scripts should use --mod.

How relative names are found

With --mods-dir, every relative name is resolved only below that directory. Without it, CWR tries the startup directory, the game directory, and then the managed local Mods directory. Folder and mod identifiers are matched without regard to case.

--workshop-dir is separate: it selects the downloaded-mod directory shown in the MODS screen, but it is not searched when resolving relative --mod names. Use an absolute path to start a downloaded mod directly when it is outside --mods-dir.

Optional mod.json

An unmanaged mod does not need a manifest. If present, a top-level mod.json can give it a stable identity and clearer text in the MODS screen:

{
  "modId": "my-mod",
  "name": "My Mod",
  "version": "1.0"
}

CWR reads these three fields for local mod identity and display. modId is also the identifier advertised in multiplayer and can be used in --mod instead of the physical folder name. Without it, CWR falls back to the folder name.

mod.json does not declare or enable dependencies. Addon dependencies remain in each PBO's CfgPatches.requiredAddons[]; every mod containing those addons must still be installed and enabled.

Other mod locations

These options and environment variables change the managed directories:

Setting Effect
--mods-dir DIR Local MODS-screen root and base for relative --mod names.
--workshop-dir DIR Downloaded/Workshop MODS-screen root.
POSEIDON_MODS_DIR Local root when --mods-dir is absent.
POSEIDON_WORKSHOP_DIR Downloaded root when --workshop-dir is absent.
POSEIDON_USER_CONTENT_DIR Parent whose Mods/ and Workshop/ children become the defaults.
--oldpaths Use Mods/ in the game directory for the legacy folder layout.

The downloaded Mods catalog appears alongside local mods in the same screen. An Available catalog entry can be ticked and applied; CWR downloads it to the Workshop directory before loading it.

Multiplayer and dedicated servers

Enable every addon the server or its missions use. Start a dedicated server with its required mod options:

./PoseidonServer --config server.cfg --public \
  --mods-dir mods --mod '@Foundation;@Units;@Gameplay'

Clients need the same referenced addon content. The mission PBO itself is transferred when they join and does not need to be installed as a client mod.

When equalModRequired = 1; is set in server.cfg, the server compares each client's complete ordered list of advertised mod identifiers. The client and server must then launch the same complete mod list in the same order, including any mission-only mod. A stable modId permits different physical folder names or absolute locations while keeping the advertised identity equal.

With equalModRequired = 0;, clients are not rejected solely for a different list, but they still need addons referenced by the current mission. See the dedicated-server guide for mission installation and server configuration.

Checking a launch

From the game directory, print the resolved multiplayer identity without starting the game normally:

./PoseidonGame --mods-dir mods --mod '@MyMod' --mp-version

The output includes mod_names and absolute mod_paths. A normal startup also prints Mod path set and one Loaded mod line per folder to the terminal. These messages occur very early and may not appear in a file selected with --log-file.

An invalid --mod name stops startup and reports every path that was checked.

Troubleshooting

  • The mod is absent from the MODS screen: extract the archive, remove any extra wrapper directory, and confirm the immediate child of the Mods root has AddOns, Dta, Bin, Campaigns, or mod.json. Reopen the screen after changing files.
  • The row is selected but the mod is not active: tick the checkbox at the left, then select Apply.
  • Apply reverts to the previous set: inspect the terminal log for an invalid addon configuration, missing dependency, or incompatible requirement. CWR keeps the previously working set when a remount fails.
  • The mod disappears after restarting CWR: MODS-screen selections are session-only. Put --mods-dir and --mod in the launch shortcut or script.
  • An addon reports a missing requirement: install its dependency and include that mod in the same ordered --mod list. The manager does not enable another local mod automatically.
  • Two mods replace the same content: use the load order documented by their authors, or disable one. Later paths have higher priority for ordinary file lookup, while addon and top-level configuration merging has additional rules.
  • Multiplayer rejects the mod list: compare mod_names from --mp-version on the client and server, including order. Prefer stable modId values over relying on local folder names.

Path reference

Path or source Value and precedence Purpose
Platform user-content directory Windows: the actual Documents folder's Cold War Assault directory. Linux: ${XDG_DATA_HOME:-$HOME/.local/share}/Cold War Assault. Default parent for local mods, Workshop downloads, and user missions.
POSEIDON_USER_CONTENT_DIR Replaces the platform user-content directory. Its Mods/ and Workshop/ children become the managed roots.
POSEIDON_USER_DIR fallback When POSEIDON_USER_CONTENT_DIR is unset but POSEIDON_USER_DIR is set, content defaults below <POSEIDON_USER_DIR>/content/. Keeps isolated installations and tests out of the real Documents/XDG directory.
Game-data root The process startup directory, or the directory selected with -C. Supplies the base DTA/, AddOns/, Worlds/, and other installed game data.
Implicit Resistance mod <game-data root>/res when that directory exists. Mounted automatically before explicit --mod entries; explicit mods have higher ordinary-file priority.
Local Mods root --mods-dir, then POSEIDON_MODS_DIR, then <user content>/Mods. Scanned for Local rows and used as the base for relative --mod names when explicitly selected.
Workshop root --workshop-dir, then POSEIDON_WORKSHOP_DIR, then <user content>/Workshop. Scanned for Workshop rows and used for catalog downloads. It is not an implicit relative --mod search root.
Legacy roots --oldpaths uses <game directory>/Mods and <game directory>/Workshop. Restores the original game-local managed-content layout.
Relative --mods-dir or --workshop-dir Resolved from the process startup directory before any -C directory change. Allows simple paths such as mods when launching from the game directory.
Relative --mod with --mods-dir Resolved only below the selected Mods root, by folder name or modId, without regard to case. Deterministic named-mod loading.
Relative --mod without --mods-dir Searched in order: process startup directory, -C game directory, managed local Mods root. Compatibility with game-local, explicit game-data, and managed-user layouts.
Absolute --mod entry Used directly. Multiple absolute and relative entries can share one semicolon list. Loads mods from unrelated disks or directories.
Recognized mod contents <mod>/AddOns/, Dta/, Bin/, Campaigns/, or a top-level <mod>/mod.json. Makes an immediate child directory recognizable as a mod.
Mod multiplayer missions <enabled mod>/MPMissions/*.pbo. Adds packed multiplayer missions from an enabled mod.

CLI reference

Switch Scope Effect
--mod LIST Client and server Mounts one quoted, semicolon-separated ordered mod list. Do not repeat the option.
-mod LIST, -mod=LIST Legacy alias Same as --mod.
--mods-dir DIR Client and server Selects the local Mods root and base for relative --mod names; does not mount anything by itself.
--workshop-dir DIR Primarily the client Selects the Workshop scan and download root; does not resolve relative --mod names or mount anything by itself.
--oldpaths, -oldpaths Client and server Uses game-local profiles, configuration, Mods, Missions, and MPMissions paths.
-C DIR, --work-dir DIR Client and server Selects the game-data directory containing DTA/, Worlds/, and other base data. It is also a fallback search root when --mods-dir is absent.
--mp-version Client and server Resolves the intended mod set, prints mod_names and mod_paths with the multiplayer compatibility tuple, then exits.
--master-server HOST Client and server Overrides the service used for the server directory and the client's Workshop catalog.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment