Totestra: A new PerfectWorld2 fork

What a great script! It is the only script that I use for singleplayer games now.

The problem is that if I try to play LAN games, the generated map is absent of trees and ice. I couldn't find any service tags on the maps (probably because of all the missing ice). It still happens if I create a LAN game just for myself and computer opponents: the trees are still missing. Is there anything I can do to fix this? I would love to play with this script with my friends!

Thank you.

edit: the used build is 3.1.9.0 (the most up-to-date), with only custom assets being Blue Marble. I found this error while playing the most excellent K-MOD but it happens on regular plain BTS. It also happens on DIRECT IP CONNECT. It does not effect hot seat games. Just to be clear: ALL the created maps for LAN games are effected (for me atleast).
 
With vanilla Civ4 we've been having issues with network games giving us out of sync (OOS) errors at the very beginning of the game. Once, we did an online game, had an OOS, saved it, and reloaded it, only to discover all of the AI players disappeared.

Our current workaround is for me to generate and save a bunch of single player maps, put the maps in PublicMaps, then just play one of those maps over multiplayer.

There also appears to be an issue with regenerated maps having multiple service tags in them.

- Sam
 
I understand that you probably are not going to update the script but I found a bug: a totally flat map generated. No hills or peaks outside the starting plots. Service tag: ee4014473f0b7a912a22b.

I feel kinda dumb for playing up to liberalism before realising that something is missing! And I even generated it with a rocky setting! :king:
 
What a great script! It is the only script that I use for singleplayer games now.

The problem is that if I try to play LAN games, the generated map is absent of trees and ice. I couldn't find any service tags on the maps (probably because of all the missing ice). It still happens if I create a LAN game just for myself and computer opponents: the trees are still missing. Is there anything I can do to fix this? I would love to play with this script with my friends!

I hit this bug earlier today on a Direct IP game. (I was surprised, and pleased, to see that the script worked at all given the provided instructions to generate a map in SP and save it.) I had Python logging on, which easily showed what happened.

Here's the trace:
Code:
ERR: Python function addFeatures failed, module Totestra
Traceback (most recent call last):

  File "Totestra", line 6226, in addFeatures

  File "Totestra", line 6303, in createIce

AttributeError: MapConstants instance has no attribute 'serviceString'
ERR: Python function addFeatures failed, module Totestra

Line 6303 is "print "SERVICE TAG: " + mc.serviceString # Always log it, of course"; tracing the creation of mc.serviceString leads us to line 935, in class PythonRandom. Because we're in a MP game, we can't use the Python RNG, we have to use the game one. And that branch of the code doesn't set up the service tag properly, explaining why there's no service tag in these created maps. It also causes the creation of ice (where the service tag is placed) to fail, and thus the function which creates forests dies early too. Hence the observed issues.

It's also worth noting that this area (lines 927-935) has mixed tabs and spaces on individual lines. My understanding of Python's behavior was that it is supposed to reject such files as the unholy abominations that they are, but evidently that didn't happen here as the code does execute. Either way it's a bug that should be fixed up.

I'm trying to patch the issue myself locally now; I may report back later if I succeed. It should be a quick fix for the author though, who presumably knows his code much better than I do!
 
The simple change of making the service tag generation unconditional seems to have done the job nicely. I also investigated some repeated complaints about failure to place BONUS_DRAMA, BONUS_MUSIC, and BONUS_MOVIES (none of which are actually valid to place on the map proper). The bonus code doesn't seem to check that these aren't valid before proceeding ahead and doing something with them anyway. It's pretty complicated code and things seem OK anyway (it only fails to place 1 of each), so I don't think this is worth fixing at the moment.

A ZIP file containing the fixed script and a diff is attached. I claim no copyright on this simple bug fix.

Thanks to both Rich and Sam for their work on this script. It generates some really nice maps, and the configurability makes it even better.
 

Attachments

  • TotestraLANFix.zip
    53.9 KB · Views: 239
The simple change of making the service tag generation unconditional seems to have done the job nicely.

Never say never.

Based on these bug reports, and in light of Doctor anything-but-a-Noob's [1] fix, I have applied a one-line fix to the map generator which always initializes serviceString for the map object. The service tag is too big of a spoiler for a multiplayer game, IMO, so I just made the service tag string in multi player "MP No Tag".

Keep in mind I can't actually test this fix, since my buddy's computer is an antique with some networking/whatever bug making MP require convoluted workarounds, but it should do the job.

http://civ4.vk.tj/

As an aside, I myself fixed someone else's bug: I fixed issues Legends of Ancient Arabia (LoAA) has with randomly generated maps: http://samiam.org/Civ4/Arabia.html

Sampo: I'm too busy playing a random map with LoAA to look at your issue right now. :D

