Barbarian generation: how it works in BTS and in AND

valergrad

Warlord
Joined
May 26, 2013
Messages
186
I decided to get an idea how it works. At first look, it can be improved and rebalanced, but before discussing this we need to get clear understanding how it works now.

First of all, there are 3 important parameters. In BTS they are:
<Define>
<DefineName>MIN_ANIMAL_STARTING_DISTANCE</DefineName>
<iDefineIntVal>2</iDefineIntVal>
</Define>
<Define>
<DefineName>MIN_BARBARIAN_STARTING_DISTANCE</DefineName>
<iDefineIntVal>2</iDefineIntVal>
</Define>
<Define>
<DefineName>MIN_BARBARIAN_CITY_STARTING_DISTANCE</DefineName>
<iDefineIntVal>2</iDefineIntVal>
</Define>

in AND they are:

<Define>
<DefineName>MIN_ANIMAL_STARTING_DISTANCE</DefineName>
<iDefineIntVal>3</iDefineIntVal>
</Define>
<Define>
<DefineName>MIN_BARBARIAN_STARTING_DISTANCE</DefineName>
<iDefineIntVal>4</iDefineIntVal>
</Define>
<Define>
<DefineName>MIN_BARBARIAN_CITY_STARTING_DISTANCE</DefineName>
<iDefineIntVal>6</iDefineIntVal>
</Define>
I think, these are the most important parameters in barbarian spamming, as we will see further. This was a spoiler, but let's start from the beginning.

We will look at function cvGame::createBarbarianUnits in BTS and AND.

First of all, if GAMEOPTION_NO_BARBARIANS enabled - no new barbarians or animals during the game, this is simple.

Then we check - do we need to add animals? Every move we can add either animals, either barbarians, but not both of them.

When do we add animals?
We do 3 checks in AND ( 2 checks in BTS) and add animals if at least one is passed. If all three checks failed, then we add barbarians.

Check 1 - AND only. We check era parameter isNoBarbUnits and if it is false - we toss a coin. And with probability 50% we will spawn animals this move:

#ifdef C2C_BUILD
//TB animal mod begin
if (!GC.getEraInfo(getCurrentEra()).isNoBarbUnits())
{
if (getSorenRandNum(100, "Animal or Barb") < 50)
{
bAnimals = true;
}
}
//TB animal mod end
#endif
This parameter is 1 starting from industrial era, so this check will work until industrial era. But the thing is that createAnimals later has it's own check based on it's own parameter - bNoAnimals, and it will be 0 already at medieval era. So, what you'll actually get:

at ancient and classics era - get 50% moves animals, 50% moves barbarians.
at medieval and reneissanse - get 50% moves barbarians, 50% moves ... just nothing. Looks strange.

Check 2. How many turns have passed since the start of the game? We take the parameter iBarbarianCreationTurnsElapsed from HandicapLevel and multiply it by iBarbPercent/100 from GamespeedLevel.

In BTS, the first parameter is 50 on the settler level, 45 on chieftain, and so on, until 10 on deity. The second percentage is 100 on Normal, 67 on Quick, 150on Epic, and 400 on Marathon.

This means, for example, on a [settler marathon] game, you will always get animals for the first 200 turns (50 * 4 = 200). No barbarians, just relax and have fun, expand like crazy. On a [deity normal] game, this is only guaranteed for the first 10 turns.

In AND, the first parameter is 45, 40, 35, 20, 20, 20, 15, 10, 10. I'm not sure why it had to be tweaked a little bit, but let's leave it for now. The second parameter is 800 for eternity, then 600, 400, 300, 200, 150, 100.

So, for example, in an [settler eternity] game, animals are guaranteed for 360 turns, whereas in a [deity normal] game, it's only guaranteed for 20 turns.

Also, if you are playing with the option GAMEOPTION_RAGING_BARBARIANS, then the first parameter multiplier will be overwritten as 1 - but this is only for AND! So, this anti-barb defense will stop working from the 2nd turn in a normal game or the 9th turn in an eternity game, regardless of your handicap level. I think this is incorrect. Furthermore, you'll see that GAMEOPTION_RAGING_BARBARIANS completely ignores your handicap level in all instances (and overall it looks like some random tweaks made in a hurry).

