First of all lets see the defection on map for reference:
The clan that defected here is Dolentos, taking cities Diathma and Amprela from Southern Empire and joining Northern Empire, which had no settlements at the time.
Here is the values my mod logged regarding this defection decision:
Base Settlement Value: This is calculated value of all of the settlements the clan has. It also checks geographical position to current faction's middle point. Since this calculation was before defection, it was calculated for Southern Empire. 618k for 2 cities is pretty normal as we can see from my previous message considering both cities are far from Southern Empire's middle point.
Settlement Value For Southern Empire: This is calculated value of all of the settlements the clan has from the viewpoint of Southern Empire. The difference from the above calculation comes from the fact that the two geographical advantage calculations are different. Now here 1.5m is a little higher but still normal for 2 cities.
Settlement Value For Northern Empire: Same calculation above done from the viewpoint of Northern Empire this time. However this time the value is 821m. About 500 times the Southern Empire. Very odd.
Before I go into checking if this crazy value has an effect on defection, first lets see why this happens.
Here is the geographical advantage code:
C#:
private float GeographicalAdvantageForFaction(Settlement settlement, IFaction faction)
{
Settlement factionMidSettlement = faction.FactionMidSettlement;
float distance = Campaign.Current.Models.MapDistanceModel.GetDistance(settlement, factionMidSettlement);
float distanceToClosestNonAllyFortification = faction.DistanceToClosestNonAllyFortification;
if (faction.FactionMidSettlement.MapFaction != faction)
{
return Campaign.AverageDistanceBetweenTwoFortifications / (distance + 0.1f);
}
if (settlement.MapFaction == faction && distance < distanceToClosestNonAllyFortification)
{
return MathF.Clamp(Campaign.AverageDistanceBetweenTwoFortifications / (distanceToClosestNonAllyFortification - distance), 1f, 4f);
}
float num = (distance - distanceToClosestNonAllyFortification) / Campaign.AverageDistanceBetweenTwoFortifications;
return 1f / (1f + num);
}
Now my personal opinion is this method, even ignoring the bug I am going to explain, is not well thought. The result of this method is used as a multiplier, which means you can get 10-40 times the values due to calculation difference thanks to `if` conditions here. But for the moment lets focus on the bug in this particular situation.
Remember that before defection, Northern Empire didn't have any settlements. So in that case what is the `FactionMidSettlement` for it? It is definitely not `null` (meaning nothing) because the code assumes it is not. So they know for sure it can't be `null`. My guess is that it still uses the old one. And in this particular situation, that old one must be either Diathma or Amprela.
Keeping that in mind, lets check first condition. Game executes first `return` line
if faction's middle settlement is not part of the faction. Since Northern Empire has no settlements, we know for sure this is true. And the
distance variable must be 0 for either Diathma or Amprela. Which means our result is `Campaign.AverageDistanceBetweenTwoFortifications / 0.1`. If the average distance between two fortifications in the game is calculated as 50 for example, we are returning 500. Considering rest of the code seems to be around 0-4 as value, you can see this is an unintentional result. And the reason why Northern Empire gets about 500 times more settlement value than Southern Empire.
Now lets check if this values actually have an effect on defection. The game calls 2 methods while calculating defection scores, `GetScoreOfClanToJoinKingdom` and `GetScoreOfKingdomToGetClan`. First one is the score of how much the clan wants to join the given kingdom and second one is the score of how much the given kingdom wants to get the clan.
As you can see from the values my mod logged, these are
820m and
48m in order.
Lets how much of these values come from the settlement values we have seen above. Since these 2 methods are quite complicated, I removed irrelevant parts.
First method:
C#:
public override float GetScoreOfClanToJoinKingdom(Clan clan, Kingdom kingdom)
{
//...
float num7 = clan.CalculateTotalSettlementBaseValue();
float num8 = clan.CalculateTotalSettlementValueForFaction(kingdom);
//...
return num9 * MathF.Sqrt((float)commanderLimit) * num14 * 0.2f * (num5 * num6) + (clan.MapFaction.IsAtWarWith(kingdom) ? (num8 - num7) : 0f) + num10;
}
Southern Empire and Northern Empire are at war so we get `num8 - num7`, which can be seen from logs as 600k and 821m in order. So the first method returned 820m all thanks to settlement values.
Second method:
C#:
public override float GetScoreOfKingdomToGetClan(Kingdom kingdom, Clan clan)
{
//..
return (clan.CalculateTotalSettlementValueForFaction(kingdom) * 0.1f + num3) * num * num2 * num4;
}
In here I removed everything else but that is fine because as you can see almost all values are multiplied by each other. We know settlement value is 821m, which becomes 82m before being part of multiplication. `num3` here is total strength of the clan and checking other logs I can safely say it is well under 1m. So once again, majority of score comes from settlement values.
This particular situation seems to be a bug and will cause odd situations every now and then. However my personal opinion is whole method needs improvement. Settlement values are a big part of calculation for defection scores. Current calculation puts huge emphasis on geographical position and faction middle settlements. If your kingdom gets quite big and Vlandia has only couple settlements on the left side of the map, any settlement on the Vlandian border will get huge settlement values for Vlandia compare to you. Doesn't make any sense. Vlandia's middle settlement being closer doesn't mean Vlandia is closer. You can have 10 settlements closer than Vlandian ones.
So fingers crossed this will be addressed soon. In the mean time if anyone is interested, I can replace geographical advantage calculation with 1.7.2 one and release as a mod.