Report Questionable AI Behavior

(abusign this thread of more code review)
In revision 258, SelectionGroupAI.cpp: You added stack attack for the AI (2x):
if ((!isHuman() | isAutomated()) && getNumUnits() > 1)
I assume you meant the logic OR "||". Not really a bug since bitwise OR will giev you the same result in the end.

Nice catch!

"Compare City Maintenance to Next Largest Empire"
Better RoM addition iirc: For every nation, the maintenance scales with the number of cities in comparison to the largest civ. Only for the largest civ, it scales to the number of the 2nd largest?
I think it's bad practice to mistreat a single empire like that. Use one number for all, either 2nd largest, average, 80% of largest, doesn't matter. Just don't treat one civ completely differently from all others.

I guess the problem with average is that in RevDCM, you're prone to having "balkan-like" states that have only a few cities, which throw off the curve, when the real powerhouses have 10-15 cities each.

Curtailing the human player to give the AIs a chance, that's what difficulty levels are for, those should be modded/extended if that's all this is about. The "largest amoung the rivals" is not as ideal as it seems, it's just unfair.

I've found that modding the difficulty levels (I have a bit), causes very sharp increases in costs, whereas something in the SDK would be less noticeable to the player. Ni ether are really solutions though, they are mainly stop-gaps for the real problem - balancing.

But most importantly: The "Civic Vacuum". What you are doing is creating a complete vacuum, and making all decisions based on the vacuum values of the civics. That is NOT how it works.
Remove that vacuum thing and use the "imperfect kludge/hack" for AI_civicValue() instead (see LM post), that will at least not cost you that many cpu cycles.
Alternatively, create vacuums only for one civic option at a time, while you are evaluating the civic for it. I hope I can have a version of that ready this week in case you don't know what I'm talking about.

I know what you are talking about. I'll look at it and update my AI accordingly.
 
When I think maintenance, I think civics. Right now civic maintenance is such a small portion, or the civics that are high are SO GOOD with such a small penalty to maint.

IMHO, the difference between Low, Medium, and High should be noticeable, with cheap civics that benefit small empires and expensive civics designed to benefit large ones. I'm not sure how to go about it, but if it was done right and the AI taught to understand, we'd be on our way.
 
Civics are already the biggest consumer of maintenance. Low upkeep in my game is already 6 gold, medium is 12, with high being 18. Per Civic. I'm paying something like 150 gold per turn for civics. I don't think that is the issue...
 
Then the income needs to go down 0_o. I dunno, I've just noticed in RoM I can pretty much shrug off the cost of any civics I adopt.
 
I know what you are talking about. I'll look at it and update my AI accordingly.
Actually nevermind my comment on the civic AI.
Doing everything in complete vacuum is no worse than doing it in a vacuum that is limited to one civic option, in the first case you get too much value, in the second case too little. Overvaluing happiness isn't such a big problem, probably.

If there are 2 civics from different cathegories, and both give +1:) (not necessarily from the same source but at least to the same cities) - then ideally the culmulative value for that happiness when selecting both should be exactly the same as the value a single +2:) civic would give. But if you look at AI_getHappinessWeight you will see that's not what you get.
You'd need to evaluate and select one civic, process it, then evaluate the other. That would give you the correct values but you'd need to decide which cathegory to handle first. Which is where I'm currently stuck :p (I think 2*bestCivicValue-1*secondBestcivicValue gives me a good enough number to decide which cathegory to handle first but I can't mathematically prove that it will in any and all situations result in the best possible civic selection)

But I repeat: creating that vacuum and reversing that process takes a LOT of cpu time. I recommend optimizing processCivics() for that.
 
I don't get why you are so worried about ProcessCivics time... It barely takes any time at all. Frankly, I'm more worried about AI_neededMissionaries calls. That might be called a couple thousand times a turn late game.
 
There was a thread on profiling a while back, check the 4th or 5th pages in the SDK/Python forums. It was started by one of the HoTK team members, and lead to the CAR mod.
 
Thx, found it.

(abusign this thread for more code review)
In revision 258, SelectionGroupAI.cpp: You added stack attack for the AI (2x):
if ((!isHuman() | isAutomated()) && getNumUnits() > 1)
I assume you meant the logic OR "||". Not really a bug since bitwise OR will give you the same result in the end.
You fixed one, and left the other? (line 6524) :crazyeye:


