limitations to AI in spreading past bad terrain?

davidlallen

Deity
Joined
Apr 28, 2008
Messages
4,743
Location
California
In the new Dune mod, we have added a terrain "deep desert" which is land, but has the terrain flag bFound 0 so that cities cannot be founded on it. We have converted the mapscripts such as archipelago or continents, so that what used to be ocean and coast is this new terrain. So you can expand normally on the "real" land, and you can move land units across the deep desert to found new cities on other "continents".

This works fine for the human player, but we have never seen the AI send settlers across the deep desert. The AI civs fill up whatever archipelago or continent they are on, and then stall. They never expand across the desert even when the other side is rich, and unoccupied.

Please see this link for details and several theories. Any help would be appreciated.
 
Is there a coastal route the AI could use to get to the other side of the desert with the coast there normal desert (as opposed to deep desert)? If so the Better AI is supposed to be able to do that with Galleys.
 
I am not sure if you are familiar with the Dune books. The entire planet is one big desert. There is no ocean route to go around.
 
I've read them. But the amount of water varied considerly in Dune's history. It's a complete desert during the novel Dune, but during the reign of the God Emperor, desert retreats and water increases. After the fall of the God Emperor the desert reclaims the planet.

For that matter "Dune" is a different planet following Heretics of Dune.
 
I have an idea assuming your mod only represents Dune at the time of the novel of the same time.

Have "Deep Desert" take on all flags that "Ocean" currently does. (Other than commerce)
Give some unit (Deep Desert Transport?) naval and transport flags.

Then you just need to found a city adjoining the Deep Desert, build a Deep Desert Transport and a settler, load the settler up onto the transport and cross.

Note that the chars constantly referred to needing Desert Power on Dune; where they needed Naval Power on the previous world, so giving all units that cross Deep Desert "naval" flags seems very fitting to me.
 
Please stop by the Dune Wars thread, where we have actively discussed this for a while. Given the current state of AI, neither a "land model" nor an "ocean model" appears to work well. We would like to find a solution, without rewriting the AI, but we cannot find any solid directions to proceed.
 
There are a variety of things which could cause this setup not to work for the AI ...

In these maps, how many CvArea objects are there? Typically, each land mass or island is its own area and the ocean and each lake are also their own areas. In debug mode, hold down shift as you mouse over tiles and the game will tell you the area ID for different tiles (along with a bunch of other info).

Whether you want each oasis to be its own area or all part of one area depends on how you want the AI to settle and fight. If transports are necessary to go across the desert, then the answer is easy: you want multiple areas. You'll also probably want to disable the AI logic which forces the AI to build it's first city in a new area on a coastal tile ...

If groups of units can cross alone, then you want all the land to be a single area. With a single area, the issue could be that the value the AI assigns to far away tiles isn't high enough for it to want to send a settler there. Again, in debug mode you can get a lot more info. If you're running BBAI, the game will draw colored circles on the tiles different civs have selected as potential city sites. Holding down ALT as you mouse around will give you some info on how the AI is valuing different tiles as potential city sites ... there quite a few numbers in the display, but the one right after each players' name is the "real" value assigned, and a value of more than 1200 is needed for the AI to consider settling there, while good spots are several thousand. The real value is forced to zero around the tile the AI thinks is best in an area, to get a sense for how the AI values the tile without that look at the number followed by an 's', the "starting" value (this is how starting sites are valued at the beginning of the game ...). This info panel will also tell you how many sites the AI has in the area, what the best value its found is, etc.

Let me know what you find and I might be able to help you sort out how to tweak the AI so it understands your setup.
 
Thanks for the info! I have not used revdcm much, and I wondered what the color circles were for. In this approach of using land for all terrain, there is only one "area". There has been further discussion in the original thread, and a "hack" solution in this post. We have improved the hack slightly so the iMinFoundValueThreshold can be passed from XML.

