NycholusV
Chieftain
This is the second chapter of my guide on modifiers, explaining the underlying anatomy of the modifiers system including dynamic modifiers (modifier types), effects and collections.
Moderator Action: link to compromised site removed
I apologise for how long it's taken to get this second chapter out. I've been very busy working on other civ-related things, such as my map script which is still a work-in-progress.
In this chapter, you will learn how to define your own dynamic modifiers, which will allow for a very high degree of versatility in your modding. We will once again be creating a basic ‘balance patch’ as an example for you to follow along with, that will make the following changes:
Moderator Action: Chapter 2 content copied below
Download the example mod. Please do not attempt to copy and paste code from this webpage; this will not work due to the way that WordPress formats inverted commas.
In this chapter, you will learn how to define your own dynamic modifiers, which will allow for a very high degree of versatility in your modding. We will once again be creating a basic ‘balance patch’ as an example for you to follow along with, that will make the following changes:
In the last chapter, we created and implemented modifiers using modifier types predefined in the base game. Now, we are going to move onto defining our own modifier types. The ability to define your own modifier types opens up an even greater degree of flexibility in your modding endeavours. Furthermore, it is important to understand how modifier types work to appreciate the overall anatomy of the modifier system, to assist in debugging, and because they relate to modifier arguments and requirements.
Modifier types are defined in the DynamicModifiers table. It is important to note that dynamic modifier and modifier type are essentially synonymous terms, with DynamicModifiers used as the name of the table, and ModifierType used as the column name. Modifier types consist of two crucial components – an effect and a collection. Effects and collections are the hard-coded roots of the modifier system. The definitions of effects and collections cannot be changed without going beyond the scope of XML/SQL based modding. Thus, modifier types are the most fundamental components that are open to modding.
So what exactly are effects and collections? We’ll start with effects. The effect is the actual change in the game that is applied by the modifier. Be it an increase in border expansion, the granting of a free unit, or a yield bonus – it is the effect that is responsible for taking action and changing something in the game. But what is this something that the effect changes? Well, recall in the last chapter, we talked about the subjects of modifiers being what the modifier applies to. Going deeper into the structure of the modifier system, the subjects are the something that the effect changes. And this is fundamentally what an effect is – it is what a modifier uses to produce a change in the subjects.
But how does the game know what the subjects actually are? This brings us to collections. The subjects of a modifier are actually defined by the collection. A collection is simply a group of entities in the game to which a modifier can apply to, i.e. the valid subjects of a modifier. Remember that the entity-modifier tables determine the owner of the modifier, which is what the modifier is attached to. So the owner of a modifier is determined by the entity-modifier tables and the subjects are determined in the DynamicModifiers table, as collections. But as you will see in the examples, there are many collections which are relative to the owner. For instance, there is a collection called PLAYER_CITIES which refers to all of the cities possessed by the player to whom the modifier is attached. This allows you to attach a modifier to a player (whether it be via a trait, policy, Great Person, etc.) and have the effect applied only to that player’s cities. So, while the owner and the subjects are very distinct concepts, the subjects can be relative to the owner. Of course, it is not the case than any effect can be applied to any collection. If you try creating a dynamic modifier using ADJUST_CITY_GROWTH as the effect and ALL_UNITS as the collection, you will find that this will not work, as it is clearly nonsensical to be “adjusting the city growth rate of a unit”. An exhaustive list of collections can be found in GameEffects.xml, but check out the reference page for collections which also contains detailed explanations for your convenience (coming soon).
As mentioned previously, the effect and the collection are the only two components of a modifier type. A ModifierType simply takes an effect and specifies a collection for it to be applied to. Just as the entries of the Modifiers table can be thought of a particular fashioning of a ModifierType, a ModifierType can be thought of as a particular fashioning of an effect. You can create different modifier types to apply the same effect to all cities, to cities possessed by a player only, to capital cities only, and so on. Hopefully this gives you an appreciation and understanding of the hierarchy of the modifier system. A modifier uses a particular modifier type for a single specific purpose, and a modifier type applies a particular effect on a particular collection. A full list of effects is available in GameEffects.xml. It is intended that a reference page for effects will be available on this website soon, but given the huge number of effects, this will likely take a while.
Let’s briefly summarise the columns of the DynamicModifiers table:
Let’s start working on our balance patch. We’ll begin by filling out the entity-modifier tables like we did in the first chapter.
INSERT INTO TraitModifiers (TraitType, ModifierId)
VALUES (‘TRAIT_CIVILIZATION_FOUNDING_FATHERS’, ‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’);INSERT INTO GreatPersonIndividualActionModifiers (GreatPersonIndividualType, ModifierId, AttachmentTargetType)
VALUES (‘GREAT_PERSON_INDIVIDUAL_MIMAR_SINAN’, ‘GREATPERSON_CITY_POPULATION’, ‘GREAT_PERSON_ACTION_ATTACHMENT_TARGET_DISTRICT_IN_TILE’);
Now let’s consider how we’re going to fill in the Modifiers table. To do this we need to know what modifier types we’re going to use. When creating modifiers, always check whether the Modifiers.xml to see whether the ModifierType you intend to use already exists in the base game. It will often be the case that the ModifierType you intend to implement already exists in the base game, as was the case with all the examples in the previous chapter. Consider the first item in our balance patch. How will we know whether or not the appropriate ModifierType already exists in the base game? Remember that a ModifierType is simply defined by a particular effect applied upon a particular collection. In our case, we want to apply an increased rate of a border expansion to all of a player’s cities. So we want a ModifierType with the effect that adjusts the rate of border expansion, and the collection ‘PLAYER_CITIES’. Take a look at the Modifiers.xml file. You might try searching ‘BORDER_EXPANSION’. And sure enough, you’ll find this:
<Row>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<CollectionType>COLLECTION_ALL_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION</EffectType>
</Row>
Is this the ModifierType we’re looking for? Well, the EffectType looks like it’s correct. But the CollectionType is ‘ALL_CITIES’, which is not what we’re looking for. We want to the collection to be ‘PLAYER_CITIES’. So we have the correct effect, but not the correct collection.
An important referencing technique when searching for a ModifierType is to search the Modifiers.xml file for the EffectType. Doing so will enable you to browse through all the modifier types that use the same effect with a different collection. Now that we know the exact name of the effect we’re looking for, we can do this.
But alas, the ModifierType we just found is the only one that uses the effect we’re looking for. This means that the ModifierType we want to implement does not exist in the base game. This brings us to an important point about the creation of custom modifier types. The sole purpose of creating custom modifier types is to fill in the blanks left by the base game. There are many effect-collection combinations that are not used in the base game, but which are perfectly valid. In our case, the developers needed to create a ModifierType to adjust border expansion in all cities (specifically the Religious Settlements pantheon, of course subject to the requirement that the city follows the pantheon), but it was never necessary in the base game for this effect to apply only to a particular player’s cities. So when creating a modifier, you will want to check the Modifiers.xml file to see if the ModifierType already exists, and if it doesn’t, then you’ll have to create your own.
Let’s create the modifier type for our first component. Remember to stick to the naming conventions. It will make things much easier for you and others adapting or debugging your work.
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’, ‘COLLECTION_PLAYER_CITIES’, ‘EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION’);
There’s one more important thing you need to do to define a custom ModifierType. If you’ve been observant when looking through the Modifiers.xml file, you may already know what it is. As a general rule, anything in the game referred to as a ‘type’ requires an entry in the Types table. As you can see in Modifiers.xml, modifier types are no exception. For our new ModifierType to work, we need to add the following:
INSERT INTO Types (Type, Kind)
VALUES (‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’, ‘KIND_MODIFIER’);
Now we’ll finally add the modifier to the Modifiers table. (Note that the order of these entries in your files does not matter; how you structure your mod is up to you.)
INSERT INTO Modifiers (ModifierId, ModifierType)
VALUES (‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’, ‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’);
Originally, the second component of this balance patch was going to be a change to the inherent government bonus of Theocracy, granting +1 Amenity to all cities with a Temple. But there’s a problem with this, and it’s worth mentioning. In GameEffects.xml, you may have noticed there is an effect named EFFECT_ADJUST_BUILDING_AMENITY. If we wanted to make Temple’s provide Amenities, it would seem that this is the effect to use. We might define a dynamic modifier like this:
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_PLAYER_CITIES_ADJUST_BUILDING_AMENITY’, ‘COLLECTION_PLAYER_CITIES’, ‘EFFECT_ADJUST_BUILDING_AMENITY’);
But upon testing, one will find that this does not work, and the GameEffects.log file will reveal why. EFFECT_ADJUST_BUILDING_AMENITY is ‘not supported’ by the game, as the log file will plainly state. Be cautioned when defining custom modifier types that there are many effects not used by the game that will simply not work, like this one, and also some that appear to work but are completely mysterious in terms of what they do or how they are to be used.
Let’s move on to the actual second component of the balance patch. We’ll start as we did before, checking to ensure that the appropriate modifier type is not already available in the base game. Remember what to consider when looking for a modifier type – the effect (what the modifier does), and the collection (what the modifier acts upon). You should be able to convince yourself that there is no modifier type that changes the population of a specific single city. However, there are two that are of interest to us:
<Row>
<ModifierType>MODIFIER_PLAYER_CITIES_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_PLAYER_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
…
<Row>
<ModifierType>MODIFIER_PLAYER_NEAREST_CITY_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_UNIT_NEAREST_OWNER_CITY</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
These both use EFFECT_ADJUST_CITY_POPULATION, which is the effect we want to use. But these are the only modifier types using that effect, and neither of them use the collection we want. We want the adjustment of population to apply to only to a specific single city. The former adjusts the population of all of a player’s cities, and the latter adjusts the population of the city closest to a unit (this is used for the population tribal village). So in this case, we again need to define our own modifier type.
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘COLLECTION_OWNER’, ‘EFFECT_ADJUST_CITY_POPULATION’);
You may be somewhat confused by this. What is COLLECTION_OWNER? This is a very important collection to be familiar with. What assigning this collection essentially does is it sets the subjects of the modifier to be the owner of the modifier. In other words, what the modifier is attached to is also what it acts upon. In our entity-modifier tables earlier in this chapter, we attached our modifier to a city (remember that the Great Person entity-modifier table works slightly differently to the others, the Great Person attaches a modifier to an entity when its ability is activated). But we also want this modifier to act upon the city itself. For this reason, we use the collection COLLECTION_OWNER. And you may have noticed that in Modifiers.xml, all modifiers that refer to a ‘single city’ also use this collection. Using this collection to set the subjects of a modifier to its owner can be used not only for cities, but for any other entity in the game that a modifier can be attached to.
Don’t forget to add an entry to the Types table:
INSERT INTO Types (Type, Kind)
VALUES (‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘KIND_MODIFIER’);
For the Modifiers table, this is a case where we want to ensure that the modifier only applies once, so we will set the RunOnce and Permanent columns to ‘1’.
INSERT INTO Modifiers (ModifierId, ModifierType, RunOnce, Permanent)
VALUES (‘GREATPERSON_CITY_POPULATION’, ‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘1’, ‘1’);
Determining Modifier Arguments
We still need to do one more thing before our mod will work. As we discussed in the last chapter, many modifiers have arguments that need to be entered into the ModifierArguments table. Remember that these modifiers are assigned to a Modifier, not a modifier type. However, as was also briefly mentioned in the previous chapter, the valid arguments of a modifier are determined not by the modifier, nor the modifier type, but the effect. This is perhaps the most important reason why it is necessary to understand the anatomy of the modifier system down to the level of effects and collections. How do we know what the appropriate arguments for a modifier are? The answer to this is simply cross-referencing the base game code. The valid arguments of a modifier is always based on the effect. Another way of putting this is that all modifiers with the same effect have the same argument specifications. So to find the appropriate arguments for a modifier you are implementing, search the game code for a modifier with the same effect, and see what its arguments are.
Let’s do this for the first component of our balance patch. We want to find out the valid arguments for the effect EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION. First, we need to find a base game modifier type that uses this effect. Recall that the modifier type definitions for the base game are stored in Modifiers.xml. Earlier in the chapter, we found this entry:
<Row>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<CollectionType>COLLECTION_ALL_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION</EffectType>
</Row>
Of course, if we hadn’t found this already, it would be as easy as searching for the desired EffectType in the file.
So we have MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION as a base game modifier type that uses the same effect. Now we need to find a modifier that uses this modifier type. To do this we will search the entire Base » Assets » Gameplay » Data folder for the modifier type in question. On Windows, there should be a search bar in the top-right of the Explorer window. You may have to select the ‘Search’ tab and ensure that ‘File contents’ is marked under ‘Advanced options’. The search should return two files: Modifiers.xml (the file we were just looking at) and Beliefs.xml. Obviously any base game modifier type is going to appear in Modifiers.xml, but that file only stores the definitions of modifier types. What we’re looking for is a modifier that uses the specified modifier type. If you know Civilization 6 inside-out by now, ‘Beliefs.xml’ should ring a bell – the ‘Religious Settlements’ pantheon. Opening the file and searching the file for our modifier type, you should find this:
<Row>
<ModifierId>RELIGIOUS_SETTLEMENTS_CULTUREBORDER</ModifierId>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<SubjectRequirementSetId>CITY_FOLLOWS_PANTHEON_REQUIREMENTS</SubjectRequirementSetId>
</Row>
So now we have a modifier that uses the same effect as our modifier, and therefore has the same argument specifications as ours. Searching the file for the ModifierId in the entry, you should find this:
<Row>
<ModifierId>RELIGIOUS_SETTLEMENTS_CULTUREBORDER</ModifierId>
<Name>Amount</Name>
<Value>15</Value>
</Row>
And that right there is what we’ve been looking for. One can easily infer that Amount is referring to the percentage increase in border expansion, which is 15 for the Religious Settlements pantheon. With this knowledge, we can now create our entry in the ModifierArguments table.
INSERT INTO ModifierArguments (ModifierId, Name, Value)
VALUES (‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’, ‘Amount’, ’20’);
A few points to remember:
We are looking for a ModifierType in Modifiers.xml using the EffectType EFFECT_ADJUST_CITY_POPULATION. There are two:
<Row>
<ModifierType>MODIFIER_PLAYER_CITIES_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_PLAYER_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
…
<Row>
<ModifierType>MODIFIER_PLAYER_NEAREST_CITY_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_UNIT_NEAREST_OWNER_CITY</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
We’ll start by searching for the first one in the Data folder. This returns no results (other than Modifiers.xml). This means that for whatever reason, MODIFIER_PLAYER_CITIES_ADD_POPULATION has been included by the developers in the base game code, but is not actually used anywhere. So let’s try the second one.
This time, the search should return GoodyHuts.xml. Searching the file for the ModifierType again, we find a definition for a modifier, with ModifierId GOODY_SURVIVORS_ADD_POPULATION. Then we search the file for this, and we find:
<Row>
<ModifierId>GOODY_SURVIVORS_ADD_POPULATION</ModifierId>
<Name>Amount</Name>
<Value>1</Value>
</Row>
You should be able to infer from this what our ModifierArguments entry will look like:
INSERT INTO ModifierArguments (ModifierId, Name, Value)
VALUES (‘GREATPERSON_CITY_POPULATION’, ‘Amount’, ‘4’);
And we’re done! Once again, the changes we made in our mod will not be reflected in the game’s text, which is beyond the scope of this guide.
In the next chapter, we’ll discuss how to set up requirements for modifiers, allow you to restrict when an effect takes action on a subject based on a broad variety of parameters.
Previous chapter:
Chapter 1: Creating and attaching modifiers
Moderator Action: link to compromised site removed
I apologise for how long it's taken to get this second chapter out. I've been very busy working on other civ-related things, such as my map script which is still a work-in-progress.
* * *
In this chapter, you will learn how to define your own dynamic modifiers, which will allow for a very high degree of versatility in your modding. We will once again be creating a basic ‘balance patch’ as an example for you to follow along with, that will make the following changes:
- Founding Fathers (America’s special ability) increases the rate of border expansion by 20% in all cities.
- Mimar Sinan’s (Great Engineer) ability instantly grants +4 Population.
- Create and implement your own dynamic modifiers.
- Understand what collections and effects are and how they are used by dynamic modifiers.
- Understand how collections and effects relate to each other and to the concept of ‘subjects’.
- Appreciate why creating your own dynamic modifiers is often necessary.
- Determine what modifier arguments are valid for a modifier.
Moderator Action: Chapter 2 content copied below

