# Best way to calculate fighting power?

Discussion in 'World Editor Help Zone' started by Ofel, Jul 21, 2018.

Tags:
1. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
So, I have a hero unit that will decide whether or not he will engage a group of hostile units. How do you think is the best way to calculate all the things needed for the hero to engage in a fight?

Calculate time to kill each enemy units? time they needed to kill the hero?
Total attack damage, armor, attack speed, (even movement speed)?

I just started to approach this by learning about damage reduction to try to calculate estimated death time of any units in combat, but I need your opinion.

I might need detailed info to approach this..

2. ### Nowow

Joined:
Jun 15, 2016
Messages:
426
Resources:
2
Tutorials:
2
Resources:
2
That depends on what data you can extract by triggers from each unit. A possible way to do it is by some sort of point system which will track and manage a hero's "fitness to engage" an enemy group. The system will increment certain amount of points for factors which will improve the hero's ability to fight, and decrement for factors leading to unfavorable results. Here are a few examples for factors:

- A hero's relative health & mana. But note those factors are not linear, as the difference between engaging with 70% hp and 40% is very big. You could put it in a formula like this
`hp_factor = total_hp*(hp_percentage**2)/10 - 30`
, and some similar formula for mana.
- The amount of available units in the hero's vicinity, can be further differentiated by type and percentage hp/mana.
- Enemy units present in visible areas, as well as enemy heroes along with hp and mana percentage, etc.
- Metrics like possible DPS dealt to the hero and such would be good, too, although I'm sure how you would collect them mid-game.

To put it generally, Allied units and heroes (including the hero in question) close by will increase engagement fitness if they can actually fight, if not they should reduce fitness. The same can be applied to visible enemy units and heroes, but with inverse effects on fitness. In the end, whether to engage or not will be decided by comparing the total fitness to some threshold number. This threshold can be played with according to AI difficulty, hero playing style, game state and any other metric you want.

This should generate a system smart enough for heroes to choose engagement with higher probability of success, although I think creating it might require a lot of fussing with fitness formulas and threshold tests. Either way that's an interesting topic, please keep updating.

3. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
Thank you for the idea.
I've never try doing with 'threshold' cuz I don't know what exactly a threshold is.. but I'll try to learn more.

Sorry for the late reply, I'm kinda busy but I still working with these AI stuff. I've made some deep coding on my AI system so I think I'll regret if I don't finish it. I'll be back to WE as soon as I got to my bedroom.

4. ### Pyrogasm

Joined:
Feb 27, 2007
Messages:
2,682
Resources:
1
Spells:
1
Resources:
1
Threshold is just a limit or value at which you do something. He's saying threshold because he suggests literally computing a number and then comparing that to another number (the threshold) that determines if they're ready to fight the enemies. For example:

Code (vJASS):
globals
real THRESH = 1.25 //only attacks if ally strength is 25% stronger than enemy strength
endglobals

function shouldFight ...
local real allyPwr = 0.00
local real enemyPwr = 0.00

set allyPwr = allyPwr + HERO_WEIGHT*LEVEL_FACTOR*HERO_LEVEL
set allyPwr = allyPwr + ALLY_WEIGHT*NUM_ALLIES
set allyPwr = allyPwr + HEALING_WEIGHT*HEALING_FACTOR //weighting the importance of each factor will be... important
set allyPwr = allyPwr + ...
// ...
set enemyPwr = enemyPwr + LEVEL_WEIGHT*NUM_CREEPS*AVG_CREEP_LEVEL
set enemyPwr = enemyPwr + ITEM_WEIGHT*NUM_OFFENSIVE_ITEMS
set enemyPwr = enemyPwr + ABILITY_FACTOR*NUM_OFFENSIVE_ABILITIES
set enemyPwr = enemyPwr + ...

return allyPwr/enemyPwr >= THRESH
endfunction

5. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
I see, thanks.. that's very useful example.

I don't really understand the formula :/
Why and how can that formula formulates as a useful factor?

Sorry if you found something confusing as english isn't my native language. *_*

6. ### Pyrogasm

Joined:
Feb 27, 2007
Messages:
2,682
Resources:
1
Spells:
1
Resources:
1
He's trying to resolve these two problems.

If you JUST look at each unit's total health percentage, a unit with a small actual amount of health (say 150) might think it can take on another unit with a very large amount of health (say 5000) simply because they both have 100% hp. Alternatively a 5k hp unit at 10% how actually has 500 health and should be able to defeat the 150hp hero at 100% hp.

So instead of comparing (unit a % hp) and (unit b % hp) you also multiply them by some other factor to scale up the comparison. What Nowow suggested is (unit a total hp)*(unit a % hp), which is actually just (unit a current hp) in this scenario, but you could use a different factor in front of it instwad. His concern is real and you gotta consider that because maybe you don't scale it by total hp if there's a better way. You'll have to find out.

What Nowow is saying about 40% vs 80% (he used 70, I think 80 is a better example) is a little nuanced. Once you get to low enough health health spells, strong attacks, and items start being able to kill the hero outright so when it reaches that low hp amount the hero becomes a big target. Players tend to order their ranged units to pick off weakend targets so the hero probably doesn't last long at that point.

