The developer menu of Wolfenstein II: The New Colossus is still in the retail game, but its map entries did nothing. The WolfSDK mod Dev Menu Map Loading (mods/tnc_devmenu_fix, version 0.2.0) makes them load maps again with data only: no DLL, no EXE patch. This page explains why the stock entries failed, how the fix works, and what is confirmed in game.
Evidence labels: Measured = read from game files or from a read-only memory snapshot of the running game; Inferred = derived from disassembly, not watched at runtime; Hypothesized = plausible, not checked. Status words: Confirmed in game, Not yet confirmed in game, Held back. Addresses are RVAs in the snapshot re_probes/runtime_87400/module.bin.
Keywords: dev menu, developer menu, debug menu, level select, map select, Wolfenstein II, Entwicklermenü, Dev-Menü, Karten laden
Dev Menu Status: What Is Confirmed in Game
| Part | Status |
|---|---|
Dev menu entries run their command lines unrestricted; devmap loads the map |
Confirmed in game (2026-10-02) |
A new map name in dlc_0 (game/wolfsdk/modtest) loads from the menu |
Confirmed in game (2026-10-02) |
| 126 restored dev starts (teleports and scenes after loading) | Not yet confirmed in game |
| Hidden Menu Options (main menu entry to the dev menu) | Not yet confirmed in game |
The WolfSDK: Box map |
Not yet confirmed in game |
Chapter progression (Progression) and give lines |
not reproduced |
Keywords: dev menu status, does the dev menu work, confirmed, tested, funktioniert, Status, im Spiel bestätigt
Why the Retail Dev Menu Map Entries Did Nothing
Measured. Picking a map entry in the retail menu queues the line loadDevMenuOption <decl> <index> <option>. The console answers Unknown command 'loadDevMenuOption'. The name is missing from the full table of 234 registered commands, not only from the 34 the console exposes. Developer cvars do not change that. g_demoDevMode was already 1 in the same snapshot: a visible menu does not prove a working load function.
Inferred. The menu selector (0x3D03B0) builds that line at 0x3D05DD and 0x3D08A9 and appends it to the command buffer. The menu init (0x3D0320) opens devmenuoption/main and registers no command.
So the selection fails before any map is resolved. The error is no evidence that the map or the DLC is missing, and map and devmap were never removed: both are registered.
Keywords: loadDevMenuOption, Unknown command, dev menu broken, map entry does nothing, nothing happens, Dev-Menü lädt keine Karten, kaputt
The Fix: Dev Menu Map Loading Turns Map Entries into Command Lines
The mod rewrites every map entry of the 95 devMenuOption decls into a pure command entry. Its devMenuCommandStrings list holds the console lines the missing native handler would have run, ending in devmap <map>. The menu has a branch that runs such lines directly, at the unrestricted level, so devmap and the si_* cvars are reachable although the console does not expose them.
- Builder:
tools/build_devmenu_fix.py.--checkcompares the mod folder with a fresh build. The stock decls are read as the loader's backup says they were, so the build is the same whether mods are applied or not. - The lines copy what the native launch code (
0x3ECF50) sets. - Confirmed in game (2026-10-02):
devmapruns from the dev menu and the map loads.
Keywords: Dev Menu Map Loading, tnc_devmenu_fix, devMenuCommandStrings, devmap from menu, fix dev menu, Dev-Menü reparieren, Mod
The Dev Menu Selector Branch for Command Entries (0x3D0556)
Inferred (code reading, re-checked independently). The selector already has a branch for entries that carry commands instead of a map. An entry takes it when:
- its display name is not empty and not the literal
...; - it has no sub list (
+0x30= 0); - its game type (
+0x148) is not 1 (PVP); - its map name is empty (length
+0x48= 0) and it has command lines (count+0x90> 0).
The branch appends each line (list at +0x88, formatted "%s\n") to a command buffer. Then it drains both buffers at once through 0x1265800, first at level 0, then at level 1, so the unrestricted buffer always runs at level 0. The menu stays open.
Confirmed in game: devmap lines run this way.
Keywords: selector branch, 0x3D0556, command entry, devMenuCommandStrings branch, dev menu code, Befehlseintrag
Why Dev Menu Lines Run Unrestricted: the Restriction Level 0x41244d8
One global integer (0x41244d8) picks which list the dispatcher searches: level 0 = all 234 commands and every cvar, level 1 = only the 34 exposed commands and 304 exposed cvars.
- Inferred: the level rests at 0. Console key input,
+argson the start line andexecset it to 1 and restore it afterwards. The key-bind dispatcher does the same (TNC Console Unlock). - Inferred: no such bracket wraps the menu's widget update (
0x3D0260), so the selector appends to the unrestricted buffer. The call chain up to the frame root was not traced. - Confirmed in game:
resourceExec <cfile> -sruns its lines at level 0, and dev menu lines reach the non-exposeddevmap.
Keywords: restriction level, restricted console, 34 commands, exposed, unrestricted, developer command, Sperrstufe, Konsole gesperrt
The Dev Menu Line Sequence for One Map Entry
Every rewritten map entry runs these lines in this order. Stock command lines of the entry, if it had any, come first.
si_spawnspot "<spawn spot>" default player_start_1
si_nextlayeractive "<active layers>" one comma-separated list
si_filllayeractive "<fill layers>"
si_devprogression ""
si_checkpointName ""
si_gamemode <game type>
si_mainmenustart 1 only for game type 2 and up
devmap <map> [-checkpoint <name>]
Active layers: the part's base layers, its Fergus or Wyatt layers for the entry's timeline, the entry's extra layers, and a marker layer for dev starts. Fill layers: the timeline layers and the marker. playerDef and mainMission are not set: MapInit picks them from map and layers. In the decl, quotes are written as \", the way retail decls escape them.
Keywords: dev menu lines, command sequence, devmap, si_spawnspot, layers, example entry, Befehlszeilen, Reihenfolge
Native Launch Cvars Used by the Dev Menu Fix
The lines set the cvars the native launch code (0x3ECF50) sets: si_spawnspot, si_nextlayeractive, si_filllayeractive, si_devprogression, si_gamemode, si_mainmenustart and si_checkpointName. The native code also sets the difficulty cvars; the fix leaves them alone.
Inferred:
- All carry the CHEAT flag (0x8), none INIT or ROM, so a level-0 line can set them.
idCVar::Set(0x1239140) has no CHEAT test. - They are one-shot inputs: map start reads and clears
si_spawnspot,si_checkpointNameandsi_devprogression. - The map parser (
0xA7BD10) reads the two layer cvars only whendevmapgets no-layername/-filllayername. - An empty value needs
"": the tokenizer keeps an empty quoted token.
Enums: GAME_TYPE CAMPAIGN = 0, PVP = 1, SCORE = 2, CHRONICLE_0..3 = 3..6. TIMELINE NONE/FERGUS/WYATT = 0/1/2. PVP entries are dropped.
Keywords: si_* cvars, launch cvars, si_gamemode, GAME_TYPE, TIMELINE, Chronicle, Spielmodus, Startparameter
The 307 Dev Menu Starts: What Is Included and What Is Dropped
Measured (build output): the mod writes 95 devMenuOption decls with 307 devmap lines. Two of them are the WolfSDK test maps.
- The first version had 220 starts. It merged entries whose lines differed only in their after-load commands. Version 0.2.0 keeps them apart with marker layers.
- Dropped: entries whose map ships in no
packagemapspec.json(the developers' reference and box maps), PVP entries, and sub lists left empty. - Entries with byte-identical lines collapse into one.
- Not reproducible:
Progression(chapter progress;si_devprogressionstays empty), thegivelines, and the dev teleports of the DLC maps. - Fixed on the way:
devMenuSubList = NULLnow counts as no sub list. The 7 c07p1 Wyatt entries were dead links before.
Keywords: 307 starts, 220 starts, dev menu entries, missing entries, Progression, chapter progress, Kapitel, Einträge
MapInit Part Resolver and Layer Rules (0xDF5860)
Inferred (code reading). MapInit (0x11B55F0) calls the chapter/variation/part resolver at 0x11B6733 and takes playerDef and mainMission from the part it finds. The resolver:
- matches the map name;
- removes every fill layer from the active layers (exact compare,
0xDF5AD4); - requires every remaining active layer to be in the candidate part's base layer list (
0xDF8540).
What follows for dev menu lines:
- An extra active layer that is not a base layer breaks the match, unless it is also a fill layer.
- The Fergus/Wyatt timeline layers go into both lists. The timeline getter (
0x11AB970) looks forlayer/fergusin the fill list. Without this, 32 timeline entries (such as c03p1 "D1 - harbor - fergus") matched no part. - Fergus and Wyatt variants with the same layers cannot be told apart: the resolver takes the first hit.
Keywords: MapInit, part resolver, 0xDF5860, fill layers, playerDef, mainMission, Fergus, Wyatt, timeline, Ebenen
Dev Starts After Map Load: What kce Did
Many stock entries also had devMenuCommandStrings_AfterMapLoad: lines run after the map loaded. Most are kce <event>, which sent a custom event (a dev teleport or a scene start); a few are give lines. 158 stock entries have such lines. Retail registers neither kce, give nor Progression, so these lines cannot simply be run.
Inferred: the after-load queue was drained in idCommonLocal::Frame (0xA747F0) directly after the map change, so kce ran before the map's BeginGame event was dispatched.
Keywords: kce, after map load, devMenuCommandStrings_AfterMapLoad, dev teleport, custom event, devstart, Dev-Teleport
Restoring 126 Dev Starts with a Marker Layer (Not Yet Confirmed in Game)
Version 0.2.0 sends the stock events from the map's own scripts instead. Each entry with servable after-load lines gets a marker layer layer/wolfsdk/<events> (event names in lower case, joined by __, such as layer/wolfsdk/devtel_soup__devstarted) in both layer cvars:
- active (
si_nextlayeractive): the spawn code copies every active layer name into the list atgameLocal+0x60C0, the only listFlowLayerCheckreads (0x9B7AB0→0x11B3340); - fill (
si_filllayeractive): the part resolver drops it before matching, soplayerDefandmainMissionstill resolve.
Inferred: an unknown layer name is never validated on this path. The marker is no real layer decl: the Kiscule reference reader creates a resource for the missing name (0xABA110). Not seen at runtime; if that fails, the chain stays silent.
Keywords: marker layer, layer/wolfsdk, FlowLayerCheck, dev starts, 126 dev starts, Markierungs-Layer, Startpunkte
FlowLayerCheck Chains in the 12 Dev Start Scripts
One script per map hosts the chains: the map's *devstart* script, else the one with the most receivers. The mod ships the edited scripts as extkisclule assets. Per marker the host gets:
BeginGame.OnBeginGame → FlowLayerCheck(marker) "Validation succeeded" → SendCustomEvent(global = true) per event, in stock order.
63 FlowLayerChecks in 12 scripts restore 126 of the 158 entries; 2 only partly (the event is sent, give is not). Per map: c01p1 13, c02p0 4, c02p1 6, c02p2 1, c04p2 2, c05p2 8, c08p1 2, c08p2 1, c09p1 9, c09p2 7, c11p1 4, submarine/c07p1 6.
Not restored (32): 14 DLC entries (their scripts are in DLC archives), 14 c08p1/c08p2 entries whose events have no receiver, 4 entries with only give. Inferred: a global script send reaches the receivers the console kce reached. Check: tools/verify_devmenu_devstarts.py.
Keywords: FlowLayerCheck, SendCustomEvent, BeginGame, devstart script, Kiscule chain, Skript, Kette
Dev Start Timing Risk on c01p1 and c09p1
Hypothesized risk. Stock kce ran before BeginGame; the new chain runs during it. Its order relative to other scripts' BeginGame nodes is not established. Two maps gate their intro on a dev event:
- c01p1:
devstartedcloses a gate inheaven_flowthat guards the "soup" intro. - c09p1:
Dev_DevLoadedgatesBossOffice_playinevent_flow.
Elsewhere the dev events only teleport or start scenes.
In-game check: Levels → c01 → c01p1 → Fergus dev starts → "bomb". Expected: the bomb scene and no soup intro. If both play, or only the intro, the order is the problem. Checks without that risk: c05p2 → "Train" (then "Train Station" and "Ending": each must end up somewhere else) and c11p1 → "hugin room". If the map loads but nothing happens after it, the marker path failed.
Keywords: dev start test, BeginGame order, c01p1 bomb, c09p1, intro plays, teleport does not work, testen
Opening the Dev Menu: Hidden Menu Options Cvars
The mod Hidden Menu Options (mods/tnc_hidden_options) sets four cvars to 1. The retail menu code reads all four:
| Cvar | Turns on |
|---|---|
menu_showOptionForDevMenu |
the main menu entry to the developer menu |
menu_showOptionForSASMenu |
the SAS menu entry |
menu_allowMeinLeben |
the hardest difficulty, Mein Leben!, without finishing the game first |
g_setting_photomode |
the photo mode setting (what it does in this game is unknown) |
They are BOOL|CHEAT cvars the console refuses, so the loader writes them into the game's default.cfg (TNC Console Unlock). Not yet confirmed in game. Fixed while building it: the loader GUI did not pass mods' cvars, only the command line did.
Keywords: open dev menu, show developer menu, menu_showOptionForDevMenu, SAS menu, Mein Leben, hidden options, Entwicklermenü öffnen, versteckt
WolfSDK Test Entries in the Dev Menu
The mod adds three entries to devmenuoption/main:
- WolfSDK: console test runs
echo ...,g_debugLayerChanges 1andg_debugLayerChanges. That cvar is not exposed, so the console must print its value 1. "Unknown command" would mean the lines ran at level 1. Try it first: if it fails, no other entry can work. - WolfSDK: Box runs
devmap game/wolfsdk/box, a closed 8 × 8 × 4 m test room. Not yet confirmed in game. - WolfSDK: Mod test map runs
devmap game/wolfsdk/modtestwith spawnmodtest_start: retail c2v1 under a new name, mission removed, 11 weapons and 8 enemies. Confirmed in game: it loads.
Both maps are extra maps in dlc/dlc_0 (TNC Custom Map Status). Their map files and builders are not in the public WolfSDK package. Without the map installed, the game reports Map ... is not present in this package.
Keywords: WolfSDK console test, WolfSDK Box, Mod test map, modtest, test map, g_debugLayerChanges, Testkarte
Applying the Dev Menu Map Loading Mod
- Close the game. In the loader, tick Dev Menu Map Loading, apply, then start the game.
- The mod changes 107 assets: 95 decls and 12 scripts. On copies of the game files, applying it rebuilt 8 archives (chunk_1, chunk_3, chunk_9, chunk_13, gameresources, patch_1_chunkbase_6, patch_2, patch_3); the backup then holds full copies of them, about 1.6 GB. Revert gave back all 13 archives that hold the assets md5-identical.
- For the main menu entry to the dev menu, also tick Hidden Menu Options (not yet confirmed in game).
- The two WolfSDK map entries also need their maps installed in
dlc/dlc_0.
Keywords: install dev menu fix, apply mod, backup size, disk space, revert, Speicherplatz, anwenden, installieren
Dev Menu Item Fields and Offsets
Measured from the reflection records in the snapshot. Items start at *(decl + 0x80), stride 0x150.
| Field | Offset |
|---|---|
devMenuDisplayName |
+0x00 |
devMenuSubList |
+0x30 |
devMenuMapName |
+0x38 (data +0x40, length +0x48) |
devMenuTestExtraLayers |
+0x68 |
devMenuCommandStrings |
+0x88 (count +0x90) |
devMenuCommandStrings_AfterMapLoad |
+0xA8 |
devMenuCheckpoint / devMenuSpawnspot |
+0xC8 / +0xF8 |
devTimelineType / devVariation |
+0x128 / +0x130 |
devPart / devProgression / devGameType |
+0x138 / +0x140 / +0x148 |
Keywords: devMenuOption fields, offsets, decl layout, devMenuMapName, devVariation, devPart, Felder
Related pages
TNC Console Unlock · TNC Custom Map Status · Developer Mode · Kiscule Scripting · Known Contradictions
Research reports behind this page: R8 dev menu fix verification · R9 dev starts · R9 box map · R10 mod test map
Keywords: related pages, see also, dev menu links, weiterführende Seiten