Controlling AI to AI relations

Seven05

Warmonger
Joined
Dec 5, 2005
Messages
2,056
Location
USA
With my recent work on the AI in TAM I thought it would be a good idea to share some of my discoveries.

For the most part I'll be dealing with the following values in the CIV4LeaderHeadInfos.xml file:

<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>0</iWarmongerRespect>

Of these values only iBaseAttitude has any effect on the human players. Attitude is calculated every turn starting with the base attitude and then modifying it. So iBaseAttitude is much more important than the common belief that it only affects their attitude on initial contact.

From the SDK (CvPlayerAI.cpp):
Code:
iAttitude = GC.getLeaderHeadInfo(getPersonalityType()).getBaseAttitude();

So an iBaseAttitude of -2 will make a leader less friendly. Pretty simple :)

The peace weight values only affect AI to AI attitudes. The values in iPeaceWeightRand is a random modifier used to add between 0 and iPeaceWeightRand to iBasePeaceWeight. So if iPeaceWeightRand is 3 and iBasePeaceWeight is 0 the final PeaceWeight can be 0, 1, 2 or 3.

The calculation for the attitude modifier based on PeaceWeight is:
Code:
	if (!(GET_PLAYER(ePlayer).isHuman()))
	{
		iAttitude += (4 - abs(AI_getPeaceWeight() - GET_PLAYER(ePlayer).AI_getPeaceWeight()));
		iAttitude += min(GC.getLeaderHeadInfo(getPersonalityType()).getWarmongerRespect(), GC.getLeaderHeadInfo(GET_PLAYER(ePlayer).getPersonalityType()).getWarmongerRespect());
	}

So what this does is take iBasePeaceWeight + (0 to iPeaceWeightRand) for each AI civ and calculates the difference (absolute value of the result) of them then subtracts that difference from 4 and uses the result as a modifier. So if Civ1 has a final peace weight of 4 and Civ2 has a final peace weight of 6 the result is a +2 attitude modifier. In the vanilla game Ghandi has a iBasePeaceWeight of 10 and Alexander has 0, without the random weight added in they would normally have a -6 attitude modifier with each other. Since it uses a difference of values any two leaders with the same values will receive a +4 attitude modifier.

At the same time iWarmongerRespect is added as a modifier. In this case the game uses the lowest iWarmongerRespect of the two leaders and applied that as a positive modifier. So if either leader has an iWarmongerRespect of 0 they receive no bonus between them (unless the other has a negative value, then they receive a penalty).

Here are some examples of using these values with each other. First, if you want all of the AI players to have relation based entirely on in-game actions (close borders, trade, etc) with no modifiers you could set them up like:

<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>0</iPeaceWeightRand>
<iWarmongerRespect>-4</iWarmongerRespect>

If they are all set the same way the -4 iWarmongerRespect will cancel out the +4 peace weight modifier.

If you want the AI to AI attitudes to fluctuate a bit instead of simple improving you can set them up like:

<iBaseAttitude>0</iBaseAttitude>
<iBasePeaceWeight>0</iBasePeaceWeight>
<iPeaceWeightRand>4</iPeaceWeightRand>
<iWarmongerRespect>-2</iWarmongerRespect>

This will result in a final modifier between -2 and +2.

Now there is a lot more to the attitude ajustements than just these four values. However, the other values seem to work more like I expected them to while these didn't. One thing to keep in mind is that any "Rand" value (ie. iMaxWarRand) will be used to figure a 1 in "value" probability. A good example of this is the various WarRand values:

Code:
if (GC.getGameINLINE().getSorenRandNum(AI_maxWarRand(), "AI Maximum War") == 0)

This, in a nutshell, means that the lower a "Rand" value is the better the odds of it occuring are.

The "Prob" values (ie. iRazeCityProb) are the opposite, so a higher value equals a higher chance.