However, one problem with this approach of using land for all terrain is that the transport vessels are also forced to be land vehicles. And nobody has solved land transport for the AI, so it would be unable to fight effectively.

So in parallel we are trying another approach where we use normal coast and ocean with a graphics change to look like desert. But this gives us a different set of problems, maybe you can help us solve these.

What we want is mid game hovercraft which can carry troops and move over all land, plus coast, but not ocean; and late game hovercraft which can carry troops and move over all land and water terrain. There is a unit flag bCanMoveAllTerrain which "should" allow this but it does not work as expected. Here are two tests I tried using standard revdcm. The changed files for assets/xml/units are in the attachment.

1. Make two copies of the galley. The first copy, "Galley Moveall", is identical to the original except bCanMoveAllTerrain is set. The second copy, "Galley Landall", has DOMAIN_LAND and bCanMoveAllTerrain. Start a standard revdcm, any game, and give yourself three units, an original galley and one each of these two new units. We cannot find any difference in the movement of Galley Moveall. The Galley Landall works as expected, it can travel over land and sea.

2. Back to an unmodified revdcm, change all the DOMAIN_SEA units (except workboat) to DOMAIN_LAND with bCanMoveAll set. No other changes. Yes, this means that DOMAIN_LAND units have AI like UNITAI_ASSAULT_SEA. Now start a small game using archipelago mapscript and autoplay 400 turns. You will see that no naval activity happens at all. I have included a save game from this setup in the attachment.

So, what we would like is some modifications so that naval units can move on land if needed, but still serve as naval transports, based on bCanMoveAllTerrain or some other flag. This "seems" easier than fully developing land transport. We do not know all the details; but it seems we would need a way to make units which (a) move on both land and sea, (b) can be built at inland cities, (c) can serve as naval transports. It would be "nice" if these units could carry their troops directly up to inland cities; however, dropping them at the coast would be fine too, and probably much less work.

Can you think of any way to accomplish this? We have a couple of sdk coders who could help, but they are not familiar with the internals of revdcm or better AI. Maniac has said that he has similar code inside Planetfall, but he does not have time/interest to pull it out separately.
 
It sounds like you're most of the way there, that map setup you described will make it possible to make smaller changes to the AI to get it to work. Some ideas:

- You'll want to keep transports and other things which enter the dessert as DOMAIN_SEA if at all possible. The AI won't build a UNITAI_ASSAULT_SEA (or any other _SEA unit ai) that isn't DOMAIN_SEA. From the code, it seems like DOMAIN_SEA with canMoveAllTerrain should work ... I couldn't find the source of the bias with a quick look through. I found one small anti-sea bias, but not one that would cause this.

- There are a bunch of ways to go for limiting movement of early transports. Deep desert could be labeled impassable, then advanced transports could be allowed to move on impassable terrain. A better way would be to make certain terrain unlockable by techs for transport units using TerrainImpassables and TerrainPassableTechs. The AI has trouble if some naval units can enter ocean and others can't, it mostly works in BTS as the unit AIs and upgrading are handled just right to compensate but terrain unlocked by tech is much easier for the AI to handle.

- Assuming you have no actual "naval" only units, then all cities should be considered coastal. For the AI, the most important change you'll need is to tell each city that it's on a useful water area so it builds naval units. You could have CvCity::waterArea() return GC.getMap().findBiggestArea(true). I don't think you'll need to short-circuit CvCity::isCoastal so it always returns true, but I'm not sure ... that has no bearing on building ships at least.

- Also, you'll need to change CvPlot::canTrain to fix this section:
Code:
                if (GC.getUnitInfo(eUnit).getDomainType() == DOMAIN_SEA)
		{
			if (!isWater() && !isCoastalLand(GC.getUnitInfo(eUnit).getMinAreaSize()))
			{
				return false;
			}
		}
The coastal land section should be replaced by a check for waterArea() I think, or simply removed.

- You'll probably want to make sure map scripts produce minimal 1-tile "offshore" islands, I think there are options for "pressed" coastline already. The AI won't send workers to improve islands.