- Sam

[1] It is impossible to both be a noob and know how to make a correct "diff", like what Doctor anything-but-a-Noob had in his zip file. Case closed.
 
Now that I have finished my first random map with Legends of Ancient Arabia (LoAA), I would like to post a brief review of it before going back to baby sitting Totestra (see below for my Totestra help).

TL;DR: Download LoAA. Download my fix at http://samiam.org/Civ4/Arabia.html if you want to play random maps. You will love it, up until the endgame.

Update: Long review moved to my blog; read it at http://samiam.org/blog/20120611.html

I understand that you probably are not going to update the script but I found a bug: a totally flat map generated. No hills or peaks outside the starting plots. Service tag: ee4014473f0b7a912a22b.

Yes, I have recreated this map (after spending an hour writing a service tag decoder) and, yes, it indeed doesn't have any mountains. Amazing; I've never seen a map like that. Perhaps the vertical map ratio makes these kinds of maps more likely.

I wouldn't call this a bug, it's more a statistical anomaly: Once in a blue moon, the height maps are smooth enough to not have mountains. It goes back to "if you don't like the map generated, generate another map" adage of random maps.

I have verified that lots of other maps made with the exact same parameters indeed have lots of mountains.

- Sam
 
Talk about a small probability!

Thanks for the quick replies and help. I really have to give the LoAA a chance. The LoAA thread is full of upraise toward it!

Now go enjoy CIV!
 
I tried this script for a map larger than the standard Huge, and I got a bizarre outcome...
The map generated and displayed, but towards the bottom and right edges of the map, it repeated itself, so that I ended up with the same identical continents in the northern hemisphere as in the extreme southern, and the same thing happened in the extreme east.
Just FYI. I wish I'd have saved a screenshot of that, but I didn't. I was testing mapscripts with my mod and if they didn't work I just deleted them.
 
Hey, I remember you!

http://forums.civfanatics.com/showpost.php?p=11522649&postcount=3

I am pleased that you are actually trying to make a Civ4 mod! However, please keep in mind:

  • I asked for service tags. I didn't see one in your posting.
  • That was a rather grouchy comment that you just delete map scripts you don't like from your mod

Listen, there's a reason why the code has a "maxWidth" and "maxHeight" and yes, randomly hacking of that will cause weird things to happen. "max" means, well, maximum and there was, as you discovered, a reason I capped the map size to it. Don't just hack randomly; study the code and understand why it works the way it does. Patience, grasshopper.

If you want an extra huge map, you will need to make the underlying height map bigger; one way to do this is to increase the Continent amount (IslandFactor in the source code).

- Sam
 
[*]I asked for service tags. I didn't see one in your posting.
That's because I wasn't asking for your help, hence the Just FYI.
[*]That was a rather grouchy comment that you just delete map scripts you don't like from your mod
Not at all. I tested a great number of map scripts, if they didn't work with the mod, why would I keep them? There's nothing mean/grouchy in that comment at all.
Listen, there's a reason why the code has a "maxWidth" and "maxHeight" and yes, randomly hacking of that will cause weird things to happen. "max" means, well, maximum and there was, as you discovered, a reason I capped the map size to it. Don't just hack randomly; study the code and understand why it works the way it does. Patience, grasshopper.
I wasn't randomly hacking, just testing your map script as-is with my mod, and got a strange result that I thought you would perhaps like to know about. I didn't even look at the code and wasn't aware that there was a cap. I did have the sizes set to what I believed were the correct values for the actual map size I was generating, though perhaps I screwed that up - I'll have to try again just to verify that, I suppose.
I also like the results I see from this script on the normal map sizes better than just about any other script, so once I actually try to dig deeper than just very quickly generating a few random maps to see the results, I'm sure it'll end up in the mod.
 
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):

Spoiler :

Code:
        heightmap_size_factor = [B]3[/B] + 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:

Spoiler :

Code:
        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:

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:         ([B]42,28[/B]),
                WorldSizeTypes.WORLDSIZE_HUGE:          ([B]54,36[/B])
    }


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; this should never be altered:

Code:
    # 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.

Also, I've made a version of Totestra that will make up to 288x192 maps by increasing hmMaxGrain to 32 and putting a cap on the other values (fixed 3:2 ratio; patience and island amount not adjustable).

It takes this side of forever to make a 288x192 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). For people who are curious, it's called qTotestraHUGE.py and it's at the usual place:

http://civ4.vk.tj
 
Thanks vkjt, that will come in handy when I get back to it.

