Planetary Population Growth

PsiCorps

FF: Babylon 5 mod team
Joined
Dec 30, 2007
Messages
1,425
Location
Britain
I've noticed something that i feel needs to be addressed.
When your home system has an influence radius of 0 it is possible to have either 1, 2 or 3 planets that you can build on. These can range from a Population 1 planet to a Population 3 planet initialy. As a test i gave myself 5000 credits on turn 1 and every other turn i purchased a building on a planet until such time as i had no more available buildings to construct. The planets were Pop 1, 2 and 3 so i had a maximum population of 6. With no facility to support an increased population on any of these planets it should not be possible for the Planetary population to keep growing but it does, continually. I would like to see a system that allows some growth over the planetary limit but only by 1 or 2 population points. As usual the excess population can cause unrest/unhappiness for the player but that's what happiness buildings and luxury resources are for. Once your borders expand through influence the excess population can be shipped off to the new planets just absorbed into your little empire thus removing the unhappiness problem until such time as your population outgrows the planets in your system again.

Is there anyway to limit this growth as i've suggested?
 
Ah, the excess population problem. It isn't much of a problem for a human player, who can control it much better. (Population growing too fast? Don't build that extra nutrition facility and move a population point over to a planet that produces no food.) It is an issue for the AI. The latest FF+ update (this was in 1.65) includes some adjustments to the Python AI override that should reduce this effect some by not counting angry population past the system's current population limit when determining how badly it wants to build a sports arena, and some other similar adjustments for food and heath. The regular production selection code in the DLL may still choose to build them, so this is not entirely effective.

There is a Python event onCityGrowth that is called when the population increases. I suppose you could manually reduce the population in there if it was higher than the desired limit. Currently that event causes the system's population assignment function to run to assign the new population point to a planet (if it can). So checking in there to see if the new population point pushes it over the limit and then removing the new population if it does or doing the existing call if it doesn't would probably work. Before the first border pop this isn't much of an issue, particularly for the home system since the Capitol produces some influence, unless there are no planets in the second zone or the population is growing so fast that by the time the borders pop there will be more population than can go on the planets in that zone.

On the manual population control front, a human player can click on the "no growth" button on the city screen and it works - the population will not increase no matter how much excess food you have (the stored food grows to 1 less than the amount needed then the excess is thrown away after that so the population doesn't increase, just like in regular BtS). That is done in the DLL somewhere. This does not appear to work for the AI - the population increases anyway even when it has the no growth option set. It does apparently set the value that does this, which you can get via PyCity.AI_avoidGrowth() in Python. Because of this, and a much better ability to manage things in general, a human player can avoid excess population (which does nothing but increase the maintenance a little) but the AI's cities tend to grow to excessively large populations.

If the DLL were adjusted so that it worked the same for the AI as for the human player in limiting population growth then this would be less of an issue.
 
You can fix that in Python, in CvGameUtils.doGrowth(). Just add a check for PyCity.AI_avoidGrowth() and return true if it's been set.

I'm not totally sure why the AI behaves like that in the DLL. I can see the mechanism for checking if Avoid Growth is on, and how it's set- but not why it would be different for the AI. It might be simpler to just override it in Python (if that function returns True, doGrowth() exits before checking if Avoid Growth is on).
 
I'm not sure why it doesn't seem to work either.

I'm not positive that in FF+ the AI still sets the AI_avoidGrowth to True, but I know it did in regular FF. It looks like CvCityAI.cpp has not been modified in FF+ so I assume it still does set it. Based on my perusal of the code it looks like the way it is set up now it will only set it if the unit being produced uses food in its production (colony ship and construction ship, since there is no civic that activates this for military units) or there are unhappy citizens, and in the unhappy citizen case it should always set it unless the city is set to emphasize food yield or great people (I didn't look to see if FF+ is likely to ever have these set). For the check for the AI_isEmphasizeAvoidGrowth() value, it looks to me like won't be set to True in FF+, or even in regular BtS, but I'm not sure. That's my interpretation of what CvCityAI::AI_avoidGrowth() will do in FF+.

If... [Argh! I just noticed something.... you can probably skip the next two paragraphs that I already wrote.]

