Wolfenstein Modloader Buy me a coffeeKaffee spendieren

Wiki / Latest research roundsNeueste Forschungsrunden

Physics: Havok Parameters Reachable by Decl/Cvar in TNC and TNO

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

In plain wordsIn einfachen Worten

This report checks which physics values can be changed in Wolfenstein II: The New Colossus (TNC) and Wolfenstein: The New Order (TNO), both built on Havok physics. In TNC, gravity and time speed are cheat-locked settings, while explosion pushes, ragdoll hits and breakable objects are text definitions that can be edited; the Panzerhund is a possessed creature, not a vehicle, and the Monowheel cannot be ridden. In TNO, gravity and player movement are locked, but per-object physics such as 1,205 breakable objects and one drivable car stay editable as text. TNO's lock was measured earlier from a real game log; everything new about TNC is static, and setting these TNC values through resourceExec is only inferred, not tested in game.

  • TNC's g_gravity (default 9.82) has no minimum or maximum in the code, and timescale is clamped to 0.1–10.0; both are cheat-locked and should be reachable through resourceExec, which is not yet tested.
  • Only 3 creatures (kampfhund, drone, alligator) have editable ragdoll text in TNC; all others use binary Havok files, and TNC has no ragdoll gravity per creature.
  • Push from explosions and weapons is set in the 154 damage definitions, and 175 breakable definitions hold the full destruction tuning (strength, density, radius).
  • In TNO, g_gravity and the movement settings failed through all 5 tested channels in a real game log, but its breakable objects even carry their own gravity value.
  • Open: whether setting g_gravity or timescale in TNC changes gameplay or only the stored value, and where the 'default' physics preset for movable props lives.

Dieser Bericht prüft, welche Physikwerte sich in Wolfenstein II: The New Colossus (TNC) und Wolfenstein: The New Order (TNO) ändern lassen, beide mit Havok-Physik. In TNC sind Schwerkraft und Zeitgeschwindigkeit als Cheat gesperrte Einstellungen, während Explosionsstöße, Ragdoll-Treffer und zerstörbare Objekte in änderbaren Text-Definitionen stehen; der Panzerhund ist eine übernommene Kreatur, kein Fahrzeug, und auf dem Monowheel kann man nicht fahren. In TNO sind Schwerkraft und Spielerbewegung gesperrt, aber Physik pro Objekt wie 1.205 zerstörbare Objekte und ein fahrbares Auto bleibt als Text änderbar. Die TNO-Sperre wurde früher aus einem echten Spiel-Log gemessen; alles Neue zu TNC ist statisch, und das Setzen dieser TNC-Werte über resourceExec ist nur abgeleitet, nicht im Spiel getestet.

  • g_gravity in TNC (Standard 9,82) hat im Code kein Minimum oder Maximum, timescale ist auf 0,1–10,0 begrenzt; beide sind als Cheat gesperrt und sollten über resourceExec erreichbar sein, was noch nicht getestet ist.
  • Nur 3 Kreaturen (Kampfhund, Drohne, Alligator) haben in TNC bearbeitbaren Ragdoll-Text; alle anderen nutzen binäre Havok-Dateien, und TNC hat keine eigene Ragdoll-Schwerkraft pro Kreatur.
  • Der Stoß von Explosionen und Waffen steht in den 154 damage-Definitionen, und 175 breakable-Definitionen enthalten die volle Zerstörungs-Abstimmung (Festigkeit, Dichte, Radius).
  • In TNO scheiterten g_gravity und die Bewegungseinstellungen laut echtem Spiel-Log über alle 5 getesteten Wege, doch seine zerstörbaren Objekte haben sogar einen eigenen Schwerkraftwert.
  • Offen: ob g_gravity oder timescale in TNC das Spielgeschehen ändern oder nur den gespeicherten Wert, und wo das Physik-Preset „default“ für bewegliche Requisiten steht.

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 on which Havok physics parameters a modder can reach through decls or cvars in TNC and TNO. TNC runs Havok Physics 2, Havok Destruction and Havok Cloth; gravity and time scale are plain cvars, ragdoll text decls exist for only three creatures, and explosion/weapon impulses, breakables and separable props are decl levers. In TNO, gravity and player movement are cvars and therefore locked by the retail cheat gate, while per-object physics is decl-driven. Read-only; reaching these cvars through resourceExec is inferred from the proven route, not tested individually in game.

Read-only track. Builds on and does not redo: re_probes/agent_reports/r4_consolecmds.md and r5_kisculecmd.md (the TNC restriction-level gate and the resourceExec <file> -s bypass — cited here, not re-derived), re_probes/cvartable/cvars_tnc_v2.json (3256-cvar TNC catalogue with flags/min/max, built by w-cvartable-a1's tools/probe_cvartable.py from the live runtime image — spot-checked against the decompiler in §2.4 below, not retaken), docs/moddingflaeche-tnc.md (TNC decl-type survey, tools/survey_tnc.py), docs/limits.md and docs/devmodus.md (TNO's retail cvar lock, measured from a real qconsole.log — this is the authoritative TNO evidence, no runtime image exists for TNO so it could not be re-measured here). Tools used directly in this track: tools/decomp.py (TNC runtime decompiler, ~15 s/call) against re_probes/runtime_87400/module.bin; tools/survey_tnc.py --type/--grep (TNC decl sampling, idcl.py + oodle.py, read-only); wolfsdk/patch.py Installation against the live TNO install (read-only) for direct decl reads, reusing the already-proven TNO archive reader. Three small scripts kept for reproducibility in re_probes/physics/: verify_tnc_grep.py (one-pass multi-pattern grep over all 43 309 unique TNC text decls, ~2m40s), verify_tnc_entitydefs.py (five named TNC entityDef reads), verify_tno_samples.py (TNO decl samples by type via Installation.lookup). No game was launched, no process attached. Nothing was written under either game install; all three scripts above only read.

Question

TNC physics: which Havok parameters are reachable by decl or cvar — gravity, timescale, ragdoll strength/weight, explosion/weapon impulse on props and bodies, destructible/ separable entities (func/separable), throwable props, rideable vehicles/mechs (Panzerhund, Monowheel) — with exact fields/cvars, code clamps, and what a "low gravity / super-ragdoll / everything breaks" fun-mod would touch. Both engines, with evidence.

Answer (short)

