This is brought on by playing the AD1000 (or AD1001) scenerio: why don't the spanish kick the arabs out of spain? They have more than enough military strength to boot them out of spain itself -- heck, they could even push further if they where aggressive enough.
Using chipolte, I get that the Spanish stay on a defensive stance against the arabs. That isn't what we want.
So I'm doing code archeology
In AI_calculateAreaAIType:
Areas are, I think, continents.
countEnemyDangerByArea counts the number of enemy combat units in the area.
iAreaCities is:
the total number of cities owned by this "team" in the area.
So if there are more enemy combat units in an area than the team has cities, at that point we fall into defensive. We don't even examine if our military strength is stronger than theirs!
Now, we can avoid the above feature by earlier escapes:
We go over the other teams, and check for warplans with them.
If they attacked us recently, we bias towards being defensive.
If they have at least 1 city or 5 units on the area (read: continent), they are a valid war target for the area.
If we chose the war (ie, we where not attacked), and we either:
A> Just recently started the war (previous 10 turns), or
B> Have a sneak attack ready
then we have a HUGE bias towards an offensive area for the war (in fact, it is automatic!)
Outside of that, here is the main bit of code that can avoid the seeminly buggy AREAAI_DEFENSIVE decision:
Breaking this down...
Total number of units on my side that are set to an aggressive AI setting:
(countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE))
Is at least 20 to 25% of the total military "weight" we have, plus 1:
> (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1)
Military Weight is the sum over each player:
return (pArea->getPopulationPerPlayer(getID()) + pArea->getCitiesPerPlayer(getID()) + 1);
So (1+population) per city, plus 1 per player.
So two size 6 cities gives us a military weight of 15, which requires 4 aggressively AI'd units to be offensive in that area.
That seems ... somewhat strange. We are making a rather key decision (be aggressive or defensive) depending on the fraction of local team units who think they should attack to local team cities.
And once we pass that test, we tutle if there are more enemy units than our team has cities -- which is a pretty ridiculous rule!
...
While I see a lot of "team" calculations here, I don't see it taking into account the local strength of other people at war with the enemy civilizations.
I'm thinking something along the lines of:
Estimated Enemy Strength in Area
------------------------------------------
Estimated Enemy of Enemy Strength in Area
as being a key parameter -- if the enemy is outnumbered by it's enemies, then we can be more confident about being aggressive towards it.
...
Another possible culprit is :
void CvUnitAI::AI_attackMove()
from CvUnitAI.cpp -- in it, you'll notice that the first option is "check if the city has enough protectors". If that is overly strong, the AI won't use it's knights to take out the city in southern spain.
Total number of units on my side that are set to an aggressive AI setting:
(countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE))
Is at least 20 to 25% of the total military "weight" we have, plus 1:
> (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1)
Military Weight is the sum over each player:
return (pArea->getPopulationPerPlayer(getID()) + pArea->getCitiesPerPlayer(getID()) + 1);
So (1+population) per city, plus 1 per player.
So two size 6 cities gives us a military weight of 15, which requires 4 aggressively AI'd units to be offensive in that area.
Hmm. That doesn't seem to be the problem.
I'm gonna keep poking at this.
It makes a good case study: the correct option for the Spanish is an all-out assault on Cordoba, which the Spanish win. In general, if Europe does an all-out assault on Byzantium/Arabs, they come out ahead -- otherwise, the Arabs continue to dominate.
Using chipolte, I get that the Spanish stay on a defensive stance against the arabs. That isn't what we want.
So I'm doing code archeology
In AI_calculateAreaAIType:
Code:
if (iAreaCities > 0)
{
if (countEnemyDangerByArea(pArea) > iAreaCities)
{
return AREAAI_DEFENSIVE;
}
}
Areas are, I think, continents.
countEnemyDangerByArea counts the number of enemy combat units in the area.
iAreaCities is:
Code:
iAreaCities = countNumCitiesByArea(pArea);
So if there are more enemy combat units in an area than the team has cities, at that point we fall into defensive. We don't even examine if our military strength is stronger than theirs!
Now, we can avoid the above feature by earlier escapes:
We go over the other teams, and check for warplans with them.
If they attacked us recently, we bias towards being defensive.
If they have at least 1 city or 5 units on the area (read: continent), they are a valid war target for the area.
If we chose the war (ie, we where not attacked), and we either:
A> Just recently started the war (previous 10 turns), or
B> Have a sneak attack ready
then we have a HUGE bias towards an offensive area for the war (in fact, it is automatic!)
Outside of that, here is the main bit of code that can avoid the seeminly buggy AREAAI_DEFENSIVE decision:
Code:
if (bTargets)
{
if ((countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE)) > (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1))
{
return AREAAI_OFFENSIVE;
}
}
Breaking this down...
Total number of units on my side that are set to an aggressive AI setting:
(countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE))
Is at least 20 to 25% of the total military "weight" we have, plus 1:
> (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1)
Military Weight is the sum over each player:
return (pArea->getPopulationPerPlayer(getID()) + pArea->getCitiesPerPlayer(getID()) + 1);
So (1+population) per city, plus 1 per player.
So two size 6 cities gives us a military weight of 15, which requires 4 aggressively AI'd units to be offensive in that area.
That seems ... somewhat strange. We are making a rather key decision (be aggressive or defensive) depending on the fraction of local team units who think they should attack to local team cities.
And once we pass that test, we tutle if there are more enemy units than our team has cities -- which is a pretty ridiculous rule!
...
While I see a lot of "team" calculations here, I don't see it taking into account the local strength of other people at war with the enemy civilizations.
I'm thinking something along the lines of:
Estimated Enemy Strength in Area
------------------------------------------
Estimated Enemy of Enemy Strength in Area
as being a key parameter -- if the enemy is outnumbered by it's enemies, then we can be more confident about being aggressive towards it.
...
Another possible culprit is :
void CvUnitAI::AI_attackMove()
from CvUnitAI.cpp -- in it, you'll notice that the first option is "check if the city has enough protectors". If that is overly strong, the AI won't use it's knights to take out the city in southern spain.
Total number of units on my side that are set to an aggressive AI setting:
(countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE))
Is at least 20 to 25% of the total military "weight" we have, plus 1:
> (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1)
Military Weight is the sum over each player:
return (pArea->getPopulationPerPlayer(getID()) + pArea->getCitiesPerPlayer(getID()) + 1);
So (1+population) per city, plus 1 per player.
So two size 6 cities gives us a military weight of 15, which requires 4 aggressively AI'd units to be offensive in that area.
Hmm. That doesn't seem to be the problem.
I'm gonna keep poking at this.

It makes a good case study: the correct option for the Spanish is an all-out assault on Cordoba, which the Spanish win. In general, if Europe does an all-out assault on Byzantium/Arabs, they come out ahead -- otherwise, the Arabs continue to dominate.