Skip to content

Commit 7aaf77e

Browse files
committed
Update documentation.
1 parent 94dadf3 commit 7aaf77e

1 file changed

Lines changed: 52 additions & 3 deletions

File tree

README.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This mod for [M&B2: Bannerlord](https://www.taleworlds.com/en/Games/Bannerlord)
44

55
## Prerequisites
66

7-
The mod is tested with Bannerlord e1.5.7 and e1.5.8 beta. Older versions of the game *may* work, but are considered unsupported.
7+
The mod is tested with Bannerlord e1.6.1 and e1.6.2 beta. Older versions of the game *may* work, but are considered unsupported.
88

99
There are no known compatibility issues with other Bannerlord mods.
1010

@@ -203,6 +203,23 @@ void Test() {
203203
```
204204
Note that this object is shared by *all* scripts, and is also accessible via `csx.eval`.
205205

206+
### Accessing non-public members
207+
208+
Both `csx.eval` expressions and scripts are compiled with visibility checks disabled; thus, internal, protected, and private members can be accessed as well as public ones. Since CLR performs additional visibility checks at runtime, any expression that needs to ignore visibility needs to be wrapped with `IgnoreVisibility()` to disable those runtime checks. For example:
209+
210+
```cs
211+
var rcb = Campaign.Current.CampaignBehaviorManager.GetBehavior<RebellionsCampaignBehavior>();
212+
IgnoreVisibility(() => rcb.StartRebellionEvent(settlement));
213+
```
214+
215+
`StartRebellionEvent` is a private member of RebellionsCampaignBehavior; thus, `IgnoreVisibility` is required here.
216+
217+
The lambda passed to `IgnoreVisibility` is an expression tree, and all [limitations](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#anonymous-function-conversions) apply. In particular, the lambda cannot perform assignments. To allow private fields to be changed within the lambda, one has to use the `Set()` method instead:
218+
219+
```cs
220+
IgnoreVisibility(() => Set(out ConversationManager._persuasion, new Persuasion(...)));
221+
```
222+
206223
### Execution environment
207224

208225
Both `csx.eval` and scripts are executed in a pre-populated environment. It includes assembly references for all assemblies loaded in the Bannerlord process, and implicit `using` statements for all available namespaces that begin with `TaleWorlds`, as well as the following:
@@ -255,15 +272,20 @@ The following lookup tables are provided:
255272

256273
- `Kingdoms` for `Kingdom.All`
257274
- `Clans` for `Clan.All`
258-
- `Heroes` for `Hero.All`
275+
- `Heroes` for `Hero.FindAll(_ => true)`
259276
- `Nobles` for `Heroes[hero => hero.IsNoble]`
260277
- `Wanderers` for `Heroes[hero => hero.IsWanderer]`
261-
- `Settlements` for `Settlement.All`
278+
- `Settlements` for `ObjectManager.GetObjectTypeList<Settlement>()`
262279
- `Fiefs` for `Town.AllFiefs`
263280
- `Towns` for `Town.AllTowns`
264281
- `Castles` for `Town.AllCastles`
265282
- `Villages` for `Village.All`
266283
- `Parties` for `MobileParty.All`
284+
- `ItemObjects` for `ObjectManager.GetObjectTypeList<ItemObject>()`
285+
- `Perks` for `ObjectManager.GetObjectTypeList<PerkObject>()`
286+
- `CharacterAttributes` for `ObjectManager.GetObjectTypeList<CharacterAttribute>()`
287+
- `Traits` for `ObjectManager.GetObjectTypeList<TraitObject>()`
288+
- `Skills` for `ObjectManager.GetObjectTypeList<SkillObject>()`
267289
- `MyFiefs` for `MyClan.Fiefs`
268290
- `MyTowns` for `MyFiefs[fief => fief.IsTown]`
269291
- `MyCastles` for `MyFiefs[fief => fief.IsCastle]`
@@ -279,9 +301,11 @@ In addition to the usual C# implicit conversions, the mod also provides implicit
279301
- `Kingdom`
280302
- `Clan`
281303
- `Hero`
304+
- `Settlement`
282305
- `Town`
283306
- `Village`
284307
- `MobileParty`
308+
- `ItemObject`
285309

286310
When invoking a script with arguments of those types, instead of passing an object, a string or `Id()` can be used; the object is then automatically looked up in the corresponding lookup table. For example:
287311
```cs
@@ -356,10 +380,35 @@ The mod comes with a stock `CampaignBehavior.csx` that already has the above sni
356380

357381
**WARNING**: messing around with `CampaignBehavior.SyncData()` can easily render your saves unusable! It is intentionally undocumented; if you don't already know what it is for, and how to *safely* use `IDataStore`, it's best to leave it alone.
358382

383+
### `SubModule`
384+
385+
If there's a script named `SubModule`, it may define a method called `OnGameStart`:
386+
387+
```cs
388+
void OnGameStart(Game game, IGameStarter gameStarterObject) => ...
389+
```
390+
391+
If present, it will be invoked from the corresponding method of the C# Scripting module. This allows registering custom campaign behaviors, e.g.:
392+
393+
```cs
394+
// SubModule.csx
395+
396+
class ClanTierModel : DefaultClanTierModel {
397+
public override int GetCompanionLimit(Clan clan) => 1000;
398+
399+
public override int GetPartyLimitForTier(Clan clan, int clanTierToCheck) => 100;
400+
}
401+
402+
void OnGameStart(Game game, IGameStarter gameStarterObject) {
403+
gameStarterObject.AddModel(new ClanTierModel());
404+
}
405+
```
406+
359407
## Editing scripts
360408

361409
The mod automatically generates omnisharp.json in the user scripts folder, which enables Intellisense in [Visual Studio Code](https://code.visualstudio.com/) (or any other editor or IDE that uses [OmniSharp](http://www.omnisharp.net/)). To use it, simply do File ⇒ Open Folder in VSCode to open the folder, and then open individual .csx files from the Explorer pane.
362410
411+
Note that OmniSharp is not aware of custom visibility settings for scripts. Thus, accessing non-public members will cause error squiggles while editing, even though the code will execute correctly at runtime.
363412
## Debugging scripts
364413

365414
Scripts are compiled with full debug information. If Visual Studio is [attached](https://docs.microsoft.com/en-us/visualstudio/debugger/attach-to-running-processes-with-the-visual-studio-debugger) to the Bannerlord process, it is possible to set breakpoints, break on exceptions, and use all other debugging facilities.

0 commit comments

Comments
 (0)