[Map Script] PerfectWorld.py

1) Is there any good way to reduce the number of rivers, particularly in the desert? Reducing the RiverThreshold value seems to help slightly, but mostly just makes them shorter. I'd much prefer a few long and twisting rivers over what I'm seeing, which is a river almost every tile, going 2-3 tiles in from the coast. I can accept this sort of thing a little more in the jungle, but it seems to really cover the desert with rivers, which is odd since as far as I can tell from the script, rivers are created from rainfall and deserts are created from a lack thereof.

This is a difficult problem since the rivers are generated from the hightmap. The only way to have longer rivers would be to have them go uphill sometimes, which is not really in line with this map script. Another problem is, the civ graphics do not allow river outflows from a lake, and since lakes can't overflow, rivers end when they hit them instead of continuing. The reason that rivers appear often in the desert is because deserts are often on the very largest continents, where there might be little rain, but the watershed is huge. Just imagine them as small rivers. I've gotten used to the way the system works and I like it. It does help to break up what can sometimes be a very large desert.

2) Is it possible to reduce the "grain" of the landmasses? By that I mean, I'd rather have larger, blobbier continents than the snaky island chains the script tends to generate. I've tried increasing the LandPercent variable, and that does help a bit, but it's too much land.

The easiest way to do that would be to change the dimensions of each map size. Extending one dimension so that it can be divided by 4 instead of 8 will have the effect you want.
 
Thanks cephalo, I ended up starting a game on a huge map last night, and it felt like I was playing an entirely different game! The exploration period was simply wonderful, these maps are truly a work of art, the likes of which the Civilization franchise has sadly not seen before.

I bumped the river threshold up a bit (I think I settled on 2.8, up from the default 2.0, IIRC), and bumped the floodplain threshold up a bit as well (I noticed I didn't have to do this much, as the increased river threshold is used as a multiplier with the floodplain threshold in the calculations). This ended up with very close to perfect rivers for me. For gameplay reasons, I'd like longer rivers, but these look very realistic. There were still a few rivers in the desert, but only the biggest had floodplains, so that's fine with me.

I also did something a little unorthodox and enabled floodplains on grass, plains, and tundra. They're extremely rare, as I set them to only check for a chance if no trees or jungles were generated, and the climate where the rainfall is right for no fauna but a floodplain is very rare. So far, it's only been in plains bordering the desert. I also bumped up the oasis chance to 12% from 8% so desert woludn't be completely barren without much floodplains.

I did however notice another minor complaint, when horses and other such resources are placed in the middle of the forest, there's a clearing. I gather that this is because there are so many forests and jungles on your map, so there otherwise wouldn't be much place to put them? I'd really rather decrease the fauna a bit and relegate such resources to only occurring in open spaces. It really gives the human an unfair advantage this way, as when I see a clearing in the middle of the forest I know to put a city near it. Ironically, the AI can't cheat in this way despite many peoples' claims to the contrary.

edit: Here's a nice little article from the straight dope that talks about how the great plains happened http://www.straightdope.com/columns/050708.html. I point this out because your script seems to put forests anywhere with enough rainfall, but in reality there should be some randomness to it that creates non-forested regions where it could otherwise support them. I may experiment with adding a deforestation routine to the map that goes through and clears off some large blobs of forest or jungle after they're generated.
 
edit: Here's a nice little article from the straight dope that talks about how the great plains happened http://www.straightdope.com/columns/050708.html. I point this out because your script seems to put forests anywhere with enough rainfall, but in reality there should be some randomness to it that creates non-forested regions where it could otherwise support them. I may experiment with adding a deforestation routine to the map that goes through and clears off some large blobs of forest or jungle after they're generated.

Thanks for the nice compliment. The only time that forests are guaranteed is when the rainfall level reaches the 'rainforest' threshold, yet is too cold to be jungle. Otherwise they are randomly generated depending on rainfall. I really like the way it looks, (see some discussions above in this thread) and when you look at real areas with lots and lots of rain, there really are always trees there. The problem with so many trees though (see above for a detailed discussion) is that certain resources are severely restricted by them, so I had to give resources the right of way over trees. I know the clearings that you speak of, occasionally there is indeed nothing there! ;)
 
Hmmm, good point I guess. Even though I still stand by the example of the great plains as a more randomness-based area, it may be beyond the scope or requirements of such a model. I was doing a bit of research on biomes, and found a really neat map: http://www.worldbiomes.com/biomes_map.htm