Check 3. This is the same for BTS and AND. If the number of cities is less than 1.5 times the number of alive civilizations, you will get animals. Therefore, with GAMEOPTION_RAGING_BARBARIANS, this will be the main obstacle to spawning barbarians in the first few turns. In a deity-level game, the AI starts with an additional settler, so most of them typically settle their second city within the first 5-7 turns, regardless of game speed. After that, the barbarians will start spawning.

Therefore, in AND with [DEITY ETERNITY] and [GAMEOPTION_RAGING_BARBARIANS], you will likely start encountering barbarians from the 9th-10th turn (based on the coin toss from check 1). Considering the unit cost at this level, there is a probability that your first warrior (if you started with a worker or scout) will not be built by that time, leading to an auto-loss. This is definitely unbalanced. In BTS [DEITY MARATHON], you have 40 turns to prepare for your first barbarians, which is actually enough time to build your first warrior.

How can we fix this? I think [GAMEOPTION_RAGING_BARBARIANS] should still consider your handicap level, and it should not make your survival dependent on randomness. In BTS, you can at least survive with raging barbarians even at [DEITY MARATHON], regardless of any randomness, and this should remain the same in AND. Therefore, we should remove this addition from AND:

if (isOption(GAMEOPTION_RAGING_BARBARIANS))
{
iBarbsTurnsElapsed = 1;
}

This was probably a desperate attempt to make barbarians 'harder,' but it should not make the game random. We can make barbarians challenging in a different way.
 
Last edited:
Now let's take a look at how CvGame::createAnimals() works if we have chosen to create animals this turn.

First of all, as mentioned, we need to check the era - animals are not created in the medieval era or later. (The era is calculated as an average of the eras of all living players.)

Secondly, animals are not created in the first 4 turns.

Thirdly, animals are not created if the number of cities on the map is less than the number of civilizations alive. So, until the last settler settles, you can freely explore the map and choose the best location for your first city. However, this does not hold true for deity level, as some AI players can quickly settle their second city, triggering the creation of animals.

Now, if all the checks have passed, the most interesting part begins - creating animals.

We do this for each area separately. An area, as I understand it, is a connected set of tiles of the same domain. So, on the map, you will have areas for each continent and island, including single-tile islands, and you will have areas for each ocean and internal lakes. I'm not entirely sure if mountains can split a continent into two areas.

For each area, we first calculate the numberOfNeededAnimals. The calculation is very simple. We take the number of overall tiles in the area, subtract the number of barbarian units we already have there (including animals and barbarians!), and use another parameter called iUnownedTilesPerGameAnimal based on the handicap level as the divisor.

In BTS, it is 100 for settler, then 80, 60, 50, 40, 35, 30, 25, and 20 for deity.
In AND, it is 40 for settler, 40, 40, 40, 40, 40, 40, 35, 35, and 30 for deity. It doesn't change much for some reason.

In BTS, we have one additional step: we divide this value by 5 and add 1.
In AND, this line was commented out.

So, for example, if we have 1000 tiles in an area and there are already 3 barbarian animals and 1 barbarian present:

  • On [BTS, settler], our iNeededAnimals will be ((1000/100) - 3 - 2)/5 + 1 = 2 extra animals to add.
  • If it was [BTS, deity], it would be ((1000/20) - 3 - 2)/5 + 1 = 10 extra animals to add.
  • In [AND, settler], it would be ((1000/40) - 3 - 2) = 20 extra animals to add.
  • In [AND, deity], it would be ((1000/20) - 3 - 2) = 45 extra animals to add.
So, at first glance, even on settler difficulty, AND actually has around 2.5 times more animals than deity difficulty in BTS, due to this commented division. However, as we will see later, this is not as important as it may seem.

Once we have determined the number of animals to add in a particular area, we proceed to attempt adding them. This involves the following steps for each iNeededAnimal:

  1. Select a random plot (lol).
  2. Check if:
    a) The plot belongs to the current area (most attempts will fail this check, especially true for a small areas like islands etc. ),
    b) It is not visible to any civilization,
    c) It is passable terrain,
    d) There are no units (of any type) within the MIN_ANIMAL_STARTING_DISTANCE radius.
  3. If all the checks pass, place an animal on the plot that is suitable for the terrain and feature. If not, return to step 1.
We make 100 attempts to find a suitable plot. If none are found, we do not place an animal but still increase the counter.

