🇬🇧 English · 🇩🇪 Deutsch: FAQ · Mod-Format · WolfSDK Loader · WolfSDK Studio
Modding Guide
Where to start depends on what you want to do: players use the WolfSDK Loader, modders the WolfSDK Studio, programmers the command line and the SDK. The reference after that (decls, paths, console) is for hand-written mods and the command line. All its examples have been tested against the actual game files: if a path is listed here, it exists.
Keywords: modding guide, where to start, how to mod, Wolfenstein modding, tutorial, Einstieg, Anleitung, Modding-Anleitung
Modding Guide for players: WolfSDK Loader
You want to play with mods, cheats or a custom map. Download WolfSDK-Loader-0.3.1.zip from the release page, extract it, double-click WolfSDK.cmd. Switch mods on in the Mods page, click Apply mods, then Start game. Revert undoes everything.
- Step by step: WolfSDK Loader (Deutsch)
- Common questions: FAQ (Deutsch)
- What does not work yet: Modding Limits
Keywords: player, play with mods, use mods, Loader, Apply mods, Start game, Revert, Spieler, Mods benutzen
Modding Guide for modders: WolfSDK Studio and mod.json
You want to make mods. WolfSDK-Studio-0.3.1.zip contains the Loader plus the Studio. Open it from the loader's Studio page with Open Studio: browse maps, videos, audio, textures and texts of both games, replace BC1 textures, texts, decls, sounds and videos. Each replacement is saved as a mod in the mods folder, which the loader applies.
- Studio guide: WolfSDK Studio (Deutsch)
- Writing
mod.jsonby hand, every field: Mod format (Deutsch) - Which values to change (weapons, skins, enemies): sections 1–3 below
Studio normal maps (BC5) and the Kiscule script editor are Not yet confirmed in game. Replacing sounds and videos (new in 0.3.0, The New Colossus only) is Not yet confirmed in game either.
Keywords: modder, make mods, Studio, Open Studio, replace textures, mod.json, Modder, Mods erstellen
Modding Guide for programmers: command line and SDK
Two different tools are called wolfsdk:
- The apps' command line (source in the repository folder
modloader/; in an extracted packagepython\python.exe -m wolfsdk):list,cat,paths,check,apply,revert,new-modand more, for both games (--title tnc). Itsmod.json: Mod format. - The SDK packages (
pip install wolfenstein-sdk, npm, cargo, go): bindings of the repository'sspec/SPEC.md. The Python package addswolfsdk -g "<game folder>" paths|apply|revert. They cover The New Order's archives and the decl format of both games, not The New Colossus' IDCL container. Theirmod.jsonusesgameinstead ofspiel: comparison.
The reference below uses the apps' command line.
Keywords: programmer, developer, command line, CLI, SDK, wolfenstein-sdk, python -m wolfsdk, Programmierer, Kommandozeile
Core Principles
Almost everything interesting in the game resides in Decls — text files within the .resources archives. A mod is a list of changes to such Decls. There are two types:
| Type | Syntax | Effect |
|---|---|---|
| Surgical | "set": { "path": value } |
Changes only this value; the rest of the file remains untouched |
| Full Replacement | "file": "decls/x.decl" |
Replaces the asset completely |
set is almost always the better choice: mods remain compatible with each other and survive detailed changes to locations they do not touch.
Keywords: decl, set, file, surgical edit, full replacement, how mods work, Grundprinzip
The Workflow
From the source folder modloader/ with Python 3.11, or in an extracted package with python\python.exe instead of python. Add --title tnc for The New Colossus.
python -m wolfsdk list --type weapon # what exists?
python -m wolfsdk cat weapon:weapon/shotgun_base # what does it look like?
python -m wolfsdk paths weapon:weapon/shotgun_base # what can I change?
# -> write mod.json
python -m wolfsdk check # full pre-check, writes nothing
python -m wolfsdk enable my.mod && python -m wolfsdk apply
check builds every payload in memory and checks asset names, decl paths, conflicts and the expected write plan, without writing anything. Always do this first.
Keywords: workflow, list, cat, paths, check, enable, apply, command line, Arbeitsablauf
1. Weapons
Changing Values
A weapon's damage does not reside in the weapon, but in its own damage Decl:
python -m wolfsdk list --type damage --grep tungsten
python -m wolfsdk paths damage:damage/tungsten/mg60
edit.damageParms.minDamage 12.5
edit.damageParms.maxDamage 17.5
edit.damageParms.ragdollImpulseMag 500
edit.damageParms.goreTypes "GORETYPE_SMALL_WOUND GORETYPE_BIG_WOUND …"
edit.damageParms.declGoreBehavior "standard/heavy"
"damage:damage/tungsten/mg60": {
"set": {
"edit.damageParms.minDamage": 22.0,
"edit.damageParms.maxDamage": 30.0,
"edit.damageParms.ragdollImpulseMag": 1200
}
}
Keywords: weapon damage, damage decl, minDamage, maxDamage, mg60, stronger weapons, Waffenschaden
Changing Behavior
The weapon Decl controls handling — in the shotgun base Decl there are 169 addressable values:
edit.isDualWieldable true
edit.ammoPerShot 1
edit.allowSprintFire false
edit.allowOneHandedReload true
edit.firingIntervals.firingIntervals[0] 200 // milliseconds
edit.burstCounts.burstCounts[2] 1
edit.validAmmoClips.item[0].clipSize 20
edit.handsFovScale 0.90
edit.handsModelMD6 "weapons/shotgun.md6"
edit.initialAmmoDecl "ammo/shotgun"
Keywords: weapon decl, fire rate, firingIntervals, clipSize, magazine, dual wield, Feuerrate, Magazin
Example: Faster Fire, Bigger Magazine, Dual-Wield
Fire faster and have a larger magazine:
"weapon:weapon/shotgun_base": {
"set": {
"edit.firingIntervals.firingIntervals[0]": 120,
"edit.firingIntervals.firingIntervals[2]": 120,
"edit.validAmmoClips.item[0].clipSize": 40
}
}
Make it dual-wieldable when it otherwise isn't:
"weapon:weapon/lasercutter_base": { "set": { "edit.isDualWieldable": true } }
Keywords: example, faster shotgun, bigger magazine, isDualWieldable, lasercutter, Beispiel
Building a "New" Weapon
New 3D geometry is not possible (see Modding Limits). A new weapon arises through Recombination, and that is more than it sounds:
- Copy an existing
weaponDecl as a full replacement and rebuild it - Set
handsModelMD6to point to another existing model - Run
initialAmmoDeclthroughammo→projectile→damage - Set fire rates, spread, magazine, and dual-wield freely
- Create your own
skinsset for the look
Result: a quiet, fast-firing double shotgun with laser projectiles — mechanically a new weapon, optically composed of existing parts.
Trace the chain:
python -m wolfsdk cat weapon:weapon/shotgun_base | grep -i ammo
python -m wolfsdk paths ammo:ammo/shotgun # -> projectile/shotgun
python -m wolfsdk cat projectile:projectile/shotgun
Keywords: new weapon, custom weapon, recombination, ammo, projectile, neue Waffe
2. Weapon Skins
A skin is a Material. The pistol shows how it works — the game already provides a white variant:
python -m wolfsdk cat material:models/weapons/handgun/handgun_hg
python -m wolfsdk cat material:models/weapons/handgun/handgun_white_hg
The difference is exactly two lines:
diffusemap "models/weapons/Handgun/Handgun" → "…/Handgun_white_hg"
virtualmapping { 0.015625, 0.015625, 0.078125, 0.031250 } → { …, 0.000000, 0.062500 }
Keywords: weapon skin, material, diffusemap, virtualmapping, white pistol, Waffen-Skin
Example: the White Pistol (The New Order)
"material:models/weapons/handgun/handgun_hg": {
"set": {
"diffusemap": "models/weapons/Handgun/Handgun_white_hg",
"virtualmapping": "{ 0.015625, 0.015625, 0.000000, 0.062500 }"
}
}
virtualmappingincluded. The pixels lie in the Megatexture, not in the Material. These four numbers are the coordinates there. Changing only thediffusemapname is likely insufficient — take the values from the target material as well.
Other knobs in the Material: specularmap (Specular), bumpmap (Surface relief), powermip.
Keywords: example, white handgun, skin example, megatexture, Beispiel
skins-Decls
A skins-Decl is a named Material override table:
{
white {
"models/weapons/handgun/handgun_hg" "models/weapons/handgun/handgun_white_hg"
"models/weapons/handgun/handgun_silencer" "…/handgun_silencer_white"
}
}
The game activates such a set via its name — for characters, via damageSwapSkin. Rebuilding an entire set is easiest as a full replacement via "file".
Keywords: skins decl, skin set, damageSwapSkin, material override
Weapon Skins in The New Colossus
In The New Colossus, weapon textures are BC1 images that can be replaced directly: the WolfSDK Studio takes a PNG and saves it as a mod. During research, a custom BC1 pistol skin was seen in a running game. The shipped mod Golden Pistol (Simple) (tnc_skin_gold_pistol_simple) uses material decls only (Not yet confirmed in game). Do not tick two skins for the same weapon: two mods that write the same textures are refused.
Keywords: TNC skin, The New Colossus skin, BC1, PNG, golden pistol, texture replace, Studio
3. Characters and Clothing
An enemy is an entityDef. Example:
python -m wolfsdk paths entityDef:ai/tungsten/c10/part_01/rifle/infantry60_01
edit.renderModelInfo.model "templates/c10/part1/Commando.md6"
edit.damageSwapSkin "commando_gore_dmg"
edit.aiHealth.components.components[0].max 65
edit.startingInventory.item[0].inventoryDecl "weapon/ai/assaultrifle1960"
edit.clipModelInfo.size.z 96
Keywords: enemy, entityDef, character, soldier, model, health, Gegner
Four Mods from One entityDef
Different Appearance — the soldier uses a different model:
"entityDef:ai/tungsten/c10/part_01/rifle/infantry60_01": {
"set": { "edit.renderModelInfo.model": "characters/standard/soldiers/infantry60/infantry60_01.md6" }
}
Different Clothing/Color — different skin set:
"set": { "edit.damageSwapSkin": "infantry60_gore_dmg" }
Tougher or weaker:
"set": { "edit.aiHealth.components.components[0].max": 200,
"edit.aiHealth.components.components[0].cur": 200 }
Different Weaponry:
"set": { "edit.startingInventory.item[0].inventoryDecl": "weapon/ai/shotgun" }
Keywords: enemy appearance, clothing, tougher enemies, enemy health, enemy weapons, aiHealth, Gegner stärker
The Model Decl (md6Def)
The model itself is an md6Def and also text:
python -m wolfsdk cat md6Def:characters/standard/soldiers/infantry60/infantry60_01.md6
init {
inherit "characters/standard/base.md6"
multimesh { base "md6/models/…/infantry60_01.md6mesh" }
}
multimesh.base points to the actual geometry (.md6mesh, binary, not editable). But inherit, hitboxes (jointGroups), modelCaps, and appended objects can be freely modified.
There are 3,182
entityDefs. Many enemies exist per chapter separately (c02/…,c10/…) — whoever wants to change an enemy type game-wide must capture all variants.wolfsdk list --type entityDef --grep <name>shows them.
Keywords: md6Def, model, md6mesh, hitbox, jointGroups, all enemy variants
4. Console Commands and Debug Access (The New Colossus)
Part 2's console only shows 34 of 234 commands and 304 of 3,256 Cvars from the normal, restricted console. That restriction is one process-wide integer, not an encryption — and one of those 34 commands, resourceExec, is a complete, no-patch way through it. Full mechanism and in-game proof: TNC Console Unlock. The shipped mod Sandbox Tools packages exactly this recipe (F6/F7, see FAQ).
Keywords: TNC console, restricted console, resourceExec, console unlock, debug access, Konsole
Running Non-Exposed Commands through resourceExec
- Pick an unused retail
cfileto carry your lines —snapdemo.cfg/snapedit.cfg(unused SnapMap configs ingameresources) are the ones already proven. Write plain text, one command per line:God 1 Notarget 1 g_infiniteAmmo 1 - Ship it as a loader mod asset keyed
"cfile:snapdemo.cfg". The file must be the encrypted form for that name: save the text through the Studio's text replacement, which encrypts it (wolfsdk/tnccrypt.py). A plain text file is written as it is and does not work. - In the normal, restricted in-game console, type:
resourceExec snapdemo.cfg -sEvery line in the file runs with the restriction dropped for that one call —God,Notarget,g_infiniteAmmo, and any other registered-but-non-exposed command or Cvar, confirmed executing in a real save game.
Keywords: resourceExec, cfile, snapdemo.cfg, God, Notarget, g_infiniteAmmo, encrypted cfile
Binding It to a Key and Opening the DevGUI
- Bind it to a key so it survives beyond one console session (binds persist across launches):
bind F6 "resourceExec snapdemo.cfg -s" - For a whole debug menu instead of one-off lines, put just
devgui 4in the file. It needs theresourceExeccall only once per session — after that, the engine's own ImGui debug pages draw and their buttons/toggles (g_infiniteAmmo,ai_drawBounds,killAI, dozens of others) work with no furtherresourceExec.
Keywords: bind, key bind, F6, devgui, DevGUI, debug menu, ImGui
What Does Not Work: +args, give, spawn, noclip
Never ship a cheat/debug toggle as a startup +arg on the launch command line — that path is bracketed at the restricted level and every non-exposed name comes back Unknown command, confirmed in game.
A map's own Kiscule script can reach the same unrestricted path with no console interaction at all, via the Command node (idKisculeNodeCommand) — see Kiscule Node Reference §8. That route is proven by code, not yet by a loaded custom map.
give, give all, spawn, noclip, and lowercase god are not shortcuts away from this recipe — they are absent from the 234-command table entirely, under any route, and would need a binary patch to add.
Keywords: Unknown command, launch arguments, give, spawn, noclip, god, Kiscule Command node
5. Conflicts and Load-Order
Mods are layered by priority, low first. Each mod works on the result of the previous one.
- Two mods change different values of the same Decl → both work.
- Two mods set the same path → higher priority wins, reported as a conflict.
- Two mods use
"file"on the same asset → hard conflict, reported, higher priority wins. - Two mods write the same texture (
imageortexdbasset) → refused before anything is written.
Conflicts do not block; they are reported — in the loader under Checks & messages, on the command line at check and apply.
Keywords: conflict, load order, priority, two mods, same value, Konflikt, Reihenfolge
6. Pitfalls
Numbers do not automatically preserve their original formatting. 25 and 25.0 are different text in Decl. Write floating-point numbers as floating-point numbers if the original is one — "maxDamage": 30.0, not 30.
Strings are automatically quoted if the original was quoted. For block values like virtualmapping, you must include the curly brackets yourself.
Keywords: pitfalls, number format, float, quotes, block value, Stolperfallen
Pitfalls: Duplicates, Inheritance, Game Updates
An asset can appear multiple times. The same (type, name) combination may exist in multiple chunks. The Patcher writes all occurrences so it does not matter which one the engine encounters first. In The New Colossus it reads the newest patch copy as the starting point since 0.2.0; before, it read the older base copy, so a mod could undo official patch changes to that file.
Inheritance. Many Decls have inherit = "…". A value you do not see in the child is defined in the base. wolfsdk cat on the base Decl shows it. A set works only on paths that are located in this file.
After a game update, offsets no longer match. First run revert, then create a new Backup. wolfsdk info warns if something does not match.
Keywords: duplicate assets, patch copy, inherit, inheritance, game update, revert, info