Barbarian Cities

krikav

Theorycrafter
Joined
Aug 25, 2011
Messages
5,314
Location
Sweden
Does anyone know the rules and mechanics of when barbarian cities are formed?

I have found the interesting thread
http://forums.civfanatics.com/showthread.php?t=299483,
but I do not think that the aspects of when barbarian cities spawn, is fully adressed.

Apparantly, barb cities can spawn in the fog of war, even if you have a barb-buster 2 tiles away!

Is there some certain conditions that need to be meet, for barb cities to start spawning?

How do previous roaming barbarians react to cites that are founded?

I'm sure there are more questions to be straighten out.
Please contribute with your own questions or facts that you posess, regarding barbarian cities (or barbarians in generall)
 
The only knowledge i posess about the topic is that Barb cities can spawn 2 tile away from your fogbusters. And i hate it when that happens.
I can only speculate about the rest of the topics you mentioned. It seemed to me that barb cities somewhat decrease the number of roaming barbs in the neighborhood of the city (until the city produces the 4th unit which leaves the city again).
Eagerly awaiting the barb-experts.
 
There seem to be a constant iUnownedTilesPerBarbarianUnit, and barbarians can only spawn, if the ratio on the continent is higher than this constant.

ie, loads of unowned tiles, and few barbarians -> much barbs spawning.
and likewise many owned tiles and some barbarians -> fewer spawnings.

Not sure what counts as a "owned" tile though. Could be cultural influences around player, AIs and barbarian cities, or it could simply be tiles that ar occupied by a unit.


It makes sense that cities follow somewhat simmilar rules when they spawn.
But I still don't find any information about what makes barb cities spawn.

They don't seem to spawn very early, so there is some threshold that need to be meet I guess.
 
I never paid any attention to it, until a couple of days ago. I razed a barb city and ended my turn. Immediately, a new barb city spawned two tile to the north of where my troops were. I thought that was a bit bizarre.
 
In summary:

Barb Cities can spawn in any fogged tile

Units can also only spawn in fogged tiles (obv), but they are further restricted in that they cannot spawn within 2 tiles of any unit (yours, AIs, even other barb units!).

(So no barb unit can spawn in a 5x5 area around any other unit)


I dont know anything about the parameters for WHEN they start appearing though.
 
had some free time today... found this code

Code:
void CvGame::createBarbarianCities() {
    CvPlot* pLoopPlot;
    CvPlot* pBestPlot;
    long lResult;
    int iTargetCities;
    int iValue;
    int iBestValue;
    int iI;

    if (getMaxCityElimination() > 0) {
        return;
    }

    if (isOption(GAMEOPTION_NO_BARBARIANS)) {
        return;
    }

    lResult = 0;
    gDLL->getPythonIFace()->callFunction(PYGameModule, "createBarbarianCities", NULL, &lResult);
    if (lResult == 1) {
        return;
    }

    if (GC.getEraInfo(getCurrentEra()).isNoBarbCities()) {
        return;
    }

    if (GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity() <= 0) {
        return;
    }

    if (getNumCivCities() < (countCivPlayersAlive() * 2)) {
        return;
    }

    if (getElapsedGameTurns() < (((GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationTurnsElapsed() * GC.getGameSpeedInfo(getGameSpeedType()).getBarbPercent()) / 100) / std::max(getStartEra() + 1, 1))) {
        return;
    }

    if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) {
        return;
    }

    iBestValue = 0;
    pBestPlot = NULL;

    int iTargetCitiesMultiplier = 100;
    {
        int iTargetBarbCities = (getNumCivCities() * 5 * GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) / 100;
        int iBarbCities = GET_PLAYER(BARBARIAN_PLAYER).getNumCities();
        if (iBarbCities < iTargetBarbCities) {
            iTargetCitiesMultiplier += (300 * (iTargetBarbCities - iBarbCities)) / iTargetBarbCities;
        }

        if (isOption(GAMEOPTION_RAGING_BARBARIANS)) {
            iTargetCitiesMultiplier *= 3;
            iTargetCitiesMultiplier /= 2;
        }
    }


    for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++) {
        pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

        if (!(pLoopPlot->isWater())) {
            if (!(pLoopPlot->isVisibleToCivTeam())) {
                iTargetCities = pLoopPlot->area()->getNumUnownedTiles();

                if (pLoopPlot->area()->getNumCities() == pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER)) {
                    iTargetCities *= 3;
                }

                int iUnownedTilesThreshold = GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity();

                if (pLoopPlot->area()->getNumTiles() < (iUnownedTilesThreshold / 3)) {
                    iTargetCities *= iTargetCitiesMultiplier;
                    iTargetCities /= 100;
                }

                iTargetCities /= std::max(1, iUnownedTilesThreshold);

                if (pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER) < iTargetCities) {
                    iValue = GET_PLAYER(BARBARIAN_PLAYER).AI_foundValue(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), GC.getDefineINT("MIN_BARBARIAN_CITY_STARTING_DISTANCE"));

                    if (iTargetCitiesMultiplier > 100) {
                        iValue *= pLoopPlot->area()->getNumOwnedTiles();
                    }

                    iValue += (100 + getSorenRandNum(50, "Barb City Found"));
                    iValue /= 100;

                    if (iValue > iBestValue) {
                        iBestValue = iValue;
                        pBestPlot = pLoopPlot;
                    }
                }
            }
        }
    }

    if (pBestPlot != NULL) {
        GET_PLAYER(BARBARIAN_PLAYER).found(pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE());
    }
}