- You could also have these desert transports forced only operate in the desert (if built in a non-"coastal" city, they could be bounced out to the desert right after creation). They could then enter forts or cities on the edge of the desert. The AI should build coastal cities unless you tweak it.
 
Great, I can see how this will definitely solve part of the problem! I would like to avoid dune-*only* changes if possible, and key off some XML attributes including bCanMoveAllTerrain. That way the code can ultimately live in a public place.

I would rather not use tech-unlockable terrain if possible. It seems odd that the same unit, out somewhere in the desert, could suddenly move onto deep desert because some gearhead at home invented something. For now, let us stick with analogs to galley (early, coast only) and other ships (coast and ocean).

I also would really like to avoid any concept of a "port" city. That doesn't make sense for the Dune theme.

So we need the following changes:

a. CvPlot::canTrain() should return true for bCanMoveAllTerrain ships.

b. In order for CvCity::waterArea() to return a water area for landlocked cities, I guess we have to add a global XML attribute like bAllCitiesCoastal. Is there a way that this can return at least some relevant water area, instead of the biggest? That may be some distance away. Maybe it doesn't matter if the function is only used to tell whether there is one or not.

c. We still need "something" to understand why bCanMoveAllTerrain doesn't affect DOMAIN_SEA units. Is it possible for you to take another run through the code and understand this? What normally prevents DOMAIN_SEA from moving on land?

Can you think of any other changes we may need?
 
Sounds good. Just make sure that there are upgrades for all of the limited transport units and keep your eye out for the AI having mixed stacks where only half the units can go over deep desert.

a) Good idea.

b) Returning the biggest one guarantees that the city will build naval units ... with other areas then it depends on coastal city counts.

c) Maybe someday ... got a few other things on my plate right now. If you figure it out in the meantime, let me know!

The next set of potential issues include:
1) The AI likes to settle coastal cities, which may not be a good decision here.
2) The AI will only settle coastal cities first in new areas.
3) I think the "naval" units will move to and pick up units in non-coastal cities correctly, but seeing is believing.
4) When running invasions, the AI currently will only consider dropping off in coastal land tiles. If you want it to attack cities directly, you'll need to tweak CvUnitAI::AI_assaultSeaTransport. Other than that, it should still work.
 
4) When running invasions, the AI currently will only consider dropping off in coastal land tiles. If you want it to attack cities directly, you'll need to tweak CvUnitAI::AI_assaultSeaTransport. Other than that, it should still work.

