Now that I have finished Totestra, let me briefly summarize how Perfect World/Totestra makes a map. Here is the "main loop" which does the majority of the map rendering in Totestra:
Code:
def generatePlotTypes():
# Core height map generator
gc = CyGlobalContext()
mmap = gc.getMap()
mc.width = mmap.getGridWidth()
mc.height = mmap.getGridHeight()
mc.minimumMeteorSize = (1 + int(round(float(mc.hmWidth)/float(mc.width)))) * 3
PRand.seed()
hm.performTectonics()
hm.generateHeightMap()
hm.combineMaps()
hm.calculateSeaLevel()
hm.fillInLakes()
pb.breakPangaeas()
## hm.Erode()
## hm.printHeightMap()
hm.rotateMap()
hm.addWaterBands()
## hm.printHeightMap()
cm.createClimateMaps()
sm.initialize()
rm.generateRiverMap()
(Note that, in Python, lines that begin with '#' are ignored. So Cephalo's code doesn't actually perform erosion; he decided he didn't like the way it looks)
To understand Perfect World's code, an important idea to understand is the "height map". This is a square grid of numbers; each square in the grid has a number between 0 and 1 that represents the height at that point. It represents, if you will, a sandbox where a given point in the sandbox has a level of sand.
What Perfect World does is perform simulated plate tectonics to this abstract height map which doesn't have any real water or land yet. It then adds water to the map; the amount of water added depends on the "ocean level" setting on Totestra. PW/Totestra then throws simulated meteors at the land (the simulated meteor in Cephalo's code acts more like a variable sized circular stamp, actually) in an attempt to break up large land masses (this is what pb.breakPangaeas() does), then Totestra performs some code I wrote which performs a circular rotate on the height map. I do this rotate so continents are less likely to be split at the international date line (the edge of the map where it wraps).
After rotating the map, Cephalo's code does a lot of simulated weather to determine whether a given square should be a desert, plains, grassland, with a river, and so on. All of this information is combined and finally converted in to a Civ4-compatible map.
Cephalo feels that just putting hills once an elevation reaches a certain value, followed by putting mountains at an even higher elevation doesn't make sense for a Civilization map, so his code determines the altitude change and adds hills and mountains based on that information.
At the default "islands" and "map ratio" settings for Totestra, a 144x96 height map is generated. This is scaled down using ShrinkMap() in to the desired size. ShrinkMap() only scales down; it does not effectively scale up, so the maximum size of a default map is 144x96.
The "islands" ("Continent amount") option in Totestra increases the size of the underlying height map. This results in the map having more islands, since the tectonic plates on the height map stay the same size, and the map ends up having more plates on it. This is why it takes more time for Totestra to make a map with more islands on it.
"map ratio" not only changes the size of the resulting map, it also scales the height map as needed so that the land forms on the final map continue to look natural.
Cephalo goes in to a lot of detail explaining what Perfect World does in the Perfect World thread.
I hope this information gives people who wish to continue making changes to Perfect World/Totestra guidance on where to start.
- Sam