this function is called in "doTurn" and is called unconditionally.
The city is spawned if "pBestPlot" is evalued and not null. I will have to invest a bit more time to the cycle going few lines up there to see the math behind this.
 
ok there is couple of conditions first.

this is basically what krikav wrote
Code:
    if (GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity() <= 0) {
        return;
    }
if there is not enough tiles the function returns. didn't go deep enough into the function, but it evaluates this somehow

this one
Code:
    if (getNumCivCities() < (countCivPlayersAlive() * 2)) {
        return;
    }
is a bit more interesting. getNumCivCities is basically counting the number of all cities minus the number of barb cities.
Barb cities can't spawn until there is enough human+AI cities. the threshold is tied to number of civs and is basically 2 per civ.

barb cities can't spawn until is enough turns played
Code:
    if (getElapsedGameTurns() < (((GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationTurnsElapsed() * GC.getGameSpeedInfo(getGameSpeedType()).getBarbPercent()) / 100) / std::max(getStartEra() + 1, 1))) {
        return;
    }
that is based on XML (I guess) and is modified by speed

barb cities will spawn on a chance
Code:
    if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) {
        return;
    }
the probability is of course tied to handicap through xml.

the map itself is tested tile per tile.

cities can't spawn on water and on VISIBLE tiles
Code:
        if (!(pLoopPlot->isWater())) {
            if (!(pLoopPlot->isVisibleToCivTeam())) {

the evaluation of "best tile" looks a bit complicate to be honest :-). So even if all conditions are met then it still can be blocked by the game not finding good enough tile.
 
another thing...
as it seems due to the way the code is done it seems there can't be more then 1 barbarian city per turn spawned (bad luck marathon, this is something where you lose a bit).

the critical part (condition for the best tile) is this:

Code:
                if (pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER) < iTargetCities) {

in my words...if the area has not enough barbarian cities (with area I understand something like island/continent etc) then it is good tile.

the value of the spot is then done this way
Code:
                    iValue = GET_PLAYER(BARBARIAN_PLAYER).AI_foundValue(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), GC.getDefineINT("MIN_BARBARIAN_CITY_STARTING_DISTANCE"));

                    if (iTargetCitiesMultiplier > 100) {
                        iValue *= pLoopPlot->area()->getNumOwnedTiles();
                    }

                    iValue += (100 + getSorenRandNum(50, "Barb City Found"));
                    iValue /= 100;

                    if (iValue > iBestValue) {
                        iBestValue = iValue;
                        pBestPlot = pLoopPlot;
                    }
basically the strength of city, modified by free tiles and random number. the highest tile wins.

Now the "iTargetCities" is value gained from a bit complicated formula

the basics is
Code:
                iTargetCities = pLoopPlot->area()->getNumUnownedTiles();
number of unowned tiles in your area (island, continent etc)

this
Code:
                if (pLoopPlot->area()->getNumCities() == pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER)) {
                    iTargetCities *= 3;
                }
I would interpret as "if the area has only barb cities, the chance is 3x higher"

this
Code:
                int iUnownedTilesThreshold = GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity();

                if (pLoopPlot->area()->getNumTiles() < (iUnownedTilesThreshold / 3)) {
                    iTargetCities *= iTargetCitiesMultiplier;
                    iTargetCities /= 100;
                }
looks like "if the area is not big enough, the chance is lower", but since I didn't check the actual "iTargetCitiesMultiplier" it could be higher chance too :-).
if "iTargetCitiesMultiplier" is > 100 then it's higher chance, if it's <100 then it's lower chance for the area to spawn city (more on this mutliplier next paragraph).

this multiplier is get this way:
Code:
    int iTargetCitiesMultiplier = 100;
    {
        int iTargetBarbCities = (getNumCivCities() * 5 * GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) / 100;
        int iBarbCities = GET_PLAYER(BARBARIAN_PLAYER).getNumCities();
        if (iBarbCities < iTargetBarbCities) {
            iTargetCitiesMultiplier += (300 * (iTargetBarbCities - iBarbCities)) / iTargetBarbCities;
        }

        if (isOption(GAMEOPTION_RAGING_BARBARIANS)) {
            iTargetCitiesMultiplier *= 3;
            iTargetCitiesMultiplier /= 2;
        }
    }
