Map Script Tutorial????

Before The Dawn

Chieftain
Joined
Nov 15, 2008
Messages
26
Location
Lat=63° 50' 10"N Long=20° 10' 36"O
I have another post her asking for som help. I could have posted this in that one. But the it would dissapear without anyone reading it and this post isn't exactly the same as the first one even if it seams so. That post can be removed by a Moderator if they wishes. But please don't merge this one with the other one.
Does any one have a good Tutorial on how you make map scripts??
One for each of the 3 types(Fractral, MultilayerdFractal and Hinted)
preferably.
If there is diffrence between map scripting in Civ 4, Warlords and BTS please point them out.
Or maby some one could make one???
I've tried reading trough some map scripts (planetgenerator, perfectworld and afew more). But I have a hard time understanding how to remove/add som of the code to suite me and my game playing.
For instance How do I make my units to start on seperate plots(scaterd)?
How do I remove, Jungle, Ice, snow and Desert? Or atleast implement an option to remove all 3 or just 2 or just 1 or none of them?
I don't want to change stuff in the XML files.
I would like to have an option to have bonuses on XX% of plots(All plots, 99%, 75% 50%, 23% of plots and so on)

If you can help but only with one or to things and post the code here pleas include what to import and from where. Example from Perfect World:
Code:
from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil 

from array import array
from random import random,randint,seed
import math
import sys
import operator
import time
It's vital that the import things are included if they doesn't exist in
Code:
import CvUtil
import CvMapGeneratorUtil
A question: What is
Code:
from CvPythonExtensions import *
??? is it the python map? is it a file somewher? I haven't found a file with that name..

Thanks in advance if you can help
And sorry for the new post!
 
Sirian's Guide isn't really a guide in my opinion.
I need something that tells me what this does if I do this and what will hapen if i do that instead of this.

This is not python but as an example it might illustrate what I'm lokking for.
Example: If you take the english word gay and write two sentences like this:
1: I'm Gay
2: I'm Gay
Most people wuold think that I like people of the same gender as me right???
Wrong!
1: I'm indifferent
2: I'm nonchalant
But I could also have been a homosexual,emancipated, open-minded, liberated, cheerful, happy, pleased, fond and insignificant.
That is how many diffrent meenings the word gay has in english.

Another example is this:
Her is continets.py from civ4
Spoiler :
#
# FILE: Continents.py
# AUTHOR: Soren Johnson
# PURPOSE: Global map script - Civ4's default map script
#-----------------------------------------------------------------------------
# Copyright (c) 2004, 2005 Firaxis Games, Inc. All rights reserved.
#-----------------------------------------------------------------------------
#

from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil
from CvMapGeneratorUtil import FractalWorld
from CvMapGeneratorUtil import TerrainGenerator
from CvMapGeneratorUtil import FeatureGenerator

def getDescription():
return "TXT_KEY_MAP_SCRIPT_CONTINENTS_DESCR"

def isAdvancedMap():
"This map should show up in simple mode"
return 0

def generatePlotTypes():
NiTextOut("Setting Plot Types (Python Continents) ...")
fractal_world = FractalWorld()
fractal_world.initFractal(polar = True)
return fractal_world.generatePlotTypes(water_percent=75)

def generateTerrainTypes():
NiTextOut("Generating Terrain (Python Continents) ...")
terraingen = TerrainGenerator()
terrainTypes = terraingen.generateTerrain()
return terrainTypes

def addFeatures():
NiTextOut("Adding Features (Python Continents) ...")
featuregen = FeatureGenerator()
featuregen.addFeatures()
return 0

and here is the continents.py from warlords:
Spoiler :
#
# FILE: Continents.py
# AUTHOR: Soren Johnson
# PURPOSE: Global map script - Civ4's default map script
#-----------------------------------------------------------------------------
# Copyright (c) 2004, 2005 Firaxis Games, Inc. All rights reserved.
#-----------------------------------------------------------------------------
#

from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil
from CvMapGeneratorUtil import FractalWorld
from CvMapGeneratorUtil import TerrainGenerator
from CvMapGeneratorUtil import FeatureGenerator
from CvMapGeneratorUtil import BonusBalancer

