Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added back basic Bannerlord support #2180

Merged
merged 20 commits into from
Nov 6, 2024

Conversation

Aragas
Copy link
Contributor

@Aragas Aragas commented Oct 16, 2024

No description provided.

@Pickysaurus
Copy link
Contributor

Thanks for setting this up @Aragas. We have a few bits to finish off before we properly dive into Bannerlord support so don't worry if this takes a while to get reviewed :)

@Sewer56
Copy link
Member

Sewer56 commented Oct 31, 2024

I went through around half of this, will look at the other half this morning.

CC. @Aragas I also started a draft of the info documentation page for the game (to familiarise myself with Bannerlord). I did some digging around for a few hours. I think it's around ~80% of the way there; just need some extra minor details mentioned such as where the load order and enabled mods are saved, etc. added.

Look through the text below and make any improvements/changes to it as needed.
[To get the markdown, just quote this post and copy from there]


General Info

  • Name: Mount & Blade II: Bannerlord
  • Release Date: 2020
  • Engine: Custom - C++ Foundation, C# Scripting

Stores and Ids

Useful Links

Engine and Mod Support

Bannerlord uses a native engine with self-hosted .NET 6 for Steam/GOG/Epic.
Modding is supported out of the box.

Bannerlord has a modding extension BLSE
that expands the modding capabilities.

It's required to run mods on Xbox and is optional for Steam/GOG/Epic.

Installing Mods (Outside of NMA)

Automatic

Typically installs immediately via Steam Client

Manual

Mod Types

Since it's not a standard mod.

BLSE

BLSE needs to be placed beside the main game binary:

  • bin/Gaming.Desktop.x64_Shipping_Client for Xbox Store
  • bin/Win64_Shipping_Client for other targets

Outside of that, we will want to launch BLSE rather than the regular game binary if BLSE is installed.

Typical Mod Structure (Module)

See: Bannerlord Documentation

MyModule
├── AssetPackages
│   └── assetpackage.tpac
├── Atmospheres
│   ├── Interpolated
│   │   └── interpolatedatmosphere.xml
│   └── atmosphere.xml
├── bin
│   └── Win64_Shipping_Client
│       └── MyModule.dll
├── GUI
│   ├── Brushes
│   └── Prefabs
├── ModuleData
├── SceneObj
└── SubModule.xml

The only needed file is SubModule.xml, this is the metadata file.
All else is optional.

Note that the bin folder contains DLLs loaded by the game, don't mistake this tree with
the folder structure of the game itself.

Example SubModule.xml

Taken from Player Settlements

<Module>
  <Name value="Player Settlement"/>
  <Id value="PlayerSettlement"/>
  <Version value="v6.0.2"/>
  <Url value="https://www.nexusmods.com/mountandblade2bannerlord/mods/7298" />
  <SingleplayerModule value="true"/>
  <MultiplayerModule value="false"/>
  <Official value="false"/>
  <DefaultModule value="false" />
  <ModuleCategory value="Singleplayer" />
  <ModuleType value="Community" />
  <UpdateInfo value="NexusMods:7298" />
  <!-- Used by PlayerSettlement to dynamically add more settlement variants -->
  <PlayerSettlementsTemplates path="ModuleData/Player_Settlement_Templates" />
  <!-- Used by PlayerSettlement to dynamically blacklist settlement variants -->
  <PlayerSettlementsTemplatesBlacklist path="ModuleData/template_blacklist.txt" />
  <DependedModules>
    <DependedModule Id="Bannerlord.Harmony" />
    <DependedModule Id="Bannerlord.ButterLib" />
    <DependedModule Id="Bannerlord.UIExtenderEx" />
    <DependedModule Id="Bannerlord.MBOptionScreen" />
    <DependedModule Id="Native"/>
    <DependedModule Id="SandBoxCore"/>
    <DependedModule Id="Sandbox"/>
    <DependedModule Id="StoryMode" />
  </DependedModules>
  <!-- Community Metadata -->
  <DependedModuleMetadatas>
    <DependedModuleMetadata id="Bannerlord.Harmony" order="LoadBeforeThis" version="v2.2.2" />
    <DependedModuleMetadata id="Bannerlord.ButterLib" order="LoadBeforeThis" version="v2.8.15" />
    <DependedModuleMetadata id="Bannerlord.UIExtenderEx" order="LoadBeforeThis" version="v2.12.0" />
    <DependedModuleMetadata id="Bannerlord.MBOptionScreen" order="LoadBeforeThis" version="v5.10.1" />
    <DependedModuleMetadata id="Native" order="LoadBeforeThis" version="1.0.0.*" />
    <DependedModuleMetadata id="SandBoxCore" order="LoadBeforeThis" version="1.0.0.*" />
    <DependedModuleMetadata id="Sandbox" order="LoadBeforeThis" version="1.0.0.*" />
    <DependedModuleMetadata id="StoryMode" order="LoadBeforeThis" version="1.0.0.*" />
    <DependedModuleMetadata id="CustomBattle" order="LoadBeforeThis" version="1.0.0.*" optional="true" />
  </DependedModuleMetadatas>
  <SubModules>
    <SubModule>
      <Name value="PlayerSettlement"/>
      <DLLName value="PlayerSettlement.dll"/>
      <SubModuleClassType value="BannerlordPlayerSettlement.Main"/>
      <Tags />
    </SubModule>
  </SubModules>
  <Xmls/>
