Report Questionable AI Behavior

It's likely that the civic yields are not properly being valued (overvalued, at first guess), causing this behavior. Thanks for the report Iceciro; I'll try to quash this in beta4.
 
In further marching through their empire, the Ottomans at some point really went fort-crazy - probably part of the secret to why they didn't seem to have production to match the empire size they had. One of their cities, Konya, is a particular offender:

264sxgj.jpg


Just wanted you to see it's not a one-of problem.
 
new game started with AI in my team. the screen shot is one turn after the advanced start (which the AI preformed very well this time. well done Afforess.) as you can see the AI starts with building a settler in a size 1 village which will take 43 turns on marathon... i'd understand building a settler in the other city but not this.

EDIT: lol, and after the AI finished the settler it stands in the city doing nothing. now that is a incredible waste of yields. you should check when AI doesn't find use for settlers and apply the same check to the city manager - i case it already started building a settler and if applicable it should change production to something else but let the settler in the list
...its nearly 100 turns after the settler was finished now.

EDIT2: my allie's worker just changed a profitable farm (4:food: 1:commerce: into a trading post with 1:food: 3:commerce: causing the neighboring city to starve; 2nd screen shot). that is questionable because the city doesn't have many food tiles currently and it was worked. i guess there is no communication between city AI and worker AI... that is bad and sad. my tip is that workers should ask cities which tiles they are going to improve which improvements they want/need and then do their job. note that a small city will require food improvement much more urgent then anything else, while a well developed city with a good size and a solid food income will be more interested in expanding its production and a gold/science oriented city might request trading posts.
 

Attachments

  • Civ4ScreenShot0000.JPG
    Civ4ScreenShot0000.JPG
    406.7 KB · Views: 129
  • Civ4ScreenShot0001.JPG
    Civ4ScreenShot0001.JPG
    433.6 KB · Views: 102
the Ottomans at some point really went fort-crazy
Did you find the cause for the fort-craze, Afforess? In r181 you removed all traces of Forts Connect Improvements from CityAI so I guess it's not happening anymore but it really shouldn't have in the first place because of the obvious differences in yield.

edit:
My only problem right now (and its probably a rather small problem) is that the AI still builds a settler right off the bat which can be quite problematic sometimes for them, especially with raging barbarians enabled but I digress.
I have already tackled this for the next beta.
And how exactly?
 
Did you find the cause for the fort-craze, Afforess? In r181 you removed all traces of Forts Connect Improvements from CityAI so I guess it's not happening anymore but it really shouldn't have in the first place because of the obvious differences in yield.

There is a civic in RoM that gives +1 :commerce: with Forts, which could have further caused issues as well...

And how exactly?

Here:
Code:
bool CvCityAI::AI_chooseUnit(UnitAITypes eUnitAI, int iOdds)
{
	UnitTypes eBestUnit;
/************************************************************************************************/
/* Afforess	                  Start		 06/26/10                                               */
/*                                                                                              */
/* Avoid Making Settlers Very Early Game                                                        */
/************************************************************************************************/
	if (eUnitAI == UNITAI_SETTLE)
	{
		if (isCapital() && getPopulation() == 1)
		{
			int iMinTurnsForSettler = getFoodTurnsLeft();
			if (GC.getGameINLINE().isOption(GAMEOPTION_RAGING_BARBARIANS))
			{
				iMinTurnsForSettler *= 3;
				iMinTurnsForSettler /= 2;
			}
			if (GC.getGameINLINE().isOption(GAMEOPTION_BARBARIAN_WORLD))
			{
				iMinTurnsForSettler *= 3;
				iMinTurnsForSettler /= 2;
			}
			if (GC.getGameINLINE().isOption(GAMEOPTION_NO_BARBARIANS))
			{
				iMinTurnsForSettler = -1;
			}
			if (GC.getGameINLINE().getElapsedGameTurns() < iMinTurnsForSettler)
			{
				return false;
			}
		}
	}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/

	if (eUnitAI != NO_UNITAI)
	{
		eBestUnit = AI_bestUnitAI(eUnitAI);
	}
	else
	{
		eBestUnit = AI_bestUnit(false, NO_ADVISOR, &eUnitAI);
	}

	if (eBestUnit != NO_UNIT)
	{
		if( iOdds < 0 ||
			getUnitProduction(eBestUnit) > 0 ||
			GC.getGameINLINE().getSorenRandNum(100, "City AI choose unit") < iOdds )
		{
			pushOrder(ORDER_TRAIN, eBestUnit, eUnitAI, false, false, false);
			return true;
		}
	}

	return false;
}

