[Map Script] PerfectWorld.py

Something I have noticed recently is how starting locations tend to have abundant (perhaps over-abundant) food resources, but the surrounding terrain is essentially devoid of anything. Is this intentional?

The starting plot normalizer will give food and other resources to make up for an inferior starting position. At the beginning of the starting area process, I compile a list on every continent of every decent city location. The starting plots are evaluated not only by the local area, but also by which decent city locations you are closest to, and thus more likely to claim. The resources help somewhat, but they don't actually help quite enough. Anytime you start with lot's of resources like that you know you are in for a challange. PW is a really tough map to find fair starting locations, but in 1.09 I think I can say that the horrible, horrible, doomed to eat snow and ice forever starting locations are gone. :D

looking over the thread I think that version 1.07 might just be exactly what I'm looking for ... is it still around?

No, I killed it off. It had a few other bugs as well. I took out that hemispheres code because I felt it was too darn predictable, and both the east and west continents always had a rectangular, very unnatural looking appearance. I suppose I could put it back in as an option for a later version. I know that some people like that since it mimicks earth somewhat. For bulkier continents, try boosting the land percentage, the pangaeas formed will likely be broken up by lots of meteors and might take a little longer to generate, but it might give you what you are looking for.

Is that "cluster" setting tunable somewhere? For instance, if I wanted to turn the clustering of resources off, can I do it?

Yes! In the XML file Civ4BonusInfos.xml, there is a iGroupRange and a iGroupRand tag. Bonuses will have an iGrouRand chance to appear within iGroupRange tiles of the original placement. The bArea tag controls whether the bonus should appear on one continent only. In PW that means one main continent and maybe some other smaller ones that don't have other resources already.
 
No, I killed it off. It had a few other bugs as well. I took out that hemispheres code because I felt it was too darn predictable, and both the east and west continents always had a rectangular, very unnatural looking appearance. I suppose I could put it back in as an option for a later version. I know that some people like that since it mimicks earth somewhat.

Yeah, that's what I'm looking for, earth-like. But not actual variations on earth like the terra and earth type scripts seem to do.

A while back in the thread, Seven05 posted some code for doing a hemisphere:

http://forums.civfanatics.com/showpost.php?p=6128001&postcount=157

But I can't figure out where in the script it ought to go. If I wanted to use that, where would I put it?
 
But I can't figure out where in the script it ought to go. If I wanted to use that, where would I put it?

Good news! It looks like I left the function in there and simply commented out the call. Find this line:

# self.SinkMiddle()

and uncomment it out again. This should do it, although the continent might still connect near the 'date line'. To help prevent that, find this line:

x = PWRand.randint(0,xChunks - 1) * self.chunkSize

and change it to:

x = PWRand.randint(1,xChunks - 2) * self.chunkSize
 
Wow!!!

It didn't do quite what I expected, but I think I like it even better!

I didn't get earthlike hemispheres, but on this first try the map I got is just amazing. Four very large, bulky continents, some very interesting island chains, and good separation into two zones (with a few large islands in the middle of nowhere).

Absolutely perfect!!

pwexcellentscreenshot1dg2.jpg


Thanks!! This is amazing!!

What I was getting before looked alot like the lower right corner, for the entire map. It looks really neat when it's just one area, but when it covers the map I don't like it. This is much, much, much better.
 
Good news! It looks like I left the function in there and simply commented out the call. Find this line:

# self.SinkMiddle()

and uncomment it out again.

If you just do this part you get the type of maps shown above (which I also love!). But if you do the second part you get giant continents near the south pole. Not sure why. I hope the second part is optional!
 
I guess there is one more thing I'd like to try to do now.

While I was changing the grid sizes, I found these lines:

def getTopLatitude():
"Default is 90. 75 is past the Arctic Circle"
return 80

def getBottomLatitude():
"Default is -90. -75 is past the Antartic Circle"
return -80

What exactly do these lines do if you fiddle with the numbers? Essentially what I want to do is make the southern hemisphere more tropical and the northern hemisphere more temperate - basically to drag the equator line from the middle of the map, to the middle of the south or so. Would these lines help me do that?
 
I guess there is one more thing I'd like to try to do now.

While I was changing the grid sizes, I found these lines:

def getTopLatitude():
"Default is 90. 75 is past the Arctic Circle"
return 80

def getBottomLatitude():
"Default is -90. -75 is past the Antartic Circle"
return -80

What exactly do these lines do if you fiddle with the numbers? Essentially what I want to do is make the southern hemisphere more tropical and the northern hemisphere more temperate - basically to drag the equator line from the middle of the map, to the middle of the south or so. Would these lines help me do that?

No, I think these only actually apply to resource placement. The code you're looking for is in generateTerrainTypes.

tm.GenerateTempMap(80,-80)
rm.GenerateRainMap(80,-80)

You can change these hard coded numbers, but keep in mind that I never have tested any values other than these, and I might have made some assumtions along the way that I shouldn't have. All I can say from this code is that at one time I wanted to be able to handle arbitrary latitudes. Did I succeed? I don't know.
 
