[Map Script] Earth Flavour: historically appropriate starting positions

lumpthing

generic lump
Joined
Sep 11, 2004
Messages
781
Location
Lumpinium, England
# FILE: Earth_flavour_mapmod.py
# VERSION: 2.1
# AUTHOR: Nicolas "lumpthing" Holzapfel (but 'see CREDIT' below)
# PURPOSE: Have civs start in regions that match their flavour.
# DISCUSSION: http://forums.civfanatics.com/showthread.php?t=251580
# CREDIT: 90% of the credit for this mod goes to David "dreiche2" Reichert.
# He did all the proper scripting stuff to create his Fall from Heaven flavor
# mod. All I did was take his mod and change the settings (this time for
# standard Earth civs, rather than fantasy civs) until I got something
# that worked reasonably well.

# DESCRIPTION:
# This module can be used in conjunction with other map scripts.
# It has the following effects:
# 1) Civs tend to start in appropriate climates: i.e. Euopean civs start in
# colder regions,
# African civs start in warmer climates
# 2) East Asian civs tend to start close together
# 3) 'New World' civs tend to start close together
# 4) The Portuguese, Dutch, Carthagians, Vikings and Americans are more likely
# to start near the sea (The former four because of unique units or buildings,
# the latter for historical flavour)
# 5) The Khmer are more likely to start close to ivory
# (because of its unique unit)
# Note that this module does not change the map itself, and only uses the
# starting locations
# assigned by the base map script. There will only be a tendency (albeit a
# clear one), no guarantee
# that all the relevant civs have 'flavoury' starting positions. An advantage
# is that this module minimally interfers with what the map scripts does.


# USAGE:
# It is very simple to use this module in a map script of your choice
# (e.g. the default continents script). Just copy this file into the
# <civ4>/PublicMaps folder, and then open the map script file
# (e.g. Continents.py) with a text editor and copy/paste the small code block
# below this paragraph into the script (preferably at the top), and uncomment
# the 'import' line by removing the '#'. Of course you're advised to backup
# the map script and rename your modified version to something like
# "Earth_Flavour_whatever.py" so that you don't confuse the various versions.

## copy below, remove '#' in 'from...import' line.

##############################################################################
# This map script was modified to use the Earth Flavour Map Mod #
# See Earth_flavour_mapmod.py for details #
##############################################################################

#from Earth_flavour_mapmod import normalizeStartingPlotLocations

##############################################################################

## copy above


# COMPATIBILITY
# The flavour module should work with most map scripts. It uses the
# normalizeStartingPlotLocations() function, hence civ does not use its
# default implementation. That means that members of a team are no longer
# placed close together as by default.

# A conflict occurs if the map script itselfs implements
# normalizeStartingPlotLocations(), though only few do. If that's the case
# you can simply remove/comment out the relevant code in the map script,
# although of course you remove any functionality that was implemented there.

# CUSTOMIZATION
# It should be easy to modify the settings to your liking, and add new flavor
# civs. Just look at the code below. Everything relevant happens in
# normalizeStartingPlotLocations().

# VERSION HISTORY
# Version 2.1: Added flood plain preferences for several Middle Eastern civs.
# Increased the Vikings' preference for tundra relative to their preference
# for ocean. Made all Northern European civs prefer tundra.
# Version 2.0: Corrected a bug identified by Seven05. Many major changes:
# Replaced most of the bonus preferences with terrain and feature preferences.
# Version 1.02: Corrected a bug identified by SevenSpirits
# Version 1.02: Corrected a major typo in the usage instructions
# Version 1.01: Added sheep to Russian and Viking bonus preferences, in case
# no tundra starting positions are available


Download here

 
Well, when you select what map script to play the game with, DON'T pick Earth_flavour_mapmod. Use another map script the code of which you have edited, as described in the instructions (see 'USAGE' in the previous post). Remember to remove the # in '#from Earth_flavour...' or nothing will happen.

Let me know if you've done all that already.
 
Very cool!

There are a couple of bugs though. First, in the part you copy and paste into your own file, "Earth_flavour_mapmod.py" needs to be just "Earth_flavour_mapmod".