First of all, this coding is incredibly inefficient and poorly implemented. I will later measure the amount of time spent on this process, and if it is significant, this illogical logic should be rewritten.

But what does this logic mean in terms of our animals?

Firstly, in BTS, every unit alive has a "defensive anti-animal square" of 5x5 = 25 tiles centered around the unit, where no animals can appear.
Secondly, in AND, this area expands to 7x7 = 49 tiles. (And later we will see that for barbarians, it even expands to 9x9 = 81 tiles.)

So, on average, the animal density will strive to achieve "1 animal per 25 free tiles" in BTS, and "1 animal per 49 free tiles" in AND.

For example, let's imagine a huge Pangea map with dimensions of 210x90 = 18,900 tiles, half of which are water. Let's say we are playing on deity difficulty.

By turn 5, the iNeededAnimals will be (9,000/20)/5 = 90 animals in BTS and 9,000/20 = 450 animals in AND.

It may seem like AND will place five times more animals, right?

Not quite. Each animal placement will occupy approximately 25 tiles of "available plots" in BTS and 49 tiles in AND.
So, BTS will likely place its 90 animals without any issues.
AND will find suitable plots for around 160 animals. For the remaining 300 animals, the CPU will be wasted on 100 attempts to find a suitable plot, resulting in no successful placements.

The next turn BTS will add more 90 animals. Then 90 more, until there will be no place for them, somewhere around 340 animals.
AND will not be able to add more to this 160 animals until some of them will be killed.

So, regardless of iUnownedTilesPerGameAnimal values, BTS will have more animals then AND on the map. You can set iUnownedTilesPerGameAnimal to 1 - it will not change almost anything, except for a wasting CPU on attempts to find a suitable plot. And difference between 40 and 20 that we have in AND between settler and deity also mean nothing.

This is how I understand the code, but of course, I need to verify it to be certain.
 
Last edited:
Shall we continue? Two things about creating animals that I haven't mentioned yesterday, because already wanted to sleep.

First is that when we placing unit we check terrain feature that this plot has. If it has not - we check the terrain type. And then we find list of all animals that can be at this feature/terrain and randomly choose one of them to put.

For example, BEAR can be put only with features FOREST, panther - with JUNGLE. Lion can be placed on terrains PLAINS, DESERT and .
Siberian Tiger has both requirements for feature - FOREST, and for terrain - TUNDRA and SNOW. This does mean we can place it either at forest ( even if this forest somewhere near the equator ), either in tundra/snow. Not sure to be honest, that it supposed to work like this - probably this check should be 'AND' , but currently it is like this.
I think, that for each combination terrain/features there is at least one animal except MOUNTAIN, but MOUNTAIN could not be choosen anyway as it is not PASSABLE.


Secondly is that AND has code for playing water animals. But as we don't have animals living in water , that code will never place anybody. This is how I understood it.
 
Now, let's go to putting barbarians.

It works extremely simular with animals, with some little differences.

In the same way we process each area separately. For each area we need to calculate our iNeededBarbs based on number of tiles in this area, number of barbarian units it already has and the divisor.

Now we have to ways: if our area is in domain WATER or it is LAND.

Water.
For water it depends on iUnownedWaterTilesPerBarbarianUnit from our handicap.
In BTS it is 750 on settler, then 600, 550, 500, 450, 400, 350, 300 and 250 on deity.
In AND it is 100 on settle to monarch, 90 on emperor and higher. Not dependent on our level for some reason.

What if we have option RAGING_BARBARIANS? Then for BTS it is divided on 2, and AND it just set it to 20 - again making it not depended on your level!
And last is BTS divide this on 4 (+1), and AND does nothing.

So, for example, again, huge pangea, 200*90 = 18k tiles, half of them is water. An let's take deity.

In BTS this variable will be ((9000/250)/4)+1 =10. With RAGING_BARBARIANS it would be 19.
In AND it will be ((9000/90) = 100. With RAGING_BARBARIANS it would be 450 - and this will happen even on settler!

Again it looks like that AND will much more, 10-50 times more water barb units? As you see later - not quite.

But before we do one more check that was added in AND.
We calculate total water units of all players in this area, let's call it A. And we calculate barbarian units in this area, let's call it B. And if B > A - we set iNeededBarbs as 0.
I believe the logic supposed to work like this: if barbarians have more navy in this area then all other players combined - don't spawn barbs there for a while, give players some time to catch up)

But what seems to me... that this check missed filter on barbarian civ in calculations in A. So, we compare from one side 'barbarian units' and on the other side 'barbarian + non-barbarian units' and this means that A will be always more than B and this check will always fail, and could be just deleted without affecting anything) This is how i read the code, of course I could be mistaken.