You did mention MAFs though, perhaps you can help me right now with a question regarding that. I was under the impression that MAFs were limited to 32-bit computers with low amounts of RAM. I've got a 64-bit system with 8GB of RAM myself and have never run into one running XXL Mod's Giant maps and 34-50 civs. Can you (or someone else for that matter) verify that? I know it's dependent on how much stuff a mod adds, but just with vanilla BtS, Giant XXL Mod maps, and 50 civs, I've had zero.

That's pretty much the focus of my mod, 34-50 civs and Giant maps (and yes they do take a hell of a long time to generate). I also get the horizontal bars in the maps, but anything larger than Huge will sometimes get them IME, and while they are ugly as sin, they've never hindered anything for me otherwise.

That reminds me of another problem I noticed - no map script can place 50 civs on a map very well, unless you make the maps even larger, which is something I don't want to do, so I'll likely have to rewrite the civ-placement portion. The mapscript that did the best job was PerfectMongoose, but it still wasn't good enough and failed at the task about half the time. I'm not 100% sure how many civs I'll be starting with though, so it may not come to that especially with Revolutions, which I do plan to add.
 
Since people keep asking about making extra huge maps with Perfect World/Totestra, I have made a technical document answering their question (as well as a special version of Totestra for making extra-huge maps):

http://samiam.org/Civ4/HugeMap.html

Now, back to playing my 76x60 map.
 
"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."

hmmm, stringy continents ...

Often when I choose "a lot of islands" I get them connected by strings of land, ie. no islands in a gameplay point of view ... with "few" the result is more compact, but most land is concentrated in the 2 biggest continents (first in list of old&new world), those 2 are too big.

I toyed around with the biggestSize/totalLand ratio (down to 0.5), got really many meteors, used the centralysation and the older chokepoint method ... now there are several islands, good, but they all need caravels to meet (minmeteorsize=6) :(

I don't mind to start alone or altogether now and then, but feel the most interesting situation is underrepresented: start with 1-3 direct neighbours & see already the land/other coast over the channel (maybe) on different sides, meet there 2-3 neighbours and after caravels the rest.

Any ideas how to make galleys more useful?
 
Any ideas how to make galleys more useful?

Well, we can make Lateens [1] more useful by making the coast bigger. Let's look at this code which makes ocean next to a landmass coast. It looks something like this:

Code:
if self.plotMap[i] == mc.OCEAN:
                    for direction in range (1,9,1):
                        xx,yy = GetXYFromDirection(x,y,direction)
                        ii = GetIndex(xx,yy)
                        if ii == -1:
                            continue
                        if self.plotMap[ii] != mc.OCEAN:
                            self.terrainMap[i] = mc.COAST

We can make the coast bigger by changing that to look something like this:

Code:
COAST_SIZE = 4

if self.plotMap[i] == mc.OCEAN:
		    for xx in range(x - COAST_SIZE,x + COAST_SIZE + 1):
			for yy in range(y - COAST_SIZE, y + COAST_SIZE + 1):
                            ii = GetIndex(xx,yy)
                            if ii == -1:
                                continue
                            if self.plotMap[ii] != mc.OCEAN:
                                self.terrainMap[i] = mc.COAST

What this change does is increase the size of the coast to convert ocean to coast up to COAST_SIZE squares from the ocean.

I have already made a fork of Totestra that does just this. Look for BigCoast.py and BigCoast.diff here:

http://samiam.org/Civ4/Totestra.html

- Sam

[1] The only way I play Civ4 right now is with the Legends of Ancient Arabia mod, which renames the Galley a "Lateen". It has something to do with the fact I am 1/8 Arabian.
 
Well, I just took the easy way out and added an option to (roughly) double the resources on the map. Attached are two comparison screenshots. There does appear to be something to En Dotter's complaint about there being not too much food on this map; I will look to see how to disable Cephalo's "only this resource on this continent" code which has generated so many complaints over the years.
The rule would be: "Some resources only appear on a single continent."
The question is, is that rule wrong? It's the bArea value in Civ4BonusInfos.xml that controls that behavior.
At least that's how Cephalo interpreted it. Should bArea do something else, or is this ignored by stock mapscripts? Idk..

Cephalo's resource allocation code resulted in a lot of complaints and even prompted FuYu to revamp that code. I would use his changes, but don't have permission from him in writing to do so.
I didn't "revamp" that part of the code at all, I just tweaked that starting bonus placement code to allow resources on the "wrong" continent too, my most pressing concern when touching that part of the code was however the frequent placement of multiple stone and marble in starting locations, which I disliked and therefore disabled.

On a different note, I claim no ownership, especially not by any kind of copyright law, of anything I made available in these forums or elsewhere on the internet, everyone can take what they want and do what he want with it.
Telling me about it would be nice but is not required either.
In other words: Yuo didn't need my permission, but you definitely have it now.
 
Top Bottom