Algorithms for the Shooting Mechanics in BF4


#1

Original title: “Algorithms for the Shooting Mechanics in BF4”, 10.11.2013
Author: 3VerstsNorth


Background and Aims
To evaluate objectively how weapons, attachments, bursting patterns, etc. possibilities compare against each other, we can use computational modeling of weapon behaviour given these parameters. Many such efforts to quantify and tabulate weapon comparisons or headshot efficiencies have been made, see:
Attachment Combinations - Numerical Benefits
Headshot Burst Distance
Headshot efficiency considerations
A dummy’s guide to calculating optimum weapon’s range

Here at Symthic, we have a fairly good understanding of the mechanisms that control weapon accuracy and damage output through knowledge of the weapon stats and by understanding how recoil and spread works. This knowledge is, however, distributed to several too often forgotten threads and Symthic web pages. The great grandfather of this stuff is probably the plotic thread where much of the algorithms and programming were pioneered: Plotic - Graphical representation of weapon deadliness that for the program code was followed by Symplot - v.0.6.8

The aims of this thread are
(i) to compile and document this information and its sources,
(ii) to make the algorithms and their assumptions explicit, and
(iii) to present discussion about and critique towards the current state-of-the art methods.
(iv) The ultimate aim is to provide the basis for anyone to build an as accurate as possible model of in-game weapon behaviour with data that are continuously improving through future discoveries that refine the model.

Tl;dr, One Ring Thread to rule them all :D. ‘them all’ denoting gun-model threads.

I will do my best to acknowledge the persons responsible for the original observations and give links to the correct threads. If there are deficiencies or omissions in this, please make a post about it. For all information, having the correct original source is critical because only that way the quality of the information can be assessed.

Finally, as a disclaimer, what I have written here is not an established truth . It is the most accurate working hypothesis about the mechanics of BF4 that we as a community have. So, if you know better, please contribute any critique that you see relevant and constructive. This thread aims to compile the best efforts of Symthic to achieve the best models achievable + this is possible only through iterative and continuous improvement.

Overview
In BF4, probability of hitting (weapon accuracy) is controlled by spread and recoil. The damage-output-per-second is controlled by damage/bullet, the firing rate of the gun, and the fraction of bullets that hit the target. These define a framework where we can assess the effectiveness of each weapon. The question of which gun+attachment-combo is the best, however, has to be formulated properly because the effects of many parameters cannot be included in simulations. Think about the value of having a large magazine or staying of the minimap with silencer. Someone could even make a list of such considerations to fuel further modelling work (for example, the magazine size issue could be included into a metric like ‘How much time does it take to get five kills? (incl. reloads)’.

So, questions we can now ask and answer effectively are like:

For a set of gun stats, attachments, recoil compensation method, hitboxes, bursting patterns, and distance:
‘How much Time does it take to produce 100 damage?’

We could call such a measure T100. It represents our ultimate estimate of the true-time-to-kill but still excludes factors like reloading.

In the two posts below, I outline the framework for modelling shooting in BF4 and the algorithms used therein. In algorithms, I use the variable names from BF4 files.

As the very core assumption, I presume ‘shooting’ and ‘aiming’ to go like this:

Shooting
The bullet leaves the player model ‘soon’ after the moment of the player giving the ‘Fire’ command (usually with LMB). The bullet is aimed at the Aimpoint of the player avatar. This aimpoint is modifiable by player mouse location all the time, by recoil after each shot, and by recoil recovery after the last bullet of the burst has been fired. This aim is modified by spread and finally the bullet trajectory is modified by gravity. The aimpoint in reality is a quaternion (a three/four dimensional complex number for representing the three angles needed to represent a point in a 3D sphere) but for all purposes needed here, it is sufficient to consider the aimpoint in the two dimensions (x,y) of the flat hit box surfaces facing the shooter.

Status of this thread
Most of the links and math that I know of are now in place - this is the release version like it or not ;). Please make a post in this thread if you think I have omitted a source or ignored some aspect of the algorithms.


Spread

