Version 0.83 discussion thread

jdog5000

Revolutionary
Joined
Nov 25, 2003
Messages
2,601
Location
California
(You can always get the latest stable release from the download thread or sourceforge. Development versions and updated source code can also be checked out from sourceforge.)

Version 0.83h includes a lot of important bug fixes and tweaks which should compound to have a very positive effect on the AI. The over/inappropriate production of transports has been fixed, as have the ways the AI climbs out of financial holes. The AI will also now waste fewer hammers as it will now make consistent probabilistic decisions. A number of these fixes are new since the beta version of 0.83 was released in early December.

There are also two new options by popular demand:

- BBAI_ALLIANCE_OPTION: Changes how defensive pacts work to be more like alliances from earlier versions of Civ. Pacts now do not cancel on war declarations and your allies will also declare war. This can easily be abused by a human player, but the option is now available.

- BBAI_HUMAN_AS_VASSAL_OPTION: Allows human player to offer themselves as a vassal to an AI. The AI has been taught to consider this offer appropriately and some exploits have been resolved. It's not perfect, but it works reasonably well.

Both of these options are controlled through GlobalDefinesAlt.xml.

New in Better BTS AI 0.83
Spoiler :

Merged in UP 1.40

Bugfix
- Fixed bug where AI would avoid techs leading to maintenance reducing buildings when in financial trouble (thanks Afforess)
- Fixed bug where AI calculated benefit of maintenance reducing buildings and then ignored it when picking techs
- Fixed bug where an AI city with civ, civic, or city bonuses for GP rate would be less inclined to use specialists (thanks Maniac)
- Fixed bug where AI overestimated how much gold it would get from steal treasury espionage missions
- Fixed bug causing AI cities to over value buildings which unlock specialists in many circumstances when picking what to build
- Fixed bug (introduced) causing AI to incorrectly think it needed to build transports in many circumstances

City AI
- Cities now consider how many missionaries they already have plus those being trained when deciding whether to train another
- Same as above for executives
- Under most circumstances, barracks now a few steps later in AI build priority queue in early game
- Split early game worker logic out into separate clause to customize
- AI may now build workers first in its capital if it has things for them to do
- Fixed logic for high priority first worker to get access to bonuses, now only counts bonuses which can be improved now or with tech currently being researched
- Cities for a player in a strike situation (very very rare) now will build buildings to help lower costs/raise income, instead of training defenders which would be disbanded anyway
- Removed improper dependence on need for land workers when deciding whether to build early sea workers
- AI cities will now pop or gold rush defenses when civ is in big trouble, especially right after being attacked
- Improved valuation of Great Wall with No Barbs or Raging Barbs (thanks Afforess)
- Reduced AI valuation of espionage generated by buildings when selecting what to build
- Changed most probabilistic decisions in city build logic so that they're consistent. Now, if a city has already rolled the dice and started to build something, then if it grows or otherwise decides to recheck its priorities, it won't do another dice roll to decide whether to continue the build (abandoning huilds because of dice rolls previously caused AI to waste hammers)
- Tweaks so AI spends fewer hammers on low priority units when in financial trouble

Worker AI
- Fixed illogical ordering where city decided how many workers it needed before selecting what it would have them do (caused small problems for deciding when to build workers)

Victory Strategy
- AIs will now send their spaceships even if someone else looks like they're going to beat them, as the other player's capital might be captured (thanks r_rolo1)

War Strategy
- AIs may now restart war preparations against an enemy while a peace treaty is still in effect

Diplomacy
- WHEOOHRN no longer shows exactly when AI begins war plans in all circumstances. If AI is just planning war, it now only shows after attitude and power denial checks.
- Vassal master no longer will give away techs to vassals that are close to it in tech score
- Some fixes and hacks so that trade denials appear correctly when the human player offers themselves as a vassal to an AI

Gold AI
- Adjusted AI priorities for disbanding units when in financial trouble to better account for game state, fix some illogical orderings

General
- Fixed issue blocking all terrain units from planning paths to distant areas
- Added option to CvPlayer::countReligionSpreadUnits and CvPlayer::countCorporationSpreadUnits to include units being trained

Customization
- Added BBAI_ALLAINCE_OPTION to change defensive pacts so they do not cancel after war declaration, cause allies to declare war as well. This is easy for human players to abuse.
- Added BBAI_HUMAN_AS_VASSAL_OPTION to enable human players to offer themselves as vassals to AIs. Some AI logic has also been added to make this work better.

