Wolfenstein Modloader Buy me a coffeeKaffee spendieren

Wiki / Latest research roundsNeueste Forschungsrunden

TNO Console and Cvars: Does the TNC Restriction Model Carry Over?

Partly solvedTeilweise gelöst Original page in the GitHub wikiOriginalseite im GitHub-Wiki

In plain wordsIn einfachen Worten

This report asked whether The New Order (TNO) restricts its console the same way Wolfenstein II: The New Colossus (TNC) does, and whether TNC's resourceExec trick works there. It does not: TNO has no resourceExec command at all and no flags that mark commands as allowed or hidden; its lock only covers cheat-flagged settings, which are refused from config files and otherwise reset once after start. Two tables were mined from text inside the game program: 2,031 commands and settings, and 55 button-to-command pairs from the hidden DevGUI menu. Everything is static because TNO's code could not be read at the time; the only in-game evidence is an earlier game log, and a later round (R7) re-checked and corrected some of these readings.

  • The text resourceExec appears 0 times in TNO's program; one exec command runs every config file, and default.cfg is blocked for cheat settings like any other config.
  • A real game log shows the cheat reset wiping com_skipIntroVideo, so the loader's 'always skip intro videos' option does not work on retail TNO.
  • The DevGUI table holds 55 clean pairs, including notarget, give, spawn, killMonsters and NoPlayerDeath; the 'God Mode' button only holds a placeholder ('TEMP 5').
  • The mined command list was cleaned of noise and shrank from 5,026 to 2,031 entries; in a fresh sample 18 of 20 entries were genuine.
  • Untested: whether commands bound to keys at start run without any lock, and whether map scripts can set cheats through setcvar or executeCommandText.

Dieser Bericht hat gefragt, ob The New Order (TNO) seine Konsole genauso einschränkt wie Wolfenstein II: The New Colossus (TNC) und ob TNCs resourceExec-Trick dort funktioniert. Das tut er nicht: TNO hat gar keinen resourceExec-Befehl und keine Markierungen, die Befehle als erlaubt oder versteckt kennzeichnen; seine Sperre betrifft nur Cheat-markierte Einstellungen, die aus Konfigurationsdateien abgelehnt und sonst einmal nach dem Start zurückgesetzt werden. Aus Text im Spielprogramm wurden zwei Tabellen gewonnen: 2.031 Befehle und Einstellungen sowie 55 Schaltfläche-zu-Befehl-Paare aus dem versteckten DevGUI-Menü. Alles ist statisch, weil sich TNOs Code damals nicht lesen ließ; der einzige Beleg aus dem Spiel ist ein früheres Spielprotokoll, und eine spätere Runde (R7) hat einige dieser Deutungen erneut geprüft und korrigiert.

  • Der Text resourceExec kommt im TNO-Programm 0-mal vor; ein einziger exec-Befehl führt jede Konfigurationsdatei aus, und default.cfg ist für Cheat-Einstellungen genauso gesperrt wie jede andere.
  • Ein echtes Spielprotokoll zeigt, wie das Cheat-Zurücksetzen com_skipIntroVideo löscht; die Loader-Option „Intro-Videos immer überspringen“ wirkt im Verkaufs-TNO also nicht.
  • Die DevGUI-Tabelle enthält 55 saubere Paare, darunter notarget, give, spawn, killMonsters und NoPlayerDeath; die Schaltfläche „God Mode“ enthält nur einen Platzhalter („TEMP 5“).
  • Die gewonnene Befehlsliste wurde von Störeinträgen bereinigt und schrumpfte von 5.026 auf 2.031 Einträge; in einer neuen Stichprobe waren 18 von 20 Einträgen echt.
  • Ungetestet: ob beim Start auf Tasten gelegte Befehle ganz ohne Sperre laufen und ob Kartenskripte über setcvar oder executeCommandText Cheats setzen können.

Technical detailsTechnische Details

Der technische Teil ist auf Englisch – so, wie er im Wiki steht. Unterstrichene Begriffe haben eine Erklärung auf Deutsch.

Round-6 research pass asking whether TNC's console-restriction model, and its resourceExec/kiscule bypass, carries over to The New Order. Answer: no — TNO's lock is architecturally different. TNO has no command-flag enum and no resourceExec command at all; its lock applies only to CVAR_CHEAT cvars, through a source-channel check and a one-time reset sweep. The report also mines a TNO command/cvar table and the DevGUI label→action table from .rdata string adjacency, and names the script VM as TNO's analogue route. Static evidence only (no TNO runtime image existed yet). Round 7 revisits several of these readings with decompiled code and corrects some of them: TNO cheat gate (R7), TNO console commands (R7).

Read-only. Track tnoconsole. Builds on docs/devmodus.md (dev-mode/retail-lock strings in both exes), docs/limits.md (the only in-game-measured TNO cheat data in the repo — five bypass channels tested, RETAIL_BLOCKED list), and docs/ladepfade.md (TNO vs TNC load/exec-chain comparison). TNO has no runtime image — everything below comes from the shipped WolfNewOrder_x64.exe .rdata/.data (SteamStub-encrypted .text, same as TNC) and from three loose, plain-text game assets read with the existing wolfsdk reader (python -m wolfsdk --title tno cat <asset>). No game was launched, nothing was written under <Steam library>/.... New files live under re_probes/tnoconsole/ (three scripts — mine_tno_cmdtable.py, mine_tno_devgui_table.py, audit_noise.py — and two generated JSON tables) and this report. One existing file was read for corroboration only: the real qconsole.log under Saved Games from the maintainer's own prior, already-completed test run (cited, not reproduced).

Pass 1 errors (fixed this pass)