When I compare that with the PerfectWorld maps, I think the main issue that's bothering me may just be too much moisture. Looking at Africa and even South America, savanna and grassland really dominates. I feel like a pw script of earth would fill them with jungle and forests.

I think I may be able to hack it to leave larger areas of low moisture surrounding the deserts by modifying this section:
Code:
                if rm.rainMap[i] > terr.plainsThreshold*1.5:#jungle
                    if tm.tempMap[i] > JungleTemp:
                        if terr.terrainMap[i] == terr.PLAINS:
                            plot.setFeatureType(featureForest,FORESTLEAFY)
                        else:
                            plot.setFeatureType(featureJungle,0)
                    elif tm.tempMap[i] > ForestTemp:
                        plot.setFeatureType(featureForest,FORESTLEAFY)
                    elif tm.tempMap[i] > TundraTemp:
                        plot.setFeatureType(featureForest,FORESTEVERGREEN)
                    elif tm.tempMap[i] > IceTemp:
                        plot.setFeatureType(featureForest,FORESTSNOWY)
                elif rm.rainMap[i] > terr.desertThreshold:#forest
                    if rm.rainMap[i] > PWRand.random() * terr.plainsThreshold * 1.5:
                        if tm.tempMap[i] > ForestTemp:
                           plot.setFeatureType(featureForest,FORESTLEAFY)
                        elif tm.tempMap[i] > TundraTemp:
                            plot.setFeatureType(featureForest,FORESTEVERGREEN)
                        elif tm.tempMap[i] > IceTemp * 0.8:
                            plot.setFeatureType(featureForest,FORESTSNOWY)

Instead of reusing the plains and desert thresholds, I can make separate forest and jungle thresholds that are slightly higher. If I'm not mistaken, this should allow for more forest on grassland, and open plains. Combined with the random deviation in plot choosing that I see is already present, this should allow for larger savanna areas surrounding the deserts.
 
When I compare that with the PerfectWorld maps, I think the main issue that's bothering me may just be too much moisture. Looking at Africa and even South America, savanna and grassland really dominates. I feel like a pw script of earth would fill them with jungle and forests.

The first version of PW was more realistic in terms of relative rainfall, but the result was that there was soooo much desert and plains. It wasn't really working well for civ, and everyone wanted it to be adjustable so I changed it from an absolute calculation to a relative one so the map could be manipulated by percentages.
 
Ah okay, I get it. So the issue is that while I do have direct control over how much plains and desert the map has with your variables, I don't have direct control over how much fauna covers those base terrain. It looks like if I add in a couple more thresholds for Forest and Jungle though, I can satisfy this desire.

edit: By the way, is there any reason you prefer to set the variables in code rather than provide in-game settings? I'd be happy to send you the code to do so if it's just a matter of not having gotten around to it yet.

edit 2: And it looks like, if I feel comfortable that I've restored enough plains, I should be able to just add the CyPlot:canHaveResource check you mentioned before to the CanPlaceBonusAt method, right? Or if I feel a little fancier, I may actually have the AddBonusType method run two passes, one with the check and one without, but only if the first pass couldn't place them all.
 
Ah okay, I get it. So the issue is that while I do have direct control over how much plains and desert the map has with your variables, I don't have direct control over how much fauna covers those base terrain. It looks like if I add in a couple more thresholds for Forest and Jungle though, I can satisfy this desire.

edit: By the way, is there any reason you prefer to set the variables in code rather than provide in-game settings? I'd be happy to send you the code to do so if it's just a matter of not having gotten around to it yet.

edit 2: And it looks like, if I feel comfortable that I've restored enough plains, I should be able to just add the CyPlot:canHaveResource check you mentioned before to the CanPlaceBonusAt method, right? Or if I feel a little fancier, I may actually have the AddBonusType method run two passes, one with the check and one without, but only if the first pass couldn't place them all.

The thing about the resource XML is that the desired number of some resources are calculated by how much available terrain there is, so if you allow the forests to block them you'll only get a small amount, even if there's room for plenty. So if half of your plains tiles are covered in forest, the XML rules will only try to place half the number of wheat bonuses than other wise. So if you want enough bonuses without removing forest, you would need two different functions for calculating numbers and then for actual placement.
 