CIV4UnitInfos
- Removed UNITAI_CITY_DEFENSE from Swordsmen
- Workboats no longer considered military units
 
Excellent stuff, looking forward to the full release.

Might I suggest that in CvTeamAI.cpp where you have made the WHEOOHRN change that DENIAL_ATTITUDE should come before DENIAL_POWER_THEM/DENIAL_NO_GAIN? If the AI is not friendly with you, why should they reveal their hesitation about the power of the enemy? I think a sensible ordering for that middle section would be ATTITUDE; ATTITUDE_THEM; POWER_THEM/NO_GAIN.
 
jdog, how does the BBAI_ALLIANCE_OPTION handles war between parts of the DP? In stock civ IV DP does not mean inability of war between two civs that sign one, and that does not bode well with keeping it after war decs ;)
 
Since you mentioned removing CITY_DEFENSE from swordsmen, I have a couple of points about the UnitInfos file:

1) Should all swordsmen types have CITY_DEFENSE removed? For example Gallics?

2) Perhaps the tag CITY_DEFENSE should be added to spear and pike units, with the possible exception of impis.

3) Perhaps ATTACK_CITY should be added to cho-ko-nu, mace, rifle and infantry units.

4) Surely work boats should not be considered military units, so that you build them faster with police state? :crazyeye: Currently work boats have <bMilitarySupport> and <bMilitaryProduction> set to 1.
 
jdog, how does the BBAI_ALLIANCE_OPTION handles war between parts of the DP? In stock civ IV DP does not mean inability of war between two civs that sign one, and that does not bode well with keeping it after war decs ;)

Good question ... that's why it's in beta!

Will this include the fix to build escorts prior to settlers?

It includes all the early game city build tweaks, yes.

Since you mentioned removing CITY_DEFENSE from swordsmen, I have a couple of points about the UnitInfos file:

1) Should all swordsmen types have CITY_DEFENSE removed? For example Gallics?

2) Perhaps the tag CITY_DEFENSE should be added to spear and pike units, with the possible exception of impis.

3) Perhaps ATTACK_CITY should be added to cho-ko-nu, mace, rifle and infantry units.

4) Surely work boats should not be considered military units, so that you build them faster with police state? :crazyeye: Currently work boats have <bMilitarySupport> and <bMilitaryProduction> set to 1.

1) I left it for Jaguars currently as they're cheaper and have no resource requirement. Removed for all sword types.

2) No, spears are better in their current role I think. We don't want them competing for general city defense slots, they're a complimentary unit which counters specific attackers. If the concern is to have the AI build more spears for defense, there are other ways of going about that.

3) The XML specifications aren't the end of the story. Any combat unit that can capture cities may be built as an ATTACK_CITY unit, but the AI has to think it's decent at the role compared to other units it can build where the values come from CvPlayer::AI_unitValue.

4) Agreed. One might be able to argue that military support kind of makes sense since any workboat which is around for more than a few turns is most likely out exploring. But also having the military production flag set makes it clear it's a copy and paste issue.
 
Maces are top-notch at attacking cities. Their counter unit (the crossbow) is only marginally stronger than them. The knight vs pikeman is at best only slightly better, and knights cannot approach on hills/forests to make counter-attacks difficult.

And the AI upgrades their archers to longbowmen just before you get maces, allowing a mass-upgrade-or-build mace rush (backed with siege).

Similarly, Riflemen break open the entire game if you mass produce them and attack with them when you first get them.
 
Interesting update, jdog! :) As I just released a new version a few days ago, I won't release a new version just yet. I'll wait for the release version of 0.83.

On Workboats: I think it's stupid that they can even explore in the first place. I've disabled that ability for workboats in Merged Mod, by the way.
 
1) I left it for Jaguars currently as they're cheaper and have no resource requirement. Removed for all sword types.

2) No, spears are better in their current role I think. We don't want them competing for general city defense slots, they're a complimentary unit which counters specific attackers. If the concern is to have the AI build more spears for defense, there are other ways of going about that.

Interesting. I see what you mean about spears being a counter unit.

3) The XML specifications aren't the end of the story. Any combat unit that can capture cities may be built as an ATTACK_CITY unit, but the AI has to think it's decent at the role compared to other units it can build where the values come from CvPlayer::AI_unitValue.

So are you saying that adding ATTACK_CITY doesn't make the AI more likely to build this unit for the purpose of capturing cities? Also, you say there are other ways to go about setting the functions of each unit, so how else would be best to get for example cho-ko-nus exploited maximally?