Suggestions for AI_neededMissionaries in bold:
Spoiler :
Code:
		int iLoop;
		for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer)
		{
			CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer);
			if (kLoopPlayer.isAlive() && kLoopPlayer.getID() != getID())
			{
				if (GET_TEAM(getTeam()).isHasMet(kLoopPlayer.getTeam()))
				{
					if (GET_TEAM(getTeam()).isOpenBorders(kLoopPlayer.getTeam()) || GET_TEAM(getTeam()).isLimitedBorders(kLoopPlayer.getTeam()))
					{
						if (!kLoopPlayer.isNoNonStateReligionSpread())
						{
							for (CvCity* pLoopCity = kLoopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoop))
							{
								if (pLoopCity->area() == pArea)
								{
									if (!pLoopCity->isHasReligion(eReligion))
									{
										[B][COLOR="Green"]//if (pLoopCity->plot()->plotCount(PUF_isMissionary, eReligion, -1) == 0)[/COLOR][/B]
										[B][COLOR="Green"]//{[/COLOR][/B]
											iCount++;
										[B][COLOR="Green"]//}[/COLOR][/B]
									}
								}
							}
						}
					}
				}
			}
		}
[B]		for(pLoopUnit = GET_PLAYER(getOwnerINLINE()).firstUnit(&iLoop); (pLoopUnit != NULL && iCount > 0); pLoopUnit = GET_PLAYER(getOwnerINLINE()).nextUnit(&iLoop))
		{
			if (pLoopUnit->AI_getUnitAIType() == UNITAI_MISSIONARY)
			{
				if (pLoopUnit->area() == pArea)
				{
					if (pLoopUnit->getUnitInfo().getReligionSpreads(eReligion) > 0)
					{
						iCount--;
					}
				}
			}
		}[/B]
		
		if (isPushReligiousVictory())
		{
			[B]iCount *= 2;[/B]		
			iCount /= [B]3[/B];
		} 
		else if (isConsiderReligiousVictory())
		{
			iCount /= [B]3[/B];
		}
		else
		{
			iCount /= 4;
		}
 
Thx, found it.

You fixed one, and left the other? (line 6524) :crazyeye:

I didn't realize I had duplicated it... :(

Suggestions for AI_neededMissionaries in bold:
Spoiler :
Code:
		int iLoop;
		for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer)
		{
			CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer);
			if (kLoopPlayer.isAlive() && kLoopPlayer.getID() != getID())
			{
				if (GET_TEAM(getTeam()).isHasMet(kLoopPlayer.getTeam()))
				{
					if (GET_TEAM(getTeam()).isOpenBorders(kLoopPlayer.getTeam()) || GET_TEAM(getTeam()).isLimitedBorders(kLoopPlayer.getTeam()))
					{
						if (!kLoopPlayer.isNoNonStateReligionSpread())
						{
							for (CvCity* pLoopCity = kLoopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoop))
							{
								if (pLoopCity->area() == pArea)
								{
									if (!pLoopCity->isHasReligion(eReligion))
									{
										[B][COLOR="Green"]//if (pLoopCity->plot()->plotCount(PUF_isMissionary, eReligion, -1) == 0)[/COLOR][/B]
										[B][COLOR="Green"]//{[/COLOR][/B]
											iCount++;
										[B][COLOR="Green"]//}[/COLOR][/B]
									}
								}
							}
						}
					}
				}
			}
		}
[B]		for(pLoopUnit = GET_PLAYER(getOwnerINLINE()).firstUnit(&iLoop); (pLoopUnit != NULL && iCount > 0); pLoopUnit = GET_PLAYER(getOwnerINLINE()).nextUnit(&iLoop))
		{
			if (pLoopUnit->AI_getUnitAIType() == UNITAI_MISSIONARY)
			{
				if (pLoopUnit->area() == pArea)
				{
					if (pLoopUnit->getUnitInfo().getReligionSpreads(eReligion) > 0)
					{
						iCount--;
					}
				}
			}
		}[/B]
		
		if (isPushReligiousVictory())
		{
			[B]iCount *= 2;[/B]		
			iCount /= [B]3[/B];
		} 
		else if (isConsiderReligiousVictory())
		{
			iCount /= [B]3[/B];
		}
		else
		{
			iCount /= 4;
		}

I'll take your suggestion, and raise you one. ;)

