Civ/Civilization IV/Modding/Tutorials/Python Tutorial/Using the API

Contents edit

The API edit

The Civ 4 API is a list of all the functions specific to Civ 4 which interface with the actual game. There are two copies of the API. The first, by Locutus can be found here, and the second, by GBM can be found here. Locutus' API is up to date with the latest patch, so I suggest you use that one.

Now, in the past month or so answering questions on the forums about python I have noticed that quite a few people have had trouble reading the APIs. Interpreting what the functions do can be quite difficult, however the APIs do give you lots of hints, if you care to read them.

Now, in the past month or so answering questions on the forums about python I have noticed that quite a few people have had trouble reading the APIs. Interpreting what the functions do can be quite difficult, however the APIs do give you lots of hints, if you care to read them.

I'll use Locutus' API as an example, as I feel the interface is better, so open it up!

Firstly, we have the classes. These list all the functions that can be done to a specific entity, or pointer. For example, CyUnit lists all the functions that will work on a unit entity (a unit in the game). The classes are listed in the top-left hand frame. You will notice that there are several classes with a little "+" symbol by them. These classes are used for getting specific information directly from the xml files on an object.

Now we have the types. These the different types which can be extracted from the xml files. The int values shown are the default values, and while you could use them, and your code would most likely work, I would recommend against it, as if the order of the xml is changed in a future patch, your code will break. Instead I recommend using gc.getInfoTypeForString("") as shown above, as this is much more patch-compatible.

Finally we have the functions. Each class has its own set of functions which must be done to that class and that class only. If you try to take a function from a class, and use it on a different class it won't work. The functions are the main bit of the API, the stuff you want to know.

Functions

Now, there are lots of different functions. Most of the functions don't "do" anything in the game, instead they get a value from your pointer which you can use in an equation. If you look on the left hand side of the function, it will show you what this function returns. For example, if you used:

BOOL CyPlayer.canChangeReligion()

it would not set the player able to change religion, instead it would return a BOOL, a true or false value depending on whether the player can or can't. See what I mean about it not "doing" anything?

Things a function can return are:

  • Bool – true or false, 1 or 0
  • Int – an integer value (can be negative) (256 for example)
  • Float – a floating point number (1.3423 for example)
  • String – a string ("The cat sat on the mat")
  • Turple – a list ([1, 4, 2, 8, 2])
  • Void – see below

The functions that do "do" things return a "VOID" – meaning that they setting rather than getting data. These functions are the most important ones really, as you can't do much without them, and unfortunately there aren't really enough of them to do everything you would want. Sorry, but that's just the way it is.

So, you know what a function returns, but that's not all you need to know. You also need to know what information to give it to return this data. Some functions don't require any inputs.

CyUnit.canMove()

for example doesn't need to know anything apart from which unit it's checking to see if can move (the unit pointer should be in the place of the CyUnit). However, most functions aren't this simple, and require an input to create an output.

Let's take, for example:

CyUnit.setHasPromotion(PromotionType eIndex, BOOL bNewValue)

This function takes two arguments (inputs), the promotion type you want to give to the unit, and a bool value of whether to take, or remove the promotion. To give an example:

pUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COMBAT1"), 1)

would give the pointer, pUnit the promotion combat 1. Note that it is important to give the int value of the promotion in this case, as when the function asks for a type, it really wants an int... don't ask! As luck would have it, if you put the wrong arguments into a function python will tell you when trying to run the function. More about this in the debugging section!

CyGlobalContext

Commonly abbreviated to gc in files this is probably the most useful class, as it contains all the general Civ 4 related functions. GlobalContext is unique in that it doesn't have to be called with a pointer, but is a standalone class for getting information.

It has a number of useful purposes:

  • As I have said before you can use it to get integers from types. For example:
gc.getInfoTypeForString("TECH_MYSTICISM")

would get the int value for Mysticism.

  • You can use it to get from an integer ID to a pointer. For example:[code]gc.getPlayer(0)[/code] would return the pPlayer pointer for the the player with an ID of zero.
  • You can use it to get info from xml files. For example
gc.getPromotionInfo("PROMOTION_COMBAT1")

would return the pointer for the combat 1 promotion, which could then be used with CvPromotionInfo to get information about that specific promotion.

  • A common usage is to get the active player pointer, which returns the pointer of the player whose turn it is:
gc.getActivePlayer()
  • The final major use is to get the number of instances of a certain thing. For example:
gc.getNumPromotionInfos()

would return the number of promotions which are available in the game. This is very useful for if you want to cycle through the promotions and check if a unit has them, activating a new function if it does.

While there are other uses for CyGlobalContext, they are a bit to numerous to list here. I've tried to list what I think are the major ones.

<--Previous Page