Nice one, Locutus![]()

General
This will just be the start, much more is to follow, but a combination of having to get the scenarios done in time and RL issues made me fall behind schedule a bit.
There are basically 4 ways to use Python:
1) Map generation - there won't be additional documentation for this in the short run, but the existing scripts are well documented so you can learn a lot by studying those. Creating completely new map scripts is not for the faint-of-heart though, some grasp of OO programming and the mathemetical concepts underlying the scripts is required. You can find the mapscripts in the PublicMaps folder
2) UI modding - documentation here isn't really needed, the code is more or less self-explanatory. You can find the UI files in the Assets/Python/Screens folder
3) Events - the most common way in which you will use Python, there are many different applications, not just for your standard scenario events. A list of available events is below. The core event manager is Assets/Python/CvEventManager.py
4) Overrides - some game functions can be overwritten, for example what can be built in what cities, what civics/techs/religions/etc are available to who (all dynamically, so on a case-by-case and turn-by-turn basis, much more powerful than the static XML files), some AI behaviour, Barbarian spawning, victory conditions, etc. These overrides are in Assets/Python/CvGameUtils.py
There are some other very specific Python applications, but those you'll normally not need. In the short run at least, there will be no documentation for them (just give me and the community time though)
A note of caution: please do NOT, I repeat, do NOT mess with the Python files in the default Assets folder, this will cause all kinds of problems with future patching, MP play, tournaments, etc. Please use the mod setup that's also used for the in-game scenarios, see the Mods folder. Here you only need to keep the things you add/change, files that remain unchanged you can leave out, the game will just take the version from the default Assets folder for any file it's missing (similar to CtP modding, for those familiar with it -- only this time it actually works). More detailed info will follow but I think most people will be able to figure this out soon enough, it's pretty simple.
API
As any programmer knows, to help you write Python code that actually interacts with the Civ4 engine, rather than just being a stand-alone application, you will need to use a so-called API (Application Programming Interface) -- basically a list of functions you can use to access routines in the game engine. I made a script to extract this info in HTML form from the SDK, but of course you guys don't have the SDK yet, so I'll just have to publish the HTML files. A few isues to keep in mind:
1) My script can only get info from the SDK, while some of the API calls are not in the SDK (game-engine related stuff). I had to add those functions manually and left them mostly undocumented (for now). Classes that have a lot of bright green ??? in them are basically the ones that are not from the SDK.
2) Documentation on what these functions do is pretty poor, I'm working on more complete info. Most of the time the name of the function pretty much tells you what it does though, so this shouldn't keep anyone from using them (it certainly hasn't kept me).
3) This is for a not-quite-final version of the game, there might be some minor changes in the release version but it should be only really minor stuff, if anything changed at all. For an even-closer-but-still-not-quite-final build my script is FUBARed, I'll have to check what goes wrong there, and then ask Soren or Trip to run my script on the release version of the SDK (which I don't have myself either) to get this fully up-to-date (there are no changes to the API itself between these two builds though). For now this version will work absolutely fine though, at least 99.99% of this should still be accurate.
4) Hmm, there was another issue but I forgot. Oh well, I'll update this post when I remember it.
You can browse the API reference here: http://civilization4.net/files/modding/PythonAPI/
A zip version that you can extract and browse on your own PC is here: http://civilization4.net/files/modding/PythonAPI.zip
Events
As promised, the list of events that's available to you in the game (sorry for the poor formatting, I don't have terribly much time today). This was also generated based on source files (with a few notes from myself) for a not-quite-final build, more detailed and final info will follow:
onKbdEvent
'keypress handler - return 1 if the event was consumed'
arguments: eventType,key,mx,my,px,py
onInit
'Called when Civ starts up'
arguments: -
onUpdate
'Called every frame'
arguments: fDeltaTime
onWindowActivation
'Called when the game window activates or deactivates'
arguements: bActive
onUnInit
'Called when Civ shuts down'
arguments: -
onPreSave
"called before a game is actually saved"
arguments: -
onSaveGame
"return the string to be saved - Must be a string"
arguments: -
onLoadGame
-
arguments: -
onGameStart
'Called at the start of the game'
arguments: -
onGameEnd
'Called at the End of the game'
arguments: -
onBeginGameTurn
'Called at the beginning of the end of each turn'
arguments: iGameTurn
onEndGameTurn
'Called at the end of the end of each turn'
arguments: iGameTurn
onBeginPlayerTurn
'Called at the beginning of a players turn'
arguments: iGameTurn, iPlayer
onEndPlayerTurn
'Called at the end of a players turn'
arguments: iGameTurn, iPlayer
onEndTurnReady
-
arguments: iGameTurn
onFirstContact
'Contact'
arguments: iTeamX,iHasMetTeamY
onCombatResult
'Combat Result'
arguments: pWinner,pLoser
onCombatCalc
'Combat Result'
arguments: cdAttacker, cdDefender, iDefenderOdds
onCombatHit
'Combat Message'
cdAttacker, cdDefender, iIsAttacker, iDamage
onImprovementBuilt
'Improvement Built'
arguments: iImprovement, iX, iY
onRouteBuilt
'Route Built' (note: routes = road or railroad)
arguments: iRoute, iX, iY
onPlotRevealed
'Plot Revealed'
arguments: pPlot, iTeam
onBuildingBuilt
'Building Completed' (note: building = improvement or wonder)
arguments: pCity, iBuildingType
onProjectBuilt
'Project Completed' (note: project = space ship part, Appollo Program, 1 or 2 other modern wonders)
arguments: pCity, iProjectType
onUnitMove
'unit move'
arguments: pPlot,pUnit
onUnitSetXY
'units xy coords set manually' (note: i.e. teleport)
arguments: pPlot,pUnit
onUnitCreated
'Unit Completed'
arguments: unit
onUnitBuilt
'Unit Completed'
arguments: city, unit
onUnitKilled
'Unit Killed'
arguments: unit, iAttacker
onUnitLost
'Unit Lost'
arguments: unit
onUnitPromoted
'Unit Promoted'
arguments: pUnit, iPromotion
onUnitSelected
'Unit Selected'
arguments: unit
onUnitRename
'Unit is renamed'
arguments: pUnit
onGoodyReceived
'Goody received'
arguments: iPlayer, pPlot, pUnit, iGoodyType
onGreatPersonBorn
'Unit Promoted' (note: obviously not, should be 'Great Peson Born')
arguments: pUnit, iPlayer, pCity
onTechAcquired
'Tech Acquired'
arguments: iTechType, iTeam, iPlayer, bAnnounce
onTechSelected
'Tech Selected'
arguments: iTechType, iPlayer
onReligionFounded
'Religion Founded'
arguments: iReligion, iFounder
onReligionSpread
'Religion Has Spread to a City'
arguments: iReligion, iOwner, pSpreadCity
onGoldenAge
'Golden Age'
arguments: iPlayer
onEndGoldenAge
'End Golden Age'
arguments: iPlayer
onChangeWar
'War Status Changes'
arguments: bIsWar, iPlayer, iRivalTeam
onChat
'Chat Message Event'
arguments: chatMessage
onSetPlayerAlive
'Set Player Alive Event' (note: either when a player dies or is revived (only in scenarios))
arguments: iPlayerID, bNewValue
onCityBuilt
'City Built'
arguments: city
onCityRazed
'City Razed'
arguments: city, iPlayer
onCityAcquired
'City Acquired'
arguments: owner,playerType,city,bConquest,bTrade
onCityLost
'City Lost'
arguments: city
onCultureExpansion
'City Culture Expansion'
arguments: pCity, iPlayer
onCityGrowth
'City Population Growth'
arguments: pCity, iPlayer
onCityDoTurn
'City Production'
arguments: pCity, iPlayer
onCityBuildingUnit
'City begins building a unit'
arguments: pCity, iUnitType
onCityBuildingBuilding
'City begins building a Building'
arguments: pCity, iBuildingType
onCityRename
'City is renamed'
arguments: pCity
onVictory
'Victory'
arguments: iTeam, iVictory
onGameUpdate
'sample generic event, called on each game turn slice' (note: at least in theory about 4 times per second (didn't test it))
arguments: turnSlice
onMouseEvent
'mouse handler - returns 1 if the event was consumed'
arguments: eventType,mx,my,px,py,interfaceConsumed,screens
Example
Finally, I'll give one simple example of how to use all this code in practice. For more examples, see the Python code in the Mods folder, the various scenarios come with a lot of interesting code.
Note that this example overwrites the existing event code, normally you will want to either append to it, or subclass it (more info on that will follow), for simplicity's sake I didn't do that here.Code:def onGameStart(self, argsList): 'Create a popup message at the start of the game' popup = PyPopup.PyPopup() popup.setBodyString( 'Hello World' ) popup.launch() def onCityBuilt(self, argsList): 'For player 1, create a Warrior (index 17) in every city that is built' city = argsList[0] if city.getOwner() == 1: city.getOwner().initUnit(17, city.getX(), city.getY(), UnitAITypes.NO_UNITAI)
If anyone has any Python-related questions, I'll try to answer them as best as I can.
Last edited by Locutus; October 26, 2005 at 16:28.

Nice one, Locutus![]()

excellent, it looks like some stuff can be converted from SLIC (kind of)/
Is there a way to select unit (or building) traits. like if unit has move of 2 than bonus attack etc?

Nice dude. Thanks, etc.
I'm amazed to see onUpdate and onGameUpdate. Does this mean a scripter can play with the graphics engine? If so, then together with the mouse and keyboard events it seems like you could script a simple arcade game right into Civ4. O_o.
Also wondering the extent of UI modification possible via scripting. Can new widgets/screens be added? Can other UI elements be disabled?
I saw in a screenshot that that scripts could be attached to a city. When is this attached script called by the program? Can a script be attached to other objects---units, specific units, techs, plots, civilizations etc?
(...taps foot and waits for copy of Civ4 to arrive on Friday...)

Good.![]()

Yeah, I made sure of thatOriginally posted by E
excellent, it looks like some stuff can be converted from SLIC (kind of)/At least in theory almost all SLIC scripts should be convertable to Civ4 (didn't actually try though). The only exception might be in some of the pre events, it was decided that those would be too bug-prone and too time consuming to get right. But when the SDK is released we can add these ourselves of course
Yes, everything that subclasses from CvInfoBase takes care of that. CvUnitInfo().getMoves() returns the movement points of a unit. To get the movement points of a Warrior:Is there a way to select unit (or building) traits. like if unit has move of 2 than bonus attack etc?
Note that 'gc' is shorthand for CyGlobalContext(), which is defined at the start of pretty much every Python file because it's so common.Code:gc.getUnitInfo(gc.getInfoTypeForString("UNIT_WARRIOR")).getMoves()
gc.getInfoTypeForString("UNIT_WARRIOR") will return 17, the index of the Warrior unit, as you could see in the example in my opening post. The difference between this and using 17 directly is that this requires less cross-referencing with the XML files for the programmer and is less prone to errors when you mod the XML files. The downside is that it's slower (though your code has to make a LOT of calls to it before you start to notice the difference).
So apart from the syntax it works pretty much the same as the Database functions in CtP2.
No. It just means those events are triggered every frame or every game slice. This is mostly useful if an existing event doesn't do the job and you want to check for a specific thing that might happen in the game. Of course, since this code gets called *very* often, best not to use it too much and keep it as efficient as possible, or you could notice a real drop in performance.Originally posted by drekmonger
I'm amazed to see onUpdate and onGameUpdate. Does this mean a scripter can play with the graphics engine?
But yeah, the code is pretty powerful, even without the SDK you could probably make an arcade mini-game in Civ4 if you wanted
Yes, you can add and remove pretty much anything you want. A few things are hardcoded, but the degree to and the ease with which the UI can be modded in Python is the thing that surprised me most (in a good way) when I got into Civ4 modding. In the Desert War scenario that comes with the game I showed off some of the things you can do with it, though it only barely scratches the surface of what is possible.Also wondering the extent of UI modification possible via scripting. Can new widgets/screens be added? Can other UI elements be disabled?

Don't DanS meOriginally posted by drekmonger
I saw in a screenshot that that scripts could be attached to a city. When is this attached script called by the program? Can a script be attached to other objects---units, specific units, techs, plots, civilizations etc?![]()
That was added pretty late in the development so I haven't really messed with that yet, but I think it's just so you can add scriptdata to objects. Just doing that in the World Builder isn't very useful though, as far as I can see -- but maybe Trip or whoever added that to the World Builder had something in mind I haven't thought of. Script data is really only useful if you have a script to handle it. It's basically just useful to associate specific data with a specific unit/city/tile/whatever -- and to make scripts savegame-safe, but I'll discuss that in my upcoming full Python guide. As it stands, in my current (non-final) build, it doesn't work anyway, just gives me an error (or maybe I'm using it the wrong way).

I'm glad to see you had a strong hand in Civ4...you are making the ctp2 to civ4 leap much more tempting...
Another question though. would it be possible in Python (or do we have to wait til the SDK) to add new unit flags? like in my ctp2 code I added cultureonly and citysyleonly flags. is it possible to just create a flag in the xml and call it through python (assuming the game would ignore the reference). i'm sure its a long shot but just hoping
offtopic. I have another thread asking about graphic formats are you able to answer those questions now, especially can we add new citystyles, or what format leaderheads are in.
thanks Loc

It's all part of Soren's nefarious plan to conquer the world (or the Civ community anyway)!!Originally posted by E
I'm glad to see you had a strong hand in Civ4...you are making the ctp2 to civ4 leap much more tempting...![]()
![]()
![]()
That's probably not possible with Python-only because as you can see in my example, to check for an XML property, you have to call a specific API function. There's no way to generically search for properties, as there is for main entries such as unit/civic/building/etc types, as far as I know (but even I am still finding new applications for Python every now and then). E.g. to check the XML unit property iMoves, you have to use the Python call getMoves(). If you were to define your own bCultureOnly flag, you would need to add a getCultureOnly call in the game engine to be able to use it in Python. You'll need the SDK for that, and even then I don't dare say with 100% certainty that it's possible (90% sure it is though).Another question though. would it be possible in Python (or do we have to wait til the SDK) to add new unit flags? like in my ctp2 code I added cultureonly and citysyleonly flags. is it possible to just create a flag in the xml and call it through python (assuming the game would ignore the reference). i'm sure its a long shot but just hoping
Either way, you *can* just define a list of all unit types (or city styles or civics or whatever you need) in Python that should have a certain property, and give them a specific value if needed. For example, something along the lines of this:
One of the major advantages of Python over SLIC is that it's a much more powerful language that among other things supports much more powerful datatypes, as you can see here, which makes adding completely new features, including new unit flags, much easier to do.Code:iNumSlavesDict = { "UNIT_WARRIOR" : 1, "UNIT_SETTLER" : 2, "UNIT_CATAPULT" : 0, # [...] "UNIT_TANK" : 1 } # [...] def onUnitKilled(self, argsList): unit, iAttacker = argsList strUnitType = gc.getUnitInfo(unit).getType() if strUnitType in iNumSlavesDict.keys(): iNumSlaves = iNumSlavesDict[strUnitType] self.addSlaves(iAttacker, iNumSlaves) # [...] def addSlaves(self, iPlayer, iNumSlaves): # some implementation to add slaves to a player
As you should know by now, if there's one thing I totally suck at it's graphics. So I'm not really the person to answer those types of questions. I'll have a look at your thread but I can't promise any answers.offtopic. I have another thread asking about graphic formats are you able to answer those questions now, especially can we add new citystyles, or what format leaderheads are in.
Last edited by Locutus; October 26, 2005 at 17:18.

Do you have details on how the xml and python interact? I guess there are several xml files. Is there some description of what they are somewhere? From what you say it looks like Python can be used to ask info from the xml files, rather than the xml used to call some python code.E.g. to check the XML unit property iMoves, you have to use the Python call getMoves(). If you were to define your own bCultureOnly flag, you would need to add a getCultureOnly call in the game engine to be able to use it in Python. You'll need the SDK for that, and even then I don't dare say with 100% certainty that it's possible (90% sure it is though).
I don't know Python (yet), but in java it is possible to find out which methods an object sports using reflection. I'd be surprised if Python didn't have a functionality like that. So if the xml is used to call back python methods, in theory, if you subclass the python objects, you could add methods on them and call them from the xml? I know in theory this is possible (the xml parser we use in Clash is based on that principle: find an object, use reflection to find the method with the name matching that in the xml file, and call it) but it depends whether the xml files drive the game (as n Clash) or the scripts read from the xml files (which would be much weaker).
Clash of Civilization team member
(a civ-like game whose goal is low micromanagement and good AI)
web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

As you mention yourself, I gave an example of how to do it. You can use CvInfoBase and subclasses to extract info from the XML files.Originally posted by LDiCesare
Do you have details on how the xml and python interact?
They are pretty self-explanatory. I haven't seen any documentation for them but it usually doesn't take me more than a few moments to find find what I need. There are a few files with global settings and there is a bunch of folders that sort the XML files by topic: the XML/Units folder contains all unit, promotion and command related XML files, XML/Civilizations everything related to civs and leaders, XML/Art contains all the art definitions, XML/Text all the in-game text (in all supported languages), etc.I guess there are several xml files. Is there some description of what they are somewhere?
As an example, XML/Civilizations contains 4 files: CIV4CivilizationInfos.xml (with things like civ name/adjective/etc, city names, art styles, UUs, starting techs, etc), CIV4CivilizationsSchema.xml (containing the Schema info for the files in this folder), CIV4LeaderHeadInfos.xml (with info on leaders and their personality) and finally the small CIV4TraitInfos.xml (containg info on trait properties). The setup for the other folders is similar. Sometimes there's only 2 files, sometimes there are close to close to 20. And then there are GameInfo and Misc which contain random stuff that doesn't warrant its own folder for some reason (game options, difficulty levels, civics, rivers, tutorial info).
There are a small number of hooks to Python in XML as well but I haven't used them yet, not sure how to do it. Not sure they're very interesting for modmakers either, seems mostly 'under-the-hood' stuff that's needed to run the game. Though I'm sure someone will eventually find some kind of use for themFrom what you say it looks like Python can be used to ask info from the xml files, rather than the xml used to call some python code.
Reflection is actually one of the key strengths of Python as a language, it probably does a better job than Java in this respect (though I never really used that aspect very extensively in either language, so don't take my word for it). There's a whole chapter dedicated to in this guide, which incidentally I would recommend as a good source for learning Python if you're an experienced programmer and want to learn all the ins and outs of the language. (If you're only interested in the parts that are relevant for Civ4, wait for my guide.)I don't know Python (yet), but in java it is possible to find out which methods an object sports using reflection.
I don't *think* so, but as I said, I haven't really used the Python hooks in XML yet, so I'm not an expert. The game is definitely not driven on XML though, it's just the format in which the database values are read during load, pretty much exactly like the TXT files in CtP (anyone who's modded CtP1/2 will notice that those games were a major inspiration for the modding aspects of Civ4).I'd be surprised if Python didn't have a functionality like that. So if the xml is used to call back python methods, in theory, if you subclass the python objects, you could add methods on them and call them from the xml?
I'm not sure if that makes it weaker, as I see it it just means that Python and the DLL (SDK) drive the XML rather than the other way around, the net result would seem the same to me. But then again, I'd really have to know more about the Clash approach, never really dug too deep into such fundamental issues (not like I can change it -- I had a big say in the development of the modding aspect of the game but not that big a say) What kind of new functionality are opened up by it?
Last edited by Locutus; October 26, 2005 at 19:05.

The aspect of modding in clash opened by the use of reflection is that anything accesssible by the java language is actually accessible from the xml. We (over?)use xml so events are also coded with that rather than Python in CIV. Since CIV uses a scripting language, (doesn't require compilation - comes with lots of features), using the same kind of approach would allow to add for instance new data fields to units in some Python code, value them in the xml files, and exploit these in some python. I'll have to wait a bit to see if that's possible, and I don't know if that's the way to add data to units (adding homemade promotions might achieve the same?). So you could add stuff like, f.e. a weapon slot, and use this as a base for a unit workshop factory for instance (add data to unit - use it to alter its abilities).
Clash of Civilization team member
(a civ-like game whose goal is low micromanagement and good AI)
web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

At this point, scenario creation looks like a daunting task (unlike Civ II) for us non-programmer types. confused:

donbrid:
If you just want to create a scenario using the existing rules in Civ4, I would recommend looking through my manual on the World Builder. You can create a full scenario based on the Civ4 rules very easily. No need to look into xml or python to make a good scenario.
Dale

(Dale beat me to it as I was composing this; but you're going to get it anyway.)
Well, it depends on what kind of scenarios you want to make. Did you do anything with the Civ2 events 'language'?
I don't remember a lot of the Civ2 scenarios I used to play as having a lot of scripting. But this was in the last millenium and I'm sure that the ones that have come out more recently are way more sophisticated.
Anyway, this thread is about scripting with Python but if you want to make a basic scenario (like those early Civ2 scenarios) you don't need to worry about it. You can start by reading Dale's Civ IV Modding Manual (it's stickied at the top of this forum). That gives you lots of info about how to use the World Builder.
The other thing you'll want to edit is the XML files. But this is in general surprisingly easy: they may look daunting at first, but they're actually very easy to play with. They're just a *very* big expansion of those Civ2 txt files you used to edit.
And if you come up with a good looking, well designed scenario, you just might be able to persuade someone to do some scripting for you.

Scenario making can be done on different levels, from very simple to very complex. Look at the Earth 1000 AD scenario for a very simple but still fun and replayable scenario: it's entirely made with the World Builder, no XML or Python changes there. Anyone who knows how to use a mouse and keyboard and is a little bit creative could design something like that, no real technical skills are required. The Greek World scenario involves some a fair amount of XML modding but very little Python, the scenario would be entirely playable and enjoyable if you deleted the Python folder. Anyone could still design something like that but you have to dive into some XML files to accomplish it, which may require some getting used to, but it's not hard to do at all. The Revolutionary War scenario contains more complex Python code, although as far as Python goes, it's still fairly straight-forward and easy to adjust for your own purposes. The Desert War scenario is another step up in complexity and it requires some skill and experience to create something similar. But I'm in the process of writing a detailed Python guide that should make Python modding a lot easier for everyone from novices to expert programmers.

Thanks Locutus
I speak from experience, you are a very helpful individual
I have called on you for many years in CTP and have had untold hours of fun modding
Looking forward after Amazon gets done abusing my Presell edition of CIV IV to doing some modding
Thanks a lot
Gramps![]()
Did anyone have Ryan Dunn From Jackass FAME? He died in a fiery car crash speeding after being in a bar. And to think, everyone thought he would die doing something stupid-rah

Thanks to everyone for your comments and encouragement. I'll be reading Dale's manual while I wait on Amazon.
There were a few extremely sophisticated Civ2 scenarios released at one point - these used multiple event files etc. For example, Red Front is a classic example. It is still my all-time favourite Civ game. Hopefully with the new tools in Civ4 this can be surpassed!Originally posted by Peter Triggs
I don't remember a lot of the Civ2 scenarios I used to play as having a lot of scripting. But this was in the last millenium and I'm sure that the ones that have come out more recently are way more sophisticated.

It most certainly can be. If it will be, is up to the fansOriginally posted by sgrig
There were a few extremely sophisticated Civ2 scenarios released at one point - these used multiple event files etc. For example, Red Front is a classic example. It is still my all-time favourite Civ game. Hopefully with the new tools in Civ4 this can be surpassed!![]()

Hey now... the functions I wrote to spawn rebel barbarian units randomly within a certain radius of any plot while also moving enemy units currently on that plot aside to a random plot in a list of the closest friendly ones is just as complicated as anything in DesertWar.Originally posted by Locutus
The Revolutionary War scenario contains more complex Python code, although as far as Python goes, it's still fairly straight-forward and easy to adjust for your own purposes. The Desert War scenario is another step up in complexity and it requires some skill and experience to create something similar.![]()

As Locutus, I certainly expect Civ 4 to pass Civ 2. The Civ community is much larger and more experienced now and more is possible - mix the two together you and you can come up with some amazing stuff.Originally posted by sgrig
There were a few extremely sophisticated Civ2 scenarios released at one point - these used multiple event files etc. For example, Red Front is a classic example. It is still my all-time favourite Civ game. Hopefully with the new tools in Civ4 this can be surpassed!![]()

My version's more robust thoughOriginally posted by Trip
Hey now... the functions I wrote to spawn rebel barbarian units randomly within a certain radius of any plot while also moving enemy units currently on that plot aside to a random plot in a list of the closest friendly ones is just as complicated as anything in DesertWar.![]()
![]()
Either way, both our scenarios are just the tip of the iceberg in terms of what can be done with Python, it'll be very exciting to see what the community will do in the coming years with the tools they've been given. If previous moddable games such as Civ2 and the CtP series are any indication, the only thing we know for sure that it'll surpass all our expectations![]()

Any idea how to attach a vertical scrollbar to an existing panel?
I printed some stuff on a panel which goes beyond it's clip boundary, so I need to somehow put a scrollbar on that panel...

I'm a bit confused... in which file i have to add those lines (for example)? "CvEventManager.py"?Originally posted by Locutus
Example
Finally, I'll give one simple example of how to use all this code in practice. For more examples, see the Python code in the Mods folder, the various scenarios come with a lot of interesting code.
Code:def onGameStart(self, argsList): 'Create a popup message at the start of the game' popup = PyPopup.PyPopup() popup.setBodyString( 'Hello World' ) popup.launch() def onCityBuilt(self, argsList): 'For player 1, create a Warrior (index 17) in every city that is built' city = argsList[0] if city.getOwner() == 1: city.getOwner().initUnit(17, city.getX(), city.getY(), UnitAITypes.NO_UNITAI)

How do I edit properties of the cities? I want to add bonuses to the cities based on resources, health, ect, but I'm not sure what event to use to keep them up to date, plus to make sure it processes for every city.
I'm thinking I can add something like this, but it has to be called for each city every turn, just to make sure it's up to date, so I'm not sure where to add it (or if I'm calling/editing the write variables).
Would I put this in onEndTurn? And how would I make sure it processes for every city?Code:if (Pycity.getFoodRate() * (getGoodHealth() - getBadHealth()) * 0.05 > 0): YieldTypes.YIELD_FOOD = Pycity.getFoodRate() * (getGoodHealth() - getBadHealth()) * 0.05:
Anyone have any suggestion on how I can forbid certain civs from getting certain religions? For example, if I wanted to put both Christianity and Islam under Monothesim and have the French, English, and Germans only able to found Christianity when getting the tech and the Persians, Arabs, and Egypt only able to found Islam?Originally posted by Locutus
4) Overrides - some game functions can be overwritten, for example what can be built in what cities, what civics/techs/religions/etc are available to who
I'm a super newbie at python/xml but I've been spending a fair amount of time poking around the files trying to get a sense of how to set something like this up. Any ideas would be greatly appreciated.![]()

I want to create a map script that recreates the same map every time, but randomizes resource placement. Can I simply input coordinates for each terrain type in the relevant portion of the script(cutting and pasting from the BMP-WBS converter values), or is it more complex than that? Can I preplace cities, units, and generate tech levels in the map script, as well?
Why I ask, is I want to create a scenario, but want certain factors randomized, but keep the same map. In civ III, I'd simply randomize the resource placement in the editor... but not having the game yet, I'm uncertain is the worldbuilder allows me to do this.
So, if I want to modify a certain PY file, I should copy it to the MODS folder, edit that copy in the mods folder, and leave it there, while keeping the original PY file in its original directory? This sounds like the system first grabs PY's in the Mods folder and then collects from the original folders any PYs that are not found in the Mods, right?Originally posted by Locutus
A note of caution: please do NOT, I repeat, do NOT mess with the Python files in the default Assets folder, this will cause all kinds of problems with future patching, MP play, tournaments, etc. Please use the mod setup that's also used for the in-game scenarios, see the Mods folder. Here you only need to keep the things you add/change, files that remain unchanged you can leave out, the game will just take the version from the default Assets folder for any file it's missing (similar to CtP modding, for those familiar with it -- only this time it actually works). More detailed info will follow but I think most people will be able to figure this out soon enough, it's pretty simple.
This is my first time modding Civ, so if my question sits better in another thread, please direct me to it... IF there is a Newbie's guide to Modding Civ, I'd love to read it. Thanks.

You have to use attachMultilineText instead of setText or whatever is currently used. The civilopedia file (CvPedia*) have a number of examples of this.Originally posted by TheDarkside
Any idea how to attach a vertical scrollbar to an existing panel?
I printed some stuff on a panel which goes beyond it's clip boundary, so I need to somehow put a scrollbar on that panel...
Yes.Originally posted by Nevs23
I'm a bit confused... in which file i have to add those lines (for example)? "CvEventManager.py"?
onCityDoTurn would seem like the best event for this, it gets called for every city at the start of every turn, when production, food, etc get updated for the new turn.Originally posted by Mylon
Would I put this in onEndTurn? And how would I make sure it processes for every city?
You can't just change the value of YieldTypes.YIELD_FOOD though, that's just the index of the food value, not the actual food value. You can't manipulate in-game variables such as food, hitpoints, etc directly, you have to do so through functions. The onCityDoTurn event gives you a city argument, so the second line in your example would have to be something like:
Code:pCity.changeFood(Pycity.getFoodRate() * (getGoodHealth() - getBadHealth()) * 0.05)You're not far off by quoting the overrides bit. You can actually sort of see an example of this in the Greek World scenario, where the founding of Christianity is forbidden until ~1 AD. By default the override functions in CvGameUtils.py return false, if you make them return True (under certain circumstances), an event is stopped. With doHolyCityTech you can allow and disallow cities from founding religions, but I don't think it's really designed to deal with several religions being founded with the same tech. You may have to wait for the SDK to be released to modify the source code so that you can actually run this override once per religion rather than once per tech. When I have time I'll play around with this myself and if it works as I think it does, I can fix this myself and request Firaxis to add my fix to the next patch. But I'm not sure when I'll get around to it, might be a while.Originally posted by Fintilgin
Anyone have any suggestion on how I can forbid certain civs from getting certain religions?
I'm by no means an expert when it comes to map scripts, that's Sirian's terrain. You might want to start a seperate thread, that might draw his attention.Originally posted by craig_sutter
I want to create a map script that recreates the same map every time, but randomizes resource placement. Can I simply input coordinates for each terrain type in the relevant portion of the script(cutting and pasting from the BMP-WBS converter values), or is it more complex than that? Can I preplace cities, units, and generate tech levels in the map script, as well?
That said, I think this was actually discussed by some of the testers and it was concluded that it would require some serious changes to the current setup. It would probably be best to just create a pre-set WBS map without resources and write a seperate Python routine (that could probably be very similar to the ones used in the map scripts) to place resources at the start of the game. Doing it the other way around of having a map script and just removing all the randomness in it would likely be much harder, but as said, I'm not the guy to ask.
Yes, exactly. I should add though that I've recently learned that you can also place your changed files in the CustomAssets folder if you want them to apply to all games, not just to one mod (but still without affecting patches, MP, etc). But the idea remains the same: the system first gets the file from the mod folder, then (I think) from CustomAssets, then from Assets. The CustomAssets thing was added (or at least functional) very late so I have no experience with it yet.Originally posted by Spocko
So, if I want to modify a certain PY file, I should copy it to the MODS folder, edit that copy in the mods folder, and leave it there, while keeping the original PY file in its original directory? This sounds like the system first grabs PY's in the Mods folder and then collects from the original folders any PYs that are not found in the Mods, right?
Bookmarks