AI_GetDamagePotential
...
The penalty we take on performance is quite significant. The fan-out may be only 10 (ontop of the previous one, for a total 160x number of leaves compared to 2.3 AI), but the tracing calculations needed here are a heavy factor.
Performance optimizations needed: An obvious proper bridge to the G_ClientShoot (no reason to try 10x, instead it can give us a base dmg+deviation), OR a complete copy of the damage calculations inside the AI code (bad, code replication&heavy maintenance). Best solution is a mathematical equation that can give us comparable results with minimal CPU.
For people wanting to try and extract the math equations, have a look at g_combat.c. Entry point is G_ClientShoot. HELP APPRECIATED, I SUCK AT MATH
Been looking at this at work today. I have a couple ideas:
1. Instead of 10x, what if we set up a delta value. We run it once to get a base value and if the 2nd run is within the deltaof the first value we just return the average of the two. If it isn't, we keep running up to 10x until the average is within the delta.
For example:
delta = 10
run 1: damage = 100
run 2: damage = 94 (avg 97)
returns 97
or
run 1: damage = 100
run 2: damage = 25 (avg 62.5)
run 3: damage = 44 (avg 56.3)
return 56.3
2. Personally, I like the project management time estimation formula ( (worst case + best case + 4x most likely) /6 ) So we'd run it at least three times. Take the best, worst, and average. Then put it through the formula. The 2nd example above would return 58.3.
AI_HideNeeded
...
Now, this function is what cause the MAJOR fan-out disaster of doom. If you exclude the changes in this function, the AI is fast enough to play, but here we fan-out again, ontop of our 160x worst case scenario. For every of those leaves we check the damage possible for every enemy. Yes, that's another set of the same fan-outs we had up to this point (we just have num_enemies, not num_enemies+civilians). So that's a worst-case scenario of 8, bringing our fanout up to 8x10=80. Since this is in sequence with the damage calculations, this is multiplicative bringing the total amount of leaves to 160x80=12.800 for a worst case scenario. Yes, this is the point where the CPU just shrieks and tries to liftoff. And don't forget, the shooting calculations are a whole lot heavier than any other calculation we ever do.
Obviously, this would need to be another place were we need to improve quite a bit if we still intend to perform full-tree non-heuristic searches. Only checking only vs enemies that have a direct line of sight would be a first step (but that would make us oblivious to indirect-fire nades/launchers). Other than that, I can't see many ways to keep this functionality and still preserve a full-tree searching. The performance of this function is mainly influenced from the AI_GetDamagePotential function, so any performance gain (in fan-outs) there affects this function in a sqrt kinda of way (8x8 vs (8-Y)x(8-Y)).
And a couple for this as well:
1. Still go through every actor, but only do the calculation if the actor is visible or has a grenade/launcher weapon.
2. Maybe if one of the 10 calls to G_ClientShoot returned a value higher than the HP * GUETE_DAMAGE_AVOID_FACTOR, that would be enough for them to hide. So stop looping if that happens and just make them hide.