Turn 135 and Only Two Cities?

I play usually RAR Americas gigantic (non-random) for about 90-95%.
With epic game speed, two plot radius.

Regulary by 1650 - 1699 reach industrial victory with about 10-15 large cities where only 3 - 6 inland but close to cover the most possible plots in territory as contiguous area. (Liked with England the whole US East coast/ s. Canada).
Most cities have a goal of very large food production, and near that specialise to 2 - 4 materials, often names represent that like "Cotton city" or "Tabac town".
Also 1 - 2 city which operates mainly by base materials delivered there while they have only industry for finished goods. Base materials come from either natives or ports (even Europe) like whale fat.

The problem with my playstyle:
There are far too many free colonist even in the endgame as they spawn regulary because of the food production, also hard to reach notable rebel sentiment with cities often over 60 population.
By specialists I mostly concentrate on: lumberjack, carpenter, fisherman, farmer, pioneer (for roads/ improvements). And whatever nearby natives can train. But save that there are few specialists mostly comes LbD.
 
"Two Continents" is absolutely optimized to be the "show case map" to test all new features in WTP. :)
Whenever I implement new features I make sure that "Two Continents" gets adjusted so I can properly test the balancing in new games.

It used to be my favourit map before we introduced 2 Plot City Radius.
(It plays best with 1 Plot City Radius.)

Hi Ray,

This brings up a question about city spacing. For two-plot cities, I shoot for CxxxxC, so there is no overlap.
What spacing do you recommend?

Thanks,
Richard
 
I play usually RAR Americas gigantic (non-random) for about 90-95%.
With epic game speed, two plot radius.

But save that there are few specialists mostly comes LbD.

I can usually figure out what abbreviations mean, but nothing is jumping at me here -- what is "LbD"?

Thanks
 
LbD stands for "Learning by Doing". :thumbsup:
(It is actually not a single featue anymore but a framework of features the mod uses.)


I usually do as well. :thumbsup:
(There is normally no reason for overlap if you can avoid.)
Once again, Ray to the rescue!
LbD seems to take forever and there is no indication about when to expect the "reward". It could take 40 turns, or it could be at 60 turns and there is still no sign of relief.

(Did I mention that I love this game?)
Thanks for your quick response and everyone's help,
Richard
 
LbD seems to take forever and there is no indication about when to expect the "reward".
The algorithm I implemented is not deterministic or even linear. (I hate to implement purely deterministic logic in my features.)
It is "threshold based increasing chances over time" - so it is a random based algorithm that adds chances every turn.
(It also has a min value of turns before it can trigger and a max value of turns when it will definitely trigger.)

So it is a "weighted random" algorithm variant that uses turns for "weighting".
(Almost all my algorithms are somehow variants of a "weighted random" - not pure random but also not pure deterministic.)

The only thing important the player needs to know:

The turns the worker has already worked in his Profession.
(And that is displayed on Mouse Over)

Summary:

It is impossible to predict LbB with certainty because it is random based. (Like almost all my algorithms are.)
Everything that could be displayed on the screen would confuse players that do not uderstand how the algorithm works.
 
Last edited:
The algorithm I implemented is not deterministic or even linear. (I hate to implement purely deterministic logic in my features.)
It is "threshold based increasing chances over time" - so it is a random based algorithm that adds chances every turn.
(It also has a min value of turns before it can trigger and a max value of turns when it will definitely trigger.)

So it is a "weighted random" algorithm variant that uses turns for "weighting".
(Almost all my algorithms are somehow variants of a "weighted random" - not pure random but also not pure deterministic.)

The only thing important the player needs to know:

The turns the worker has already worked in his Profession.
(And that is displayed on Mouse Over)

Summary:

It is impossible to predict LbB with certainty because it is random based. (Like almost all my algorithms are.)
Everything that could be displayed on the screen would confuse players that do not uderstand how the algorithm works.

Thanks for the explanation -- very interesting.
 
This is all great info, thanks. I prefer to play a casual game focusing on exploration and ideal spots for cities. It's the exploration and building that interests me the most. A lot of times I don't even play with Independence as a victory condition. Mem de Sa is my go-to thanks to the scout he comes with. I do a fair amount of sailing around maximizing the number of native settlements and goodie huts I can hit with the scout, which doubles for finding the best place to land and I use natives and treasure I get from the goodie huts to scout inland so I can see what the land looks like. I usually get a very late start on my first settlement, but I'm not really playing to rush as I usually don't play anything less than huge or gigantic size anyway, with plenty of room to settle when I'm ready.
 
can you please guide to the exact place in code, where LbD is calculated?
In the source code you can simply search for "doLbD()". :thumbsup:
I will not copy & paste it here, because LbD is filling pages of code in its completeness.

From there you can follow the rest of the method calls to see how it gets all the variables and does the calculation.
And it is not like you can simple see a mathematic formula there, like in math class. (The formula needed to be translated in C++ logic.)

These are algorithms inside of "logic / feature code" that are really not that easy to read if you are not a programmer.

I'd like to know exact formulas :)
Something like an "exact formula" simply does not exist if there are "randoms" used. ;)
That is the whole point of using "randoms". And "weighted randoms" are even more complicated. :dunno:

