.modinfo structure

Status
Not open for further replies.
Change "<Row" to "<Replace"

Used in a XML file placed in the <UpdateDatabase> section, <Replace> will tell the game "Replace existing entries or add new ones", while <Row> says "Add new entries" and that will fail (meaning the whole file is not loaded) if there is already an entry of that type in the game's database

for example the couple Era="ERA_ANCIENT" Unit="UNIT_SETTLER" must be unique in the table MajorStartingUnits, you can't add a new one with <Row> but <Replace> will update the existing entry with the new values.
 
I hate to ask for help this much (I made a thread about a different issue), but I'm having a very strange issue that I assume is because of my modinfo file. My mod is able to load up the xml files for text, but only once. It is able to present one line of text from the file, then it acts as if the file doesn't exist, even when trying to load the exact same piece of text. For example, I'll unlock a civic and it will say the quote at the bottom, but then with every other civic and even if I load up the same file and get the same civic, it won't show the quote. Here's my modinfo file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<Mod id="ed141a5f-0b70-4d11-a795-cd31e964bd38" version="0.1">
    <Properties>
        <Name>Our Sovereign Nation: Quotes</Name>
        <Teaser>Gives each Civilization their own Tech and Civic Quotes</Teaser>
        <Description>Every Civilization gets a unique quote for Techs and Civics that is either about that civilizations usage of it or by someone of that civilization.</Description>
        <Authors>Desertmoongw</Authors>
    </Properties>
    <Files>
        <File>TechCivicCompletedPopup.lua</File>
        <File>Aztec_Quotes.xml</File>
        <File>Default_Quotes.xml</File>
    </Files>
    <Components>
        <ImportFiles id="OurSovereignNationQuotesLua">
            <Items>
                <File>TechCivicCompletedPopup.lua</File>
            </Items>
        </ImportFiles>
        <LocalizedText>
            <Items>
                <File>Aztec_Quotes.xml</File>
                <File>Default_Quotes.xml</File>
            </Items>
        </LocalizedText>
    </Components>
</Mod>
 

Attachments

  • 20161029132557_1.jpg
    20161029132557_1.jpg
    419.9 KB · Views: 242
  • 20161029132634_1.jpg
    20161029132634_1.jpg
    418 KB · Views: 269
1. Valid Table Columns:
C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Gameplay\Data\Schema/01_GameplaySchema.sql shows you all the valid columns for each game table. It shows this for all game tables that must be loaded from a file set as
Code:
<Components>
     <UpdateDatabase......
in the modinfo file. Gametables that must be loaded via
Code:
<Settings>
     <Custom id="XXXXXXXXXXXXXX">
          <Items>
               <File>xxxxxxxx.xml</File>
          </Items>
     </Custom>
</Settings>
are shown in C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Configuration\Data\Schema/AdditionalTables.sql
2. So within that file the definition of table <StartBiasRivers> is
Code:
CREATE TABLE "StartBiasRivers" (
     "CivilizationType" TEXT NOT NULL,
    "Tier" INTEGER NOT NULL DEFAULT -1,
   PRIMARY KEY(CivilizationType),
   FOREIGN KEY (CivilizationType) REFERENCES Civilizations(CivilizationType) ON DELETE CASCADE ON UPDATE CASCADE);
"CivilizationType" and "Tier" are the columns valid for the table. No other columns can be stated else the game will dump the entire contents of the file where the error occurs and will lock the database from any further changes until you exit and reload the game. The
Code:
   PRIMARY KEY(CivilizationType),
   FOREIGN KEY (CivilizationType) REFERENCES Civilizations(CivilizationType) ON DELETE CASCADE ON UPDATE CASCADE);
portion is SQL commands on how to behave when new rows are added to the table. The table as used by Firaxis
Code:
<StartBiasRivers>
     <Row CivilizationType="CIVILIZATION_EGYPT" Tier="5"/>
     <Row CivilizationType="CIVILIZATION_FRANCE" Tier="3"/>
     <Row CivilizationType="CIVILIZATION_SUMERIA" Tier="3"/>
