This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
user:loggy:castingaiexample [2022/02/15 20:56] loggy created |
user:loggy:castingaiexample [2022/12/14 04:18] (current) loggy |
||
---|---|---|---|
Line 4: | Line 4: | ||
===== The colossus and the werewolf ===== | ===== The colossus and the werewolf ===== | ||
+ | |||
+ | **This was run on 5.54. In 5.57 the cached offensive flag was replaced by a simple switch to an offensive effect number, meaning that this part of the discussion no longer applies** | ||
I wrote primarily for myself to better understand this case. In places it won't be structured logically, but rather it represents how I thought about the discrepancy. | I wrote primarily for myself to better understand this case. In places it won't be structured logically, but rather it represents how I thought about the discrepancy. | ||
Line 162: | Line 164: | ||
The score for damaging effects is 10 * strength value = 120 | The score for damaging effects is 10 * strength value = 120 | ||
| | ||
+ | ===== Hypotheticals and Blade Wind ===== | ||
+ | |||
+ | AKA: "Why does the casting AI love to cast ??Blade Wind???" | ||
+ | |||
+ | A lot of the values that come up in my rather lengthy and dry notes aren't going to be really meaningful, so let's pick a competitor, something like say the fairly humble ??Falling Fires??. Notably, Blade Wind is 4x the fatigue cost, and gets penalised for that, but let's forget about that for now. I'll get back to that later if I remember. | ||
+ | |||
+ | For the sake of this, I'm assuming " | ||
+ | |||
+ | * Falling fires: aoe 3, nreff 1, 15pts AP fire | ||
+ | * Blade wind: aoe 0, nreff 35, 14pts mundane slashing | ||
+ | |||
+ | Let's assume (as is the case in most battles) that we're not dealing with things within 5 range of the mage, as that uses different stuff for blade wind. For AoE spreading, both of them fall under... | ||
+ | |||
+ | If the spell' | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | |||
+ | This means mages are looking at 3x3 boxes (1 square deviation in all directions from the square being considered) of units. The weights (more on what these are used for later are): | ||
+ | |||
+ | Falling fires: accurate = 60, inaccurate = 30 | ||
+ | Blade wind: accurate = 700, inaccurate = 350 | ||
+ | | ||
+ | ==== Unit Scores ==== | ||
+ | |||
+ | Now we're onto unit scores, which are a numeric value of how much the AI rates casting the spell on one specific unit - how many are then in the considered area is the basis of the spell score. Let's, for the sake of examples, look at fully packed squares of two unit types. For the sake of an example, I'm picking ?? | ||
+ | |||
+ | I'll pull all the relevant values together when they' | ||
+ | |||
+ | === Barbarian === | ||
+ | |||
+ | 7 prot, 13 hp, 12 strength. | ||
+ | |||
+ | == Falling Fires == | ||
+ | |||
+ | * This is AP, so we add (1- prot/2) rounded down. | ||
+ | * Final damage = 15 (base) + (1 - 7/2) = 15 + (1 - 3) = 13. | ||
+ | * This does not exceed target max hp + 5 (18) so doesn' | ||
+ | * Strength value = 12 (str) - 10 (constant) + 13 (final damage) = 15 | ||
+ | * Final score for damaging effects = strength value * friendly bias (this is just 1 for hostiles, and -1 for friends) * 10. | ||
+ | * = 150 | ||
+ | |||
+ | == Blade Wind == | ||
+ | |||
+ | * This isn't AP, so we add (1 - 7) = -6 | ||
+ | * Final damage = 14 - 6 = 8 | ||
+ | * Spell is single target and doesn' | ||
+ | * Strength value = 12 (str) - 10 (constant) + 5 (final damage) = 7 | ||
+ | * Final score = 70 | ||
+ | |||
+ | === Wolf === | ||
+ | |||
+ | 8 hp, 9 str, 2 prot. | ||
+ | |||
+ | == Falling Fires == | ||
+ | |||
+ | * This is AP, so we add (1- prot/2) rounded down. | ||
+ | * Final damage = 15 (base) + (1 - 2/2) = 15 + (1 - 1) = 15. | ||
+ | * This does exceed target max hp + 5 (13) so gets lowered to this | ||
+ | * Strength value = 9 (str) - 10 (constant) + 13 (final damage) = 12 | ||
+ | * Final score for damaging effects = strength value * friendly bias (this is just 1 for hostiles, and -1 for friends) * 10. | ||
+ | * = 120 | ||
+ | |||
+ | == Blade Wind == | ||
+ | |||
+ | * This isn't AP, so we add (1 - 2) = -1 | ||
+ | * Final damage = 14 - 1 = 13 | ||
+ | * Spell is single target and doesn' | ||
+ | * Strength value = 9 (str) - 10 (constant) + 8 (final damage) = 7 | ||
+ | * Final score = 70 | ||
+ | |||
+ | === Heavy Infantry === | ||
+ | |||
+ | 10 hp, 10 str, 14 prot. | ||
+ | |||
+ | == Falling Fires == | ||
+ | |||
+ | * This is AP, so we add (1- prot/2) rounded down. | ||
+ | * Final damage = 15 (base) + (1 - 14/2) = 15 + (1 - 7) = 9. | ||
+ | * This does not exceed target max hp + 5 (18) so doesn' | ||
+ | * Strength value = 10 (str) - 10 (constant) + 9 (final damage) = 9 | ||
+ | * Final score for damaging effects = strength value * friendly bias (this is just 1 for hostiles, and -1 for friends) * 10. | ||
+ | * = 90 | ||
+ | |||
+ | == Blade Wind == | ||
+ | |||
+ | * This isn't AP, so we add (1 - 14) = -13 | ||
+ | * Final damage = 14 - 13 = 1 | ||
+ | * Spell is single target and doesn' | ||
+ | * Strength value = 10(str) - 10 (constant) + 0 (final damage) = 0 | ||
+ | * Final score = 0 | ||
+ | * Aka: the casting AI won't want to do this at all! | ||
+ | |||
+ | ==== Square totals ==== | ||
+ | |||
+ | Adapted from the notes: | ||
+ | |||
+ | Check a square of tiles containing units. As per the above, this is a 3x3 box, for 9 squares total. | ||
+ | | ||
+ | - Sum the unit scores of the things in that square. | ||
+ | - If there was more than one thing in the square, and the spell affects only 1 person, divide the summed score by the number of units in the square | ||
+ | - If the square struck was the originally picked square at the centre of the 3x3 spread... | ||
+ | - add (this square' | ||
+ | - Otherwise, add (this square' | ||
+ | |||
+ | === Wolf === | ||
+ | |||
+ | == Falling Fires == | ||
+ | |||
+ | Relevant values from above: | ||
+ | |||
+ | * Spellunitscore = 120 | ||
+ | * accurate weight = 60 | ||
+ | * inaccurate weight = 30 | ||
+ | |||
+ | Onto new calculation: | ||
+ | |||
+ | * A square of wolves has three of them, so total unit score for each square = 360. | ||
+ | * Falling Fires has AoE > one person, so we're not dividing anything. | ||
+ | * Because we're dealing with a 3x3 box of all the same unit, we get 8 " | ||
+ | * = 8 * (360*30) + (60*360) = 86400 + 21600 = 108000 | ||
+ | |||
+ | == Blade Wind == | ||
+ | |||
+ | Relevant values from above: | ||
+ | |||
+ | * Spellunitscore = 70 | ||
+ | * accurate weight = 700 | ||
+ | * inaccurate weight = 350 | ||
+ | |||
+ | Onto new calculation: | ||
+ | |||
+ | * A square of wolves has three of them, so total unit score for each square = 210. | ||
+ | * Blade Wind is AoE = one person, so we divide by the number of units in the square and go back to 70 again. | ||
+ | * Same deal, 8 squares with the inaccurate weight, 1 with the accurate weight. | ||
+ | * = 8 * (70*350) + (70*700) = 196000 + 49000 = 245000 | ||
+ | |||
+ | === Barbarian === | ||
+ | |||
+ | == Falling Fires == | ||
+ | |||
+ | Relevant values from above: | ||
+ | |||
+ | * Spellunitscore = 150 | ||
+ | * accurate weight = 60 | ||
+ | * inaccurate weight = 30 | ||
+ | |||
+ | Becomes... | ||
+ | |||
+ | * One square' | ||
+ | * = 8 * (450*30) + (60*450) = 108000 + 27000 = 135000 | ||
+ | |||
+ | == Blade Wind == | ||
+ | |||
+ | Relevant values from above: | ||
+ | |||
+ | * Spellunitscore = 70 | ||
+ | * accurate weight = 700 | ||
+ | * inaccurate weight = 350 | ||
+ | |||
+ | These numbers are exactly the same as the wolves. We end up at 245000 here too. | ||
+ | |||
+ | ==== Theoretical results ===== | ||
+ | |||
+ | If you've read the debug log and seen the spell scores before, you'll notice that these are extremely large compared to what you get there: the game divides them by 100 and throws some randomness in there before working with them. If you opened up the game and actually did this, you'd also run into this, but assuming I haven' | ||
+ | |||
+ | There are other things not included, there' | ||
+ | |||
+ | ^ Unit ^ ??Blade Wind?? ^ ??Falling Fires?? ^ | ||
+ | | ??Wolf?? | 2450 | 1080 | | ||
+ | | ?? | ||
+ | |||
+ | For the sake of completeness, | ||
+ | |||
+ | ==== Practical Testing ==== | ||
+ | |||
+ | The above mentioned precision and distance factors need taking into account. Dominions does not output the scores before they are applied. Due to the fact this needs 3x3 packed squares, I modded off undisciplined (via #clearspec) for these units to make my life a LOT easier. This doesn' | ||
+ | |||
+ | I empowered a Mound King (it was what I had laying around) and foward positioned him against a bunch of the respective unit types on hold and attack. | ||
+ | |||
+ | === Barbarians === | ||
+ | |||
+ | best Falling Fires this far, 26 18 (500 pnts) (midedge 60 30, marg 1, pot 27, hostile 1) | ||
+ | best Falling Fires this far, 27 18 (518 pnts) (midedge 60 30, marg 1, pot 27, hostile 1) | ||
+ | best Falling Fires this far, 27 19 (519 pnts) (midedge 60 30, marg 1, pot 27, hostile 1) | ||
+ | |||
+ | All of these coordinates are 3x3 boxes packed with barbarians. The caster himself is at (53, 20). The first entry is one square further away than the next two. The total distance between the caster and the middle line (27, 18) is %%sqrt((53-27)^2 + (20-18)^2)%% = 26 squares, once rounded down. Even unrounded it's only marginally larger than that anyway (Python' | ||
+ | |||
+ | Above I predicted a whopping 1350, and got something a bit under half of what I expected. Notably, it falls foul of: | ||
+ | |||
+ | If the spell' | ||
+ | |||
+ | score = max(1, (score * 10)/max(10, distance from caster)) | ||
+ | |||
+ | Putting 1350 into this gives max(1, (1350*10)/ | ||
+ | |||
+ | best Blade Wind this far, 24 17 (443 pnts) (midedge 307 153, marg 2, pot 27, hostile 1) | ||
+ | best Blade Wind this far, 26 17 (713 pnts) (midedge 307 153, marg 2, pot 27, hostile 1) | ||
+ | best Blade Wind this far, 25 18 (727 pnts) (midedge 307 153, marg 2, pot 27, hostile 1) | ||
+ | best Blade Wind this far, 26 18 (914 pnts) (midedge 307 153, marg 2, pot 27, hostile 1) | ||
+ | |||
+ | These scores are highly variable. The highest one, (26, 18), is further away than falling fires we looked at, and comes to 27 squares away after Pythagorus %%- math.sqrt((53-26)**2 + (20-18)**2) = 27.073%% | ||
+ | |||
+ | |||
+ | The range modification: | ||
+ | |||
+ | |||
+ | The high fatigue penalty is, usefully, applied after these values are written to the log. In any case, this was the first cast of the battle, and when starting at 0 fatigue neither of these spells suffered from it. | ||
+ | |||
+ | But, how much damage is Blade Wind really going to do in reality anyway? |