balancer = BonusBalancer()

def getDescription():
return "TXT_KEY_MAP_SCRIPT_CONTINENTS_DESCR"

def isAdvancedMap():
"This map should show up in simple mode"
return 0

def getNumCustomMapOptions():
return 2

def getNumHiddenCustomMapOptions():
return 2

def getCustomMapOptionName(argsList):
[iOption] = argsList
option_names = {
0: "TXT_KEY_MAP_WORLD_WRAP",
1: "TXT_KEY_CONCEPT_RESOURCES"
}
translated_text = unicode(CyTranslator().getText(option_names[iOption], ()))
return translated_text

def getNumCustomMapOptionValues(argsList):
[iOption] = argsList
option_values = {
0: 3,
1: 2
}
return option_values[iOption]

def getCustomMapOptionDescAt(argsList):
[iOption, iSelection] = argsList
selection_names = {
0: {
0: "TXT_KEY_MAP_WRAP_FLAT",
1: "TXT_KEY_MAP_WRAP_CYLINDER",
2: "TXT_KEY_MAP_WRAP_TOROID"
},
1: {
0: "TXT_KEY_WORLD_STANDARD",
1: "TXT_KEY_MAP_BALANCED"
}
}
translated_text = unicode(CyTranslator().getText(selection_names[iOption][iSelection], ()))
return translated_text

def getCustomMapOptionDefault(argsList):
[iOption] = argsList
option_defaults = {
0: 1,
1: 0
}
return option_defaults[iOption]

def isRandomCustomMapOption(argsList):
[iOption] = argsList
option_random = {
0: false,
1: false
}
return option_random[iOption]

def getWrapX():
map = CyMap()
return (map.getCustomMapOption(0) == 1 or map.getCustomMapOption(0) == 2)

def getWrapY():
map = CyMap()
return (map.getCustomMapOption(0) == 2)

def normalizeAddExtras():
if (CyMap().getCustomMapOption(1) == 1):
balancer.normalizeAddExtras()
CyPythonMgr().allowDefaultImpl() # do the rest of the usual normalizeStartingPlots stuff, don't overrride

def addBonusType(argsList):
[iBonusType] = argsList
gc = CyGlobalContext()
type_string = gc.getBonusInfo(iBonusType).getType()

if (CyMap().getCustomMapOption(1) == 1):
if (type_string in balancer.resourcesToBalance) or (type_string in balancer.resourcesToEliminate):
return None # don't place any of this bonus randomly

CyPythonMgr().allowDefaultImpl() # pretend we didn't implement this method, and let C handle this bonus in the default way

def generatePlotTypes():
NiTextOut("Setting Plot Types (Python Continents) ...")
fractal_world = FractalWorld()
fractal_world.initFractal(polar = True)
return fractal_world.generatePlotTypes(water_percent=75)

def generateTerrainTypes():
NiTextOut("Generating Terrain (Python Continents) ...")
terraingen = TerrainGenerator()
terrainTypes = terraingen.generateTerrain()
return terrainTypes

def addFeatures():
NiTextOut("Adding Features (Python Continents) ...")
featuregen = FeatureGenerator()
featuregen.addFeatures()
return 0


There is a lot of diffrerence between them. But what does the extra code in warlords version of continents.py do? and whay? and what whould happen if I change somethings and what should I change to suite me?

That is what I look for in a Tutorial.

This is a quote from Sirian's map guide:
Spoiler :
Balanced
Global Map: World Wrap left to right
Oceanic Map: 84 plots wide, 52 plots tall, at "Standard" map size

Balanced Strategics: This map script will ensure that all players have the key strategic
resources within four plots of their starting location.

Continents
Global Map: World Wrap left to right
Oceanic Map: 84 plots wide, 52 plots tall, at "Standard" map size

It doesn't tell me anything on how I should do tho change anything...:sad:
 