Spread is radial noise added to the aimpoint of every shot (see What kind of noise is Spread? and Plotic - Graphical representation of weapon deadliness). This was confirmed by Demize and in game by John Stuart-Mill’s analysis in this post: What kind of noise is Spread?. Mechanics of spread are summarized below.

“The algorithm for spread”

For an aimpoint az,
az = ax + iay,
and spread sz,
sz = Spread * e(i
theta),
the bullet will go towards the location z,
z = ax + sz.

Here Spread is the current player"s current spread value and theta is a uniformly random angle from +pi to +pi. For grasping the polar notation for complex numbers, see Complex number. It is important to note that radially random spread gives much more hits close to the aimpoint than uniform spread (see first post in the ref above): within 0.5 x Spread, 50% of shots will hit whereas uniform predicts only 25% to hit and within 0.25 x spread, 25% of shots will hit whereas uniform predicts only 6.25% to hit.

Spread is dependent on the player state variables: mode {ADS, HIP}, stance {Stand,Crouch,Prone}, and motion {Base,Move}. In addition, Spread is dependent on spread accumulated from prior shots AND on spread recovered during time spent without shooting time or during the time spent after a change in the state variable(s).

In gamefiles, the minimum spread is defined in variables named by state variable names and ‘Min’, like ADSStandBaseMin for example. Spread increase per shot is similarly defined by ‘SpreadInc’, e.g., by ADSStandBaseSpreadInc. For clarity, I refer to these variables by ‘Min’ and ‘SpreadInc’. Look into the spoilers for all the interesting stuff:

“Spread accumulation”

For each shot j from 0 to N-1,
Spread = Min + j * SpreadInc.

Note that the maximum Spread achievable during ADS or HIP by accumulation is limited by ADSMax and HIPMax values.

“Spread recovery”

Spread recovery in files is controlled by ‘SpreadDec’. Spread recovery has been confirmed by a reliable source to be linear. Spread recovery can be approximated with a linear dependence on time, t.
Spread recovery:
AccumulatedSpread(t2) = AccumulatedSpread(t1) + (t1-t2)*SpreadDec.

Spread recovery, albeit short in time, is essential for determining optimal bursting rates. For those tabulated, see: Mouse click rates for optimal RoF

Moving Spread

The minimum spread variable for a moving player (**MoveMin) is apparently not used directly for giving the Min(spread) but rather used to define a ‘moving penalty’ so that

SpreadPenalty = (MoveMin + BaseMin * BaseMinModifiers)

In this scenario, the 0.5 moving spread multiplier of ergo/vertical grip influences spread so that

Min = BaseMin + 0.5 * Penalty * SpeedModifier

For the heavy barrel, the 0.5 stationary ads spread multiplier influence spread so that

Min = 0.5 * BaseMin + Penalty * SpeedModifier,

where Penalty would be MoveMin - 0.5 * BaseMin.

The SpeedModifier is the fraction of the player’s movement speed from the normal running (not sprinting) speed. For most guns, SpeedModifier during ADS is 0.5. For bullpup weapons, it is 0.75.

Considering multiple modifiers together, Rezal argues that the order of computations is

ADS_move_spread_effective=(ADS_move_spread-ADS_stationary_spreadADS_stationary_modifiers)ADS_move_modifiersADS_move_speed)+ADS_stationary_spreadADS_stationary_modifiers

( Rezal’s notation for variables )

For sources, see this and this post by Rezal. See also this thread by WoopsyYaya where many very good questions are answered in great detail and where Woopsy has tabulated the moving spread values for all guns.


Recoil

Recoil is defined by its horizontal and vertical components defined in the files by RecoilLeft, RecoilRight, and RecoilUp. The vertical recoil and the mean horizontal recoil can be compensated for: ‘Recoil Compensation’.

The vertical component moves for each shot the aimpoint upwards apparently without randomness and so that for the first shot, the vertical recoil is multiplied by FirstShotMultiplier.

“In pseudo-code:”

For each shot after the first shot
if j=0
VRecoil = VerticalRecoil * FirstShotMultiplier
else
VRecoil = VerticalRecoil
ay(j+1) = ay(j) + VRecoil