</Module>

Per-Store Mods

It's possible to have per-store specific code for Bannerlord, namely:

📁 Gaming.Desktop.x64_Shipping_Client
    📄 0Harmony.dll (2.2 MB)
    📄 MCMv5.dll (493.1 kB)
    📄 PlayerSettlement.dll (250.9 kB)
    📄 PlayerSettlement.pdb (97.1 kB)
    📄 System.Numerics.Vectors.dll (115.9 kB)
📁 Win64_Shipping_Client
    📄 0Harmony.dll (2.2 MB)
    📄 MCMv5.dll (493.1 kB)
    📄 PlayerSettlement.dll (250.9 kB)
    📄 PlayerSettlement.pdb (97.1 kB)
    📄 System.Numerics.Vectors.dll (115.9 kB)
  • Gaming.Desktop.x64_Shipping_Client applies to Xbox Store
  • Win64_Shipping_Client applies to other targets

Mod Load Order

As seen in order="LoadBeforeThis, some mods may be rearranged on boot in terms of load order.
This needs to be expressed in App UI.

Mod Names

We should ideally extract the mod name from the SubModule.xml if possible,
i.e. from <Name value="Player Settlement"/>.

If there are multiple mods in 1 download, we may need to combine it with the mod page name.

Outside Changes

The game has a built-in mod manager.

If the user chooses to rearrange mods in the 1st party launcher, we will need to ingest
the changes. Ask team for clarification given last week's discussion.

Ingesting RuntimeDataCache Folders

Mod modules can generate a RuntimeDataCache folder their module at runtime; which contains
assets ready for consumption generated by the game engine (from the module sources).

Computing this folder's contents is a costly operation, for large total conversion mods, this can
even take half an hour, or longer on some machines based on reports.

It's imperative we ingest the files generated in this folder right into the App, so the user can
quickly switch between loadouts. An override of MoveNewFilesToMods should do the trick.

Diagnostics

Diagnostics NMA Wiki Link

