View RSS Feed

Dale

Civ 5 Modding Tutorial 2: Religion Mod - XML

Rating: 28 votes, 4.86 average.
Welcome to the second of my Civ 5 mod tutorial series.

To quickly recap on tutorial 1, we covered the basic fundamentals of modding Civ 5. We look at how the backend data store operates, the in-game XML->SQL converter as well as an example of how everything can be tied in. The biggest thing people should've taken from tutorial 1 is that the data store for Civ 5 operates like a big database, with tables rows and columns. A bit like a giant spreadsheet.

Religion mod:
For these tutorials, I believe that explaining things using real examples is important. If the reader has a clue about the example, then they will find it easier to pick up the lesson. So for these tutorials, we are going to make a religion mod for Civ 5.

This is how it'll work:
- There will be five religions in the game: Christian, Jewish, Hindu, Buddhist and Muslim.
- Each religion will become available on researching a tech.
- A religion can only be associated with one Civ, but can spread to any Civ.
- The capital city of the Civ that finishes the relevant tech first, will become the Holy City of that religion.
- A new unit, the Missionary, will spread religion to other cities.
- A Missionary can only be built in cities with a religion.
- A Missionary spreads religion by being adjacent to a city. It is used up in the action.
- Religious buildings will generate Prayers and at certain threshold levels will generate a Great Priest.
- The Great Priest can start a golden age, or remove any religion from a city. It is used up in these actions.

So there we go. That should cover it all. Let's get started eh?

Getting the tools:
If you haven't already, go get Sid Meier's Civilization V SDK off the Library-->Tools menu of Steam's client program. This will download the necessary tools you need to create a mod. Once they're downloaded, right-click on the entry in Steam and click on Create Desktop Shortcut. This will make things a LOT better over the next few weeks as we progress through this mod.

Now you've got the fundamentals, you've got the idea, you've got the tools, let's put it in action!

Setting up ModBuddy for the mod:
Open ModBuddy by running the new desktop shortcut, and click on ModBuddy. The program that opens looks like a professional development environment. Well it is! ModBuddy is actually a customised version of Microsoft Visual Studio Shell, which means we'll be making mods like professional programmers.

