I think one key information missing is what range of damage you'd like to see (minimum to maximum).
The range of damage values is only a scaling factor, so simple to manage that I forgot it in the example formulas in my post.
The starting points are
- A set of benchmarks: the fight of unit A vs. weaker unit B should end with A's victory with probability p, often p=1, and its duration of n turns should follow a distribution with a given mean N and a given minimum and maximum, possibly approximate.
- A range of hit point totals for different units: highly compressed like in Warhammer to make defense and "saving" hit points a big deal, extremely wide like in D&D to make minor damage insignificant, or something in the middle.
Given these constraints, it's obvious that, if unit B has b hit points, A's typical attack should do b/N average damage per turn, independently of how the stats and equipment of A and B determine damage.
Different ways to do b/N damage per turn are also independent from stats:
- Fixed and certain damage X every turn: X=b/N. Only an option if hit point ranges are large or N is very small, or the necessary rounding to an integer will distort damage values.
- Random damage: unit A's damage can be a random variable with an average of b/N. Winning probability p and the distribution of fight duration n can be computed from the distribution of damage.
- A chance to miss: if unit A hits with probability q, doing X damage, q*X=b/N. Critical hits are a slight generalization to X or Y damage rather than X or nothing: q*X+(1-q)*Y=b/N. With both misses (probability 1-q) and critical hits (probability c conditional on hitting) you simply add three branches for X,Y and 0 damage: q*(c*X+(1-c)*Y) =b/N. And so on; X and Y can, of course, be random variables.
- Random delay: if unit A attacks (on average) every m turns doing X damage each time, X/m=b/N. In most games X<b (no 1-hit kills) implying m<N.