I don't think it would be incredibly beneficial in base BTS, as I write the AI strictly for RoM gameplay, not standard gameplay.
 
There is a civic in RoM that gives +1 :commerce: with Forts, which could have further caused issues as well...
Even with +1 :commerce: the other improvement should have been far superior, so yield comparison should have resulted in a negative value. Combined with zero bonus from connecting an already connected resource, I am still confused about how this could happen. Unless +1 :commerce: from civic is valued a dozen times higher than simply +1 :commerce:.


I don't think it would be incredibly beneficial in base BTS, as I write the AI strictly for RoM gameplay, not standard gameplay.
You might be writing only for your own modmod but that doesn't mean nothing could be useful for Better AI.
The Forts Connect Resources part is actually something I found in your mod, I adapted it a bit (to prevent exactly the described situation from happening, which is forts being built in the city radius when that is clearly not the best improvement to build there), phungus merged it into RevDCM, which is part of RoM 2.92, which is what your modmod is based on, and thus the circle is closed ;)

Settlers being built on the first turn should have been fixed for Better BTS AI 1.0 though, I was sure jdog made it so the AI would build at least an escort first, even if the warrior unit is the only choice.. unless it already has escort units from difficulty level.

As for your code, I honestly don't understand it. getElapsedGameTurns() >= getFoodTurnsLeft() as settler building condition makes very little sense to me but I guess you did warn me :p
I would have used something like (getFoodTurnsLeft()*2 > getProductionTurnsLeft(eBestUnit, 0)) - Only build the settler if building it takes less than twice the time of waiting for city growth to 2 pop.
.. or getProductionTurnsLeft(eBestUnit, 0)/3 > getElapsedGameTurns()
 
Even with +1 :commerce: the other improvement should have been far superior, so yield comparison should have resulted in a negative value. Combined with zero bonus from connecting an already connected resource, I am still confused about how this could happen. Unless +1 :commerce: from civic is valued a dozen times higher than simply +1 :commerce:.

I don't know. The Worker AI is pretty complex, I try to avoid messing with it too much.

Settlers being built on the first turn should have been fixed for Better BTS AI 1.0 though, I was sure jdog made it so the AI would build at least an escort first, even if the warrior unit is the only choice.. unless it already has escort units from difficulty level.

It's not the first turn that is the issue. It's just not beneficial for the AI to build a settler right out of the gate, since there are a couple more important priorities, especially with lots of Barbs.

As for your code, I honestly don't understand it. getElapsedGameTurns() >= getFoodTurnsLeft() as settler building condition makes very little sense to me but I guess you did warn me :p
I would have used something like (getFoodTurnsLeft()*2 > getProductionTurnsLeft(eBestUnit, 0)) - Only build the settler if building it takes less than twice the time of waiting for city growth to 2 pop.
.. or getProductionTurnsLeft(eBestUnit, 0)/3 > getElapsedGameTurns()

Let's say the capital has 2 turns left to grow, and the settler takes 10 turns. 4 is not less than 10, so the city starts producing a settler.

Unless I misunderstand you, and you meant your check to see that 4 is not less than ten, so don't produce a settler. In which case, that makes perfect sense. :lol:

Thanks for the suggestion, I'm going to opt to use this instead:

Code:
bool CvCityAI::AI_chooseUnit(UnitAITypes eUnitAI, int iOdds)
{
	UnitTypes eBestUnit;

	if (eUnitAI != NO_UNITAI)
	{
		eBestUnit = AI_bestUnitAI(eUnitAI);
	}
	else
	{
		eBestUnit = AI_bestUnit(false, NO_ADVISOR, &eUnitAI);
	}

	if (eBestUnit != NO_UNIT)
	{
/************************************************************************************************/
/* Afforess	                  Start		 06/27/10                                               */
/*                                                                                              */
/* Avoid Making Settlers Very Early Game                                                        */
/************************************************************************************************/
		if (eUnitAI == UNITAI_SETTLE)
		{
			if (isCapital() && getPopulation() == 1)
			{
				int iMinTurnsForSettler = getFoodTurnsLeft();
				iMinTurnsForSettler *= 3;
				iMinTurnsForSettler /= 2;
				if (GC.getGameINLINE().isOption(GAMEOPTION_RAGING_BARBARIANS))
				{
					iMinTurnsForSettler *= 3;
					iMinTurnsForSettler /= 2;
				}
				if (GC.getGameINLINE().isOption(GAMEOPTION_BARBARIAN_WORLD))
				{
					iMinTurnsForSettler *= 3;
					iMinTurnsForSettler /= 2;
				}
				if (GC.getGameINLINE().isOption(GAMEOPTION_NO_BARBARIANS))
				{
					iMinTurnsForSettler = -1;
				}
				if (getProductionTurnsLeft(eBestUnit, 0) > iMinTurnsForSettler)
				{
					return false;
				}
			}
		}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
		if( iOdds < 0 ||
			getUnitProduction(eBestUnit) > 0 ||
			GC.getGameINLINE().getSorenRandNum(100, "City AI choose unit") < iOdds )
		{
			pushOrder(ORDER_TRAIN, eBestUnit, eUnitAI, false, false, false);
			return true;
		}
	}

	return false;
}
 