Code:
/************************************************************************************************/
/* Afforess	                  Start		 08/19/10                                               */
/*                                                                                              */
/*  What about Civics that block religion spread and open borders?                               */
/************************************************************************************************/
/*
        iCount += ((pArea->getNumCities() * 2) - (pArea->countHasReligion(eReligion) * 3));
        iCount /= 8;

        iCount = std::max(0, iCount);

		if (AI_isPrimaryArea(pArea))
		{
			iCount++;
		}
*/
		int iLoop;
		for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer)
		{
			CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer);
			if (kLoopPlayer.isAlive() && kLoopPlayer.getID() != getID())
			{
				if (GET_TEAM(getTeam()).isHasMet(kLoopPlayer.getTeam()))
				{
					if (GET_TEAM(getTeam()).isOpenBorders(kLoopPlayer.getTeam()) || GET_TEAM(getTeam()).isLimitedBorders(kLoopPlayer.getTeam()))
					{
						if (!kLoopPlayer.isNoNonStateReligionSpread())
						{
							for (CvCity* pLoopCity = kLoopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoop))
							{
								if (pLoopCity->area() == pArea)
								{
									if (!pLoopCity->isHasReligion(eReligion))
									{
										iCount++;
									}
								}
							}
						}
					}
				}
			}
		}
		for(CvUnit* pLoopUnit = firstUnit(&iLoop); (pLoopUnit != NULL && iCount > 0); pLoopUnit = nextUnit(&iLoop))
		{
			if (pLoopUnit->AI_getUnitAIType() == UNITAI_MISSIONARY)
			{
				if (pLoopUnit->area() == pArea)
				{
					if (pLoopUnit->getUnitInfo().getReligionSpreads(eReligion) > 0)
					{
						iCount--;
					}
				}
			}
		}
		for (CvCity* pLoopCity = firstCity(&iLoop); (pLoopCity != NULL && iCount > 0); pLoopCity = nextCity(&iLoop))
		{
			if (pLoopCity->area() == pArea)
			{
				if (pLoopCity->getProductionUnit() != NO_UNIT)
				{
					if (GC.getUnitInfo(pLoopCity->getProductionUnit()).getReligionSpreads(eReligion) > 0)
					{
						iCount--;
					}
				}
			}
		}
				
		if (isPushReligiousVictory())
		{
			iCount *= 2;
			iCount /= 3;
		} 
		else if (isConsiderReligiousVictory())
		{
			iCount /= 3;
		}
		else
		{
			iCount /= 4;
		}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
 
I'll take your suggestion, and raise you one. ;)
Re-raise for probably better late-game performance:
(replacing the loop through own units and own cities with a loop through unitclassinfos)
Code:
		for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
		{
			UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));

			if (eLoopUnit != NO_UNIT)
			{
				if (GC.getUnitInfo(eLoopUnit).getReligionSpreads(eReligion) > 0)
				{
					iCount -= getUnitClassCountPlusMaking((UnitClassTypes)iI);
					if (iCount <= 0)
					{
						break;
					}
				}
			}
		}
 
Nice. This probably does what you wan it to do better though:

Code:
		for (iI = 0; iI < GC.getNumUnitClassInfos() && iCount > 0; iI++)
		{
			UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));

			if (eLoopUnit != NO_UNIT)
			{
				if (GC.getUnitInfo(eLoopUnit).getReligionSpreads(eReligion) > 0)
				{
					iCount -= getUnitClassCountPlusMaking((UnitClassTypes)iI);
				}
			}
		}
		
		iCount =  std::max(0, iCount);

Also, keep in mind your new code isn't area specific, which doesn't matter for Pangea maps, but will affect islands ones a great deal...
 
Oh damn, area .. now I remember why I didn't use that in the first place ;) So your first raise is what you should use.
But no, I disagree, that isn't "better". Functionally the same only in your version iCount > 0 is checked for every unit class, as opposed to only for missionaries in my case.
 
But yours could have lead to a negative iCount value, since you didn't stop it from falling below zero, so we're even. ;)

The point is moot though...
 
hello,

I am currently playing a game, on marathon speed with a huge map. It is late industrial era atm. The AI seems to be having a huge issue with building to many factories around there cities. This is then causing there cities to starve to 1 pop because of unhealthiness. I noticed that about half of the AI has done this in my game so far. I can post screen shots and/or save games if you need me to.
 
Would it be possible to get the AI to show more favour than it currently does to a religion that it founded itself?

I'm currently playing a game using "Limited Religions" and "Choose Religions", so lots of nations are getting to found one. A human player will usually want to go with their state religion being the one they founded themselves, but the AI seems very fickle indeed.