Land.

Now, how iNeededBarbs is calculated for land areas. As divisor it depends on iUnownedWaterTilesPerBarbarianUnit based on hadnicap level.

In BTS this variable will be 150 on settler, then 100, 80, 60, 50, 40, 35, 30 and 25 on deity.
in AND it is 10, 5, 4, 4, 3, 3, 2 and 2 on deity.

And with RAGING_BARBARIANS it is divided on 2 in BTS, and AND just set it to 1. So, again AND doesn't care about your handicap level.

And at last, we divide iNeededBarbs it on 4 with BTS, but in AND we will not do this with RAGING_BARBARIANS.
And the last desperate attempt to increase the spawn of barbarians in AND it is just clear adding 75 with RAGING_BARBARIAN to that value, lol. As you see further, this will not have any affect at all, it could be 75000 or 75 millions with exactly the same effect.

So, again, let's take our huge pangea 200*90, half-water as an example and calculate iNeedBarbs at different levels in BTS and AND.

in BTS we will get :
at Settler , non-raging: (9000/150)/4+1 = 16
at Settler , raging: (9000/75)/4+1 = 31
at Deity, non-raging: (9000/25)/4+1 = 91
at Deity, raging: (9000/12)/4+1 = 188

in AND we will get:
at Settler , non-raging: (9000/10)/4 + 1 = 226 ( lol )
at Settler , raging: (9000/1) + 75 = 9075 ( lol )
at Deity, non-raging: (9000/2)/4+1 = 1226
at Deity, raging: (9000/1) + 75 = 9075

So, again this numbers looks increadibly high in AND and not pretty much dependent on your handicap level. But does this mean that we will place this over 9k barbs? No, we not. Because for each number we
just do an attempt to place the unit, and as you see, in AND they almost all will fail anyway, just wasting time for the CPU and player patience.


So, how the attempt to place a barb works? Pretty much the same as for the animals.

This involves the following steps for each iNeededBarb:

Do in cycle 100 times until your find a good plot or count to 100:
  1. Select a random plot (lol).
  2. Check if:
    a) The plot belongs to the current area ,
    b) It is not visible to any civilization,
    c) It is passable terrain,
    d) The plot is LAND or neighbour to a LAND. So, this condition actually fail for all ocean tiles for generating barbarian navies. They will be always near the coast.
    e) There are no units (of any type) within the MIN_BARBARIAN_STARTING_DISTANCE radius.
  3. If all the checks pass, place a barb on the plot ( type of the barb will discuss later).
So, we do make 100 attempts to find a suitable plot. If none are found, we do not place a barb, but still increase the counter.

