Better City Sites AI

koma13

King
Joined
Sep 29, 2008
Messages
662
My new task for dune wars will be helping the ai in deciding where to found a new city. If done right, this could not only boost ai competition in general, but also give better starting locations.
I can't do this on my own. It will need a lot of balancing and testing before we will have any satisfiable results. You can all help by trying out the new CvGameCoreDLLs that will be posted in this thread and by giving feedback.

Here is the initial reaction by davidlallen on my restarted plans to focus on that topic:

Excellent! I wish that the Arrakis mapscript used the same code as AI colony placement during the game. Was it you who suggested that perhaps the whole huge function AI_foundValue could be replaced with something much simpler customized for DW? I think that is the right approach. I never got back to my project of studying and adding comments to the existing function. Do you think it is worth a thread, to propose and review a simple function for city placement? For example, +50 points per adjacent ocean/coast plot, +100 points for each water bonus, etc?

Thanks David.

My current plan is still trying to improve the existing function. After all, the ai decisions aren't completly bad. Only if that is failing I would like to try to create a new one. We would have to make sure, not hardcoding too much things into it, making creation a challenge and examination of the current function necessary.
 
I've put attention, that some ai travels long road before it found its capital. Once when i played short game (unfinished) with IX, BG built her capital few turns later, on decent spot 3 tiles from my capital. The land she came from was really crappy. Too pity i just built few soldiers and killed her.
 
My understanding is that when choosing a city site, the AI evaluates particular sites based (primarily) on bonus resources and tile yields within the BFC of that site (and to some extent on the value of those tiles with basic improvements?). It calculates a value/score for each site, and then builds a city on the site with the highest score.
Is that right?

If so, as I have said elsewhere, I think the single largest gain for city placement would be for the AI to eliminate from its score calculation for a particular site A any tiles (especially bonus resources) within the BFC of A that are also within the BFC of any other city owned by that player (or maybe by any player).
Time and time again I see the AI's build cities too close together, because they build one city and then build a second city, the second city chooses a site so as to include in its BFC resources tiles that are already being worked by the first city.

In vanilla, this is just poor, but in Dunewars this is a huge penalty, because cities are so dependent on a few particular water-yielding tiles in order to be able to grow at all.

The second thing I would suggest would be a minimum water value. If a site does not have at least 2 (or maybe 3) water-yielding tiles (non-adjacent mesas, groundwater, dew-collector resource, polar anchor grass, polar) within its BFC (and not in the BFC of another nearby city) then it should not build a city there.

ICS is not a good strategy in this mod.
 
I've put attention, that some ai travels long road before it found its capital.
Maybe BG started on mesa?
Having starting locations on mesa is very strange and from my understanding shouldn't happen at all. :confused: It is non foundable peak terrain, normally returning a value of 0, not suited for a game start. Maybe it's related to that other peak weirdness we are currently dealing with?

My understanding is that when choosing a city site, the AI evaluates particular sites based (primarily) on bonus resources and tile yields within the BFC of that site (and to some extent on the value of those tiles with basic improvements?).
Found value is calculated by dozens of arguments. A few examples:
-bonus resources in bfc
-yields on tiles in bfc
-potential improvements and their influence on tiles in bfc
-foreign/own culture present in bfc
-distance to next foreign/own/captial city
-area calculations (number of own/foreign/coastal cities in that area)
-a lot more...

It calculates a value/score for each site, and then builds a city on the site with the highest score.
Is that right?
Correct (but it calculates a value for each plot)

If so, as I have said elsewhere, I think the single largest gain for city placement would be for the AI to eliminate from its score calculation for a particular site A any tiles (especially bonus resources) within the BFC of A that are also within the BFC of any other city owned by that player (or maybe by any player).
Time and time again I see the AI's build cities too close together, because they build one city and then build a second city, the second city chooses a site so as to include in its BFC resources tiles that are already being worked by the first city.
This should be possible. Of course it only works for city sites (A) vs. existing cities.

The second thing I would suggest would be a minimum water value. If a site does not have at least 2 (or maybe 3) water-yielding tiles (non-adjacent mesas, groundwater, dew-collector resource, polar anchor grass, polar) within its BFC (and not in the BFC of another nearby city) then it should not build a city there.
Non-adjacent mesas will be a pain to do, but otherwise I don't see much problems.
We just have to make sure not having too much hardcoded/specific stuff in it. We don't want to rewrite it everytime someone changes the terrain xmls...

ICS is not a good strategy in this mod.
What is ICS?
 
There were not only peaks, just bad resourceless terrain mixed of mesas and rugged i think, some sneaky landmass.
 
Correct (but it calculates a value for each plot)

I think we mean the same thing here. Plot = site = tile I think.

Of course it only works for city sites (A) vs. existing cities.

Yes, but I think thats the biggest problem. And it works iteratively to spread cities out; every city is built in relation to existing cities.

Non-adjacent mesas will be a pain to do, but otherwise I don't see much problems.

Alternative fudge would just be to have mesas count as 2/3 of a water source.

We just have to make sure not having too much hardcoded/specific stuff in it. We don't want to rewrite it everytime someone changes the terrain xmls...

Understood, but the terrain xmls seem fairly fixed to me, no?

What is ICS?
Infinite City Sprawl (or Sleaze). Basically packing in lots of small cities in very tightly.
The two "main" strategies in previous versions of civ were ICS and REX (Rapid EXpansion).
 
I've put attention, that some ai travels long road before it found its capital.

This would surely be fixed by merging the civ start position function with the city founding function, right?
 
I think we mean the same thing here. Plot = site = tile I think.
City site always have a nice found value, something not necessary true for plots/tiles...

