Overwriting native xml

Users who are viewing this thread

Hello all,

I found some earlier topics but still can't find my error to make my mod work.
I've tested it by modding the original native files and it works, even savegame compatible.

I've placed the folder "MyTestMod" into Modules. Inside "MyTestMod" is a folder "ModuleData" which contains the file "horses_and_others.xml"
Personally I feel like I've screwed up something within the xmlnode, given I have no clue how that line is supposed to work.

My Submodule.xml looks as per below;
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Module xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/BUTR/Bannerlord.XmlSchemas/master/SubModule.xsd" >
  <Id value="MyTestMod" />
  <Name value="MyTestMod" />
  <Version value="v1.0.0" />
  <Official value="false" />
  <DefaultModule value="false" />
  <ModuleCategory value="Singleplayer"/>
  <DependedModules>
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="CustomBattle"/>
    <DependedModule Id="StoryMode" />
  </DependedModules>
  <SubModules>
    <SubModule>
    </SubModule>
  </SubModules>
  <Xmls>
        <XmlNode>
            <XmlName id="Items" path="horses_and_others"/>
        </XmlNode>
  </Xmls> 
</Module>

Many thanks in advance for your help.
 
Your XmlNode doesn't specify any IncludedGameTypes to use your items in. Recheck SandboxCore's SubModule.xml:
Code:
        <XmlNode>          
            <XmlName id="Items" path="items"/>
            <IncludedGameTypes>
                <GameType value = "Campaign"/>
                <GameType value = "CampaignStoryMode"/>
                <GameType value = "CustomGame"/>
                <GameType value = "EditorGame"/>
            </IncludedGameTypes>
        </XmlNode>

BTW <Official value="false" /> should now be <ModuleType value ="Community" /> although I don't think it causes any problems.

You don't need xslt if you are just adding new items. You only need xslt to remove SandboxCore items where you are removing or replacing them. For example, I used this xslt to remove Bannerlord bows as I wanted to add them back in my own xml with different stats etc.:
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

 
    <xsl:template match="Item[@id='training_bow']"/>
    <xsl:template match="Item[@id='training_longbow']"/>
    <xsl:template match="Item[@id='hunting_bow']"/>
    <xsl:template match="Item[@id='mountain_hunting_bow']"/>
    <xsl:template match="Item[@id='steppe_bow']"/>
    <xsl:template match="Item[@id='glen_ranger_bow']"/>
    <xsl:template match="Item[@id='highland_ranger_bow']"/>
    <xsl:template match="Item[@id='composite_bow']"/>
    <xsl:template match="Item[@id='composite_steppe_bow']"/>
    <xsl:template match="Item[@id='steppe_heavy_bow']"/>
    <xsl:template match="Item[@id='nordic_shortbow']"/>
    <xsl:template match="Item[@id='lowland_longbow']"/>
    <xsl:template match="Item[@id='tribal_bow']"/>
    <xsl:template match="Item[@id='steppe_war_bow']"/>
    <xsl:template match="Item[@id='woodland_yew_bow']"/>
    <xsl:template match="Item[@id='woodland_longbow']"/>
    <xsl:template match="Item[@id='longbow_recurve_desert_bow']"/>
    <xsl:template match="Item[@id='nomad_bow']"/>
    <xsl:template match="Item[@id='lowland_yew_bow']"/>
    <xsl:template match="Item[@id='noble_bow']"/>
    <xsl:template match="Item[@id='noble_long_bow']"/>
 
 
    </xsl:stylesheet>
IMO it's easier if your path horses_and_others is a subfolder of ModuleData as opposed to a single xml file in ModuleData. That way you can break it up into logical parts. So, for example, I have bows.xml bows.xslt crossbows.xml crossbows.xslt etc in my path's folder. the wording in your SubModule.xml is the same whether you use a single horses_and_others.xml in ModuleData or a subfolder of lots of xmls (only for items) named horses_and_others. The files in your subfolder can be named whatever you like as long as paired xslt and xml files share the same name to link them. Makes xslt easier as lots of types of items will just be additions (only requiring xml). Working with smaller files and changes makes step at a time debugging easier.
 
Last edited:
BTW <Official value="false" /> should now be <ModuleType value ="Community" /> although I don't think it causes any problems.
Hmm I actually "stole" that from someone else's submodule. I'll change it to be safe. Thanks!

You don't need xslt if you are just adding new items. You only need xslt to remove SandboxCore items where you are removing or replacing them. For example, I used this xslt to remove Bannerlord bows as I wanted to add them back in my own xml with different stats etc.:
Right. Again, stole it lol. But I actually do want to change the vanilla files. It was the way how I made "total conversion" mods for Total war games. Just copy the file and delete entries.