4) Agreed. One might be able to argue that military support kind of makes sense since any workboat which is around for more than a few turns is most likely out exploring. But also having the military production flag set makes it clear it's a copy and paste issue.

Yeah. I would have thought if anything they'd have copy/pasted from the worker block, but clearly not.
 
On Workboats: I think it's stupid that they can even explore in the first place. I've disabled that ability for workboats in Merged Mod, by the way.

So people have to send them to explore manually? Or are they prevented from leaving your cultural borders?
 
In my personal mod, workboats are set to "no exploring" -- ie, they cannot move to any square where they would remove the 'black cloak of unexplored territory'.

I assume the other poster was talking about the same.
 
Yakk:

Thanks for bringing that up ... the poor AI would still make exploration workboats it seems, but just couldn't use them! I just fixed the checks for land and sea exploration being a valid UNITAI for units marked no reveal map.

So are you saying that adding ATTACK_CITY doesn't make the AI more likely to build this unit for the purpose of capturing cities? Also, you say there are other ways to go about setting the functions of each unit, so how else would be best to get for example cho-ko-nus exploited maximally?

Correct, there's no benefit to giving UNITAI_ATTACK_CITY to most combat units in the game. Here's the check for which unit types can use this AI type:

Code:
		case UNITAI_ATTACK_CITY:
			if (GC.getUnitInfo(eUnit).getCombat() > 0)
			{
				if (!(GC.getUnitInfo(eUnit).isOnlyDefensive()))
				{
					if (!(GC.getUnitInfo(eUnit).isNoCapture()))
					{
						bValid = true;
					}
				}
			}
			break;

There are two ways for bValid to be true, either the unit has the UNITAI type explicitly defined for it in XML or the unit passes the above test. There's a test like this for every UNITAI type, but many others are much more restrictive (for example, the AI would never build CITY_DEFENSE swordsmen without having it explicitly allowed in XML because they have no city defense bonus).

For any unit for which bValid is true for UNITAI_CITY_ATTACK, they are evaluated for their fitness for duty:

Code:
	iValue = 1;

	iValue += GC.getUnitInfo(eUnit).getAIWeight();

	...

	case UNITAI_ATTACK_CITY:
		iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
		
		iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
		iValue += iTempValue;
		if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).getDropRange() > 0)
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
		{
			iValue += (iTempValue * 8) / 100;
		}		
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 100);
		[B]iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);[/B]
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
		if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
		{
			int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
			if (iBombardValue > 0)
			{
				//Percentage change
				//Total Bombard == 0 : 600%
				//Total Bombard == 100 : 200%
				//Total Bombard == 200: 100%
				//Total Bombard == 300: 50%
				//Total Bombard == 400: 
				[B]int iTotalBombardRate = AI_calculateTotalBombard(DOMAIN_LAND)[/B];
				if (iTotalBombardRate < 100)
				{
					iBombardValue *= 4 * (200 - iTotalBombardRate);
					iBombardValue /= 100;
				}
				else
				{
					iBombardValue *= 100;
					iBombardValue /= std::min(400, iTotalBombardRate);
				}
				iValue += iBombardValue;
			}
		}

		break;

Where, as I've mentioned before, iCombatValue is actually a ratio of the combat strength of the unit type in question compared to the best combat strength any civ has built (units with built in first strike abilities get a small boost). So, if Macemen are also available the iCombatValue of the cho-ko-nu would be:

iCombatValue = (100 * 6)/8;
iCombatValue *= (100 + (2 first strikes) * 2 * 4 + (0 first strike chances) * 4);
iCombatValue /= 100;

So, the cho-ko-nu would have a value of 87 while the mace would have 100. Carrying the computation through, for mace vs cho we have (note: integer math, divisions round down):

Mace: (100*100)/75 + 100/2 + 100*1*1/4 = 208

Cho: (87*87)/75 + 87/2 + (87*50)/400 + 87*1*1/4 = 174

Ratio: 208/174 = 1.20

For the final valuation to decide what the AI will build, these values are then processed as:

iValue *= 100 + rand between 0 and 49;
iValue /= 100;