Yes, but I think thats the biggest problem. And it works iteratively to spread cities out; every city is built in relation to existing cities.
True, but it won't work very well when we have multiple settlers with founding missions on map.

Alternative fudge would just be to have mesas count as 2/3 of a water source.
Agreed.

Understood, but the terrain xmls seem fairly fixed to me, no?
No more yield balancing? :)

This would surely be fixed by merging the civ start position function with the city founding function, right?
It is already merged. :eek: Starting location are valued by the same ai_foundvalue funtion as normal city sites (but with a special argument).
 
City site always have a nice found value, something not necessary true for plots/tiles...

I think we are just using different terminology; I did not mean anything specific when I used the "site" term - just a potential place where you might consider building.

True, but it won't work very well when we have multiple settlers with founding missions on map.

Yeah, I thought of that - do settlers pick a location when they are built, and then not update that? Maybe there is a way to make all settlers pick new city found locations whenever another settler of your founds a city? But still, I doubt that many cities are foudned by multiple settlers at the same time.

No more yield balancing?
Probably, but the rough ratios between the well, windtrap and dew collector will likely remain unchanged. And isn't that what matters for this specific hardcap on spots with not enough water?

It is already merged. Starting location are valued by the same ai_foundvalue funtion as normal city sites (but with a special argument).
If it were compeltely merged, then every civ's start position would already be a decent site to found a city, in which case you would not observe AI players wandernig with their settler unit without founding, because they would found where they started.

I have also observed AI's wandernig; in a couple of games they have never founded, and been stuck with just a settler or worker or slave somewhere with no cities.
 
I think we are just using different terminology; I did not mean anything specific when I used the "site" term - just a potential place where you might consider building.
Ah ok. For me 'site' is a 100% civ4 term I read for the first time in my life inside the cvgamecoredll. It only appears in combination with 'city'. :)

Yeah, I thought of that - do settlers pick a location when they are built, and then not update that?
Afaik location are picked when a settler is starting its journey. Otherwise I remember rival settlers immediately changing their destination when I founded a city in the area they headed for. Maybe it's updated each turn...

If it were compeltely merged, then every civ's start position would already be a decent site to found a city, in which case you would not observe AI players wandernig with their settler unit without founding, because they would found where they started.

AI players wandering with their first settler only happens, if ai can't found a city on its starting tile. If that happens it should calculate a new city site and move its settler to that tile.
I remember testing a few days ago to return all peak terrain with a found value of 0 (should prevent ai from viewing this tile as a good city site (and starting location)). But the ai/human player still started on this plot type. For some reason AI foundvalue on mesa was completley ignored. :confused:
 
There were not only peaks, just bad resourceless terrain mixed of mesas and rugged i think, some sneaky landmass.

This emphasizes one point I made earlier. The code which the arrakis mapscript uses to choose starting plots has a completely different way of computing which are good plots. So the mapscript thought, for whatever silly reason, that the BG was at a good starting point, but the AI for founding a city did not think so, and the BG settler had to walk a long way to find a good spot. We need to solve both, or make the mapscript use koma's new scheme when he gets it, in order to really see the result.
 
I suspect that the start position finder liked it because it saw the water value of the mesa tiles. But this discrepancy is what I meant by merging the functions; using the same plot evaluator for both.
 
So the mapscript thought, for whatever silly reason, that the BG was at a good starting point, but the AI for founding a city did not think so, and the BG settler had to walk a long way to find a good spot.

When an ai has zero cities, it will immediately found one:

Code:
void CvUnitAI::AI_settleMove()
{
	PROFILE_FUNC();

	if (GET_PLAYER(getOwnerINLINE()).getNumCities() == 0)
	{
		if (canFound(plot()))
		{
			getGroup()->pushMission(MISSION_FOUND);
			return;
		}
	}
 
I guess that means the BG settler must have been standing in a block of mesa, and moved down off it before founding.

I have noticed, however, that tiny arrakis mapscripts often give starting points that are very close to each other. In this case, the settler does not have to walk to get near me; it starts out near me. I posted a screenshot on the mapscript thread a couple of days ago.
 
I guess that means the BG settler must have been standing in a block of mesa,
I agree.

This emphasizes one point I made earlier. The code which the arrakis mapscript uses to choose starting plots has a completely different way of computing which are good plots. So the mapscript thought, for whatever silly reason, that the BG was at a good starting point
I checked Arrakis.py and indeed it has its own starting plot value function mostly making distance checks (which seems to fail often).

What is the general plan with map scripts? Will we continue to support both (dunepilago and arrakis) or only one of them?
 
What is the general plan with map scripts? Will we continue to support both (dunepilago and arrakis) or only one of them?

Good question. I think we are close to eliminating dunipelago/archipelago (they are copies of each other) and only distributing arrakis; but we are not there yet. I would be happy if you updated the arrakis mapscript with the better scheme and left archipelago alone. We could drop it, maybe for 1.7.
 
Well, I personally would prefer leaving the Duneipegalo there... as long as it is still playable, why cut it?
More is better.

But the Arrakis is very playable these days so I have mostly been testing that.
 
I removed the special starting plot function in arrakis.py. I think it's better now. I haven't seen a single mesa start. :)
 

Attachments

Well, I personally would prefer leaving the Duneipegalo there... as long as it is still playable, why cut it?

For one thing, it doubles the time it takes me to test a release. Because of the difference in availability of ice, I try to do all the autoplays once on arrakis and once on archipelago. If it's useful, fine, but cutting it would make releases a little easier.

koma13 said:
I removed the special starting plot function in arrakis.py. I think it's better now. I haven't seen a single mesa start.

Great, I will add that in.

EDIT: it is fine, but next time you change the mapscript, please bump the version number in the comment block, and add #koma13 by your change.
 
Back
Top Bottom