I.E. for testing purposes I want a certain horse to not be mounted. So in SandboxCore I changed in the original horses /is_mountable="true"/ into /is_mountable="false"/ which worked. I tried to duplicate it, by above logic with just duplicating the file as a mod and change what needed to be changed. But I fear it doesn't work as I assumed it did.

IMO it's easier if your path horses_and_others is a subfolder of ModuleData as opposed to a single xml file in ModuleData. That way you can break it up into logical parts. So, for example, I have bows.xml bows.xslt crossbows.xml crossbows.xslt etc in my path's folder. the wording in your SubModule.xml is the same whether you use a single horses_and_others.xml in ModuleData or a subfolder of lots of xmls (only for items) named horses_and_others. The files in your subfolder can be named whatever you like as long as paired xslt and xml files share the same name to link them. Makes xslt easier as lots of types of items will just be additions (only requiring xml). Working with smaller files and changes makes step at a time debugging easier.
Do you have some links to resources regarding this? Perhaps a tutorial I can go through? Just to familiarize myself more with the method.
I do agree, it makes it far more easier. I just feel that I don't understand the "<XmlName id="Items" path="horses_and_others"/>"
Could you perhaps explain where "Items" refer to and where does "horses_and_others" refer to exactly? I just tried to fumble around as none of my google searches led to any results to what I'm intended to create in the end.
 