So, for the Cho to be selected over the mace, it needs to beat it in the rand dice toss by 21 (at 20 there's a risk of ties which go to the mace). Fun math question: two rand integers x and y between 0 and 49 inclusive, what's the chance that x + 21 <= y?

My calculations say 16.2%, so the AI will heavily favor the mace for an attack city unit.

Now, a typical AI attack stack is made up of a collection of ATTACK_CITY, ATTACK, and COUNTER units with a sprinkling of PILLAGE. Here's some more breakdown:

ATTACK:
Mace value: 100 + 100/3 = 133
Cho value: 87 + 87/3 = 116
Ratio: 1.15 -> Cho chosen about 24%

Counter:
Mace value: 100/2 + 100*1/2 + (100 * 50 * M)/10000 = 100 + 0.5*M
Cho value: 87/2 + 87*1/2 + (87 *50 *M)/10000 = 86 + 0.435*M
Ratio: 1.16 -> Cho chosen about 22%

Where M is the AIs weight for countering melee troops, in this case it would only affect the ratio a tiny amount through integer quantization. These percentages would be more like 12-15% for a regular crossbow (iCombatValue of 81 compared to mace).


Two other notable things:

- The boost for collateral damage for the cho-ko-nu is only a +10. The iTempValue is 143, while the movement term is either +21 or +87. Collateral damage is a pretty small factor in the valuation, why? Is there some balance issue in other eras?

- The AI player changes its valuation of siege unit bombard abilities based on the total amount of land bombard rate it has. This function is a strict sum of (bombard rate)*(num units of that type), and has no scaling by army size at all. Bombard would thus be underweighted in large civs or games played on larger maps.
 
The BBAI 0.82 thread should probably stay dead, but here is a question about the stock BBAI 0.82. I can see in the code that AI spies in an enemy city are likely to cause revolt if there is a strong stack nearby. That is great. I have some players in Dune Wars who are really looking forward to seeing that happen. (In the Dune novel, one of the most important scenes is where a spy does exactly this.)

What we have observed is that AI spies in enemy cities tend to squander their EP on low value missions like steal treasury and they are never around when it would be useful to cause revolt.

I cannot quite locate the code which runs the low value missions in enemy cities. Is there some provision to skip low value missions and wait? Or does the code greedily take the first mission for which there are enough EP? If the spies could be made a little more patient, I think the DW players would be rewarded.
 
So people have to send them to explore manually? Or are they prevented from leaving your cultural borders?

I've set bNoRevealMap to 1, which means they can't remove FOW. They can leave your borders, but they can't boldy go where no man has gone before.
 
Maces are top-notch at attacking cities. Their counter unit (the crossbow) is only marginally stronger than them. The knight vs pikeman is at best only slightly better, and knights cannot approach on hills/forests to make counter-attacks difficult.

And the AI upgrades their archers to longbowmen just before you get maces, allowing a mass-upgrade-or-build mace rush (backed with siege).

Similarly, Riflemen break open the entire game if you mass produce them and attack with them when you first get them.

Longbows are considerably before maces (far fewer aggregate beakers to get there) and the AI likes going there early in many cases. Provided you have stack D anything can sweep post-siege, and if it's just longbows even swords can break 50% odds frequently after minimal collateral.

Knights get 2 moves and can thus threaten multiple cities and put a lot of pressure on opponents to field fight...although the AI doesn't know how to use them that way.

Rifles are a valid attack unit, but only in one of the following cases:

1. Tech lead + something to strip defenses away quickly
2. As stack defense for cannons (rifles counter mounted flanking decently).

To make use of 1 requires a tech lead, and the AI isn't especially awesome at attaining a tech lead currently without substantial bonuses (immortal+ bonuses required with stock AI, but even with betterAI emp and below might not be enough...and this project isn't designed to milk bonuses but rather to cut the need for bonuses).

Maces are viable attackers but the AI will do much, much better if it merely builds enough siege and covers it with a balanced stack defense. Spears can kill medieval units if they're redlined by siege. Hell, cruddy units like axes can pick off rifles if the cannons pounded them down. Siege initiative rules this game until nukes, where you don't want big stacks anymore...
 
Yakk:

Thanks for bringing that up ... the poor AI would still make exploration workboats it seems, but just couldn't use them! I just fixed the checks for land and sea exploration being a valid UNITAI for units marked no reveal map.



Correct, there's no benefit to giving UNITAI_ATTACK_CITY to most combat units in the game. Here's the check for which unit types can use this AI type:

Code:
		case UNITAI_ATTACK_CITY:
			if (GC.getUnitInfo(eUnit).getCombat() > 0)
			{
				if (!(GC.getUnitInfo(eUnit).isOnlyDefensive()))
				{
					if (!(GC.getUnitInfo(eUnit).isNoCapture()))
					{
						bValid = true;
					}
				}
			}
			break;