The verifier refuted 5 of pass 1's claims; all 5 are fixed below, not just noted:

  • Mined table (§4) reliability was overstated. Independently measured: 45–50% of "high confidence" entries were C++ RTTI/template noise (idList < int , TAG_SWF >, bare unsigned int), not real descriptions — a 15-sample spot check found 13/15 (87%) were noise. Fixed: mine_tno_cmdtable.py now rejects </::/bare-type-name/.cpp( strings (new audit_noise.py measures this mechanically); table shrank 5026 → 2031 entries, and a fresh 20-entry sample of the new high-confidence bucket found noise down to 2/20 (10%). See §4.
  • testWeapon was cited from the table but isn't in it. Confirmed: its description and name are genuinely not adjacent (3 unrelated entries sit between them in .rdata) — a real counterexample to the adjacency premise, now stated as such instead of silently miscited. com_production has the same problem (plausible description sits one slot past its name, not before it) — both are flagged in §4 as named, reproducible failure instances of the method, not hidden.
  • notarget/give/spawn/com_production wrongly left as "not found" or "ambiguous". All four exist. Resolved this pass by reading the DevGUI (Label→Action) row table directly (new §4b, new script mine_tno_devgui_table.py, 117 entries, self-check re-reads every one against the live exe): notarget, give throwable/player/grenade, spawn zion/ai/imp/demon_imp (+3 more spawn variants), killMonsters, changeTeam 1/2, NoPlayerDeath and 40+ more are clean, wired Label→Action pairs. com_production is confirmed present as a standalone string by direct grep (§4).
  • god/noclip were treated as uniformly ambiguous; notarget deserved more credit. Fixed with exact byte-bounded evidence in §4b: notarget is a clean pair (strong positive). god and noclip each exist as a single unpaired ("stray") string in the DevGUI region, neither adjacent to a matching label — and the DevGUI row literally labelled "God Mode" has its action slot filled with a placeholder (TEMP 5), not a real command. This is still not proof of absence (.text encrypted, DevGUI-row wiring and the console dispatcher are not necessarily the same list), but it is concrete, differentiated evidence, not a shrug.

What the verifier flagged as missed and is now covered: the DevGUI table is mined (§4b); every curated citation in this report was checked against the file it claims to come from before publishing; DevGUI UI reachability was searched for further static evidence this pass (no new signal found — see §2) and remains an open, game-launch-only question.

Question

Does TNO have the same exposed/non-exposed command-table restriction as TNC? Where are TNO's command/cvar tables and flags in .rdata/.data, and what are its console/exec code paths? Which loader-passed TNO tweaks actually apply? Does TNO have a resourceExec -s-like unrestricted route, or a startup cfg that runs unrestricted? How can dev commands be unlocked in TNO without a code patch?

Answer (short)

No — TNO's lock is architecturally different from TNC's, not a weaker copy of it. TNC gates both commands and cvars through one shared dispatcher with an explicit exposed/restricted two-tier flag system (CMD_EXPOSE/CMD_NOCHEAT/ CMD_SHIPPINGDISABLED, proven in r4/r5). TNO has no such command-flag enum at all — a targeted string search for CMD_* in WolfNewOrder_x64.exe finds only unrelated AWCMD_* (animation-command) and idUCmdInhibit::UCMD_* (usercmd) names, zero hits for anything resembling CMD_EXPOSE/CMD_CHEAT/ CMD_SHIPPINGDISABLED. TNO's lock lives only on cvars, via the CVAR_CHEAT bit (0x8, confirmed absent CVAR_SHIPPINGDISABLED/CVAR_DEVELOPER per docs/devmodus.md) plus a source-channel check, not a dispatch-level check: a CVAR_CHEAT cvar is rejected ("%s CANNOT be set in retail!") whenever it comes from a config file — measured, this already includes default.cfg/ binary.cfg, i.e. the very-first, earliest-possible config exec — and is otherwise silently wiped back to default by a one-time post-command-line sweep ("Resetting cheat cvar: %s"). There is no window analogous to TNC's resourceExec/kiscule exploit (r4/r5), because TNO has no resourceExec command at all (0 occurrences of the string anywhere in the exe) — its single exec <file> [-s] command is used uniformly for every cfg, loose-file and archived alike, and the measured channel table in docs/limits.md already shows that earliest-possible exec (default.cfg) is just as blocked as every other config source. Commands, by contrast, appear structurally ungated — no CMD_CHEAT-equivalent flag exists to check — so once a command reaches the dispatcher at all (via +bind on the command line, which is proven to be accepted without a console) it most likely just runs, with no concept of "exposed" at all; this is the single biggest difference from TNC and the most promising lead, but it rests on the absence of a flag, not on a positive dispatch trace, since .text is encrypted — see §6 for the cheap test that would turn this from inferred into proven or refuted.

The actual new unrestricted-execution candidate for TNO is not a console mechanism at all: the shipped script bytecode-source file script/script_events.script declares native engine calls scriptEvent void setcvar( string name, string value ), scriptEvent string getcvar( string name ), and scriptEvent void executeCommandText( string command ) — callable from any level/map .script file — plus an entity class idTarget_Cvar in the engine's own class hierarchy, placeable straight from a .entities file with no script at all. This is TNO's structural counterpart to TNC's kiscule Command node (r5): game-logic-sourced command/cvar text, a source channel docs/limits.md's five tested channels never covered. Unproven — nobody has built or run the map — but concrete and cheap to try (§7).

1. No resourceExec in TNO — static, exhaustive

python3 - <<'EOF'
data = open(r"<Steam library>\steamapps\common\Wolfenstein.The.New.Order\WolfNewOrder_x64.exe","rb").read()
for s in (b'resourceExec', b'ExecuteCommandText', b'AppendCommandText', b'cfile:'):
    print(s, data.count(s))
EOF
resourceExec 0   ExecuteCommandText 0   AppendCommandText 0   cfile: 0

TNO's exec family, found by the same method (grep over the raw bytes, context read as C strings):

0x0102E160  'exec default.cfg\n'                (device-profile loop, 4x "exec 360_%i.cfg")
0x00E5EB28  'exec default.cfg -s\n'              <- idCommonLocal::Init, real startup exec
0x00E5EB40  'Executing default.cfg for device #%d...\n'
0x00F15018  'exec %s/binary.cfg -s\n'            (game-root cfg, same name/role as TNC's binary.cfg)
0x00F15098  'exec package.cfg -s\n'
0x01052477  'USAGE: exec <filename> -s <define>: execute a script file\n'
0x01052569  "couldn't exec %s\n"

idCommonLocal::Init (surrounding strings 'idCommonLocal::Init', 'Wolfenstein The New Order initialization', 'Command line is: %s\n', "Could not find default.cfg. Check paths.\nfs_basepath = '%s'\nfs_savepath = '%s'", all pooled within 300 bytes of 0xE5EB28) is a single exec command, run through the normal filesystem path search (fs_basepath/fs_savepath), not a separate archive-reading command — because TNO never packs default.cfg in a .resources archive in the first place; D:\...\Wolfenstein.The.New.Order\base\default.cfg is a 4 966-byte loose file on disk (confirmed present). TNC needed a second verb (resourceExec) specifically because its default.cfg moved into the archive; TNO's never did, so one exec already covers both the engine-shipped config and anything a mod drops as a loose file at the same path. This symmetry is also why there is no TNO equivalent of r4/r5's finding: TNC's bypass worked because resourceExec-drained text runs at the dispatcher's unrestricted level (idCmdSystemLocal+0x200b8 == 0), a state that has nothing to do with whether the underlying cvar is cheat-flagged. TNO's exec (same function for every cfg) instead feeds text into a system whose gate checks the cvar's own CVAR_CHEAT flag against the text's source, which is why the measured channel table in §2 shows default.cfg blocked exactly like every other config file — there's no second, lower-privilege dispatch level to land in.

2. The retail lock, cross-checked against the real log

docs/limits.md (already in the repo, measured in an actual game run, not redone here) gives the authoritative channel table:

Channel Config-gate (CANNOT be set in retail) Cheat-reset (Resetting cheat cvar) Net result
binary.cfg / default.cfg blocks — ✗
+cvar 1 (command line) passes wipes ✗
+set cvar 1 passes wipes ✗
+exec file.cfg (after reset) blocks survives (ran after reset) ✗
+toggle cvar (command line) bypasses survives cvar = 1, but unwired for devgui (F8/F10 do nothing)

This session additionally read the real qconsole.log (<user folder>\Saved Games\MachineGames\Wolfenstein The New Order\base\qconsole.log, 10 182 lines, session of 2026‑09‑22 18:16, the maintainer's own prior run — read-only, not reproduced here) and it corroborates the table exactly:

Command line is: ...WolfNewOrder_x64.exe +com_skipIntroVideo 1 +pm_autoSprint 1
  +com_allowConsole 1 +g_showHud 1 +g_EnableGore 1 +g_bloodEffects 1
  +g_goreBloodyMess 1 +bind F1 "toggle g_permaGodMode 0 1" ...
Resetting cheat cvar: com_allowConsole
Resetting cheat cvar: com_skipIntroVideo
Resetting cheat cvar: g_goreBloodyMess
Resetting cheat cvar: pm_autoSprint

Practical consequence for the loader itself: wolfsdk/cvars.py sets ALWAYS = {"com_skipIntroVideo": "1"} on every TNO launch — but com_skipIntroVideo is in RETAIL_BLOCKED, and the log line above is the measured proof that it gets wiped the same way pm_autoSprint/g_goreBloodyMess did in the same run. The loader's "always skip intro videos" feature does not work on the retail build; the intro plays regardless. This was previously only inferred from the static RETAIL_BLOCKED set — this track ties it to the actual log line. (wolfsdk/mod.py:610-614 already documents, correctly, that it does not attempt the TNC-style cfile-routing workaround for TNO, because docs/limits.md already measured that channel as blocked too — there genuinely is no better delivery route today.)

wolfsdk/cvars.py::COMMANDS lists noclip bound to F3 on every launch (+bind F3 noclip, present verbatim in the Command-line log line above). Table §4 below could not find a clean registration/description pairing for noclip in .rdata (unlike kill/teleport/screenshot, which did). This pass counted every bounded (non-substring) occurrence of noclip\0 in the whole exe: there are exactly 4 — one inside an unrelated animation locomotion-state name list (...combat, run, Excellent, noclip, run, Perfect... at file offset 0xff83b4, clearly an animation-blend tag, not a command), two inside longer sentences where noclip is just the last word of a cvar description (pm_noclipspeed's own description, and g_debugPlayer's — matched only because the byte search doesn't respect string boundaries, not real "noclip"-command hits), and one standalone occurrence in the DevGUI region (0x1038b0c, see §4b) that is not adjacent to the later "No Clip" label either. god\0 similarly exists standalone in exactly one place in the whole binary (0x1038aa4), and it sits between two unrelated strings, not next to the "God Mode" label — whose own action slot instead holds a literal placeholder TEMP 5 (§4b). This is not proof either command is absent from the dispatcher (.text is encrypted; DevGUI row wiring and the console command table are not necessarily the same list) but it is now the strongest static signal in either direction for TNO specifically: notarget has a clean wired pair (§4b), god/noclip do not, in a dataset where "has a clean wired pair" was independently confirmed to track roughly 40+ other genuinely-real commands. docs/limits.md's own session never pressed F3 (tail of the log shows the player quit at the main menu), so this is still untested in-game — see the recipe and §7.

This pass also searched for any further static evidence of whether the DevGUI UI itself (not just the devgui cvar) is reachable in retail: no string resembling "DevGUI is disabled in retail", sv_cheats, com_enableDeveloperMode, or a distinct retail-gate message for DevGUI specifically exists anywhere in the exe (checked by direct bytes.count() grep, same method as §1's resourceExec check). This closes off the cheap static angle without answering the question — it genuinely needs the in-game +toggle devgui / +toggle com_allowConsole test from the recipe.

3. The flag enums (recap, docs/devmodus.md, not re-derived)

CVAR_BOOL 0x1  CVAR_INTEGER 0x2  CVAR_FLOAT 0x4  CVAR_CHEAT 0x8  CVAR_NOCHEAT 0x10
CVAR_INIT 0x4000  CVAR_ROM 0x8000  CVAR_ARCHIVE 0x10000  CVAR_MODIFIED 0x20000
CVAR_MODIFIED2 0x40000

No CVAR_STRING/CVAR_TIME_MS/CVAR_NETWORKSYNC/CVAR_LOCAL_SETTING/ CVAR_SHADERSYNC/CVAR_EXPOSE/CVAR_SHIPPINGDISABLED — all six are TNC-only additions. CVAR_SHIPPINGDISABLED is the best candidate for the flag behind "Attempting to set a developer cvar" in TNC; TNO never grew that flag at all, so by elimination TNO's lock is the plain CVAR_CHEAT bit it shares with TNC's own (separately-still-working) "Resetting cheat cvar" path. This session's own search adds the command-side half: no CMD_* command-flag enum exists in TNO at all — TNC's CMD_NOCHEAT 0x2 / CMD_EXPOSE 0x4 / CMD_SHIPPINGDISABLED 0x8 have zero counterpart. The engine's own reflection-table naming convention is consistent enough (every real enum in this binary prints as EnumName_VALUE in .rdata) that this is a meaningful negative result, not just "didn't look hard enough" — the same convention is exactly how idDeclGameModeSP::FLAG_*, gameDificulty_t, devMode_t, fsPathSearch_t etc. were all found elsewhere in this project's docs.

4. New: a mined TNO command/cvar table from .rdata string adjacency

re_probes/tnoconsole/mine_tno_cmdtable.py (read-only, --self-check verifies 4 known-good pairs against live-mined addresses every run). Method: TNC's own tools/mine_cvars_tnc.py explicitly rejected naive string-adjacency as wrong for that binary (the linker pools literals across many unrelated registrations). For TNO, adjacency turns out to genuinely hold in long, call-order-preserved runs — most likely because MSVC pools a translation unit's literals in first-use order, and TNO's many idCmdSystem::AddCommand/ idCVar constructor calls for one subsystem (AI debug, cvar registration, etc.) sit sequentially in one source file, unlike TNC's more scattered call sites. Verified by three independent, unambiguous spot checks the script's --self-check re-asserts every run:

g_gravity    -> description "control the force of gravity on physics objects", literal '1066'
               (1066 is the real id Tech default gravity magnitude -- not a guess)
g_knockback  -> "control how much the player gets knocked back when damaged", literal '50'
killMonsters -> "removes all monsters"           (a command, no literal -- idCmdSystem::AddCommand)
teleport     -> "teleports the player to an entity location"

Classification: a cvar entry has 1–3 short non-prose literal tokens (a numeric default, sometimes min/max) directly before the name; a command entry has the description immediately before the name with nothing in between. A second filter (is_registrar_desc) rejects DevGUI page-label strings, which are Title Case ("No Target", "Spawn AI") — real idCmdSystem/idCVar descriptions in this binary are uniformly lowercase sentences or start with a digit ("kills the player", "0 = disable DevGUI, ..."). This single filter is what separates the real kill/teleport/screenshot/devmap entries from false DevGUI-button hits for god/noclip/notarget (§2).

Result, run against the live retail exe (pass-2 numbers — see below for what changed):

WolfNewOrder_x64.exe
  .rdata strings       : 207265
  candidate entries    : 2117 (2031 unique names)
  classified as cmd    : 1154
  classified as cvar   : 877
  high confidence (run): 1200   <- part of a chain of >=2 consecutive hits
  rejected (reflection noise, pass-2 filter): 6229

Pass 1's version of this table overstated its own reliability — the verifier independently sampled 15 "high confidence" entries and found only 2 (13%) were genuine; the rest were C++ RTTI/template-reflection strings (idList < int , TAG_SWF >, bare unsigned int/bool) that the original is_registrar_desc filter did not reject, because it only checked Title-Case-vs-lowercase, not string shape. Independently reproducing the verifier's finding this pass: of the original 5026 entries, ≥56.7% (2852/5026) globally and ≥45.1% (1062/2354) within "high confidence" matched one of three mechanical noise shapes (contains < or ::; is a bare primitive-type word like unsigned int/bool; is a compiler debug-tag/path string like w:\tech5\...cpp(1355) : TAG_TEMP). Fixed: is_reflection_noise() rejects all three in mine_tno_cmdtable.py now. Effect: the table shrank from 5026 to 2031 unique names (2117 candidate hits, 6229 rejected as noise); a fresh, differently-seeded 20-entry random sample of the new "high confidence" bucket (1200 entries) found 18/20 (90%) genuine registrations, with the 2 residual false positives being script-literal text (idCQuat paired with an embedded .script snippet) and a node-graph test-harness name (idTypeInfoGraphNodeTest) — a different, smaller, named residual noise category, not hidden. This is a real, large improvement, not a claim of perfection: treat any single value from this table as a lead to verify in qconsole.log, not a certainty, same caveat docs/ladepfade.md already states for its own smaller, hand-picked pool-neighbour reads.

Saved to re_probes/tnoconsole/tno_cmdtable.json (2031 entries: name, description, kind, literals [default/min/max tokens, where present], confidence, offset, va). This is not flags-with-certainty the way the TNC runtime dump is (no live process, no disassembly of the registration call itself — .text is encrypted here too) — it is the TNO equivalent of docs/cvars-tnc.md's token-matched catalogue, one level more reliable because the pairing is true adjacency here rather than a nearest-word-overlap guess, confirmed on real numeric defaults rather than inferred from prose alone.

Two concrete, reproducible counterexamples to the adjacency premise itself (not noise — real strings, just not adjacent to their real partner), found while investigating the verifier's testWeapon finding:

  • testWeapon (file offset 0xff4a50) and its real description "test a weapon model" (0xff49c8) are genuinely not adjacent — three unrelated entries (lists players inventory..., listInventory, listJobs) sit between them. testWeapon is absent from the mined table for exactly this reason, not a tooling bug; the verifier's citation of this was correct, confirmed by independently re-reading the raw bytes.
  • com_production (0x104d308) exists as a standalone string (confirmed by direct grep, resolving the pass-1 "not found" entry), but its plausible description ("Used to enable and/or inhibit specific behaviour during production building mode. All demo and retail builds are built with this on.") sits one slot after its name instead of before it — the slot immediately after com_production actually holds "Exits the process on a com_error.", which reads far more like neighbour com_exitProcessOnError's description. Two adjacent cvars' description slots are swapped relative to what pure positional adjacency predicts — a second, independent, concrete illustration that the linker's literal-pooling order is not reliably call-order-preserving at the single-pair level, even though it holds well in aggregate (confirmed by the ≥1172-entry clean high-confidence set above).

Other caveats, found while building it: common short names (map, toggle) collide with unrelated reflection-table entries (type names, member fields) and the dedup can pick the wrong one of several hits — map resolved to "shows collision model info" instead of its real "loads a map", g_permaGodMode's mined default -20 is implausible for a boolean and is very likely a wrong neighbour grab.

Confirmed real entries directly relevant to unlocking TNO (kind, confidence, mined default, description, cross-checked against RETAIL_BLOCKED/docs/devmodus.md where already known):

name kind default description
com_allowConsole cvar 0 "allow toggling console with the tilde key" — confirms it gates the ~ key itself, nothing else
devgui cvar 0 "0 = disable DevGUI, 1 = enable DevGUI, 2 = enable DevGUI with key legend" (3 modes, matches docs/devmodus.md §5.4)
g_gravity cvar 1066 "control the force of gravity on physics objects"
g_gameDifficulty cvar -1,0 "the difficulty setting for the game, if -1 will not use the cvar but the var in gameLocal currentGameDifficulty ( 0 is very easy and 4 is nightmare )" — the difficulty enum TNO actually uses, spelled out in full (not previously documented)
g_showThinks cvar 0 "show entity thinks. 0 = off, 1 = show and update, 2 = show but don't update"
pm_noclipspeed cvar 0 "speed the player can move while in noclip" — confirms a noclip player-physics mode exists engine-side even though the noclip command itself could not be confirmed (§2)
kill cmd — "kills the player"
teleport cmd — "teleports the player to an entity location"
killMonsters / killAI / killUnhiddenAI / killDeadAI cmd — "removes all monsters" / "kills all AI in the level" / "...that are not currently hidden..." / "...that are dead"
healAI cmd — "heals all AI in the level"
devmap / cmap / devcmap / checkmap cmd — "loads a combo map in developer mode" / "loads a combo map" / same as devmap / "...from checkpoint load"
screenshot / rawscreenshot / envshot cmd — "takes a screenshot" / "...raw frame buffer dump..." / "...environment shot"
tw_save cmd — "writes current testweapon parameters to a config file" (testWeapon itself is a real string pair too — confirmed by direct grep — but not in this mined table; see the adjacency counterexample above)
DebugUnlockPerkByAbility / DebugUnlockPerkByRequirement / DebugLockAllPerks cmd — "adds perk with given ability/requirement ID, -1 unlocks all" / "remove all perks"
cvar_restart cmd — "restarts the cvar system, defaulting all cvars" (low confidence, but matches docs/limits.md's own cheat-reset finding structurally)

None of these carry any flag info in the table (can't — .text encrypted), so whether each one needs an unlocked console is still an open question per §1's core finding: commands have no cheat/expose flag at all in this binary, so the real gate is not "is this command exposed" but "can the dispatcher be reached" — i.e. §7's +bind test.

4b. The DevGUI (Label → Action) row table — missed in pass 1, mined now

The general miner in §4 structurally cannot see this table: its is_registrar_desc filter rejects Title-Case strings to keep DevGUI page/button labels out of the cvar/command catalogue (§4's own stated purpose), but that same filter throws away the actions those labels pair with — a second, separate, smaller linker-pooled string region (one DevGUI row-array literal, file offset roughly 0x1038700–0x103a040) that the original miner never looked at as its own table. re_probes/tnoconsole/ mine_tno_devgui_table.py reads it directly: 117 hand-curated, VA-cited string offsets, each re-read from the live exe and checked verbatim on every run (--self-check, currently OK, 0 mismatches). It does not attempt a general parser (row field count varies — some rows carry an extra TEMP n placeholder slot, child-page rows link to a separately-pooled run of page names, slider rows carry extra bound literals) — that would be speculative struct reverse engineering from strings alone, which is exactly the kind of overclaiming this pass is fixing elsewhere. Instead it folds the 117 entries into 55 clean, unambiguous (label, action) pairs plus 2 flagged "stray" singletons. Full output: re_probes/tnoconsole/tno_devgui_table.json.

Selected pairs most relevant to unlocking TNO (all independently self-check-verified against the live exe, VA = tno_devgui_table.json):

DevGUI label Action string Note
No Target notarget clean pair — resolves §2's open question, positive
Give Grenades give throwable/player/grenade resolves pass-1 "give not found" (R11)
Spawn Imp / Spawn Hellified Soldier / Spawn Mini Gunner / Spawn Zombie spawn zion/ai/imp/demon_imp / spawn zion/ai/hellified_soldier/hellified_marine_rifle / spawn zion/ai/minigunner/gunner1 / spawn zion/ai/zombie/fast spawn <entityDef path> is real and takes a full asset path, not a bare name — pass 1's "spawn not found" was a tooling miss the same way give was
Remove AI killMonsters corroborates §4's mined entry via an independent source
Suicide killPlayer %d distinct from kill (§4) — kills the player by index, not the console-caller
Set Team Red / Set Team Blue changeTeam 1 / changeTeam 2 previously undocumented command
No Player Death NoPlayerDeath previously undocumented command
Infinite Ammo toggle g_infiniteAmmo corroborates the cvar name already in RETAIL_BLOCKED-adjacent discussion
Pause AI / Show AI Bounds / Show AI Path toggle ai_enable / toggle ai_drawBounds / toggle ai_debugMove previously undocumented ai_* toggle cvars
ScreenShot screenshot corroborates §4's mined entry (and directly contradicts the verifier's observation that the general miner's own backward-adjacency pairs ScreenShot with the unrelated toggle r_showSkel 0 1 2 — that mispairing is in tno_cmdtable.json's classification, not in this forward-read table)

Two strays, exact-offset-verified, not part of any clean pair:

  • god — standalone string at VA 0x14103a0a4, the only occurrence of the bare word anywhere in the exe. Sits between toggle g_showEntityInfo 0 1 and Show Entity Warnings — adjacent to neither. The DevGUI row that is explicitly labelled God Mode (VA 0x14103a2e8) has its action slot filled with the literal placeholder TEMP 5, not a command string — one of 7 TEMP 1..TEMP 7 stub slots in this table, a concrete, verifiable sign this row shipped non-functional in retail. This does not prove the god console command is absent (DevGUI row wiring and the dispatcher's command table are not provably the same list from statics alone), but it is stronger, more specific negative evidence than pass 1's "ambiguous" hedge.
  • noclip — standalone string at VA 0x14103a10c (inside the Time-Scale row group, between Slow Time and timescale .1), not adjacent to the later No Clip label (VA 0x14103a320), whose own neighbours are unrelated strings too. Same hedge as god.

5. The script-VM route — the actual TNO analogue of TNC's kiscule bypass

docs/moddingflaeche-tno.md §4.2 already flagged TNO's SuperScript VM (.script files, 913 native scriptEvent signatures in script/script_events.script) as "the by far most powerful unused lever" for gameplay cheats, but only in terms of entity-level natives (giveInventoryItem, setHealth, ...). Read in full this session (python -m wolfsdk --title tno cat "file:script/script_events.script", 6 744 lines, read-only, cross-checked by grep for console/cvar):

// Sets a cvar.
scriptEvent void setcvar( string name, string value );

// Returns the string for a cvar.
scriptEvent string getcvar( string name );

// executes a console command
scriptEvent void executeCommandText( string command );

executeCommandText is a script-callable wrapper around exactly the kind of function TNC's idCmdSystemLocal::AppendCommandText/ ExecuteCommandText belongs to (same naming family across the id Tech 4/5/6 lineage, independently confirmed present under that exact name in TNC by r4/r5) — a native that queues or runs a command string from inside the game's own logic layer, not from the player's console. The same file's auto-generated entity-class-hierarchy comment block additionally lists idTarget_Cvar alongside ~800 other idTarget_* classes (idTarget_ChangeMapFlag, idTarget_Damage, etc. — the standard trigger-target entity family) — an entity class that most plausibly sets a cvar when triggered, placeable from a .entities file with no script required at all. No shipped entityDef decl named target_Cvar was found (wolfsdk --title tno list --type entityDef | grep -i cvar → empty), so it would have to be spawned by raw classname inside a hand-edited .entities file rather than referenced by decl name — consistent with it being an editor-only/internal class MachineGames never shipped a decl wrapper for.

This is the structural counterpart of r5's TNC finding — a game-logic execution path for command/cvar text that docs/limits.md's five tested channels (command line, two config-file variants, post-reset +exec, +toggle) never covered, because none of them is "a trigger fires inside a loaded map". Whether it is actually privileged (reaches the dispatcher the same way command-line text does, bypassing the config-file-source check from §2) or just as blocked as every other channel is unproven — .text is encrypted, there is no way to trace what executeCommandText/setcvar call into statically, and this agent cannot launch the game to find out. It is, however, the single cheapest, most concrete new lead this track produced: one line in an existing map's .script (c02p0.script-style, 415 bytes, already quoted whole in docs/moddingflaeche-tno.md) is enough to test it.

PROVEN (this track, static evidence only — no game was launched)

  • resourceExec does not exist in TNO as a string, anywhere in the exe (0 of 26 345 040 bytes match). TNO's single exec <file> [-s] command is used for every cfg, loose and (nominally) archived alike — unlike TNC, which needed a second verb because its default.cfg moved into an archive and TNO's never did.
  • No CMD_* command-flag enum exists in TNO (CMD_NOCHEAT/CMD_EXPOSE/ CMD_SHIPPINGDISABLED are TNC-only, confirmed by targeted string search; only unrelated AWCMD_*/UCMD_* names present).
  • com_allowConsole's real in-binary description ("allow toggling console with the tilde key") and default (0) are now directly mined, not just inferred from its address — corroborates docs/devmodus.md's identification.
  • devgui's 3-mode description is now directly mined, matching docs/devmodus.md §5.4 exactly.
  • The real qconsole.log from the maintainer's own prior run shows com_skipIntroVideo — which wolfsdk/cvars.py::ALWAYS adds on every TNO launch — being wiped by the cheat-reset in that exact run; the loader's "always skip intro" feature does not take effect on retail.
  • A static registration-table scan for com_allowConsole (the same method tools/probe_cvars.py was written for) finds zero 8-byte pointer references to its name string anywhere in the file — confirming (same dead end TNC's mine_cvars_tnc.py already documents for its own binary) that TNO's cvars are registered by code, not a static data table, so per-cvar flags cannot be recovered from .rdata/.data alone for either game.
  • script/script_events.script declares setcvar/getcvar/ executeCommandText as callable natives, and idTarget_Cvar exists in the engine's entity class hierarchy.
  • (pass 2) The mined command/cvar table's original noise rate was independently re-measured at ≥56.7% globally / ≥45.1% within "high confidence" (reflection/RTTI strings misclassified as descriptions); a mechanical fix (reject </::/bare-type-word/.cpp( strings) cut a fresh 20-sample high-confidence noise rate to 2/20 (10%). Table now 2031 entries (was 5026).
  • (pass 2) testWeapon's name and real description are confirmed genuinely non-adjacent in .rdata (3 unrelated strings between them) — a real counterexample to the adjacency method, not a tooling bug. com_production exists as a standalone string (resolves pass-1's "not found") but its plausible description sits one slot after it instead of before — a second, independent non-adjacency case.
  • (pass 2) The DevGUI (Label→Action) row table (file offset 0x1038700–0x103a040) is a separate, cleanly-structured region the general miner cannot see; 55 clean pairs read and self-check-verified, including previously-undocumented real commands notarget, give throwable/player/grenade, spawn <entityDef path> (4 variants), killPlayer %d, changeTeam 1/2, NoPlayerDeath, and 25+ toggle <cvar> pairs (ai_enable, ai_drawBounds, ai_debugMove, g_infiniteAmmo, g_debugWeapon, g_showSpread, g_weaponkick, g_tracePlayerDamage, g_showCollisionWorld/Models/Surfaces, r_showDynamicLighting/ AmbientLighting/SurfaceInfo/Tris/Trace/WorldAreas/DuplicateTriangles/ Cracks/Skel, com_showMemoryUsage, com_speeds, hands_show, con_noPrint). god and noclip each exist as a single unpaired string in this region, neither next to a matching label; the God Mode row's action slot holds the literal placeholder TEMP 5 instead of a command.

INFERRED (plausible, not measured)

  • TNO's command dispatcher is architecturally ungated (no flag to check) — inferred from the absence of a CMD_* enum, not from a positive trace of the dispatcher itself.
  • setcvar/executeCommandText, called from a map's .script, would reach the dispatcher through a channel the config-file-source check does not see, the same structural shape as TNC's proven kiscule bypass (r5) — plausible by analogy, not demonstrated for this engine.
  • +toggle com_allowConsole on the command line would, like +toggle devgui, bypass both the config gate and the cheat-reset and leave com_allowConsole at 1 — extrapolated from the one measured +toggle case in docs/limits.md; untested for this specific cvar.
  • +bind <key> <command> (already proven accepted on the command line, +bind F3 noclip from the real log) would call kill/teleport/devmap/ etc. ungated, since no flag exists to gate it — follows from the §3/PROVEN absence-of-flag finding, not from having actually pressed such a key in game.

Failed hypotheses / dead ends (this track)

  • Naive probe_cvars.py pointer scan for a static cvar-flags table: zero references found for com_allowConsole's name string anywhere in the binary. Dead end, same shape as mine_cvars_tnc.py's own documented dead end #2 for TNC — confirms (does not newly discover) that registration is code-driven, not data-table-driven, in both games.
  • String adjacency for god/noclip specifically (revised pass 2 — notarget is now resolved positive, see §4b, removed from this list): god and noclip each exist as exactly one standalone string in the whole exe, in the DevGUI region, neither adjacent to a matching label — genuinely "not found as a clean wired pair", not a tooling gap, though still not proof of absence from the console dispatcher specifically (DevGUI row wiring and the dispatcher's command table are not provably the same list from statics alone).
  • com_enableDeveloperMode, devMode_*, sv_cheats, fs_overlaypath in the mined adjacency table: still not found by this method this pass either (either genuinely absent, like the devMode_* family already proven absent in docs/devmodus.md, or present but paired differently than this heuristic expects — fs_overlaypath is known present from docs/ladepfade.md's own, differently-targeted probe, so its absence here is a tooling miss, not a new negative finding). com_production moved to PROVEN (confirmed present by direct grep, §4). give/spawn moved to PROVEN (confirmed present and DevGUI-wired, §4b) — both were a tooling miss (combined verb+argument literals, not bare verb tokens), not genuine absences; this was pass 1's R11/part-of-R12 error, now fixed.

Concrete recipe for the maintainer

  1. Cheapest, zero-build test — confirm or kill the "commands are ungated" hypothesis (§3): launch with several +bind <unused key> <command> pairs, mixing §4b's DevGUI-confirmed-wired commands (higher prior) with the two still-ambiguous ones, no mod needed, pure command line:

WolfNewOrder_x64.exe +bind F5 god +bind F6 kill +bind F7 notarget +bind F8 "give throwable/player/grenade" +bind F9 killMonsters notarget/give .../killMonsters are DevGUI-wired real strings (§4b) — if they fire, that's a strong, near-certain confirmation TNO's command system has no exposed-list restriction at all (the single biggest practical difference from TNC this track found); god/kill are the still-open ones this same test resolves for free. 2. +toggle com_allowConsole (command line, no mod): if it survives the way +toggle devgui did, the ~ console itself opens, and every command in §4/§4b's tables becomes directly typeable — turning "is noclip/god real" from a guess into a one-line console check. 3. Script-VM route (the real unlock candidate, §5): take the existing 415-byte c02p0.script quoted whole in docs/moddingflaeche-tno.md §4.2, add one line to main():

c void main() { executeCommandText( "god" ); } or, to test the cvar side directly: setcvar( "g_infiniteAmmo", "1" );. Needs a full chunk rebuild (c02p0.script's csize budget is 0 bytes per docs/moddingflaeche-tno.md §4.1 — wolfsdk's existing rebuild path handles this, same as any other full-chunk patch already proven for TNC map assets). This is the one experiment in this report that would actually answer the open question, and it is well within what the loader's existing .script/archive-rebuild tooling already supports.

Open questions

  • Does +bind <key> <command> actually reach the dispatcher ungated, or is there a gate this static read cannot see (encrypted .text)? → recipe #1.
  • Does +toggle com_allowConsole actually open the console the way +toggle devgui set the cvar? And if it does, is the console UI itself compiled into the retail build, or stripped the way DevGUI's F8/F10 functionality was (cvar set, no effect)?
  • Do setcvar/executeCommandText, called from a map script, run through the same config-file-source check that blocks default.cfg, or through the unrestricted command-line-equivalent path? This is the TNO question that actually matters most and is the least answerable without a build+launch.
  • Is noclip/god registered at all in the retail command table, or stripped the way TNC's own give/spawn/noclip/SpawnAI are? (notarget is now resolved positive, §4b — this question narrows to just these two.) pm_noclipspeed existing as a real cvar is weak evidence for a noclip mode existing engine-side, but says nothing about whether the command survived into retail, and the God Mode DevGUI row's TEMP 5 stub (§4b) is new, mildly negative evidence for god specifically.
  • Is DevGUI UI reachability (not just the devgui cvar value) possible in retail by any means? Searched again this pass for static evidence (no distinct retail-gate string found, §2) — still open, still needs the in-game +toggle devgui test; if reachable, §4b's full 55-pair table becomes a ready-made cheat menu with zero further guessing.

Smallest in-game test

(Translated from German.)

Without any mod, only start arguments, two minutes:

WolfNewOrder_x64.exe +bind F5 god +bind F6 notarget +bind F7 "toggle com_allowConsole 0 1" +bind F8 "give throwable/player/grenade" +bind F9 killMonsters

Start the game, load a save (or stay in the main menu), then press F7, then F5, F6, F8, F9 in order. Meanwhile keep an eye on qconsole.log (%USERPROFILE%\Saved Games\MachineGames\Wolfenstein The New Order\base\qconsole.log) or search it afterwards:

  • notarget (F6), give throwable/player/grenade (F8) and killMonsters (F9) are confirmed since this second pass as real command strings hard-wired in the DevGUI (section 4b) — if no Unknown command line appears after these keys, that is the strongest confirmation so far that TNO commands are generally ungated.
  • If no Unknown command line appears after F7 and the console can then be opened with the tilde key (^/~) → com_allowConsole can be set via toggle, exactly like devgui in docs/limits.md. Then type god, notarget, noclip one at a time in the console and watch whether Unknown command comes or not — that answers in one go which of the commands found in this report really exist.
  • If an "invulnerable" state appears after F5 (e.g. no damage from a hit) or a log line without Unknown command 'god' → the god command exists and is reachable ungated via +bind, without an open console — that would be the simplest unlock route this report has found, and would confirm the central assumption from section 3/PROVEN ("commands carry no cheat flag at all in TNO"). Note: god is less well supported than notarget/give/killMonsters (section 4b — the corresponding DevGUI row "God Mode" only has the placeholder "TEMP 5" instead of a real command), so do not be surprised if this one in particular does not fire while the other four do.
  • If instead Unknown command 'god' or similar comes → the command does not exist in this form in retail (like give/spawn/noclip/SpawnAI in part 2), and the next lead is section 5 (script VM, executeCommandText/setcvar) — but that would need a map build of its own, no longer a pure start test.

Back up saves first (checkpoint.dat, profile.bin, progression.bin) — unclear whether TNO, like part 2, permanently marks saves when entering a cheat state; not yet checked for part 1.

Reproducibility

python re_probes/tnoconsole/mine_tno_cmdtable.py --self-check
# WolfNewOrder_x64.exe
#   .rdata strings       : 207265
#   candidate entries    : 2117 (2031 unique names)
#   classified as cmd    : 1154
#   classified as cvar   : 877
#   high confidence (run): 1200
#   rejected (reflection noise, pass-2 filter): 6229
#   self-check: OK
#   wrote re_probes/tnoconsole/tno_cmdtable.json (2031 entries)

python re_probes/tnoconsole/mine_tno_devgui_table.py --self-check
# DevGUI (label, action) table -- 117 curated entries, 55 clean pairs
#   ... (55 pairs printed, see §4b)
#   self-check: OK
#   wrote re_probes/tnoconsole/tno_devgui_table.json (117 entries)

Related: Research Report: R7 Tno Cheat Gate, Research Report: R7 Tno Commands, Developer Mode, Modding Limits, Asset Loading Paths, TNC CVar Catalog, TNO Modding Surface, TNO CVar Catalog.