Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Witcher 3: Wild Hunt

The Witcher 3: Wild Hunt is the second REDengine title modde supports (alongside Cyberpunk 2077). It ships as a built-in plugin under the witcher3 game id.

Engine & overall status

PropertyValue
Engine familyREDengine (EngineFamily::Witcher)
game idwitcher3
Display nameThe Witcher 3: Wild Hunt
Overall statusPartial
ScannerYes
Conflict detectionYes
Save trackingDone

The status is Partial, matching the supported games table. Deployment, the filesystem scanner, .ws script-conflict classification, save tracking, and Wine/Proton DLL-override detection are wired up and reachable, but The Witcher 3 does not yet have the deeper engine integrations some Bethesda titles enjoy (there is no LOOT-style load-order sorter and no plugin validation — REDengine has no .esp/.esm plugin model). Treat it as solid for loose-folder mods and script mods, with the usual REDengine caveat that heavily-scripted modlists still benefit from manual review.

Install detection

modde locates the game through its launcher registration:

FieldValue
Steam App ID292030
Steam install dirThe Witcher 3
Heroic (GOG)not wired
Heroic (Epic)not wired
Nexus domainwitcher3

On a typical Linux Steam install the game directory resolves to something like ~/.local/share/Steam/steamapps/common/The Witcher 3. Run modde detect to see what modde found, and confirm the resolved path before deploying:

modde detect

Because no Heroic GOG/Epic app ids are registered for this title yet, GOG and Epic copies are not auto-detected. You can still point a profile at any install directory manually (see the worked example below) — detection only affects auto-discovery, not the ability to deploy into a known path.

Proton prefix

The Witcher 3 runs through Proton on Linux. modde does not install Proton or the game; the proton tool stores per-game launch settings (runner version, prefix path override, extra environment, DLL-override mode). The DLL proxies modde detects for script-extender-style mods (below) are surfaced as Wine DLL overrides so they take effect inside the Proton prefix. See Tools & Overlays for the proton tool options.

Mod directory & deploy strategy

The mod directory is mods/ directly under the game install:

<install>/mods/

REDengine loads mods from a small set of well-known top-level roots. modde recognises the multi-root REDkit/REDmod-style layout — mods/, dlc/, bin/, and content/ — and chooses its deploy path accordingly:

  • Multi-root overlay — If the staged content already contains any of mods/, dlc/, bin/, or content/ at its top level, modde symlinks those roots straight into the install (a symlink farm, leaving the original game files untouched). This is what most archive mods that bundle their own mods/modFoo/ directory will hit.
  • Single mod-root deploy — Otherwise modde treats the staged tree as the contents of one mod and deploys it into the resolved mod root under mods/.

Either way deployment is non-destructive and reversible — see Deployment & VFS for the build → materialize → deploy pipeline and modde rollback.

Archive analysis

When modde unpacks a downloaded archive it picks an install method:

  • If the extracted tree contains any of mods, dlc, bin, or content, it is installed as a multi-root overlay preserving those roots.
  • Otherwise, if there is a single top-level directory whose name begins with mod (case-insensitive, e.g. modFoo), it is installed as a directory mod under mods/.

The same mod*-prefixed-directory heuristic is also used to recognise a “bare” mod layout (a folder that is a single mod, with no wrapper directory).

What scanning finds

modde scan --game witcher3 walks the install and discovers already-present mods in two directories:

Directorymod id prefixConfidence
mods/mod0.90
dlc/dlc0.75

Each immediate sub-directory of mods/ becomes a discovered mod (mod/<name>), and each sub-directory of dlc/ becomes a discovered DLC-style mod (dlc/<name>). The on-disk footprint modde records for a discovered mod is the directory itself, lowercased — mods/<name>/ or dlc/<name>/ — so it can be matched and removed cleanly later. Import the results into a profile with:

modde scan --game witcher3 --import-to my-witcher3

See Mod Scanning for --dry-run, threshold tuning, and manifest matching.

Conflict classification

The Witcher 3 collision classifier treats .bundle and .cache as archive extensions and otherwise uses modde’s default per-extension severities. The most important entries for this title:

Extension(s)Category / severity
wsScript — Dangerous (overrides game scripts)
dllBinary — Dangerous
xml, csvConfig
bundle, cacheArchive
dds, png, jpg, xbmTexture / Cosmetic

Run the standard conflict report:

modde collisions --profile my-witcher3

.ws script conflicts

The defining gotcha for Witcher 3 modding is script merging: many mods ship gameplay scripts under content/scripts/, and REDengine compiles only one copy of each script file. Two mods that both ship r4Player.ws will silently clobber each other unless their changes are merged.

modde detects this specifically:

  • has_script_conflict(mod_dir) returns true if a mod directory contains any .ws file anywhere in its tree (case-insensitive).
  • script_conflict_paths(mods_root) walks every installed mod under mods/, records the relative .ws paths each one provides (lowercased, forward-slashed), and returns exactly the script paths provided by more than one mod — i.e. the scripts that actually collide.

Because .ws is classified Dangerous and content/scripts is flagged as a save-breaking directory, script-shipping mods also contribute to the save fingerprint (below). When two mods collide on the same .ws file you generally need a manual or tool-assisted script merge — modde tells you which files collide, but it does not merge REDengine scripts for you. See Conflicts & Load Order for the general workflow and per-file hiding.

Save tracking