</StartBiasRivers>
3. You cannot restate data the game already has as in this manner:
Code:
<StartEras>
     <Row EraType="ERA_ANCIENT" Gold="1000" StartingMeleeStrengthMajor="20" StartingMeleeStrengthMinor="20" Tiles="0" Year="-4000"/>
</StartEras>
The game already has a definition for EraType="ERA_ANCIENT", as here:
Code:
<Row EraType="ERA_ANCIENT" Gold="10" StartingMeleeStrengthMajor="20" StartingMeleeStrengthMinor="20" Tiles="0" Year="-4000"/>
So you need to <Update> the existing row within the table:
Code:
<StartEras>
     <Update>
           <Where EraType="ERA_ANCIENT" />
          <Set Gold="1000" />
     </Update>
</StartEras>
You will have similar issues with other parts of your code.​
4. Note that the "Where" clause acts as a logical "AND":
so that when there are two rows within a table that have
Code:
<Row BuildingType="BUILDING_LIGHTHOUSE" .....
you simply do an update like as so:
Code:
<Building_YieldChanges>
     <Update>
           <Where BuildingType="BUILDING_LIGHTHOUSE" YieldType="YIELD_FOOD" />
          <Set YieldChange="3" />
     </Update>
</Building_YieldChanges>
This will only change the food yield of the lighthouse and will leave the gold alone.​
5. Sometimes you are better off to delete and then re-add, as in like this
Code:
<MajorStartingUnits>
     <Delete Era="ERA_ANCIENT" />
     <Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_WARRIOR" Quantity="2" NotStartTile="true"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_BUILDER" Quantity="3" NotStartTile="true"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_SCOUT" Quantity="5" NotStartTile="true"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" AiOnly="true" MinDifficulty="DIFFICULTY_EMPEROR" DifficultyDelta="0.5"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_WARRIOR" AiOnly="true" MinDifficulty="DIFFICULTY_KING" DifficultyDelta="1" NotStartTile="true"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_BUILDER" AiOnly="true" MinDifficulty="DIFFICULTY_KING" DifficultyDelta="0.5" OnDistrictCreated="true"/>
</MajorStartingUnits>
I don't believe you actually want that
Code:
Quantity="1" NotStartTile="true"
on that human player Unit="UNIT_SETTLER" row.

It would look like in your specific case it might be better to do an update to the existing "Warrior" row with a Where clause as:
Code:
<Where Era="ERA_ANCIENT" Unit="UNIT_WARRIOR" AiOnly="false" NotStartTile="true"/>
like this
Code:
<MajorStartingUnits>
     <Update>
          <Where Era="ERA_ANCIENT" Unit="UNIT_WARRIOR" AiOnly="false" NotStartTile="true"/>
          <Set Quantity="2" />
     </Update>
     <Row Era="ERA_ANCIENT" Unit="UNIT_BUILDER" Quantity="3" NotStartTile="true"/>
     <Row Era="ERA_ANCIENT" Unit="UNIT_SCOUT" Quantity="5" NotStartTile="true"/>
</MajorStartingUnits>
 
