While I haven't looked at Civ4 code myself, DanF said in a post that the AI needs to be able to build 2 Attack Units in the capital before it will go into war-mode. So the AI needs to hook up copper first. I actually can never remember to have a BTS-AI declare on me with just a stack of archers.
So this code is still in place? Interesting. The reason I mentioned Soren is that he said he prevented it in a podcast.
Well perhaps you're right after all. The original code has a strategy called
AI_STRATEGY_GET_BETTER_UNITS. The effect of this strategy was that it would cause the AI to focus on techs that granted better units; but also, the AI generally wouldn't play for war if it was using this strategy.
In the original code, the determination of whether the AI should use this strategy or not was very simplistic. It essentially just counted how many different types of units they had - and it would use the strategy if it had fewer than 2 "attack units", with a very broad definition of what counted as an attack unit in this context.
In K-Mod, made some changes which allowed the AI to use this strategy through the whole game, not just at the very start of the game. In particular, they use it when their units are significantly weaker than the units of their enemies. (And so the AI generally won't start planning wars if their units aren't good enough.)
I also kept the original condition, so that the strategy would be used if there the AI had fewer than 2 'attack units', but I adjusted the definition of what counted as 'attack units' to actually include
UNITAI_ATTACK...
Interestingly, I made a comment in my changes questioning whether or not the original code had left that out deliberately...
Code:
/* original bts code
if (kLoopUnit.getUnitAIType(UNITAI_RESERVE) || kLoopUnit.getUnitAIType(UNITAI_ATTACK_CITY)
|| kLoopUnit.getUnitAIType(UNITAI_COUNTER) || kLoopUnit.getUnitAIType(UNITAI_PILLAGE)) */
// K-Mod. Original code was missing the obvious: UNITAI_ATTACK. Was this a bug? (I'm skipping "pillage".)
if (kLoopUnit.getUnitAIType(UNITAI_ATTACK) || kLoopUnit.getUnitAIType(UNITAI_ATTACK_CITY)
|| kLoopUnit.getUnitAIType(UNITAI_RESERVE) || kLoopUnit.getUnitAIType(UNITAI_COUNTER))
// K-Mod end
The code was meant to be counting 'attack units', so it seemed obvious to me that it should include
UNITAI_ATTACK, especially if it's counting 'reserve' and 'counter' units which may be entirely unsuitable for attack purposes.
But now we come to the crux of the matter: archers and warriors both count as UNITAI_ATTACK, and so if the AI starts with archery, they then probably won't start with the
GET_BETTER_UNITS strategy - and so they may think about war sooner than they would have in the original code.
So I guess you're right that the original AI was blocked from considering early war more than in K-Mod.
I'm not sure if that was by design though. Maybe it was, but to me it seems like a pretty flaky was of doing it because there were a bunch of arbitrary connections which were all necessary for the block to take effect.
- Ignoring UNITAI_ATTACK while claiming to count "attack units" weird, and sounds like bug. (but maybe it wasn't.)
- The UNITAI tags attached to the units are pretty arbitrary and could easily be different. For example, both archers and warriors have 'attack' and 'city defense' but no other tags, whereas musketmen have 'reserve' in addition to those two tags.
- The name of the strategy "get better units" sounds to me like it is about getting better units rather than being about avoiding wars.
- The threshold number of these so called "attack units" (ie. 2) is arbitrary. I don't doubt now that it was chosen post hoc to meet a specific objective after all the other conditions had been chosen.
I think it would probably make more sense for archers to have the 'reserve' tag, but not have the 'attack' tag, and for the counting of 'attack units' for that strategy to not include 'reserve'. With those two changes together, the early wars would once again be blocked... but on the other hand, the "get better units" strategy should probably only prevent the AI from considering wars against teams which already have better units - in which case archer rushes would not be blocked.
My point is that if the goal of all this was to prevent the AI from considering early wars, then they probably should have coded it in directly in a way like I'm intending to do, rather than have it rely on a the combined effect of a hodge-podge of conditions, each of which don't make a great deal of sense.
I guess this is just another example of where 'fixing' stuff can have unintended consequences. (There have been more extreme cases than this, where fixing something that is very obvious a bug has resulted in the AI becoming completely incompetent and thus requiring further changes in seemingly unrelated parts of the code.)
On avoiding/preventing them: In the timeframe we speak of the only trade option is to gift a city. Its a solid choice, but a very cheesy one. Speaking of outer and inner cities when you only got 1 or 2 makes little sense.
As I mentioned, religion and keeping some distance are also options that are often available (but not always desirable).
In any case, perhaps the tweaks to this stuff are something to look forward to for people who have been bothered by the early wars.