Yet, the population in AI controlled systems often grows out of control, into the 30s and 40s when they can not possibly have enough happiness to prevent some from being unhappy (I've seen systems where there must be at least a dozen unhappy citizens). The new 1.65 AI tweaks should improve the situation, but not fix it.

The check for it in updateHumanCityTurn was commented out to improve the AI's behavior, particularly to insure all of the system's population is assigned to planets at the start of the game but also for when more planets become available due to border pops or when the capacity of a planet changes due to buildings being built or the green economy civic adopted. When I was determining that this would be helpful I was printing out that setting's value so I know it was setting it to True sometimes. (You also added a check for it in AI.py, in doCityAIUpdate, to change the priority for assigning population to planets if it is True.)

...... Post Argh! section ......

I just noticed that in CvCity::doGrowth() the function that it checks is AI_isEmphasizeAvoidGrowth(), not AI_avoidGrowth().

As I mentioned in the first paragraph, it seems to me that this is not likely to get set. The function AI_isEmphasizeAvoidGrowth() returns True if the value of m_iEmphasizeAvoidGrowthCount is > 0. The value m_iEmphasizeAvoidGrowthCount is only changed in CvCityAI::AI_setEmphasize() and that is only called in CvCityAI::AI_doEmphasize() and CvCity::doTask() (which is rather mysterious - I think this is what is called if the human clicks on the emphasis buttons, as well as the various other city related buttons in the interface, which explains why this works for the human). CvCityAI::AI_doEmphasize() was gutted at some point in Civ4 development, the comments say as much, so there are some checks that do nothing. To me it is looking like this can't actually cause m_iEmphasizeAvoidGrowthCount to be incremented. It doesn't have any check for happiness levels and the conditions under which it can call AI_setEmphasize() with the second argument set to True are quite limited.

So since CvCity::doGrowth() uses AI_isEmphasizeAvoidGrowth() it doesn't do anything for the AI if the AI is not actually incrementing m_iEmphasizeAvoidGrowthCount via CvCityAI::AI_setEmphasize().

The value you get in Python via PyCity.AI_avoidGrowth() is the return from the AI_avoidGrowth() fucntion, not AI_isEmphasizeAvoidGrowth(). There is a PyCity.AI_isEmphasize (INT iEmphasizeType) which could presumably get the avoid growth emphasis setting, although this actually accesses a completely different variable (the boolean array m_pbEmphasize) and doesn't check m_iEmphasizeAvoidGrowthCount (maintaining multiple values for these things seems like a bad plan).

Net result:

It seems to me that line 11285 in CvCity.cpp should use AI_avoidGrowth() if the player is an AI. That would have it actually avoid growth when there are unhappy citizens. Perhaps this:
Code:
if ((isHuman() && AI_isEmphasizeAvoidGrowth()) || (!isHuman() && AI_avoidGrowth()))
since AI_avoidGrowth() already checks AI_isEmphasizeAvoidGrowth(), plus the other stuff like happiness.

Or something like that.
 
Thanks God-Emperor. I've crossposted your findings to the Unofficial Patches forum as well (since this should affect BTS, not just FF).

I realize it would be a lot more convenient if you didn't have to wait for me to compile and test and release a new DLL every time you find a bug in it... do you want to set up a FF+ DLL project of your own? Or maybe we should use an online repository/RCS or something?

What do you think?
 
Yes, it should affect BtS but it doesn't really seem to be a serious problem there. Probably because the couple of things that can cause AI_isEmphasizeAvoidGrowth() to end up being true can actually happen (it is possible that they might happen in some rare instances in FF+, my examination was not completely thorough so I'm not certain).

So far, I've been resisting the urges to fiddle with the DLL directly myself...

What has saved me so far is that I don't have Visual C++ installed, but I did install Visual Basic at one time and made the mistake of letting it install on the C drive (or it didn't give an option to install it elsewhere, perhaps) and I expect that it would want to install C++ to the same location since the Visual Studio IDE part is shared, but I don't really have enough room on C: for it. So I'd have to uninstall VB and reinstall everything elsewhere (assuming it allows installs off of C:, which I would hope is the case). A couple of times, the amount of time and, to a lesser degree, effort all this could take before even trying to build the DLL is all that has saved me from myself...
 
Top Bottom