Creating Specific Companion Prefab instead of randomgen?

Users who are viewing this thread

KrispyJones

Recruit
With the current tools and through XML only, is it possible to create specific companions rather than generating from templates?

Specifically, I’m trying to add Game of Thrones inspired characters like Bronn, Red Viper, The Hound, Etc into the companion pool. Besides wanderers and wanderer string XMLs, I couldn’t find this specific functionality.
 
Solution
Yes, but as of 15/04/2020 the game will not load conversation strings referenced in your SubModule.xml file. So while you can do everything in XML you will have to wait until the game is more fully developed to see your companion's conversation text in game, unless you create a mod DLL and load your XML files in code (which is easy, and detailed below).

First the XML:
Create a mod and copy this to your empty SubModule.xml file (making sure to update "YourModName"):
Code:
<Module>
    <Name value="YourModName"/>
    <Id value="YourModName"/>
    <Version value="v1.0.0"/>
    <SingleplayerModule value="true"/>
    <MultiplayerModule value="false"/>
    <DependedModules>
        <DependedModule Id="Native"/>
        <DependedModule...
Yes, but as of 15/04/2020 the game will not load conversation strings referenced in your SubModule.xml file. So while you can do everything in XML you will have to wait until the game is more fully developed to see your companion's conversation text in game, unless you create a mod DLL and load your XML files in code (which is easy, and detailed below).

First the XML:
Create a mod and copy this to your empty SubModule.xml file (making sure to update "YourModName"):
Code:
<Module>
    <Name value="YourModName"/>
    <Id value="YourModName"/>
    <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>
    </SubModules>
    <Xmls>

        <XmlNode>
            <XmlName id="NPCCharacters" path="CustomCompanions"/>
            <IncludedGameTypes>
                <GameType value = "Campaign"/>
                <GameType value = "Sandbox"/>
                <GameType value = "SandBoxCore"/>
                <GameType value = "CampaignStoryMode"/>
                <GameType value = "CustomGame"/>
            </IncludedGameTypes>
        </XmlNode>
 
        <XmlNode>
            <XmlName id="strings" path="CustomCompanionStrings"/>
            <IncludedGameTypes>
                <GameType value = "Campaign"/>
                <GameType value = "Sandbox"/>
                <GameType value = "SandBoxCore"/>
                <GameType value = "CampaignStoryMode"/>
                <GameType value = "CustomGame"/>
            </IncludedGameTypes>
        </XmlNode>
 
    </Xmls>
</Module>

Then create a CustomCompanions.xml file within your ModuleData folder and add this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Original file copied from: ...\Modules\SandBox\ModuleData\spspecialcharacters.xml -->
<!-- File renamed to avoid overwrite issues. -->

