Co-authored-by: Claude (Opus 4.6) <claude@hermes.local> Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
101 lines
4.3 KiB
Markdown
101 lines
4.3 KiB
Markdown
# Issue #1097 — Bannerlord M5 Sovereign Victory: Implementation
|
||
|
||
**Date:** 2026-03-23
|
||
**Status:** Python stack implemented — game infrastructure pending
|
||
|
||
## Summary
|
||
|
||
Issue #1097 is the final milestone of Project Bannerlord (#1091): Timmy holds
|
||
the title of King with majority territory control through pure local strategy.
|
||
|
||
This PR implements the Python-side sovereign victory stack (`src/bannerlord/`).
|
||
The game-side infrastructure (Windows VM, GABS C# mod) remains external to this
|
||
repository, consistent with the scope decision on M4 (#1096).
|
||
|
||
## What was implemented
|
||
|
||
### `src/bannerlord/` package
|
||
|
||
| Module | Purpose |
|
||
|--------|---------|
|
||
| `models.py` | Pydantic data contracts — KingSubgoal, SubgoalMessage, TaskMessage, ResultMessage, StateUpdateMessage, reward functions, VictoryCondition |
|
||
| `gabs_client.py` | Async TCP JSON-RPC client for Bannerlord.GABS (port 4825), graceful degradation when game server is offline |
|
||
| `ledger.py` | SQLite-backed asset ledger — treasury, fiefs, vassal budgets, campaign tick log |
|
||
| `agents/king.py` | King agent — Qwen3:32b, 1× per campaign day, sovereign campaign loop, victory detection, subgoal broadcast |
|
||
| `agents/vassals.py` | War / Economy / Diplomacy vassals — Qwen3:14b, domain reward functions, primitive dispatch |
|
||
| `agents/companions.py` | Logistics / Caravan / Scout companions — event-driven, primitive execution against GABS |
|
||
|
||
### `tests/unit/test_bannerlord/` — 56 unit tests
|
||
|
||
- `test_models.py` — Pydantic validation, reward math, victory condition logic
|
||
- `test_gabs_client.py` — Connection lifecycle, RPC dispatch, error handling, graceful degradation
|
||
- `test_agents.py` — King campaign loop, vassal subgoal routing, companion primitive execution
|
||
|
||
All 56 tests pass.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
KingAgent (Qwen3:32b, 1×/day)
|
||
└── KingSubgoal → SubgoalQueue
|
||
├── WarVassal (Qwen3:14b, 4×/day)
|
||
│ └── TaskMessage → LogisticsCompanion
|
||
│ └── GABS: move_party, recruit_troops, upgrade_troops
|
||
├── EconomyVassal (Qwen3:14b, 4×/day)
|
||
│ └── TaskMessage → CaravanCompanion
|
||
│ └── GABS: assess_prices, buy_goods, establish_caravan
|
||
└── DiplomacyVassal (Qwen3:14b, 4×/day)
|
||
└── TaskMessage → ScoutCompanion
|
||
└── GABS: track_lord, assess_garrison, report_intel
|
||
```
|
||
|
||
## Subgoal vocabulary
|
||
|
||
| Token | Vassal | Meaning |
|
||
|-------|--------|---------|
|
||
| `EXPAND_TERRITORY` | War | Take or secure a fief |
|
||
| `RAID_ECONOMY` | War | Raid enemy villages for denars |
|
||
| `TRAIN` | War | Level troops via auto-resolve |
|
||
| `FORTIFY` | Economy | Upgrade or repair a settlement |
|
||
| `CONSOLIDATE` | Economy | Hold territory, no expansion |
|
||
| `TRADE` | Economy | Execute profitable trade route |
|
||
| `ALLY` | Diplomacy | Pursue non-aggression / alliance |
|
||
| `RECRUIT` | Logistics | Fill party to capacity |
|
||
| `HEAL` | Logistics | Rest party until wounds recovered |
|
||
| `SPY` | Scout | Gain information on target faction |
|
||
|
||
## Victory condition
|
||
|
||
```python
|
||
VictoryCondition(
|
||
holds_king_title=True, # player_title == "King" from GABS
|
||
territory_control_pct=55.0, # > 51% of Calradia fiefs
|
||
)
|
||
```
|
||
|
||
## Graceful degradation
|
||
|
||
When GABS is offline (game not running), `GABSClient` logs a warning and raises
|
||
`GABSUnavailable`. The King agent catches this and runs with an empty game state
|
||
(falls back to RECRUIT subgoal). No part of the dashboard crashes.
|
||
|
||
## Remaining prerequisites
|
||
|
||
Before M5 can run live:
|
||
|
||
1. **M1-M3** — Passive observer, basic campaign actions, full campaign strategy
|
||
(currently open; their Python stubs can build on this `src/bannerlord/` package)
|
||
2. **M4** — Formation Commander (#1096) — declined as out-of-scope; M5 works
|
||
around M4 by using Bannerlord's Tactics auto-resolve path
|
||
3. **Windows VM** — Mount & Blade II: Bannerlord + GABS mod (BUTR/Bannerlord.GABS)
|
||
4. **OBS streaming** — Cinematic Camera pipeline (Step 3 of M5) — external to repo
|
||
5. **BattleLink** — Alex co-op integration (Step 4 of M5) — requires dedicated server
|
||
|
||
## Design references
|
||
|
||
- Ahilan & Dayan (2019): Feudal Multi-Agent Hierarchies — manager/worker hierarchy
|
||
- Wang et al. (2023): Voyager — LLM lifelong learning pattern
|
||
- Feudal hierarchy design doc: `docs/research/bannerlord-feudal-hierarchy-design.md`
|
||
|
||
Fixes #1097
|