Imagine the hero came into the fight at 80% hp, fights for 30 seconds, and dies. If it had come in at 40% hp it might only have lived 10 seconds (not the full 15s, which would be half as long as the hero with twice as much health). If he had come with 100% hp maybe he would have lived another 5 seconds (rather than 30*(100-80)/80 = 7.5s if it was proportional).

It won't always be that way but in general the unit having half the hp % of another unit probably doesn't even live half as long on the battlefield.

7. ### Wark

Joined:
Oct 12, 2016
Messages:
738
Resources:
2
Maps:
2
Resources:
2
This can easily be determined by linear level scaling for creeps, units or heroes, and making it all standardized with variations for specialized purposes.

Last edited: Jul 24, 2018
8. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
Okay, I think I'm getting it.

Linear level scaling?

9. ### Wark

Joined:
Oct 12, 2016
Messages:
738
Resources:
2
Maps:
2
Resources:
2
For example:
lvl 1 units have 100 hp, and deal 3 - 5 damage.
lvl 2 units have 150 hp, and deal 5 - 7 damage.
lvl 3 units have 200 hp, and deal 7 - 9 damage.

Something like that, so that a unit's level can accurately indicate its power rating in calculations.
Of course you may have some units that are ranged, some that are more tanky melee, some with spells, etc. for variation.
You'll just have to weight those differently with some coefficient value.
A rule of thumb is that a lvl 2 should beat a lvl 1 unit, but two lvl 1 units should beat a lvl 2 unit (with some exceptions, like unit counters).

Last edited: Jul 24, 2018

### Spell Reviewer

Joined:
Jan 18, 2005
Messages:
25,430
Resources:
3
Maps:
1
Spells:
2
Resources:
3
On top of health based "fitness" or threat one needs a per unit type value, possibly modified by the current life percentage. This is because some units might have low health but powerful abilities like the Undead Necromancer which can summon skeletons.

A step above that would be to factor in actual army compositions. So for example if the player has a largely air army and the enemy team has a lot of Siege Engines with upgrades then each siege engine should be worth more threat than if the player had a largely land army due to the Air Barrage mechanics of Siege Engines making them hard counter air.

11. ### Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
If the units are simple autoattackers in a 1v1 fight you can calculate the time it takes for one to kill the other.
Just take the health of defender and divide it by DPS of attacker, then you get the time in seconds. Do the same thing in reverse and you can already compare the results to know who will win. Since you know the result in time, you can make a unit engage only if the result is overwhelming enough.

12. ### Pyrogasm

Joined:
Feb 27, 2007
Messages:
2,682
Resources:
1
Spells:
1
Resources:
1
Good idea, but to show how this can be broken (ignoring armor for examples):
1. Footman with 100 hp, 50 damage per attack, 1 attack per second vs siege tank 100 hp 200 damage per attack, 1 attack per 5 seconds. Footman sees time-to-kill of 2 seconds vs siege's 2.5, but since siege damage is frontloaded into the first attack it will actually win on that attack... and then wait around for 5 seconds.
2. footman with 100 hp, 50 damage per attack, 1 attack per second vs ranger 100 hp, 50 damage per attack, 1 attack per second. Same TTK, but archer wins because it's ranged and gets its attacks in first.
3. Units with 1 hp, ranged attacks, very high dps, very high attack speed. Those would likely seem 'easy' to kill for most forces but they would actually annihilate.
I do, however, think that if you compared (total HP of force 1)/(total DPS of force 2) vs (total HP of force 2)/(total DPS of force 1) that might be a pretty good estimate of how the battle might go. Something tells me there should be an exponential in there because the strength of each force is decaying over time. A slightly stronger force that preserves slightly more units earlier on will be able to kill more and more and slightly more enemy units over time, like a lane autopushing in LoL.

Last edited: Jul 24, 2018
13. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
Is there other way to get a unit attack damage including bonuses?

14. ### Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
Yeah, my model is simple, but you can basically make it support anything. Armor is just a % increase to health against autoattacks, range is just extra time, which is countered by the opponent's speed. Etc.

### Map Moderator

Joined:
Jan 30, 2013
Messages:
7,617
Resources:
27
Packs:
1
Maps:
8
Spells:
16
Tutorials:
2
Resources:
27
Damage Detection?

### Spell Reviewer

Joined:
Jan 18, 2005
Messages:
25,430
Resources:
3
Maps:
1
Spells:
2
Resources:
3
So the following does not factor in bonuses?
Code (vJASS):
native BlzGetUnitBaseDamage takes unit whichUnit,integer weaponIndex returns integer

17. ### BloodSoul

Joined:
May 10, 2009
Messages:
728
Resources:
2
Spells:
2
Resources:
2
No. It takes into account only "Combat - Base Damage" and the primary attribute (both base and bonus)

18. ### Ofel

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10
No, it cannot return directly as what is written on the game interface (base and bonus).

They only return the data that we input from Object Editor I guess. Just like the new collision function.

19. ### Light

Joined:
Apr 23, 2011
Messages:
491
Resources:
0
Resources:
0
I think there was a DDS that could return the pure amount of damage that would have been dealt if there were no reductions. Wouldn't it help in regards to calculating DPS?

Joined:
Mar 29, 2012
Messages:
439
Resources:
10
Spells:
10
Resources:
10