TNC (id Tech 6) runs on Havok Physics 2 (hknp*) + Havok Destruction (hknd*) + Havok Cloth (idHavokCloth) + a Havok-based AI/navmesh bridge (hkai*, idNavMesh_Havok) — all confirmed by RTTI class names, not inferred. A global gravity cvar (g_gravity, default 9.82, no engine-side min/max clamp — confirmed both in the cvar table and independently in the cvar's own constructor via the decompiler) and a time-scale cvar (timescale, default 1, clamped 0.1–10.0 in the constructor) exist and are plain floats with no decl equivalent. Ragdoll behaviour is split: a global force multiplier (af_forceScale, default 0.3, no clamp) and blend duration (af_blendDuration) are cvars; only 3 creatures ship a text articulatedFigure decl in TNC (ai/kampfhund, ai/drone, ai/alligator) with full Havok solver constants (solverConstants.* ErrorReduction*, *LcpEpsilon, per-body density/linearFriction/angularFriction/ contactFriction/bouncyness) exposed as plain text — every other creature's ragdoll is a binary .hkt Havok Cloth/AF setup, not decl-editable, and TNC's articulatedFigure dropped the per-creature gravity-scale field that TNO's format had (confirmed: 0 hits for "gravity" in a full-byte scan of all 3 decls). Impulse on props/bodies from explosions and weapons is a decl lever, not a cvar: damage.damageParms.ragdollImpulseMag, .physicsExplosionParms.{radius,intensity}, .physicsParms.{forceBreakOff, projectileMass}, .minKnockBack/.maxKnockBack, .kickAmplitude/.kickTime — all plain key = value; TNC-dialect, all editable today with decl.py, used by 154 damage decls (37/22/19/16/55/55/13 resp.). Destructible/separable props are breakable decls (175, full Havok Destruction tuning: density, breakingStrength, elasticity, destructionRadius, minConnectionArea, collision.{convexRadius,shrinkByRadius, maxHullVertices}, fx.vaporizeThreshold) plus entityDef class="idBreakable" (prop/breakable) and 8 aiComponent_BreakableLimbs decls (wound-triggered AI gib thresholds); func/separable/compound (idSeparableEntity) and func/separable/part (idSeparablePartEntity) exist as entityDef base classes but ship with an empty edit block — their actual per-object physics values live only inside the 397 MiB .entities map text (29 maps, not sampled here, see docs/moddingflaeche-tnc.md §5.1). No vehicle, throwable, destructiblePiece or text glass decl type exists in TNC at all (confirmed by a full --types scan) — despite Havok Vehicle middleware being compiled in (hknpVehicleViewer RTTI class exists). Panzerhund is not a vehicle: it is a player-possession swap — entityDef:player/playercontrolled/panzerhund, class = "idPlayerControlled", with mountScenes/dismountScenes and its own 800-HP aiHealth, driven afterwards by ordinary pm_* cvars (pm_jumpHeightPanzerRide). Monowheel is not player-rideable at all — every hit for it is md6Def/animSys/ material (NPC-ridden scripted animation + skin), no physics decl of any kind.

All of the TNC cvars above (g_gravity, timescale, af_forceScale, af_blendDuration, pm_lineardamping_free/grounded, g_knockback, g_breakableVaporizeMultiplier) carry the identical flag shape — CVAR_CHEAT, exposed=False, settable_in_retail=False — as g_infiniteAmmo, which r4/r5 already proved reachable and settable through resourceExec <loader-replaced cfile> -s (same gate, same bypass). This generalisation is INFERRED by mechanism, not yet individually retested for each physics cvar — the smallest in-game test to close that gap is below. +args is proven rejected for this cvar class (prior finding, not redone).

TNO (id Tech 5) is the opposite story for the player-global levers and the better one for per-object levers. g_gravity and every pm_* movement cvar are proven locked in TNO retail — measured from a real qconsole.log, not inferred: config-file assignment is flatly rejected (%s CANNOT be set in retail!), command-line assignment is accepted but wiped one frame later by a startup cheat-reset (Resetting cheat cvar: %s), and the one channel that survives both (+toggle) does nothing because the retail build never wired the functionality behind it (docs/limits.md §1–2, 5 channels tested, all failed; docs/limits.md §5 also already ran a full-text search for a player-gravity decl equivalent across all 60 210 TNO text assets and found none). No TNO runtime image exists, so whether TNC's resourceExec bypass has a TNO analogue is unknown — open question, not testable with current tools. But TNO's per-object physics are plain-text decls, not cvars, so the retail lock never touches them at all: breakable (1205 decls — linearFriction/angularFriction/contactFriction/bouncyness/vector gravity/ worldCollisionOnly/maxSimulationTime plus an explosion{radius,impulse,falloff, angular,delay,duration} block with real retail values up to impulse 325000), articulatedFigure (9 decls, richer than TNC's — each has its own defaultGravityScale, e.g. 1 for human/base/human/supersoldat, independent of the locked global cvar), cloth (30 decls — mass, gravity, friction, springFriction), destructiblePiece (22 decls — health, breakDelay, obliterateChance, obliterateInfo.entityToSpawn). TNO ships exactly one vehicle decl — vehicle:car/c04/escapecar_base_def, the one drivable-car chase (chapter 4) — with full Havok vehicle tuning in plain text: maxSpeed, maxReverseSpeed, handBrakeForce, brakeForce, motorTorque (table ref), frictionForce, pitchStabilization/rollStabilization, skidRoll, per-wheel wheels.item[N], plus a matching vehicleWindowKit for breakable glass.

1. The Havok middleware actually compiled into TNC

Grade: proven, from RTTI class names in docs/ghidra/rtti_tnc.json (5627 classes, static MSVC-RTTI parse, preferred base 0x140000000). A substring scan for Havok|^hkn|Physics|Vehicle|Breakable|Ragdoll returns 835 hits; the module families:

Namespace/class prefix What it is TNC-relevant hit
hknp* Havok Physics 2 ("next-gen") — rigid bodies, queries hknpCollisionQueryCollector, hknpAllHitsCollector, hknpClosestHitCollector, hknpWorld, hknpVehicleViewer
hknd* Havok Destruction — fracture simulation hkndBreakableBody, hkndCutOutFracture, hkndDebrisFracture, hkndConvexDecompositionAction, hkndDefaultController::ComputeBrokenConnections/Fragments (≈150 classes)
hkd* Havok Destruction (older "2012" shape layer) hkdBreakableBody, hkdBreakableShape, hkdDeformableBreakableShape
hkai* Havok AI — navmesh built from live physics geometry hkaiPhysicsBodyObstacleGenerator, hkaiPhysicsWorldListener, hkaiPhysicsBridgeBase
idHavok* id Software's own wrapper layer idHavokPhysics, idHavokPhysics_Player, idHavokPhysicsSignalHandler, idHavokCloth, idHavokDestructionLocal, idNavMesh_Havok
idAFJointMod / idAnimSysNode_Ragdoll anim-to-ragdoll blend confirms af_blendDuration's target
idDeclInfoTemplate<idDeclBreakable>, <idDeclAIComponent_BreakableLimbs>, <idDeclProp_BreakableComponent>, <idDeclProp_PhysicsAttribs> decl-system glue for the decl types in §3 ties breakable/aiComponent_BreakableLimbs decls to their C++ handler classes

hknpVehicleViewer exists — Havok's vehicle component is linked into the TNC binary — but, per §4, zero vehicle decls ship and no entityDef references vehicle physics. Whatever uses it (if anything live) is not reachable through decls; treat TNC "vehicles" as unused middleware, not a modding surface.

idDeclProp_PhysicsAttribs matches entityDef:prop/moveable's edit.physicsAttributes = "default" field (§4.3) — a named physics preset. No decl type by a matching name was found in the --types scan; where "default" resolves to concrete density/friction/bounce values is unresolved — open question, §7.

2. TNC cvars — exact names, flags, defaults, clamps

Source: re_probes/cvartable/cvars_tnc_v2.json (built by w-cvartable-a1's tools/probe_cvartable.py against the live runtime image; methodology in re_probes/agent_reports/cvartable.md §1 — cited, not rebuilt). All entries below were re-read directly from that JSON in this track, and g_gravity's registration site was independently re-verified by decompiling its constructor (§2.4) rather than trusting the table blind.

cvar default type flags exposed min max description
g_gravity 9.82 float CHEAT, NETWORKSYNC (0x200c) no — — control the force of gravity on physics objects
timescale 1 float CHEAT (0xc) no 0.1 10.0 scales the time
af_forceScale 0.3 float CHEAT (0xc) no — — (no description string) — global ragdoll force multiplier
af_blendDuration 0.2 float CHEAT (0xc) no — — duration over which animation blends into ragdoll once active
af_syncTestMargin 0.1 float CHEAT no — — collision fraction margin (AF/ragdoll network sync)
af_syncVoidCheckDistance 0.4 float CHEAT no — — how far to do the "void" (fell through world) test
af_spamJointWarnings 0 bool CHEAT no — — spam console with AF joint warnings
pm_lineardamping_free 5.0 float CHEAT, NETWORKSYNC no — — linear damping on the havok body when free floating (air, swimming)
pm_lineardamping_grounded 0.01 float CHEAT, NETWORKSYNC no — — linear damping on the havok body when connected with the ground
g_knockback -1 int CHEAT no — — -1 = use damage decl's knockback; >-1 overrides every decl's value globally
g_breakableVaporizeMultiplier 1 float CHEAT no — — vaporize threshold multiplier; higher = larger pieces vaporized
pm_jumpHeightPanzerRide 1.15 float CHEAT no — — jump height while possessing the Panzerhund
pm_wheelchairfriction/height/Speed/StrafeSpeedRatio/printspeed various float CHEAT(+NETWORKSYNC) no — — wheelchair sequence movement (c01 prologue)
pm_rammbockactivationtime 200 int CHEAT, NETWORKSYNC no — — ms after sprint start before rammbock (BJ's charge) activates
pm_rammbockDotChecker -0.69 float CHEAT, NETWORKSYNC no — — facing-angle threshold for a valid rammbock hit
g_infiniteAmmo (reference) 0 int CHEAT (0xa) no — — already proven settable via resourceExec -s — same flag shape as every row above

No cvar above has an engine-registered min/max except timescale. That is not an assumption: min/max in the table come from whichever idCVar constructor overload was called (the 2-float-arg one passes bounds, the bare one does not), and §2.4 confirms by direct disassembly that g_gravity's constructor call is the bare overload.

2.1 Ragdoll AF decls — exact fields (3 creatures total)

python tools/survey_tnc.py --type articulatedFigure --samples 3 (TNC dialect, no =, no ; — the id-Tech-5 key value style, which decl.py parses correctly for this type per docs/moddingflaeche-tnc.md §2.3's exception list). ai/kampfhund:

settings {
    defaultBouncyness 0.3000000119
    defaultLinearFriction 0.0099999998
    defaultAngularFriction 0.0099999998
    defaultContactFriction 0.8000000119
    defaultConstraintFriction 0.5
    suspendSpeed 20, 30, 40, 60
    contents corpse
    clipMask solid, corpse
    selfCollision 1
    solverConstants {
        errorReduction 0.5          errorReductionMax 256
        lcpEpsilon 0.00001          maxLcpEpsilon 0.001
        limitErrorReduction 0.3     limitErrorReductionMax 256
        limitLcpEpsilon 0.0001
        contactErrorReduction 0.2   contactErrorReductionMax 256
        contactLcpEpsilon 0.000001
        universalErrorReduction 0.5 universalErrorReductionMax 256
        universalTorsionLcpEpsilon 0.1
        minTwistErrorReduction 0.1  maxTwistErrorReduction 0.5
    }
    syncSolverConstants { ...same fields, separate values for networked sync... }
}
body "hips" {
    joint "hips"
    model dodecahedron( (-0.1,-0.15,-0.1), (0.1,0.15,0.1) )
    density 1000
    linearFriction 0.0099999998
    angularFriction 0.0099999998
    contactFriction 0.8000000119
    bouncyness 0.3000000119
    clipMask solid, moveableclip, corpse, ikclip
    selfCollision 1
}

The other two (ai/drone, ai/alligator) repeat the same settings/solverConstants/ per-body shape with their own numbers. No gravity field anywhere in any of the 3 (verified: --bytes 14300 full-length read, 0 case-insensitive hits for "gravity"). This contrasts with TNO's format (§6) — TNC's AF dialect dropped per-creature gravity scaling; the only gravity lever left for ragdolls is the global g_gravity cvar plus the global af_forceScale multiplier.

2.2 Damage-decl physics fields (154 decls)

Field frequency across all 154 damage decls (survey_tnc.py --type damage): ragdollImpulseMag 37×, minKnockBack/maxKnockBack 55× each, physicsExplosionParms 22× (with .radius 19×, .intensity rarer), physicsParms.forceBreakOff 19×, physicsParms.projectileMass 16×, kickAmplitude/kickTime 13–15×. Example, damage/explosions/misc/radius_car_explosion:

minDamage = 75; maxDamage = 100; minKnockBack = 250; maxKnockBack = 250;
radius = 8; radiusInner = 3; ragdollImpulseMag = 400;

damage/player/ground_pound and damage/player/rammbock (BJ's two physics-pushback abilities) both carry physicsParms.forceBreakOff = true and a physicsExplosionParms block — these are the two decls to raise for a "ground pound launches everything" mod.

2.3 Destructible/separable (175 breakable + 8 aiComponent_BreakableLimbs)

breakable:breakable/covers/submarine_railings_cover_100cm.breakable (full Havok Destruction tuning surface):

breakable = {
    density = 1000; breakingStrength = 1; elasticity = 200;
    destructionRadius = 1; minConnectionArea = 0.0001;
    maxDistanceForConnection = 0.05; smallestPlayerCollidable = 0.125;
    fx = { vaporizeThreshold = 0.02; vaporize = { particleSystem; soundEvent; } }
    integrity = { enable = false; delay = 0.5; breakingLength = 1; }
    collision = { convexRadius = 0.01; shrinkByRadius = 0.01; maxHullVertices = 16;
        pieceDecomposition = { enable = false; maxError = 0.05; } }
}

density = 2800 is the most common concrete value (41×, concrete pieces); breakingStrength and destructionRadius are the direct "make it shatter at a touch" levers. aiComponent_BreakableLimbs (panzerhund_death_breakablelimbs, zerstorer_breakablelimbs, soldier_limbs, supersoldat_breakablelimbs, …) is wound-triggered gib logic (triggeredByWound, limbFlags = "DESTRUCTLIMB_*", requiredOtherLimbsToKill, explosionDecl), not raw mass/impulse — it decides which limb detaches, not how hard.

func/separable/compound (class = "idSeparableEntity") and func/separable/part (class = "idSeparablePartEntity") both read, both ship an empty edit = {} — confirmed via re_probes/physics/verify_tnc_entitydefs.py. These are base classes only; every placed separable object (a car losing its doors, etc.) sets its real physics per-instance inside a .entities map, which this track did not open (397 MiB × 29 maps, already surveyed structurally in docs/moddingflaeche-tnc.md §5.1 — reuse that, not redone here).

2.4 g_gravity has no code-side clamp — direct disassembly, not inferred

python tools/decomp.py --strings "g_gravity" finds the registration constructor (FUN_7ff62c485bc0, RVA 0x275bc0); decompiled:

PTR_s_g_gravity_7ff62f1bd798 = s_g_gravity_7ff62e8347c8;        // name
PTR_s_control_the_force_of_gravity_on_p..._7ff62f1bd7a8 = ...;  // description
DAT_7ff62f1bd7b0 = 0x200c;                                      // flags: CHEAT|FLOAT|NETWORKSYNC

No call to the min/max-taking idCVar constructor overload, no comparison against a literal bound anywhere in the function — matches the table's min=None, max=None. (timescale's constructor was not independently redisassembled this run; its 0.1–10.0 bound is taken from the table as built by w-cvartable-a1, whose methodology — reading the same constructor-argument pattern — was spot-verified here on g_gravity.)

3. TNC decl types that do not exist

Full --types scan (PYTHONIOENCODING=utf-8 python tools/survey_tnc.py --types --limit 0 — needs that env var, the default console codepage crashes on one UTF-8 byte in the output; this is a pre-existing script issue, not touched here): 141 text types, 32 binary, 1 mixed, 174 total. None of vehicle, throwable, destructiblePiece, glass appear as text types at all. glass exists only as binary glassmodel (136 entries); hkcloth (40) and hknavmesh (45) are binary too — TNC cloth physics (mass, gravity, friction) are opaque Havok Cloth setup blobs, not decl-editable, unlike TNO (§6). destructionmodeldata (177, binary) is breakable's precomputed fracture-piece geometry companion.

4. Rideables — Panzerhund and Monowheel

4.1 Panzerhund: a player-possession entity, not a vehicle

entityDef:player/playercontrolled/panzerhund (re_probes/physics/verify_tnc_entitydefs.py):

class = "idPlayerControlled";
renderModelInfo.model = "old/robots/panzerhund/panzerhund.md6";
mountScenes = { item[0].scene = "interact/panzerhund/mount_leftside"; item[1]... }
dismountScenes = { ...dismount_leftside/rightside... }
actorEditable.faction.myFaction = "faction/player";

Per docs/moddingflaeche-tnc.md §3.2, this same entityDef carries aiHealth.max = 800. Movement while possessing it is governed by the ordinary pm_* cvar set (pm_jumpHeightPanzerRide is the one Panzerhund-specific override found; everything else is the shared player physics capsule). There is no separate "Panzerhund physics" decl or cvar block — tuning it means tuning the player movement cvars (§2) while possessed, or this entityDef's aiHealth/scenes.

4.2 Monowheel: scripted prop, never player-rideable

Every TNC hit for "monowheel" (verify_tnc_grep.py, pattern monowheel) is one of: entityDef:prop/pickup/collectible/gold/gold_25 (a gold-coin pickup model that happens to be monowheel-shaped — unrelated), material:models/vehicles/military/monowheel_01/... (skin textures), md6Def:old/vehicles/military/monowheel_01.md6 (the mesh/skeleton), and four md6Def/animSys entries under old/animation/ev/c05p1_roswell/.../monowheel/ (monowheel/officer01, monowheel/soldier02_mh — NPC riding animations inside a cutscene midnightScene). No entityDef class="idPlayerControlled", no physics decl, no vehicle decl. Monowheels in TNC are set dressing an NPC rides through a scripted animation, not a drivable Havok vehicle — confirmed negative, not merely unsearched.

4.3 prop/moveable and the unresolved physicsAttributes preset

entityDef:prop/moveable (inherit = "prop/default"): edit.physicsAttributes = "default", edit.damageComponentDecl = "propmoveable_hit", edit.lootStyle = "LOOT_LOOK_USE". physicsAttributes matches the RTTI class idDeclInfoTemplate<idDeclProp_PhysicsAttribs> (§1), implying a decl type exists for named density/friction/bounce presets ("default" being one), but no decl type with a matching name turned up in the --types scan. Open question (§7) — likely either a differently-named decl type not yet grepped for, or a hardcoded table in .text.

5. TNC reachability: the resourceExec generalisation (inferred, not individually tested)

Every cvar in §2's table has the exact flag shape (CVAR_CHEAT, exposed=False, settable_in_retail=False) that g_infiniteAmmo and God have — and r4/r5 already proved (runtime-proven, per the task's own prior-findings list) that a loader-replaced cfile executed via resourceExec <file> -s reaches the dispatcher at restriction level 0 (full 234-command/3256-cvar catalogue, no exposed-only filter) and successfully sets both of those. Because the gate is the single shared restriction-level integer (0x41244d8 in re_probes/runtime_87400, documented in r4) and not a per-cvar check, the same route should reach g_gravity, timescale, af_forceScale, af_blendDuration, pm_lineardamping_free/grounded, g_knockback, g_breakableVaporizeMultiplier with no code difference — this is the mechanism generalising, not a new mechanism. It has not been individually retested for any of these seven cvars in this track (no game launch permitted). +args is separately proven rejected for this whole cvar class by r4 (not redone here).

What "settable" does not prove: effect. r5's own caveat applies identically here — Notarget was confirmed set via this route but engaged enemies kept attacking, i.e. the cvar value changed without the gameplay behaviour changing. The same gap could exist for g_gravity/af_forceScale: the cvar may update while the Havok world was already initialized with the old value and never re-reads it per-frame. Unverified either way.

6. TNO — the contrast

6.1 Proven locked: gravity and player movement are cvars, and cvars are blocked

Not re-derived, cited from docs/limits.md §1–2 (measured from an actual retail qconsole.log, 21.09.2026 run): g_gravity, pm_jumpheight, pm_runspeed, pm_walkspeed, pm_sprintspeed, pm_crouchspeed, pm_noclipspeed, pm_sprintMaxTime, pm_autoSprint, pm_noBob are all in the measured blocked list — "%s CANNOT be set in retail!" from a config line, silently wiped (Resetting cheat cvar: %s) one frame later from the command line. Five channels were tested (binary.cfg/default.cfg, +cvar, +set cvar, +exec file.cfg, +toggle cvar) and all five failed to produce a working change — +toggle is the only one that survives both gates, and it does nothing because devgui-class functionality is not wired in the retail build (same shape of "present but inert" that r4 found for TNC's devMode_enable branch). docs/limits.md §5 already ran the natural decl-equivalent search — full text over all 60 210 TNO text assets for runSpeed|sprintSpeed|walkSpeed|jumpHeight|gravity — and found nothing for the player. TNO's lock mechanism (docs/devmodus.md §2) is the single CVAR_CHEAT flag plus a reject-string ("%s CANNOT be set in retail!"), structurally different from TNC's two-tier exposed-list system — no runtime image exists for TNO, so whether an analogue of TNC's resourceExec bypass exists is genuinely unknown, not merely untested.

6.2 Open and fully decl-driven: everything per-object

The retail lock in §6.1 is a cvar lock; none of the following are cvars, so it never applies (re_probes/physics/verify_tno_samples.py, direct reads via wolfsdk/patch.py Installation against the live TNO install):

  • breakable — 1205 decls, the largest physics-decl type in either game. Full sample (breakable/c01/condor9_01):

linearFriction 0.6 angularFriction 0.6 contactFriction 0.5 bouncyness 0.5 // bounce amount gravity 0 2000 -900 // default g_gravity (vector, per-object override!) worldCollisionOnly 1 // 0 = collide with other breakables too maxSimulationTime 30 explosion { radius 5000 impulse 325000 falloff 0.05 angular 1500 delay 0 duration 0.25 randomangular 16 16 16 randomlinearminmax 0 12000 0 0 18000 0 } This is the single richest "everything breaks" lever found in either game — a per-object gravity vector override that already exists in retail content (explicitly commented "default g_gravity", i.e. the engine lets each breakable opt out of the locked global), plus a full impulse/falloff/duration explosion block, on 1205 objects, all plain key value text. * articulatedFigure — 9 decls (human/base, human/supersoldat, kamphund/base, +6 more), same solverConstants shape as TNC §2.1 but with a defaultGravityScale field TNC's format lacks (1 in both samples read) — a per-creature ragdoll-gravity multiplier, fully open, cvar-lock-proof. * cloth — 30 decls: mass, springFriction, gravity (scalar here, e.g. -1800 for gore/entrails_a, -450 for a fan streamer), friction, collisionFriction, springMaxLengthMultiplier. * destructiblePiece — 22 decls: health (as low as 2, e.g. medicine bottles), breakDelay, obliterateChance (up to 1 = always fully destroyed), obliterateInfo.entityToSpawn/entitiesInPool. * glass — 9 decls: thin — decalSize, destroyParticle, impactSound/ destroySound only. No mass/impulse fields; glass breaking physics ride on breakable or vehicleWindowKit, not on glass itself. * vehicle — exactly 1 decl: vehicle:car/c04/escapecar_base_def (the chapter-4 escape-car chase, the only drivable vehicle in the game):

maxSpeed = 90; maxReverseSpeed = 25; handBrakeForce = 600; brakeForce = 2400; motorTorque = "vehicle/physics/c04/escapecar/motortorque"; // table reference frictionForce = 10; pitchStabilization = 1; rollStabilization = 1; skidRoll = 0.0003; skidRollBoostMult = 0.8; wheels = { item[0] = { wheelJoint = "left_front_tire"; ... } } plus a matching vehicleWindowKit:c04/escapecar (breakable windows: normalModelName/brokenModelName/collisionModelName, maxDecals, traceDepth, damageWhenDriverPresent). * throwable — 2 decls (throwable/grenade46, throwable/grenade60): thin, just a projectileDecl reference each — the actual physics sit in the referenced projectile decl, not here. * dragJoints — 2 decls (dragjoints/kampfhund, dragjoints/panzerhund2): rope-like joint chains for grab/drag animations (ghostJointDistance, maxBend, baseJoint, joints), not rigid-body physics.

7. Open questions

  • Does resourceExec-set g_gravity/af_forceScale/timescale etc. actually change TNC gameplay, or only the cvar's stored value (per r5's Notarget caveat, §5)? Smallest test below.
  • TNC's physicsAttributes = "default" preset (prop/moveable, §4.3): matching RTTI class exists (idDeclProp_PhysicsAttribs), no matching decl type name found. Where the concrete density/friction values live is unresolved.
  • func/separable/*'s real per-object values sit only inside the 29 .entities maps (397 MiB), not opened in this track — docs/moddingflaeche-tnc.md §5.1 already surveys that layer structurally; a follow-up could --grep those maps specifically for "func/separable" instances and their edit overrides.
  • Is there a TNO analogue of TNC's resourceExec bypass? Genuinely unknown — no runtime image for TNO exists under this project yet (task brief confirms this is a known gap, not an oversight here).
  • TNC hkcloth/.hkt binary Havok Cloth setups — confirmed opaque, not explored further (would need a Havok Cloth Toolset / .hkt format reverse-engineering track of its own, out of scope here).

8. Recipe sketch for a fun mod (design, not built)

TNC — "Low-G Rampage": a resourceExec-style loader carrier cfile (same recipe as re_probes/agent_reports/execcarrier.md, already structurally proven — not rebuilt here) containing seta g_gravity 1, seta timescale 0.4, seta af_forceScale 6, seta pm_lineardamping_free 0, seta pm_lineardamping_grounded 0, seta g_knockback 1500, run once at a devmap start — combined with decl edits (already proven editable) raising ragdollImpulseMag/physicsExplosionParms.radius on damage/player/ground_pound and damage/player/rammbock, and lowering breakingStrength across a handful of breakable decls for one-hit destruction. Every piece here individually reuses an already-proven mechanism (decl edit, resourceExec carrier); the combination is untested.

TNO — "Everything Breaks" (safer, no lock risk): pure decl edit, zero cvar/retail-lock exposure — bulk-set impulse→×10, gravity→÷4, bouncyness→0.9 across the 1205 breakable decls (text, key value dialect, decl.py already handles this id-Tech-5 format natively — no "vector weakness" caveat here, that only affects TNC's dialect per docs/moddingflaeche-tnc.md §2.3), set destructiblePiece.health = 1 everywhere, and for one chapter crank vehicle:car/c04/escapecar_base_def.maxSpeed/motorTorque for an absurd chase. Player-global low-gravity is not available in TNO (§6.1) — the honest answer for that specific ask is "no", not "untested".

Smallest in-game test (for the maintainer)

(Translated from German.)

TNC, a single console swap, no new mechanism: Build exactly the same resourceExec carrier cfile as in the already-proven God/g_infiniteAmmo test (re_probes/agent_reports/execcarrier.md recipe), but with the content seta timescale 0.2 instead of God 1. timescale is the only one of the seven physics cvars with a real code clamp (0.1–10.0) — so the one with the highest chance that it is not only set but also effective, and the effect on screen is unmistakable (everything runs in slow motion, including particles and ragdolls). Start the game, load a devmap, run the carrier with resourceExec <file> -s, throw a grenade or kill an enemy and watch whether the ragdoll animation plays in slow motion. If so, step 5 above (the generalisation over all seven cvars) is raised from "inferred" to "proven" — and g_gravity 1 next, the same recipe with a thrown object (e.g. a bottle from prop/moveable) instead of slow motion.

Related: Research Report: R4 Console Commands, Research Report: R5 Kiscule Command, Research Report: Cvartable, Research Report: Execcarrier, TNC Modding Surface, Modding Limits, Developer Mode, TNC Console Unlock.