I'll have to do a little fiddling, but that does seem to be it. I changed the tm.GenerateTempMap(80,-80) to (70,-90) which more or less seems to have shifted everything south in terms of temperature. Hard to tell when there's no real banding, but on one map I got a desert at the south pole, a few squares even on the very bottom row of tiles. Thanks, I will play around with this and see if I can get something to approximate what I'm looking for.
 
PART-1:
Good news! It looks like I left the function in there and simply commented out the call. Find this line:

# self.SinkMiddle()

and uncomment it out again. This should do it...

PART-2:
although the continent might still connect near the 'date line'. To help prevent that, find this line:

x = PWRand.randint(0,xChunks - 1) * self.chunkSize
and change it to:
x = PWRand.randint(1,xChunks - 2) * self.chunkSize

Cephalo... I started using your "Perfect World" map-script with v1.07... which I liked immensely. However, when you took the Hemispheres out in the new version, I tend to get a lot of "Pangea" type super-continents now... after reading your above comments (and some of the other comments), I experminted with some changes... if I change both Part-1 and Part-2, I indeed get less occurances of Pangeas, but as another person mentioned, those continents tend to "drift south" a bit.

I then went back and ensured only "Part-1" was changed and didn't change "Part-2" and left Part-2 as it is in the current version (without changing as you suggested)... I still get less Pangea-like continents, and now they seem to stay more centered... this was my very first huge map attempt here with ONLY changing "Part-1" in your current Perfect World script, and look what I got... I like it very much!

ModifiedPerfectWorld.jpg


Three distinct continents and some good island chains... a little more centered too! I think I'll leave the script like this!

Thanks for the great work!
 
Well, this part:

x = PWRand.randint(0,xChunks - 1) * self.chunkSize
and change it to:
x = PWRand.randint(1,xChunks - 2) * self.chunkSize

Only prevents the initial altitude peaks from being placed on the 'date line'. Why it would cause continents to drift south boggles my mind.

Whether you use the hemishpere divider or not, the meteors should be effective in taking out any pangaeas. It's no guarantee, but I haven't seen it fail yet.
 
Well, this part:

x = PWRand.randint(0,xChunks - 1) * self.chunkSize
and change it to:
x = PWRand.randint(1,xChunks - 2) * self.chunkSize

Only prevents the initial altitude peaks from being placed on the 'date line'. Why it would cause continents to drift south boggles my mind.

Whether you use the hemishpere divider or not, the meteors should be effective in taking out any pangaeas. It's no guarantee, but I haven't seen it fail yet.
I dunno... but using the "no date line" thingie... wouldn't that cause MORE Pangea-like super-continents, or less continents overall? Correct me if I'm wrong, but you're placing an artificial barrier on the globe that land can't shouldn't appear in (to prevent a land mass from stradling the "date line"). I would think if a continent is allowed to form or float wherever it wants without any artificial barriers you might get more "earth-like" continents.

I dunno... I have no experience with these map scripts, and I simply love the work you've done cephalo. I am curious though... in v1.09 by default this dateline thingy is turned-off... and those of us who liked the "hemispheres" option of 1.07 you're telling us to turn-on or modify two features.

Could you then please explain what the other change does?

...if...
x = PWRand.randint(1,xChunks - 2) * self.chunkSize
...prevents continents from straddling the dateline...

...what does activating...
self.SinkMiddle()
do?
 
The 'problem' with PerfectWorld is that the heightfield is generated a bit more 'naturally' that normal mapscripts with fractal layers. If you dig around a bit you'll see that you have absolutely no control over where continents form, how many form and what their general size or shape will be. Instead, you get a basic heightfield that is then manipulated with plate tectonics. The results are much better landmass shapes in general but almost no control over their creation.

It is possible to have a little bit of each and it's not even that much work. I've taken the default multilayer fractal code and use that to generate a 'fake' plotmap. Then I use that plotmap to modufy the base heightfield prior to performaning plate tectonics, I also use the 'peaks' from that plotmap to seed the 'peaks' used to generate PerfectWorld's midpoint displacement heightfield.

Like I said, it's not very hard to impliment. I add a couple of lines into the generateHeightField() function like this:

Near the top...
Code:
		global plotgen
		self.terraMap = array('d')
		plotgen = BnSMultilayeredFractal()
		self.terraMap = plotgen.generatePlotsByRegion()
		
		for i in range(self.mapWidth * self.mapHeight):
			if self.terraMap[i] == PlotTypes.PLOT_PEAK:
				self.map[i] = 1.00
At the bottom...
Code:
		for i in range(self.mapWidth * self.mapHeight):
			if self.terraMap[i] == PlotTypes.PLOT_OCEAN:
				self.map[i] *= 0.5

This requires pulling the BnSMultilayeredFractal() (Big and Small in this case) function from the appropriate mapscrip and merging it in. The hardest part is getting the map options to work.

