• Civilization 7 has been announced. For more info please check the forum here .

Colonial AIs are too hard to kill

jooe

Warlord
Joined
Oct 25, 2014
Messages
120
In my games (usually on gigantic maps) AI players (not natives) are mostly very hard to kill.
They can respawn until turn 100 - and after that they soon have:
1) many units spread out on the map
2) a queue of many units on the docks in Europe
3) lots of money to spend

After turn 100 there is a possibility to kill a player if all the following conditions apply at the same time (CvPlayer.cpp:8387):
1) it is not a human player (= it is AI)
2) the setting KI_RESPAWN_OFF is 1
3) it has no settlers left
4) it has less than 5 units (excluding treasures, wagons and working boats) or no transport ships left
5) it has no cities

But if these are not fullfilled at the same time (e.g. 5 units left somewhere on the map), it will respawn with their starting units. (CvPlayer.cpp:8435)

Those starting units are powerful enough to start a new settlement and until you discover that on a gigantic map, they will again have sent some units to some remote place so you won't find them before conquering the settlement.
And then they respawn again.

Also, as long as they have some money left, they will buy settlers in Europe - so they do not fulfill condition 3) anymore.

We were discussion this in the chat and there were two suggestions that came up:
A)
1) If more than 10 units wait in Europe of AI: We tell AI to buy additional Ships if it has enough Gold (and Cities) to affo
2) After Grace Time: If AI has no more Cities / Settlers: It may try to buy a Settler for Gold --> it gets kill
3) After Grace Time: If AI has no more Ships: Ity may try to buy a Ship for Gold --> it gets kill
4) After Grace Time: If AI falls below 5 Units (except Treasures, Wagon Trains, Worker Boats) --> it gets killed

B)
An AI could (under certain conditions - having lost all cities, being very weak in comparison to the player, maybe more ...) allow a diplomatic action like "retreat from the new world"
By utterly defeating an AI, you could force them to retreat by a diplomatic action similar to a peace treaty, but which they would usually not accept
 
I suggest the following solution approach:

Part A) Ensuring that AI has enough Ships

We ensure that AI is better at transporting Units from Europe.

If more than 10 units wait in Europe of AI:
We tell AI to buy one more instance of its Starting Ship if it has enough Gold (and Cities) to afford. <--- At least twice as much money as the Ship costs.
(Otherwise it should save its money for Settlers.)

Part B) Logic after Grace Period (changed)
After grace period AI will not get respawned its Starting Units for a tax increase anymore.
After grace period there will be an "OR" of 3 respawn or kill conditions:

If AI has no more Cities / Settlers: It may try to buy a Settler for Gold --> If it cannot afford it gets killed
If AI has no more Ships: Ity may try to buy a Ship for Gold --> If it cannot afford it gets killed
If AI falls below 5 Units (except Treasures, Wagon Trains, Worker Boats) --> it gets killed

Part C) Logic before Grace Period (unchanged)
Before grace period logic will stay as it is.
Meaning AI will get respawned its Starting Units for a tax increase.

-----------

Is that a good compromise?
 
Last edited:
If I understand your idea (Part B) correctly, the pseudocode for that would be:
Code:
bWillRetreat = false;

if(numCities() == 0 && numSettlers() == 0 && !buySettlerInEurope())
  bWillRetreat = true;
if(numTransportShips == 0 && !buyTransportShipInEurope())
  bWillRetreat = true;
if(numUnits() <= 5)
  bWillRetreat = true;

if(bWillRetreat) retreatFromNewWorld();

But what about the current respawn (after grace period) option - we would then eliminate that completely?
Also that logic would mean the player is killed even if it has a ship with a setller en route from Europe. (if these are the only two units)
 
But what about the current respawn (after grace period) option - we would then eliminate that completely?
It would not really be "eliminated".
It would basically be replaced by this.

buySettlerInEurope()
buyTransportShipInEurope()


But yeah, there would not be a "respawn of Starting Units" (for tax increase) anymore after Grace Period.
 
Last edited:
if(numUnitsOnMap() <= 5)
I was not saying "OnMap", I was saying "Units Total" (incl. Europe).
Since the other conditions are so strong already, this is just a "third" additional check.

So e.g. after Grace Period:
It has a Ship with a Settler but only 2 Units in Europe --> too weak to pose a challenge or recover --> killed
It has a Ship with a Settler but about 5 Units in Europe --> we still give it a chance --> not killed
 
if(bWillRetreat) retreatFromNewWorld();
For the moment this could be "killed".

In the future we might rewrite the logic that it will sell its assets to the next weakest player for e.g. 2000 gold (modified by GameSpeed).
(To find out who is the next weakest player, all that needs to be done is to compare the game scores.)

A) If that other player can afford that, he will get all the stuff that "retreating player" still has.