Yes, sorry for the confusion, it was meant as condition for building the settler, not against. "4 is not bigger than 10 so don't build a settler." I obviously didn't make that as clear as I thought I did.
Code looks good now, should hinder the AI from building settlers in pop1 capitals almost all the time. You might need an exception for cases like capital in foodless environment (ice/dessert or plains/tundra hills), even if that probably never happens:

(if all city radius tiles are owned OR border popping takes longer than settler building) AND foodDifference() <= 0 then let the city build the settler, at least eventually (like when productionturns/3 > gameturns)

.

Yes the worker AI isn't trivial but what improvement is built for a city is all in CvCityAI::AI_bestPlotBuild(), not even 900 lines of code.
Oh well, I guess I'll have to watch out if my AI opponents are building stupid forts too.. I hope not.
 
Code looks good now, should hinder the AI from building settlers in pop1 capitals almost all the time. You might need an exception for cases like capital in foodless environment (ice/dessert or plains/tundra hills), even if that probably never happens:
(if all city radius tiles are owned OR border popping takes longer than settler building) AND foodDifference() <= 0 then let the city build the settler, at least eventually (like when productionturns/3 > gameturns)

True. I'll make sure to add that in.
Yes the worker AI isn't trivial but what improvement is built for a city is all in CvCityAI::AI_bestPlotBuild(), not even 900 lines of code.
Oh well, I guess I'll have to watch out if my AI opponents are building stupid forts too.. I hope not.
It might be easier to play a team game with an AI on your team, then you can watch an AI as the entire game progresses.
 
I didn't play-test but I think I still figured it out. You were right, it must be the +1:commerce:, I have no other explanation for it. A fort without any output at all wouldn't get any value from bonus yet not penality either, so even that small output would be enough if the fort was the only improvement that didn't get that -1000 penality. I think I got that now: forts will not be considered inside city radius until the bonus resource enabling tech is researched, and at that point the actual resource-connecting improvement will be available and outperform the fort.
And because I am crazy, and too lazy to start coding for CivicAI yet, I also enabled the AI to handle improvement upgrade paths where the first (buildable) improvement and the final improvement don't have the same resource-connecting behavior (Imagine Town acting as city and thus connecting resources, but not Cottage/Hamlet/Village)

edit: stupid thing crashes on me and I still can't debug.

More questions about your AI code:
(note that I simply took some notes while looking through your code, so it's not very verbose but I hope you still know what I'm talking about)
CityAI:
* isDevelopingCity(): does it do much good? ie is that a candidate for Better AI?
* check if building is prereq for units: do units add value even when player doesn't have the required techs? do they, if we can already build them because of civics or so? is that the same code FFH is using? Also value should probably scale to (unitCombatValue / our current best unitCombatValue), not just unitCombat. And a bool BuildingInfo::isPrereqForAnyUnit() would probably be a good idea too.
PlayerAI:
* foundValue: shouldn't bonus from getRiverBuildings() only go to CITY_HOME_PLOT, instead of every single LoopPlot?
Specifying isDevelopingCity() question: what buildings get chosen there, that wouldn't get chosen without it? I was playing with the thought of stealing it but I wasn't exactly sure what you were trying to do with it.

AI_foundValue: I believe you are adding a lot of value to secondary river plots when you actually just wanted to give that bonus if the city itself would be next to a river.
Spoiler :
The part I understand: city next to river is nice (changed value from Better AI's 60 to 300):
Code:
	if (pPlot->isRiver())
	{
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      02/03/09                                jdog5000      */
/*                                                                                              */
/* Settler AI                                                                                   */
/************************************************************************************************/[/COLOR]
		iValue += [B]300[/B];
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/[/COLOR]
	}
Right afterwards a part I do not comprehend: Why would you encourage settling on forests?
Code:
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 04/01/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
	if (pPlot->isFreshWater() [B]&& pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).getHealthPercent() >= 0[/B])
	{
		iValue += 40;
		iValue += (GC.getDefineINT("FRESH_WATER_HEALTH_CHANGE") * 30);
	}
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]