Download the example mod. Please do not attempt to copy and paste code from this webpage; this will not work due to the way that WordPress formats inverted commas.
In this chapter, you will learn how to define your own dynamic modifiers, which will allow for a very high degree of versatility in your modding. We will once again be creating a basic ‘balance patch’ as an example for you to follow along with, that will make the following changes:
- Founding Fathers (America’s special ability) increases the rate of border expansion by 20% in all cities.
- Mimar Sinan’s (Great Engineer) ability instantly grants +4 Population.
- Create and implement your own dynamic modifiers.
- Understand what collections and effects are and how they are used by dynamic modifiers.
- Understand how collections and effects relate to each other and to the concept of ‘subjects’.
- Appreciate why creating your own dynamic modifiers is often necessary.
- Determine what modifier arguments are valid for a modifier.
In the last chapter, we created and implemented modifiers using modifier types predefined in the base game. Now, we are going to move onto defining our own modifier types. The ability to define your own modifier types opens up an even greater degree of flexibility in your modding endeavours. Furthermore, it is important to understand how modifier types work to appreciate the overall anatomy of the modifier system, to assist in debugging, and because they relate to modifier arguments and requirements.
Modifier types are defined in the DynamicModifiers table. It is important to note that dynamic modifier and modifier type are essentially synonymous terms, with DynamicModifiers used as the name of the table, and ModifierType used as the column name. Modifier types consist of two crucial components – an effect and a collection. Effects and collections are the hard-coded roots of the modifier system. The definitions of effects and collections cannot be changed without going beyond the scope of XML/SQL based modding. Thus, modifier types are the most fundamental components that are open to modding.
So what exactly are effects and collections? We’ll start with effects. The effect is the actual change in the game that is applied by the modifier. Be it an increase in border expansion, the granting of a free unit, or a yield bonus – it is the effect that is responsible for taking action and changing something in the game. But what is this something that the effect changes? Well, recall in the last chapter, we talked about the subjects of modifiers being what the modifier applies to. Going deeper into the structure of the modifier system, the subjects are the something that the effect changes. And this is fundamentally what an effect is – it is what a modifier uses to produce a change in the subjects.
But how does the game know what the subjects actually are? This brings us to collections. The subjects of a modifier are actually defined by the collection. A collection is simply a group of entities in the game to which a modifier can apply to, i.e. the valid subjects of a modifier. Remember that the entity-modifier tables determine the owner of the modifier, which is what the modifier is attached to. So the owner of a modifier is determined by the entity-modifier tables and the subjects are determined in the DynamicModifiers table, as collections. But as you will see in the examples, there are many collections which are relative to the owner. For instance, there is a collection called PLAYER_CITIES which refers to all of the cities possessed by the player to whom the modifier is attached. This allows you to attach a modifier to a player (whether it be via a trait, policy, Great Person, etc.) and have the effect applied only to that player’s cities. So, while the owner and the subjects are very distinct concepts, the subjects can be relative to the owner. Of course, it is not the case than any effect can be applied to any collection. If you try creating a dynamic modifier using ADJUST_CITY_GROWTH as the effect and ALL_UNITS as the collection, you will find that this will not work, as it is clearly nonsensical to be “adjusting the city growth rate of a unit”. An exhaustive list of collections can be found in GameEffects.xml, but check out the reference page for collections which also contains detailed explanations for your convenience (coming soon).
As mentioned previously, the effect and the collection are the only two components of a modifier type. A ModifierType simply takes an effect and specifies a collection for it to be applied to. Just as the entries of the Modifiers table can be thought of a particular fashioning of a ModifierType, a ModifierType can be thought of as a particular fashioning of an effect. You can create different modifier types to apply the same effect to all cities, to cities possessed by a player only, to capital cities only, and so on. Hopefully this gives you an appreciation and understanding of the hierarchy of the modifier system. A modifier uses a particular modifier type for a single specific purpose, and a modifier type applies a particular effect on a particular collection. A full list of effects is available in GameEffects.xml. It is intended that a reference page for effects will be available on this website soon, but given the huge number of effects, this will likely take a while.
Let’s briefly summarise the columns of the DynamicModifiers table:
- ModifierType: The name of the modifier type, as referenced in the Modifiers table. The naming convention for modifier type names is to always begin with ‘MODIFIER_’ followed by the name of the collection and then the name of the effect, for example:
MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION
MODIFIER_PLAYER_UNITS_ADJUST_HEAL_PER_TURN
MODIFIER_SINGLE_CITY_GRANT_PRODUCTION_IN_CITY - CollectionType: The collection that this dynamic modifier applies to, i.e. the valid subjects of the modifier.
- EffectType: The effect that this dynamic modifier applies to its subjects.
Let’s start working on our balance patch. We’ll begin by filling out the entity-modifier tables like we did in the first chapter.
INSERT INTO TraitModifiers (TraitType, ModifierId)
VALUES (‘TRAIT_CIVILIZATION_FOUNDING_FATHERS’, ‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’);INSERT INTO GreatPersonIndividualActionModifiers (GreatPersonIndividualType, ModifierId, AttachmentTargetType)
VALUES (‘GREAT_PERSON_INDIVIDUAL_MIMAR_SINAN’, ‘GREATPERSON_CITY_POPULATION’, ‘GREAT_PERSON_ACTION_ATTACHMENT_TARGET_DISTRICT_IN_TILE’);
Now let’s consider how we’re going to fill in the Modifiers table. To do this we need to know what modifier types we’re going to use. When creating modifiers, always check whether the Modifiers.xml to see whether the ModifierType you intend to use already exists in the base game. It will often be the case that the ModifierType you intend to implement already exists in the base game, as was the case with all the examples in the previous chapter. Consider the first item in our balance patch. How will we know whether or not the appropriate ModifierType already exists in the base game? Remember that a ModifierType is simply defined by a particular effect applied upon a particular collection. In our case, we want to apply an increased rate of a border expansion to all of a player’s cities. So we want a ModifierType with the effect that adjusts the rate of border expansion, and the collection ‘PLAYER_CITIES’. Take a look at the Modifiers.xml file. You might try searching ‘BORDER_EXPANSION’. And sure enough, you’ll find this:
<Row>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<CollectionType>COLLECTION_ALL_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION</EffectType>
</Row>
Is this the ModifierType we’re looking for? Well, the EffectType looks like it’s correct. But the CollectionType is ‘ALL_CITIES’, which is not what we’re looking for. We want to the collection to be ‘PLAYER_CITIES’. So we have the correct effect, but not the correct collection.
An important referencing technique when searching for a ModifierType is to search the Modifiers.xml file for the EffectType. Doing so will enable you to browse through all the modifier types that use the same effect with a different collection. Now that we know the exact name of the effect we’re looking for, we can do this.
But alas, the ModifierType we just found is the only one that uses the effect we’re looking for. This means that the ModifierType we want to implement does not exist in the base game. This brings us to an important point about the creation of custom modifier types. The sole purpose of creating custom modifier types is to fill in the blanks left by the base game. There are many effect-collection combinations that are not used in the base game, but which are perfectly valid. In our case, the developers needed to create a ModifierType to adjust border expansion in all cities (specifically the Religious Settlements pantheon, of course subject to the requirement that the city follows the pantheon), but it was never necessary in the base game for this effect to apply only to a particular player’s cities. So when creating a modifier, you will want to check the Modifiers.xml file to see if the ModifierType already exists, and if it doesn’t, then you’ll have to create your own.
Let’s create the modifier type for our first component. Remember to stick to the naming conventions. It will make things much easier for you and others adapting or debugging your work.
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’, ‘COLLECTION_PLAYER_CITIES’, ‘EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION’);
There’s one more important thing you need to do to define a custom ModifierType. If you’ve been observant when looking through the Modifiers.xml file, you may already know what it is. As a general rule, anything in the game referred to as a ‘type’ requires an entry in the Types table. As you can see in Modifiers.xml, modifier types are no exception. For our new ModifierType to work, we need to add the following:
INSERT INTO Types (Type, Kind)
VALUES (‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’, ‘KIND_MODIFIER’);
Now we’ll finally add the modifier to the Modifiers table. (Note that the order of these entries in your files does not matter; how you structure your mod is up to you.)
INSERT INTO Modifiers (ModifierId, ModifierType)
VALUES (‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’, ‘MODIFIER_PLAYER_CITIES_CULTURE_BORDER_EXPANSION’);
Originally, the second component of this balance patch was going to be a change to the inherent government bonus of Theocracy, granting +1 Amenity to all cities with a Temple. But there’s a problem with this, and it’s worth mentioning. In GameEffects.xml, you may have noticed there is an effect named EFFECT_ADJUST_BUILDING_AMENITY. If we wanted to make Temple’s provide Amenities, it would seem that this is the effect to use. We might define a dynamic modifier like this:
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_PLAYER_CITIES_ADJUST_BUILDING_AMENITY’, ‘COLLECTION_PLAYER_CITIES’, ‘EFFECT_ADJUST_BUILDING_AMENITY’);
But upon testing, one will find that this does not work, and the GameEffects.log file will reveal why. EFFECT_ADJUST_BUILDING_AMENITY is ‘not supported’ by the game, as the log file will plainly state. Be cautioned when defining custom modifier types that there are many effects not used by the game that will simply not work, like this one, and also some that appear to work but are completely mysterious in terms of what they do or how they are to be used.
Let’s move on to the actual second component of the balance patch. We’ll start as we did before, checking to ensure that the appropriate modifier type is not already available in the base game. Remember what to consider when looking for a modifier type – the effect (what the modifier does), and the collection (what the modifier acts upon). You should be able to convince yourself that there is no modifier type that changes the population of a specific single city. However, there are two that are of interest to us:
<Row>
<ModifierType>MODIFIER_PLAYER_CITIES_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_PLAYER_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
…
<Row>
<ModifierType>MODIFIER_PLAYER_NEAREST_CITY_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_UNIT_NEAREST_OWNER_CITY</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
These both use EFFECT_ADJUST_CITY_POPULATION, which is the effect we want to use. But these are the only modifier types using that effect, and neither of them use the collection we want. We want the adjustment of population to apply to only to a specific single city. The former adjusts the population of all of a player’s cities, and the latter adjusts the population of the city closest to a unit (this is used for the population tribal village). So in this case, we again need to define our own modifier type.
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType)
VALUES (‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘COLLECTION_OWNER’, ‘EFFECT_ADJUST_CITY_POPULATION’);
You may be somewhat confused by this. What is COLLECTION_OWNER? This is a very important collection to be familiar with. What assigning this collection essentially does is it sets the subjects of the modifier to be the owner of the modifier. In other words, what the modifier is attached to is also what it acts upon. In our entity-modifier tables earlier in this chapter, we attached our modifier to a city (remember that the Great Person entity-modifier table works slightly differently to the others, the Great Person attaches a modifier to an entity when its ability is activated). But we also want this modifier to act upon the city itself. For this reason, we use the collection COLLECTION_OWNER. And you may have noticed that in Modifiers.xml, all modifiers that refer to a ‘single city’ also use this collection. Using this collection to set the subjects of a modifier to its owner can be used not only for cities, but for any other entity in the game that a modifier can be attached to.
Don’t forget to add an entry to the Types table:
INSERT INTO Types (Type, Kind)
VALUES (‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘KIND_MODIFIER’);
For the Modifiers table, this is a case where we want to ensure that the modifier only applies once, so we will set the RunOnce and Permanent columns to ‘1’.
INSERT INTO Modifiers (ModifierId, ModifierType, RunOnce, Permanent)
VALUES (‘GREATPERSON_CITY_POPULATION’, ‘MODIFIER_SINGLE_CITY_ADD_POPULATION’, ‘1’, ‘1’);
Determining Modifier Arguments
We still need to do one more thing before our mod will work. As we discussed in the last chapter, many modifiers have arguments that need to be entered into the ModifierArguments table. Remember that these modifiers are assigned to a Modifier, not a modifier type. However, as was also briefly mentioned in the previous chapter, the valid arguments of a modifier are determined not by the modifier, nor the modifier type, but the effect. This is perhaps the most important reason why it is necessary to understand the anatomy of the modifier system down to the level of effects and collections. How do we know what the appropriate arguments for a modifier are? The answer to this is simply cross-referencing the base game code. The valid arguments of a modifier is always based on the effect. Another way of putting this is that all modifiers with the same effect have the same argument specifications. So to find the appropriate arguments for a modifier you are implementing, search the game code for a modifier with the same effect, and see what its arguments are.
Let’s do this for the first component of our balance patch. We want to find out the valid arguments for the effect EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION. First, we need to find a base game modifier type that uses this effect. Recall that the modifier type definitions for the base game are stored in Modifiers.xml. Earlier in the chapter, we found this entry:
<Row>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<CollectionType>COLLECTION_ALL_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_CULTURE_BORDER_EXPANSION</EffectType>
</Row>
Of course, if we hadn’t found this already, it would be as easy as searching for the desired EffectType in the file.
So we have MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION as a base game modifier type that uses the same effect. Now we need to find a modifier that uses this modifier type. To do this we will search the entire Base » Assets » Gameplay » Data folder for the modifier type in question. On Windows, there should be a search bar in the top-right of the Explorer window. You may have to select the ‘Search’ tab and ensure that ‘File contents’ is marked under ‘Advanced options’. The search should return two files: Modifiers.xml (the file we were just looking at) and Beliefs.xml. Obviously any base game modifier type is going to appear in Modifiers.xml, but that file only stores the definitions of modifier types. What we’re looking for is a modifier that uses the specified modifier type. If you know Civilization 6 inside-out by now, ‘Beliefs.xml’ should ring a bell – the ‘Religious Settlements’ pantheon. Opening the file and searching the file for our modifier type, you should find this:
<Row>
<ModifierId>RELIGIOUS_SETTLEMENTS_CULTUREBORDER</ModifierId>
<ModifierType>MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION</ModifierType>
<SubjectRequirementSetId>CITY_FOLLOWS_PANTHEON_REQUIREMENTS</SubjectRequirementSetId>
</Row>
So now we have a modifier that uses the same effect as our modifier, and therefore has the same argument specifications as ours. Searching the file for the ModifierId in the entry, you should find this:
<Row>
<ModifierId>RELIGIOUS_SETTLEMENTS_CULTUREBORDER</ModifierId>
<Name>Amount</Name>
<Value>15</Value>
</Row>
And that right there is what we’ve been looking for. One can easily infer that Amount is referring to the percentage increase in border expansion, which is 15 for the Religious Settlements pantheon. With this knowledge, we can now create our entry in the ModifierArguments table.
INSERT INTO ModifierArguments (ModifierId, Name, Value)
VALUES (‘TRAIT_INCREASED_CULTURE_BORDER_EXPANSION’, ‘Amount’, ’20’);
A few points to remember:
- Many effects have more than one argument in their specification. Conversely, some effects have no arguments.
- If a modifier’s arguments are invalid, the GameEffects.log file will say so (as long as you have effects logging set to diagnostic).
- Determining the modifier arguments is just as important if you are using a ModifierType from the base game. In this case, you can simply search for the ModifierType in the Data folder to begin with.
- Search Modifiers.xml to find a base game ModifierType using the same EffectType as your modifier’s ModifierType. If your modifier itself uses a base game ModifierType, you can skip this step.
- Search for the base game ModifierType in the Data folder. (Note: It may also be worth checking the DLC folder in the game’s root directory if you can’t find anything. This will become more frequently necessary as more DLCs are released.)
- Open a file (other than Modifiers.xml) that was returned by the search, and search that file to find a modifier that uses the ModifierType we’ve been looking for.
- Search the same file for the ModifierId you just found. In doing so you should be able to find the modifier arguments for that modifier. Those arguments are what you need to replicate for your modifier.
We are looking for a ModifierType in Modifiers.xml using the EffectType EFFECT_ADJUST_CITY_POPULATION. There are two:
<Row>
<ModifierType>MODIFIER_PLAYER_CITIES_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_PLAYER_CITIES</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
…
<Row>
<ModifierType>MODIFIER_PLAYER_NEAREST_CITY_ADD_POPULATION</ModifierType>
<CollectionType>COLLECTION_UNIT_NEAREST_OWNER_CITY</CollectionType>
<EffectType>EFFECT_ADJUST_CITY_POPULATION</EffectType>
</Row>
We’ll start by searching for the first one in the Data folder. This returns no results (other than Modifiers.xml). This means that for whatever reason, MODIFIER_PLAYER_CITIES_ADD_POPULATION has been included by the developers in the base game code, but is not actually used anywhere. So let’s try the second one.
This time, the search should return GoodyHuts.xml. Searching the file for the ModifierType again, we find a definition for a modifier, with ModifierId GOODY_SURVIVORS_ADD_POPULATION. Then we search the file for this, and we find:
<Row>
<ModifierId>GOODY_SURVIVORS_ADD_POPULATION</ModifierId>
<Name>Amount</Name>
<Value>1</Value>
</Row>
You should be able to infer from this what our ModifierArguments entry will look like:
INSERT INTO ModifierArguments (ModifierId, Name, Value)
VALUES (‘GREATPERSON_CITY_POPULATION’, ‘Amount’, ‘4’);
And we’re done! Once again, the changes we made in our mod will not be reflected in the game’s text, which is beyond the scope of this guide.
In the next chapter, we’ll discuss how to set up requirements for modifiers, allow you to restrict when an effect takes action on a subject based on a broad variety of parameters.
Previous chapter:
Chapter 1: Creating and attaching modifiers
Last edited by a moderator: