### 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.