: It would be best to disallow the AI from building anything that would cause immediate unhappiness or unhealthiness. For that, the AI needs to know the actual unhappiness and unhealthiness effects and the current health and happy status of the city - and it would need to check against it. Also Factories probably need a lower AI value, and power plants need a higher one - even more importantly the values for plants when the city already has power should be close to zero. (Coal Plant info needs to be corrected to say +4 ) Higher priority for Medicine might be a good idea too. The basic idea though would be to keep the AI from building a factory and most importantly a coal plant before it gets of fission or plastics. At least I am always waiting for that ..
First off, which is it? Is a coal plant +2 with the factory already having +2 just for coal, or is the coal plant +4 ? I don't currently have a game in the right era to just build and check, and I've seen both asserted by trusted parties.
As for when to/not to build unhealth causing buildings... I guess for the most part I agree that maybe the AI shouldn't begin construction of a building that would cause the city to be unhealthy. But I wouldn't say it's always true- certainly, the AI would not be able to make best use out of Sid's Sushi if it followed such a rule entirely. So I might argue that the calculation should involve food in excess of what is required to reach the happy cap being counted as though it was health. After all, what we really care about isn't whether the city is healthy (unless we want to try to specifically set it up so the city can have We Love the Foo days), but whether it is starving or being denied useful growth.
The next step would be, if the formula for deciding what to build calls for a producing building such that the above calculation would dictate it not be built, the city instead builds a producing building it has available to it. If there are none... here I'm not sure of order of operations, but the AI should attempt to trade for more health, which I assume it can't do while in the middle of deciding what to build, so that implies the build would get postponed in favor of something else.
None of that would require memory beyond a turn. Oh, one additional thing- if the AI is currently in WHEOOHRN, any health benefits derived from trades with the proposed target should be considered to not exist for purposes of determining whether there is enough health to build. After all, you know that you're about to cancel those trades! And you shouldn't make decisions based on the assumption that you are going to successfully conquer health resources.
Coal plant gives a net 4 indeed when built if you never had a power source in the city and have coal: 2 from coal and two from power ( remember, in BtS power gives always 2 regardless of where the power comes ). The civilopedia is perfectly correct.
A coal plant does need a factory to be build, it only needs coal to provide power and +4 though. Something to think about: will the AI build coal plants when it has no coal? I think it might and I sure hope I'm wrong (needs testing).
As for why it does, that is actually pretty simple: Power always gives +2 - the coal plant just gives +2 in addition to that. rolo beat me to it
At any rate, only one source of power is needed. Does the standard AI know that?
You are probably right though, disallowing shrinking is probably enough, city doesn't need to be healthy, and probably not even happy for that matter. I'd say allow unhealtiness unless greater than food surplus, and allow 1* unhappiness (there are no unhappiness buildings in BTS but there could be in mods *number might need tweaking)
So that anti-shrink function would need:
actual health change that the considered building would cause (provided in getAdditionalHealthByBuilding function that BULL provides*)
total current city health - unhealth (goodHealth()-badhealth())
current food surplus or even max food surplus if all available tiles are worked (do not consider more tiles than there is population, do not consider improvement changes, do not consider tiles that are in the BFC but in use by a different city... yeah, just using current food surplus is probably simpler: getYieldRate(YIELD_FOOD) - foodConsumption(true))
Having established what is needed, I just need to find out how to implement it
*edit: Actual Building Effects handles power plants correctly, I was obviously just too stupid to notice so far. Coal gives +4, both Nuclear and Hydro will remove 2 of them.
Building a Hydro Plant where there is a Nulear Plant will NOT save you from meltdowns though, if I understood that code correctly
The issue with that solution ( that is not that bad, regardless of being in skeleton state ) is that the biggest use for stack attack odds ( and why not a stack defense odd counter as well? In terms of stacks, odds of sucessful attack + odds of sucessful defense != 1 necessarily ) is far before the time where the stack is facing the city, when the would-be stack is leaving home ( the human "is this enough?" ). Otherwise, if the AI sends a insuficient stack, realizes that it can't take the city just when it gets there and proceeds to retreat, it will actually make the AI fight worse than it does today , because the more difcult thing to do in a war is a sucessful retreat ( this also applies in civ IV: it means running away 1 tile/turn against a foe that has the potential to use the huge active defense bonuses to reduce it to a shadow of what it was ( at best )
All very true, however as you mention retreat is difficult. I dont mind the AI messing up difficult decisions so much as messing up easy ones.
Making sure you have a large enough attack stack is generally down to deciding when is the best point to attack. The human will consider which tech will affect the quality of its troops, target the weakest AI city, gather funds for upgrades and concentrate its strength.
Generally the AI cant do alot of these things and generally will look at the power chart and then decide whether to attack or not. (which may happen to take into account a recent power surge from upgrades).
Although it would be nice to have an AI that could recreate a MP game I think thats pretty much impossible with current hardware. Therefore the AI needs to get the simple decisions right ie can I attack a city straight away or should I bombard or possibly retreat. In fact if anything I a bit pleased that I can make better macro-decisions than the AI.
Personally if the AI can retreat along a line of hills/forests it is likely to be either more annoying opponent (if pillaging) or to do more damage to the opponent if they try to destroy the units than suiciding them against city walls.
Also some times you dont need to retreat you just need to wait for the war to end and to be transported home.
Personally I find have AI troops on your on terrain very annoying as it stops you getting workers back out.
Otherwise, if the AI sends a insuficient stack, realizes that it can't take the city just when it gets there and proceeds to retreat, it will actually make the AI fight worse than it does today , because the more difcult thing to do in a war is a sucessful retreat ( this also applies in civ IV: it means running away 1 tile/turn against a foe that has the potential to use the huge active defense bonuses to reduce it to a shadow of what it was ( at best )
Just a thought, but maybe the AI could look at the target city, find an analogously sized city of its own (if it doesn't have LOS), and using the number of defenders in its own city, calculate what units it would need to capture this city of its own, factoring in tech leads, resource access, and power differences, and then adding a few extra units for good measure and defense.
Of course, the stack attack odds are the thing that need to be worked out in the first place - but can't it take a stack of its own, simulate the battle between most powerful attacker/defender, assume an outcome, and keep going like this down the line for all units in the stack. Then it could use the results to determine whether or not the stack will be successful or to keep adding in members to the stack.
I dont have anything to back my statement up, but I think the AI currently builds quite a few SAMs. Also, there are situation where they are decent, although rare and far in between.
While the AI has no access to Infantry but access to SAMs, it will build them because they are the strongest current unit. If it has access to both, it will build both, more infantry though.
If the AI's riflemen can only upgrade to Infantry, it will do that, that should give the AI a nice defence already. It will still build a lot of SAMs when it detects that this unit is underrepresented or so (I think, or was that going by unit class?)
But anyway, I agree, it has to be a LOT more infantry than SAM. Would changing he flavor value in the XML help? Like 8 for SAM, 9 for Mobile SAM (10 is normal).
The real AI KO scenario atm is having access to the SAM upgrade before the Mobile Infantry upgrade - which will ALWAYS happen - paired with the AI always upgrading when it can. Rocketery will therefore always weaken the AI. Upgrade path change looks like the only solution to me. All other ways are probably hidden in UnitAI
back to (my most overused smiley ) [me trying to understand C++ code, please be aware that all of this could be total nonsense]
BUILDINGFOCUS_PRODUCTION 1 is only checking for bDanger and that doesn't do much. The really important check against bLandWar && WarSuccessRatio is not there.
I think the AI does indeed not know about bad health from power, dirty or not, but it knows about the good health gained by adding a clean power plan to a city with dirty power. For other buildings it should actually take the unhealthiness into account, and even overvalues its negative effects - Factory with coal and oil should get -60 iValue from the health check alone, which would mean it would need to generate 6+ additional hammers (focus production, twice that without) just to be above zero again.
The Factory gets a lot of value for the prodution bonus with power even when there is still no power in the city (which is ok if you can build a power plant right afterwards - without shrinking the city - though that isn't always the case).
Even in a war, with lots of unhealthiness in the cities, a nuclear plant can look really nice to the AI because of its health bonus and the lack of any other health buildings (it correctly doesn't add production bonus from power if power is already there) - and because at least BUILDINGFOCUS_PROCUTION 1 doesn't even consider wars, it can get built with no consideration for wartrouble. If you have BBAI logs for those turns when your vassal built nuclear plants, that would be helpful to confirm my suspicion.
My simple check for shrinking inside CvCityAI::AI_buildingValueThreshold looks like this:
Spoiler:
Code:
...
[SIZE="1"] int iHappinessLevel = happyLevel() - unhappyLevel(1);
int iAngryPopulation = range(-iHappinessLevel, 0, (getPopulation() + 1));
int iHealthLevel = goodHealth() - badHealth(/*bNoAngry*/ false, std::max(0, (iHappinessLevel + 1) / 2));
int iBadHealth = std::max(0, -iHealthLevel);
int iHappyModifier = (iHappinessLevel >= iHealthLevel && iHappinessLevel <= 6) ? 6 : 3;
int iHealthModifier = (iHealthLevel > iHappinessLevel && iHealthLevel <= 4) ? 4 : 2;
if (iHappinessLevel >= 10)
{
iHappyModifier = 1;
}
if (iHealthModifier >= 8)
{
iHealthModifier = 0;
}
[/SIZE]
[COLOR="Green"]/********************************************************************************/
/* Anti-Shrink 16/01/10 Fuyu */
/* - requires Actual Building Effects (BULL) */
/********************************************************************************/
// Don't consider a building if it causes the city to immediately start shrinking from unhealthiness
// For that purpose ignore bad health from Espionage.[/COLOR]
int iGood = 0;
int iBad = 0;
int iBadHealthFromBuilding = std::max(0,(-kBuilding.getAdditionalHealthByBuilding(iGood,iBad)));
int iUnhealthFromBuilding = std::min(0,(badHealth() - goodHealth() [B][COLOR="Red"]-[/COLOR][/B] getEspionageHealthCounter())) + iBadHealthFromBuilding;
[COLOR="Green"]// Allow a bit of shrinking after all? Recommended settings: <= 1[/COLOR]
int iAllowedShrinkRate = 0;
if (iUnhealthFromBuilding > 0 && (iFoodDifference + iAllowedShrinkRate < iUnhealthFromBuilding ))
{
return 0;
}
[COLOR="Green"]/********************************************************************************/
/* Anti-Shrink END */
/********************************************************************************/[/COLOR]
int iAllowedShrinkRate = 0; <- that simply reduces the building value to 0 and thus (I hope) disallows building something that will start shrinking the city at current pop level - if the city grows until building is finished it could still start shrinking back but there's no easy way to check against that.
I am currently trying to rewrite happy and health parts of this function too...
Some very good ideas and important issues here ... thanks everyone. Version 0.83 has just gone gold and I'll post it soon, so it's too late to be included there but I'll look at these issues directly for the next version.
The AI does already keep track of the different combat types of enemy units, Melee/Mounted/etc and does adjust its production accordingly. However, the UNITAI type divisions mean it will always have balanced stacks ... basically, UNITAI_COUNTER is the main UNITAI type where the AI considers what kind of units it's up against and adjusts weights accordingly. If Monte had 1/3 Spears in his stack, then he was considering your overweight in mounted as typically an attack stack against an enemy with no mounted would have very few spears. In terms of unit construction, the main thing I intend to modify is the number of siege units the AI builds for its attack stacks and for defense. Adjusting stack aggregation and composition, and then unit movement in the field is one of the planned focuses for 0.85. In particular, I want an AI which is badly outgunned to use its attack stacks for active defense ... then we should see battles around cities and with siege used to knock out incoming stacks.
The AI definitely does have issues with health in the industrial era ... basically, the industrial and later were certainly not tested nearly as much by Firaxis during the main AI development. Building health first becomes an issue then, so the AI is setup so it works okay most of the time in the later eras but not fine tuned to consider all cases.
I'll look into whether and why the AI "upgrades" many of its normal infantry to SAM ... the root cause will be the same as why it might build one over the other. There are a number of ways this can be addressed, and we do want the AI to have a few in cities and in its attack stacks. Tweaking AI valuation of interception odds for certain UNITAI types would probably do the trick.
The AI does place a very high priority on buildings which boost production (or that it thinks boost production ...). It's common to see the AI start building factories in all its cities as soon as it can, regardless of its war situation. This is something I now know how to address, and with some of the new abilities added to city construction decision making for 0.83 this should get easier to fix. As for the double power plant, my bet is that the AI doesn't check whether it already has power.
Multiple people have posted about privateer suicides lately ... one issue is that when the AI decides whether to build privateers it only checks whether they're reasonably strong compared to the other naval units it can build. The AI doesn't currently keep track of whether its enemies have gotten destroyers, which it really should. There are certain AIs who are suicide happy, and there are some strange internal mechanics to how the AI adjusts attack odds thresholds for stacks and leader personalities.
In particular, I want an AI which is badly outgunned to use its attack stacks for active defense ... then we should see battles around cities and with siege used to knock out incoming stacks.
Not that the rest of the ideas don't sound interesting, but this one just sounds excellent! In my opinion, this is the main weakness in defensive AI fighting. And since most human players typically encounter the AI on the defence, it will have a large effect on the perception of the AI war capabilities.
I also think it will be hard to fix. Good luck with this one.
Edit:
The valuation of the negative effect of an unhealth increasing building could be based on the shortage of health after the construction of unhealth increasing buildings.
The shortage of health is equal to:
minimum (#unused tiles (which hold some minimum value), excess happiness) - (excess health)
Example 1 :
A city has 3 unused tiles which hold some minimum value. It also has 3 net happiness and 2 net health. There's a shortage of 1 health. Building a coal plant will increase the shortage to 5.
Calculation before construction of coal plant min (3, 3) - 2 = 1. Calculation after construction of coal plant: min (3, 3) - (-2) = 5.
Example 2 :
A city has 4 unused tiles and 0 net happiness, 2 net health. Buildings a coal plant will result in a health shortage to 2.
Calculation before construction of coal plant min (4, 0) - (2) = -2 (a shortage of -2 is a surplus of 2). Calculation after construction of coal plant: min (4, 0) - (-2) = 2.
Example 3:
A city has 3 unused tiles and 1 net unhappiness, 3 net health. Building a coal plant will result in a health shortage of 1. But that's not an issue since there's also a happiness shortage of 1.
Calculation before: min (3, -1) - 3 = -4. Calculation after: min (3, -1) - (-1) = 0
This is what the AI needs not an exact prediction of what the chances are of a stack will winning. In fact it would be very easy to calculate exact stack odds. It would just be very computationally demanding and if every AI had call this routine every time it considered attacking a city it would seriously slow down the AI.
What we would need is a scalable algorithm... the AI should use a preliminary simple bare-bone (non computational heavy) algorithm to check if it has any chance at all in the fight. Then if the odds are favorable, it fires the more complex and computational heavy algorithm to make a final decision. (In this final step it can take things like unit type and match ups into consideration.)
The first algorithm could be as simple as comparing the AI total stack power devided by number of units, to the enemy total power divided by number of units. If that "average power" number is low (in other words lower than a constant we create and change/balance with testing), it stops considering the attack right there without wasting more CPU power with more calculations. If it seems to have the advantage, it does further (more precise) calculations to take a final decision on doing the attack or not.
The advantage of such method is, if the odds are ridiculously low (say a stack of 15 weak units vs 40 strong units), the AI won't waste computing power to calculate an in depth simulation of the fight. If you have 20 civs in a huge map, each one considering attacking or not (and where, vs multiple targets), the amount of computer power (and waiting time between turns for the human player) you save will be huge.
We (as human players) do the same thing. If we have a quick look at a stack and see clearly that we can't win (without thinking much about it, just a half second glance at the stacks), we won't even bother thinking much about it. But if we see with a quick look that a win is possible, we will think about the details and take a final decision depending on how much loss we estimate, and if it is acceptable to us. (The "acceptable loss" threshold for the AI could be derived from one of its properties like level of aggressiveness and such. Or if the extra computing power is acceptable, we can come up with a formula taking into account aggressiveness + number of turns that would take the AI to replace its losses, etc.)
The valuation of the negative effect of an unhealth increasing building could be based on the shortage of health after the construction of unhealth increasing buildings.
Actually that's how it works currently. Almost. Actually it doesn't even value bad health lower when there is enough good health to compensate, bad health just has the same value as good health would have for an unhealthy city, only negative.
Actual shrinking is not considered though, and the value for production bonus is incredibly high.
Considerations: Do you look at the current city size, or do you look at size+1, or even target size (or all of those)? Are temporary effects (whip and espionage bad happy/health) to be ignored completely, or just reduced, and by what value/factor? There should also be a bonus for a city with neither unhappiness nor unhealth.
How much is one unhappy citicen turned happy - or the other way round - worth, and doesn't that have something to do with the yields of tile (or open specialist slot) it is working / could work, multiplied with all yieldmodifiers?
Increasing or reducing unhealth should be valued stronger the lower the iFoodDifference, even more if shrinking starts - but by how much exactly?
The AI currently considers size+1 for happy, and for health size or size+(happiness+1)/2, whichever is higher.
Code:
int iHappinessLevel = happyLevel() - unhappyLevel(1);
int iHealthLevel = goodHealth() - badHealth([COLOR="Green"]/*bNoAngry*/[/COLOR] false, std::max(0, (iHappinessLevel + 1) / 2));
It does check if there is already power in the city (bProvidesPower && !isPower()) but it gives insane values to power plant buildings if there is none.
It doesn't loop through all cities or all cities in the area to find out how much area or global effects would currently really be worth but I guess that's simply for CPU time savings?
I strongly disagree that a calculation-based approach is desirable. Leaving aside the computation time, the problem is that it would tend to lead to the AI sitting there until it has reached some well known victory chance threshold. Against Monty maybe you'd have a 66% victory chance, cause he's insane. Against Gandhi maybe you'd have 33% because he's cautious. What's the fun in that?
r_rolo1 said:
Otherwise, if the AI sends a insuficient stack, realizes that it can't take the city just when it gets there and proceeds to retreat, it will actually make the AI fight worse than it does today , because the more difcult thing to do in a war is a sucessful retreat ( this also applies in civ IV: it means running away 1 tile/turn against a foe that has the potential to use the huge active defense bonuses to reduce it to a shadow of what it was ( at best )
I think the difficulty of retreat is more of a real-world concern than a civ4 concern. In my experience, with my style of play, if I can kill the AI stack so easily then it would not have gotten a chance to arrive at my city, let alone run away. In any case, I often cannot afford to attack it, I rely on how stupid they are about attacking me. If they simply didn't throw away their units, I would loose a lot more games.
My victories over AIs rest on the twin pillars of: (1) AIs throw away armies on my cities, generally in tasty bite-sized increments, (2) AIs store their armies where they are most vulnerable to me: in their cities!
The AI definitely needs defensive Stacks of Death along with some basic improvements to city assault.
I think a stack calculator is not practical. It would be so easy to lure the AI into attacking, simply by leaving your city with one or two weak defenders. The AI would then send small stacks into my territory, and I can simply reinforce my city as I see fit with a mobile reserve, and the AI's calculation then tells it to retreat. That then gives me time to build an effective countering force.
How does the AI target anyways? Does it alway go after the city closest to its border?
I think a stack calculator is not practical. It would be so easy to lure the AI into attacking, simply by leaving your city with one or two weak defenders. The AI would then send small stacks into my territory, and I can simply reinforce my city as I see fit with a mobile reserve, and the AI's calculation then tells it to retreat. That then gives me time to build an effective countering force.
How does the AI target anyways? Does it alway go after the city closest to its border?
I dont think anyone is suggesting using a stack calculator to target cities / decide how big its attack stack is going to be. I think the current mechanics for this are ok.
Except sometimes the AI will form 2 smaller stacks when 1 large stack would be better. Or it will have some units on some other duty near the stack which should join but dont.
I think we are suggesting using this algorithm when the stack has a chance to launch a stack attack. In particular Im looking at instances when the AI could take a city but chooses to bombard for no reason.
I read with great joy that jdog is going to look at this - imho - the most glaring remaing weakness of the AI. After all the great work jdog has done so far, the old "let them commit suicide at my walls" will be one of the easiest way to defeat the AI. Even if they outnumber him greatly, they just can´t hold a candle tactically to the human player. I know nothing of programming, but even a few "simple" tweaks might improve the situation dramatically:
1.) Always bring some "2 move" units in a stack and make them pillage everything they move over on their way back (and forth) across enemy territory. If no 2-move-units available, then start pillaging after moving to 2nd city (see point 2).
2.) If a stack arrives at a target city and doesn´t contain at least twice the hitpoints of the defenders (modified by city defence) then move to next city (pillaging on the way).
3.) If a stack moves in enemy territory for 10+ turns (indicating of lack of defense force by enemy), start forming some "pillaging stacks" of 3-5 units that wage a war of destruction on the improvements.
Many times I wage war on a stronger enemy, have his stacks move through my territory without damaging anything, then committing suicide at my walls - giving me valuable XP. If it would at least force me out of my cities... but this way I can win the "war of hammers" / war of attrition easily.
I second this, with my only reservation being that it could be quite annoying for the human player. I have had some very hard battles against my brother solely because he was able to effectively pillage my strategic resources.
When the AI determines that its attacking army is not strong enough, it should most certainly focus on laying waste to the countryside. I think that the logic does not need to be complex, beyond deciding not to attack. If the forces are not judged to be sufficient, simply move to some convenient squares and pillage them. In order to avoid silly back-and-forth behavior, the AI should be able to judge the power of its army vs nearby cities from a distance.
This could also provide a boost in AI vs AI wars, where the stronger combatant finds itself in enemy territory but not able to finish the job. A lack of roads and resources could definitely push the weaker AI down.
My brother and I have been playing with doubled AI unit production and halved AI unit support costs. While this can be intimidating, it has made less difference than we expected because the AIs have no fear while on the offensive and no bravery on the defensive. Also interestingly, it might have actually made it harder for AIs to conquest each other.
pre BTS obviously wanted a higher stack Power Ratio (attack force / defenders) - was it 250?
You can still set it in GlobalDefinesAlt.xml, the 110 BBAI_ATTACK_CITY_STACK_RATIO is simply too low. Seriously, why 110? (oh right, because it is BTS default .. still needs higher number I believe) As a human I wouldn't even attack below ~300
Higher value = less suicide. Simple enough. The not so simple alternative would be to introduce real stack odds based on some actual combat simulation.
Defending is a whole lot trickier, how would an AI know when it is better to attack than to wait in the city where it's getting all the collateral damage?
One idea would be to simply use all available siege units and then all units that don't get defence boni to suicide against the attacker, then compare power again and see it what is left can be picked off with the remaining units.. or so. IF the attacker has a lot of siege of course, but human tends to have a lot.
A different question: where in the code does the AI decide it is ready to go to war, and where does it actually declare it? In my latest test game some AI declared on me, moved 1 (!) Axeman onto a remote forest tile in my territory and there this unit is still waiting .. for me to kill it I assume. Changing into debug mode to see everything didn't reveal any hidden attack stack anywhere either.
Barring the simulation solution (which is possible, but difficult -- others have tried, it really gets bogged down), we need heuristics that are robust under unit type changes (but not game rule changes).
I'd do a two pass check. First, if I "fully reduce" the enemy by siege, is it worth attacking? If not, then attacking is suicide.
Next, if I presume that my siege will be able to "efficiently reduce" (ie, use the majority of collateral damage attacks happen) the enemy, will the expected damage to their "real" power be enough that I have a decent chance of winning?
Next, am I better off waiting a round (to beat down the defences or wait for reinforcements to arrive).
#1 requires an ability to determine what my "reduction" abilities are, and an ability to estimate "real power" of both my stack and the enemy defence stack at hypothetical reduced HP. If this (relatively simple) model says "in this case, I still don't have a chance", then attacking is probably futile.
#2 requires a back-of-napkin estimate of how much damage a collateral unit causes when it attacks in collateral damage and non-collateral damage, and similar for the rest of the combatants in my stack. If that back-of-napkin says "my attack + collateral power is sufficient", I should attack.
#3 requires doing a model of "what will it be like after a round, if I use siege to reduce defences", and have a clue asto what units are moving into help out with the fight.
You can still set it in GlobalDefinesAlt.xml, the 110 BBAI_ATTACK_CITY_STACK_RATIO is simply too low. Seriously, why 110? (oh right, because it is BTS default .. still needs higher number I believe) As a human I wouldn't even attack below ~300
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.