Yeah, I'm just talking about adding a first pass in addition to your bonus placement, that works the same except it additionally has the CyPlot:canHaveResource check. That would leave the total number of resources the same (since your CalculateNumBonusesToAdd is still used), but would cluster them in non-forested areas where possible. I think this will allow for much more balanced maps with more plains, as the bonus resources will make up for the lack of forests and rivers in these regions.

If there's simply not enough unforested area to place all of a resource, it can make a second pass where it places them in forest clearings. I would also like to make these clearings a little bigger though. I do see that there's random chances of clearings anywhere in a forest, but the forest growth routines in-game will fill these in very quickly. Adding a routine instead that runs after forests are placed and makes random 2-3 tile clearings would be more subtle (and making the resource clearings 2-3 tiles to match).
 
I don't post very oftern, but I just want to say that this is a very good map script (I only use it). I wholeheartedly recommend it to anyone who wants a realistic planet generated. Thought the author should know that there are plenty of people like me that fully support this script even though the forums don't show it. Keep up the good work.

On a side not, I do have one recommendation. It seems that in all the maps I've played, there are relatively few individual health resources (besides seafood). What I mean is there is only like 1 wheat on the entire map. However, I must admit that I play on small or tiny maps so it could just be that I need to play on a larger map.

Anyway, really nice script. It just keeps getting better and better.
 
I think I found the solution to the problem of short rivers. I replaced
self.averageRainfallMap = avg
with
self.averageRainfallMap = sqrt(avg * avg * avg)
and changed RiverThreshold from 2.0 to 0.06

There were less rivers and lakes in general but they were longer. The script produced some interesting rivers like the one on the first screenshot but occasionally I had some strange results (second screenshots). The other problem is that there were no floodplains no matter how low the FloodplainThreshold was (I had to make every desert river tile a floodplain).
 

Attachments

  • Civ4ScreenShot0006.JPG
    Civ4ScreenShot0006.JPG
    163.3 KB · Views: 278
  • Civ4ScreenShot0005.JPG
    Civ4ScreenShot0005.JPG
    185.2 KB · Views: 315
  • PerfectWorld2.zip
    33.1 KB · Views: 200
I've been tweaking this script for myself. One notable change I made was to how you distribute the initial peaks. The way you do it now favors putting more peaks in the southernmost locations, because it loops through them from south to north.

I recommend replacing the loop starting with "allPeaksPlaced = False" with this one.

Code:
		xGridPoints  = self.mapWidth/self.chunkSize	
		yGridPoints  = self.mapHeight/self.chunkSize -1 #we want to skip 0
		while peaksPlaced < numberOfPeaks:
			randomX = int(xGridPoints * PWRand.random())
			randomY = int(yGridPoints * PWRand.random()) + 1
			i = self.GetIndex(randomX*self.chunkSize,randomY*self.chunkSize)
			if self.map[i] == 0.0:
				self.map[i] = 1.0
				peaksPlaced += 1

I also changed the tectonic section in my script so that colliding plates don't always both go up. I based how they interact on their IDs. If the IDs are 1 apart, they both go up a lot. If they are 2 or 3 apart, they both go down a lot. If they are more than that apart, the lower one goes down and the higher one goes up. I changed this because I thought making trenches would be useful in avoiding pangaeas. I'm not sure how much difference it makes, but I like it.

I also made a lot of changes to to starting locations that I'm really happy with, but that will take a while to format more nicely for you.
 
On a side not, I do have one recommendation. It seems that in all the maps I've played, there are relatively few individual health resources (besides seafood). What I mean is there is only like 1 wheat on the entire map. However, I must admit that I play on small or tiny maps so it could just be that I need to play on a larger map.
I tried very hard to fix that in the last patch. The XML rules are very strict regarding those resources. They must be very far apart from one another and also far apart from same class resources like corn, and only exist on one continent. I kept the distance rule but also chose a few other continents to place them on in a way that preserved the spirit of that rule. Still, PW's landforms are so variable that sometimes there just isn't any any room on the smaller maps for all the resources that should be placed. No matter what sized map, wheat still will not allow placement within 5 squares of any other crop. That's alot of real estate on a duel sized map.

There were less rivers and lakes in general but they were longer. The script produced some interesting rivers like the one on the first screenshot but occasionally I had some strange results (second screenshots). The other problem is that there were no floodplains no matter how low the FloodplainThreshold was (I had to make every desert river tile a floodplain).
Looks like you're adding a curve to the resulting rainfall map used to create rivers. That's a cool idea, it helps to simulate an evaporation factor that is missing. It should be very easy to fix the floodplains to follow that so you don't need a floodplain at every river tile. It's a double float so you can make it very small if need be. Floodplains are generated from the drainage map.

