Sam Trenholme's webpage
Support this website or listen to my music

Totestra

Making extra-huge maps

One question I've been seeing a lot on the Civ fanatics forums is how to make extra-extra huge maps with Totestra (or Perfect World).

Before making a really huge map, the first thing to consider is this: Will we be playing Civ4 on a computer powerful enough to handle an extra huge map? Ultra-huge maps are slow in Civ4; an overclocked Ivy Bridge Core i7 is suggested if playing them. They are buggy in Civ4: There are ugly horizontal bands when the maps are made too big. They are more prone to memory allocation failures.

If one insists on an extra huge map, it's not trivial to change Totestra to accommodate these maps. It's not a simple matter of making the map bigger; the underlying height map also has to be altered.

There are a few ways to get an extra-huge PerfectWorld map:

  • PerfectMongoose, a PerfectWorld fork, has two sizes bigger than huge when played in the Mongoose mod.
  • I have a fork of Totestra, qTotestraHUGE.py, that can make maps up to 288x192 in size. There's also a diff file showing what is changed.
  • I recently posted technical details on how to change Totestra to have bigger maps. I'll include the contents of that post here.

In order to make maps bigger than the huge size, hmWidth and hmHeight need to be adjusted. Here is the relevant code that needs to be adjusted (selectionID in this code is a number between 0 and 3, depending on the island factor/continent amount chosen by the user, since making the height map bigger without changing the plate amount results in maps with more islands as well as more stringy continents):

        heightmap_size_factor = 3 + selectionID
        self.hmWidth  = (self.hmMaxGrain * self.ratioX * 
                         heightmap_size_factor)
        self.hmHeight = (self.hmMaxGrain * self.ratioY * 
                         heightmap_size_factor) + 1

        # These are expressed in 4x4 "Grid" units
        self.maxMapWidth = int(self.hmWidth / 4)
        self.maxMapHeight = int(self.hmHeight / 4)
By changing the number "3" above to a bigger number, it becomes possible to make bigger maps. For example, to make a "Planetary Mongoose" sized map (216 x 144), we would probably make the code look like this:
        heightmap_size_factor = 5 + selectionID
        if heightmap_size_factor > 6: # Cap
            heightmap_size_factor = 6
        self.hmWidth  = (self.hmMaxGrain * self.ratioX * 
                         heightmap_size_factor)
        self.hmHeight = (self.hmMaxGrain * self.ratioY * 
                         heightmap_size_factor) + 1

        # These are expressed in 4x4 "Grid" units
        self.maxMapWidth = int(self.hmWidth / 4)
        self.maxMapHeight = int(self.hmHeight / 4)
As well as this code:
def getGridSize(argsList):
    grid_sizes = { # Super size me!
                WorldSizeTypes.WORLDSIZE_DUEL:          (20,13),
                WorldSizeTypes.WORLDSIZE_TINY:          (24,16),
                WorldSizeTypes.WORLDSIZE_SMALL:         (30,20),
                WorldSizeTypes.WORLDSIZE_STANDARD:      (36,24),
                WorldSizeTypes.WORLDSIZE_LARGE:         (42,28),
                WorldSizeTypes.WORLDSIZE_HUGE:          (54,36)
    }
Continents and islands will be more stringy, yes, but boy will the map be huge.

Note that there is code to cap the map size; the following code should never be altered:

    # The map generator goes in to an infinite loop if the 
    # output map is bigger than (hmWidth, hmHeight)
    if(sizex > mc.maxMapWidth):
        sizex = mc.maxMapWidth
    if(sizey > mc.maxMapHeight):
        sizey = mc.maxMapHeight
    mc.serviceFlags |= sizey # Service Tag
    return (sizex, sizey)
Other values in the code are:
  • hmMaxGrain: One of Cephalo's magic values. This is 16; can be 8 if you want a lot of islands and really really stringy continents. Making it 32 can put Totestra in an infinite loop. Making it not a power of 2 breaks things.
  • ratioX: A value between 2 and 3 for most maps (7 for "ringworld" maps). By default, 3.
  • ratioY: 2 for most maps. 3 for the tall map and the extra-large map; 1 for the "ringworld" map.

It takes this side of forever to make an extra-huge map; it is really slow and acts buggy in Civ4. There are ugly horizontal bands on the map and I'm sure trying to play an actual game with such a map will quickly cause one to hit a memory allocation failure (MAF).

Civ4 is a very flexible engine and it's possible to play maps in it far bigger than anything Civ3 or Civ2 could ever work with.