An arsenal built from parts
Guns from a stat list
A weapon is also a list of values, and each one combines with the others: damage, knockback (which can pull instead of push), recoil, fire rate, magazine and maximum ammo, shot speed, count, spread, gravity and acceleration, lifetime, whether it inherits your movement, its weight (heavier is slower) and its cumbersomeness, a delay on how quickly your aim follows the mouse.
Its shot can be a projectile, a cone, a line, a sphere, a curve or a sine wave. It can explode on contact, on a timer or by proximity, leave a trail of other projectiles, split into submunitions, stun, make noise that enemies hear, and remove a chosen radius of dirt. A flag decides whether it can break rock.
What a shot spawns when it goes off follows one strict rule: a blast with a radius, damage, knockback or pull, stun, and optionally a ball of fresh dirt. No falloff, no damage over time, no odd shapes: the effect lands on the spot, in full, and is gone. Those simple pieces combine into hundreds of weapons that all behave predictably, so you can read any new gun at a glance.