How to register custom text processor class (inherited from the TaleWorlds.Localization.TextProcessor.LanguageSpecificTextProcessor) in system?

Users who are viewing this thread

Hello everyone, I am creating localization for a new non-official language and want to add a text processor for it.
I created a text processor using tips from this tutorial.
Now I want to register it in the system to be able to use it inside localization files by specifying it in the attribute text_processor of the LanguageData tag inside the language_data.xml file.

I have a dll file that contain class of text processor inherited from TaleWorlds.Localization.TextProcessor.LanguageSpecificTextProcessor.
What do I need to do next?

I tried to make a module for the game by putting the file in the bin/Win64_Shipping_Client folder of the module.

But as far as I understand, without a class inherited from MBSubModuleBase, the game will not be able to load this dll. Is this correct?
In general, I am new at developing game mods, but I have experience in programming.
 
It's no biggie. Edit your submodule.xml, so that your mod "knows" about the DLL:

XML:
<Module>
  <Name value="BRUTALITY"/>
  <Id value="BRUTALITY"/>
  <Version value="v1.0.0"/>
  <SingleplayerModule value="true"/>
  <MultiplayerModule value="FALSE UNLESS YOU'RE BUILDING FOR MP"/>
  <DependedModules>
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="StoryMode"/>
  </DependedModules>
  <SubModules>
    <SubModule>
      <Name value="YOUR_MOD_NAME"/>
      <DLLName value="YOUR_DLL_NAME.dll"/>
      <SubModuleClassType value="YOUR_MOD_NAME.SubModule"/>
         <Tags>
             <Tag key="DedicatedServerType" value="none" />
             <Tag key="IsNoRenderModeElement" value="false" />
         </Tags>     
    </SubModule>
  </SubModules>
  <Xmls>
  </Xmls>
</Module>
 
It's no biggie. Edit your submodule.xml, so that your mod "knows" about the DLL:

XML:
<Module>
  <Name value="BRUTALITY"/>
  <Id value="BRUTALITY"/>
  <Version value="v1.0.0"/>
  <SingleplayerModule value="true"/>
  <MultiplayerModule value="FALSE UNLESS YOU'RE BUILDING FOR MP"/>
  <DependedModules>
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="StoryMode"/>
  </DependedModules>
  <SubModules>
    <SubModule>
      <Name value="YOUR_MOD_NAME"/>
      <DLLName value="YOUR_DLL_NAME.dll"/>
      <SubModuleClassType value="YOUR_MOD_NAME.SubModule"/>
         <Tags>
             <Tag key="DedicatedServerType" value="none" />
             <Tag key="IsNoRenderModeElement" value="false" />
         </Tags>    
    </SubModule>
  </SubModules>
  <Xmls>
  </Xmls>
</Module>
Thank you for your reply.

When in this line:
<DLLName value="YOUR_DLL_NAME.dll"/>
I specify the correct name of my dll, the following entry appears in the log:
The system cannot find the file specified at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo) at TaleWorlds.MountAndBlade.Launcher.Library.LauncherModsDLLManager.GetDLLVerifyReport(String[] dlls)

(If the name is incorrect, then this name is simply added to the list of dlls that failed to load and this error is not displayed)

I believe this is because my class (which is specified in the <SubModuleClassType value="YOUR_MOD_NAME.SubModule"/> line) is not a descendant of the MBSubModuleBase class, but is inherited, as I mentioned above, from TaleWorlds.Localization.TextProcessor.LanguageSpecificTextProcessor.
 
The error indicates that your DLL may not be in the right directory. Is it in \bin\Win64_Shipping_Client ?

As for inheriting from existing classes that aren't derived from MBSubModuleBase, that's totally allowed. Is your code using the correct namespace?
 
The error indicates that your DLL may not be in the right directory. Is it in \bin\Win64_Shipping_Client ?