The Units on Map change the Player / Owner and are "transported" to the Capitol of the new Owner
The Units in Europe change the Player / Owner and are "transported" to the Capitol of the new Owner
The Cities if the "retreating Player" still has any would then also switch the owner. (e.g. in the case "No Ships")

B) If he cannot afford that stuff the Player is simply killed.

i.e. as of now

-------

Comment:
The Human player should be exclude from this "inheritance" logic. (Since it would be extremely rare anyways that Human is 2nd weakest player.)
Otherwise it would become too much effort to make it immersive by e.g. a Diplo-Event-Dialogue for very little gameplay benefit.
 
Last edited:
By the way:
All this discussion is of course only applicable of course fo KI_RESPAWN_OFF == 1
(Because otherwise the "grace period" is more or less endless.)
 
Also that logic would mean the player is killed even if it has a ship with a setller en route from Europe. (if these are the only two units)
Correct. :thumbsup:

Because after grace period it would be no challenge anymore to any other player.
It would have no chance anymore to catch up with the already established empires.

But again:
The condition for that is still the "Total Number" (except Treasures, Wagon Trains, Worker Boats).
So having e.g. 3 Colonists waiting in Europe would then prevent it from being eliminated, if it still has the Ship with a Settler.
 
Also that logic would mean the player is killed even if it has a ship with a setller en route from Europe. (if these are the only two units)
We should adjust this condition however:
if(numUnits() <= 5)
bWillRetreat = true;

to this:
if(numUnits() <= 5 && numCities() == 0)
bWillRetreat = true;

Because with the "Or" we should not kill a player in that condition that still has a City. :thumbsup:
(If the player has no Ships it is killed anyways by the second condition checked before.)
 
I'll see if I find enough time.
Because after grace period it would be no challenge anymore to any other player.
It would have no chance anymore to catch up with the already established empires.

But again:
The condition for that is still the "Total Number" (except Treasures, Wagon Trains, Worker Boats).
So having e.g. 3 Colonists waiting in Europe would then prevent it from being eliminated, if it still has the Ship with a Settler.
If we only want them to survive in the case the have a realistic chance to catch up, then we might want to increase the number of minimum units proportional to game turns somehow. Like turns / 20 or so.
 
If we only want them to survive in the case the have a realistic chance to catch up, then we might want to increase the number of minimum units proportional to game turns somehow. Like turns / 20 or so.
Nah, let us not make it more complicated than it needs to be.
It would be too difficult to match it to e.g. GameSpeeds and WorldSize.

The other 2 conditions are already pretty strong. :)
(Condition number 3 is just like a last safety check.)

Also you already excluded Treasures, Worker Boats and Wagon Trains.
 
Part A) Ensuring that AI has enough Ships
We ensure that AI is better at transporting Units from Europe.

If more than 10 units wait in Europe of AI:
We tell AI to buy one more instance of its Starting Ship if it has enough Gold to spare (and Cities) to afford. <--- At least twice as much money as the Ship costs.
(Otherwise it should save its money for Settlers.)
This here is also an important part of the equation. :)
It is not just about the "respawn / kill logic".
 
Last edited:
Part A) Ensuring that AI has enough Ships
We ensure that AI is better at transporting Units from Europe.

If more than 10 units wait in Europe of AI:
We tell AI to buy one more instance of its Starting Ship if it has enough Gold (and Cities) to afford. <--- At least twice as much money as the Ship costs.
(Otherwise it should save its money for Settlers.)
I was just checking how the AI decides what to buy in Europe. The code for that is apparently in CvPlayerAI::AI_unitGoldValue(...)
So maybe it is the most elegant solution to just change the weight it gives to transport units depending on how many waiting unit there are in the queue?
Maybe something like this:
Code:
case UNITAI_TRANSPORT_SEA:
        // WTP, jooe: increase desirability of transports for each unit in Europe queue > 5
        iTempValue = 4 + kUnitInfo.getMoves();
        iTempValue *= (iCargoValue + iDefenseCombatValue / 2);
        iValue += iTempValue / 7;
        iValue += std::max(getNumEuropeUnits()-5,0) * 500;
        break;
What do you think?
(I am starting with 5 units in queue because it is a slow increase in desirability, so at about 10 units I would expect it to be the most desirable unit. But of course the exact weighting will have to be tested.)
 
What do you think?
Sounds pretty reasonable. :thumbsup:

But I would increase the threshold for giving it additional value from 5 to 10.
AI really often needs to also prioritize e.g. Military, Settlers, equipment ...
 
Yeah, but remember it is scaling with the additional units, not a simple on/off switch. So it might take a few units to be really valued more than one of the other available purchases.
Also, if the AI buys another (valuable) unit in Europe but cannot transport it, it won't be useful after all ...
 
I wonder if the person who wrote that code did some table calculations on the weightings ...
 
A small remark / thought. :think:

If AI has less ships than colonies AND enough defenders for its colonies:
Then it should potentially also increase the value of buying a Ship. <--- Because it will then better be able to trade goods.
 
Top Bottom