Last edited:
I hate to ask for help this much (I made a thread about a different issue), but I'm having a very strange issue that I assume is because of my modinfo file. My mod is able to load up the xml files for text, but only once. It is able to present one line of text from the file, then it acts as if the file doesn't exist, even when trying to load the exact same piece of text. For example, I'll unlock a civic and it will say the quote at the bottom, but then with every other civic and even if I load up the same file and get the same civic, it won't show the quote. Here's my modinfo file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<Mod id="ed141a5f-0b70-4d11-a795-cd31e964bd38" version="0.1">
    <Properties>
        <Name>Our Sovereign Nation: Quotes</Name>
        <Teaser>Gives each Civilization their own Tech and Civic Quotes</Teaser>
        <Description>Every Civilization gets a unique quote for Techs and Civics that is either about that civilizations usage of it or by someone of that civilization.</Description>
        <Authors>Desertmoongw</Authors>
    </Properties>
    <Files>
        <File>TechCivicCompletedPopup.lua</File>
        <File>Aztec_Quotes.xml</File>
        <File>Default_Quotes.xml</File>
    </Files>
    <Components>
        <ImportFiles id="OurSovereignNationQuotesLua">
            <Items>
                <File>TechCivicCompletedPopup.lua</File>
            </Items>
        </ImportFiles>
        <LocalizedText>
            <Items>
                <File>Aztec_Quotes.xml</File>
                <File>Default_Quotes.xml</File>
            </Items>
        </LocalizedText>
    </Components>
</Mod>
I've run into similar if I exit from in-game to the main menu and then reload a game or start a new game. Exiting to desktop and restarting the game application seems to force the game to reload the text. It's not just you that has been encountering these sorts of it works and then it doesn't and then it does as far as text goes. It seem to always work if you directly enter the text rather than use a LOC_SOMETHING but that is not a good practice to get into long-term as there are so many parts of the game that expect buildings and civics and the like to be using the localization system.
 
@Gedemon have you gotten <Replace> to work? So far when I have tried it in Civ6 all I got was a locked database. But maybe I was doing something wrong that was not obvious to me.
Yes, I'm using Replace a lot in YnAMP, but now that I think of it, none has to actually replace something in the DB, it's all for new entries.
 
I'll have to test again, but when I used it to alter existing Districts I got the locked database errors and no changes implemented. I had to redraft my code to use Update.
 
Thanks for the help guys, especially Gedemon, Mynex and Lee S. I put what I learned here into a brief example mod. I'd love to keep it updated as I learn more, a sort of hands-on how-to guy for modding beginners. I'm still a bit stymied as to some of the features of the .modinfo file. I don't suppose there's an in-depth write-up yet as to what all the different bits of it do? If not, maybe we can put our heads together and come up with one.

In the meantime, if you want to check the mod out and offer suggestions, you can do so here: http://forums.civfanatics.com/threads/lockes-russia-modding-example.603034/.
 
Change "<Row" to "<Replace"

Used in a XML file placed in the <UpdateDatabase> section, <Replace> will tell the game "Replace existing entries or add new ones", while <Row> says "Add new entries" and that will fail (meaning the whole file is not loaded) if there is already an entry of that type in the game's database

for example the couple Era="ERA_ANCIENT" Unit="UNIT_SETTLER" must be unique in the table MajorStartingUnits, you can't add a new one with <Row> but <Replace> will update the existing entry with the new values.

Thank you for this, @Gedemon !
I was trying to change a base game civ color doing this (after defining PINK as a color):

Code:
    <PlayerColors>
        <Update>
            <Where Type="COLOR_PLAYER_AMERICA_SECONDARY"/>
            <Set PrimaryColor="PINK"/>
        </Update>
    </PlayerColors>

And no matter what I did, the change just wouldn't kick in. Then I tried this:

Code:
    <PlayerColors>
        <Replace>
            <Type>LEADER_T_ROOSEVELT</Type>
            <Usage>Unique</Usage>
            <PrimaryColor>PINK</PrimaryColor>
            <SecondaryColor>COLOR_WHITE</SecondaryColor>
            <TextColor>COLOR_PLAYER_WHITE_TEXT</TextColor>
        </Replace>
    </PlayerColors>

And it worked!
So, thanks for the insight!
 
Your update attempt did not work because there is no pre-existing Type="COLOR_PLAYER_AMERICA_SECONDARY" so there was nothing for the Where clause to match to. You would have needed to do as
Code:
    <PlayerColors>
        <Update>
            <Where Type="LEADER_T_ROOSEVELT"/>
            <Set PrimaryColor="PINK"/>
        </Update>
    </PlayerColors>