As for inheriting from existing classes that aren't derived from MBSubModuleBase, that's totally allowed. Is your code using the correct namespace?
OK, now I don't understand what the problem is.
I tried to do everything from scratch. I have only the original files in the Modules folder.
I downloaded this template for mods, which is recommended in the documentation for the mods (https://github.com/BUTR/Bannerlord.Module.Template)
I set everything up. Created an empty mod. Compiled it. It created a mod in the Modules folder. I launch Bannerlord and the same error.
log message:
Code:
Init LauncherModsDLLManager
Need to verify: CustomTextProcessor.dll
Starting verifying DLLs
Couldn't verify dlls
The system cannot find the file specified
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at TaleWorlds.MountAndBlade.Launcher.Library.LauncherModsDLLManager.GetDLLVerifyReport(String[] dlls)

Yes, dll file in \bin\Win64_Shipping_Client

The mod's structure is:
Code:
CustomTextProcessor
    bin
        Win64_Shipping_Client
            CustomTextProcessor.dll
    SubModule.xml

SubModule.cs file:
C#:
using TaleWorlds.MountAndBlade;


namespace CustomTextProcessor
{
    public class SubModule : MBSubModuleBase
    {
        protected override void OnSubModuleLoad()
        {
            base.OnSubModuleLoad();

        }

        protected override void OnSubModuleUnloaded()
        {
            base.OnSubModuleUnloaded();

        }

        protected override void OnBeforeInitialModuleScreenSetAsRoot()
        {
            base.OnBeforeInitialModuleScreenSetAsRoot();

        }
    }
}

SubModule.xml:
XML:
  <?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="CustomTextProcessor" />
      <Name value="CustomTextProcessor" />
      <Version value="v0.0.1" />
      <DefaultModule value="false" />
      <ModuleCategory value="Singleplayer" />
      <ModuleType value="Community" />
      <Url value="$moduleurl$" />
    - <DependedModules>
          <DependedModule Id="Native" />
          <DependedModule Id="SandBoxCore" />
          <DependedModule Id="Sandbox" />
          <DependedModule Id="StoryMode" />
          <DependedModule Id="CustomBattle" />
      </DependedModules>
- <!--  Community Dependency Metadata
  -->
- <!--  https://github.com/BUTR/Bannerlord.BLSE#for-modders
  -->
    - <DependedModuleMetadatas>
          <DependedModuleMetadata id="Native" order="LoadBeforeThis" />
          <DependedModuleMetadata id="SandBoxCore" order="LoadBeforeThis" />
          <DependedModuleMetadata id="Sandbox" order="LoadBeforeThis" />
          <DependedModuleMetadata id="StoryMode" order="LoadBeforeThis" />
          <DependedModuleMetadata id="CustomBattle" order="LoadBeforeThis" />
      </DependedModuleMetadatas>
- <!--  Community Dependency Metadata
  -->
    - <SubModules>
        - <SubModule>
              <Name value="CustomTextProcessor" />
              <DLLName value="CustomTextProcessor.dll" />
              <SubModuleClassType value="CustomTextProcessor.SubModule" />
              <Tags />
          </SubModule>
      </SubModules>
  </Module>
 
Hmm. It all looks OK. If you comment out everything that's not in your current SubModule.cs and rebuild your DLL, does your mod now operate?

If "yes", then your problem's in your new code; you want to run in Debug and see where it broke, or post it here and let's see if we can spot what's wrong.

If "no", then your problem may be XML-related. IIRC, I had some real problems with that at first, and, like you, I started with the BUTR template. I've since built something that's a lot simpler, basically just "drop this into your Modules folder, open SLN, start coding"... but I didn't build it as a generic template for everybody's use. Maybe I need to take the time to do this.
 
Hmm. It all looks OK. If you comment out everything that's not in your current SubModule.cs and rebuild your DLL, does your mod now operate?

If "yes", then your problem's in your new code; you want to run in Debug and see where it broke, or post it here and let's see if we can spot what's wrong.

If "no", then your problem may be XML-related. IIRC, I had some real problems with that at first, and, like you, I started with the BUTR template. I've since built something that's a lot simpler, basically just "drop this into your Modules folder, open SLN, start coding"... but I didn't build it as a generic template for everybody's use. Maybe I need to take the time to do this.
OK, I added a simple code that displays the message in the game, as in the example in the tutorial, and everything works.
Although I still don't understand why those messages are displayed in the log. In addition to the message in the log, a red icon with a message is also drawn opposite the mod: "Couldn't verify some or all of the code included in this module." Is this normal? Is there any way to remove it (uh, verify the mod?)?



Also, in case anyone who reads this thread because of the title is interested, I found a way to "register" a text processor in the game.
The game loads the text processor specified in the text_processor attribute using the C# function Type.GetType. Since your class will be in an external assembly, you need to specify the AssemblyQualifiedName of your class in this attribute. That's all.
 
Is this normal? Is there any way to remove it (uh, verify the mod?)?
Beats me. So far as I can tell, any DLL included with any mod is "unverified", lol. Seriously, you can merely be writing code in SubModule.cs using public static methods written by TaleWorlds, and you're still not "verified".

So... good news, you've built code that runs at all. Trust me, that's half the battle.
 
Beats me. So far as I can tell, any DLL included with any mod is "unverified", lol. Seriously, you can merely be writing code in SubModule.cs using public static methods written by TaleWorlds, and you're still not "verified".

So... good news, you've built code that runs at all. Trust me, that's half the battle.
OK. Thank you for the explanation!
 
Back
Top Bottom