A comprehensive Mount & Blade II: Bannerlord modification that brings the world of Middle-earth to life with authentic Lord of the Rings races, gameplay systems, and strategic depth.
- About
- Features
- Technical Highlights
- Getting Started
- Development Workflow
- Contributing
- Documentation
- Community
LOTRAOM (Lord of the Rings: Age of Men) is a feature-rich Bannerlord mod that transforms the game into a Middle-earth experience. Built with modern software engineering practices, the mod features a robust C# architecture with dependency injection, comprehensive testing, and performance optimizations designed for large-scale battles and complex campaign gameplay.
This project is designed for collaborative development, with a well-defined branching strategy that supports multiple developers working simultaneously on features and bug fixes.
-
Race-Based Combat Bonuses - Authentic LOTR racial abilities affecting damage, defense, and tactics
- Men, Elves, Dwarves, Orcs, Uruk-hai, and more
- Dynamic bonus calculations based on attacker/defender race combinations
- Indexed rule parsing engine for performance
-
Custom Battles - Enhanced battle configuration with LOTR factions
- Faction-specific troop rosters
- Custom battle scenarios
-
Advanced AI Systems
- Strategic intelligence for settlement targeting
- Diplomatic decision-making
- Enhanced warfare behaviors
-
Custom Wanderers - LOTR-themed wandering companions with unique backstories
-
Messenger System - In-game messenger management integrated with the encyclopedia
-
Warg System - AI-controlled wargs with custom behavior trees
-
Strategic Gameplay
- Troop weight-based party size limits
- Custom starting conditions (funds, influence, equipment)
- Enhanced bandit behaviors
Playable factions include:
- Free Peoples: Rohan, Gondor, Erebor, Rivendell, Mirkwood
- Forces of Darkness: Mordor, Isengard, Gundabad, Dol Guldur, Harad, Rhûn, Umbar
- Independent: Dunland, and more
- Modern C# Design: Built on .NET Framework 4.7.2 with nullable reference types enabled
- Dependency Injection: DryIoC container for clean, testable architecture
- Design Patterns: Hook pattern, Strategy pattern, Builder/Fluent APIs, Registry pattern
- Harmony Patching: Non-destructive game modifications using Harmony 2.x
- UIExtender Integration: Custom UI extensions for encyclopedia and game menus
- Mod Configuration Menu (MCM): In-game configuration options
- Object Pooling: Reduces garbage collection pressure in combat-heavy scenarios
- String Caching: Pre-computed enum-to-string mappings with concurrent dictionary caching
- Indexed Rule Parsing: Fast bonus calculation engine
- Optimized Hook Coordination: Efficient game event handling
- Test-Driven Development: 2039 unit tests (MSTest + NSubstitute); 26.89% line coverage today, held above a 26% pre-commit floor that ratchets up as coverage climbs
- Code Quality Standards: SOLID principles, interface segregation, constructor injection
- CI/CD Ready: Automated build scripts for Windows (PowerShell) and Linux (Bash)
- Documentation: XML docs, Architecture Decision Records (ADR), inline comments
- Visual Studio 2022 or later (or VS Code with C# extension)
- .NET Framework 4.7.2 SDK
- Mount & Blade II: Bannerlord (for game references)
- Git
-
Clone the repository
git clone https://github.com/haterade22/LOTRAOM.git cd LOTRAOM -
Set up environment variables
# Windows PowerShell ./setup-dev-env.ps1
This sets the
BANNERLORD_GAME_DIRenvironment variable required for build scripts. -
Build the project
# Windows PowerShell ./build.ps1 # Linux/WSL Bash ./build.sh
-
Run tests
dotnet test LOTRAOM.Tests/LOTRAOM.Tests.csproj -
Activate the pre-commit hook (once per clone)
git config core.hooksPath .githooks
.githooks/pre-commitbuilds, runs the tests and checks the coverage floor — for every committer, not only for the ones using Claude. It steps aside without gating when nothing is staged, when no.cs/.csproj/.sln/.props/.targets/.json/.xmlfile is staged, when the floor cannot be read, and when no PowerShell is onPATH— so a Linux/WSL setup that builds through./build.shmay never be gated at all. Git will not honour a hooks path from tracked content on its own — a repository that ran code on checkout would be a supply-chain hole — so every clone has to opt in with this one command.
We use a multi-tier branching strategy designed for collaborative development:
dev (main development branch)
├── feature/your-feature-name
├── bugfix/issue-description
└── ... (merge back to dev after testing)
↓
alpha (internal team testing)
↓
beta (community testing)
↓
public (stable releases)
dev: The main development branch. All feature and bugfix branches are created fromdev, and all pull requests merge back todev.feature/*: Feature branches for new functionalitybugfix/*: Bug fix branches for resolving issuesalpha: Internal testing by the development team (merged fromdevwhen ready)beta: Community testing with select testers (merged fromalphawhen stable)public: Stable public releases (merged frombetaafter validation)
-
Create a branch from
devgit checkout dev git pull origin dev git checkout -b feature/my-new-feature
-
Develop and test your changes
- Write tests first (TDD approach)
- Implement the feature
- Ensure all tests pass
- Build and verify in-game
-
Commit your changes
git add . git commit -m "Add: Description of your feature"
-
Push your branch
git push origin feature/my-new-feature
-
Create a Pull Request to
dev- Describe your changes
- Reference any related issues
- Request code review
-
After approval, merge to
dev- The team lead will merge to
alpha,beta, andpublicat appropriate times
- The team lead will merge to
# Build debug version (default)
./build.ps1
# Build release version
./build.ps1 -Configuration Release
# Build + tests + coverage floor (what the pre-commit hook runs)
./build.ps1 -RunTests -MinCoverage 26# Build debug version (default)
./build.sh
# Build release version
./build.sh ReleaseBuild scripts automatically copy DLLs to the appropriate module folders.
That 26 is a ratchet floor — raised as real coverage climbs, never lowered. It is defined once, in .claude/hooks/pre-commit-tests.sh, and .githooks/pre-commit reads it from there so the two gates cannot drift apart.
# Run all tests
dotnet test LOTRAOM.Tests/LOTRAOM.Tests.csproj
# Run tests with specific configuration
dotnet test LOTRAOM.Tests/LOTRAOM.Tests.csproj -c Debug
# Run tests with specific framework target
dotnet test LOTRAOM.Tests/LOTRAOM.Tests.csproj -f net472- Follow SOLID principles
- Use constructor injection for dependencies
- Write unit tests for new features (TDD)
- Document public APIs with XML comments
- Use meaningful variable and method names
- Follow existing code patterns and conventions
See CLAUDE.md for detailed coding guidelines and architecture patterns.
We welcome contributions from the community! Whether you're interested in:
- Adding new features
- Fixing bugs
- Improving documentation
- Optimizing performance
- Creating new LOTR content
- Join the team - Reach out on our Discord or open an issue expressing interest
- Create an issue - Required: Before starting work, create an issue to be tracked by the team. This prevents duplicate efforts and ensures coordination across the development team.
- Pick an issue - Check the Issues page for open tasks, or work on the issue you created
- Follow the workflow - Use the branching strategy outlined above
- Submit quality code - Follow our code quality standards and include tests
- Engage in code review - Be open to feedback and iterate on your changes
- Architecture Overview - Technical documentation
- Architecture Decision Records (ADR) - Key design decisions
- CLAUDE.md - Comprehensive developer guide
- Project Overview - Technical summary and architecture
- Branching Strategy - Detailed branching workflow
- Architecture Decision Records (ADR) - Design decisions and rationale
- CLAUDE.md - AI-assisted development guide with patterns and best practices
/Main/ # Core mod implementation
/Features/ # Feature modules (race bonuses, AI, combat, etc.)
/Services/ # Core services (hooks, pooling, combat)
/CampaignBehaviors/ # Campaign integration
/Models/ # Custom game models
/_Module/ # Module metadata and binaries
/ModuleData/ # XML game configuration
/GUI/ # UI definitions
/Assets/ # Textures and sprites
/LOTRAOM.Tests/ # Unit tests
/Decompiled/ # Decompiled v1.2.12 reference source (gitignored, generated)
/docs/ # Documentation
- Discord: Join our server
- Issues: Report bugs or request features
- Discussions: Join the conversation
- Releases: Download stable versions
This project uses split licensing to balance community access with protection of reusable infrastructure:
- Mod Content (Main/, ModuleData/, GUI/, Assets/) - MIT License
- Infrastructure & Tools (launcher/, devops/, web/) - Polyform Noncompete 1.0.0
- Documentation (docs/) - CC BY-SA 4.0
See LICENSE.md for complete licensing details, including what you can and cannot do with each component.
- TaleWorlds Entertainment for Mount & Blade II: Bannerlord
- The Bannerlord modding community
- LOTR Armory team for asset support
- Inspiration and contributions from:
- Alliance - Bannerlord modding innovations
- Shadows of the Past - LOTR mod development
- The Old Realms (TOR) - Fantasy total conversion techniques
- Realms of Thrones (ROT) - Campaign and faction systems
- A Dance of Dragons (ADOD) - Advanced gameplay mechanics
- Realms Forgotten (RF) - World-building and content design
- All contributors to this project
Note: This is a community mod and is not affiliated with or endorsed by TaleWorlds Entertainment, Middle-earth Enterprises, or any official Lord of the Rings license holders.