Skip to content

Research Report R6 Photo Camera

LopeKinz edited this page Oct 4, 2026 · 1 revision

Photocam: A Free Camera / Photo-Mode Cfg and Keybind Set for The New Colossus

Round-6 research pass on screenshots and machinima in The New Colossus: everything usable as a free camera or photo mode — commands, cvars, kiscule camera nodes and camera entities — and which of it a retail build can reach. The game ships a real, named photo-mode toolkit (g_setting_photomode, a free-camera/time-freeze cluster, depth-of-field, post-FX, HUD and screenshot-quality cvars); some of these cvars are already exposed to the plain console, the rest are cheat-flagged and need the already-proven resourceExec <cfile> -s route. A key bound directly to a non-exposed command does not work, so the recipe binds keys to resourceExec carrier cfgs instead. Static analysis only; the cfg and keybind set has not been run in game.

Read-only on the game installs and on every project file outside this track's own folder (re_probes/photocam/) and this report. Builds on, and does not redo, re_probes/agent_reports/r4_consolecmds.md (the restriction-level gate, the resourceExec level-0 window, the DevGUI call-graph) and r5_kisculecmd.md (kiscule idKisculeNodeCommand's Exec path, the per-frame drain). Ground truth for every cvar/command claim below is re_probes/cvartable/cvars_tnc_v2.json (3256 cvars, live-snapshot-verified) and re_probes/cmdtable/commands.json (234 commands) — not the string-mined candidate lists in docs/cvars-tnc.md/docs/cvars_tnc.json, which that doc's own header says are only ~10% real names. New disassembly this track did itself: RVA 0xaa8780 (key-bind execution) via tools/decomp.py, cross-checked against re_probes/runtime_87400/module.bin. No game was launched, no debugger attached. Every cvar/command/node fact cited below is re-derived and asserted by re_probes/photocam/verify.py (run: python re_probes/photocam/verify.py, prints ALL OK) straight from the ground-truth JSON tables and docs/ghidra/rtti_tnc.json — a mismatch there is this report's own negative control.

Pass 1 errors (fixed in this pass)