There are two ways for bValid to be true, either the unit has the UNITAI type explicitly defined for it in XML or the unit passes the above test. There's a test like this for every UNITAI type, but many others are much more restrictive (for example, the AI would never build CITY_DEFENSE swordsmen without having it explicitly allowed in XML because they have no city defense bonus).

For any unit for which bValid is true for UNITAI_CITY_ATTACK, they are evaluated for their fitness for duty:

Code:
	iValue = 1;

	iValue += GC.getUnitInfo(eUnit).getAIWeight();

	...

	case UNITAI_ATTACK_CITY:
		iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
		
		iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
		iValue += iTempValue;
		if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).getDropRange() > 0)
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
		{
			iValue += (iTempValue * 8) / 100;
		}		
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 100);
		[B]iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);[/B]
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
		if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
		{
			int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
			if (iBombardValue > 0)
			{
				//Percentage change
				//Total Bombard == 0 : 600%
				//Total Bombard == 100 : 200%
				//Total Bombard == 200: 100%
				//Total Bombard == 300: 50%
				//Total Bombard == 400: 
				[B]int iTotalBombardRate = AI_calculateTotalBombard(DOMAIN_LAND)[/B];
				if (iTotalBombardRate < 100)
				{
					iBombardValue *= 4 * (200 - iTotalBombardRate);
					iBombardValue /= 100;
				}
				else
				{
					iBombardValue *= 100;
					iBombardValue /= std::min(400, iTotalBombardRate);
				}
				iValue += iBombardValue;
			}
		}

		break;

Where, as I've mentioned before, iCombatValue is actually a ratio of the combat strength of the unit type in question compared to the best combat strength any civ has built (units with built in first strike abilities get a small boost). So, if Macemen are also available the iCombatValue of the cho-ko-nu would be:

iCombatValue = (100 * 6)/8;
iCombatValue *= (100 + (2 first strikes) * 2 * 4 + (0 first strike chances) * 4);
iCombatValue /= 100;

So, the cho-ko-nu would have a value of 87 while the mace would have 100. Carrying the computation through, for mace vs cho we have (note: integer math, divisions round down):

Mace: (100*100)/75 + 100/2 + 100*1*1/4 = 208

Cho: (87*87)/75 + 87/2 + (87*50)/400 + 87*1*1/4 = 174

Ratio: 208/174 = 1.20

For the final valuation to decide what the AI will build, these values are then processed as:

iValue *= 100 + rand between 0 and 49;
iValue /= 100;

So, for the Cho to be selected over the mace, it needs to beat it in the rand dice toss by 21 (at 20 there's a risk of ties which go to the mace). Fun math question: two rand integers x and y between 0 and 49 inclusive, what's the chance that x + 21 <= y?

My calculations say 16.2%, so the AI will heavily favor the mace for an attack city unit.

Now, a typical AI attack stack is made up of a collection of ATTACK_CITY, ATTACK, and COUNTER units with a sprinkling of PILLAGE. Here's some more breakdown:

ATTACK:
Mace value: 100 + 100/3 = 133
Cho value: 87 + 87/3 = 116
Ratio: 1.15 -> Cho chosen about 24%

Counter:
Mace value: 100/2 + 100*1/2 + (100 * 50 * M)/10000 = 100 + 0.5*M
Cho value: 87/2 + 87*1/2 + (87 *50 *M)/10000 = 86 + 0.435*M
Ratio: 1.16 -> Cho chosen about 22%

Where M is the AIs weight for countering melee troops, in this case it would only affect the ratio a tiny amount through integer quantization. These percentages would be more like 12-15% for a regular crossbow (iCombatValue of 81 compared to mace).


Two other notable things:

- The boost for collateral damage for the cho-ko-nu is only a +10. The iTempValue is 143, while the movement term is either +21 or +87. Collateral damage is a pretty small factor in the valuation, why? Is there some balance issue in other eras?

- The AI player changes its valuation of siege unit bombard abilities based on the total amount of land bombard rate it has. This function is a strict sum of (bombard rate)*(num units of that type), and has no scaling by army size at all. Bombard would thus be underweighted in large civs or games played on larger maps.

Is there any way to get the AI to assign more value to there UU, most of the time the UU are a fair bit better than the standard unit, Cho's are an example of this as the 2 FS + collateral make them very effective compared to a standard Xbow, it would be nice to see the AI place more value on there UU, with perhaps a bonus added to the AI choice logic, as i feel that many a time the AI does not factor in the advantages many UU offer and were UU do not replace core units they see less use than they should.
 
Back
Top Bottom