Right. Again, stole it lol. But I actually do want to change the vanilla files. It was the way how I made "total conversion" mods for Total war games. Just copy the file and delete entries.
I don't recommend it for items. The official documentation includes an xslt example which deletes all Calradia's settlements, allowing the modder to then substitute his/her own. That can be used elsewhere. However, there are only a limited number of settlements, which all need customisation in a new campaign map. There are tons of items. Look at the contents of ...\SandBoxCore\ModuleData\items there are ten xmls. Deleting all items would remove all armours, weapons, shields, banners and other items from the game, requiring you to replace them all and leaving your mod open to crashes should TW add new items in future updates (that your xslt will delete without replacements).
I.E. for testing purposes I want a certain horse to not be mounted. So in SandboxCore I changed in the original horses /is_mountable="true"/ into /is_mountable="false"/ which worked. I tried to duplicate it, by above logic with just duplicating the file as a mod and change what needed to be changed. But I fear it doesn't work as I assumed it did.
AFAIK it should work if executed properly. However, I've not modded horses or horse scales, so, I could be wrong.
Do you have some links to resources regarding this? Perhaps a tutorial I can go through? Just to familiarize myself more with the method.
Just look at the SubModule.xml and ModuleData for SandboxCore - that's how Taleworlds implemented items (as a subfolder). An xslt just needs to have the same name and sit in the same folder as its related xml.
I don't understand the "<XmlName id="Items" path="horses_and_others"/>"
Could you perhaps explain where "Items" refer to and where does "horses_and_others" refer to exactly?
Look in any xml in the ...\SandBoxCore\ModuleData\items subfolder. After <?xml version="1.0" encoding="utf-8"?> the opening tag is <Items> and the closing tag is </Items>. These tags tell the game engine that there are Items between them that need to be loaded. The line in your SubModule.xml <XmlName id="Items" path="horses_and_others"/> just tells the game engine to load all items that it can find on the specified path (which can be a single file or a folder of files).
So, in an xml between the tags <Items> and </Items> there will be lists of items, which follow prescribed rules and start with the tag <Item> and close with the tag </Item>. Singular vs plural. Effectively, xmls are just hierarchical lists. Easiest to see if you edit them in Notepad++ and fold or unfold levels.
Previously, xslt worked to allow adjustment of elements within XmlNodes (i.e. changing a troop's equipment as opposed to replacing the troop). However, I haven't been able to get that to work with more recent versions. I suspect Taleworlds have blocked us from using xslt to change elements within an XmlNode to avoid conflicts between multiple mods editing say incompatible bits of the same item. So, I assume we can only use xslt at the top level - for Items that means removing a whole Item.
 
Sorry for a bit later reply. Last update had me bugged out to actually boot it up till now.
I don't recommend it for items. The official documentation includes an xslt example which deletes all Calradia's settlements, allowing the modder to then substitute his/her own. That can be used elsewhere. However, there are only a limited number of settlements, which all need customisation in a new campaign map. There are tons of items. Look at the contents of ...\SandBoxCore\ModuleData\items there are ten xmls. Deleting all items would remove all armours, weapons, shields, banners and other items from the game, requiring you to replace them all and leaving your mod open to crashes should TW add new items in future updates (that your xslt will delete without replacements).
I tried as a mere trial as I can't find to seem decent tutorials around. In the end, if I can find out to make certain troops recruitable, I rather do that than to delete them as for your reasoning :smile:.Usually safer that way.

AFAIK it should work if executed properly. However, I've not modded horses or horse scales, so, I could be wrong.
Yeah that's the weird part. On SanboxCore original file it works. In a mod it doesn't. So I feel I must be doing something wrong in either the Submodule or I'm doing something wrong with the logic how the engine "overwrites" vanilla files.

Just look at the SubModule.xml and ModuleData for SandboxCore - that's how Taleworlds implemented items (as a subfolder). An xslt just needs to have the same name and sit in the same folder as its related xml.
Well that might be my issue then? As I have no clue what a "xslt" is or what is supposed to do. Do you know of any resources where I can read up?

Previously, xslt worked to allow adjustment of elements within XmlNodes (i.e. changing a troop's equipment as opposed to replacing the troop). However, I haven't been able to get that to work with more recent versions. I suspect Taleworlds have blocked us from using xslt to change elements within an XmlNode to avoid conflicts between multiple mods editing say incompatible bits of the same item. So, I assume we can only use xslt at the top level - for Items that means removing a whole Item.
I'm familiar with how xml formatting works. I worked with JSON's in the pas as well. And personally I always prefer Sublime Tesxt (works great for Python as well). Not sure if you know it, but it automatically detects errors like a missing ">" or in the case of JSON "}". Tbh I would much rather work with MSSQL for modding but at least this way I'm able to learn something new lol.

What I am missing is as well I guess what is supposed to go in the XmlNodes.
I remade the xml (based on a different mod) and it now looks like this, but game still gives me a CTD.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <Name value="Mymod"/>
  <Id value="Mymod"/>
  <Version value="v1.0.0" />
  <SingleplayerModule value="true"/>
  <MultiplayerModule value="false"/>
  <DependedModules>
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="CustomBattle"/>
    <DependedModule Id="StoryMode"/>
  </DependedModules>
  <SubModules>
    <SubModule>
    </SubModule>
  </SubModules>
  <Xmls>
    <XmlNode>
      <XmlName id="Items" path="horsies"/>
    </XmlNode>
  </Xmls>
</Module>

I've renames the modded version "horses_and_others.xml" into "horsies.xml" to see if a dupe name might cause issues.
And I've tried to place the xml in MyMod\ModuleData and in MyMod\ModuleData\Items
But to no luck in either way unfortunately. Do you by chance have any idea?

Just in case, I don't need to use C# for a simple xml mod right?
 
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <Name value="MyMod"/>
  <Id value="MyMod"/>
  <Version value="v1.0.0" />
  <SingleplayerModule value="true"/>
  <MultiplayerModule value="false"/>
  <DependedModules>
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="CustomBattle"/>
    <DependedModule Id="StoryMode"/>
  </DependedModules>
  <SubModules>
    <SubModule>
    </SubModule>
  </SubModules>
  <Xmls>
    <XmlNode>
      <XmlName id="Items" path="horses_and_others"/>
      <IncludedGameTypes>
                <GameType value = "Campaign"/>
                <GameType value = "CampaignStoryMode"/>
                <GameType value = "CustomGame"/>
                <GameType value = "EditorGame"/>
      </IncludedGameTypes>
    </XmlNode>
  </Xmls> 
</Module>
Many thanks again for your input. Seems I got lost a bit...
I do now have it as per below (still crashes obviously).

I've renames the "Horsies" back into "horses_and_others" just to be safe, I've placed it under ModuleData\Items.
Or do I still misunderstand " <XmlName id="Items" path="horses_and_others"/>"? is it pointing to the Native file or my modded file?

Furthermore, I still don't understand anything about the xslt. I've looked again at your code, am I supposed to duplicate every ID from SandboxCore\horses_and_others.xml into my submodule? Just like you did I.E. "<xsl:template match="Item[@id='training_bow']"/>"
As if that's the case, I'm gonna need a butload of time to do so lol. But if it's necessary, guess it's necessary. Rather use;
SELECT * FROM dbo.SandboxCore.horses_and_others
WHERE RECRUITABLE = FALSE
And then something about an INNER JOIN haha.

Again, many thanks for your feedback.
 
I've placed it under ModuleData\Items.
If you’ve created a subfolder named Items that should what your path points at in your sub module.xml. However, IDK how well it will work, using the same name: <XmlName id=“Items” path=“Items” />
If it doesn’t work rename your subfolder and path something like spitems to differentiate it from your XmlName. In SandboxCore SubModule.xml, TW used Items (uppercase i) for XmlName and items (lowercase i) for the subfolder and path.
 
Last edited:
Back
Top Bottom