The verifier found 8 real problems and 2 missed items in pass 1. Fixed here, each re-asserted mechanically by the updated re_probes/photocam/verify.py (ALL OK):

  1. Headline gap: g_setting_photomode was never in the recipe. The report's own best-named discovery was absent from photomode_enter.cfg/ exit.cfg and from the in-game test plan. Fixed: added to both cfg files and to §12 as its own isolated "Ziel 0" test (test it alone first, since its effect beyond its own description is unproven).
  2. Recipe no-op: photomode_enter.cfg set pmec_ForceShowThirdPersonBody 0, which is that cvar's own documented default — a dead line. Fixed: flipped to 1 (a real change, untested effect), pmec_EnableThirdPersonBody left alone at its own default.
  3. TNO candidate g_debugCam was fabricated — no such name exists in tno_cmdtable.json, the report's own cited source. Fixed: replaced with the one real entry, ai_debugCam. (Re-checked the verifier's own suggested addition, debugCam as a "kind=cmd" entry — it does not exist in tno_cmdtable.json either, under any case; dropped rather than re-added unverified.)
  4. TNO thirdperson family misspelled: written as pm_thirdPerson_Height/_Angle/_Clip (implying an underscore); the real mined names have none — pm_thirdPersonHeight/Angle/Clip. Fixed, with each entry's own actual mined confidence (Height=high, Angle=low, Clip=low), kept separate from the correctly-named pm_thirdPersonRange.
  5. Negative-control overclaim: "god (lowercase) ... absent ... under any case" is false under a literal reading — capitalized God is a real, non-exposed command. The report's own body text already treats God correctly elsewhere (§1/§2/PROVEN, non-exposed, resourceExec-only, same as Notarget) — the verifier's framing that God is "EXPOSEd" is itself wrong (commands.json: God.exposed == False). Fixed: reworded to state what was actually checked (no separate lowercase/synonym command), and verify.py now asserts this case-insensitively instead of only by exact string.
  6. 0xf515b0 scope undercount: reported as shared by "three unrelated BOOL cvars"; a full-table scan shows 1136 of the engine's 1138 total bool-type cvars share it. Fixed: §2 and PROVEN now state the real scope (which strengthens the "generic validator" conclusion), verify.py now asserts the full-table count.
  7. verify.py coverage gap: 10 cvars cited in §4's own tables (g_setting_hudNotifications, g_setting_hud_show, g_showPlayerInfo, p_allowPlayerWeaponFarDOF, r_chromaticAberrationLimit, r_cutsceneRender, r_dofDebug, r_motionBlurQuality, r_screenshotTag, view_dofBlendIn) were missing from verify.py's own list, so "re-derives and asserts every fact" was an overclaim. Fixed: added (all 10 matched the report's stated values — no factual error, just a coverage gap).
  8. 105-vs-113 kiscule unused-class inconsistency, flagged but not resolved in pass 1: diffing RTTI's idKisculeNode* classes (excluding the per-node *Parameters/*Parameter companion structs, which are not node types) against catalogue.json's used(205)+unused_node_classes(105) sets finds exactly 8 real node classes present in RTTI but missing from both — the idKisculeNodeParameterListOperator* family (GetIndexInt/ Bool/String/EntityReference, AddItemInt/Bool/String/ EntityReference). 105 + 8 = 113: docs/kiscule.md's figure was right, catalogue.json's own field undercounts by exactly these 8 (not fixed — outside this track's read-only scope; §6 now states this precisely instead of silently citing 113).
  9. Missed: the DevGUI route's one real in-game data point. Project memory tnc-console-unlock.md already recorded, from the one actual resourceExec test, "devgui 4 showed no window (open)" — photomode_extras.cfg's toggle devgui 0 4 comment presented the "~50 buttons" route as working without surfacing this. Fixed: added as an explicit caveat in the cfg file and §9/§10.
  10. Missed: the TNO ScreenShot (CamelCase) candidate's mined description ("toggle r_showSkel 0 1 2") is an unrelated string-mining pairing artifact, not a real screenshot-command description — flagged now in §8 as a data-quality caveat on that table, since this report leans on exact description overlap as its TNO corroboration method.

Not changed: the verifier's f515b0/113-vs-105/god observations were independently re-derived above and matched (where the verifier's own stated premise was itself slightly off, e.g. God's exposed flag, this section says so rather than copying it).

Question

TNC screenshots/machinima: everything usable as a free camera or photo mode — camera-related commands/cvars (timescale/pause/freeze, third person, free fly, detach view, viewpos setters like teleport/setviewpos, HUD/viewmodel/ crosshair off, DOF control), kiscule camera/cinematic nodes and camera entities. What works in the retail build (registered + reachable via resourceExec -s or kiscule), and the best possible photo-mode cfg set + key binds.

Answer (short)

The retail build already ships a real, named photo-mode toolkit — it is just locked behind the same console gate r4_consolecmds.md already broke. g_setting_photomode ("enable/disable photomode"), a g_stopTime/ g_freezeTime/g_runFrames/g_freeCamSpeed/cam_cutsceneFreecam free-camera cluster, a full depth-of-field cluster (r_dof* plus a manual com_overrideDOF/com_override_dof_* focus-plane override), a post-FX cluster (r_motionblur, r_vignette, r_filmGrainRatio, r_chromaticAberration, r_hdrShutterSpeed/r_hdrAutoExposure*), a HUD/crosshair/GUI-visibility cluster, and a screenshot-quality cluster (com_captureSamples/com_captureTGA/image_screenshotQuality/ r_screenshotBatchSize) all exist as real, registered cvars (full tables in §4, cross-checked against the 3256-cvar runtime table). A good number of them are already EXPOSEd (g_fov, r_dof, r_dofTAA, r_motionblur, r_motionBlurQuality, r_filmGrainRatio, r_chromaticAberration, r_hdrShutterSpeed, g_showHud, g_showGuis, hud_disableAll, g_showPoiInfo, com_captureFilename/Path/Samples/TGA — 16 cvars, §4 marks each direct) and work from the plain, unmodified console today, no mod needed. The rest — the free-camera cluster itself, g_setting_photomode, crosshair, r_vignette, DOF overrides, screenshot quality, devgui, timescale — are CHEAT-flagged and non-exposed, so they need the already-proven resourceExec <cfile> -s route (project memory tnc-console-unlock.md: runtime-proven 2026-10-01, God/Notarget/ g_infiniteAmmo 1/snapEdit_devMode 1 all executed from a loader-replaced snapdemo.cfg). mods/sandbox_tools/mod.json, already in this repo, demonstrates the exact pattern a photo-mode keybind needs and is itself proven in game: bind F6 "resourceExec snapdemo.cfg -s" — God/infinite ammo confirmed working from a single keypress, no console typing at the moment of the press.

This track's own contribution, new this run: (1) disassembled the key-bind execution function (RVA 0xaa8780) and found it forces the restriction level to 1 for the duration of queuing a bound key's command — unlike kiscule's idKisculeNodeCommand (r5), a key bound straight to a non-exposed cvar will not work; it only works when the bound command is itself exposed, or is resourceExec <file> -s (itself exposed, and which internally re-opens level 0 for its own file — exactly what sandbox_tools already relies on). (2) Found that wolfsdk/mod.py's with_tnc_tweaks() / cvars.split_tnc() already implement a second, automatic delivery route for every one of these cvars: append them as plain lines to cfile: default.cfg, which the engine itself resourceExecs at init at level 0 (idCommonLocal::Init(), r5 §3) — built, round-trip-verified in copies (tools/verify_tnc_tweaks.py, 17/17), but not yet confirmed in a running game (TODO.md, 2026-10-01: "im Spiel unbestätigt", i.e. "unconfirmed in game"). (3) Confirmed the cfile AES-128-CBC encryption is fully solved (wolfsdk/tnccrypt.py, re_probes/agent_reports/cfilekey2.md) and a from-scratch carrier with arbitrary text content and an arbitrary resource name is already built and verified (tools/build_exec_carrier.py) — a photo-mode cfg is not limited to reusing the two unused stock files sandbox_tools found. (4) Surveyed kiscule's camera-adjacent node types (idKisculeNodeActionTeleport 126×, ActionFadeView 55×, ActionRumbleCam 35×, ActionGlobalCameraShake 1×, the ActionMidnightControl/OpMidnightParametersControl cutscene-camera system 958× each) and TNC's compiled-in camera entity classes (idFreeCamera, idUtilityCamera, idSpringCamera, idCinematicCamera, idDeclCameraTrigger, …) — real, RTTI-confirmed, but map/entity placement of these is untested, out of this track's scope. (5) TNO (id Tech 5) has no runtime image; its camera cvars below are string-mined candidates only from a sibling, in-progress track (re_probes/tnoconsole/tno_cmdtable.json), cross-validated only by exact name/description overlap with TNC's proven real cvars — presented clearly labelled, nothing claimed as proven for TNO.

1. The gate, in one paragraph (full mechanism: r4/r5)

One process-wide integer, the "restriction level" (RVA 0x41244d8, idCmdSystemLocal/idCVarSystemLocal shared field +0x200b8). Level 0 = dispatcher (0x1265150) searches all 234 commands/3256 cvars; level 1 = only the 34 exposed commands/304 exposed cvars. It rests at 0 almost all of the time; the console, +args, exec, and the key-bind executor (§2, new this run) each force it to 1 for the duration of one line/keystroke, then restore it. resourceExec <cfile> -s (itself one of the 34 exposed commands) is the one reachable command that forces it to 0 for the duration of the whole file, so every line inside that file — command or cvar, exposed or not — resolves against the full catalogue. Runtime-proven (project memory tnc-console-unlock.md): a loader-replaced snapdemo.cfg run with resourceExec snapdemo.cfg -s printed godmode ON for player 0 / notarget ON for player 0, no "Unknown command", for names absent from the 34-exposed list.

2. New this run: a key bound to a non-exposed command does not work directly

The task asked specifically for key binds, which neither r4 nor r5 settled (r5 explicitly left "does a bound key execute like a kiscule node, or like console input" open). Found it: RVA 0xaa8780 (tools/decomp.py 0xaa8780, called from only one place, 0x11bbe90/0x11bc25f+0x11bc278 — a large input-event function) is the key-bind lookup-and-execute function. Its body:

iVar3 = DAT_7ff6303344d8;              // save old restriction level
... set DAT_7ff6303344d8 = 1 ...       // RVA 0x41244d8 -- the SAME level global r4/r5 use
iVar4 = FUN_7ff62ccb4650(param_1, param_2, param_3);   // resolve key -> binding-table index
for (bound-command list at that index) {
    if (bindset byte matches param_4) {
        if (bound command string is non-empty) {
            AppendCommandText(bound_text);   // via the same devirt-inline pattern as r5 S2
            AppendCommandText("\n");
            ...
        }
        break;
    }
}
...
DAT_7ff6303344d8 = iVar3;              // restore old restriction level

DAT_7ff6303344d8 is confirmed to be exactly RVA 0x41244d8 (0x7ff6303344d8 - 0x7ff62c210000 = 0x41244d8, the live snapshot's image base). This is the identical save/set(1)/restore bracket r4 found for console input, +args, and exec — not the unbracketed-at-ambient-level pattern r5 found for kiscule Command nodes and DevGUI. Consequence: a key bound with bind <key> "<text>" executes <text> at level 1 when pressed, so it only reaches the 34 exposed commands / 304 exposed cvars directly. Binding a key straight to g_freezeTime 1 (non-exposed) will print "Unknown command" the moment the key is pressed, exactly as if it had been typed at the console.

The workaround is the one mods/sandbox_tools already uses and already proved in game: bind the key to resourceExec <file> -s instead. resourceExec is exposed, so it passes the key-bind's level-1 window; its own callback (r4 §3, re-confirmed by r5 §2.1) then force-sets level 0 for the duration of <file>, so every line inside that file — however non-exposed — executes. mods/sandbox_tools/mod.json's own description: "F6 toggles God mode, Notarget and infinite ammo [...] God and infinite ammo are confirmed in game." This is the mechanism §9's recipe is built on.

(0xf515b0, the callback_rva that g_setting_photomode, g_freezeTime, g_debugRenderForceDepthTest all share in the cvar table, turned out to be the generic CVAR_BOOL value-validator, not a "photomode-changed" side-effect handler: its disassembly only compares the new value string against "0"/"1". Correction (pass 1 said "three unrelated BOOL cvars"; a full scan of all 1138 bool-type cvars in the table shows 1136 of them — 99.8% — share this exact callback_rva. It is not a coincidental 3-way share, it is the near-universal BOOL validator; the three named above are unremarkable members of that set. This strengthens the "generic validator, not photomode-specific" conclusion rather than weakening it. Ruled out as a lead, recorded so a later track does not re-walk it.)

3. New this run: cfile:default.cfg already has a built, automatic delivery path

wolfsdk/mod.py (with_tnc_tweaks, TNC_DEFAULT_CFG, _tnc_tweaks_cfile) and wolfsdk/cvars.py (split_tnc, blocked_for("tnc", key) against docs/cvars_tnc_exposed.json, the same 304-name set as cvars_tnc_v2.json's exposed=True rows) already implement: read the retail cfile:default.cfg (decryptable — see below), append every non-exposed tweak as a plain name value line after the retail text, re-wrap and re-encrypt, deploy as one more mod asset. Because the engine itself execs default.cfg at level 0 inside idCommonLocal::Init() (r5 §3, confirmed disassembly), every line added this way runs unfiltered, automatically, at every single launch — no console typing, no key press. This is already wired into WolfSDK Studio's generic TNC cvar-tweak page (_tnc_catalog() loads every name from docs/cvars_tnc.json by prefix; g_→"Game & Cheats", r_→"Renderer", etc. — every cvar in this report's tables is settable there today, though that page's own default-value labels come from the unreliable mined candidate list, not the verified table this report uses).

Caveat, stated plainly: this specific route (cfile:default.cfg auto-applied tweaks) is built and round-trip-verified on copies (tools/verify_tnc_tweaks.py, 17/17 cvars, bit-exact archive round trip, negative control: an all-exposed tweak set never touches the archive) but "im Spiel unbestätigt" (TODO.md, 01.10.2026) — not yet confirmed in an actual running game, unlike the resourceExec <file> -s-at-runtime route (§1/§2), which is runtime-proven. The two routes share the same underlying mechanism (an engine-exec'd cfile at level 0) and the same crypto, so a failure in one would be surprising given the other works — but this track did not launch the game to close that gap itself (out of scope, read-only).

The crypto itself (wolfsdk/tnccrypt.py, re_probes/agent_reports/cfilekey2.md, not this track's own work but load-bearing for the recipe below): cfile payload = u32 declen | 12B salt | 16B IV | AES-128-CBC ciphertext (PKCS7) | 32B HMAC-SHA256 tag; digest = SHA256(salt || "swapTeam\n\x00" || resource name), AES key = digest[:16], HMAC key = digest. Solved and round-trip proven against all 67 retail cfile payloads. tools/build_exec_carrier.py already builds and verifies a brand-new named cfile resource (wolfsdk_test.cfg, arbitrary text "map game/dlc/c02/c2v1_custom\n") in a synthetic DLC chunk that resourceExec would find — so a photo-mode .cfg is not limited to the two unused stock files (snapdemo.cfg/snapedit.cfg) sandbox_tools reuses; it can be its own, clearly-named resource.

4. TNC photo-mode cvars — the full confirmed set

All 39 rows below exist in re_probes/cvartable/cvars_tnc_v2.json (live 19-process-snapshot, 3256/3256 cross-checked against listCvars), not the unreliable mined list. "Route" = how the value reaches the game: direct = already exposed, works from the plain console/+arg today; resourceExec = needs §1's level-0 window (one-off via console, or automatically via §3's default.cfg route for a value that should hold for the whole session).

4.1 Free camera / time control

cvar flags exposed default description route
g_setting_photomode 0x9 BOOL|CHEAT no 0 "enable/disable photomode" resourceExec
g_stopTime 0xa INT|CHEAT no 0 1 = stop entity updating, player still runs around; 2 = stop all entity updating, including player — uses free cam resourceExec
g_freezeTime 0x9 BOOL|CHEAT no 0 1 = stop all game time and go into free camera mode resourceExec
g_runFrames 0xa INT|CHEAT no 0 step N frames while g_stopTime is set, then stop again — single-frame advance resourceExec
g_freeCamSpeed 0xc FLOAT|CHEAT no 0.015 how fast the free cam moves resourceExec
cam_cutsceneFreecam 0xa INT|CHEAT no 0 0 = normal debug free cam, 1 = use the cutscene camera to set up camera effects (DOF etc.) while in freecam, 2 = cutscene setup excluding FOV & DOF resourceExec
g_cameraPlayerHack 0x9 BOOL|CHEAT no 0 force player 0 for camera (useful in a multi-actor/spectator context) resourceExec
timescale 0xc FLOAT|CHEAT no 1 scales time; clamped 0.1–10.0 in the cvar record itself resourceExec
g_debugPlayer 0xa INT|CHEAT no -1 "Player for debug commands like noclip. If -1, uses the local player" resourceExec
pm_noclipspeed 0xc FLOAT|CHEAT no 10.0 noclip movement speed — the cvar exists, confirming a noclip mode is compiled in, but no noclip command exists (r4, re-confirmed §8); how it is toggled is an open question resourceExec
pm_noclipfriction 0x200c FLOAT|CHEAT|NETWORKSYNC no 12.0 noclip friction resourceExec

4.2 Third-person body

cvar flags exposed default description route
pmec_EnableThirdPersonBody 0x9 BOOL|CHEAT no 1 enable the 3rd-person body resourceExec
pmec_ForceShowThirdPersonBody 0x9 BOOL|CHEAT no 0 always draw the 3rd-person body resourceExec

No pm_thirdPerson/pm_thirdPersonRange-style full third-person camera cvar was found registered in TNC (unlike TNO, §8) — these two only govern whether the player's own body mesh is rendered (useful for shadow/reflection correctness and for a photo where the player must be visible), not necessarily a behind-the-shoulder camera mode. Whether TNC has a genuine third-person camera mode at all is an open question (§11).

Recipe note (pass 1 fixed a no-op here, §9): pmec_ForceShowThirdPersonBody's own default is 0, so a recipe line setting it to 0 does nothing. The useful flip for a detached free camera (g_stopTime 2) that should be able to see the player's own body is pmec_ForceShowThirdPersonBody 1 — photomode_enter.cfg now sets this; pmec_EnableThirdPersonBody is left at its own default (1, already enabled). Whether this actually makes the body visible to the free cam is untested (INFERRED, §10/§12).

4.3 HUD / crosshair / GUI visibility

cvar flags exposed default description route
g_showHud 0x210011 BOOL|NOCHEAT|ARCHIVE|EXPOSE yes 1 enables drawing of HUD elements direct
g_showGuis 0x210011 …|EXPOSE yes 1 enables drawing of GUI elements other than HUD direct
hud_disableAll 0x210011 …|EXPOSE yes 0 disables HUD rendering outright direct
g_showPoiInfo 0x210011 …|EXPOSE yes 0 POI/objective markers (leader, base, flag) direct
g_showCrosshair 0x9 BOOL|CHEAT no 1 if true, draw the crosshair resourceExec
g_showPlayerInfo 0x9 BOOL|CHEAT no 1 player name/health HUD elements resourceExec
g_setting_hud_show 0x9 BOOL|CHEAT no 1 show/hide the HUD (a second, apparently redundant switch to g_showHud) resourceExec
g_setting_hudNotifications 0x9 BOOL|CHEAT no 1 HUD notifications resourceExec

4.4 Depth of field

cvar flags exposed default description route
r_dof 0x220012 INT|NOCHEAT|LOCAL_SETTING|EXPOSE yes 1 0 disabled, 1 enabled, 2 enable DOF near field direct
r_dofTAA 0x220011 …|EXPOSE yes 1 DOF temporal AA direct
r_dofHalfRes 0x9 BOOL|CHEAT no 1 0 full res, 1 half res resourceExec
r_dofDebug 0xa INT|CHEAT no 0 1 = show DoF debug info resourceExec
com_overrideDOF / com_override_dof 0x9 BOOL|CHEAT (×2, likely one stale/one live) no 0 / 1 manual override switch for a fixed focus plane instead of gameplay auto-DOF resourceExec
com_override_dof_near_start/_near_end/_far_start/_far_end/_intensity 0xc FLOAT|CHEAT no 2/1/50/100/1.0 the manual focus-plane distances and strength resourceExec
view_skipDof 0x9 BOOL|CHEAT no 0 don't use the view DOF lerpers resourceExec
view_dofBlendIn 0x9 BOOL|CHEAT no 1 blend DOF in via bokeh disc radius instead of moving the focus plane resourceExec
p_allowPlayerWeaponFarDOF/_NearDOF/p_enablePlayerWeaponDof 0x9 BOOL|CHEAT no 1/0/1 DOF applied to the player's own weapon/viewmodel resourceExec

4.5 FOV and post-FX

cvar flags exposed default description route
g_fov 0x210012 INT|NOCHEAT|ARCHIVE|EXPOSE yes 90, clamped 10–120 camera field of view direct
r_motionblur 0x220012 …|EXPOSE yes 1 0/1 direct
r_motionBlurQuality 0x220012 …|EXPOSE yes 2 2 high / 1 medium / 0 low direct
r_filmGrainRatio 0x220014 FLOAT|…|EXPOSE yes 1.0 film-grain strength override direct
r_chromaticAberration 0x220012 …|EXPOSE yes 1 enable chromatic aberration direct
r_chromaticAberrationLimit 0xc FLOAT|CHEAT no 1.0 its intensity limit resourceExec
r_vignette 0x9 BOOL|CHEAT no 1 enable vignetting resourceExec
r_hdrShutterSpeed 0x200014 FLOAT|NOCHEAT|EXPOSE yes 10.0 "set camera shutter speed" direct
r_hdrAutoExposureBase/Ratio/Speed/Instant 0xc/0x9 CHEAT no 0.01/1.0/1.0/0 "helpful for screenshots and fine-tuning automated exposure" (its own description) resourceExec

4.6 Screenshot / capture quality

cvar flags exposed default description route
com_captureFilename 0x200010 NOCHEAT|EXPOSE yes "" optional filename override direct
com_capturePath 0x200010 …|EXPOSE yes "" optional output path, appended to screenshots/ direct
com_captureSamples 0x200012 INT|…|EXPOSE yes 1 supersample count for TakeScreenshot direct
com_captureTGA 0x200012 …|EXPOSE yes 0 0 = JPG, 1 = TGA direct
image_screenshotQuality 0xa INT|CHEAT no 75 JPEG quality, 100 = best resourceExec
r_screenshotBatchSize 0xa INT|CHEAT no 8, clamped 0–16 screenshot job batch size resourceExec
r_screenshotTag 0x8 CHEAT (STRING) no "" text stamped on captured screenshots resourceExec

4.7 Cutscene / cinematic rendering state

cvar flags exposed default description route
devgui 0xa INT|CHEAT, clamped 0–5 no 0 0 off … 4 ImGui with custom windows (r4 §4.6: one-time set, then ~50 non-exposed buttons/toggles run unbracketed) resourceExec
snapEdit_devMode 0x9 BOOL|CHEAT no 0 "sets dev mode on match parms. This will give the player ALL THE THINGS" — already runtime-proven settable via resourceExec (project memory), its actual in-game effect not traced into code resourceExec
hud_skip_cinematics 0x9 BOOL|CHEAT no 1 skips intro cinematics after load resourceExec
com_frameLockHz 0xa INT|CHEAT no 0 "set when game is running a pre-rendered cutscene in idStudio. Overrides any tick related cvars" resourceExec
r_cutsceneRender 0x9 BOOL|CHEAT no 0 marks that a cutscene is being rendered — renderer avoids changing cvars underneath it resourceExec

5. TNC photo-mode commands

command exposed description route
getviewpos yes prints the current view position direct
where yes same as getviewpos direct
bind/unbind/unbindAll/listBinds yes key binding, including binding a key to resourceExec ... -s (§2/§9) direct
vstr yes inserts a cvar's current value as command text — still runs at whatever level is ambient at that moment, so it does not bypass the gate on its own direct
TakeScreenshot yes the screenshot command itself direct
exec / resourceExec yes exec reads a loose disk file at level 1; resourceExec <name> -s reads a resource at level 0 — the gate's only reachable bypass (§1) direct
activateConsole / listCmds / writeConfig yes console toggle, list commands, dump a cfg direct
teleport no "teleports the player to an entity location" resourceExec
teleportposition no teleports to an explicit (X,Y,Z) + yaw resourceExec
setviewpos no "sets the current view position" — the direct viewpos setter the task asked about resourceExec
centerview no centers the view (pitch = 0) resourceExec
resetViewParms no resets the current view render parms resourceExec
freeze no "freezes the game for a number of seconds" (time-based, distinct from the g_stopTime/g_freezeTime cvar switches) resourceExec
envshot no "takes an environment shot" (cubemap-probe-style capture, not a player screenshot) resourceExec
snapEdit no enters the (otherwise editor-only) SnapMap/level-editor mode — has its own free-fly camera and a snapEdit_* cvar family (§4.7, snapEdit_cameraDistanceLimit, snapEdit_fpsAccelerationTime, …); genuinely promising as a second free-camera system, entirely untested in game by this track resourceExec
toggle no generic cvar toggler (toggle <cvar> [values...]) — this is what each tiny resourceExec carrier in §9 uses internally resourceExec
killMonsters / clearInventory no useful for clearing a frame of enemies/combat clutter before a shot resourceExec
mdnt_pause / mdnt_play / mdnt_list_active / mdnt_list_paused no pause/resume a playing Midnight (TNC's scripted-camera cutscene system, §6) by name — the way to freeze a cutscene mid-shot for a screenshot resourceExec

Negative control, re-confirmed and reworded (pass 1 fix): the real god-mode command is capitalized God — registered, non-exposed (commands.json: flags_decoded ["BIT21_CHEAT?"], exposed: False, same shape as Notarget), reachable only via resourceExec and already runtime-proven working that way (§1/PROVEN). There is no separate lowercase/synonym god-mode command: a case-insensitive lookup over all 234 registered commands maps god to that one real God entry and nothing else — verify.py now asserts this case-insensitively, not just by exact string. noclip, spawn, give, freecam, photomode, thirdperson, spectator, debugcam are genuinely absent under any case (checked the full 234-name list, case-folded). Camera control in TNC is cvar-driven, not command-driven, except for the view-position setters above and God itself.

6. Kiscule camera/cinematic nodes

Retail usage counts from re_probes/kisculeref/catalogue.json (full survey, 2408 scripts, 70274 nodes, 205 types — docs/kiscule.md):

node type retail count scripts what it does
idKisculeNodeActionMidnightControl 958 647 Play/Pause/Resume/Stop/Reset/SkipToNextScene a Midnight (declMdnt decl path) — TNC's dedicated scripted-camera/cutscene system, separate from kiscule itself; Started/Interrupted/Finished/BlendOutStarted/Skipped/Failed notifications
idKisculeNodeOpMidnightParametersControl 958 647 builds the parameter block (previewSetup groups: Director, PlayerBody, Player, …) a Midnight is played with
idKisculeNodeMidnightNotification 244 158 named sub-events inside a running Midnight (EnterDone, LeverActivated, …)
idKisculeNodeActionTeleport 126 62 teleport an entity to a named destination/location, with position/rotation offset and alignment — the kiscule-side equivalent of the teleport console command
idKisculeNodeActionFadeView 55 27 fade the view to a colour over fadeTime ms — the scripted screen-fade primitive
idKisculeNodeActionRumbleCam 35 15 start/stop a named screenviewshake/* camera-shake + controller rumble, with scale/fadeOutTime/durationOverride
idKisculeNodeActionGlobalCameraShake 1 1 barely used (one script) global camera-shake enable/disable

113 kiscule node classes exist in the EXE but are never used in any retail script (docs/kiscule.md §4), including camera-adjacent ones: idKisculeNodeActionCutsceneEvents, idKisculeNodeActionSetOrientation, idKisculeNodeAddOrientation/InterpolateOrientation/InvertOrientation/ ScaleOrientation/SubOrientation, idKisculeNodeMidnightLink, idKisculeNodeActionMidnightMoveAIToScene. Whether the engine accepts one of these if hand-added to a script is untested (the game was not started) — same caveat docs/kiscule.md already states for all 113.

Pass-1 correction — the "113" figure's own source reconciled: the verifier found that this project's own ground truth disagreed with itself: docs/kiscule.md says 113, but re_probes/kisculeref/catalogue.json's own unused_node_classes field lists only 105 names. Resolved this run: diffing RTTI's idKisculeNode*-prefixed classes (excluding the per-node *Parameters/*Parameter companion structs, which describe a node's parameter block and are not node types themselves) against catalogue.json's used(205) and unused_node_classes(105) sets finds exactly 8 real node classes present in the EXE's RTTI but listed in neither set: the idKisculeNodeParameterListOperator* family (GetIndexInt/Bool/String/EntityReference, AddItemInt/Bool/String/EntityReference — generic list/array operators, not camera-related). 105 + 8 = 113: docs/kiscule.md's figure was correct all along; catalogue.json's unused_node_classes field itself undercounts by exactly these 8 (a builder-script gap this track did not fix, being outside its read-only scope — flagged here for whoever next touches re_probes/kisculeref/build_catalogue.py). verify.py asserts this reconciliation mechanically.

Practical read for a camera shot inside an existing/custom map: a Trigger_Volume → ActionFadeView/ActionRumbleCam/ActionTeleport Command chain works today in retail scripts (r5's proven Exec path covers Command nodes specifically; these three are plain Action nodes and were not individually re-traced for their own level handling this run — they run through the normal entity/game-logic call path, not through idCmdSystemLocal at all, so the restriction-level gate does not apply to them in the first place).

6.1 Camera entity classes (RTTI-confirmed, map-placement untested)

docs/ghidra/rtti_tnc.json lists real, compiled-in camera-entity classes beyond kiscule's node graph: idFreeCamera, idUtilityCamera, idSpringCamera, idRotatableCamera, idCinematicCamera, idSlowMotionCamera, idInteractionCamera, idSpectatorCamera, idAnimCamera, idEntityCamera, idAIDebugCamera, and a decl-driven idDeclCameraTrigger (its own idDeclInfoTemplate<idDeclCameraTrigger> exists too, implying a dedicated .decl file type for camera triggers, separate from both kiscule and the entity/map format). None of this is tested — no track has placed one of these as an entityDef in a custom map (the already-proven dlc_0-precedence route could carry it) or checked whether the resource/decl loader accepts a hand-written camera_trigger decl. Flagged as the most promising untested avenue for a scripted, reusable camera rig, as opposed to this report's cvar/keybind-driven manual photo mode.

7. What resourceExec/the key-bind workaround does not reach

Three negative results, each confirmed by absence from the live 234-command table (verify.py asserts the first three by name): no noclip, spawn, give, god (lowercase), freecam, photomode, thirdperson, or spectator commands exist at all — a decl/entity-placement or code-patch route would be needed, both out of this track's scope. The pm_noclipspeed/pm_noclipfriction cvars prove a noclip mode exists in the engine, but this track did not find what toggles it (open question, §11) — most plausibly a DevGUI button (r4 §4.6 found ~15 DevGUI pages this track did not individually string-dump) or an internal dev-only key-bind never exposed to AddCommand at all.

PROVEN

  • The restriction-level gate, the 234/34 and 3256/304 splits, and resourceExec's level-0 window: r4_consolecmds.md, re-used here, not re-derived.
  • idKisculeNodeCommand's unbracketed Exec path (ambient level, usually 0): r5_kisculecmd.md, re-used here.
  • 0xaa8780 (key-bind execute) saves the restriction level, forces it to 1, appends the bound command text via the same devirtualized AppendCommandText pattern r5 documented, then restores the old level — full disassembly read and cross-checked this run (DAT_7ff6303344d8 == RVA 0x41244d8 verified numerically against the live snapshot's image base).
  • 0xf515b0 is a generic CVAR_BOOL validator — checked its disassembly (compares the incoming value string against the literals "0"/"1" only), not a "photomode changed" callback. Corrected scope (pass 1 undercounted this): a full scan of the live table shows it is shared by 1136 of the engine's 1138 total bool-type cvars (99.8%), not merely the 3 named examples — it is the near-universal BOOL validator.
  • All cvars and commands named in §4/§5 are real, registered entries in the live-verified cvars_tnc_v2.json/commands.json tables, with the exact exposed/flags/default shown — verify.py now individually checks 51 cvar names (41 originally + the 10 pass-1 found missing from its own coverage) and 33 command names, ALL OK.
  • God is a real, registered, non-exposed command (same shape as Notarget) — confirmed directly in commands.json (exposed: False). No separate lowercase/synonym god-mode command exists; noclip, spawn, give, freecam, photomode, thirdperson, spectator, debugcam do not exist as commands under any case — case-insensitively re-confirmed this pass (verify.py).
  • The docs/kiscule.md "113 unused node classes" vs catalogue.json's own 105-entry unused_node_classes field inconsistency is resolved: the missing 8 are the idKisculeNodeParameterListOperator* family, present in RTTI but listed in neither catalogue.json set — 105 + 8 = 113, docs/kiscule.md's figure was correct, catalogue.json's field undercounts — asserted mechanically by verify.py.
  • TNO: ai_debugCam (not g_debugCam, which does not exist) and pm_thirdPersonHeight/Angle/Clip/Range (no underscore before the suffix) are confirmed present with these exact spellings in re_probes/tnoconsole/tno_cmdtable.json — asserted mechanically by verify.py.
  • The kiscule node usage counts in §6 (idKisculeNodeActionTeleport 126×, ActionFadeView 55×, ActionRumbleCam 35×, ActionGlobalCameraShake 1×, ActionMidnightControl/OpMidnightParametersControl 958× each) are exact retail counts from the full kisculeref survey — asserted by verify.py.
  • wolfsdk/tnccrypt.py's cfile AES-128-CBC scheme and tools/build_exec_carrier.py's from-scratch, arbitrary-name carrier are pre-existing, checked-in, and self-verifying (own --pruefen pass) — read and cited, not redone by this track.
  • mods/sandbox_tools (bind F6 "resourceExec snapdemo.cfg -s") is confirmed working in an actual running game for non-exposed commands (project memory tnc-console-unlock.md): this is the exact mechanism §9's recipe generalizes.
  • The RTTI camera-entity class list in §6.1 and the idFreeCamera/ idUtilityCamera/idSpringCamera/idCinematicCamera/ idDeclCameraTrigger/idSpectatorCamera names exist in docs/ghidra/rtti_tnc.json — asserted by verify.py.

INFERRED (plausible, not independently closed this run)

  • That the automatic cfile:default.cfg-tweaks route (§3) works in a real running game the same way the manual resourceExec <file> -s route is proven to — both share the same engine-exec-at-level-0 mechanism and the same crypto, but this specific route is explicitly flagged "im Spiel unbestätigt" ("unconfirmed in game") in the project's own TODO.md.
  • That g_stopTime 2 and g_freezeTime 1 both really do enter a working free-fly camera, and that they are either redundant or complementary — both cvar descriptions independently claim "free camera mode," but this was not traced into the code that reads them, and no in-game test has run yet.
  • That cam_cutsceneFreecam 1/2 meaningfully changes what the free camera from g_stopTime 2 looks like (per its own description, "use the cutscene camera to set up camera effects... FOV & DOF") — plausible from the description, not traced into code.
  • That snapEdit (the command) and its snapEdit_* cvar family amount to a second, independent free-camera/editor-mode system reachable in a shipped retail session — plausible from the cvar descriptions (snapEdit_cameraDistanceLimit, snapEdit_fpsAccelerationTime, snapEdit_findCameraDistance, snapEdit_noClipOffset), not run.
  • That the camera entity classes in §6.1 can be placed in a custom map via the already-proven dlc_0 entity/map-override route and will actually spawn/function — plausible by analogy with every other dlc_0-override success in this project, not tested for these specific classes.
  • That pm_noclipspeed/pm_noclipfriction are driven by a DevGUI toggle this track did not individually find (r4 already flagged ~15 unexamined DevGUI pages) rather than an entirely unreachable internal switch.

Failed hypotheses

  1. "The shared callback_rva on g_setting_photomode/g_freezeTime is a photomode-specific side-effect handler." Refuted by disassembly (§2): it is the generic BOOL validator, re-confirmed by a third, unrelated cvar (g_debugRenderForceDepthTest) sharing the exact same address.
  2. "A key bound to a non-exposed cvar/command works the way a kiscule Command node does (ambient level, usually 0)." Refuted: the key-bind executor (0xaa8780) explicitly brackets to level 1, unlike kiscule's Exec path. Binding straight to toggle g_freezeTime or God 1 would fail; binding to resourceExec <file> -s is the correct, already-proven pattern.
  3. "TNC has a pm_thirdPerson-style full third-person camera cvar like TNO's." Not found: the full 3256-cvar table has no pm_thirdPerson*/ g_thirdPerson* entry, only pmec_EnableThirdPersonBody/ pmec_ForceShowThirdPersonBody, which read as body-mesh visibility switches, not a camera-position switch. Left open rather than claimed either way (§11).

8. TNO (id Tech 5) — clearly labelled as candidate-string-only

No runtime image exists for TNO (computed task brief, re-confirmed: docs/ghidra/ only has static RTTI/pdata for WolfNewOrder_x64.exe, whose .text is still SteamStub-encrypted — nothing here was decompiled or disassembled). A sibling, in-progress track (tnoconsole, re_probes/tnoconsole/tno_cmdtable.json, 5026 string-mined entries with a per-entry confidence the mining script itself assigned) owns TNC's console/ cvar-gate equivalent for TNO; this section only lists camera-relevant candidate names, read-only, for completeness against the "both games" framing of this round, and defers the actual gate/reachability question to that track's own report.

Cross-validation available without a runtime image: many of these candidate names/descriptions are character-for-character identical to TNC's independently-proven-real cvars above (g_showHud, com_captureSamples, com_capturePath, com_captureTGA, pm_noclipspeed, win_pauseOnAltTab, g_cameraPlayerHack, image_screenshotQuality, g_freeCamSpeed-adjacent g_freeCam) — since TNC is id Tech 6 built on id Tech 5's codebase, this overlap is circumstantial but real corroboration, not proof.

candidate (TNO, mined, unverified) confidence description
g_freeCam high "enable debug camera (free move) 0 = disable/normal, 1 = enable, 2 = lock camera completely" — a single three-state freecam switch, more direct than TNC's g_stopTime/g_freezeTime pair
pm_thirdPerson high "enables third person view"
pm_thirdPersonRange low "camera distance from player in 3rd person"
pm_thirdPersonHeight high "height of camera from normal view height in 3rd person"
pm_thirdPersonAngle low "direction of camera from player in 3rd person in degrees (0 = behind player, 180 = in front)"
pm_thirdPersonClip low "clip third person view into world space" — TNO appears to have the full third-person camera TNC seems to lack (§7). Pass-1 fix: these four have no underscore before the suffix (pm_thirdPersonHeight, not pm_thirdPerson_Height) — corrected from pass 1's shorthand, each confidence now matches the real mined entry instead of one blended "high/low"
g_showHud high enables drawing of HUD elements (identical name+text to TNC's real cvar)
com_captureSamples/com_capturePath/com_captureTGA high screenshot supersampling/path/format (identical to TNC's real cvars, TGA adds a 2 = PNG option in this candidate's text)
image_screenshotQuality — JPEG screenshot quality
screenshot/rawscreenshot high screenshot commands, including a raw-framebuffer dump variant TNC's table does not have. Data-quality caveat: a third, differently-cased entry, ScreenShot (CamelCase), also exists at high confidence but its mined description reads "toggle r_showSkel 0 1 2" — an unrelated string-mining pairing artifact (the miner paired this name with the wrong neighbouring literal), not a real description of a screenshot command. Excluded from this table; noted because this section leans on exact name/description overlap as its only TNO corroboration method, so the mining script's own pairing errors matter
timescale low "scales the time"
freeze high "freezes the game for a number of seconds" (identical text to TNC's real command)
cine_cam_debug/cine_captureFrames high/low cinematic-camera debug / "set to 1 to capture the cinematic frames to jpgs/tgas"
springCam_* (12 entries) mixed the same spring-camera family TNC has, debug/force-mode switches
g_cameraPlayerHack low identical text to TNC's real cvar
ai_debugCam low "enable debug camera" — pass-1 fix: the cited name was g_debugCam, which does not exist anywhere in tno_cmdtable.json (the report's own source); the one real entry is ai_debugCam. (A debugCam entry, suggested as a replacement, was checked too and also does not exist in this table under any case — dropped rather than re-added unverified)
g_drawPlayerViewPos/g_tracePlayerViewPos low/high view-position HUD overlay / console trace
getviewpos/setviewpos/teleport high identical names to TNC's real commands
g_dragEntity low identical text to TNC's real cvar
win_pauseOnAltTab low identical text to TNC's real cvar

TNO also has the same camera entity-class family in RTTI (docs/ghidra/rtti_tno.json): idFreeCamera, idSpectatorCamera, idCinematicCamera, idUtilityCamera, idSpringCamera, idRotatableCamera, idDeclCameraTrigger, plus TNO-only idDeathCamera/idRaceCamera/idTrailerCamera/idThrownCamera/ idTarget_CameraShake/idTarget_GlobalCameraShake (the idTarget_* naming matches idTech4/5's classic directly-spawnable target_* entity convention). Nothing about TNO's reachability (exposed/blocked, a resourceExec-equivalent, key-bind semantics) is known — that is squarely the tnoconsole track's question, not re-derived or guessed at here.

9. The recipe: best-possible TNC photo-mode cfg + keybind design

Two tiers, both built on already-proven mechanisms, nothing here needs a new loader feature:

Tier A — baked into cfile:default.cfg via WolfSDK's existing "Cheats & QoL" cvar-tweak pipeline (split_tnc/with_tnc_tweaks, already wired into Studio's generic TNC cvar page), for settings that are safe to hold for the entire session and should need zero interaction: image_screenshotQuality 100, r_screenshotBatchSize 16, com_captureSamples raised (this one is already exposed, so it can go as a plain +arg too), hud_skip_cinematics left at its default. Caveat: per §3, this specific route is unconfirmed in an actual game session — the smallest in-game test in §12 settles it with one line before relying on it for anything.

Tier B — two resourceExec carriers bound to two keys, for the actual "enter/exit photo mode" action, generalizing mods/sandbox_tools's proven pattern. Sample content (written this run, re_probes/photocam/ photomode_enter.cfg / photomode_exit.cfg / photomode_extras.cfg — text only; turning them into real encrypted cfile resources and a DLC/loader mod is the next, in-game-testing step, using wolfsdk/tnccrypt.py/ tools/build_exec_carrier.py, both already built):

// photomode_enter.cfg  (bind to e.g. F9:  resourceExec photomode_enter.cfg -s)
g_setting_photomode 1   // the headline cvar itself; effect beyond its own
                         // description is unproven, see S10/S12 "Ziel 0"
g_stopTime 2            // stop all entity updating, free cam (per its own description)
g_freeCamSpeed 6         // faster than the 0.015 default, tune to taste
g_showCrosshair 0
g_showHud 0
g_showGuis 0
pmec_ForceShowThirdPersonBody 1   // pass-1 fix: was "0", a no-op (already
                                  // the default) -- "1" actually forces the
                                  // player's body visible to the detached
                                  // free cam; untested whether it does
r_vignette 0
com_captureTGA 1         // lossless capture while composing
com_captureSamples 4     // supersampled TakeScreenshot

// photomode_exit.cfg  (bind to e.g. F10)
g_setting_photomode 0
g_stopTime 0
g_showCrosshair 1
g_showHud 1
g_showGuis 1
pmec_ForceShowThirdPersonBody 0
r_vignette 1

(re_probes/photocam/photomode_enter.cfg/exit.cfg carry the exact, current text; this block mirrors them after the pass-1 fixes above.)

Both binds are set once, from the normal restricted console (bind is exposed, §5), and persist across sessions (mods/sandbox_tools's own description: "binds are saved"):

bind F9  "resourceExec photomode_enter.cfg -s"
bind F10 "resourceExec photomode_exit.cfg -s"

Everything already-exposed can be bound directly, no carrier file needed:

bind F6  "TakeScreenshot"
bind PGUP "toggle g_fov 70 90 110"     // not exposed command? -- 'toggle' itself is NOT
                                        // exposed (S5): this line needs the resourceExec
                                        // route too (or 'g_fov' cycled via repeated direct
                                        // +/- sets, since g_fov itself IS exposed/direct)

(toggle the command is not exposed, §5 — a key meant to cycle an already- exposed cvar like g_fov still needs either its own tiny resourceExec carrier containing toggle g_fov 70 90 110, or two direct binds to fixed g_fov <value> lines instead of one cycling bind.)

Extra one-off carriers (photomode_extras.cfg, one resourceExec target per independent live action — each needs its own file since resourceExec runs the whole named file, not a parametrized line): single-frame step (g_runFrames 1, useful while g_stopTime is active, to hunt the exact mid-explosion frame), devgui toggle (toggle devgui 0 4 — after that, r4 §4.6's ~50 non-exposed DevGUI buttons/toggles would work for the rest of the session with no further resourceExec call, including a dedicated TimeScale DevGUI child page — pass-1 caveat, missed before: project memory tnc-console-unlock.md already recorded, from the one actual in-game resourceExec test that tried this exact line, "devgui 4 showed no window (open)"; treat the "~50 buttons" route as unconfirmed, not disproven, and retest it specifically before relying on it), and a manual-DOF pair (com_overrideDOF 1 + fixed near/far/intensity vs com_overrideDOF 0) for a deliberately staged focus plane instead of gameplay auto-DOF.

For a cutscene screenshot: mdnt_pause <name> (non-exposed, same resourceExec route) freezes a running Midnight mid-playback; mdnt_list_active finds its name first.

10. Open questions

  • What g_setting_photomode 1 alone visibly does — the report's own headline discovery ("enable/disable photomode") was, in pass 1, never actually isolated and tested; its effect beyond that one description string is not traced into code. Highest-value single-line test: a tiny resourceExec carrier containing only g_setting_photomode 1, run by itself (§12 "Ziel 0"), before trusting it bundled into the full recipe.
  • Does cfile:default.cfg's automatic tweak route actually apply in a real running game (§3's one open caveat — the single highest-value next check, since it would make Tier A's settings need zero console interaction ever).
  • Do g_stopTime 2 and g_freezeTime 1 produce the same free-camera behaviour, different ones, or need to be combined? Does g_runFrames actually single-step while either is active?
  • What cam_cutsceneFreecam 1/2 visibly changes about the free camera.
  • Whether pm_noclipspeed/pm_noclipfriction are reachable from any DevGUI page this track did not individually dump, or are dead cvars with no live toggle at all.
  • Whether TNC has any genuine third-person camera mode, or only the two third-person-body visibility switches in §4.2.
  • Whether snapEdit (command) opens a usable second free-camera/editor mode in a shipped retail session, and what its snapEdit_* cvar family (§5, §4.7) actually controls once inside it.
  • Whether any of the camera entity classes in §6.1 (idFreeCamera, idUtilityCamera, idDeclCameraTrigger, …) can be placed via a custom map's entity list and will spawn/function — and what a hand-written idDeclCameraTrigger-type decl needs to look like.
  • Whether any of kiscule's 113 unused node classes (§6, including the camera-orientation ones) load if hand-added to a script.
  • Whether pmec_ForceShowThirdPersonBody 1 actually makes the player's body visible to a detached free camera (g_stopTime 2) — the recipe now sets it (§9, pass-1 fix), but this is INFERRED from the cvar's description alone, not traced into the rendering code or tested in game.
  • Whether devgui 4 ever opens a visible window in a real session at all — the one existing in-game data point (tnc-console-unlock.md) says it did not, which §9's extras carrier now states as a caveat rather than treating the DevGUI route as a working given.
  • Everything in §8 (TNO) — deferred to the tnoconsole track by design.

Smallest in-game test for the maintainer

(Translated from German.)

Goal 0 — test g_setting_photomode in isolation (pass-1 gap, before everything else, one line): This cvar ("enable/disable photomode") was not in the recipe at all in the first version and was never tested. Build a tiny resourceExec carrier file with only the one line g_setting_photomode 1 (same route as photomode_enter.cfg), put it on a free key via bind, press it and look closely: does anything change visibly at all (HUD, camera, any overlay)? Whatever happens — the result (nothing visible / something specific visible) is itself the finding this report does not have so far, and should be noted before goal 2, before the cvar is trusted blindly bundled with the other seven lines in photomode_enter.cfg.

Goal 1 — confirm or reject the automatic path from section 3 (highest value, one line): In WolfSDK Studio, set image_screenshotQuality to 100 in the TNC cvar tweaks and apply (it is non-exposed, so it goes via the cfile:default.cfg route). Start the game normally, enter TakeScreenshot in the console, then look at the generated file under screenshots/. Confirmed if the file is visibly higher quality/larger than before (75 % JPEG) — that would be the first in-game confirmation of the automatic default.cfg route, so far only checked on copies.

Goal 2 — the actual photo-mode chain:

  1. Bring in photomode_enter.cfg/photomode_exit.cfg (contents in re_probes/photocam/) as new cfile resources via the already- proven dlc_0/mod route (same pattern as mods/sandbox_tools, which already works).
  2. Once, in the normal (restricted) console:
    bind F9  "resourceExec photomode_enter.cfg -s"
    bind F10 "resourceExec photomode_exit.cfg -s"
    
  3. Press F9 without opening the console. Confirmed if the game freezes (no more enemy movement), crosshair and HUD disappear, and the camera can be moved freely (g_stopTime 2) — that would be the evidence that a directly pressed keybind reaches the same non-exposed catalogue via resourceExec as mods/sandbox_tools has already shown for God/Notarget, only this time for the camera cvars of this report.
  4. Press F10: the game continues, HUD/crosshair are back.
  5. Control (must NOT work): as an experiment, put the same keybind directly on "g_freezeTime 1" instead of on "resourceExec ... -s" and press it. According to section 2, nothing may change (the keybind forces level 1, g_freezeTime is not exposed) — if the game reacts anyway, the chain documented in this report is wrong or incomplete.

Related: Research Report: R4 Console Commands, Research Report: R5 Kiscule Command, Research Report: Cfilekey2, TNC CVar Catalog, Kiscule Scripting, TNC Console Unlock, Kiscule Node Reference, Developer Mode.

Clone this wiki locally