Well, the function names are rather straightforward.
If you want a dictionary, it would say:
getNumCustomMapOptions():returns the number of custom map options.
You can get the lexicon there: http://civilization4.net/files/modding/PythonAPI/
Unfortunatrly, it explains little, but has some useful info like:

CustomMapOptionType getCustomMapOption(INT iOption)
CustomMapOptionTypes () - user defined map setting at this option id

Does any one have a good Tutorial on how you make map scripts??
One for each of the 3 types(Fractral, MultilayerdFractal and Hinted)
preferably.
You don't have to rely on any of these, you can use something different if you like. That will probably not help you much, but if you want mountain ranges for instance, none of these will produce something worthwhile. So being more specific could help.
How do I remove, Jungle, Ice, snow and Desert? Or atleast implement an option to remove all 3 or just 2 or just 1 or none of them?
I think I told you how to get rid of ice. Now you must understand that desert and snow are terrains, jungle is a feature and the ice on water is something else. The latitude thing I proposed in the other trhead should get rid of ice and snow. The same trick I proposed for Peaks is usable for desert.
Regarding jungle, you'll have to hardcode a reference to jungle in the map script, which means it will probably not run properly if the xml files don't have a jungle, or have two jungles, which means editing the xml would be simpler.
 
The problem when I removed Ice is that some Ice and almost everything else dissapeard..
I've just seen something that I missed in the post where you explaind how to remove Ice.
I just added
Code:
class NoIceFeatureGenerator(FeatureGenerator):
	def addIceAtPlot(self, pPlot, iX, iY, lat):
		return

Instead of
Code:
def addFeatures():
	featuregen = NoIceFeatureGenerator()
	featuregen.addFeatures()
	return 0

class NoIceFeatureGenerator(FeatureGenerator):
	def addIceAtPlot(self, pPlot, iX, iY, lat):
		return

That might have coontributed to my faliure..

Some things that I can specifie concerning what I'm looking for:
1) In Full_of_Resources.py there is an option to get the units to start scaterd instead of everybody on the same tile. How do I do that? For instance if I have 1 settler and 8 workers how do I get them to start like this:
Code:
www
wsw
www
???
That is something that I realy would like to know

2) And in smartmap.py You can change the way "huts" are placed how do I do that??

3) And In the same script ther is an option that changes the amount of bonuses how do I do that?

I've tried cutting and pasting but it won't work.

If I can find the code string that allows me to change the placement of starting units how do I implement it in for instance Fractalworld.py?? What to Import to make it work(If something must be imported)?
And finaly how do I do so I get diffrent options to choose from besides the normal options(Mapsize,Climate and so on)???? Just incase that I get the things in 1), 2), 3) to work properly

Thanks again for your tips. White some more tips/help I might soon be able to make my own mapscripts.. Atleast befor thiss Millenium(Not Year) ends...:)
 
Did you try to PM these scripts authors? I haven't dabbled in these areas so I can't help much there.
I can see an addGoodies method in SmartMap, so defining this function will do the job. Ripping it from the script should almost work, you can either copy checkForBadPlots (but it's a kludge, it shouldn't be needed), then remove or replace the bonusMethod things depending on which options you want. Depending on the pattern you want, you'll always end up calling:
cgc = CyGlobalContext()
impGoodyHut = cgc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
pPlot.setImprovementType(impGoodyHut)

addBonuses lets you change the bonuses, depends on what you want.
 
Most of the stuff in MapGeneratorUtils is just stuff that somebody made up. It's useful to look at for learning but you don't actually have to use it. You can do almost anything you want in a map script. The most important file to look at is MapScriptInterface.py. The comments section in that file outlines the map generation process and the order in which certain functions are called. When you override those functions in your map script, it does your stuff instead of the default stuff.

As far as what you can do to each plot, the best tool for learning is to download microsofts latest C++ IDE and look at the functions available in the CvPlot class in the SDK. You can't actually compile anything with the new compilers but they are better for examining the SDK code. Most of the methods on the CvPlot class are exposed to python so you can use them in your map script. Since map generation is all about manipulating plots, most of what you need to know is in the CvPlot class in the SDK. CvGame, CvMap and CvMapGenerator also have useful stuff to know but CvPlot is the most important.
 