Now once ModBuddy is open, click on New Mod from the menu on the left. This opens a new window where we set the mod's filenames. Now it's fairly important to get the names in these first few windows right, as they determine a lot of things further down the track, even as far as what folder name any players of the mod will receive in their Mods folder. Make sure Empty Mod is selected, and type in DalesModBlogReligionMod for the Name. You'll notice that Solution Name fills in too, leave this be as we want the solution name to be the same as the mod's name. Click on OK and the mod General Information window will appear. Fill in Dales Mod Blog Religion Mod for the Title (this is the name that appears in the Mod Browser in game), the author (that's you), any special thanks you want to give, and the Description (I simply put Dales Mod Blog Religion Mod in here). We'll come to the Description in a later tutorial so don't worry about it at the moment.

Finally, click on Finish and you're new mod is now created! But don't get too excited yet, it doesn't actually DO anything at this point.

Adding some XML:
Since all game objects are stored in XML, and we need some new objects for our Religion Mod, it's pretty obvious we're going to need an XML file in the mod. But firstly, here's some important information. Civ 5 comes with a pretty strict file and folder format for the XML files. For instance, any buildings in the core game are defined in /Assets/Gameplay/XML/Buildings/CIV5Buildings.xml. Luckily for us modders, we do not need to stick to this format. We can have our XML files named anything, in any location, and actually can have all our XML in a single file or a million files if we wanted. There is no restriction here (unlike Civ 4 where you had to follow folder and file formats).

Click on the Project menu and select Add New Item. This opens the new item window with a number of Civ 5 file formats to select from. We want a Game Rules (XML) file, so click on that. Then type in a name for the file. I've chosen to type in ReligionMod.xml for the filename. Lastly, click on Add to create the file. ModBuddy will now create our XML file, list it on the right in our solution, and open the file in the main window. At this point you should see the following templated items:

Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Created by ModBuddy on 11/29/2010 10:15:12 PM -->
<GameData>
  <!-- TODO: Insert table creation example here. -->
 
  <!-- TODO: Insert table data example here.-->
  
  <!-- Enter your Game Data here. -->
  
</GameData>
All XML data is GameData, so everything we define in XML will go between those two lines. In XML, each item in the file is known as a tag. A tag must be open and then closed. In the code above you'll see the tag in the last line has a slash before the word GameData. This means this tag is the closing. The GameData tag with no slash, is the opening. This means anything between the opening and the closing is of the type GameData. This is good, that means anything in this file will load into Civ 5's data store.

XML also works in a nested format. This means that each tag can have what's called children tags. These are tags contained WITHIN another tag. The tag which contains the child tag, is known as the parent of the child tags. And these children tags can have further children tags. And so on, and so on. Each parent may hold multiple children tags. But each child tag may only ever have one parent tag. So we get something like the following:

Code:
<Level1>
	<Level2>
		<Level3a>
			<Level4>
			</Level4>
		</Level3a>

		<Level3b>
			<Level4>
			</Level4>
		</Level3b>
	</Level2>
</Level1>
Notice that Level3 exists twice within Level2. In Civ 5 terms, this would be the equivalent of two units within the Units table. Level4 is a properties of the units, such as movement, strength, graphic to use, etc.

In terms of file setup, each level within the XML file has a specific purpose. Here is how each level relates to Civ 5:
- Level1: For defining objects via XML, this will always be the GameData tag. This is different for UI and text components, but we'll cover them in a later tutorial.
- Level2: This level is the database table definition. This tells the game what table (or set of objects) you are addressing. In our case for the Missionary, the table we're interested in is Units. If you know some SQL, then you can consider it as SELECT * from Units.
- Level3: Think of this level as each row (or individual object) within the table. When considering the Units table, each row represents a different unit type within the game, such as settler, worker or warrior.
- Level4: Here is where the properties of the row are defined. The properties are the columns within the database. Examples for our Missionary include moves, strength and text definitions.

Adding our Missionary:
One of the best things about modding Civ 5, is that Firaxis have provided us with perfect copy/paste material for creating our objects. For instance, there's heaps of units within Civ 5 that we could copy/paste into our XML file, and then modify as we need to define our unit's properties.

Search for and open the file ../Steam/Steamapps/Common/Sid Meiers Civilization V/Assets/Gameplay/XML/Units/CIV5Units.xml

Scroll down until you find the following lines:
Code:
		<Row>
			<Class>UNITCLASS_WORKER</Class>
			<Type>UNIT_WORKER</Type>
We are going to copy/paste the worker as a template for our missionary. Our missionary will be a citizen (no combat) and will be captured if attacked by an enemy. So for our purposes, the worker will do fine. To start, you need to specify what table we are modifying. Add the <Units> tag as below (Don't forget the closing tag) in ModBuddy.

Code:
  <!-- Enter your Game Data here. -->
	<Units>
	</Units>
</GameData>
Now select ALL lines between <Row> and </Row> which contains the worker's information in CIV5Units.xml. In ModBuddy, paste this information under the line which says <Units>. You should now have something that looks like this.
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Created by ModBuddy on 11/29/2010 10:15:12 PM -->
<GameData>
  <!-- TODO: Insert table creation example here. -->
 
  <!-- TODO: Insert table data example here.-->
  
  <!-- Enter your Game Data here. -->
	<Units>
		<Row>
			<Class>UNITCLASS_MISSIONARY</Class>
			<Type>UNIT_MISSIONARY</Type>
			<Cost>70</Cost>
			<Moves>2</Moves>
			<Capture>UNITCLASS_WORKER</Capture>
			<Domain>DOMAIN_LAND</Domain>
			<DefaultUnitAI>UNITAI_WORKER</DefaultUnitAI>
			<Description>Missionary</Description>
			<Civilopedia>TXT_KEY_CIV5_ANTIQUITY_WORKER_TEXT</Civilopedia>
			<Strategy>TXT_KEY_UNIT_WORKER_STRATEGY</Strategy>
			<Help>TXT_KEY_UNIT_HELP_WORKER</Help>
			<AdvancedStartCost>20</AdvancedStartCost>
			<WorkRate>0</WorkRate>
			<CombatLimit>0</CombatLimit>
			<UnitArtInfo>ART_DEF_UNIT__WORKER</UnitArtInfo>
			<UnitArtInfoEraVariation>true</UnitArtInfoEraVariation>
			<UnitFlagIconOffset>1</UnitFlagIconOffset>
			<PortraitIndex>1</PortraitIndex>
			<IconAtlas>UNIT_ATLAS_1</IconAtlas>
		</Row>
	</Units>
</GameData>
Now to make our unit unique, we need to change some of these entries so we get our Missionary, and so we don't get errors in our mod. Change the italicized lines below in ModBuddy.

Code:
		<Class>UNITCLASS_MISSIONARY</Class>
		<Type>UNIT_MISSIONARY</Type>
		<Cost>70</Cost>
		<Moves>2</Moves>
		<Capture>UNITCLASS_WORKER</Capture>
		<Domain>DOMAIN_LAND</Domain>
		<DefaultUnitAI>UNITAI_WORKER</DefaultUnitAI>
		<Description>Missionary</Description>
		<Civilopedia>TXT_KEY_CIV5_ANTIQUITY_WORKER_TEXT</Civilopedia>
		<Strategy>TXT_KEY_UNIT_WORKER_STRATEGY</Strategy>
		<Help>TXT_KEY_UNIT_HELP_WORKER</Help>
		<AdvancedStartCost>20</AdvancedStartCost>
		<WorkRate>0</WorkRate>
		<CombatLimit>0</CombatLimit>
		<UnitArtInfo>ART_DEF_UNIT__WORKER</UnitArtInfo>
		<UnitArtInfoEraVariation>true</UnitArtInfoEraVariation>
		<UnitFlagIconOffset>1</UnitFlagIconOffset>
		<PortraitIndex>1</PortraitIndex>
		<IconAtlas>UNIT_ATLAS_1</IconAtlas>
Now, the unit isn't finished yet. If you scroll down a lot further past all the units, you'll find some more definitons for UNIT_WORKER. We need to copy that information as well. Between the </Units> and </GameData> tags copy and paste the following code. I've already changed the information for our Missionary.

Code:
	<Unit_AITypes>
		<Row>
			<UnitType>UNIT_MISSIONARY</UnitType>
			<UnitAIType>UNITAI_WORKER</UnitAIType>
		</Row>
	</Unit_AITypes>
	<Unit_Flavors>
		<Row>
			<UnitType>UNIT_MISSIONARY</UnitType>
			<FlavorType>FLAVOR_RECON</FlavorType>
			<Flavor>15</Flavor>
		</Row>
	</Unit_Flavors>
That's all for CIV5Units.xml. But to get a unit into the game, there's one more piece of vital information the game needs. If you notice in our Unit definition, we have defined the unit class as UNITCLASS_MISSIONARY. Unit classes are defined in the file CIV5UnitClasses.xml. Once again we copy/paste the worker's unit class definition into our XML file, and make the following changes.

Code:
	<UnitClasses>
		<Row>
			<Type>UNITCLASS_MISSIONARY</Type>
			<Description>Missionary</Description>
			<DefaultUnit>UNIT_MISSIONARY</DefaultUnit>
		</Row>
	</UnitClasses>
NOW, we're finished with our Missionary.

Getting a mod into the game:
At the moment, we have a mod setup with an XML file that defines the Missionary unit for our religion mod. However, if we were to load up Civ 5 now, it wouldn't appear in the game. We have to compile our mod before it will show up in Civ 5. We won't publish the mod at this stage (upload to the public Mod Hub) because we are not finished.

Click on the Project menu in ModBuddy, and then click DalesModBlogReligionMod Properties. This brings up a screen similar to one we saw when we setup the mod, but with some more options, and tabs on the left. What we need to do now is tell the game to load our XML file and process it into the data store (game database). Click on the Actions tab. The actions tab is to tell the game to perform certain actions when the mod is loaded. For now, we want the game to update the database with our new XML file, so the Missionary will be in the game. Click on the first row under the Set column. Type in OnModActivated. This means this action will be performed when someone clicks on the Enable button in the Mod Browser. The type of action we want to perform is to update the database. Type in UpdateDatabase under the heading Type. The last column simply wants the name of the file to process. The filename is ReligionMod.xml, type this in under the heading FileName. This tab should now look like the following.



In the modinfo file (the configuration file which tells the game how to load our mod from the Mod Browser) will now include the following section. But you don't need to worry about this as ModBuddy sets this file up for you.

Code:
  <Actions>
    <OnModActivated>
      <UpdateDatabase>ReligionMod.xml</UpdateDatabase>
    </OnModActivated>
  </Actions>
So to recap, our XML file now looks like the below.

Spoiler:

Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Created by ModBuddy on 11/29/2010 10:15:12 PM -->
<GameData>
  <!-- TODO: Insert table creation example here. -->
 
  <!-- TODO: Insert table data example here.-->
  
  <!-- Enter your Game Data here. -->
	<Units>
		<Row>
			<Class>UNITCLASS_MISSIONARY</Class>
			<Type>UNIT_MISSIONARY</Type>
			<Cost>70</Cost>
			<Moves>2</Moves>
			<Capture>UNITCLASS_WORKER</Capture>
			<Domain>DOMAIN_LAND</Domain>
			<DefaultUnitAI>UNITAI_WORKER</DefaultUnitAI>
			<Description>Missionary</Description>
			<Civilopedia>TXT_KEY_CIV5_ANTIQUITY_WORKER_TEXT</Civilopedia>
			<Strategy>TXT_KEY_UNIT_WORKER_STRATEGY</Strategy>
			<Help>TXT_KEY_UNIT_HELP_WORKER</Help>
			<AdvancedStartCost>20</AdvancedStartCost>
			<WorkRate>0</WorkRate>
			<CombatLimit>0</CombatLimit>
			<UnitArtInfo>ART_DEF_UNIT__WORKER</UnitArtInfo>
			<UnitArtInfoEraVariation>true</UnitArtInfoEraVariation>
			<UnitFlagIconOffset>1</UnitFlagIconOffset>
			<PortraitIndex>1</PortraitIndex>
			<IconAtlas>UNIT_ATLAS_1</IconAtlas>
		</Row>
	</Units>
	<Unit_AITypes>
		<Row>
			<UnitType>UNIT_MISSIONARY</UnitType>
			<UnitAIType>UNITAI_WORKER</UnitAIType>
		</Row>
	</Unit_AITypes>
	<Unit_Flavors>
		<Row>
			<UnitType>UNIT_MISSIONARY</UnitType>
			<FlavorType>FLAVOR_RECON</FlavorType>
			<Flavor>15</Flavor>
		</Row>
	</Unit_Flavors>
	<UnitClasses>
		<Row>
			<Type>UNITCLASS_MISSIONARY</Type>
			<Description>Missionary</Description>
			<DefaultUnit>UNIT_MISSIONARY</DefaultUnit>
		</Row>
	</UnitClasses>
</GameData>


The final step to get a mod from ModBuddy into the game is to compile the mod. Click the Build menu and select Build Solution. You should see the following in the bottom Output screen (the inner lines might not appear, as long as Build: 1 succeeded shows on the bottom line).

Code:
------ Build started: Project: DalesModBlogReligionMod, Configuration: Default x86 ------
		Creating target folder structure...
		Copying files...
		Packaging mod...
		Deploying mod...
		Mod deployed.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
Mods in the game:
So we've created a mod, added an XML file, defined a unit, set the mod actions and compiled it. What's next? Why, we go and look at the new unit in the game. Open Civ 5 and click on the Mods menu item. Select Browse Mods and enable your new mod by clicking on the green tick button on the right of the mod's line. Then click Back, Single Player and then Set up game. Configure the options you want and click Play. You'll now find your unit is in the game. To check, either look in the Civolopedia, or open a city's build options as the Missionary is available to build from the start of the game (we'll change this in a later mod).

Obtaining the code for this tutorial:
For your reference, I have uploaded the full mod project for this tutorial to the Mod Hub. Search for Dales Mod Blog to find the mod, and download and install the mod. This will enable the full tutorial code as written above. Attached at the bottom of this blog you will find a zip file containing the actual ModBuddy project. Simple unzip this file and place in the folder ../My Documents/Firaxis ModBuddy/ and open the project in ModBuddy.

Please post any comments, and let me know how you went with this tutorial.
Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	ModBlogTut2.jpg 
Views:	13752 
Size:	61.3 KB 
ID:	9176  
Attached Thumbnails Attached Files

Updated 29-11-10 at 13:15 by Dale

Categories
Uncategorized

Comments

  1. dalhamir's Avatar
    Thanks a lot for making this tutorial, it looks really interesting and I can't wait to get started modding.

    I did have one question however. Instead of changing <WorkRate> to 0, couldn't you delete the line? It looks like WorkRate is set to 0 by default. Not that it's a huge deal at this stage, I just mostly want to make sure I understand how things are working.

    Maybe you chose to do it that way for style (it's hard to italicize a deletion)? Or am I missing something?
  2. Dale's Avatar
    Hi dalhamir, yes you could just delete that line if you wanted to. It does no harm to specify it though.
  3. MarathonMan's Avatar
    Just a nit, but in the section that starts: "Now select ALL lines between <Row> and </Row>", in the code window it should show the xml for the worker unit and not the modified xml for the new missionary unit.
  4. crashtheparty's Avatar
    Okay, so i did everything up there. Now, when I go into the mods section in the game, i dont see mine anywhere. Any help?
  5. Jaom's Avatar
    Ive done everything right... but when I go into the game.. to "Browse mods" theres nothing, no new mods to click on... plz help :P
  6. Jrobwhodat's Avatar
    i rated this a 1 because you didn't finish the mod, all you did was create a missionary, where can I go to get a tutorial for the whole mod?