Show / Hide Table of Contents

How Mods are Loaded

Mods are packaged in the Modules folder with along with a respective SubModule.xml (where ${name} is the name of your module folder).
Bannerlord loads these modules at startup.

External Documentation

Reading Bannerlord Code

We recommend using dnspy to read Bannerlord dlls.

Accessing Private Variables/Classes

Reading and Writing to a Private Variable

using System;
using System.Reflection;

class Foo {
    private string _bar = "private bar";

    public void printBar()
    {
        Console.WriteLine(_bar);
    }
}

class MainClass {
  public static void Main (string[] args) {
    // Create instance
    Foo foo = new Foo();

    foo.printBar(); // -> private bar

FieldInfo is used to access variable information of a given class We have to specify NonPublic as BindingFlags for "GetField" default to Public and Instance

    FieldInfo fieldInfo = typeof(Foo).GetField("_bar", BindingFlags.NonPublic | BindingFlags.Instance);

Reading value needs a instance (or null if static)

    string bar = (string)fieldInfo.GetValue(foo);
    Console.WriteLine(bar); // -> private bar

Setting values needs a instance to set (or null if static) and a value.

    fieldInfo.SetValue(foo, "I set a new value!");
    foo.printBar(); // -> I set a new value!
  }
}


Full Class

using System;
using System.Reflection;

class Foo {
    private string _bar = "private bar";

    public void printBar()
    {
        Console.WriteLine(_bar);
    }
}

class MainClass {
  public static void Main (string[] args) {
    // Create instance
    Foo foo = new Foo();

    foo.printBar();

    // FieldInfo is used to access variable information of a given class
    // We have to specify NonPublic as BindingFlags for "GetField" default to Public and Instance
    FieldInfo fieldInfo = typeof(Foo).GetField("_bar", BindingFlags.NonPublic | BindingFlags.Instance);

    // Reading value needs a instance (or null if static)
    string bar = (string)fieldInfo.GetValue(foo);
    Console.WriteLine(bar);

    // Setting values needs a instance to set (or null if static) and a value.
    fieldInfo.SetValue(foo, "I set a new value!");
    foo.printBar();

  }
}


Instantiating a Internal/Private Class

Inaccessible code

namespace ConsoleApp.Private
{
    class PrivateClass
    {
        public int someVar = 5;
    }
}

Creating an instance with Activator

using System;
using System.Reflection;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Activator
            // Need to get assembly when getting type, need full namespace type name as well.
            // Assembly may be different, you can pull assembly off public types
            Type privateType = Assembly.GetCallingAssembly().GetType("ConsoleApp.Private.PrivateClass");
            // Create class given a type
            object privateClass = Activator.CreateInstance(privateType);

            // Get someVar field value and print it
            Console.WriteLine(privateType.GetField("someVar").GetValue(privateClass));

            Console.ReadKey();
        }
    }
}

Creating an instance with constructor

using System;
using System.Reflection;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Get the constructor and invoke it
            // Need to get assembly when getting type, need full namespace type name as well.
            // Assembly may be different, you can pull assembly off public types
            Type privateType = Assembly.GetCallingAssembly().GetType("ConsoleApp.Private.PrivateClass");
            // Get constructor with no arguments
            ConstructorInfo privateTypeCtor = privateType.GetConstructor(new Type[0]);
            // Invoke constructor with no arguments
            object privateClass = privateTypeCtor.Invoke(new object[0]);

            // Get someVar field value and print it
            Console.WriteLine(privateType.GetField("someVar").GetValue(privateClass));

            Console.ReadKey();
        }
    }
}

Patching Existing Code

There is existing Bannerlord code that you may want to change. For this we use Harmony.

  • Improve this Doc
☀
☾
Back to top Generated by DocFX