Second, right below "#ok some code could be more elegant" (hehe) and above "#remaining players" you need to put the following, like this:

Code:
	for pRem in playersToRemove:
		playersLeft.remove(pRem)	
		
	#remaining players
(I put the next line in for indentation reference.)

I'm sure there is a nicer way to do it but that is the quickest fix, without changing the way you are doing anything. Anyway I bet if you look at it you can see what the problem is.

I think that if you change these things it works. At the very least it doesn't cause any more error messages. :)
 
There are a couple of bugs though. First, in the part you copy and paste into your own file, "Earth_flavour_mapmod.py" needs to be just "Earth_flavour_mapmod".

Oh dear, can't believe I didn't notice this. Not like I had the '.py' version in my own edited map scripts. I've uploaded a new version with correct instructions.

Second, right below "#ok some code could be more elegant" (hehe) and above "#remaining players" you need to put the following, like this:

Code:
	for pRem in playersToRemove:
		playersLeft.remove(pRem)	
		
	#remaining players
(I put the next line in for indentation reference.)

I'm sure there is a nicer way to do it but that is the quickest fix, without changing the way you are doing anything. Anyway I bet if you look at it you can see what the problem is.

I think that if you change these things it works. At the very least it doesn't cause any more error messages. :)

Are you sure this makes a difference? I've tested this map script many times and it definitely makes a difference. What kind of error do you think is being caused? The code above is actually dreiche2's, from his original FfH flavor mod. I don't understand it myself so I'm weary of changing it.
 
Here's the problem - the next loop caused an error:

Code:
	#remaining players	
	for Index in range(len(playersLeft)):
		player=cgc.getPlayer(playersLeft[Index])
		player.setStartingPlot(startingPlots[Index],True)
Index out of bounds I think. The only possibility is there were more players left than starting plots.

Given the lazy removal of players, it seems that's the problem. And in fact the lazy removal happens at the beginning of the loop, so the last time through it, the removal won't happen.
 
What kind of error do you think is being caused? The code above is actually dreiche2's, from his original FfH flavor mod. I don't understand it myself so I'm weary of changing it.
SevenSpirits' suggested fix works, without it you can (but not always) get an index out of bounds error when iterating through the list of remaining players the last time. The funny thing is that sometimes even when the script doesn't work you get lucky and some or even most of the civs start in places you would expect based on the rules you have set. However, if you enable logging you'll see that you got and index out of bounds error and the script didn't run.

When it does run, or if you put in the fix suggested by SevenSpirits so it always works, the results are very good. I've changed all of the rules to be based on terrain types (I have a bunch of extra terrain types in my mod) and it works beautifully. One thing I did that you may want to consider is adding rules for civs with unique buildings or units that have very specific requirments. For instance I have added the coastal city preference for civs like the Vikings with a UB that would be worthless if they started inland.

This is really helpful for me, I've always wanted to give civs more unique benefits based on their native climate/terrain but never had a way of ensuring they'd be in the appropriate areas.
 
Thanks for the help and suggestions guys. I changed the log thingy in the script to TRUE but where does the log actually appear? Nothing seems to appear to be in the logs folder.
You have to enable it in your BTS ini file:


; Enable the logging system
LoggingEnabled = 1

Once you've done that you will see a new logs folder created the next time you run the game, it will be in My Documents/My Games/Beyond the Sword. You don't actually need to enable the debugging messages in the script, that will add extra information to the one of the log files (PythonDbg.log) which can be helpful in tracking behavior but the log file you want to see is 'PythonErr.log' (not the one with a '2' in its name). If the script runs without errors this log file will have a size of zero bytes and will be empty if you open it, if it is any larger you can open it and see the trace log of the most recent functions & the problem line numbers. In most cases you'll only need to look at the last function listed since the error is most likely in there, however sometimes the error is caused by feeding bad information to the function and in these cases you can step back in the trace to the previous functions until you find the error.
 
Nice script. I especially like how you organized all the code, making it easier for those of us with extremely limited python ability to add lines for custom civs.
One suggestion, though. Could you implement two additional starting location parameters? Hills and mountains. These would fit in nicely for some custom civs, like the Swiss and Austrians.
 