---

But as I said, the source code is open to read for everybody. :thumbsup:
"doLbD()"
 
Last edited:
This (it is a link) is generally how LbD algorithm works like.
(It explains how the "random base" looks like.)

It is the closest thing you will ever get to a "mathematic formula" ...
(But again, even this heavily simplifies because it does not yet consider e.g. Happiness, Expert Teachers, ...)

-----

Summary:

Guys, please understand that for the features I code there are no "exact formulas" anymore.
I have purposely eliminated all "dertermination" so even I can not predict myself with certainty when specific things happen.
(I only know what will make times for LbD shorter and what will make them longer.)

Otherwise ingame I can only give vagues guesses because there are too many facors coming together ...
Once you have enough variables in a "weighted random algorithm" (like UnitType, Profession to Learn, City Size, Turns already worked, Turn Thresholds, Happiness, Expert as Teacher, GameSpeed Modifier, HandiCap Modifier, ...) any real calculation becomes almost impossible ...

The only things that are possbile to know:
(Those are the things a player should also know.)

  • Main factor (e.g. turns in LbD)
  • General Curve Behaviour (e.g. increasing chances over time in LbD)
  • Good Influences (e.g. in LbD stuff that is shortening time)
  • Bad Influences (e.g. in LbD stuff that is lengthening time)
 
Last edited:
To explain what I am talking about:

This is a part of the collection of the variables the algorithm uses for later calculating inside the feature logic.
The logic has not even started here ... again, this is just variable collection for the algorithm and not the algorithm in the feature logic itself yet ...

LbD itself fills pages of code like that.
(After all variables are colletcted the rest is mostly actual feature logic though.)

So this is just the "start method" for LbD.
(From here it calls the 4 separate algorithms in feature logic that also check variables..)

Spoiler :