<NPCCharacters>
<!-- For random name with set suffix use name="{=c5Kjcxsa}the Example" or for set name use name="Example" -->
  <NPCCharacter id="CompanionExample" name="{=c5Kjcxsa}the Example" voice="curt" age="25" default_group="Infantry" is_female="true" is_template="true" is_hero="false" culture="Culture.empire" occupation="Wanderer">
    <face>
        <!-- Use Ctrl+C and Ctrl+V to copy and paste the body properties from the character editor when starting a new campaign. -->
        <!-- The game will randomise between the values for BodyProperties and BodyPropertiesMax -->
        <BodyProperties version="4" age="25.84" weight="0.5" build="0.5"  key="000084058014000FC9A6BA24DA96CA8B778395B1C68727896418D76878BD6A4401C776130C98BBA40000000000000000000000000000000000000000459C1003"  />
        <BodyPropertiesMax version="4" age="25.84" weight="0.5" build="0.5"  key="000084058014000FC9A6BA24DA96CA8B778395B1C68727896418D76878BD6A4401C776130C98BBA40000000000000000000000000000000000000000459C1003"  />
    </face>
    <Traits>
      <Trait id="RomanHair" value="1" />
      <Trait id="Calculating" value="1" />
      <Trait id="Generosity" value="1" />
      <Trait id="Valor" value="1" />
      <!-- There are many traits but some combinations may cause conflicts when setting individual skills and equipment. These examples may not be a complete list.
      <Trait id="WandererEquipment" value="1" />
      <Trait id="Commander" value="7" />
      <Trait id="RomanHair" value="1" />
      <Trait id="BalancedFightingSkills" value="2" />
      <Trait id="EngineerSkills" value="3" />
      <Trait id="Mercy" value="1" />
      <Trait id="Generosity" value="-1" />
      <Trait id="GangLeaderIsNemesis" value="1" />
      <Trait id="HopliteFightingSkills" value="5" />
      <Trait id="Manager" value="8" />
      <Trait id="Politician" value="5" />
      <Trait id="RogueSkills" value="2" />
      -->
    </Traits>
    <skills>
      <skill id="OneHanded" value="1" />
      <skill id="TwoHanded" value="1" />
      <skill id="Polearm" value="1" />
      <skill id="Bow" value="1" />
      <skill id="Crossbow" value="1" />
      <skill id="Throwing" value="1" />
      <skill id="Riding" value="1" />
      <skill id="Athletics" value="1" />
      <skill id="Crafting" value="1" />
      <skill id="Scouting" value="1" />
      <skill id="Tactics" value="1" />
      <skill id="Roguery" value="1" />
      <skill id="Charm" value="1" />
      <skill id="Leadership" value="1" />
      <skill id="Trade" value="1" />
      <skill id="Steward" value="1" />
      <skill id="Medicine" value="1" />
      <skill id="Engineering" value="1" />
    </skills>
    <equipmentSet>
      <!-- Set your items for each slot as shown below using id's from SandBoxCore\ModuleData\spitems.xml. -->
      <equipment slot="Item0" id="Item.wooden_sword_t1" />
      <equipment slot="Item1" id="Item.training_bow" />
      <equipment slot="Item2" id="Item.default_arrows" />
      <equipment slot="Item3" id="" />
      <equipment slot="Head" id="" />
      <equipment slot="Cape" id="" />
      <equipment slot="Body" id="Item.empire_dress" />
      <equipment slot="Gloves" id="" />
      <equipment slot="Leg" id="Item.ladys_shoe" />
      <equipment slot="Horse" id="" />
      <equipment slot="HorseHarness" id="" />
    </equipmentSet>
    <!-- Your hero must have civilian equipment as well as battle equipment. -->
    <equipmentSet civilian="true">
      <equipment slot="Item0" id="" />
      <equipment slot="Item1" id="" />
      <equipment slot="Item2" id="" />
      <equipment slot="Item3" id="" />
      <equipment slot="Head" id="" />
      <equipment slot="Cape" id="" />
      <equipment slot="Body" id="Item.empire_dress" />
      <equipment slot="Gloves" id="" />
      <equipment slot="Leg" id="Item.ladys_shoe" />
      <equipment slot="Horse" id="" />
      <equipment slot="HorseHarness" id="" />
    </equipmentSet>
  </NPCCharacter>

</NPCCharacters>

Now create a CustomCompanionStrings.xml file within your ModuleData folder and add this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="string">
    <strings>
    <!-- Original example copied from: ...\Modules\SandBox\ModuleData\companion_strings.xml -->
    <!-- File renamed to avoid overwrite issues. -->
   
    <!-- Example of a custom wanderer recruitment conversation. -->
    <!-- This conversation is required for wanderer id="CompanionExample" -->
        <string id="prebackstory.CompanionExample" text="You want to know about me?" />
        <string id="backstory_a.CompanionExample" text="I'm an example of a custom wanderer." />
        <string id="backstory_b.CompanionExample" text="This conversation is just a template." />
        <string id="backstory_c.CompanionExample" text="It was created to help with mod development." />
        <string id="response_1.CompanionExample" text="Interesting, this is response 1." />
        <string id="response_2.CompanionExample" text="Hmm, this is response 2." />
        <string id="backstory_d.CompanionExample" text="Yes, well. It appears this example works." />
       
    </strings>
</base>