I've been tweaking this script for myself. One notable change I made was to how you distribute the initial peaks. The way you do it now favors putting more peaks in the southernmost locations, because it loops through them from south to north.
Yeah, looking back I don't why I did it that way. Your way should work better. I have also had some complaints regarding the amount of land at the poles. It might be nice to eliminate the bottom row as well as the top row from consideration.

Right now I'm neck deep in a totally different map script, and I'm kinda excited about it. I will come back here and update PW when I get a chance. I'm not abandoning it.
 
Oh wow, I know this is sort of cheating, but I just figured out how to apply my hemispheres logic to this script. It's not perfect, but it's really quite cool.
 
Nice to see I'm not the only person getting a lot of enjoyment out of hacking Cephalo's script to pieces :)

I'd definately be interested in seeing some of the changes you've come up with, and I'd be happy to share my own. I'm particularly interested in SevenSpirits' (no relation BTW :) ) plate tectonics modification and SlighlyMad's hemisphere logic, even if it's not perfect :)

I have modifide plate creation to make landmass generation highly unpredictable (not always the same number of plates, not always even distribution) and reduce landmasses at the poles (pre-sinking of plates that 'touch' the top & bottom rows of the map). I've added climate based terrain (quite a bit more to that than just the mapscript though) and a bunch of other very minor tweaks.
 
Reading this just triggered a thought.
How about a chance that some of your rivers are actually underground rivers, rather than Nile-esque rivers? And related, perhaps the underground rivers have a chance of seeding 1-tile oasis and lake tiles?

This is a difficult problem since the rivers are generated from the hightmap. The only way to have longer rivers would be to have them go uphill sometimes, which is not really in line with this map script. Another problem is, the civ graphics do not allow river outflows from a lake, and since lakes can't overflow, rivers end when they hit them instead of continuing. The reason that rivers appear often in the desert is because deserts are often on the very largest continents, where there might be little rain, but the watershed is huge. Just imagine them as small rivers. I've gotten used to the way the system works and I like it. It does help to break up what can sometimes be a very large desert.
 
Here's the code I modified for hemisphere logic. Like I said, it's not at all perfect, and there's probably a much better way to do it, but it was a simple hack. I only implemented it for the height map, not the techtonics, as I ran into some problems there, and I sort of like it this way better since it's much less predictable. It's not a perfect split all of the time, but it is enough of the time for me. It also doesn't work with Duel maps, as it loses too much from the split, and there's not enough space to place all the peaks.

This is just a modification of SevenSpirits' code, above:
Code:
        xGridPoints  = (self.mapWidth/self.chunkSize) - 2
        yGridPoints  = (self.mapHeight/self.chunkSize) - 1 #we want to skip 1 around each side
        if xGridPoints < 5:
            errorString = "Map too small"
            raise ValueError,errorString
        #print "peak bounds: " + str(xGridPoints) + "," + str(yGridPoints)
        while peaksPlaced < numberOfPeaks:
            randomX = int(xGridPoints * PWRand.random()) + 1
            randomY = int(yGridPoints * PWRand.random()) + 1
            #print "trying peak " + str(randomX) + "," + str(randomY)
            if (randomX < ((xGridPoints / 2) - 1) or randomX > ((xGridPoints / 2) + 1)):
                i = self.GetIndex(randomX*self.chunkSize,randomY*self.chunkSize)
                #print "accepted"
                if self.map[i] == 0.0:
                    self.map[i] = 1.0
                    peaksPlaced += 1
                    #print "placed " + str(peaksPlaced) + " of " + str(numberOfPeaks)
 
Interesting, I took a completely different approach and 'carved' two random canyon-like paths up the heightmap by adding this pass after the 'midpoint displacement' passes. It's random enough to be hard to predict and it can create things like an inverted 'Y' or an 'X' pattern. At the same time is runs a subtractive noise over the entire heightmap with the effect being stronger closer to the poles. This helps break-up landmasses away from the equator without removing them completely. Being pre-tectonics it's not blatantly obvious so having your code before tectonics isn't really a bad thing.