Anyway, the last line of code I posted: self.map *= 0.5 controls how strong you want the influence from the fractal map to be. The exampel code isn't a very strong influence as it only take every plot that is water on the fractal map and reduces it by 50% on the heightfield so that land from the fractal map *should* be higher. In cases where I merged more specific mapscript like the Earth2.py script I used much stronger influence like:
Code:
		for i in range(self.mapWidth * self.mapHeight):
			if self.terraMap[i] == PlotTypes.PLOT_OCEAN:
				self.map[i] -= 1.00
			elif self.terraMap[i] == PlotTypes.PLOT_PEAK:
				self.map[i] += 1.00
			elif self.terraMap[i] == PlotTypes.PLOT_HILLS:
				self.map[i] += 0.75
			else:
				self.map[i] += 0.50
With these values I all but eliminate the base heightfield, essentially making it little more than some noise. The purpose of this method is that it lets me take advantage of PerfectWorld climate code which requires the underlying heightfield to work.

So, if you are looking for more control over the continent placement and makup of PerfectWorld maps this is one way to get that. Otherwise you just kind of need to accept the fact that PerfectWorld's creation process is highly random and not easily controlled. Personally, I prefer the unpredictable nature of PerfectWorld maps over the hard rules of the fractal maps but not many players feel the same way :)

Edit: I've attached screenshots showing example maps in this post, that is using hemispheres with two different sets of options.
 
...if...
x = PWRand.randint(1,xChunks - 2) * self.chunkSize
...prevents continents from straddling the dateline...

...what does activating...
self.SinkMiddle()
do?

The first example attempts to prevent land from starting it's growth on the date line, or where x == 0. The second example actually sinks the middle after the heightmap is generated, and is therefore more reliable in it's intended effect. I could have written a similar function called SinkDateline, but I figured that by not placing the initial peaks there, it wouldn't connect very often. The scheme really didn't work very well, but I abandoned the whole sinking philosophy once I found a way to target the meteors.

You really should not be getting super-continents with 1.09. Are you really getting those? There should almost never be a continent that is over 70% of the land mass. If you really want to prevent large continents, you might experiment with the function called 'isPangea' (misspelled, I know) Try turning that down to 0.5 from 0.7. The map will likely take longer to generate, but maybe not by too much.
 
You really should not be getting super-continents with 1.09. Are you really getting those? There should almost never be a continent that is over 70% of the land mass. If you really want to prevent large continents, you might experiment with the function called 'isPangea' (misspelled, I know) Try turning that down to 0.5 from 0.7. The map will likely take longer to generate, but maybe not by too much.
Is there a big differance between 1.08 and 1.09 in continent generation? My current game (using 1.08) I have a massive super-continent on a Huge map and one tiny continent...

I've downloaded 1.09 and toyed with map generation, but using 1.08 for my current game, I gat a massive super-continent... which takes up almost all of the land % for the planet (I'd say 70% of the land on this planet is part of the super-continent). It's making navies on this map pretty useless since everybody is on the super continent.

If you tell me you did a major fix between 1.08 and 1.09 I'll be happy... but the last few games I played on 1.07 I never had a map like the one I got using 1.08. Hence my nostalgia for 1.07's code.
 
If you tell me you did a major fix between 1.08 and 1.09 I'll be happy... but the last few games I played on 1.07 I never had a map like the one I got using 1.08. Hence my nostalgia for 1.07's code.

1.07 introduced a bug in starting placement that I really didn't fix until 1.09. You may have noticed that in 1.07 there are almost no coastal starting citys. Also, 1.07 and 1.08 have alot of all tundra starts that I wasn't happy with. Because tundra has one food, my city evaluator saw a city with all tundra as having enough food to support 10 or so pop, which is really very far from the truth since non of those plots can feed themselves, so you can never really work more than 2 tiles or so, rather than the full 20 needed to get 20 food (for 10 pop).

Again, find that isPangea() function, and tweak the percentage of land that constitutes a pangaea. You can probably do some good with that. 70% is just an arbitrary number that I thought up. maybe later I can make a tuning variable for that.
 
:goodjob:

very nice map!

but:

would it be possible to include a script for a fair startpositions and with nearly the same distance/space between the startpositions?

i would like to use the mapskript for MP games.

thx
 
:goodjob:

very nice map!

but:

would it be possible to include a script for a fair startpositions and with nearly the same distance/space between the startpositions?

i would like to use the mapskript for MP games.

thx

Well, I nearly gave myself a stroke trying to get these starting positions as fair as possible over a period of some weeks. For this map, I think this is about the best I can do...

The thing is, this map was never designed to offer a tournament quality MP game. I'm not even sure that it's even possible to find exactly fair starts on most of the maps PW generates. I was thinking more along the lines of a fun exploration phase.

This map should be fine for a fun MP game of civ, but not if your are seeking a real test of skill, only if you are looking for a fun series of events to put together a fun story.
 
Yep, it's a fantastic map for SP, but it's innately imbalanced for MP. Starting positions will often be in sprawling deserts or jungles, or small isolated areas.
 
Back
Top Bottom