Correction -- A novel by Dave
I was recently looking into this again after somebody asked me some questions about it. I noticed the things Clovis said in this topic, and even the things I said too, were not matching up with what was actually happening in-game when I did some tests. It turns out what we both said were wrong.
I've looked through the code again, AND tested in-game, and the following is what really happens.
First, we have to understand the issue of move order. This is important because it may seem like you "escaped a turnblock", when in fact a turnblock was never possible due to the particular order of moves. (Clovis has explained this system correctly, but I'll explain it again in my own way.)
So... Within in a turn, players can make several moves. Let's call that the "moves list". It may look something like this:
Player A:
- Build some units
- Move stack X from A to B
- Use stack Y to attack enemy stack Z
Player B:
- Build some units
- Move stack Z from C to D
At the end of the turn, the game processes these moves like so: 1) pick a random player, 2) process the first move from their list, 3) pick a random player (might even be the same player again), 4) process the next move on their list, and so on.
So the end result might look like this:
Player A -- Build some units
Player B -- Build some units
Player B -- Move stack Z from C to D
Player A -- Move stack X from A to B
Player A -- Use stack Y to attack enemy stack Z.
But that's just one possible result... it could just as easily come out another way, for example:
Player B -- Build some units
Player A -- Build some units
Player A -- Move stack X from A to B
Player A -- Use stack Y to attack enemy stack Z.
Player B -- Move stack Z from C to D
Other combinations are possible too, these are just 2 examples. As you see, the moves are taken "in order" in the sense that a player's first move is always done before his later moves... but overall it's random in the sense that Player A's moves could be before Player B's, or they could be after, or mixed in different combinations.
With that in mind, now lets consider what happens when you attack a stack that's moving. Let's say Player A has stack Y, and Player B has stack Z. Player A moves stack Y to attack Player B's stack Z. During the same turn, Player B moves stack Z from place C to D.
What happens at the end of the turn?
Well, if the move list looks like the first example above, we see that "Player B -- Move stack Z from C to D" is processed BEFORE "Player A -- Use stack Y to attack enemy stack Z". In other words, Player B's stack moves before Player A's attack. Now the question becomes distance -- did Player B's stack move out of range of Player A? If yes, then no attack happens. If no, then Player A's stack follows Player B's and attacks.
So, the point here is, depending on the order in which the moves are applied, a stack might "escape" before we even consider if its a turnblock situation or not.
Or, put another way, if the stack moves out of range of the would-be attacker, it escapes. There's no question of a turnblock in this case.
Finally, lets talk about turnblocks. Continuing with the above examples, lets say Player B is moving stack Z from place C to D. Meanwhile Player A is using stack Y to attack stack Z. Let's suppose stack Z's move is entirely within the range of stack Y, so escape due to range is not a possibility. So now we have, by default, a turnblock.
I say "by default", because the system starts with the assumption the move will be blocked. It then applies the "turnblock formula" as a possible means of escaping the turnblock, and only IF that is successful is the turnblock avoided.
To say that again, turnblocks ALWAYS happen, unless you win the chance to escape it.
So how to escape a turnblock? First, the defender (Player B) must have MORE THAN 3 units in his stack to escape. If you have 3 or less units, you will be turnblocked every single time. (Unless your stack escapes due to range, as discussed earlier, which happens before turnblocks enter into the equation.)
Assuming the defending stack has > 3 units, the famous "turnblock formula" now arrives:
If RandomNumber > AttackerArmyCount / DefenderArmyCount * 2
Then escape
(This is almost verbatim from the atWar source code... I've only simplified the names for clarity.)
RandomNumber is a random number between 0 and 1.
AttackerArmyCount is how many units are in the attacking stack.
DefenderArmyCount is how many units are in the defending stack.
Here's the problem though: this is NOT as Clovis wrote in the original post, when he said:
AttackerArmyCount / (DefenderArmyCount * 2)
Those parentheses are NOT present in the source code. It may seem like a slight difference, but it's actually really important as that completely changes the math order of operations here. As a result what I said in this thread about the max chance being 50% is WRONG!
It is, in fact, like this, without the parentheses:
AttackerArmyCount / DefenderArmyCount * 2
Which, in C# code, is mathmatically the same as:
(AttackerArmyCount / DefenderArmyCount) * 2
Now, I don't know if Amok/Ivan did it this way on purpose or not. Maybe this is what they wanted. All I know is I've never changed it... it is exactly how it was from their time.
What's so important about this? It means that... if the attacking stack is at least half the size of the defending stack, the defending stack has NO HOPE OF ESCAPE. In other words, they will be turnblocked every single time.
If there is a stack of 20 units and I send 10 units to attack it, it WILL BE turnblocked. Every time. (Again, unless the 20 stack moved out of range of my attack... that's the only loophole.)
If I send less than 10, against a stack of 20, it then becomes a chance. For example if I send only 5, the chance of TB will be 50%.
So to sum up, what does all this mean?
First, when attacking a stack that's moving, any of the following could happen:
1) it could move out of range, preventing the attack
2) it could move within range and the attack proceeds
Second, if the attack proceeds, you are now "turnblocked" unless you can escape from it:
1) If defender has 3 or fewer units, they can't escape. They are turnblocked.
2) If attacker has at least 50% the units the defender has, they can't escape. They are turnblocked.
3) Otherwise, there is a % chance the defender *might* escape.
So there.