For settling all civs of one style together, why not use this with a continent map script and have it create appropriately sized continents for each of the civ types? IE, if there are three european civs, create a continent for three civs and place them there.
 
I'm afraid I'm one of the people with extremely limited python ability. The meaty stuff is all dreiche2's, all I did was take his script and add lines for the standard civs, instead of the Fall from Heaven civs in his original script. Molybdeus suggestion is great but implementing it is completely beyond me.

If anyone creates an alternative Earth flavour script (such as Seven05's creation) it'd be great if you could post it here too.
 
I would post my version here but it won't work without the rest of my mod because it uses all of my new terrains. It works though, with one minor error that I had to fix, the civilization name for the holy roman empire was wrong I believe, it should just be CIVILIZATION_HOLY_ROMAN. I just caught that one myself and was coming here to pass it on :)
 
I'm afraid I'm one of the people with extremely limited python ability. The meaty stuff is all dreiche2's, all I did was take his script and add lines for the standard civs, instead of the Fall from Heaven civs in his original script. Molybdeus suggestion is great but implementing it is completely beyond me.

If anyone creates an alternative Earth flavour script (such as Seven05's creation) it'd be great if you could post it here too.

I am pretty bad as well. The real problem is that the terrain generation functions do not create a map for the civs, but instead the map scripts assign civs starting spots after a completely random map is created. You can't tell a terrain generator to make a continent sized for three or four civs. Thus this project would probably involve making a completely new terrain generation function, which is beyond my feeble abilities.
 
I am pretty bad as well. The real problem is that the terrain generation functions do not create a map for the civs, but instead the map scripts assign civs starting spots after a completely random map is created. You can't tell a terrain generator to make a continent sized for three or four civs. Thus this project would probably involve making a completely new terrain generation function, which is beyond my feeble abilities.
True, but wouldn't it be easier to tell the map script to put a higher priority on placing a specific civ near a specified terrain type? That's what I was getting at. It wouldn't necessarily mean the civ always starts on or near that terrain, it would just be more likely to (assuming, of course, the map generated such terrain to begin with).
 
I use terrain almost exclsuively to determine where civs should start. I have a few with rules for specific features like jungles and floodplains but none with resources. However, I think the only reason that works fairly well for me is because I have several new terrains that represent the climate so it's easy for me to define a 'cold climate' or a 'temperate climate' on a map whereas the vanila game can really only diferentiate between very cold and tropical. The original script by Dreiche has examples of using terrains, features and resources (and coastal starts too which are handy).
 
Lumpthing,

I like how this script looks. I think that this could merge very well with the Earth3.py script. At the very least, I hope to be able to assign Old World/New World starting positions for the various civs. If I could do that then add in the terrain scripts from this thread...well, that would be awesome!

I'll get right on it after I finish up those last few tweaks to my Events mod.

And the NextWar mod.

Oh, and I have to go to work for 10 hours tomorrow.

Yep, I'll have this wrapped up by the end of Fiscal '08, no problem. :)
 
Just to give an update on this. I successfully got all the logging stuff to work, and then changed the script to work with base terrains rather than bonuses. Unfortunately this seemed to make it ineffective (but with no errors showing up in the logs). I don't think I'll ever get to the bottom of this mystery without learning python; but if I do that I'll have to stop pretending I'm more interested in my studies than in civ, which is unthinkable.

Yep, I'll have this wrapped up by the end of Fiscal '08, no problem. :)

Heh, well at least this script, such as it is, is at least very simple to mod into another map script. As mentioned in the readme you just need to add the 'import...' line into the main map script.
 
The biggest problem with using terrains (the stock ones anyway) is that the starting plots are already defined before this script runs. On standard maps the terrain types are all mixed up together anyway resulting in very few places with substantially more of one terrain than any other. About the only two that are of any use would be tundra and desert. Now if you combined your original version with the bonuses and then used tundra and desert on some civs and jungles (feature, not a terrain) on others you might be able to influence their position with the cultural group. Of course with the defaults a lot of resources are limited by latitude ranges which can result in impossible pairings like a civ that has a preference for jungles and deer.
 
Top Bottom