### Create a Custom Screen Source: https://docs.bannerlordmodding.com/_gauntlet/screenbase Use this template to create your own screens by extending ScreenBase. It covers initialization, layer management, and data source setup. ```csharp public class MyExampleScreen : ScreenBase { private MyExampleVM _dataSource; private GauntletLayer _gauntletLayer; private GauntletMovie _movie; protected override void OnInitialize() { base.OnInitialize(); _dataSource = new MyExampleVM(); _gauntletLayer = new GauntletLayer(100) { IsFocusLayer = true }; AddLayer(_gauntletLayer); _gauntletLayer.InputRestrictions.SetInputRestrictions(); _movie = _gauntletLayer.LoadMovie("MyExampleMovie", _dataSource); } protected override void OnActivate() { base.OnActivate(); ScreenManager.TrySetFocus(_gauntletLayer); } protected override void OnDeactivate() { base.OnDeactivate(); _gauntletLayer.IsFocusLayer = false; ScreenManager.TryLoseFocus(_gauntletLayer); } protected override void OnFinalize() { base.OnFinalize(); RemoveLayer(_gauntletLayer); _dataSource = null; _gauntletLayer = null; } } ``` -------------------------------- ### Example XML for Module Strings Source: https://docs.bannerlordmodding.com/_csharp-api/localization An example of the std_module_strings_xml.xml file structure, defining English translations for localizable strings used in the module. This file serves as a reference for translators. ```xml ``` -------------------------------- ### Visual Studio Debugging - Launcher Source: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod Configure Visual Studio to launch the Bannerlord Launcher for debugging. This allows you to start your debugging session from the familiar launcher window. ```text TaleWorlds.MountAndBlade.Launcher.exe ``` -------------------------------- ### Visual Studio Debugging - Start External Program Source: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod Configure Visual Studio to launch Bannerlord.exe directly for debugging. Ensure the working directory and command-line arguments are set correctly. ```text /singleplayer _MODULES_*Native*SandBoxCore*CustomBattle*SandBox*StoryMode*ExampleMod*_MODULES_ ``` -------------------------------- ### SubModule.xml Configuration for UI Mod Source: https://docs.bannerlordmodding.com/_tutorials/modding-gauntlet-without-csharp This XML file defines the basic properties of your Bannerlord module. Ensure the 'Id' matches your module folder name. This setup is for a UI-only mod. ```xml ``` -------------------------------- ### Enabling Live UI Editing in Bannerlord Source: https://docs.bannerlordmodding.com/_tutorials/modding-gauntlet-without-csharp Use this console command within the game to enable live UI editing. This requires the Developer Console mod to be installed and enabled. ```plaintext ui.toggle_debug_mode ``` -------------------------------- ### Registering Dictionary of Lists for Saving Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem To save nested data structures like a Dictionary containing Lists, register both the outer and inner types. This example shows registering a Dictionary where the values are Lists of ExampleStruct. ```csharp protected override void DefineContainerDefinitions() { ConstructContainerDefinition(typeof(List)); ConstructContainerDefinition(typeof(Dictionary>)); } ``` -------------------------------- ### Implement Message Display on Title Screen Source: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod Override the OnSubModuleLoad method to add a new option to the game's title screen. This option, when selected, will display a "Hello World!" message in the game's chat. ```csharp Module.CurrentModule.AddInitialStateOption(new InitialStateOption("Message", new TextObject("Message", null), 9990, () => { InformationManager.DisplayMessage(new InformationMessage("Hello World!")); }, () => { return (false, null); })); ``` -------------------------------- ### Push a Screen onto the Stack Source: https://docs.bannerlordmodding.com/_gauntlet/screenbase This code demonstrates how to push a newly created screen onto the screen manager's stack. ```csharp ScreenManager.PushScreen(ViewCreatorManager.CreateScreenView()); ``` -------------------------------- ### SubModule.xml Configuration Source: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod This XML file defines your mod's metadata and structure. Ensure the Id matches your project name and the DLLName matches your compiled assembly. ```xml ``` -------------------------------- ### Define a Bannerlord Movie XML Template Source: https://docs.bannerlordmodding.com/_gauntlet/movie Use this template as the base structure for creating new GauntletView movies. Widgets should be added within the Window element. ```xml ``` -------------------------------- ### Basic Saving with SyncData in Campaign Behavior Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Implement SyncData in a CampaignBehaviorBase to persist simple string data across saves. Ensure the data field is declared and synced with a unique identifier. ```csharp public class CustomBehavior : CampaignBehaviorBase { // The data in this field will persist across saving public string Data; public override void SyncData(IDataStore dataStore) { // First argument is an identifier, only needs to be unique to this behavior dataStore.SyncData("Data", ref Data); } public override void RegisterEvents() { } } ``` -------------------------------- ### Sync Custom Data with Chunking Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Implement this method within your module's class to handle saving and loading of custom data. It serializes custom objects to JSON, splits them into chunks if necessary, and deserializes them back upon loading. Ensure `_customData` is initialized. ```csharp public override void SyncData(IDataStore dataStore) { if (dataStore.IsSaving) { var dataJson = JsonConvert.SerializeObject(_customData); var chunks = ToChunks(dataJson, short.MaxValue - 1024).ToArray(); dataStore.SyncData("NestedStruct", ref chunks); } if (dataStore.IsLoading) { var jsonDataChunks = Array.Empty(); if (dataStore.SyncData("NestedStruct", ref jsonDataChunks) && jsonDataChunks is not null) { JsonConvert.DeserializeObject>(ChunksToString(jsonDataChunks)); } else { _customData = new List(); } } } ``` -------------------------------- ### Registering List for Saving with SaveableTypeDefiner Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Define container types for saving built-in data structures like Lists. Register the specific generic type, such as List, within DefineContainerDefinitions. ```csharp protected override void DefineContainerDefinitions() { ConstructContainerDefinition(typeof(List)); } ``` -------------------------------- ### Define Localizable String with TextObject Source: https://docs.bannerlordmodding.com/_csharp-api/localization Define a localizable string using TextObject, including a string ID and placeholders for dynamic content. Ensure the string ID is unique and alphanumeric. ```csharp public const string conditionalString = "{=conditionalStringID}This proposal is on cooldown for {NUMBER_OF_DAYS} {?NUMBER_OF_DAYS.PLURAL_FORM}days{\}day{\\?}."; public static readonly TextObject conditionalTextObject = new TextObject(conditionalString); ``` ```csharp private const string exampleString = "{=stringID}Some text"; public static readonly TextObject exampleTextObject = new TextObject (exampleString); ``` -------------------------------- ### Add Using Directives for Bannerlord Modding Source: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod Include these directives at the top of your C# class to access necessary Bannerlord functionalities. Ensure your class inherits from MBSubModuleBase. ```csharp using TaleWorlds.Library; using TaleWorlds.Localization; using TaleWorlds.MountAndBlade; ``` -------------------------------- ### Advanced Serialization with SyncData Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Utilize SyncData with local variables for custom serialization and deserialization logic. This pattern is useful for complex data handling, especially when combined with IsLoading and IsSaving checks. ```csharp public override void SyncData(IDataStore dataStore) { var dataToSave = new List(); if(dataStore.IsSaving) { // Load the data to save into the list, can gather data from other parts of the mod dataToSave = gatherData(); } dataStore.SyncData("dataToSave", ref dataToSave); if(dataStore.IsLoading) { // The save data has been loaded into dataToSave array. // Do whatever logic is necessary to restore the state based on the saved data restoreData(dataToSave); } } ``` -------------------------------- ### Registering Settlements in submodule.xml Source: https://docs.bannerlordmodding.com/_tutorials/new_settlements Add this XmlNode to your mod's submodule.xml to include your custom settlement definitions. ```xml ``` -------------------------------- ### Split Large Strings into Chunks Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Use this utility function to split a large string into smaller chunks, suitable for saving when the total string size exceeds game limits. The `maxChunkSize` should be less than `short.MaxValue - 1024`. ```csharp private static IEnumerable ToChunks(string str, int maxChunkSize) { for (var i = 0; i < str.Length; i += maxChunkSize) yield return str.Substring(i, Math.Min(maxChunkSize, str.Length-i)); } ``` -------------------------------- ### Save Custom Data Using JSON Serialization Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem An alternative to SaveableTypeDefiner, this method uses JSON serialization for saving custom data. It requires manual serialization and deserialization within the SyncData method. ```csharp public class CustomJSONBehavior : CampaignBehaviorBase { public class ExampleNested { public NestedStruct Data; } public struct NestedStruct { public bool Flag; } private List _customData = new List(); public override void SyncData(IDataStore dataStore) { if (dataStore.IsSaving) { var jsonString = JsonConvert.SerializeObject(_customData); dataStore.SyncData("NestedStruct", ref jsonString); } if (dataStore.IsLoading) { var jsonString = ""; if (dataStore.SyncData("NestedStruct", ref jsonString) && !string.IsNullOrEmpty(jsonString)) { _customData = JsonConvert.DeserializeObject>(jsonString); } else { _customData = new List(); } } } public override void RegisterEvents() { } } ``` -------------------------------- ### Define Custom Saveable Types with SaveableTypeDefiner Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem Use SaveableTypeDefiner to register custom classes and structs for game data saving. Ensure a unique base ID and define all custom types and containers. ```csharp public class CustomBehavior : CampaignBehaviorBase { public ExampleStruct StructData; public List MapNotificationList; public Dictionary> NestedData; public override void SyncData(IDataStore dataStore) { dataStore.SyncData("StructData", ref StructData); dataStore.SyncData("MapNotificationList", ref MapNotificationList); dataStore.SyncData("NestedData", ref NestedData); } public override void RegisterEvents() { } } public class CustomSaveDefiner : SaveableTypeDefiner { // use a big number and ensure that no other mod is using a close range public CustomSaveDefiner() : base(2_333_000) { } protected override void DefineClassTypes() { // The Id's here are local and will be related to the Id passed to the constructor AddClassDefinition(typeof(CustomMapNotification), 1); AddStructDefinition(typeof(ExampleStruct), 2); AddClassDefinition(typeof(ExampleNested), 3); AddStructDefinition(typeof(NestedStruct), 4); } protected override void DefineContainerDefinitions() { ConstructContainerDefinition(typeof(List)); // Both of these are necessary: order isn't important ConstructContainerDefinition(typeof(List)); ConstructContainerDefinition(typeof(Dictionary>)); } } public struct ExampleStruct { // Local ID's start from one if the class/struct does not inherit from any // game's types with saveable data [SaveableField(1)] public PartyBase Attacker; } public class CustomMapNotification : InformationData { // InformationData already contains 5 definitions, so start from 6 for custom data [SaveableProperty(6)] public Hero Mercenary { get; set; } [SaveableProperty(7)] public bool IsHandled { get; set; } } public struct NestedStruct { [SaveableField(1)] public bool Flag; } public class ExampleNested { [SaveableField(1)] public NestedStruct Data; } ``` -------------------------------- ### Defining Settlement Trade and Binding Source: https://docs.bannerlordmodding.com/_tutorials/new_settlements Attributes used within the settlements.xml to link villages to towns and define trade relationships. ```xml trade_bound="Settlement.town_M1" bound="Settlement.town_M1" ``` -------------------------------- ### Reconstruct String from Chunks Source: https://docs.bannerlordmodding.com/_csharp-api/savesystem This function reconstructs a single string from an array of string chunks. It's used when loading data that was previously split for saving. ```csharp private static string ChunksToString(string[] chunks) { if (chunks.Length == 0) return string.Empty; else if (chunks.Length == 1) return chunks[0]; var strBuilder = new StringBuilder(short.MaxValue); foreach (var chunk in chunks) strBuilder.Append(chunk); return strBuilder.ToString(); } ``` -------------------------------- ### Set Numeric Variables for TextObject Source: https://docs.bannerlordmodding.com/_csharp-api/localization A utility function to set numeric variables within a TextObject, handling pluralization based on the provided value. This is useful for dynamic text generation. ```csharp public static void SetNumericVariable(TextObject textObject, string variableKey, int variableValue) { if (string.IsNullOrEmpty(variableKey)) { return; } TextObject explainedTextObject = new TextObject(variableValue); explainedTextObject.SetTextVariable("PLURAL_FORM", variableValue != 1 ? 1 : 0); if (textObject is null) { MBTextManager.SetTextVariable(variableKey, explainedTextObject); } else { textObject.SetTextVariable(variableKey, explainedTextObject); } } ``` -------------------------------- ### XML Structure for Module Translation Source: https://docs.bannerlordmodding.com/_csharp-api/localization This XML structure defines the translation for a specific language, including language tags and string translations. Ensure all original string IDs and variables are preserved. ```xml ``` -------------------------------- ### Defining Village Production Type Source: https://docs.bannerlordmodding.com/_tutorials/new_settlements Attribute used to specify the production type for a village, referencing definitions in spprojects.xml. ```xml village_type="VillageType.fisherman" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.