No worries. I assume it is for a professional, but I then again for someone that taught himself programming in the evening with no real need for readable coding in the job that is excusable.
Readability is fine,
But here is an optimization,
def correct_time(val):
if val>0: return math.ceil(val*8)*0.125
else: return 0
Well then I'll just hand out the pre-version right away.
This is a zip file containing the weapon_report as exported from the attribute editor (thanks to MMX for providing this since my table program fucks it up) and an ipynb file with the necessary code (I used jupyter notebook for that). Needs pandas, numpy and plotly.express libraries installed (most recent version, older ones should work too). You can also use seaborn instead, just change the last cell accordingly.
Don't take this the wrong way but as a software dev some of the code just looks so inelegant.
Well then I'll just hand out the pre-version right away.
This is a zip file containing the weapon_report as exported from the attribute editor (thanks to MMX for providing this since my table program fucks it up) and an ipynb file with the necessary code (I used jupyter notebook for that). Needs pandas, numpy and plotly.express libraries installed (most recent version, older ones should work too). You can also use seaborn instead, just change the last cell accordingly.
All of those squads have a preferred range, though. Fallschirmjager are exceedingly strong at /every/ range.
Ok, so what is the preferred Range for LMG Para's vs Grens/Volks/LMG obers??? the answer is every range.
What do you think the preferred of 2x LMG mandos are vs PG's/IR obers/LMG Obers??? the answer is every range.
Those squads are also extremely strong at all ranges.
Currently, the only source of DPS for small arms fire is Cruzz’ formula (also see Vipper’s guide), as well as coh2.serealia.ca which is an updated version that apparently uses Cruzz’ formula as well. However, no one knows where this formula came from.
When I tried to re-calculate these values on my own, I was unable to replicate the exact same values. Since this error could become quite large. I did some more digging only to find out that the formula does not match what I saw in-game.
Some time ago when I tested tank cannons, I found another probably game engine-related issue that increased the time between shots by 0.125 per used stat (I will call this 0.125 addition ‘correction time’ from now on), therefore I expected a similar issue with small arms. I then started iteratively modding and things turned out to be more complicated than that, but finally time I can present a model that:
I’ll spare you the lengthy details, in essence I had to test every stat separately to see how it behaves, changed it in a mod and then measured the time in-game by hand. If some of you wish to see the raw data, I can provide it but warning ahead it is quite convoluted. "Readability” was not an aim since I initially thought it would only be a quick notation sheet.
Additionally, one limitation is that I had to use "fixed" stats, meaning every stat was defined. The game however often uses randomization for some stats. Although I am fairly certain that I checked for all or at least most of this and my new model reflects this randomness, I cannot exclude with 100% certainty is that this will lead to minor differences in the game and in my model. However, these differences will be minor, so I am confident to say that the new formula is better than the old one in any case.
The following spoiler defines a couple of “functions” that are necessary to understand the final formula:
Single fire weapons:
Stat overview:
The easiest way to calculate the DPS is to calculate the expected damage done and divide by the time for a complete shot cycle. Therefore, all variables that are randomly picked from an interval need to be taken as the mean between the interval borders. For brevity and visual clarity, I won’t note it down in the formula.
Expected damage:
Note ahead: Accuracy and penetration are capped at 1. The braces are only there to group related stats and not needed for calculation
It’s fairly straight forward: chance to hit times chance to pen times bullets in magazine times damage per bullet.
Cycle time:
This means the model cycles through (fire_aim_time + wind_up + wind_down + cooldown) until the last bullet left in the magazine. For the last bullet, no cooldown is applied and the model directly enters the reload animation.
I have seen that the model also sometimes has intermediary animations (looking left and right, cowering etc. This does NOT affect the timings.
Burst fire weapons:
This is were things get tricky mostly because we get some additional stats.
Stat overview:
The reasoning is the same as before: Expected damage divided by the time needed.
Expected damage:
Accuracy and penetration are capped at 1. The braces are only there to group related stats and not needed for calculation. I only have limited data on the ROF*burst_duration, but from what I saw this value is not rounded down. If a “half bullet” is calculated, there is either a random check of the bullet is given or not or it is carried over to the next cycle. I assume the latter, but not sure.
Same as before. But since we have multiple bullets instead of one, we add another factor to calculate how many: ROF times burst_duration.
Cycle time:
Same as before. We just add the burst_duration.
Further comments:
The old formula adds the ready_aim time. This is false. Ready_aim time defines the time to focus on a new enemy and is applied only ONCE at the beginning of the fight. It also subtracts the fire aim time. This is false too.
Aftermath
(I'll quickly add another paragraph to give some perspective)
So, what about all this. Overall this doesn't sound like a huge change, does it?
Depends on the weapon you look at. Literally all DPS profiles in coh2.serealia.ca are incorrect. Some values are still close to each other, others are not. For example, the Ranger M1A1 carbine is shows as having 10 DPS in serealia at range 0-4. My in-game tests however showed something closer to 8 (39-40 seconds needed to kill 4 Partisans with in total 320 HP at point blank which leads a DPS of 8-8,2. This leads to a difference of 20% in this rather extreme case. My formula calculates 8,207 which seems to be way closer to the in-game situation. In serealia, the Tommy Bren gun starts at 4,1 and ends at 6,9 DPS, my formula calculates 4,5 (+10%) and 6,95 (+0,1%) respectively. Or the Gren K98 goes from 5,99 to 2,26 DPS, while the new formula returns 5,27 (-12%) to 2,16 (-4%). We're currently in a state of the game where things are in general decently balanced, every move we make now can naturally only be a tiny step. If we want to make further changes, we need to get the correct numbers. I checked some few weapons in the game and my model is consistent with what I measures in game regarding timings and a couple of DPS data I tried to measure. I encourage everyone to do some measurements though themselves and also report back what they got.
I’ll leave it at this for now, it is quite a wall of text already. I spent a lot of time on this already, if anyone has doubts about my formula I would kindly ask to gather some data yourself. I will be all ears for discussion, but after countless cycles of changing stats and stopping times, I would like to have a break on this.
I hope this helps for the upcoming commander patch. I might (no promises) release a python script soon to calculate and compare weapons.
Hannibal out
I have a python script that uses the old formula. If you tell what the adjustment that need to be made I can modify a line or two of that code in the mean time to check.
Fallschirmjägers are overpowered and have needed a nerf for a long time
Not really. Considering LGM para's are stronger at long range and are far more tanky. And just about every
cqc infantry squad are more tankier then them + allied infantry in general are more resilient and have higher dps. If you don't consider Shocks, Rangers, Paras, Mandos too be OP and long deserved of nerfs than Falls don't deserve it either.
OKW also has 4 close to mid range squads (Strums, Volks, Pfus, and Fallschirmjägers) but what OKW does lack a mainline long range combat infantry
M8 i don't about you but a single FG42 has the same max range dps as a single Bren LMG and has higher dps than a BAR(equal to mando sten) at close range i'd call em every range.