And I guess I need to figure out what I goofed on when I used replace earlier :sad:
 
Someone asked: "is there any way to specify that only certain civilizations should receive certain starting units? I'd love to be able to give some Civs extra warrior units, others extra builders, etc"

The answer, so far, (that I have found) is yes... and no.

I added the following to - LockeRussiaMods_Eras.xml - file; the <MajorStartingUnits> section.
1) If you add "Change-1", then only the Russian empire will receive this unit - AI or human, makes no difference [exceedingly likely because it is unique to this civ]
2) If you add "Change-2" (with "Change-1"), this works, you will have 3 Cossack units (no reason for it not to work) [the maintenance costs would be a sever drain on an Ancient Era civ]
3) Adding "Change-3" to the mix will, in fact, change all the Cossack units to Archers... but now (exceedingly likely because Archers are available to all civs), all Major players start with 3 Archers

<!-- Change-1 -->
<Row Era="ERA_ANCIENT" Unit="UNIT_RUSSIAN_COSSACK" NotStartTile="true" />

<!-- Change-2 -->
<Update>
<Where Era="ERA_ANCIENT" Unit="UNIT_RUSSIAN_COSSACK" />
<Set Quantity="3" />
</Update>

<!-- Change-3 -->
<Update>
<Where Era="ERA_ANCIENT" Unit="UNIT_RUSSIAN_COSSACK" />
<Set Unit="UNIT_ARCHER" />
</Update>
 
That was me (and at least 2 other people :D )

Yea, I figured I would have to create unique units to do that. I've been noodling how best to accomplish this so it would be easy for folks to change the name/civ association if they wanted to.

I think I have it, need to go make/test it now that I've finished a few other things.

Thanks for confirming! :)
 
I am trying to create an Ancient Era mod but cant get it working.

Any help welcome.

I started off with one file but cant get it working.

<Mod id="08cc7d11-cee0-451f-b6f9-7086b88f175c" version="1">
<Properties>
<Name>AncientEraMod</Name>
<Teaser>Ancient to Classical Era</Teaser>
</Properties>
<Components>
<UpdateDatabase>
<Items>
<File>Eras.xml</File>
</Items>
</UpdateDatabase>
<ImportFiles>
<Items>
<File>Eras.xml</File>
</Items>
</ImportFiles>
</Components>
<Files>
<File>Eras.xml</File>
</Files>
</Mod>

The othe files I want to include are:

CivilizationInfo.xml
Civilizations.xml
Improvements.xml
Units.xml
Religions.xml
Policies.xml
Civics.xml
Buildings.xml
Districts.xml
Technologies.xml
Governments.xml
 
I am trying to cut out all the eras beyond medieval.

When I copy the 3 files Civics.xml, Technologies.xml and Eras.xml into the main game files and over write them it works.

But when I put the 3 files into the modinfo files as such:
<Items>
<File>Eras.xml</File>
<File>Technologies.xml</File>
<File>Civics.xml</File>
</Items>
It crashes. (PS when I try out the mod, I repair the overwritten game files first and make sure the game works correctly with the original files)

There must be something in the modinfo file I'm not doing properly.
 
I am trying to create an Ancient Era mod but cant get it working.

Any help welcome.

I started off with one file but cant get it working.

<Mod id="08cc7d11-cee0-451f-b6f9-7086b88f175c" version="1">
<Properties>
<Name>AncientEraMod</Name>
<Teaser>Ancient to Classical Era</Teaser>
</Properties>
<Components>
<UpdateDatabase>
<Items>
<File>Eras.xml</File>
</Items>
</UpdateDatabase>
<ImportFiles>
<Items>
<File>Eras.xml</File>
</Items>
</ImportFiles>
</Components>
<Files>
<File>Eras.xml</File>
</Files>
</Mod>

The othe files I want to include are:

CivilizationInfo.xml
Civilizations.xml
Improvements.xml
Units.xml
Religions.xml
Policies.xml
Civics.xml
Buildings.xml
Districts.xml
Technologies.xml
Governments.xml

I do not use the following parts in my mod info, and it works great, just put them in updatedatabase and files
<ImportFiles>
<Items>
<File>Eras.xml</File>
</Items>
</ImportFiles>
 
Importing the xml files that use <GameInfo> or <GameData> is not going to work because the game opens the original Firaxis-supplied files and adds their contents into the game's database before any code from a mod is ever executed. Such xml files are not accessed by the game from the file "Import" system (the VFS) and are thus treated in a completely different way to how lua UI panel files are treated and their associated xml files that use <Context ....> instead of <GameInfo> or <GameData>. This was also the behavior used in Civ5, and for the most part it still obtains true: the difference is that there is the Configuration and UpdataBase systems in addition to the text localization system for xml and sql file contents whereas in Civ5 it was all one UpdateDatabase system using <GameData>.

This also is why it works when you directly edit the original game files. The game reads the contents of these files upon game loading.

Also, you cannot repeat code the game already has. So in any xml file of a mod I cannot do this:
Code:
<GameInfo>
     <Buildings>
          <Row BuildingType="BUILDING_MONUMENT" Name="LOC_BUILDING_MONUMENT_NAME"
               PrereqDistrict="DISTRICT_CITY_CENTER" PurchaseYield="YIELD_GOLD" Cost="60"
               AdvisorType="ADVISOR_CULTURE"/>
     </Buildings>
</GameInfo>
because the game already has a BuildingType="BUILDING_MONUMENT" registered within table <Buildings>. I would have to use <Replace> instead of <Row> or I would have to make an <Update> to the existing data in table <Buildings> for the Monument building.
 
Last edited:
I do not use the following parts in my mod info, and it works great, just put them in updatedatabase and files
<ImportFiles>
<Items>
<File>Eras.xml</File>
</Items>
</ImportFiles>


This what my modinfo file looks like but it still crashes:

<Mod id="08cc7d11-cee0-451f-b6f9-7086b88f175c" version="1">
<Properties>
<Name>AncientEraMod</Name>
<Teaser>Ancient to Classical Era</Teaser>
</Properties>
<Components>
<UpdateDatabase>
<Property>
</Property>
<Items>
<File>Eras.xml</File>
<File>Technologies.xml</File>
<File>Civics.xml</File>
</Items>
</UpdateDatabase>
<GameplayScripts>
</GameplayScripts>
</Components>
</Mod>


Importing the xml files that use <GameInfo> or <GameData> is not going to work because the game opens the original Firaxis-supplied files and adds their contents into the game's database before any code from a mod is ever executed. Such xml files are not accessed by the game from the file "Import" system (the VFS) and are thus treated in a completely different way to how lua UI panel files are treated and their associated xml files that use <Context ....> instead of <GameInfo> or <GameData>. This was also the behavior used in Civ5, and for the most part it still obtains true: the difference is that there is the Configuration and UpdataBase systems in addition to the text localization system for xml and sql file contents whereas in Civ5 it was all one UpdateDatabase system using <GameData>.

This also is why it works when you directly edit the original game files. The game reads the contents of these files upon game loading.