PropertyValue
Save directory~/Documents/The Witcher 3/gamesaves
Tracked extension.sav
Excluded*.png (save thumbnails)
RecursiveNo — top-level of the save dir only
Save profilesSupported

Saves live in a git-backed vault per the Save Management guide, with one branch per profile. For The Witcher 3 modde tracks *.sav files at the top level of the save directory and ignores the *.png save-thumbnail images that sit alongside them.

What is fingerprinted

modde computes a SHA-256 mod fingerprint from the sorted list of enabled mods classified as save-breaking, and stores it as a commit trailer on each save snapshot. For The Witcher 3 the save-breaking surface is:

  • Save-breaking extensions: ws, xml, bundle, cache, csv, dll
  • Save-breaking directory: content/scripts

Cosmetic-only mods (textures such as dds, png, jpg, xbm) do not move the fingerprint, so swapping a texture pack will not trigger a save-compatibility warning. Adding or removing a script/archive mod will. On restore, modde compares fingerprints and warns when the snapshot’s save-breaking set differs from your current profile.

Plugin / load-order handling

REDengine has no Bethesda-style plugin system, so there is no .esp/.esm load order, no LOOT sorting, and no plugin validation for this title. Mod precedence is the ordinary modde load-order priority (later mods win file conflicts), resolved during the VFS build phase. The one ordering-sensitive area is .ws script conflicts, which modde surfaces (see above) but does not auto-resolve. There is no built-in mods.settings/modList priority writer.

Installer specifics

The Witcher 3 modding ecosystem does not use FOMOD, REDmod CLI packaging, UE .pak chunks, or SMAPI. In practice mods are distributed as archives that either:

  1. contain the REDengine root layout (mods/, dlc/, bin/, content/), or
  2. contain a single mod*-prefixed directory.

modde handles both via the archive-analysis heuristics described above — there is no separate scripted-installer step for this title. (For games that do use guided installers, see FOMOD Installers.)

bundle and cache are treated as packed archive formats for conflict reporting; modde does not repack them.

Gaming tools that matter

modde does not ship any built-in OptiScaler presets for The Witcher 3 — the title’s OptiScaler profile list is empty — so upscaling is best handled through the generic optiscaler tool or your own pin if you want one. The tools that matter most here:

  • proton — runner version, prefix override, extra_env, and DLL-override mode. This is where you control how the game launches under Proton.
  • mangohud / vkbasalt / gamemode — overlay, post-processing, and the Feral GameMode daemon, all wired through modde’s launcher integration.
  • Script-extender-style DLLs — see the Wine DLL proxies below.

See Tools & Overlays for enabling and configuring each.

Wine DLL proxies

Several Witcher 3 mods inject through a proxy DLL placed next to the game executable (in bin/x64). modde knows the proxy names this title uses and emits the corresponding Wine DLL overrides so they load inside the Proton prefix:

dxgi, d3d11, version, winmm

When a staged mod (or the live executable directory) contains one of these DLLs, modde adds it to the game’s Wine DLL overrides automatically, so the proxy is picked up under Proton without hand-editing the prefix.

Linux / Proton notes & gotchas

These notes cover the game’s runtime on Linux and macOS, where The Witcher 3 runs through Proton/Wine. On Windows the game runs natively — there is no Wine prefix, proxy DLLs load directly, and saves live at their native Windows location. modde itself runs natively on all three platforms.

  • Documents path. The save directory is the Wine/Proton-mapped ~/Documents/The Witcher 3/gamesaves. If your distro or home setup relocates Documents, confirm modde detect/save scanning is looking where the Proton prefix actually writes saves.
  • Script merging is on you. modde flags colliding .ws files but does not merge REDengine scripts. For modlists that touch the same scripts, plan to do a manual or tool-assisted merge — and re-check modde collisions afterward.
  • Proxy DLLs need the override. A mod that relies on a dxgi/d3d11/ version/winmm proxy will silently do nothing under Proton if the override is missing. modde sets these automatically when it sees the DLL; if you install such a mod outside modde, you may need to set the override yourself via the proton tool.
  • No Heroic auto-detect. GOG/Epic copies are not auto-discovered; point the profile’s gameDir at the install directory explicitly.

Worked example

Home-Manager profile

programs.modde = {
  enable = true;

  nexus.apiKeyFile = "/run/secrets/nexus-api-key";

  profiles.my-witcher3 = {
    game = "witcher3";
    installMode = "auto";
    gameDir = "/home/me/.local/share/Steam/steamapps/common/The Witcher 3";

    tools = {
      gamemode.enable = true;
      vkbasalt = {
        enable = true;
        settings = {
          enableOnLaunch = true;
          casSharpness = 0.4;
        };
      };
      proton = {
        enable = true;
        settings = {
          version_mode = "launcher_default";
        };
      };
    };
  };
};

Declare the profile before the game is installed by omitting gameDir or setting installMode = "await-game"; activation prints the next step instead of failing. After Steam finishes installing, set gameDir and rebuild. See the Home-Manager Module reference for every option.

CLI workflow

# 1. Confirm modde found the install
modde detect

# 2. Import any mods already sitting in mods/ and dlc/
modde scan --game witcher3 --import-to my-witcher3

# 3. Check for colliding files (especially .ws scripts)
modde collisions --profile my-witcher3

# 4. Adopt your existing saves into the vault
modde save adopt --game witcher3 --profile my-witcher3

# 5. Deploy and launch (captures saves on exit)
modde play my-witcher3 --game witcher3

See also