1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Initial Python documentation

Discussion in 'Civ4 - SDK/Python' started by Locutus, Oct 27, 2005.

  1. Locutus

    Locutus King of the Collective

    Joined:
    Oct 30, 2001
    Messages:
    365
    Location:
    Hengelo/Enschede, the Netherlands
    I posted this on Apolyton here, I figured I'd better post it here as well. If you have any questions for me, I'd prefer you posted them in the Apolyton thread, since Apolyton is much, much faster than CFC and it's my own site, I hang out there every day (and these days every night as well ;)) and it's best to initially keep what little info there is for now in one place as much as possible (I already answered a bunch of questions there which give more info and examples). I'll swing by here a few times as well though.

    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.

    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)
    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.

    If anyone has any Python-related questions, I'll try to answer them as best as I can. Again, prefer place to post questions: http://apolyton.net/forums/showthread.php?s=&threadid=140611
     
  2. tbear2520

    tbear2520 Warlord

    Joined:
    Oct 28, 2005
    Messages:
    103
    Thanks, I've been looking for some information on these lines. However I don't see the main thing I would like. I am trying to put a predefined map in the Single player - custom. Instead of the random ones. The purpose is to use the flexiability of that area while playing on Earth. So I have looked around for some sort of command that will allow me plot out the X\Y land for earth in a py file. Do you got any ideas? formulas :p
     
  3. Locutus

    Locutus King of the Collective

    Joined:
    Oct 30, 2001
    Messages:
    365
    Location:
    Hengelo/Enschede, the Netherlands
    I'm not sure what exactly you're asking, you want to know how to get a plot at certain coordinates? That would be CyGlobalContext().getGame().plot(<someX>, <someY>). That gives you the plot, you can then call all kinds of functions (from CyPlot) on it, for example setPlotType() to change the terrain, setBonusType() to add a resource, etc. Is that what you want?
     
  4. smellymummy

    smellymummy King

    Joined:
    Jul 31, 2002
    Messages:
    705
    thanks :goodjob:

    looking forward to see more info and practical examples :)
     
  5. Jeckel

    Jeckel Great Reverend

    Joined:
    Nov 16, 2005
    Messages:
    1,637
    Location:
    Peoria, IL
    Hey, does anyone have the script that extracts the API from the SDK?

    Would be nice to have so we don't have to work with a Vanilla API when trying to write BtS code. :)
     
  6. Zebra 9

    Zebra 9 Emperor

    Joined:
    May 17, 2006
    Messages:
    1,554
    Location:
    Middle of Cyberspace
    I'm almost done with my API for BtS. And if I get my extraction script working completly I'll upload it too.
     
  7. Paolo80

    Paolo80 Chieftain

    Joined:
    Dec 20, 2019
    Messages:
    79
    Gender:
    Male
  8. bluepotato

    bluepotato Warlord

    Joined:
    Dec 11, 2018
    Messages:
    237
  9. Paolo80

    Paolo80 Chieftain

    Joined:
    Dec 20, 2019
    Messages:
    79
    Gender:
    Male
    thanks!
     

Share This Page