Next is the key. MIN_BARBARIAN_STARTING_DISTANCE is 2 for BTS and 4 for AND. And this means that each unit alive has "defensive anti-barb square" of 5x5 = 25 tiles in BTS and 9*9 = 81 tiles in AND.
So, actually placing every unit removes around 81 tiles from consideration ( typically less with intersections, but i don't want to go deep in such details ).
And this means that having this increadible values for iNeedBarbs as 1200, 9075 , even 500 millions - will not change anything. All that it will change: it will make game turn slower, as the game will do 9000 cycles for attempt to place a unit, in each cycle 100 attempts to find a good tile, for each tile scan this 81 squares to check if there is some unit already .... - tons, tons of waster cpu that will not cause placing any unit.

So, what will happen for example on deity giant pangea with 9k tiles and raging barbarians?

In BTS iNeedBarbs will be as we saw 188. So, game will place them when we will get more than 1.5 times more cities than civs alive. 188*25 = 4500, so it will took some place. Also, some place will be used by civilizations. Next turn it will try to place 188 more, but probably will find place only for 150 or something. And later it will just attempt to replace units after civilizations will kill some barbs and clear some space.

in AND iNeedBarbs will be as we saw 9075. But as each barbarian needs around 81 tiles, game will be able to place around 110 only. Other 8900+ attempts to place a barb will work to no effect.So, actually we will spend 50 times more time on placing barbs, but will place them even less that in BTS. Setting this variables to normal will not change barbarian generation, but will reduce time between turns. Definitely something I am going to check - because of course, I could be mistaken and could read the code incorrectly. And I starting to understand why AND is so slow, comparing to BTS...
 
Last edited:
What barbarian unit will be generated?
Basically it looks for all combat units that barbarians can train based on their technologies and resources available. So, this does mean, that for example, if some barbarian city got access to horses in Australia, then everywhere on the map, even in Canada, you can from now on get horse archers. Doesn't feel right IMO, may be better would be to check - what resources just have the nearest barbarian city?

Also, it excludes from consideration units that can be upgraded i.e. too outdated. Excludes units that can only defend.
From that list of units it just take the random one. But before it increases on 20% probability ( not exactly like this, it is oversimplification, i don't want to calculate real probability ) to unit that have UNITAI as UNITAI_ATTACK or UNITAI_ATTACK_SEA.

Additionally in this procedure there is a logic for putting units in ships with cargo ( e.g. Galleys ) and also for adding workers for barbarians cities there - but this is only if you play with game option [BARBARIAN CIVS].
So, in that case if all this conditions are true:
1. City was initially created as barbarian.
2. City size is more than 1
3. This city lacks workers ( there is a complicated function for checking it, basically it looks how many tiles we can improve there taking into account specialists etc. )
4. Passed 10 * GetTrainPercent() turns from the beginning of the game ( this coefficient is 1.67 for Blitz, 3.3 for Normal, 13.20 for Eternity etc, so it will be 17, 33, 132 moves correspondingly )

Then we do a random check. It is actually 7% chance for each city size. So, city with size 6 have 42% to get a free worker every turn, and with size 10 - 70% chance. So, we can just easily assume that barbarians civs will always have enough workers no matter what.

Random strategy comment. I am even thinking - can human player exploit this free source of workers with Woodsman II? Get workers from the barbs, sell them to AI for technologies/money/siege units. Sounds promising. But with [BARBARIAN CIVS] probably this city will evolve to a civilization even faster then you'll get enough money from that.
 
Last edited:
Next function I want to check is - how barbarian cities are created? This is function createBarbarianCities.

1. Of course, we don't create barb cities with option NO_BARBARIANS.
2. Next there is check for an era bNoBarbCities.
In BTS it is 1 for ERA_MODERN and ERA_FUTURE, so we don't place barbarian cities there.
In AND it is 0 for everywhere, so we can get barbarian cities even in TRANSHUMAN era ( this doesn't sounds logical to me ).

3. Next there is check if we have enough cities on the map.
In BTS you need 2 times more cities than alive players.
In AND just need as many cities as an alive players. So, this check in AND will be ready when everybody settle.

4. Now we check if enough turns are passed. We take the parameter iBarbarianCityCreationTurns based on our handicap level.
In BTS it is 55 on settler, then 50, 45, 40, 35, 30, 25, 20 and 15 on deity.
In AND it is 10 for all handicap levels - doesn't depend on levels again.

Then we multiply this on iBarbPercent based on your gamespeed. I've already posted it's values, it is from 67 to 400 in BTS, and from 100 to 800 in AND.
And lastly we divide on start era, so if you've started at ancient it will be 1.
So, in BTS we do not start placing cities before 50 moves on [normal, settler] and for example, 15 moves on [normal, deity].
In AND it will be 20 moves on normal regardless your handicap level.

5. Next is some random check. It depends on iBarbarianCityCreationProb based on handicap level.
In BTS it is 4 at settler, then 5, 5, 6, 6, 7, 7, 7, 8 at deity.
In AND it is again 50 for all handicap levels.
So, basically the code for placing cities will work with probability 4-8% in BTS and with probability 50% in AND.

This code will choose the 'best' place for creating a barb city and create it. But only one. So, basically you'll get 1 new barb city in average every 12-25 turns in BTS and every 2 turns in AND. But this will happen only if density of that area will not be exceeded. So, until we have land area where we have place for a new barbarian city - we will add them one by one.

There is a complicated logic to determine what will be the 'best' place for this city, but for us important are 2 things.
We will not place a city if within a plot MIN_BARBARIAN_CITY_STARTING_DISTANCE there is a tile that belongs to somebody who is no barbarian. MIN_BARBARIAN_CITY_STARTING_DISTANCE is 6 in BTS, so, placing somewhere, for example, a fort will create a huge 13*13 'defense square' where will never be put a barbarian city.

And also, what is important for us, is that city can be placed only if C < T / D where

C = num of already exists barbarian cities in this area.
T = num of unowned tiles in this area .
D = is parameter iUnownedTilesPerBarbarianCity based from handicap level.
In BTS it is 160 for settler, then 150, 140, 130, 120, 110, 100, 90, 80 on deity.
in AND it is 150 for settler, then 140, 130, and apparently jumps to 75 on noble and then 75 until deity.

So, again, let's imagine pangea, 200*90, half-water, deity.

In BTS when civs will have 2 cities in average ( this basically will happen when first AI found a 3rd city), we will start placing a cities. Every move with probability 8% we will found 1 barbarian city, somewhere far away ( radius = 6) from any culture, but, at best places ( that have many resources or good plots ). This will stop until we will have 9000/80 = 110 barbarian cities. But probably much earlier we will just not get good plots anymore or even modern era will happen.

In AND we will start placing barbarian cities after turn 10. Every move with probability 50% we will found 1 barbarian city, somewhere far away ( radius = 6) from any culture, but, at best places ( that have many resources or good plots ). This will stop until we will have 9000/75 = 120 barbarian cities. But again, probably good plots will run out earlier. So, probably around move 160 we will have something like 75 barbarian cities and then this number will stabilize.
 
Previously I've many times stated looking at the code that option RAGING_BARBARIANS doesn't check a handicap level.
This should mean, that for example, if you playing on settler with RAGING_BARBARIANS AI's probably would not survive. That was my hypothesis.

I've checked it - started a new game on GEM, on settler with RAGING_BARBARIANS. This is where 27 civs placed on correct historical locations. Then I've pushed CTRL + SHIFT + X.

After 500 turns ( on normal) I've returned and what I've observed? Only 4 civs survived from 27. One is the one I've started ( Rome) , obviously because it was not on actual settler level, it had actually different handicap and bonuses.

One was my neighbour Spain - probably because of some kind of 'shield', created by Rome.
And two others were that two, that have started on an island - England and Japan.
All others has been eliminated.

Why island civs survived? This is because how placement of barbarians worked. Remember , when I've described that it works for each area separately? And you have 100 attempts to place a barbarian in this area? For each attempt it just take the random plot all over the world, and first check is to check if this plot belongs to that area. Obviously, for small areas, like Island of England, this check will fail almost always ( as number of England tiles is quite small comparing to number of all map tiles ).

This means, that if you area is quite small, less than , for example, 2% of total land area (including water ), you have reduced chances to get a barbarian unit there. On a very small island ( or internal lake ) this chances are negligible. Also IIRC correctly ( i didn't investigated this logic properly, so could be mistaken slightly ) , that chances to get a barbarian city are almost zero if this area is less than 75 tiles.

This is true for both England and Japan, and that is the only reason they've survived.
In total barbarians had 116 cities ( including Uppsala size 18 etc. ) , all other civs combined - 22.

So, I'll use this game as proof that RAGING_BARBARIANS, regardless how it will be fixed, MUST take into account handicap level. Otherwise low-level game it is just 'play with barbarians only'.
Btw for comparison how it looks at the same stage, on the same map, with the same level , but without RAGING_BARBARIANS. In this case AI's feel themselves quite comfortable. Barbarians still world leaders in number of cities ( 42), but their defeat is pretty soon.

1688815184347.png
1688860840134.png
 
Last edited:
This is very helpful. Can you add an explanation of how barbarian cities forming new civilizations? This has been bugging me ever since I started playing AND v1096. I have been testing on a same map with 8 starting civs and placing 4 barbarians cities with population 5+ at fixed positions. 0 and 1 new civs are the most regular occurrences with one game out of dozens of tries resulted in 2 new civilizations. I don't know if the mechanics have changed but I seem to recall in v.1092? pretty much all barbarians cities with population 5+ will likely result in new civilizations. Thanks
 
Top Bottom