Static utility that provides a single project-wide multiplier for weapon muzzle flash particle scale and a console command nz_muzzle to read or change it at runtime. It stores an optional backing field, exposes Scale with default 1.92f, and logs the effective rendered size and composition with PapMuzzleFlash.ParticleScale.
using Sandbox;
namespace NZombies;
/// <summary>
/// WEAPONS/MUZZLE FLASH — one project-wide multiplier on every weapon's flash size.
///
/// ⛔ ONE NUMBER INSTEAD OF 496 PREFAB EDITS, which is the argument `GlobalHandling` already
/// makes for recoil and hip-fire spread: "all weapons flash bigger" is a decision about the
/// game's look, not about any one gun, so it belongs at the read chokepoint where it also
/// covers every weapon added later. Baking a size into the prefabs would have to be redone by
/// the next pack that arrives, and `weapon_patch.py` would have to carry it between machines.
///
/// ⚠️ THE FLEET IS AT HALF SIZE AND ALWAYS HAS BEEN. All 496 prefabs author
/// `VMParticleScale` and `WMMuzzleParticleScale` as **0.5**, against a `ShootInfo` default of
/// 1.0 — uniformly, with no variation whatsoever, which is the signature of an import default
/// rather than 496 authoring decisions. So this multiplier is read against a baseline that was
/// never chosen: ×2.0 is where the particles were actually designed to sit.
///
/// ⚠️ IT MULTIPLIES, IT DOES NOT REPLACE. A weapon that one day wants a genuinely smaller or
/// larger flash than its neighbours still says so in its own prefab, and this scales that
/// rather than flattening it — the same reason `RecoilScale` multiplies the authored kick.
///
/// ⚠️ AND IT COMPOSES WITH THE PACK-A-PUNCH SCALE RATHER THAN COMPETING WITH IT.
/// `PapMuzzleFlash.ParticleScale` is applied after this one, so a packed gun is still bigger
/// than the same gun unpacked by exactly the factor that knob names.
/// </summary>
public static class MuzzleFlash
{
// ⚠️ Nullable getter, not an initialiser — a changed default has to survive a hotload.
// PhdAugments carries the full note; the PaP palette's ×2-that-would-not-die is why.
static float? _scale;
/// <summary>
/// Multiplier on every weapon's muzzle flash particle. 1.92.
///
/// ⚠️ 2.0 IS "THE SIZE THE PARTICLE WAS AUTHORED AT", because the prefabs halve it. It was 2.4,
/// a little above the designed size rather than a lot above it — the request then was a bigger
/// flash, not a different effect, and the particle stops reading as a flash and starts reading
/// as a fireball some way past that.
/// ⛔ 1.92 SINCE 2026-09-28: *"decrease the muzzle flash size by 20%"* — 2.4 x 0.8, so a shot renders at 0.96, just under
/// the designed size. A packed gun's flash comes down with it, since `PapMuzzleFlash.ParticleScale` multiplies this one.
/// </summary>
public static float Scale
{
get => _scale ?? 1.92f;
set => _scale = value;
}
/// <summary>
/// `nz_muzzle [scale]` — resize every weapon's muzzle flash, live.
///
/// ⚠️ IT PRINTS THE DELIVERED SIZE, NOT THE MULTIPLIER, for the reason the recoil tuner's
/// whole readout exists: the authored 0.5 makes "1.92" mean 0.96 on screen, and a number that
/// has to be halved in your head before it means anything has misled every conversation
/// this project has had about a multiplier.
/// </summary>
/// <summary>
/// ⛔ THE FLASH OFFSET IS PER WEAPON AND LIVES ON `Weapon.MuzzleOffset`, NOT HERE.
/// </summary>
///
/// It was briefly a static beside `Scale`, which was wrong: `Scale` corrects something all 496
/// prefabs got wrong together — an import default of 0.5 — while a flash sitting off the
/// barrel is ONE model's attachment being misplaced. A global fix for that moves the other 495
/// off theirs. `nz_muzzle_offset` writes the held weapon's own value and saves it through
/// `WeaponPlacement`.
[ConCmd( "nz_muzzle" )]
public static void Cmd( float scale = -1f )
{
if ( scale > 0f ) Scale = scale;
Log.Info( $"[nz] muzzle flash x{Scale:0.##} — the fleet authors 0.5, so shots render at "
+ $"{0.5f * Scale:0.##} (1.0 is the particle's designed size)" );
Log.Info( $"[nz] a packed weapon multiplies again by {PapMuzzleFlash.ParticleScale:0.##}"
+ $" — {0.5f * Scale * PapMuzzleFlash.ParticleScale:0.##} — see `nz_pap_flash`" );
}
}