As of 15/04/2020 the game will not load your conversation text in the CustomCompanionStrings.xml file, but at least by setting it up it should load once the game is further developed. Until this happens you can still recruit your custom companions, however the game gives an error message in the conversation text when recruiting them. This does not prevent gameplay.

BE CAREFUL WHEN WRITING CUSTOM STRINGS XML
If you place any <!-- comments --> outside the <strings></strings> tags it will crash the game when the file is loaded. This is only relevant if you load it yourself, or if the game is finally updated to load more files from SubModule.xml without fixing this issue. Regardless, the XML above works although must be loaded in a DLL at this time.

The game will randomly select wanders from a pool of all available definitions. To ensure that only yours are loaded you can remove all wanderers from "\Modules\SandBox\ModuleData\spspecialcharacters.xml". To do this, open the file and delete everything between the lines marked here:
Code:
<?xml version="1.0" encoding="utf-8"?>
<NPCCharacters>
<!-- *** KEEP ABOVE, DELETE BELOW *** -->



<!-- *** DELETE ABOVE, KEEP EVERYTHING FROM THE LINE BELOW -->
  <!-- Templates BEGIN -->
  <!--TODO Cihan -->
  <!--Culture:Empire -->
  <!--Townsman -->

Rather than modify the contents of "\Modules\SandBox\ModuleData\spspecialcharacters.xml" you are meant to be able to add a modified version of "spspecialcharacters.xml" to your own ModuleData folder and reference it in your "SubModule.xml" file. But while I have had some success doing this with items it did not work for wanderers. Maybe I did something wrong or maybe the game isn't working as intended yet.

Either way if you do as stated above you will find the Example wanderer in the closest city when starting a new campaign. If you change her gear too much she will be too expensive to recruit immediately.

Although this is beyond the scope of your original question, if you would like to get your companion conversations working without waiting for the game to be updated, it is easy to make an empty module DLL and you need only add this code to your main class:
C#:
    protected override void OnGameStart(Game game, IGameStarter gameStarter)
    {
        // Called 1st after choosing (Resume Game, Campaign, Custom Battle) from the main menu.
        // The game does not load strings from XML, so for now custom conversation text must be loaded manually.
        try
        {
            CampaignGameStarter campaignGameStarter;
            if (game.GameType is Campaign)
            {
                campaignGameStarter = (gameStarter as CampaignGameStarter);
                campaignGameStarter.LoadGameTexts(BasePath.Name + "Modules/YourModName/ModuleData/CustomCompanionStrings.xml");
                InformationManager.DisplayMessage(new InformationMessage("XML Loaded."));
            }
        }
        catch (Exception e)
        {
            InformationManager.DisplayMessage(new InformationMessage("XML failed to load:" + e.Message));
        }
    }

Be sure to update your "YourModName"in the code above.
 
Last edited:
Upvote 0
Solution
If you have any issues with starting the game please let me know, as I have copy, paste, edited my own module contents to this post and may have made a typo (or 10) in the process.
 
Upvote 0
I have fixed a few typos in the XML above and tested the example character works. The recruitment conversation still isn't right, but it's a good start.
 
Upvote 0
Thanks again. I did run into an crash issue with an XML error. At first I thought it was this, but it’s from editing the lords.xml after using the Detailed Character Creator mod. While I don’t think you need my input since this most likely works, I will confirm it once I can.
 
Upvote 0
I have updated my original response significantly, to reflect new discoveries after @RapidFire helped me resolve the issue with recruitment conversations. Note my original companion conversation strings XML included a comment related error that was crashing the game when manually loaded using a DLL. It's only because the conversation XMLs are not currently loading via SubModule.xml that the error went unnoticed until now.

This issue may be causing some of your crashes. I have certainly had crashes related to poor use of the comment tags, for example:
<!--
<!--
-->

Leaving comment tags unclosed within closed comment tags as shown above caused the game to crash, although this was several updates ago. This gave me a real headache to find because I had done the same thing in other files (which in hindsight I bet the game wasn't loading) and I figured everything within comment tags would be ignored.
 
Upvote 0
Back
Top Bottom