for raging barbs the chance will be 1.5 higher then normal barbs.
the beginning looks like the game calculates based on number of civ cities the "target number of barb cities" and if it is not met then the "iTargetCities" mutliplier is higher, 300% of difference between target number of barb cities and actual number (basically the game tries to 'catch up' with barb cities if there is not enough of them already).


this
Code:
                iTargetCities /= std::max(1, iUnownedTilesThreshold);
looks like universal division based on handicap. (the bigger the number the lesser the chance for barb cities overall)
 
I assume the "best plot" thing is referring to a requirement for special tiles in the small cross and the theoretical big cross. My experience is that barb cities will always have 2 special tiles with at least one being in the small cross and probably some sort of minimum possible food yield for that tile.
 
I assume the "best plot" thing is referring to a requirement for special tiles in the small cross and the theoretical big cross. My experience is that barb cities will always have 2 special tiles with at least one being in the small cross and probably some sort of minimum possible food yield for that tile.

no no the "best plot" in this case is the tile where the city will spawn. if you talk about the variable "pBestPlot" since it's tested on non-NULL and used inner data for coords.
 
I didn't realize the code was that available.
Where can I find it? :)

Awesome job vranasm!

One can clearly see the reason why diety barbs is soo much more agressive compared to immortal. Since all AIs start with a extra settler.
 
Code:
void CvGame::createBarbarianCities() {
    CvPlot* pLoopPlot;
    CvPlot* pBestPlot;
    long lResult;
    int iTargetCities;
    int iValue;
    int iBestValue;
    int iI;

    if (getMaxCityElimination() > 0) {
        return;
    }

    if (isOption(GAMEOPTION_NO_BARBARIANS)) {
[COLOR="Red"]// No barbarians enabled, no cities spawning...[/COLOR]
        return;
    }

    lResult = 0;
    gDLL->getPythonIFace()->callFunction(PYGameModule, "createBarbarianCities", NULL, &lResult);
[COLOR="Red"]// Not sure what this is... perhaps if Python spawns a city, we don't do it in C++ ? [/COLOR]
    if (lResult == 1) {
        return;
    }

    if (GC.getEraInfo(getCurrentEra()).isNoBarbCities()) {
[COLOR="Red"]// Late enough era -> No barbarians spawned. This should be in some XML which era is specified in
 Civ4EraInfos.xml (this wasn't available on the wiki[/COLOR]
        return;
    }

    if (GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity() <= 0) {
[COLOR="Red"]// From quite extensive diving, I have concluded that a plot (the code name for what we usually call "tile"), 
is "Owned" if it is either a city, OR is under the cultural influence of a city.
A continent with many creative players, will have far less unowned tiles early. [/COLOR]
        return;
    }

    if (getNumCivCities() < (countCivPlayersAlive() * 2)) { 
[COLOR="Red"]// Worth to notice that this is map-wide, most other things look at the continens.[/COLOR]
        return;
    }

    if (getElapsedGameTurns() < (((GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationTurnsElapsed() * GC.getGameSpeedInfo(getGameSpeedType()).getBarbPercent()) / 100) / std::max(getStartEra() + 1, 1))) {  [COLOR="Red"]// This is turn 40 on noble, turn 15 on deity.[/COLOR]
        return;
    }

    if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) {
[COLOR="Red"]//the cityCreationProb is 6 on noble and 8 on deity.
And this is probably the reason why barb cities are so irregular.[/COLOR]
        return;
    }

    iBestValue = 0;
    pBestPlot = NULL;

    int iTargetCitiesMultiplier = 100;
    {
        int iTargetBarbCities = (getNumCivCities() * 5 * GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) / 100;
[COLOR="Red"]// getBarbarianCityProb is 8 on deity. so if we are playing with 6 AIs
 (7 player total. And all AIs settle their first city, there would be 13 * 5 * 8 / 100 = 1.95 [/COLOR]
        int iBarbCities = GET_PLAYER(BARBARIAN_PLAYER).getNumCities();
        if (iBarbCities < iTargetBarbCities) {
            iTargetCitiesMultiplier += (300 * (iTargetBarbCities - iBarbCities)) / iTargetBarbCities;
[COLOR="Red"] with one barb city: 300 * (1.95 - 1) / 1.95 =  146[/COLOR]
        }

        if (isOption(GAMEOPTION_RAGING_BARBARIANS)) {
            iTargetCitiesMultiplier *= 3;
            iTargetCitiesMultiplier /= 2;
        }
    }


    for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++) {
        pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

        if (!(pLoopPlot->isWater())) {
            if (!(pLoopPlot->isVisibleToCivTeam())) {
                iTargetCities = pLoopPlot->area()->getNumUnownedTiles(); 
[COLOR="Red"]//If we have a small island of 20 tiles, with one barb city
 spawned in the middle of it, we would have a iTargetCities of 20 - 9 = 11 here.[/COLOR]

                if (pLoopPlot->area()->getNumCities() == pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER)) {
                    iTargetCities *= 3;
 [COLOR="Red"]// Since there was only barb cities on this island, the number would get trippled.. 11 * 3 = 33.[/COLOR]
                }

                int iUnownedTilesThreshold = GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity();  [COLOR="Red"]// This is defined in Civ4HandicapInfo.xml, defined as 130 on noble and as 80 on deity.[/COLOR]

                if (pLoopPlot->area()->getNumTiles() < (iUnownedTilesThreshold / 3)) { 
[COLOR="Red"]// If 33 < (60 / 3) no... 33 is not less than 20. This would not be done in our example. [/COLOR] 
                    iTargetCities *= iTargetCitiesMultiplier;
                    iTargetCities /= 100;
                }

                iTargetCities /= std::max(1, iUnownedTilesThreshold);

                if (pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER) < iTargetCities) {
                    iValue = GET_PLAYER(BARBARIAN_PLAYER).AI_foundValue(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), GC.getDefineINT("MIN_BARBARIAN_CITY_STARTING_DISTANCE")); 
[COLOR="Red"] // The code in AI_foundValue was 400 lines of total mystery. 
It takes most of the factors under consideration though, much like human players. [/COLOR]

                    if (iTargetCitiesMultiplier > 100) {
                        iValue *= pLoopPlot->area()->getNumOwnedTiles();
                    }

                    iValue += (100 + getSorenRandNum(50, "Barb City Found"));
                    iValue /= 100;

                    if (iValue > iBestValue) {
 [COLOR="Red"] // This will just weight all possible city locations against each other, keeping the best one in mind at each iteration. [/COLOR]
                        iBestValue = iValue;
                        pBestPlot = pLoopPlot;
                    }
                }
            }
        }
    }

    if (pBestPlot != NULL) { [COLOR="Red"]
        GET_PLAYER(BARBARIAN_PLAYER).found(pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE());
    }
}
 