This is before missionaries become available, but I've accidentally already turned almost the entire Pangea Taoist , probably as a result of having researched trade and seafaring first, and compounded by the AI's seeming unwillingness to build much in the way of religious buildings (from what I can see through my spies).

For example, Egypt (Hatshepsut) went to the trouble of researching religious techs, and I assigned it Kemetism, the very religion of Ancient Egypt. It's gone on researching religious techs, but has not bothered to build a single temple to anyone. As soon as Taoism arrived in a single Egyptian city, it converted. It may well only have had one city with Kemetism, but even so, it needs to have a bit more self-respect. This might perhaps be helped by giving the free missionary to all religion founders, so they can at least spread it to a second city. Using "Multiple Religion spread" should provide opportunity for recovery, but the AIs are currently unwilling to take that opportunity. There's no point them rushing religious techs if they're not going to use them.

India's Asoka, another Spiritual leader, has built no religious buildings either (apart from Schools of Scribes which are sort of part of the religious tree, but tagged as science). Abu Bakr, another spiritual leader has none also, while Babylon's Nebuchadrezzar has built some, and he's neither spiritual or even a religion founder. Something does not feel right in this behaviour.

Probably worth mentioning that I'm using Dancing Hoskuld's custom religion modcomp, though I saw the same behaviour before I added it, and I don't think it touched the AI.

Actually, looking at things, does the Spiritual trait even work properly? Generic temples are gone. Is it halving the building time for the religion specific ones, or the sacred site? I don't know my way around the files too well, but I'm not sure it is, which makes the trait a good deal less useful to it's intended strategy.

Like the above poster, I'm also seeing most AI cities stagnant with terrible health issues, though in my case it's still the classical era. Do they understand that mines cause ill health?
 
Sacred Site makes temple construction faster.
Temple adds +10% maintenance. If they don't have money, they will not build it.
But I agree with religion converting problem. AIs usually don't change it after first one they got.
I'm not sure they should convert to their own religion, though.
AIs should consider many things like relationships with other civs, whether they have Great Priest so that they can build shrine, how many cities have that religion, and anarchy time before conversion.
 
Sacred Site makes temple construction faster.

Sure, but I don't think Spiritual trait is helping with Sacred sites either, and none of the spiritual AIs I mentioned even built those. When a spiritual leader isn't trying to get in on religion then something has gone odd.


Temple adds +10% maintenance. If they don't have money, they will not build it.
But I agree with religion converting problem. AIs usually don't change it after first one they got.
I'm not sure they should convert to their own religion, though.
AIs should consider many things like relationships with other civs, whether they have Great Priest so that they can build shrine, how many cities have that religion, and anarchy time before conversion.

There are possible diplomatic reasons to not go with the religion that you founded yourself, but this was during the ancient and classical eras where I am fairly sure that most players, if they founded a religion, would try pretty hard to work with it. I'd switch to my own founded religion even if a different religion was present in more cities, and then I'd try to fix that. The AI should have a similar attitude, as it could really use the rewards that can come from success in the religious sphere.
 
Sure, but I don't think Spiritual trait is helping with Sacred sites either, and none of the spiritual AIs I mentioned even built those. When a spiritual leader isn't trying to get in on religion then something has gone odd.

I changed many files in BUC (Sacred Site is introduced by BUC), so I'm not sure this is default, but AFAIK, Sacred Site doesn't get construction speed bonus with Spiritual and it requires state religion.
Perhaps changing these is better. I changed these.

There are possible diplomatic reasons to not go with the religion that you founded yourself, but this was during the ancient and classical eras where I am fairly sure that most players, if they founded a religion, would try pretty hard to work with it. I'd switch to my own founded religion even if a different religion was present in more cities, and then I'd try to fix that. The AI should have a similar attitude, as it could really use the rewards that can come from success in the religious sphere.

I agree with this.
 
I changed many files in BUC (Sacred Site is introduced by BUC), so I'm not sure this is default, but AFAIK, Sacred Site doesn't get construction speed bonus with Spiritual and it requires state religion.
Perhaps changing these is better. I changed these.

Great. I've made those changes in my own file until it becomes part of the official release. Maybe it'll help the AIs make a better start.

I just spent a jolly half hour assigning favoured religions to leaders lacking one (including some from Dancing Hoskuld's religion expansion, so I doubt the changed files would be much use to anyone here). Hopefully that'll make them a bit less willing to give them up.
 
Back
Top Bottom