Code:
if ((GC.getGameINLINE().getSorenRandNum(100, "AI Declare War 1") < GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIDeclareWarProb())

So in this case a random number between 0-99 is generated and if that random number is less than the Declare War Prob (defined in HandicapInfos in this case) the result would be successful.
 
Thx for the info here that helps a bit however wouldn't you like to share all not just some of your disvoveries and add a little more detail to it like what are sensible values for crazed men and fanatics?:D What are the attitude-ranges that aren't in vanilla but still could make sense or what limits to nr. are there? And for noobs what does each of the Leaderinftags do (explained for those who can't read code also)- I'm not really an expert in xml but have to struggle a lot with the Leader AI now. That would really be a help! I mean whatever detail you could add.:)

Edit:
hat are the exact effects of Powerratios? And how to make the AI declare war more likely to neighbors than civs far away if they like them better than those far of? What about iwondercontruct Rand allthough a Rand the Leaders with high values build wonders. I'm quite puzzled.
 
Sorry guy's, I've neglected my tutorial... I'll just blame it on real life since I've been pretty busy lately :)

All I intended to address here was the AI to AI relations. The problem I had with the vanila game was that the AI would always like the other AI more than human players. As a result the frequency of AI vs. AI wars were pretty low, well too low for my tastes. However, I'm happy to answer some specific questions so I'll start with Ploeperpengel's questions.

What are the effects of power ratios? The in-game "power" value that each player has is used to figure out how much "power" the current civ needs compared to them to start a limited or full war. The ratio is viewed as the current civ compared to the potential target. So a ratio of 150 would mean the current civ needs a power rating 1.5 times that of their opponent while a ratio of 50 would mean the current civ only needs at least half of the power of the target civ. The ratio itself has no effect on how many units will be used but it does tell the AI which type of war plan to use and the war plan (limited or full) will tell the AI how many units, and to a degree which type, to use. The power rations tie in closely with iMaxWarMinAdjacentLandPercent, anything with adjacent land equal to or above the minimum percent will be considered a nearby power so if set to zero the leader will always use the nearby power ratio. The power value can be seen in the in-game score graph if you're ever curious, it is determined by the iPower value for all of the units & buildings possessed by the civ. Power is computed per team if teams are used it figures the average power of all members of the team for both sides.

how to make the AI declare war more likely to neighbors than civs far away if they like them better than those far of? You can control this with a couple of settings. First, having a large negative value in iCloseBordersAttitudeChange, such as -6 or -8, will make them really dislike their neighbors once the border tension kicks in. Setting this to zero negates the penalty, I don't know if positive values will work to make them like their closest neighbors. This is close borders as in near, not as in the opposite of open, in the game this is the, "our close borders spark tensions" message. If you have a large percent in iMaxWarMinAdjacentLandPercent, such as 15 or 20, you can have a high nearby power ratio and a low distant power ratio to make it easier for them to declare war on distant civs than on nearby civs. Limited wars don't take nearby/distant factors into consideration.

What about iwondercontruct Rand allthough a Rand the Leaders with high values build wonders. I'm quite puzzled. All "rand" values work by giving you a better chance if the value is lower. The game generates a number between 0 and this value, if it is a 0 or 1 the AI can construct the wonder. Unfortunately it isn't so simple since it is checked per city by the build AI and this is not the only factor in the descision it is quite possible for the AI to build a wonder even with high values here. In general, a high value will make them less likely to build wonders but will never prevent it entirely, a low value will however cause them to build wonders whenever they have a chance to.
 
How are specific relations controlled?

The sequence I'm hoping for is Carthage to declare war on Rome around turn 5 or so, and then after that war they should look to expand in Iberia (Spain). They start with 1 city in Spain to give them a beachhead. The 2nd Punic War will be initiated by Rome, and Numidia will join forces with Rome once they make contact.

Any suggestions?
 
Sepecific relationships can be set in the WB, but for quick tweaks here is what is necessary:

In the wbs file, the relationships (attitudes) are set with:

AttitudePlayer=2, AttitudeExtra=-72

Negative is.. unfavorable. For exmaple -72 is furious.

War status is set by:

BeginTeam
Tech=TECH_ETRUSCAN_HERITAGE
Tech=TECH_CIVILIZED_BUILDINGS
ContactWithTeam=1
<snip>
AtWar=11
RevealMap=0
EndTeam


In <beginTeam> the team# is not explicitly stated. The order they are in corresponds with the team#. So the first <beginTeam> is team0, etc.. Also note that team# is used for the turn order.
 
Just noticed this. Terrific start to helping all of us noobs understand this stuff. :)
 
This is really cool. I especially like that you included sdk code to show what going on under the scenes. Great work!
 
Top Bottom