Thanks again for your wonderful tips!
I'm learning more and more nut I'm note near the point where I want to be. BUt It's moving :)

Concerning the SDK code. Is there any way to code the things in the sdk files in Python instead??
It would be marvolus since there would be a lot less diffrent file extensions to fiddle with. And if you could remove a lot of the xml files and convert them to python it would be eaven greater(And that is comming from me who can't code in python but are'nt to bad in XML). The Unit, civilization, buildigs xml files should remain but the rest would be good to convert to py. I think it would be alot easier for the engine to not have to deal with alot of diffrent file extensions. But I might be wrong.

If the changes that makes units start scaterd are in the SDK code I won't change them atleast not untill I know hoe to code in Python. I can't learn more then one thing at the time :sad:

COncering the cutting from SmartMap.py I changed som values in that file and all options that You should be able to select from the begining dissaperd. I only changed numbers eg. 4 to 1 and 5 to 3 and so on.. But I will continue struggle to find a soultion.

Is there any one that can tell me how I make options availible??? Options = Selecting diffrent things whens starting the game eg. Map Size.

I'm going to read through MapScriptInterface.py and the SDK files but I will use notepad to read them. As I understand If I change one file I have to recompile that one and that is not something I know how to do and therefor I dont make changes in those files...
 
It's much better to read the py files and sdk files with the proper IDEs. They are both free to download. Check out Python.org and microsoft visual studio express. In python, the error checking you get in the IDE is a huge time saver.
 
You must have missed that I can't deal with both pyton and SDK(C++?) at the same time. I have to learn first one and when I know the first I can learn the other. If I try to learn them both at the same time I won't learn anything.
And reading SDK files with proper IDEs(What that is) won't tell me anything since I'm not familiar with that type of coding. I haven't figured out the tabbing(Layout?) in Python yet and if I must learn the Layout in the SDK files while I'm still struggeling with python I can as well give up. :sad:
So if some things In my questions abow aren't possible to do in Python I'll have to leave them untill I've learned Python....

After reading in CvMapScriptInterface.py I've not learned much.
When I read this:
Code:
def generateTerrain(argsList):
	"returns a list of terrain data for all pixels on the map, indexed with (0,0) in NW"
	CyPythonMgr().allowDefaultImpl()
I don't get it. Or atleast I get this
Code:
def generateTerrain(argsList):
But the rest...
How do I make
Code:
CyPythonMgr().allowDefaultImpl()
to generate Plains? That is the type of descripton I Need.
Example: If you would like to have only these 2 terrains: Dessert and Grass and no jungle and Ice and Peaks You must write like this: (This is not real python code! :) )
Bla.bla.bla.yes.Grass
Bla.bla.bla.yes.Desert
Bla.bla.bla.no.Ice
Bla.bla.bla.no.Peaks
Bla.bla.bla.no.Jungle

The descriptions in CvMapScriptInterface.py concerning adding terrain
"returns a list of terrain data for all pixels on the map, indexed with (0,0) in NW"
Doesn't point out how to do or what to write to get the result I would like. Atleast not to me.:confused:

A tutorial that would suite me seams to be to much effort for someone to write. Atlest that what I think.. But whit your help I might learn enough to write my own mapscript tutorial but to that point in my python knowledge its a long way still to go...

Some of the things In CvMapScriptInterface.py however wasn't to hard to understand. Th eproblem is that the things I would like to do is not the things I can understand.
I now know how to get "custom" options. Atleast I know what to change/add to enable them. But how do I make the options them self is another question...:confused:
 
For now, think of an IDE as simply a text editor that color codes the different kinds of keywords and also can find simple errors in your code.

As for this:
Code:
def generateTerrain(argsList):
	"returns a list of terrain data for all pixels on the map, indexed with (0,0) in NW"
	CyPythonMgr().allowDefaultImpl()

This is the function that is called when there is no 'generateTerrain' in your map script. It simply calles the SDK for default behavior. When you have one in your map script, it will override this function you see here and do what you want instead of the default.

You must look at the SDK to know what your possibilities are. You don't need to understand the code, but you need to see the function names etc.
 
The problem for me is to understand the functions names and what they'll do. I need to have examples that say if you write this, this will happen and if wou write that, that will happen and if you write both this and that you'll end up with a bunch of errors.

I can rewrite almost every xml file and do things I want to do. But I still doesn't know why this happen when I do this, or if 50% means that you get plus or minus 50% ingame or if you get plus or minus 5 or if it just doubbles whatever it changes.
But when it comes to Python that wont work at all. if I change only one number in any of the mapscripts it almost allways ends up in a broken mapscript.

Btw cephalo I must say that I love your mapscripts especially the FaireWaether for Col.
But I would like to know how to make my own. and they doesn't have to be as large as yours and not as full of options. I only would like to have a few options:
1) Choose between no dessert, no snow/ice, no jungle, no peaks, none of them, no dessert and Jungle, No dessert and snow/ice, no dessert and peaks and so on wit every combination of them.
2) Choose how many plots should contain bonuses, 100%, 90%, 80% 70%, 60%, 50%, 40%, 30%, 20%, 10%, 1%, 0%.
3) Same as above but for huts.
4) If its possible an option to have starting units start scaterd.
5) the option to choose wrapping. When I change/add something(anything) in ex. FractalWorld.py that option dissapers.
6) this is the least important one. Choose the amount of rivers from 100%(every land plot adjectant to a river) down to no rivers at all.

Maby my script will be bigger than yours If I can implement all of this but I don't know that yet and probalbly never will know either. However theese are the options I would like the learn to implement.

And if someone know how to not get Islands and not more than one continet when creating maps I would be glad if someone told me how to do that.

Thanks again for all of your efforts. Sorry that I'm a really slow learner whith problems to sometimes understanding eaven the simplest things. And spelling correctly...
 
What you want to do is entirely possible but it looks like a major project. You will not accomplish this with notepad! Python is a language that has what they call 'significant white space'. That means that while most languages ignore spaces and tabs, Python actually uses them for block control! This is something that is very strange and sometimes very frustrating about Python. One extra space character and the whole file is broken.

This is why you need a Python IDE so it can help you find these errors. Follow this link and download the Windows Installer for Python 2.6. It should come with it's own IDE.
http://www.python.org/download/
 
I'm not using Notpad I use IDLE(?) when it comes to python. If I had used Notepad I wouldn't have learned anything at all since fore instance "def" is orange in IDLE and "True" is Purple and so on so if I would use Notepad I would miss all of the diffrent commands...

So taht is not a problem.. :)

You say it's possible and it will tak alot of effort and time(maby not exactly those words but I understand what you meen. Time is something I have an abundence of...
I have absolutley nothing that takes time from me, no school, no job, and only one daughter that have daycare from 08.45 to 15.00 every day and between 15.00 to 08.45 my daughter isn't to much of a distraction or time consumer. SO time I have.
The problem is to get started: ie. To learn what command does what and how to use it. How to write so I get the result I want...
When I've learned about half of it the rest shouldn't be to much for me to understand(Know how to use it and so on). But untill then I would need alot of guidence.
I really wishes that some school i the vicinity of me could start teaching classes in Python(In Swedish).. Since that would be of greate use to me.. Nut since taht will never happen my hope is that you guys can help me in someway.

I can say this much: If I get the help I need and I can learn the thing I need to learn I will besides making maps scripts(and maby some other python files for civ) also write a tutorial in python. A tutorial that even I can understand. I think that such a tutorial would be of greate use to other to.

***********

This is not directed to anyone special. It's just something I've noticed when reading tutorials:
If you know how to code in python you doesn't see the difficulties, that some one who can't sees and therfore whe yo write a tutorial you misses the things of importance for newbies.
 
I'm also searching for this kind of tutorial... that's how I landed here. ^^
So please let me know as soon as it's available. :goodjob:
 
Oh... dang... so maybe this thread comes back to life if just enough curiosity is generated by posting alot in it. -.-
Maybe a new thread for my project it will be then...
 
Back
Top Bottom