And the part where I you probably went too far (BTS "+10" became AND "+100*GC.getGameINLINE().getRiverBuildings()"):
Code:
			if (pLoopPlot->isRiver())
			{
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 06/08/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
				iTempValue += [B]100 * GC.getGameINLINE().getRiverBuildings()[/B];
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]
			}
 
what isDevelopingCity() function intended i can give you an answer. it originates on a discussion i started long ago about the AI. i'm not sure how much of my concepts Afforess implemented and by what changes he made to it. but you can follow the discussion to get some idea.
 
More questions about your AI code:
(note that I simply took some notes while looking through your code, so it's not very verbose but I hope you still know what I'm talking about)
Specifying isDevelopingCity() question: what buildings get chosen there, that wouldn't get chosen without it? I was playing with the thought of stealing it but I wasn't exactly sure what you were trying to do with it.

Basically, smaller cities, with limited production get flagged as Developing cities. This means that their normal behavior is interrupted, right after the checks to ensure that there are enough defenders in the city. I try to encourage the cities to build fast, production, gold, or food buildings (or culture, if they have no culture/turn). I'm not sure how helpful it would be for BTS, since buildings have a much greater significance in RoM than BTS. In BTS, you can get away with only 3-4 buildings a city late game, where in RoM, that would destroy your economy.
AI_foundValue: I believe you are adding a lot of value to secondary river plots when you actually just wanted to give that bonus if the city itself would be next to a river.
Spoiler :
The part I understand: city next to river is nice (changed value from Better AI's 60 to 300):
Code:
	if (pPlot->isRiver())
	{
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      02/03/09                                jdog5000      */
/*                                                                                              */
/* Settler AI                                                                                   */
/************************************************************************************************/[/COLOR]
		iValue += [B]300[/B];
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/[/COLOR]
	}
Right afterwards a part I do not comprehend: Why would you encourage settling on forests?
Code:
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 04/01/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
	if (pPlot->isFreshWater() [B]&& pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).getHealthPercent() >= 0[/B])
	{
		iValue += 40;
		iValue += (GC.getDefineINT("FRESH_WATER_HEALTH_CHANGE") * 30);
	}
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]

And the part where I you probably went too far (BTS "+10" became AND "+100*GC.getGameINLINE().getRiverBuildings()"):
Code:
			if (pLoopPlot->isRiver())
			{
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 06/08/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
				iTempValue += [B]100 * GC.getGameINLINE().getRiverBuildings()[/B];
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]
			}

It's not so much an encouragement for forests as a way to ensure the AI don't overvalue jungles. In RoM, jungles provide fresh water too, so the BTS code made them jungle-happy with city founding.

As for the river code, there are about 10 buildings in RoM that require rivers, and they all very powerful and make settling on rivers very significant, much more so than in BTS. I don't think it's overvalued, if anything, it may still be too small.
 
It's not so much an encouragement for forests as a way to ensure the AI don't overvalue jungles. In RoM, jungles provide fresh water too, so the BTS code made them jungle-happy with city founding.
I still don't get what that code is supposed to do though. Is it supposed to make settling on top of jungles less attractive? Maybe what you meant was
Code:
[COLOR="Green"]//no extra value if we are settling on top of a feature with negative health%[/COLOR]
if (pPlot->isFreshWater() && [B](pPlot->getFeatureType() == NO_FEATURE || ([/B]pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).getHealthPercent() >= 0[B]))[/B])
If that's not it I will just have to accept that commenting on a mod I never played is not such a good idea ;)

As for the river code, there are about 10 buildings in RoM that require rivers, and they all very powerful and make settling on rivers very significant, much more so than in BTS. I don't think it's overvalued, if anything, it may still be too small.
In BTS, you can only build the river buildings if your city itself is next to a river. If that is true for RoM too, then the code should be:
Code:
			if (pLoopPlot->isRiver())
			{
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 06/08/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
				[B]if (pPlot->isRiver())[/B]
				[B]{[/B]
					iTempValue += 100 * GC.getGameINLINE().getRiverBuildings();
				[B]}
				else
				{
					iTempValue += 10
				}[/B]
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]
			}
 
I still don't get what that code is supposed to do though. Is it supposed to make settling on top of jungles less attractive? Maybe what you meant was
Code:
[COLOR="Green"]//no extra value if we are settling on top of a feature with negative health%[/COLOR]
if (pPlot->isFreshWater() && [B](pPlot->getFeatureType() == NO_FEATURE || ([/B]pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).getHealthPercent() >= 0[B]))[/B])
If that's not it I will just have to accept that commenting on a mod I never played is not such a good idea ;)

