Terrain damage

Kaiserisak

Chieftain
Joined
Apr 15, 2008
Messages
32
I have been working on and off on a mod for probably ten years now (an old version is here http://forums.civfanatics.com/showthread.php?p=11245121#post11245121).

One of my ambitions with it, was always to limit the stupid "send an explorer to the other side of the world in 2500 bc to get all huts/meet all the civs", and try to have more natural borders between the civs on the world map. For instance, I completely removed open borders from the early game (they are now available with Nationalism, which of course, screwed trade), inserted more strategically peaks (like in the Hindu Kush, the Urals etc), made it impossible to create a city in a forest/jungle, and also created a new impassable desert-type (called "dune" for lack of more imagination) to limit contact across the sahara. One more thing I did, was to set a (very low) percentage damage to units when in jungles to limit contact in south-east asia, the congo and so on.

I have recently been playing it with a friend, and was thinking about doing more with the terrain damage. First of all, up it from now 5 to 20% to make crossing jungles way less of a good idea (and hopefully, make the AI return home), and i wanted to do the same with deserts and tundra to avoid the stupid tendency of all civs meeting in siberia before bc. However, there is another xml-file that is used for jungles than desert/tundra since it is considered a "feature" of a terrain, and when I tried to just insert the same lines in the normal xml-file for desert/tundra, i predictably, wasnt able to load the mod. Any advice on this? Do i need to dive into python, or is there an easy way to insert terrain damage to deserts by only using xml? Any help would be appreciated!
 
I once considered creating fake features like tundra feature on tundra terrain. :eek:

I decided not to do that. First, it's not convenient, second, I don't even like how the feature attributes health damage (when you exit the feature).

I suppose it would not be too hard to modify it in the dll, adding the damage to terrains. The hardest part is to teach the AI about it. Think of the path finder function: units should try to avoid terrains like tundra, snow, desert (even ocean)...

But I absolutely love the idea and in my mod I'm doing it in Python. I started it from a modcomp "Hardship" by Xooll. Of course the AI has no clue about it and suffers... :(
 
It wouldn't be hard to do in the dll. Two functions would be interesting: move() and doTurn() (both members of CvUnit). Move is the damage for entering a plot while doTurn is what happens at turn start as in the unit is resting in the plot.

It's fairly complex to get this done right though. We would like the pathfinder to avoid damage as much as possible. Right now it will find the fastest route and if it mean spending 3 turns going through the desert, then it will do that. We want it to spend 7 turns going around the desert. At the same time going through a desert plot should be possible if there is no alternative, but it should place the path to keep the number of desert plots to a minimum rather than the fastest route. I can't think of a solution to this problem and just telling people to control units on plot at a time is not an option because we can't tell that to the AI.

Another problem is convincing the AI that patrolling the desert is a bad idea. Not sure what to do about that either.

An alternative approach could be to mod CvUnit::canMoveInto(). If that function returns false, then moving into the plot is impossible. Adding required tech or era to terrain xml can then force the function to return false unless the unit owner has the tech/era in question. Not quite the same thing as damage, but it would be a lot easier to implement and both vanilla AI and pathfinding understands this approach and will act accordingly.

Also remember unit movement and pathfinding is some of the slowest code (if not the slowest) since all the functions related to it are called an astronomical amount of times each turn. This mean modding those functions requires to think at least a bit about performance and you should not do stuff like looping all techs to see if the team as a tech with a certain tag set. Getting the tech/era ID (int) from plot info and then check if the player/team has that tech/era should be fast enough as it is basically just looking up two ints and comparing those two.
 
An alternative approach could be to mod CvUnit::canMoveInto(). If that function returns false, then moving into the plot is impossible. Adding required tech or era to terrain xml can then force the function to return false unless the unit owner has the tech/era in question. Not quite the same thing as damage, but it would be a lot easier to implement and both vanilla AI and pathfinding understands this approach and will act accordingly.
So easy that's it's already in the XML for units ;)
Spoiler :
Code:
			<TerrainImpassables>
				<TerrainImpassable>
					<TerrainType>TERRAIN_OCEAN</TerrainType>
					<bTerrainImpassable>1</bTerrainImpassable>
				</TerrainImpassable>
			</TerrainImpassables>
			<FeatureImpassables/>
			<TerrainPassableTechs>
				<TerrainPassableTech>
					<TerrainType>TERRAIN_OCEAN</TerrainType>
					<PassableTech>TECH_ASTRONOMY</PassableTech>
				</TerrainPassableTech>
			</TerrainPassableTechs>
 
As it is, you can differentiate the behaviour per unit, I like it that way (example: a Viking longboat may enter ocean earlier than any other naval unit).
 
I think that that the best solution for the OP problem would be not terrain damage, but distance damage. The further your unit is from the nearest city the more damage it takes each turn, something like this:

1%/[Distance-(10+Mapsize+Era)]
so in smallest map in ancient era it is safe to go 12 tiles away from your nearest city. 13 tiles away it gets 1% of damage/turn, 10% at 22 tiles, 30% at 42 and so on.

So scouts going to far would die because of the lack of supplies.

Of course the formula needs balancing but I think it is easier to tell the AI not to venture too far from its cities than tinker with path-finding.

Is it doable?
 
Distance damage would have to depend on manhattan distance, as in for each unit, it loops all your cities and the distance is abs(unit_x - city_X) or abs(unit_Y - city_Y). The distance is then the lowest number and it doesn't care if it use x or y.

Alternatively some distance formula is made and the result is cached into the plots. If done right, the cache will only have to be recalculated when a player gains or loses a city. This approach will be the fastest, but it also lose any hope of a non-dll solution.

The AI should be able to cope with it if unitAI will send units back to a city to recover if they lost more than 1/3 of their health. That should be fairly simple compared to how complex the AI code is in general.

It does leave another question though: modern ships can sail around the world easily. They shouldn't be heavily damaged or even lost if they do so. How should the game determine which ancient units to damage and which modern to leave alone? Determined based on units or tech or something else?
 
Back
Top Bottom