Warning: Gauntlet (non-C#) Modules Must load Before Official Module

Modding Wiki Link

Severity: Warning
Summary: Codeless Gauntlet UI Mods must be loaded before Official Modules.
Details: Mods which override Gauntlet UIs from Official Modules MUST be loaded before said module.

To detect this, look at mods which override the GUI/Prefabs folder. There may be more folders.

Suggestion: Mods Should load after Official Modules

Modding Wiki Link

Severity: Suggestion
Summary: Mods should load after official modules.
Details: User created mods should load after the following official modules. Native, SandBox, Sandbox Core, CustomBattle, StoryMode.

Note: Excludes Gauntlet non-C# Modules.

Critical: Missing Dependency Submodules

Relevant Documentation

Severity: Critical
Summary: Missing Required Module {ModuleA} required by {ModuleB}
Details: {ModuleB} requires {ModuleA} but is not present. You must download {ModuleA} first.

We check against the DependedModules array of SubModule.xml.
Question: Is there a database of Module IDs to download pages?

Warning: Duplicated Module ID Detected

Relevant Documentation

Severity: Warning
Summary: Mod conflict: {ModA} and {ModB} can't run together (using same ID).
Details:

We found two mods that can't run together:
- {ModA} (version {VersionA})
- {ModB} (version {VersionB})

They're using the same identifier ({ModId}), so you'll need to pick one and disable the other.

if the mod versions match, the text should change a little bit:

Summary: {ModA} might be installed twice (found two copies with version {VersionA}).
Details:

We found what looks like a duplicate mod:
- {ModA} (version {VersionA})
- {ModB} (version {VersionA})

Since they're using the same identifier ({ModId}) and have identical versions, you might have
accidentally installed the same mod twice. Check your loadout and remove one copy.

To determine this, check ID and version of SubModule.xml.

Diagnostics (Potential/Future)

Missing Bin Files for Current Store

[Note: Doublecheck with Community if Copying Stuff across Folders is Ok]

Presumably a mod which has Win64_Shipping_Client folder only will not work on Xbox (Game Pass)
but will work on other platforms. Likewise a mod with only Gaming.Desktop.x64_Shipping_Client will
only work on Xbox.

Whether we copy Win64_Shipping_Client to Gaming.Desktop.x64_Shipping_Client and vice versa
will require discussion with rest of team and community.

Questions (Aragas & Co)

What's Missing in Existing Mod Managers

Some mod pages say 'Installing with some mod managers may cause a crash'.
I believe this info is out of date, but need to doublecheck.

Auto Copy Binary Files Across Store Releases

Discuss whether we should copy binary files across store releases.

Display Native Game Modules

Should we show the native game modules, Native, SandBox, Sandbox Core, CustomBattle, StoryMode.
Doing this may require some new tech in the App.

Diagnostics for Save Breaking Features

Are there diagnostics for things that break saves?

That's not well defined in docs outside of https://docs.bannerlordmodding.com/_intro/general-recommendations.html (not linked in sidebar).

Questions (Future Features)

  • https://docs.bannerlordmodding.com/_xmldocs/submodule.html#element-descriptions Description is unclear.

    • "XMLs with the same id from two separate mods (or the same mod) will have their assets combined and NOT overwritten." refers to <XmlName id=, so multiple entries from those will be combined.
    • Does 'overwritten' work with regards to when the 'path' field is the same?
    • Should we inform the user of this conflict in load order?
    • Highlight mods with same item IDs as conflicts https://docs.bannerlordmodding.com/_xmldocs/items/item/
  • Some mods are packed with .tpac. (a.k.a. 'Taleworlds Package' named by some people)

    • Does this affect load ordering?
    • Can a .tpac file contain any content that 'maps' onto the module folder?
    • Should we emit a diagnostic if a mod can be packed as .tpac for performance reasons?

@Aragas
Copy link
Contributor Author

Aragas commented Oct 31, 2024

@Sewer56
The game uses .NET Framework on Steam/GOG/Epic for now. The game seems to work when launched via .NET 6 (and BLSE give has a parameter for that), but it's not by default.
Xbox only uses .NET 6

@Aragas
Copy link
Contributor Author

Aragas commented Oct 31, 2024

Whether we copy Win64_Shipping_Client to Gaming.Desktop.x64_Shipping_Client and vice versa
will require discussion with rest of team and community.

It should be generally safe to use Win64_Shipping_Client on Gaming.Desktop.x64_Shipping_Client. I've added this feature recently in the Vortex extension, generally, works. The only exception was a Visual Basic mod

@Aragas
Copy link
Contributor Author

Aragas commented Oct 31, 2024

Diagnostics for Save Breaking Features

Save files contain the mods and the versions that were used. We produce a warning in both BLSE and Vortex when the version mismatches (should be an error if we downgraded, but I haven't done that yet)
And there should be an error if a mod is missing

@Sewer56
Copy link
Member

Sewer56 commented Oct 31, 2024

@Sewer56 The game uses .NET Framework on Steam/GOG/Epic for now. The game seems to work when launched via .NET 6 (and BLSE give has a parameter for that), but it's not by default. Xbox only uses .NET 6

Oh that's whack, so they have an entire untrimmed .NET 6.0.12 runtime present in the game files but that goes entirely unused.
I didn't expect that.

@Sewer56
Copy link
Member

Sewer56 commented Oct 31, 2024

@Aragas as for the big blob of text. Just make any edits you deem necessary and throw it in the markdown file (alongside other games in docs/developers/games folder). 👌

@Sewer56
Copy link
Member

Sewer56 commented Oct 31, 2024

Save files contain the mods and the versions that were used. We produce a warning in both BLSE and Vortex when the version mismatches (should be an error if we downgraded, but I haven't done that yet)
And there should be an error if a mod is missing

The way we emit warnings in the App is through the 'Health Check' (Diagnostics) view.
Example with Stardew Valley.

image

image

And if it's a module that's required by another mod:

image

image

Although there isn't any UX around this currently, the plans are to stop the user if there's any diagnostic which emits a critical (or similar). In this case, for Bannerlord we could emit a critical if a module is missing, letting the user know before they boot a game.

@Aragas
Copy link
Contributor Author

Aragas commented Oct 31, 2024

@Sewer56 The game uses .NET Framework on Steam/GOG/Epic for now. The game seems to work when launched via .NET 6 (and BLSE give has a parameter for that), but it's not by default. Xbox only uses .NET 6

Oh that's whack, so they have an entire untrimmed .NET 6.0.12 runtime present in the game files but that goes entirely unused. I didn't expect that.

It's like this for a long time, we also had some jokes regarding this. The game developers were in the process of migrating .NET FX 472 libraries into .NET Standard2.0, but I haven;t checked for a whle if they finished or not

@github-actions github-actions bot added the status-needs-rebase Set by CI do not remove label Nov 4, 2024
Copy link
Contributor

github-actions bot commented Nov 4, 2024

This PR conflicts with main. You need to rebase the PR before it can be merged.

@github-actions github-actions bot removed the status-needs-rebase Set by CI do not remove label Nov 5, 2024
Copy link
Contributor

github-actions bot commented Nov 5, 2024

This PR doesn't conflict with main anymore. It can be merged after all status checks have passed and it has been reviewed.

@Sewer56 Sewer56 merged commit 7bd0970 into Nexus-Mods:main Nov 6, 2024
14 checks passed
@Aragas Aragas deleted the bannerlord-ressurection branch November 7, 2024 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants