Gaius Octavius
Deity
- Joined
- Jul 28, 2006
- Messages
- 4,016
Requested yesterday by GeneralMatt for his British Empire mod (not to mention numerous other people in the past), this simple C++/XML change finally lets you have multiple derivative civs. It includes two main features, 6 new <DerivativeCiv> slots for a total of 7 possible colonies per civ, and a new tag named <bColony>, which I explain below.
Extended description:
The order of derivative civs
The spawning function is weighted toward the top of the colony list, which means that order matters. If you put France, England, and Germany as the first three derivative civs of the Celts, for instance, they will always spawn in that order. The exception is when a target civ is already in the game. Then the list defaults to the next entry. Any subsequent blank tags ("NONE") will result in a random colony.
The bColony tag
This is used in conjunction with <bPlayable> or <bAIPlayable> when you want to limit where and how a civ can spawn. I play a lot of mods, and I always thought it was strange to meet civs like Australia or California in 2000 B.C. only to watch them declare war on England or America. With this nifty tag, you can prevent a civ from being chosen randomly at the start of the game but still keep it available to emerge later as a colony.
Let's say you have created a New Zealand civ, which is a derivative of England. You want to keep it open for human players, but don't want it randomly chosen by the AI at startup. You'd just set bPlayable to 1, bAIPlayable to 0, and bColony to 1 in XML. Now the only way New Zealand can appear in your games is if you or another human picks it, or if you release it as a colony. Similarly, if you wanted a civ that never appeared in the game except as a colony, you'd set both bPlayable and bAIPlayable to 0 and bColony to 1. This has a lot of potential for big mods with many new civs, because you can squeeze in more variety without overloading the player with dozens of options.
Note that this system places no restrictions on possible mother countries; if, say, Germany runs through all its own derivative civs, it could conceivably release New Zealand as well. However, as long as you keep the number of non-random colonies fairly high across the board, this scenario is unlikely.
Additional notes for programmers
All changes in C++ are clearly marked with the comment "Multiple Derivative Civs". There are only four modded files, so merging should be straightforward.
The code itself is very simplistic. I didn't really change the handling of the DerivativeCiv function so much as I reproduced it six times. Originally, I intended to set the code up like the <Units> or <InitialCivics> arrays so that you could specify as many colonies as you wanted, but I kept running into an odd parsing error where the mod would only work for the first civ in the XML index. After repeated attempts at debugging, I finally went for the dumbed-down version in the interests of releasing it sooner. There is no practical difference except that you're now limited to 7 possible colonies, but let's face it, how many times are you going to release that many in a game anyway?
The only other thing worth noting is that the Python setDerivativeCiv function has been adversely affected by multiple entries: it can only be used to change the first colony. I haven't ever seen this used in mods so I don't think it's much of an issue, but if enough people ask I might rewrite the function.
How to use this in Civ 4
The mod contains its own DLL and is playable out of the box, but is intended primarily for other modders to use in their own projects. As such I haven't changed the default BTS derivative civs - that's for you to do, depending on how you want to use it. Just remember that if your mod implements C++ changes, you will have to merge the files included in the download with yours and compile your own CvGameCoreDLL. If it doesn't, you can use the one provided and ignore what's in the extra SDK subfolder.
Installation instructions: Simply download the zip and extract to Beyond the Sword/Mods/, and then load the mod from the BTS main screen.
If there are any bugs, please report them in this thread.
Download link
Extended description:
The order of derivative civs
The spawning function is weighted toward the top of the colony list, which means that order matters. If you put France, England, and Germany as the first three derivative civs of the Celts, for instance, they will always spawn in that order. The exception is when a target civ is already in the game. Then the list defaults to the next entry. Any subsequent blank tags ("NONE") will result in a random colony.
The bColony tag
This is used in conjunction with <bPlayable> or <bAIPlayable> when you want to limit where and how a civ can spawn. I play a lot of mods, and I always thought it was strange to meet civs like Australia or California in 2000 B.C. only to watch them declare war on England or America. With this nifty tag, you can prevent a civ from being chosen randomly at the start of the game but still keep it available to emerge later as a colony.
Let's say you have created a New Zealand civ, which is a derivative of England. You want to keep it open for human players, but don't want it randomly chosen by the AI at startup. You'd just set bPlayable to 1, bAIPlayable to 0, and bColony to 1 in XML. Now the only way New Zealand can appear in your games is if you or another human picks it, or if you release it as a colony. Similarly, if you wanted a civ that never appeared in the game except as a colony, you'd set both bPlayable and bAIPlayable to 0 and bColony to 1. This has a lot of potential for big mods with many new civs, because you can squeeze in more variety without overloading the player with dozens of options.
Note that this system places no restrictions on possible mother countries; if, say, Germany runs through all its own derivative civs, it could conceivably release New Zealand as well. However, as long as you keep the number of non-random colonies fairly high across the board, this scenario is unlikely.
Additional notes for programmers
Spoiler :
All changes in C++ are clearly marked with the comment "Multiple Derivative Civs". There are only four modded files, so merging should be straightforward.
The code itself is very simplistic. I didn't really change the handling of the DerivativeCiv function so much as I reproduced it six times. Originally, I intended to set the code up like the <Units> or <InitialCivics> arrays so that you could specify as many colonies as you wanted, but I kept running into an odd parsing error where the mod would only work for the first civ in the XML index. After repeated attempts at debugging, I finally went for the dumbed-down version in the interests of releasing it sooner. There is no practical difference except that you're now limited to 7 possible colonies, but let's face it, how many times are you going to release that many in a game anyway?

The only other thing worth noting is that the Python setDerivativeCiv function has been adversely affected by multiple entries: it can only be used to change the first colony. I haven't ever seen this used in mods so I don't think it's much of an issue, but if enough people ask I might rewrite the function.
How to use this in Civ 4
Spoiler :
The mod contains its own DLL and is playable out of the box, but is intended primarily for other modders to use in their own projects. As such I haven't changed the default BTS derivative civs - that's for you to do, depending on how you want to use it. Just remember that if your mod implements C++ changes, you will have to merge the files included in the download with yours and compile your own CvGameCoreDLL. If it doesn't, you can use the one provided and ignore what's in the extra SDK subfolder.
Installation instructions: Simply download the zip and extract to Beyond the Sword/Mods/, and then load the mod from the BTS main screen.
If there are any bugs, please report them in this thread.
Download link