Skip to content

Research Report R3 Newweapon

LopeKinz edited this page Oct 1, 2026 · 1 revision

Weapon Decl Anatomy and Building a New Weapon End to End

This research decodes how weapon decls are structured in TNC end to end — the entity/class system, fire modes, hitscan vs. travelling-projectile logic, viewmodel/animation/sound wiring, upgrades, dual wield, and the three ways the player actually receives a weapon — and works out exactly what a brand-new, separately-named weapon clone would need. The key finding is a clean, corpus-measured refutation of an earlier diagnosis that the default weapon class could only fire hitscan: the pistol and the hatchet share the identical absence of a specialized weapon class, and the hatchet already fires a genuine travelling projectile in unmodified retail, proving the restriction never existed. All of this is static decl-corpus analysis (no game launch); one incidental finding is that the explosive-pistol mod currently installed on the test machine is still the older, pre-fix version.

The weapon class system

Every player and AI weapon in the game — all 34 weapons/entity/* entity definitions — is rendered and fired through the same single C++ entity class, idWeaponEntity. One level down, an optional inventoryClass decl field can name one of exactly 12 compiled logic subclasses (idShotgun, idBattleRifle, idKampfpistol, etc.) — corpus-measured 12/12 match against the engine's own class list, 0 extra, 0 unused. The handgun sets no inventoryClass at all (runs on the engine's bare default), and so does the hatchet — whose axe_throw projectile already fires as a real, non-hitscan travelling entity in unmodified retail. Since both weapons share the identical missing field, there is no hitscan-only restriction baked into the default class; whether a weapon fires hitscan or a travelling projectile is decided purely by the fired projectile decl (hitscan=false plus a populated notHitscanInfo.entityDef) — 27 of the 44 retail player projectiles already take that path, including an ordinary full-auto rifle, not just melee/throwables.

Other weapon decl anatomy

  • Viewmodel/worldmodel: two independent fields — handsModelMD6 on the weapon decl (first person) and renderModelInfo.model on its attachEntityDef (world/third-person) — sometimes the same .md6 file, sometimes a dedicated one.
  • Animations: a decl-driven state machine (animSysDecl) reacts to fire/reload/equip/unequip events and names clip aliases resolved through an md6Def to .md6anim files. Since .md6anim's per-frame compression still isn't decoded (see the animation-decode report), a new weapon can reuse an existing animation set for free but can't get bespoke new animations yet.
  • Sounds: three separate channels — an fx decl for particle/sound trigger events, a Wwise switch-container key on the weapon decl, and a fireSoundEvent on the projectile decl — plus a fourth, gunfireEventDecl, which governs how loud AI perceives each shot.
  • Upgrades: upgrade decls (195 corpus-wide) are referenced by an ordered unlock-slot list on the weapon decl, with up to three typed modifier arrays each (weapon/ammo/data modifiers).
  • Dual wield: purely decl-side — dualwieldable=true plus maxCount=2 on the same weapon decl, no second decl needed.

How the player actually gets weapons — and how they don't

Three corpus-proven, independent routes: devInvLoadout decls (per-map dev/test starting kits, 21-item default list, gated per story-timeline), propItem pickups placed in a map's entity data, and the mission-script node idKisculeNodeActionGiveItems (45 uses across 29 retail scripts). There is no console "give" command — the full list of 234 registered console commands was checked exhaustively and contains none.

The weapon wheel ceiling

The weapon-wheel/HUD is an unwritable, closed Flash-derived binary format with no existing or buildable writer. A weapon decl only controls the data the wheel reads — icon, display name, and two small closed enums (weaponSlotFlash, 8 values; weaponSelectionGroup, 7 values), both shared by several weapons each. A new weapon can occupy an existing slot but can never invent its own.

What a brand-new, separately-named weapon needs end to end

Every single piece — decl chain, viewmodel, animations, sounds, upgrades, pickup — is individually buildable with existing tooling by reusing retail assets, except making it a genuinely new name rather than a retune of an existing one, which needs appending new entries to the archive (structurally proven possible, not yet a production tool — see the related new-assets report). Until that tool exists, the proven, shippable version of "a new weapon" is retuning an existing weapon's own decl in place, exactly as the project's current explosive-pistol mod does.

In-game test

  1. Re-apply the explosive-pistol mod's current (fixed) version — the archive on the test machine was found to still carry the older, pre-fix build — then fire at a wall beyond 10 m on the custom map. An explosion (where there wasn't one before) confirms both the earlier load-order diagnosis and that redirecting via the ammo decl's own field (rather than the projectile's inherit chain) is the correct approach.
  2. No action needed to confirm travelling projectiles work with a specialized weapon class too — just observe during normal play that the Dieselgewehr rifle (which already uses a specialized inventoryClass and a travelling projectile) behaves normally.

Clone this wiki locally