void CvCity::doLbD()
{
//getting global values for formula
int base_chance_expert = GC.getLBD_BASE_CHANCE_EXPERT();
int chance_increase_expert = GC.getLBD_CHANCE_INCREASE_EXPERT();
int pre_rounds_expert = GC.getLBD_PRE_ROUNDS_EXPERT();

int chance_increase_expert_from_teacher = GC.getLBD_CHANCE_INCREASE_EXPERT_FROM_TEACHER(); // WTP, ray, teacher addon for LbD
int pre_rounds_expert_decrease_from_teacher = GC.getLBD_PRE_ROUNDS_EXPERT_DECREASE_FROM_TEACHER(); // WTP, ray, teacher addon for LbD

int base_chance_free = GC.getLBD_BASE_CHANCE_FREE();
int chance_increase_free = GC.getLBD_CHANCE_INCREASE_FREE();
int pre_rounds_free = GC.getLBD_PRE_ROUNDS_FREE();
int mod_free_criminal = GC.getLBD_CHANCE_MOD_FREE_CRIMINAL();
int mod_free_servant = GC.getLBD_CHANCE_MOD_FREE_SERVANT();

int base_chance_escape = GC.getLBD_CHANCE_ESCAPE();
int mod_escape_criminal = GC.getLBD_CHANCE_MOD_ESCAPE_CRIMINAL();
int mod_escape_servant = GC.getLBD_CHANCE_MOD_ESCAPE_SERVANT();

// WTP, ray, LbD Slaves Revolt and Free - START
int base_chance_revolt = GC.getLBD_CHANCE_REVOLT();
int mod_revolt_slave = GC.getLBD_CHANCE_MOD_REVOLT_SLAVE();
int mod_revolt_criminal = GC.getLBD_CHANCE_MOD_REVOLT_CRIMINAL();
// WTP, ray, LbD Slaves Revolt and Free - END

//getting GameSpeedModifiert in percent
int train_percent = GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent();

//moddifying values with GameSpeed
chance_increase_expert = chance_increase_expert / train_percent / 100;
pre_rounds_expert = pre_rounds_expert * train_percent / 100;
chance_increase_expert_from_teacher = chance_increase_expert_from_teacher * train_percent / 100;
pre_rounds_expert_decrease_from_teacher = pre_rounds_expert_decrease_from_teacher * train_percent / 100;

chance_increase_free = chance_increase_free / train_percent / 100;
pre_rounds_free = pre_rounds_free * train_percent / 100;

// WTP, ray, Happiness - START
// we now calculate and apply Happiness vs. Unhappiness on it
int iCityHappiness = getCityHappiness();
int iCityUnHappiness = getCityUnHappiness();

// this is the percentage rate we apply for positive features - it may become negative but that is intended
int iPosHappinessBalance = iCityHappiness - iCityUnHappiness;

// become expert Happiness vs Unhappiness modification
base_chance_expert = base_chance_expert + (iPosHappinessBalance / 5); // chances are increased for positive values iPosHappinessBalance, decreased for negative values iPosHappinessBalance
chance_increase_expert = chance_increase_expert + (iPosHappinessBalance / 5); // chances are increased for positive values iPosHappinessBalance, decreased for negative values iPosHappinessBalance
pre_rounds_expert = pre_rounds_expert * (100 - iPosHappinessBalance) / 100; // pre rounds experts is shortened

// become free Happiness vs Unhappiness modification
base_chance_free = base_chance_free + (iPosHappinessBalance / 5); // chances are increased for positive values iPosHappinessBalance, decreased for negative values iPosHappinessBalance
chance_increase_free = chance_increase_free + (iPosHappinessBalance / 5); // chances are increased for positive values iPosHappinessBalance, decreased for negative values iPosHappinessBalance
pre_rounds_free = pre_rounds_free * (100 - iPosHappinessBalance) / 100; // pre rounds free is shortened

// this is the percentage rate we apply for negative features - it may become negative but that is intended
int iNegHappinessBalance = iCityUnHappiness - iCityHappiness;

// escape and revolt Unhappiness vs Happiness modification
base_chance_escape = base_chance_escape + (iNegHappinessBalance / 5); // chances are increased for positive values iNegHappinessBalance, decreased for negative values iNegHappinessBalance
base_chance_revolt = base_chance_revolt + (iNegHappinessBalance / 5); // chances are increased for positive values iNegHappinessBalance, decreased for negative values iNegHappinessBalance

// WTP, ray, Happiness - END

// loop through units
for (uint i = 0; i < m_aPopulationUnits.size(); ++i)
{
CvUnit* pLoopUnit = m_aPopulationUnits;

bool lbd_expert_successful = false;
bool lbd_free_successful = false;
bool lbd_escape_successful = false;
bool lbd_revolt_successful = false; // WTP, ray, LbD Slaves Revolt and Free - START


// only do something for this unit if the profession does use LbD
if (pLoopUnit->getProfession()!= NO_PROFESSION && GC.getProfessionInfo(pLoopUnit->getProfession()).LbD_isUsed())
{

//get LearnLevel of profession
int learn_level = GC.getProfessionInfo(pLoopUnit->getProfession()).LbD_getLearnLevel();
// just for safety, catch possible XML mistakes which might break calculation
if (learn_level == 0)
{
learn_level = 1;
}

// try to become expert if poosible
if(pLoopUnit->getUnitInfo().LbD_canBecomeExpert())
{
// WTP, ray, teacher addon for LbD
// adjusted method call with new teacher attributes
lbd_expert_successful = LbD_try_become_expert(pLoopUnit, base_chance_expert, chance_increase_expert, pre_rounds_expert, learn_level, chance_increase_expert_from_teacher, pre_rounds_expert_decrease_from_teacher);
}

// try to become free if poosible
if(pLoopUnit->getUnitInfo().LbD_canGetFree() && !lbd_expert_successful)
{
lbd_free_successful = LbD_try_get_free(pLoopUnit, base_chance_free, chance_increase_free, pre_rounds_free, mod_free_criminal, mod_free_servant, learn_level);
}

// try to escape if free unsuccesful and escape possible
if(pLoopUnit->getUnitInfo().LbD_canEscape() && !lbd_free_successful && !lbd_expert_successful)
{
lbd_escape_successful = LbD_try_escape(pLoopUnit, base_chance_escape, mod_escape_criminal, mod_escape_servant);
}

// WTP, ray, LbD Slaves Revolt and Free - START
// try to revolt if escape revolt possible and free unsuccessful and escape unsuccessufl
if(pLoopUnit->getUnitInfo().LbD_canRevolt() && !lbd_escape_successful && !lbd_free_successful && !lbd_expert_successful)
{
lbd_revolt_successful = LbD_try_revolt(pLoopUnit, base_chance_revolt, mod_revolt_criminal, mod_revolt_slave);
}
// WTP, ray, LbD Slaves Revolt and Free - END

}

}

}
// TAC - LbD - Ray - END



This here is e.g the call for the "become Expert" algorithm.

Do you see how many variables it transmits in the call?
And those are already refined variables that have already been computed using other variables.
And in the algorithm it checks further stuff as well.

Spoiler :

LbD_try_become_expert(pLoopUnit, base_chance_expert, chance_increase_expert, pre_rounds_expert, learn_level, chance_increase_expert_from_teacher, pre_rounds_expert_decrease_from_teacher);


-----

Summary:

It is simply not possible to calculate the outcome anymore ingame with anything even close to certainty. :dunno:
(All you can do is vague guessing of your chances or to put it in other words "gut feeling".)
 
Last edited:
Ok, then you should have no big issue to understand it. :thumbsup:


Great because most players expect an "exact value" that is deterministically calculated. :thumbsup:
obviously not, as it takes different amount of turns for each colonist :) Now I understand the threashold idea and also happiness impact
 
Actually if you can read my confusing code you should then consider to become a Civ4Col modder yourself. :mischief:
thought about it a few times, but
1. reading c++ and writing c++ are different things
2. don't think I'm self-motivated enough to do such a great and long-termed work
 
No problem. :thumbsup:

Nobody can be forced to become a modder. :)
Either you are motivated enough and it is fun for you or not.

People often just do not know how much fun modding can be. :dunno:
And often they accidently think it is "witchcraft" although it is actually quite simple once you try.
 
Back
Top Bottom