For Planetfall I modified the original code:
Spoiler :
Code:
	for (int iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
	{
		CvPlot* pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

		if (pLoopPlot->isCoastalLand())
		{
to this:
Spoiler :
Code:
	bool bCity = false; // Planetfall Maniac

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

		// ************************
		// Added for Planetfall
		// ************************

		bCity = false;
		CvCity* pCity = pLoopPlot->getPlotCity();
		if (pCity == NULL)
		{
			for (int iJ = 0; iJ < NUM_DIRECTION_TYPES; iJ++)
			{
				CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), ((DirectionTypes)iJ));
				if (pAdjacentPlot != NULL)
				{
					pCity = pAdjacentPlot->getPlotCity();
					if (pCity != NULL)
					{
						if (pCity->getOwnerINLINE() == pLoopPlot->getOwnerINLINE())
						{
							bCity = true;
							break;
						}
						else
						{
							pCity = NULL;
						}
					}
				}
			}
		}
		if (pCity != NULL)
		{
			bCity = true;
		}
		// ************************
		// End Added For Planetfall
		// ************************

		if (pLoopPlot->isCoastalLand() || (bCity && canMoveInto(pLoopPlot)))
		{

Basically I made all plots adjacent to cities valid destination plots. I should probably disable water plots as valid plots though...
Anyway, so far I have not seen an AI drop units inland. This may just be though because there are always good coastal drop sites available.

CvSelectionGroup::isAmphibPlot should also be changed - otherwise the cargo will automatically be dropped every time you move on a coastal plot, no matter if it's your destination or not.

Spoiler :
Code:
bool CvSelectionGroup::isAmphibPlot(const CvPlot* pPlot) const
{
	bool bFriendly = true;
	CvUnit* pUnit = getHeadUnit();
	if (NULL != pUnit)
	{
		bFriendly = pPlot->isFriendlyCity(*pUnit, true);
	}

	return ((getDomainType() == DOMAIN_SEA) && pPlot->isCoastalLand() && !bFriendly && !canMoveAllTerrain());
}

c) Maybe someday ... got a few other things on my plate right now. If you figure it out in the meantime, let me know!

CvSelectionGroup::isAmphibPlot may be why your galleys can't move on land. There's some code in CvGameCoreUtils pathDestValid that basically says naval units without a cargo can't move on coastal land.

Changing CvSelectionGroup::isAmphibPlot and thus disabling automatic unloading has a side-effect though. I recently noticed an AI dropship moving next to a city of mine, but it only unloaded its cargo the next turn! So the dropshop was a sitting duck for a turn... Moving on the target plot expended all the dropship's remaining movement points - perhaps that may have been an issue too. JDog, do you know a way to make the AI unload its cargo right away when arriving on the target plot??
 
I can see in the planetfall distribution that the dropship does use bCanMoveInAllTerrain. The disti does contain the whole source code, and the changes seem to be well-marked. So theoretically, it should be possible to pull out the right bits of Maniac's code and get this to work.

Unfortunately there are a ton of changes in Maniac's source files, and it is not clear which ones are needed. For example, there are a number of changes related to stealth units. There is no way I can think of for an outside person to figure out for sure which are related.

I recommend koma13 and johny smith, if they have time, to look at the changes in planetfall and in the thread above, and see if they can pull out just the related bits. Of course if Maniac has the opportunity, it would be more efficient for him to pull out a "submod" (?) with just the changes needed to have bCanMoveAllTerrain work for DOMAIN_SEA units, and the related AI changes so that some kind of amphibious assault will work.

Right now Dune Wars is playable, but it is easy to beat the AI on normal difficulty levels. Bumping it up just means that the AI sits there building defensive units, and no reasonable player amphibious assault will work. So having a smarter AI seems required for interesting play.
 
@Maniac:

Not off hand ... there'd need to be some addition to the CvSelectionGroup logic which determines when the assault group as reached its desired plot, then a call to unloadAll(). You're correct that it is an issue because the unit runs out of moves right as it gets to the desired plot.

@davidlallen

It sounds to be that with what Maniac mentions above, you should be in good shape. I'll see whether any of these changes makes sense for BBAI so that others don't run into this issue.
 
You can certainly change the AI type of units that are already in the game, the game just proceeds forward as if they are units of the new type. If you do this for units you control (and you're not using AI AUTOPLAY or something), then it has no effect.

This can, however, cause odd behavior or even crashes/hangs if done without careful thought (as I learned recently in RevDCM ...).
 
I recommend koma13 and johny smith, if they have time, to look at the changes in planetfall and in the thread above, and see if they can pull out just the related bits. Of course if Maniac has the opportunity, it would be more efficient for him to pull out a "submod" (?) with just the changes needed to have bCanMoveAllTerrain work for DOMAIN_SEA units, and the related AI changes so that some kind of amphibious assault will work.

Koma13 has done it! Thanks. Please see this post.
 
Koma13 has done it! Thanks. Please see this post.

Yes, it is working now. Thanks for all the help. :)

Some pics of a city assault by ai autoplay:
Spoiler :

I imported the dropship from Planetfall. Red player attacks green player. 2 dropships on their way to the target destination (city Ammon).


Drop ships reached peak next to Ammon.


Dropships unloaded units and going back to home territory. :goodjob:

 
Top Bottom