This is an old revision of the document!
This will on several occasions walk through the processes described on this page, it might be useful to keep both open.
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.
Picture the following:
The finer details of these gear setups are not too important. The green clouds are from a popped mossbody (the werewolf broke moss with a smasher, but that's not relevant for this analysis).
The colossus here (after buffs and items) is 5
4
4
4
4 with 27 strength, 32 protection, 24 shock res, 12 precision.
The werewolf here (also after buffs and items) has 30 shock res, 31 strength, 25 protection.
If you owned the colossus and could have it cast any spell you wanted, you'd probably choose fists of iron and direct all of its effects into the werewolf, as with these stats it would be extremely likely to just outright delete the werewolf in a single cast and win the battle.
What the casting AI decided to do is instead cast shock wave at the square marked X, with coordinates 22, 8. The numbers in orange denote the coordinates of the other squares containing enemies, which the AI trial-runs its casts at. But more on that later.
Note that this analysis references two debug log lines that do not normally exist: I modified the executable to make it write these
As I am running this in debug level 2, any replay desyncs are made very obvious by messages in the top left of combat. Based on this and no observable differences in the playback of the fight in question (which was a Clockwork multiplayer game, hosted on a normal executable) I am fairly confident that my increased reporting has no adverse effects on gameplay.
The log:
spellunitscore against no one nr 87264: 120 spellunitscore against Large Spider nr 15: -10 spellunitscore against Large Scorpion nr 18: -10 spellunitscore against Frog nr 20: -10 spellunitscore against Red Ant nr 9: -10 best Shock Wave this far, 20 8 (585 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) spellunitscore against no one nr 87264: 120 spellunitscore against no one nr 87264: 120 best Shock Wave this far, 22 8 (1105 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) spellunitscore against Bronze Colossus nr 25006: 0 inferior Shock Wave, 22 9 (221 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) spellunitscore against no one nr 87264: 120 spellunitscore against no one nr 87264: 120 inferior Shock Wave, 24 10 (1075 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) spellunitscore against Jotun Werewolf nr 2157: 0 inferior Shock Wave, 22 11 (68 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) inferior Shock Wave, 23 11 (218 pnts) (midedge 120 60, marg 1, pot 6, hostile 1) spellscore, Shock Wave score 1089 (boost 99 scorat 0) Eval: Shock Wave score 1183 (fat 2) comp_castspell: eval Shock Wave result 1183 best spell so far Shock Wave (score1183)
There's a fair amount going on here, both in what is written and what is not.
Importantly there are blocks of scores against individual units, followed by a "best Shock Wave this far" or "inferior Shock Wave" line, which details the lists the coordinates being checked and the final score it got for casting at this position. There's also more numbers in brackets after the score (or "pnts") but this can safely be ignored here.
The other twist is that the game caches scores against squares, that is to say that it will only calculate shock wave once per square it can possibly affect. When reading cached values NOTHING is written to the log, which makes following what is going on a bit harder.
But, in this situation, simulating shock wave will always consider a square spread of 1, IE a 3x3 box around the primary square being targeted. Let's start by running through the chosen outcome, targeting (22, 8).
Here, the simulation sees the imp in the primary square, and the imp in the square between that and the colossus (22, 9). The log tells us that the score for the shock on a single imp is 120 (my hack to get the extra debug line is not perfect and sometimes fails to get the unit being referred to, in this case they are the "no ones").
Rather than simply add the two 120 results together for the two imps, the game takes into account that the middle square is by far the most likely to be hit. Specifically, it does this by multiplying the middle square scores by a larger number (20 * spell aoe) than the outside squares (10 * spell aoe). Once all the scores are added up, the result is then divided by 100.
Shock wave's AoE is 6. Thus the score for the two imps is 120 * 20 * 6 + 120 * 10 * 6 = 21600, or 216 when divided by 100.
This score than has a closed d10 added to it, then has 5 subtracted from it. Due to the small average change, we'll ignore this for now.
As the spell hits enemies and the targeted square is within 10 of the colossus (the actual distance is 2), we multiply it by 10 and then divide by the distance, giving a net multiplication of 5 and a final score of 1080. The log gave a result of 1105, which means that the closed d10 rolled the maximum 10 in this case.
The log later does make this become 1089 when applying the randomness for all spell results later, but that is not important for this analysis.
We can see that, for the analogous square (24,10), the log result is 1075, which is consistent with a d10 result of 4. Needless to say that doesn't beat the maximum d10 roll above, so the choice here can be easily explained.
The mystery is, given that the log clearly states that the scores for the werewolf and colossus are 0 due to their shock resistance, why is the score for (23,11) only 218, about a fifth as large? It would seem logical that it also falls into the 1080 ± 25 result calculated above, but something is altering it.
Despite what the debug log line made (the "inferior Spell"… line was added by me, and I likely either don't understand what hostile 1 means or loaded the wrong value onto the stack for it, this was my first bit of fun writing assembly and I found it hard), the most likely explanation is that the cast at (23,11) is not recognised as hostile due to drawing all its score values from the cache, which is very likely a bug. This means that it skips getting the net multiplication of 5, which would give a final calculated score of 216 ± 5 - which fits with the log result.
The simulation at (22, 11) may also suffer from this, as the hostile flag is only set if the final score is greater than 0. This did run a fresh score, but against the werewolf where the flag would not have been set.
Only target is the imp in the secondary square 120 * 10 * 6 = 7200 / 100 = 72
When given the random ±5 this is consistent with the log reported value of 68.
With the case closed on the shock wave portion of the log, let's examine what it had to say about Fists of Iron.
spellunitscore against no one nr 87264: 70 spellunitscore against no one nr 87264: 70 spellunitscore against Bronze Colossus nr 25006: -70 best Fists of Iron this far, 22 9 (275 pnts) (midedge 80 40, marg 1, pot 3, hostile 1) spellunitscore against Jotun Werewolf nr 2157: 120 spellunitscore against no one nr 87264: 70 best Fists of Iron this far, 22 11 (460 pnts) (midedge 80 40, marg 1, pot 3, hostile 1) spellunitscore against no one nr 87264: 70 best Fists of Iron this far, 23 11 (515 pnts) (midedge 80 40, marg 1, pot 3, hostile 1) spellscore, Fists of Iron score 483 (boost 93 scorat 0) Eval: Fists of Iron score 497 (fat 7) comp_castspell: eval Fists of Iron result 497 loser spell Fists of Iron (score 497)
Fists of iron inflicts 16 damage, +1 per additional caster level, and adds the caster's strength. When used by the colossus at 4, it inflicts 19 + the 27 strength = 46 points of magical blunt damage.
Additionally, it has one effect per caster level, so this colossus has a total of four "swings". For reference, the jotun has 25 protection and 53 hp plus 4 undying. Despite this, 4x(46-25) = 84, producing enough expected damage barring limb caps to kill the wolf in a single cast, and yet the casting AI chalks this up to be a bit under half as useful as shock wave.
Upon reading this log, there are a few things to consider:
First, the colossus is considering that it can hit itself. Based on my notes, I think this can technically happen but the risk is very very minimal:
12 colossus base precision +5 fists of iron precison bonus -4 per number of effects = 13 /3, 2% chance = 4 if (4/2)-2 < distance, IE 1, deviation will occur. With these parameters, the deviation will be 1 square So there is a 2/(100*9) per swing (IE: 0.22% chance) to hit himself.
Second, the lethality of the spell is lost in these calculations. This is likely the result of both issues in spellunitscore and also due to shock wave's square weights being multiplied by the area of effect.
We see that the spell effect scores 70 vs imps, -70 against the colossus, and 120 against the werewolf. Shock wave on the other hand scores 120 vs imps. But where did these come from?
Imps have 8 hp, 9 strength, and 6 protection. This means that the cap of (max hp + 5) limits damage to 13 against them. The other values come into play later.
Fists of Iron is treated poorly in multiple ways here. First, the fact the caster's strength is added is not respected means the colossus is considered to do 19 damage and not 46. Second, as a single target spell that does not ignore shields, its damage is reduced to 2/3, rounded down.
As such, its calculations proceed as follows:
Imp
19 - Damage after E4 caster level As it is fully protection respecting we add (1 - target's prot), IE -5 = 14 Apply the max hp +5 limit, reduced to 13 Reduce to 2/3, rounded down = 8 Next, we calculate the strength value, damage + (target's strength) - 10 = 8 + 9 - 10 = 7 The score for damaging effects is 10 * strength value = 70
Jotun Werewolf
19 - Damage after E4 caster level As it is fully protection respecting we add (1 - target's prot), IE -24 = -5 Max hp+5 limit does not apply Reduce to 2/3, rounded towards 0 = -3 Next, we calculate the strength value, damage + (target's chassis base strength) - 10 = -3 + 25 - 10 = 12 The score for damaging effects is 10 * strength value = 120
Shock wave vs imps, on the other hand…
12 - Damage after A5 caster level As it is AN we add 1 = 13 Apply the max hp +5 limit, no effect Next, we calculate the strength value, damage + (target's strength) - 10 = 13 + 9 - 10 = 12 The score for damaging effects is 10 * strength value = 120