My knowledge of modding is clearly very limted.
All my edited files have either <GameInfo> or <GameData> therefore does that mean the Mod will never work. :(
 
This what my modinfo file looks like but it still crashes:

<Mod id="08cc7d11-cee0-451f-b6f9-7086b88f175c" version="1">
<Properties>
<Name>AncientEraMod</Name>
<Teaser>Ancient to Classical Era</Teaser>
</Properties>
<Components>
<UpdateDatabase>
<Property>
</Property>
<Items>
<File>Eras.xml</File>
<File>Technologies.xml</File>
<File>Civics.xml</File>
</Items>
</UpdateDatabase>
<GameplayScripts>
</GameplayScripts>
</Components>
</Mod>




My knowledge of modding is clearly very limted.
All my edited files have either <GameInfo> or <GameData> therefore does that mean the Mod will never work. :(

No, it means that this set-up in a modinfo file:
Code:
	<Components>
		<ImportFiles id="JFD_RULE_WITH_FAITH_IMPORT">
			<Items>
				<File>Lua/UI/Overrides/CivicsTree.lua</File>
				<File>Lua/UI/Overrides/CivicsTree.xml</File>
			</Items>
		</ImportFiles>
	</Components>
only works for the CivicsTree.xml because that file is a UserInterface (UI) xml file that starts its code with
Code:
<Context xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="..\..\..\..\..\CivTech\Libs\ForgeUI\ForgeUI_Assets\Controls.xsd">
instead of the <GameData> or <GameInfo> tags used to instruct the game to add contents to the game's database.

But files that use <GameData> and <GameInfo> are never imported. By "imported" we mean the entire file as a unit is added to the game's Virtual Fle System (VFS). This is an entirely different system than the game's xml database. For xml files that use <GameData> and <GameInfo>, they are adding new information or altering existing information in the game's database. The contents of files that use <GameData> or <GameInfo> are read into the game's database, but the file itself is not added to the game VFS. XML files that are using <GameData> or <GameInfo> must use one of the following set-ups within a modinfo file (to, for example, load the contents of example xml files into the game's database):
Code:
     <Components>
          <UpdateDatabase id="GAMEPLAY_CHANGES">
               <Items>
                   <File>Example1.xml</File>
               </Items>
          </UpdateDatabase>
          <LocalizedText id="GAMEPLAY_TEXT">
               <Items>
                   <File>Example2.xml</File>
               </Items>
          </LocalizedText>
     </Components>
     <Settings>
          <Custom id="CONFIG_UPDATE">
               <Items>
                   <File>Example3.xml</File>
               </Items>
          </Custom>
          <LocalizedText id="CONFIG_TEXT">
               <Items>
                   <File>Example4.xml</File>
              </Items>
          </LocalizedText>
     </Settings>
     <Files>
          <File>Example1.xml</File>
          <File>Example2.xml</File>
          <File>Example3.xml</File>
          <File>Example4.xml</File>
     </Files>
  1. File Example1.xml must start and end its code with <GameInfo>/</GameInfo> and must only contain information for those tables defined within the folder C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Gameplay\Data\Schema in the sql and/or xml files located there and that define the game xml-tables that can be used as part of the <Components><UpdateDatabase> system.
  2. File Example2.xml must start and end its code with <GameData>/</GameData> and must only contain text tag info for those tables defined within the folder C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Gameplay\Data\Schema in the sql and/or xml files located there and that define the game xml-tables that can be used as part of the <Components><UpdateDatabase> system. The file Example2.xml should also only contain table <LocalizedText>, and really should only contain the text tag info that is needed by anything in Example1.xml.
  3. File Example3.xml must start and end its code with <GameInfo>/</GameInfo> and must only contain information for those tables defined within the folder C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Configuration\Data\Schema in the sql and/or xml files located there and that define the game xml-tables that can be used as part of the <Settings><Custom> system.
  4. File Example4.xml must start and end its code with <GameData>/</GameData> and must only contain text tag info for those tables defined within the folder C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Configuration\Data\Schema in the sql and/or xml files located there and that define the game xml-tables that can be used as part of the <Settings><Custom> system. The file Example4.xml should also only contain table <LocalizedText>, and really should only contain the text tag info that is needed by anything in Example3.xml.
See the linked mod at the dropbox link for a practical example of a working mod that adds a new type of building and a unique version of the new type of building for Trajan's Rome. I am working on it to use the mod as a practical example of how to add a unique building for a tutorial: https://www.dropbox.com/s/t1rq6y5dvyjm3kx/TrajansForum.zip?dl=0
 
Status
Not open for further replies.
Back
Top Bottom