embryodead
Caliph
After a major code overhaul in versions 0.4-0.5, I had to update this documentation, so here it is. Feel free to ask questions about RFC-SoI engine here (but for general RFC modding questions please use the The Modding Q&A Thread). The old version of this documentation (for SoI 0.3.x) is archived at the end of the post.
Introduction
SoI 0.5 removed a lot of the data hard-coded in the DLL to Python and XML. Moreover, the data is stored in the savegame. This only takes a few kilobytes and allows editing of previously hard-coded civ and map data even when the game is running. It is possible, for instance, to modify the civ balance modifiers, settler maps or war maps, with a Python event. It is also possible to have maps of different sizes in the same mod, with the same DLL.
All the relevant data from CvRhyes is now kept in Consts.py and Maps.py. It is loaded into the DLL through DataLoader.py module. CvRhyes.cpp known from RFC is no longer needed and has been removed from the project.
Below is the detailed list of files you'd typically want to edit to make your own mod.
Python
Consts.py - nearly all the data is stored here, with appriopriate descriptions; other modules use con.* constants from Consts.py, so you'll have to modify pretty much everything accordingly, file by file. Fortunately with Python exceptions and debug messages turned ON, Python will report everything in-game.
Maps.py - region maps, art style maps, AI settler maps; note that unlike the old maps in CvRhyes, these don't have to be the same size as the actual map - well, they should, but the game won't crash if they don't, which means that you don't have to prepare all the data for a new or extended map just to launch the game.
CityNameManager.py - city name map and a dictionary for city name changes.
XML
GlobalDefinesAlt.xml - this extra file contains a number of defines used by the game; comments should be sufficient
CIV4CivilizationInfos.xml - note that in RFC, SoI and other modmods, the order of civs in this file should be the same as the order in Const.py and WBSave!
WBSave
Map & player data is stored in WBSaves. Two things to remember:
- the number of teams & players must be the same as MAX_CIV_PLAYERS in CvDefines.h
- the order of teams & players should be the same as in Consts.py and CIV4CivilizationInfos.xml
CvGameCoreDLL
Here's a list of stuff that needs to be modified in the CvGameCoreDLL code. The list doesn't include all the changes I did, but ALL changes are commented usually by "edead" or "Rhye" (or modcomp name in case of Better BTS AI, Unofficial patch, BTS on Speed etc.)
CvDefines.h - MAX_CIV_PLAYERS determines the max. number of players the DLL can support; note that changing this has serious consequences, as you have to modify the following accordingly: all lists/tuples in Consts.py and other Python files, players & teams in WBSave; NUM_MAJOR_PLAYERS is the number of players excluding independents / minor civs (assuming they are placed at the end).
CvEnums.h - enums for Players, Religions, Wonders etc. are placed here, they have to be modified in accordance with XML data
CvCityAI::AI_bestUnit - civ-specific UNITAI weights
CvCityAI::AI_bestBuildingThreshold - building and location specific AI weights
CvCityAI::AI_chooseProduction - code related to air units is commented ("speed / unused features"); uncomment if you need air units
CvCity::getArtStyleType - this function replaces the default city style with another; replace style types with your own
CvCity::getReligionPercentAnger, CvCity::getReligionBadHappiness, CvCity::getRevoltTestProbability - Fatimid UP is hard-coded here
CvCity::getRealPopulation - real population formula is modified from pop^2.8 to pop^2.0
CvCity::updateCultureLevel - barbarian & minor civs are limited to culture level 2 here
CvCity::getProductionToCommerceModifier - Sindhi UP is hardcoded here
CvCity::isActiveCorporation - the code is modified so that the corporation is always active, whether the player has needed resources or not
CvCity::getGreatPeopleUnitRate, CvCity::getGreatPeopleUnitProgress - barbarian & minor civs have Great People Unit Rate reduced to 0
CvCity::doReligion - declining spread of Buddhism is hard-coded here
CvDLLTranslator.cpp - here you have some extra icons defined for use in game / civilopedia - they use enums from CvEnums.h so remove or modify this accordingly
CvDLLWidgetData.cpp - here you have the widget data for RFC/SoI leader tooltip etc.; no enums here, but if you want to modify stability, piety and title display, it's the place to look
CvMap::calculateAreas - this contains the code that splits solid continents into subcontinents for AI logic; all of this code should be removed for a new map; you can modify it as well, but I don't recommend using this feature unless you know what you're doing - splitting continents with this method makes the AI think it's actually two continents/islands split by water, so it will not link them with roads and try to use transport ships to carry units across; in SoI it's used for Oman, Bahrain and Mahra, as those areas are seperated from the rest of Arabia by unworkable desert.
CvPlayer::canConstruct - first, there's a hard-coded check that makes it impossible for Portugal to build any wonders; near the end, there's another hard-coded check that prevents the AI from building certain UHV-related wonders too early
CvPlayer::canConvert - code that disables converting to minor religions is here, uses religion enums from CvEnums.h
CvPlayer::getAnarchyModifier - code for Prophet's Mosque is hard-coded here, delete it
CvPlayer::getProductionModifier(UnitTypes eUnit) - Turkish UP is hard-coded here
CvPlayer::getProductionModifier(BuildingTypes eBuilding) - Armenian UP is hard-coded here
CvPlayer::getGreatPeopleRateModifier - Abbasid UP is hard-coded here
CvPlayer::getMaxConscript - Ottoman UP is hard-coded here
CvPlayer::verifyAlive - code that makes Portugal immortal is here
CvPlayerAI::AI_bestTech - civ-specific tech modifier (what the AI likes)
CvPlayerAI::AI_civicValue - civ-specific civic modifier (what the AI likes)
CvPlayerAI::AI_religionValue - civ-specific religion modifier (what the AI likes)
CvPlayerAI::AI_conquerCity - some years are hard-coded here, in the part that deals with AI city razing; remove it
CvPlayerAI::AI_targetCityValue - Franco-Mongol alliance is hard-coded here, uses fixed years & enums etc.; delete it all
CvPlayerAI::AI_getSameReligionAttitude and CvPlayerAI::AI_getDifferentReligionAttitude - religion relations are hard-coded here with usual enums; you don't need this unless you want something similar to SoI's Catholicism-Orthodoxy and Sunni-Shia relations
CvPlayerAI::AI_bonusTradeVal - the "Muslims not liking pigs or wine" feature is hard-code here... remove it
Extras
Attached to the post is my ODS file that contains the map data in spreadsheet format. ODS is the native format of OpenOffice/LibreOffice calc, but I'm sure MS Excel can import it somehow. This is mainly to show you how I (and Rhye) worked: all modifications are done in the spreadsheet, then I select the contents of a tab, copy it and paste to a Python or C++ file. Tab legend:
CityNames - single city name map (CityNameManager.py)
Provinces - province map (Maps.py)
ArtStyles - city art style map (Maps.py)
everything else - settler maps for all civs (also used for stability and AI wars in Maps.py)
Also check this post for a python script that will print WB map data into a CSV format that you can copy & paste to make your own spreadsheets.
Introduction
SoI 0.5 removed a lot of the data hard-coded in the DLL to Python and XML. Moreover, the data is stored in the savegame. This only takes a few kilobytes and allows editing of previously hard-coded civ and map data even when the game is running. It is possible, for instance, to modify the civ balance modifiers, settler maps or war maps, with a Python event. It is also possible to have maps of different sizes in the same mod, with the same DLL.
All the relevant data from CvRhyes is now kept in Consts.py and Maps.py. It is loaded into the DLL through DataLoader.py module. CvRhyes.cpp known from RFC is no longer needed and has been removed from the project.
Below is the detailed list of files you'd typically want to edit to make your own mod.
Python
Consts.py - nearly all the data is stored here, with appriopriate descriptions; other modules use con.* constants from Consts.py, so you'll have to modify pretty much everything accordingly, file by file. Fortunately with Python exceptions and debug messages turned ON, Python will report everything in-game.
Maps.py - region maps, art style maps, AI settler maps; note that unlike the old maps in CvRhyes, these don't have to be the same size as the actual map - well, they should, but the game won't crash if they don't, which means that you don't have to prepare all the data for a new or extended map just to launch the game.
CityNameManager.py - city name map and a dictionary for city name changes.
XML
GlobalDefinesAlt.xml - this extra file contains a number of defines used by the game; comments should be sufficient
CIV4CivilizationInfos.xml - note that in RFC, SoI and other modmods, the order of civs in this file should be the same as the order in Const.py and WBSave!
WBSave
Map & player data is stored in WBSaves. Two things to remember:
- the number of teams & players must be the same as MAX_CIV_PLAYERS in CvDefines.h
- the order of teams & players should be the same as in Consts.py and CIV4CivilizationInfos.xml
CvGameCoreDLL
Here's a list of stuff that needs to be modified in the CvGameCoreDLL code. The list doesn't include all the changes I did, but ALL changes are commented usually by "edead" or "Rhye" (or modcomp name in case of Better BTS AI, Unofficial patch, BTS on Speed etc.)
CvDefines.h - MAX_CIV_PLAYERS determines the max. number of players the DLL can support; note that changing this has serious consequences, as you have to modify the following accordingly: all lists/tuples in Consts.py and other Python files, players & teams in WBSave; NUM_MAJOR_PLAYERS is the number of players excluding independents / minor civs (assuming they are placed at the end).
CvEnums.h - enums for Players, Religions, Wonders etc. are placed here, they have to be modified in accordance with XML data
CvCityAI::AI_bestUnit - civ-specific UNITAI weights
CvCityAI::AI_bestBuildingThreshold - building and location specific AI weights
CvCityAI::AI_chooseProduction - code related to air units is commented ("speed / unused features"); uncomment if you need air units
CvCity::getArtStyleType - this function replaces the default city style with another; replace style types with your own
CvCity::getReligionPercentAnger, CvCity::getReligionBadHappiness, CvCity::getRevoltTestProbability - Fatimid UP is hard-coded here
CvCity::getRealPopulation - real population formula is modified from pop^2.8 to pop^2.0
CvCity::updateCultureLevel - barbarian & minor civs are limited to culture level 2 here
CvCity::getProductionToCommerceModifier - Sindhi UP is hardcoded here
CvCity::isActiveCorporation - the code is modified so that the corporation is always active, whether the player has needed resources or not
CvCity::getGreatPeopleUnitRate, CvCity::getGreatPeopleUnitProgress - barbarian & minor civs have Great People Unit Rate reduced to 0
CvCity::doReligion - declining spread of Buddhism is hard-coded here
CvDLLTranslator.cpp - here you have some extra icons defined for use in game / civilopedia - they use enums from CvEnums.h so remove or modify this accordingly
CvDLLWidgetData.cpp - here you have the widget data for RFC/SoI leader tooltip etc.; no enums here, but if you want to modify stability, piety and title display, it's the place to look
CvMap::calculateAreas - this contains the code that splits solid continents into subcontinents for AI logic; all of this code should be removed for a new map; you can modify it as well, but I don't recommend using this feature unless you know what you're doing - splitting continents with this method makes the AI think it's actually two continents/islands split by water, so it will not link them with roads and try to use transport ships to carry units across; in SoI it's used for Oman, Bahrain and Mahra, as those areas are seperated from the rest of Arabia by unworkable desert.
CvPlayer::canConstruct - first, there's a hard-coded check that makes it impossible for Portugal to build any wonders; near the end, there's another hard-coded check that prevents the AI from building certain UHV-related wonders too early
CvPlayer::canConvert - code that disables converting to minor religions is here, uses religion enums from CvEnums.h
CvPlayer::getAnarchyModifier - code for Prophet's Mosque is hard-coded here, delete it
CvPlayer::getProductionModifier(UnitTypes eUnit) - Turkish UP is hard-coded here
CvPlayer::getProductionModifier(BuildingTypes eBuilding) - Armenian UP is hard-coded here
CvPlayer::getGreatPeopleRateModifier - Abbasid UP is hard-coded here
CvPlayer::getMaxConscript - Ottoman UP is hard-coded here
CvPlayer::verifyAlive - code that makes Portugal immortal is here
CvPlayerAI::AI_bestTech - civ-specific tech modifier (what the AI likes)
CvPlayerAI::AI_civicValue - civ-specific civic modifier (what the AI likes)
CvPlayerAI::AI_religionValue - civ-specific religion modifier (what the AI likes)
CvPlayerAI::AI_conquerCity - some years are hard-coded here, in the part that deals with AI city razing; remove it
CvPlayerAI::AI_targetCityValue - Franco-Mongol alliance is hard-coded here, uses fixed years & enums etc.; delete it all
CvPlayerAI::AI_getSameReligionAttitude and CvPlayerAI::AI_getDifferentReligionAttitude - religion relations are hard-coded here with usual enums; you don't need this unless you want something similar to SoI's Catholicism-Orthodoxy and Sunni-Shia relations
CvPlayerAI::AI_bonusTradeVal - the "Muslims not liking pigs or wine" feature is hard-code here... remove it
Extras
Attached to the post is my ODS file that contains the map data in spreadsheet format. ODS is the native format of OpenOffice/LibreOffice calc, but I'm sure MS Excel can import it somehow. This is mainly to show you how I (and Rhye) worked: all modifications are done in the spreadsheet, then I select the contents of a tab, copy it and paste to a Python or C++ file. Tab legend:
CityNames - single city name map (CityNameManager.py)
Provinces - province map (Maps.py)
ArtStyles - city art style map (Maps.py)
everything else - settler maps for all civs (also used for stability and AI wars in Maps.py)
Also check this post for a python script that will print WB map data into a CSV format that you can copy & paste to make your own spreadsheets.