Code:
        long1 = PWRand.randint(0,self.mapWidth)
        long2 = long1 + (self.mapWidth * 0.5)

        if long2 > self.mapWidth:
            long2 = long2 - self.mapWidth

        for y in range(0,self.mapHeight,1):
            biasPole = abs((self.mapHeight * 0.5) - y) / (self.mapHeight * 0.5)
            long1 = PWRand.randint(long1 - 1,long1 + 1)
            long2 = PWRand.randint(long2 - 1,long2 + 1)
            for x in range(0,self.mapWidth,1):
                i = self.GetIndex(x,y)
                if PWRand.random() < biasPole:
                    self.map[i] *= PWRand.random() * 0.5 + 0.25
                if x == long1 or x == long2:
                    for xx in range(x - 6,x + 6,1):
                        #Subtractive noise along simulated oceanic canyons
                        ii = self.GetIndex(xx,y)
                        if abs(xx - x) < 1:
                            self.map[ii] = 0
                        elif abs(xx - x) < 4:
                            self.map[ii] *= PWRand.random() * 0.5
                        else:
                            self.map[ii] *= PWRand.random()
 
Ooh, that's a much more interesting approach! I guess the purpose of mine was specifically to be more predictable, although in practice it isn't really anyways, and I'm noticing that it sometimes creates a pangea on one side and just scattered islands on the other (sort of like big & small).

A more interesting approach might be to take your "canyon carving" code, but have it work from a set start and end point, while making the path between them randomized. This would add more predictability to the split, while still avoiding perfectly straight lines.

edit: wait a second, that's more or less exactly what you're doing there, isn't it? I have to play with this more tonight!
 
I am very amused right now. :lol:

The day before discovering this map script, I was trying to mod Big and Small so that rather than use the more predictable hemispheres logic for making multiple continents (like Hemispheres does, obviously, not Big and Small itself), it would create a more random and unpredictable water barrier from north to south. Basically, the same idea as the underwater canyons here, but modifying actual terrain types (land -> water) instead of a heightmap.

I finally got it to work and it was pretty ugly. So I decided to come here and see if there were any good map scripts that could satisfy my hunger. What do you know!

I'm going to try out both of these modifications.
 
The start & end points are random, it picks one start (long1) then puts the second point 50% of the mapwitdh away them works it's way up the map shifting the x point +/- 1. So the only known factor is that you'll have two starting points evenly spaced, God only knows how they'll end up though :)

Where you used hemispheres here, I used them (sort of) in the plate tectonics. I place more plates initially then randomly select one region of the map and loop through those plots removing 25% of the plates. This results in less detailed plates in part of the map which can then translate to large landmasses or large oceans. But I also did this in a random fashion so sometimes it doesn't create any extra plates and doesn't remove any. The regions themselves are staggered blocks of tiles of various sizes so as not to create a 'big and small' type of map every time, sometimes the 'big' plates are in the center of the map, sometimes they're off in a corner. Unfortunately, it's a little sloppy and needs some tweaking, here's the code though if you want to play with it. This is the entire PerformaTectonics() function and include the polar plates code I worte to reduce landmasses near the poles a little:

Code:
    def PerformTectonics(self):
        self.plateMap = array('i')
        doneMap = array('b') #use a little extra memory to speed this operation up
        #initialize map with zeros
        for i in range(0,self.mapHeight*self.mapWidth):
            self.plateMap.append(0)
            doneMap.append(False)
        
        #seed plates
        randomPlates = PWRand.randint(3,5)
        numberOfPlates = self.mapWidth / randomPlates

        randomRegions = True

        topGap = int(self.mapHeight * (1.0 - self.polarGap * 0.5))
        botGap = int(self.mapHeight * self.polarGap)

        #The regions work by defining their portion of the map and removing plates
        #in those regions.

        #Default plate placement
        for x in range(1,numberOfPlates + 1):
            i = PWRand.randint(0,self.mapWidth*self.mapHeight - 1)
            if self.plateMap[i] == 0:
                self.plateMap[i] = x

        if randomRegions == True:
            regionSelect = PWRand.randint(1,3)
            if regionSelect < 2:
                #Western Region
                iSouthY = int(botGap)
                iNorthY = int(topGap) - 1
                iHeight = iNorthY - iSouthY + 1
                iWestX = int(self.mapWidth * 0.1)
                iEastX = int(self.mapWidth * 0.4) - 1
                iWidth = iEastX - iWestX + 1
            elif regionSelect < 3:
                #Eastern Region
                iSouthY = int(botGap)
                iNorthY = int(topGap) - 1
                iHeight = iNorthY - iSouthY + 1
                iWestX = int(self.mapWidth * 0.6)
                iEastX = int(self.mapWidth * 0.9) - 1
                iWidth = iEastX - iWestX + 1
            else:
                #Equatorial Region
                iSouthY = int(self.mapHeight * 0.40)
                iNorthY = int(self.mapHeight * 0.60) - 1
                iHeight = iNorthY - iSouthY + 1
                iWestX = 0
                iEastX = self.mapWidth - 1
                iWidth = iEastX - iWestX + 1

            for y in range(iSouthY,iNorthY):
                for x in range(iWestX,iEastX):
                    i = self.GetIndex(x,y)
                    if self.plateMap[i] != 0 and PWRand.random() < 0.25:
                        self.plateMap[i] = 0

        #grow plates
        doneMapFull = False
        while not doneMapFull:
            doneMapFull = True
            for y in range(0,self.mapHeight):
                for x in range(0,self.mapWidth):
                    i = self.GetIndex(x,y)
                    if self.plateMap[i] != 0 and doneMap[i] == False:
                        up = self.GetIndex(x,y-1)
                        down = self.GetIndex(x,y+1)
                        left = self.GetIndex(x-1,y)
                        right = self.GetIndex(x+1,y)
                        done = True
                        if self.plateMap[up] == 0:
                            done = False
                            if PWRand.random() < .5:
                                self.plateMap[up] = self.plateMap[i]
                        if self.plateMap[down] == 0:
                            done = False
                            if PWRand.random() < .5:
                                self.plateMap[down] = self.plateMap[i]
                        if self.plateMap[left] == 0:
                            done = False
                            if PWRand.random() < .5:
                                self.plateMap[left] = self.plateMap[i]
                        if self.plateMap[right] == 0:
                            done = False
                            if PWRand.random() < .5:
                                self.plateMap[right] = self.plateMap[i]
                        if done == True:
                            doneMap[i] = True
                        else:
                            doneMapFull = False
                            
        #Stagger the plates somewhat to add interest
        for iPlate in range(1,numberOfPlates + 1):
            polarPlate = False

            #Bottom of map
            for y in range (0,botGap):
                for x in range(0,self.mapWidth):
                    i = self.GetIndex(x,y)
                    if self.plateMap[i] == iPlate:
                        polarPlate = True

            #Top of map
            for y in range (0,topGap):
                for x in range(0,self.mapWidth):
                    i = self.GetIndex(x,y)
                    if self.plateMap[i] == iPlate:
                        polarPlate = True

            adjPlate = PWRand.random() * 0.5 + 0.5

            for i in range(0,self.mapHeight*self.mapWidth):
                if self.plateMap[i] == iPlate:
                    if polarPlate == False:
                        self.map[i] += adjPlate
                    else:
                        self.map[i] -= adjPlate
                            
        #Now that the plates are grown, we must decide how the plate boundaries
        #will effect our map. Basically, plots away from plate boundaries will
        #cause some sinking, while plots closer to them while rise. After
        #multiplying, the main heightmap will be re-normalized.
        sinkValue = 1.5
        peakValue = 2.0
        searchRadius = 4
        self.influMap = array('d')
        #initialize map with sinkValue
        for i in range(0,self.mapHeight*self.mapWidth):
            self.influMap.append(sinkValue)

        for y in range(self.mapHeight):
            for x in range(self.mapWidth):
                distance = self.FindDistanceToPlateBoundary(x,y,searchRadius)
                i = self.GetIndex(x,y)
                if distance == 0.0:
                    #not found in search radius
                    self.influMap[i] = sinkValue
                else:
                    self.influMap[i] = self.GetInfluFromDistance(sinkValue,peakValue,searchRadius,distance)

        #next step is to multiply the influence map by the original heightmap
        for y in range(self.mapHeight):
            for x in range (self.mapWidth):
                i = self.GetIndex(x,y)
                self.map[i] *= self.influMap[i]
                            
        return

As you can see it's a work in progress, I've reduce and simplified the regions to three (east, west and equatorial) to make them more obvious in testing. I'd have to dig up the region code with more complex regions when I get home, it's burried there somewhere. I've had mixed results with this, the 'polar plates' code works very well but the regions have been giving me almost too much variety ranging from really crappy results to really, really good results.

Edit: Quick note, I have self.polarGap defined in the heightmap generation, you can replace them with values around 0.2 or define it yourself. COme to think of it, I think those values were used in my other code from the previous post... nope, nevermind :)
 
Top Bottom