This is an updated version of the original guide, reflecting changes to the code base that have happened since then. If you use this guide and encounter a mistake, please let me know. Okay, I'll try to write a tutorial on how to insert a new civilization. First off, I want to clarify some terminology. Usually, when talking about the game, the terms "civilization" and "player" are used interchangeably. In the code, there is an important difference between the two. You can think of players as "slots" for civilizations in the scenario. Let's say, the current RFC scenario has 26 players. These players can be any civilization, it's just that they are defined as Egypt, Babylonia, China etc. in the scenario. All players may just as well be Egypt. Civilizations can be added to the game without affecting it at all. For instance, the Sumerian or Zulu civilizations are in DoC but aren't assigned to any player. Adding a civilization to the game doesn't make it appear. A new player has to be created first before you can assign that civilization to it. There is a third term called "team" which you will encounter during the process. Teams are comprised of multiple players and are used in BtS to implement permanent alliances (players that form a permanent alliance become a team, sharing techs and other stuff). Permanent alliances don't exist in RFC, which is why teams and players are treated interchangeably. There are always as many teams as players, and every team is comprised of only one player. For ease of use, teams are ordered in the same way as players are, so that the same ID refers to related teams and players. More on that later. Creating your civilization I'm going to assume you have all the graphics you need for your civilization. I'm also going to assume you know how to edit XML. It's documented in the modiki and there are some guides out there. Generally it is a good idea to always look for an entry that is most similar to what you want to add, copy it and then modify it to suit your needs. You need to edit the following files: 1) The civilization itself: XML\Civilizations\CIV4CivilizationInfos.xml It's a good idea to insert it in alphabetical order (all current civilizations are ordered this way), but that isn't mandatory. A civilization contains a city list that is used for all cities not covered by the CityNameManager. If you know a name on the list is covered by the CNM you should remove it. I have added a couple of extra mandatory XML that have to be accounted for when adding a new civ: Identifier: a three letter identifier for the civ, it must match the identifier used for the civilization in various text keys (e.g. UHV or UP texts). StartingYear: the spawn year of the civilization (impacts interface only) LoadingTimes: the estimated loading times for the three scenarios Rating: the number of stars in the different rating categories in the civilization information screen. 2) Their leader: XML\Civilizations\CIV4LeaderheadInfos.xml If you don't have your own leader personality, I suggest you try to think of which existing leader comes closest to the desired behavior of the new LH and just copy their entry. 3) Their unique building: XML\Buildings\CIV4BuildingInfos.xml It's a good idea to copy the building it replaces and make some changes. I suggest you insert the new UB after the building it replaces, this is the current standard. 4) Their unique unit: XML\Units\CIV4UnitInfos.xml Basically the same procedure as with buildings. 5) Graphics If you copy the XML entries, I suggest to keep the ART_DEF_... entry unchanged in the beginning. Everything will look like the building/unit/leader it replaced, but you can be sure that the pointers to the graphics are correct and the mod should load fine without crashes (always start the mod after an XML change to make sure you have no syntax errors). You can create new ART_DEF_... entries in the XML if you have art files they can point to. Civilization button and flag: XML\Art\CIV4ArtDefines_Civilization.xml Leaderhead graphics: XML\Art\CIV4ArtDefines_Leaderhead.xml Building button and graphics: XML\Art\CIV4ArtDefines_Building.xml Unit button and graphics: XML\Art\CIV4ArtDefines_Unit.xml 6) Text If you have given your new civilization/leader/unit/building a new TXT_KEY_..., it will show up as that in the game because you haven't yet defined what the text key refers to. You can do that in the XML\Text\ folder. The names of the files in there are very explicit and descriptive, and for the sake of clarity you should put everything in its appropriate file. The DynamicNames subfolder is for dynamic names (duh), should also create a new file named DynamicNames_[your civ's name].xml there where you can store its dynamic names. You don't have to put in anything there for the mod to work. Adding a new player to the scenario Right now we are at the stage where a new civ with all its stuff is in the civilopedia, but doesn't exist in the scenario. The mod should run fine, but behave unexpectedly in some occasions. That is because several Python and C++ constants still need to be adjusted after you have added new civs, buildings and units to the XML files. All of this will happen in the process. 7) Scenario files: Private Maps\ This is where new players can be added. The following changes are required for all scenarios in this folder. Adding a team: as I said, every player needs its own team, so you first have to add a new team. You can do this by adding another Code: BeginTeam EndTeam to the long list of identical statements right at the beginning of the file. You don't have to set anything else for teams (don't worry about techs, we're going to do that in Python later). Adding a player: Just replicate the pattern from the other players: Code: BeginPlayer LeaderType=[The leader you have added to the XML] CivType=[The civilization you have added to the XML] Team=[The position of this player entry in the list of player entries] PlayableCiv=1 Handicap=HANDICAP_PRINCE EndPlayer The position of this entry is very important because the order of entries determines the order of players in the selection screen of the scenario. This order has to be identical to the order of spawn dates, and must be the same in all scenarios (don't worry if this civ is already alive at the beginning of one of the scenarios). The Team variable has to be ascending for all entries. That means you must increment this value for all players that come after your new one. If you have multiple leaders, the leader entry only determines who you will see in the selection screen (and the human players leader as far as savegame name suggestions etc. are concerned). AI leaders will always be assigned by Python. If your scenario has independents and barbarians present at the beginning of the game (anything except 3000 BC), you must find all their unit (BeginUnit/EndUnit) and city (BeginCity/EndCity) entries and increment their UnitOwner/CityOwner values by one. This is because your new player has invariably been inserted before the independents and barbarians, which means their ID has increased by one, which you now have to account for. The same goes for the PlayerXXCulture=Y entries for cities, where you have to increment XX by one. Your new player now exists in the scenario. At this point, the mod is guaranteed to crash on start. To fix this, the new player has to be accounted for in the DLL. DLL adjustments 8) Increase the maximum number of players: CvDefines.h Find the line that begins with #define MAX_CIV_PLAYERS and increment its value by one. 9) Defining the new player's constant: CvEnums.h Find the entry "enum PlayerTypes" and add a new constant for your civilization according to its position in the scenario files. Even if you do not intend to use the constant in C++ code (likely if you don't want to code special effects for them), you have to add it so the constants for all following players are increased by one corresponding to their new position. 10) Adjusting global constants: CvRhyes.h Depending on your changes, you have to increment a couple of constants here by one: - BEGIN_WONDERS (unless your civ's unique building has already been in the game) - NUM_BUILDINGS_PLAGUE (unless your civ's unique building has already been in the game) - NUM_MAJOR_PLAYERS - NUM_PL - NUM_CIVS (unless your player's civilization has already been in the game) 11) CvGame.cpp initDiplomacy(): you can define here if you want your player to be at war with the Independents at the start of a scenario (All AI code is optional - the game will run without it - but strongly encouraged to give your new civ a unique and historically appropriate behavior.) 12) Further AI stuff: CvCityAI.cpp (always use the constant you defined in CvEnums.h). AI_bestUnit(): find the switch statement for multiple civilizations and add your civilization here if you want it to prioritize building specific unit types. AI_bestBuildingThreshold(): find the switch statement for multiple civilizations and add your civilization here if you want it to prioritize or avoid specific wonders. 13) Further AI stuff: CvPlayerAI.cpp AI_bestTech(): find the switch statement for multiple civilizations and add your civilizations here if you want it to prioritize or avoid specific technologies. AI_bestReligion(): add your civ to this check if you don't want it to convert to Christianity too easily With this, we're done with the DLL changes, you only have to compile your code now. It's important to rebuild the entire project because you changed some header files. Python adjustments All of these files are in Assets\Python\. 14) Set constants: Consts.py This is basically the Python equivalent of CvRhyes.cpp, which means that you have a lot to do. Increase iNumPlayers by one and add a constant for your player in the list below it (order according to scenario file). Increase iNumCivilizations by one and add a constant for your civilization in the list below it (order according to the XML file). After that comes a list of geographical groups where you have to insert your player according to its location, it should always be in one group per type. lNeighbors: insert into list of all players your new player is a neighbor to, and add an own list of neighbors for this player lOlderNeighbors: as neighbors, but only includes those that have spawned before tBirth: insert your spawn year in the correct location in the tuple tFall: year after which a civilization becomes more unstable tVictoryYears: to display the turn in the victory goal display tRebirth: scripted respawn, make sure to add a -1 for your civ even if you don't want it to respawn tRebirthCiv: the civilization a player respawns as (add -1) tResurrectionIntervals: list of intervals in which a civ can randomly respawn, add an empty list even if you don't want it to respawn tYear: starting year and BC/AD tGoals: UHV goal text keys again, this time accounting for game speed too (marathon/epic/normal), tGoals2 is for respawns again, just copy tGoals1 if you don't want it to respawn dDawnOfMan3000BC: add your civ here (order doesn't matter here, but I suggest you keep it), you can define the text key XML\Text\CIV4GameText_Dawn_of_Man.xml. If your player is available from start in later scenarios, you might want to set a different DOM text in the following dictionaries. The following entries are double for respawns again, just do it twice if you don't want to define a respawn. Order is important again. tStartingGold: gold at the beginning of the game lEnemyCivsOnSpawn: chance to start at war with (multiple entries increase chances) lTotalWarOnSpawn: if it starts at war with these civs, the war will be fought longer tAggressionLevel: how often the AI will start wars tAIStopBirthThreshold: the chance to fight a newly spawned civ tResurrectionProb: chances for a random resurrection tPatienceThreshold: how the civ reacts to bribes tMaxColonists: number of free settlers and ships the AI will receive during the game Increase iNumUnits by one if you added a UU, and add a constant for it in the correct location according to the XML in the list below. Increase iNumBuildings by one if you added a UB, and add a constant for it in the correct location according to the XML in the list below. Increase iNumLeaders by the amount of leaders you have added, and insert constants for them into the list below. In the following, a lot of further maps and constants for your new civilization are defined. They are defined by its civilization constant (iCivXXX) not the player constant (iXXX) unless otherwise noted. The order of insertion does not matter, but for the sake of clarity I suggest inserting them according to spawn date like the existing entries are ordered. 15) Define AI settler maps: SettlerMaps.py This map (dWarMaps) influences both AI settling behavior and the historicity of a tile. A value of 90 or higher makes a historical tile. This is also the value for which the AI will usually settle a tile, the higher it is, the more likely for this tile to be chosen. 20 is chosen for water tiles. 40-90 can be settled by the AI, but are rarely prioritized. Values of 3 mean the tile is forbidden from settling. 16) Define AI war maps: WarMaps.py The dWarMaps map determines how much cities on a specific tile will be targeted in wars by this civilization (useful to guide its conquests in a historical way). Values between 0-10 are used. 10 is usually for their own core which they ought to recover at all costs, 8 for important historical expansion. This map also increases chances of declaring war against players holding many cities with high values here. 17) Define capital locations, birth, core, and further areas: Areas.py Here, entries in tuples (beginning with t) are required and dictionaries (beginning with d) are optional. All entries in this file are by player constant (iXXX). If the elements are a pair of tuples, they describe the bottom left and top right corners of a rectangle. tCapital: starting location dChangedCapitals: new capital locations after rebirth etc. (bReborn = true) dNewCapitals: dynamic capital location changes triggered by a specific event (entering an era etc.) dRespawnCapitals: new capital locations after random respawns tBirthArea: area flipped on spawn dBirthAreaExceptions: tiles excluded from birth area tCoreArea: the core of the civilization dChangedCoreArea: new core area after respawn etc. (bReborn = true) dCoreAreaExceptions: tiles excluded from core area dChangedCoreAreaExceptions: tiles excluded from changed core area (The pattern for corea areas repeats for normal and broader areas) dRespawnArea: area flipped on respawn, if different from core dRebirthPlot: the spawn plot for a reborn civilization dRebirthArea: are flipped on rebirth dRebirthAreaExceptions: tiles excluded from rebirth area 18) Civilization modifiers: Modifiers.py Add your civilization to the lOrder list according to its spawn date. This is the position of your civ in the following tuples of modifiers. The purpose of the modifiers should be evident from their names. Except tHealth, they are all in percentage points. 19) Parameters influencing AI behavior: AIParameters.py All entries here are optional, if left your civ will use the default values you can find in the getter methods. dTakenTilesThreshold: maximum number of culturally controlled tiles (by another city) the AI will tolerate for a new city location dDistanceSubtrahend: the higher the value, the closer the AI will build its cities to existing cities dDistanceFactor: the higher the value, the more the distance to other cities will affect city locations chosen by the AI dCompactnessModifier: the higher the value, the more the AI will prefer to found new cities close to its own existing cities (compact vs far flung empires) dTargetDistanceModifier: how much the distance to a target city will prevent the AI from trying to conquer it. The value is in tenths, i.e. ten is normal. dReligiousTolerance: how likely the civilization is to persecute non-state religions 20) Script their spawn: RiseAndFall.py In the beginning, you should make a copy of the constant from Consts.py and get the PyPlayer and PyTeam objects for your player. assign600ADGold(): set their starting gold if they appear in the 600 AD scenario assign1700ADGold(): set their starting gold if they appear in the 1700 AD scenario init1700ADDiplomacy(): set the relations between players at the beginning of the 1700 AD scenario createAdditionalUnits(): spawn the units received should they end up in a war on spawn createStartingUnits(): spawn the starting stack (note: the createSettlers() method spawns as many settlers as specified minus the cities already present in their core, but at least one) createRespawnUnits(): spawn units received after a scripted respawn createStartingWorkers(): spawn workers received after the capital is founded 21) Adjust barbarians: Barbs.py You might not have to do anything here, but it's worth checking if a minor city exists in your new civilizations area, in which case you might want to disable its spawn. You can also add new barbarian spawns here to challenge your new civ, or remove old ones that are now represented by a proper civilization. 22) Include in city name manager: CityNameManager.py If your new civilization has the same language as an existing civilization, you have it easy here: getLanguages(): include a check for your civilization and return the appropriate language(s). In every situation, the languages will be tried in order until one is found that has a name for this tile or city. If you want to add a new language, increment iNumLanguages by one and include it in the list below (position doesn't really matter). You still have to include your civ in the getLanguages() method as below. Afterwards, go to dFoundMaps and make a new entry for your language. As with settler and war maps, I suggest using OpenOffice Calc or a similar spreadsheet editor. Also, go to tRenames and define how your new language translates city names. Order is important here, based on where you have inserted your new language in the list above. Every city in the CNM is referenced by its identifier in tRenames. For example, the identifier for Venice is "Venezia", but defining a name for "Venezia" in tRenames will also take care for renaming "Venice", "Venedig", "Venise" and so on. You can look up a name in dIdentifiers. If you want to rename a city that is not yet handled in dIdentifiers, you have to add it to that dict. 23) Adjust the AI communications script: Communications.py Add your new player to one of the pools at the beginning of the file. I usually only choose the third one. 24) Unique Power and Unique Historical Victory: Victory.py You can code your UHV in the Victory.py file. Due to the variety of possible victory conditions I won't go into detail here, I suggest you choose similar goals to those that already exist and locate and replicate their code. Unique Powers are similar, because they are basically extra rules for potentially every aspect of the game. Usually you will have to locate the part of the code that controls the aspect you want it to affect, and then make an exception there. 25) The mod should run again now. Have fun with your new civilization!