Does anyone know the rules and mechanics of when barbarian cities are formed?
I have found the interesting thread
http://forums.civfanatics.com/showthread.php?t=299483,
but I do not think that the aspects of when barbarian cities spawn, is fully adressed.

Apparantly, barb cities can spawn in the fog of war, even if you have a barb-buster 2 tiles away!
Barb cities can only spawn in the fog of war, but they can do this even if there is a unit 2 tiles away.

Is there some certain conditions that need to be meet, for barb cities to start spawning?
Yes:
* A certain turn need to have been reached. (on deity we must have reached turn 15.)
* There need to be a certain ammount of player/AI cities founded, before Barb cities spawn. If there are 1 human and 6 AIs in a game, there need to be 14 or more cities founded before barb cities spawn.
* There need to be enough tiles on the _continent_ that are not under player (or barbarian) culturan influence.
* There is a certain percentage chance that they will spawn (8% per turn on deity)


How do previous roaming barbarians react to cites that are founded?
Not known, perhaps irrelevant

I'm sure there are more questions to be straighten out.
Please contribute with your own questions or facts that you posess, regarding barbarian cities (or barbarians in generall)

I find the % probability factor to be of most interest.
Barb cities only spawn with 8% chance each turn on deity (6% chance on noble).
 
I think you misenterpreted the chance... the randnumber is 0-99 and is compared >= then the probability, if the value of "GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()" is 8 then the chance is actually 92% to spawn city.
 
Code:
if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb())  // BarbarianCItyCreationProb is 8 on deity. 
{
	return;
}

If random(0->99) is higher or equal to 8) then
return; // This means no city is spawned.

Hence, 92% chance we will NOT spawn a city.
 
Code:
if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb())  // BarbarianCItyCreationProb is 8 on deity. 
{
	return;
}

If random(0->99) is higher or equal to 8) then
return; // This means no city is spawned.

Hence, 92% chance we will NOT spawn a city.

omg you're of course right... well one shouldn't watch LoL videos while trying to figure simple "if" out ;-)
 
omg you're of course right... well one shouldn't watch LoL videos while trying to figure simple "if" out ;-)

We humans aren't built to figure out negations it seems.
I thought you were right in your critique at first, only when I took a close look I saw why I was right.

Thank you for the introduction to code-diving btw! There is much to be found here. :)
 
We humans aren't built to figure out negations it seems.
I thought you were right in your critique at first, only when I took a close look I saw why I was right.

Thank you for the introduction to code-diving btw! There is much to be found here. :)

nah this premature returns are common way of doing things, I do this whole time, I just didn't think this much through when replying ;-)
 
Back
Top Bottom