"We fear your enemies"

r_rolo1

King of myself
Joined
May 19, 2006
Messages
13,818
Location
Lisbon, Portugal
I think that it is quite known around here my strong dislike for the current vassal mechanics, with all the half-ended and "what works for 1:1 will always work with 7 , 18 or 359 civs on map" aproaches, but I thin kI must share what is , IMHO , the pearl :mischief: of the vassal mechanics misachievements:

CvTeamAI::AI_surrenderTrade ( this part is unchanged in Better AI 0.82 )

Code:
for (int iLoopTeam = 0; iLoopTeam < MAX_CIV_TEAMS; iLoopTeam++)
		{
			if (iLoopTeam != getID())
			{
				CvTeamAI& kLoopTeam = GET_TEAM((TeamTypes)iLoopTeam);

				if (kLoopTeam.isAlive())
				{
					if (kLoopTeam.AI_isLandTarget(getID()))
					{
						if (iLoopTeam != eTeam)
						{
							if (kLoopTeam.getPower(true) > getPower(true))
							{
								if (kLoopTeam.isAtWar(eTeam) && !kLoopTeam.isAtWar(getID()))
								{
									return DENIAL_POWER_YOUR_ENEMIES;
								}

								iAveragePower = (2 * iAveragePower * kLoopTeam.getPower(true)) / std::max(1, kLoopTeam.getPower(true) + getPower(true));

								iAttitudeModifier += (3 * kLoopTeam.getPower(true)) / std::max(1, getPower(true)) - 2;
							}

							if (!kLoopTeam.isAtWar(eTeam) && kLoopTeam.isAtWar(getID()))
							{
								iAveragePower = (iAveragePower * (getPower(true) + GET_TEAM(eTeam).getPower(false))) / std::max(1, getPower(true));
							}
						}
					}

					if (!atWar(getID(), eTeam))
					{
						if (kLoopTeam.isAtWar(eTeam) && !kLoopTeam.isAtWar(getID()))
						{
							DenialTypes eDenial = AI_declareWarTrade((TeamTypes)iLoopTeam, eTeam, false);
							if (eDenial != NO_DENIAL)
							{
								return eDenial;
							}
						}
					}
				}
			}
		}
I decided to drop all this loop in here, but the part of the code that I wanted to gripe about is the check that gives DENIAL_POWER_YOUR_ENEMIES, that basically gives " if the potential master is warring someone more powerful than us, tell him to eat grass".

IMHO this is simply stupid ... think about it: a AI will NEVER surrender as long as the master is warring someone that has a soldier worth more of power , no matter how strong is the civ that is pounding them and no matter how threathning the other AI might be or not to them. I can show you a consequence of this in play in here, where a civ ( the human ) went on war against the superpower of the other continent and it's two vassals, and because of both variant constraints and geographical considerations the superpower took most of the intial beating, making that the two vassals broke free. By unluck this ended with all of them refusing to vassal to the human for quite a while, because they had very similar powers that were pretty close of the average, leading to a almost hilarious situation of all the AI changing his opinion from "we are fine on your own" to " we fear your enemies" and back various times during a turn as the human killed various troops from diferent foes ( and before you ask , we had enough war sucess on all of them ).

I think this highlights a point in here that probably passed unnoticed in the beta testing: this makes that you can only vassal one free AI at the time ,no matter how good you conduct a war against multiple foes, because all but the strongest of them will be in fear of the strongest :p And if the strongest will not vassal for any other reason, too bad for you, master in potence, eat WW for atleast a little longer :( That is neither good for the possible master or for the possible vassals in potence in most of the cases, because it can have the nasty side effect of dragging wars for no good reason, pretty much like the already changed by better AI average rule in the same function. It is also a little strange to be forced to ceasefire with all the other foes to make a civ acept capitulation in spite of being beaten to crap, like I had to do in here ( the human resumed war with the rest of the foes as soon as he got the ink on the paper :p ).

Well, the big point is "When do a AI should refuse vassaling because it fears the enemies of the possible master?" . The anwser to original coder gives , as stated above, besides giving bad results in terms of AI performance when there is a civ that is warring more than one foe ( a not so uncommon situation ;) ), has some nasty side effects, as pointed above. I would suggest:

- A AI should refuse vassaling by fearing the possible master enemies when the power of the master + the power of the possible vassal is smaller than the one of the enemies of the master combined

- A AI should refuse vassaling by fearing the possible master enemies if there is atleast one of the foes of the possible master that is a bigger military threat than the possible master to them ( say, for sake of example , bigger power than them + long shared border vs possible master that does not border them or has little border , a thing we see a lot in intercontinental warfare ). There is already code for similar functions elsewhere, so it should be relatively easy to put this on here
 
This is particularly relevant now that the AI can start multiple wars.

If you want to improve this code, you need a more sophisticated understanding of "enemy". Sure, if the Aztecs and Spanish are at war, and I vassal to the Spanish, then I may need to deal with an attack by the Aztecs. However, this also occurs if the Aztecs and Spanish are at peace, and subsequently one of them declares war. Without that, the AI will be vulnerable to exploitation from civs that throw temporary ceasefires up to manipulate the capitulation decision.

So, I would look at each team's threat level as follows:
Current Threat = Their power x their DoW% on me. Includes the team for the potential master.
Vassal Threat = Their power x (their DoW% on my master + my master's DoW% on them). This does not include the team for the potential master.

Power can be weighted by nearness/borders, per rolo's post. DoW% is 100% if at war, otherwise taken from the leader traits XML. If Total Vassal Threat Level > Total Current Threat (including from the prospective master), then becoming a vassal will increase the military danger we face.
 
AIs should not know the DoW% of their opponents.

Knowing the DoW% of your master is even questionable, because it breaks when your master is a human.
 
I have to agree with Yakk, in spite of the idea of having the AI acting based on knowing the "personality" of the other AI being tempting, but not for the reason he said, because the game already makes the AI assume a lot of stuff about the human player behavior ( like in diplo, where it is explicitely stated in code that the AI should assume that the human player is cautious with them at all times ). My line of reasoning is that, besides random personalities issues ( reading the XML from Isabella is of nil utility if her is behaving like Monty ), the philosophy behind the coding of the AI in Civ IV seems to be of making the AI having the same ammount of good faith against all civs, modulated obviously by the diplo considerations. Making the AI to read the XML to get their "belicocity" is clearly making the AI to assume that not all the leaders are created equal and I'm not sure that all the players would welcome that change in philosophy ...

Other consideration to have in your mechanism is that the diplo considerations regarding what side constitutes a bigger threat can become horribly complex, especially if you insert third parties currently not in war with neither the possible master or the possible vassal, and that is why I only suggested those two circumstances in the OP. When you start counting with third parties currently not in war, just for a quick example of a quirk, besides you need to get the individual propensity for every individual actor to enter in the war by one of the sides ( or to not enter the war at all ), a thing that is already complex per se ( it depends of how long the war is and of the AP/UN existance, and this is assuming that all the parties will continue to exist as free actors and that no one more will enter the diplo board as a free civ or not ) , but also of the order of the facts ( A could consider to help B in the war to make C their vassal , but might not do that if D decides to do that before them, due to bad relations between A and D , just for another quick example ), and resolving that is hard even for humans if the diplo enviroment is complex enough...
 
If it's ok, I'll take the issue of the AI estimating and using DoW% to a separate thread.

The diplo considerations regarding what side constitutes a bigger threat can become horribly complex, especially if you insert third parties currently not in war with neither the possible master or the possible vassal.

The intention of DENIAL_POWER_YOUR_ENEMIES is to prevent civs from capitulating if doing so would be suicidal. However, the current code fails to do this, because I can quickly organise a ceasefire, capitulate the civ, and then start the war up again.

It could become horribly complicated, but I think we can keep it simple. If we don't like DoW%, we could weight the various powers by mutual attitude, for example. It's just one more number to multiply into the calculation.
 
Top Bottom