Wow, it seems that I neglected the fact that inland lakes give fresh water too, I was thinking fresh water was only from features. Nice find.
In BTS, you can only build the river buildings if your city itself is next to a river. If that is true for RoM too, then the code should be:
Code:
			if (pLoopPlot->isRiver())
			{
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                  Start		 06/08/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/[/COLOR]
				[B]if (pPlot->isRiver())[/B]
				[B]{[/B]
					iTempValue += 100 * GC.getGameINLINE().getRiverBuildings();
				[B]}
				else
				{
					iTempValue += 10
				}[/B]
[COLOR="Green"]/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/[/COLOR]
			}

I guess I didn't understand (or didn't try to understand) the function. So pLoopPlot is plot in the BFC, and pPlot is the city site? Well, than I guess I should move the code somewhere else than, eh?

I'm thinking of replacing it with this then:

Code:
			if (pLoopPlot->isRiver())
			{
/************************************************************************************************/
/* Afforess	                  Start		 07/21/10                                               */
/*                                                                                              */
/* Favor extra river tiles for eventual building yields, if we are on a river                   */
/************************************************************************************************/
				if (pPlot->isRiver())
				{
					iTempValue += 10 * GC.getGameINLINE().getRiverBuildings();
				}
				else
				{
					iTempValue += 10;
				}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
			}
And adding a section overtop of Jdog's +300 for pPlot->isRiver:

Code:
	if (pPlot->isHills())
	{
		iValue += 200;
	}

	if (pPlot->isRiver())
	{
/************************************************************************************************/
/* Afforess	                  Start		 07/21/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
		iValue += 100 * GC.getGameINLINE().getRiverBuildings();
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
	}
 
Wow, it seems that I neglected the fact that inland lakes give fresh water too, I was thinking fresh water was only from features. Nice find.
Ok, now I am completely confused. River is no feature, and that should be the main source of fresh water. Also you aren't checking the source of the fresh water, you are merely checking what kind of feature there is on the city plot.

Anyway, if all you want to do is to give fresh water bonus only if the fresh water doesn't come from jungle (or at least not exclusively), then add a new argument to CvPlot::isFreshWater
bool isFreshWater(bool bIgnoreJungle = false) const; in the header file and the code
Code:
if (pLoopPlot != NULL)
{
	if (pLoopPlot->isLake())
	{
		return true;
	}

	if (pLoopPlot->getFeatureType() != NO_FEATURE)
	{
		if (GC.getFeatureInfo(pLoopPlot->getFeatureType()).isAddsFreshWater() [B]&& (!bIgnoreJungle || GC.getFeatureInfo(pPlot->getFeatureType()).getHealthPercent() >= 0)[/B])
		{
			return true;
		}
	}
Then all you need to do in AI_foundValue is
Code:
if (pPlot->isFreshWater([B]true[/B])
 
About that preventing small cities from building settlers too early stuff, I see you're using a very basic version now. CvCityAI::AI_bestUnitAI holds the Better AI code that should do exactly that, only without the differentiation between different barbarian settings, so it might be a good idea to try building on top of that. (Just letting you know in case you didn't know it was there, like me until I finally found it yesterday)

Just a note to self:
self said:
I didn't play-test but I think I still figured it out. You were right, it must be the +1:commerce:, I have no other explanation for it. (bla)
Actually it was just too long ago so I didn't remember it all. :crazyeye: I still have no clue how that fort building happened when there was a better resource-connecting improvement already in place, and therefore can only assume that my current code wouldn't fix that either.
 
In A New Dawn 1.74 beta9 the following happened more than once:
An AI stack apparently intent on attacking one of my cities comes into my country. I reinforce the city to defend it. The AI realizes it can no longer take the city and decides to go back an forth at 2 tiles in my land.

This stack should decide on a new mission, e.g.
find something to pillage
find another city to conquer
fortify on a strategic position and call for siege
go home and report that the mission cannot be accomplished
 
Wow, it seems that I neglected the fact that inland lakes give fresh water too, I was thinking fresh water was only from features. Nice find.

Would this also prohibit Lighthouse and such improvements on lakes? I've noticed that the last several versions if I play Maps that have lakes that I can't build improvements like coastal or river cities can. The lighthouse and fishing hut in particular. And even moreso if the lake is only a few tiles.

But this could be a different path than what you've been discussing. I don't know, but your discussion brought this observation to mind.

JosEPh
 
Back
Top Bottom