XML改変
XML の改変による MOD 制作を解説していきます。この方法ではプログラミングの知識はほとんど必要ありません。XML で記述するため、テキストエディターがあると作業しやすいですが、メモ帳でもできなくはないです。
基礎知識編
XML について、最低限必要な知識を書いておきます。知っている方は読み飛ばしてもらって構いません。
XMLとは何ぞや
XML文書は、要素 (element) と属性 (attribute) が複数集まって、構成されている。 要素は内部に子要素を含むことができる。属性は要素に付随し、属性の内部に子要素を含むことはできない。要素は開始タグと終了タグで内容を挟むことで表現する。 開始タグは「<要素名>」、終了タグは「</要素名>」で記述する。
一つの要素を記述するための基本的な構文を次に示す。
ここで、<要素名 属性="値"> をこの要素の開始タグといい、</要素名> を終了タグという。「内容」は何らかのテキストである。
簡単に言うと、テキストデータにタグ付けして分類することで、コンピューターが認識しやすいようにしたものです。
XMLの構造
<親要素>
<子要素1 />
<子要素2>
<孫要素 />
</子要素2>
</親要素>
<!-- この部分はコメント -->
要素は別の要素を内容として持つことができます (入れ子構造)上の例で言えば、「親要素」は2つの子要素を持ち、そのうちの「子要素2」だけがさらなる子要素 (=「孫要素」) を持っているという形になります
親子関係は通常、スペースかタブによって字下げを行い、見やすくします
子要素を持たない場合、<子要素1 /> のような終了タグを省略した表記ができます
<!-- と --> との間はコメント行で、XML の一部としては扱われない部分です
制作準備編
前置きはこのくらいにして、いよいよ制作開始です。最初に MOD の保存場所を作成します。
まずは自分の MOD の名前を決めましょう。例では CustomItems という MOD を作っているものとします。別の名前にする場合は、以下、CustomItems となっている部分をそちらに読み替えてください。
1.
[Bannerlord インストールフォルダー]\Modules
の中に CustomItems フォルダー を作成します。
2.
以下の内容をテキストエディターにコピペし、SubModule.xml という名前で CustomItems フォルダーの中に 保存します。このファイル名は固定で、他のものにはできません。
保存の際、文字コードは UTF-8 にしてください。方法は使用しているテキストエディターによって異なりますが、通常は「名前を付けて保存」などにオプションがあるはずです。
<Module>
<Name value ="Custom Items" />
<Id value ="CustomItems" />
<Version value ="v1.0.0" />
<SingleplayerModule value ="true" />
<MultiplayerModule value ="false" />
<DependedModules>
<DependedModule Id ="Native" />
<DependedModule Id ="SandBoxCore" />
<DependedModule Id ="Sandbox" />
<DependedModule Id ="CustomBattle" />
<DependedModule Id ="StoryMode" />
</DependedModules>
<SubModules />
<Xmls />
</Module>
Name value
Bannerlord のランチャーなどに表示される、MOD の正式名称です。自由に設定できます。
Id value
プログラム内での MOD の名称です。自由に設定できます。
Version value
MOD のバージョンです。自由に番号を付けられます。
3.
CustomItems フォルダーの中に ModuleData フォルダー を作成します。
4.
最終的な構造は以下のようになります。
📁Bannerlord インストールフォルダー📁Modules📁CustomItems📁ModuleData
📄SubModule.xml
これで MOD フォルダーの準備ができました。
初級編
クラフト武器の性能を変える
Bannerlord の
アイテム には2種類あります。
単一のパーツ で作られているもの (弓や防具など)
複数のパーツを組み合わせて作られているもの (クラフティング可能なもの)
まずは、
クラフト 武器である片手剣の Backsword を改造してみましょう。
改造箇所を見つける
エディターで
[Bannerlord インストールフォルダー]\Modules\SandBoxCore\ModuleData\spitems\weapons.xml
を開いてください。
「backsword」というワードで weapons.xml 内を検索すると
<CraftedItem id ="sturgia_sword_2_t3"
name ="{=FQHaFsyQ}Backsword"
crafting_template ="OneHandedSword"
culture ="Culture.sturgia" >
<Pieces>
<Piece id ="sturgian_blade_5"
Type ="Blade"
scale_factor ="100" />
<Piece id ="sturgian_guard_2"
Type ="Guard"
scale_factor ="100" />
<Piece id ="sturgian_grip_4"
Type ="Handle"
scale_factor ="100" />
<Piece id ="sturgian_pommel_3"
Type ="Pommel"
scale_factor ="100" />
</Pieces>
</CraftedItem>
という部分が見つかるはずです。(細かい値はバージョンごとに差異があるかも)
このように、ゲーム内のクラフティング可能な武器は、全て Piece (パーツ) の組み合わせによって生成されています。
ですから、クラフト武器の性能を変えるには、パーツの性能から変えなければなりません。
それでは次に、エディターで
[Bannerlord インストールフォルダー]\Modules\Native\ModuleData\crafting_pieces.xml
を開いてください。公式の武器パーツのデータはこのファイルに記述されています。
武器性能の大部分は Blade (刃) によって決まります。
先ほど見つけた Backsword のパーツのうち、刃の ID は「sturgian_blade_5」でした。
このワードで crafting_pieces.xml 内を検索すると
<CraftingPiece id ="sturgian_blade_5"
name ="{=bGfs8gNv}Northern Backsword Blade"
tier ="3"
piece_type ="Blade"
mesh ="sturgian_blade_5"
culture ="Culture.sturgia"
length ="68.2"
weight ="0.7" >
<PieceUsages unavailable_usages ="" />
<BladeData stack_amount ="3"
physics_material ="metal_weapon"
body_name ="bo_sword_one_handed"
holster_mesh ="sturgian_blade_5_scabbard_5" >
<Thrust damage_type ="Pierce"
damage_factor ="2.7" />
<Swing damage_type ="Cut"
damage_factor ="3.6" />
</BladeData>
<Flags>
<Flag name ="Civilian"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="2" />
</Materials>
</CraftingPiece>
という部分が見つかります。
ここが、今回改造するところです。
MODファイルの作成
改造箇所を見つけたら、その部分を新規テキストにコピペします。その際、必ずコピー元の構造を踏襲するようにしてください。
つまり、
元ファイルの先頭行に version や encoding の記述があれば、それもコピペする
<CraftingPiece> の親要素である <CraftingPieces> も追加して、階層を維持する
ということです。
+
プログラミング的なお話
XML 読み込みの一部に、XML 宣言のノードが存在することを前提とした、定数のインデックスでコレクションにアクセスしている部分があり、構造が違うと即座にクラッシュしてしまいます。
エディター上では以下の状態になります。
<?xml version ="1.0" encoding ="utf-8" ?>
<CraftingPieces>
<CraftingPiece id ="sturgian_blade_5"
name ="{=bGfs8gNv}Northern Backsword Blade"
tier ="3"
piece_type ="Blade"
mesh ="sturgian_blade_5"
culture ="Culture.sturgia"
length ="68.2"
weight ="0.7" >
<PieceUsages unavailable_usages ="" />
<BladeData stack_amount ="3"
physics_material ="metal_weapon"
body_name ="bo_sword_one_handed"
holster_mesh ="sturgian_blade_5_scabbard_5" >
<Thrust damage_type ="Pierce"
damage_factor ="2.7" />
<Swing damage_type ="Cut"
damage_factor ="3.6" />
</BladeData>
<Flags>
<Flag name ="Civilian"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="2" />
</Materials>
</CraftingPiece>
</CraftingPieces>
これに適当なファイル名を付けて
[Bannerlord インストールフォルダー]\Modules\CustomItems\ModuleData
の中に保存しましょう。例では custom_crafting_pieces.xml という名前にしたものとします。
データをいじる
MOD ファイルができたので、今度はその内容を変えていきます。
Bannerlord は割と物理法則を意識して作られているようで、基本的には、長く重い武器ほど、高威力・低速度になるようになっています。
ですから、<CraftingPiece> の length や weight を増やすと、威力は高くなりますが、遅い武器になってしまうでしょう。
一応、length には当たり判定が伸びるという効果もありますが、刃のグラフィックまで自動で伸ばしてくれるようなことはなく、刃が柄から浮いた状態になってしまうため、基本的に length は変えないほうがいいです。
武器の使用感を変えずにダメージだけを変えたいのであれば、<Thrust> や <Swing> にある damage_factor 属性を変えるといいでしょう。
こちらは、そういった物理法則とは関係のないダメージ倍率ですから、<Swing> の damage_factor を上げて、weight を下げれば、高威力ながらも速く振れる武器になります。<Thrust> の方は突き攻撃です。
例では、<Thrust> と <Swing> の damage_factor を2倍に、weight を半分にしてみます。
<Flags> は各種のフラグです。例では、盾に対するボーナスダメージを付けます。
<Material> はクラフティングにかかるコストです。id が素材、count が消費個数です。
指定可能な ID は以下の通りです。
ID
アイテム名
IronOre
Iron Ore
Iron1
Crude Iron
Iron2
Wrought Iron
Iron3
Iron
Iron4
Steel
Iron5
Fine Steel
Iron6
Thamaskene Steel
Wood
Wood
Charcoal
Charcoal
各要素の属性の意味を知りたい場合は
こちら を参照してください。
+
custom_crafting_pieces.xml の最終形
<?xml version ="1.0" encoding ="utf-8" ?>
<CraftingPieces>
<!-- weight を変更 -->
<CraftingPiece id ="sturgian_blade_5"
name ="{=bGfs8gNv}Northern Backsword Blade"
tier ="3"
piece_type ="Blade"
mesh ="sturgian_blade_5"
culture ="Culture.sturgia"
length ="68.2"
weight ="0.35" >
<PieceUsages unavailable_usages ="" />
<BladeData stack_amount ="3"
physics_material ="metal_weapon"
body_name ="bo_sword_one_handed"
holster_mesh ="sturgian_blade_5_scabbard_5" >
<!-- damage_factor を変更 -->
<Thrust damage_type ="Pierce"
damage_factor ="5.4" />
<!-- damage_factor を変更 -->
<Swing damage_type ="Cut"
damage_factor ="7.2" />
</BladeData>
<!-- BonusAgainstShield を追加 -->
<Flags>
<Flag name ="BonusAgainstShield"
type ="WeaponFlags" />
<Flag name ="Civilian"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="2" />
</Materials>
</CraftingPiece>
</CraftingPieces>
MODを設定する
最後に、MOD ファイルをゲームに認識させるための記述を行う必要があります。
制作準備編で作っておいた SubModule.xml を開き、以下のように書き換えてください。
<Module>
<Name value ="Custom Items" />
<Id value ="CustomItems" />
<Version value ="v1.0.0" />
<SingleplayerModule value ="true" />
<MultiplayerModule value ="false" />
<DependedModules>
<DependedModule Id ="Native" />
<DependedModule Id ="SandBoxCore" />
<DependedModule Id ="Sandbox" />
<DependedModule Id ="CustomBattle" />
<DependedModule Id ="StoryMode" />
</DependedModules>
<SubModules />
<Xmls>
<XmlNode>
<XmlName id ="CraftingPieces" path ="custom_crafting_pieces" />
<IncludedGameTypes>
<GameType value ="Campaign" />
<GameType value ="CampaignStoryMode" />
<GameType value ="CustomGame" />
<GameType value ="EditorGame" />
</IncludedGameTypes>
</XmlNode>
</Xmls>
</Module>
元々は <Xmls /> のみだった部分に記述が増えています。どのファイル (path) によって、何のデータ (id) を書き換えるのかを指定しています。
XmlName id
この ID は上書きする元ファイル の ID と同じでなければなりません。元ファイルが所属するモジュール の ModuleData フォルダーにある SubModule.xml を開き、元ファイルを読み込んでいる部分の <XmlNode> ごとコピペしてきて、path だけ変えれば OK です。
XmlName path
MOD ファイルの場所です。ModuleData フォルダーを基点にしたパスで指定します。拡張子は必要ありません。
結果
MOD マネージャーに Custom Items が追加されています。
ここでリストに自分の MOD 名が無いようなら、SubModule.xml の内容か保存場所が間違っています。制作準備編などを再確認してください。
ゲーム内で実際に Backsword を見てみると……
MOD 適用前
MOD 適用後
威力をはじめ、ほとんど全てが変化しています。価格やティアまで変化しているのは、これらの値が武器の総合性能から自動算出されているためです。
なお、この手法による改変はセーブデータを汚さないので、MOD 適用中にセーブしたデータを MOD を外してロードしたとしても、ちゃんと元の性能に戻ります。
非クラフトアイテムの性能を変える
今度は、非クラフト武器である Arbalest を改造してみましょう。
クラフト武器では、<CraftingPiece> 要素を抜き出して MOD ファイルにしてしまえば既存のパーツが上書きされていましたが、非クラフトアイテムである <Item> 要素は、同じ方法では既存アイテムの上書きができません。
(少なくとも、筆者が実験した限りではできませんでした。元ファイルの書き換え以外で何か方法をご存知の方がいらっしゃれば、情報提供あるいは加筆していただけるとありがたいです。)
そんな訳で、非クラフトアイテムの改造には「既存アイテムを流用し、新しいアイテムとして定義する」という別の手法が必要となります。
MODファイルの作成
[Bannerlord インストールフォルダー]\Modules\SandBoxCore\ModuleData\spitems\weapons.xml
を開き、「arbalest」で検索すると、以下の部分が見つかります。
<Item id ="crossbow_c"
name ="{=0e17RZrZ}Arbalest"
body_name ="bo_cross_bow_heavy"
mesh ="crossbow_c"
culture ="Culture.vlandia"
weight ="3.0"
appearance ="0.4"
difficulty ="20"
Type ="Crossbow"
AmmoOffset ="0.0, 0.02131, 0.24675"
item_holsters ="crossbow_back:bow_hip:mace_right_hip:bow_hip_2"
holster_position_shift ="0.02,0,-0.4" >
<ItemComponent>
<Weapon weapon_class ="Crossbow"
ammo_class ="Bolt"
missile_speed ="87"
accuracy ="98"
thrust_damage ="89"
thrust_speed ="78"
speed_rating ="60"
weapon_length ="95"
ammo_limit ="1"
thrust_damage_type ="Pierce"
item_usage ="crossbow"
physics_material ="wood_weapon"
center_of_mass ="0,0,0.4"
item_modifier_group ="crossbow" >
<WeaponFlags RangedWeapon ="true"
HasString ="true"
CantReloadOnHorseback ="true"
NotUsableWithOneHand ="true"
TwoHandIdleOnMount ="true" />
</Weapon>
</ItemComponent>
</Item>
クラフト武器のときは <CraftedItem> として <Piece> をまとめているだけだったのが、<Item> に変わり、中でいろいろ設定されています。
<Item> はアイテムとしての基本情報です。
<ItemComponent> では、内部に <Armor>、<Weapon>、<Horse>、<Trade> のいずれかを持つことで、そのアイテムの性質を定義しています。
見つけた Arbalest の定義を新規テキストにコピペしましょう。例によって <Item> の親要素である <Items> を付け足すのも忘れずに 。
これに適当なファイル名を付け、最初の例と同じく
[Bannerlord インストールフォルダー]\Modules\CustomItems\ModuleData
の中に保存します。例では custom_items.xml という名前にしたものとします。
データをいじる
最初に書いたとおり、非クラフトアイテムを改造するには「新しいアイテムとして定義する」ことが必要です。
それは別に難しいことではなく、単に新しい ID を与えるだけです。
「id="crossbow_c"」となっている部分を、「id="CustomItems_crossbow_c"」とでもしてやりましょう。
こんな風に、自分の MOD で使う ID では MOD 名を接頭辞とするようにしておくと、他の MOD と ID が競合しにくくなります。
リロードをいちいち挟まずに連射できるようにするには、<Weapon> の ammo_limit を設定します。
これは、銃でいうところの装弾数ですね。デフォルト値は 1 なので、撃つ → リロード → 撃つ → リロード…… という挙動になっています。
連弩は10本ほど撃てたそうなので、値を 10 にしてみます。そうすれば、撃つ×10 → リロード → 撃つ×10 → リロード…… になるはずです。
<Weapon> の各属性の意味については
こちら を参照してください。
フラグを変更して馬上でも使えるようにしておきます。フラグの設定方法が <CraftingPiece> の時とは若干異なることに注意してください。
<WeaponFlags> の属性は、一見ブール値 を取るように見えますが、実は、属性の有無だけでフラグを判別していて値は参照されておらず、CantReloadOnHorseback="false" としても、フラグを消したことにはなりません。フラグを消すには、属性そのものを消す必要があります。
<WeaponFlgs> で使用可能なフラグは
こちら を参照してください。
他にも多少いじって、最終的には以下のようになりました。
+
custom_items.xml の最終形
<?xml version ="1.0" encoding ="utf-8" ?>
<Items>
<!-- id, name, difficulty を変更 -->
<Item id ="CustomItems_crossbow_c"
name ="{=!}Chu-ko-nu"
body_name ="bo_cross_bow_heavy"
mesh ="crossbow_c"
culture ="Culture.vlandia"
weight ="3.0"
appearance ="0.4"
difficulty ="0"
Type ="Crossbow"
AmmoOffset ="0.0, 0.02131, 0.24675"
item_holsters ="crossbow_back:bow_hip:mace_right_hip:bow_hip_2"
holster_position_shift ="0.02,0,-0.4" >
<ItemComponent>
<!-- thrust_speed と ammo_limit を変更 -->
<Weapon weapon_class ="Crossbow"
ammo_class ="Bolt"
missile_speed ="87"
accuracy ="98"
thrust_damage ="89"
thrust_speed ="200"
speed_rating ="60"
weapon_length ="95"
ammo_limit ="10"
thrust_damage_type ="Pierce"
item_usage ="crossbow"
physics_material ="wood_weapon"
center_of_mass ="0,0,0.4"
item_modifier_group ="crossbow" >
<!-- CantReloadOnHorseback を削除 -->
<WeaponFlags RangedWeapon ="true"
HasString ="true"
NotUsableWithOneHand ="true"
TwoHandIdleOnMount ="true" />
</Weapon>
</ItemComponent>
</Item>
</Items>
MODを設定する
MOD ファイルができたら、クラフト武器のときと同じように SubModule.xml でファイルをゲームに認識させましょう。
MOD のベースとなっているファイルは SandBoxCore\ModuleData\spitems\weapons.xml でしたから、SandBoxCore\SubModule.xml 内を「weapons」で検索すると……
あれ? 見つからない。……と思いきや、どうも spitems というフォルダー名で一括読み込みさせているみたいですね。
改変対象の ID は "Items" であることが判明しましたので、CustomItems の SubModule.xml は以下のようになります。
<Module>
<Name value ="Custom Items" />
<Id value ="CustomItems" />
<Version value ="v1.0.0" />
<SingleplayerModule value ="true" />
<MultiplayerModule value ="false" />
<DependedModules>
<DependedModule Id ="Native" />
<DependedModule Id ="SandBoxCore" />
<DependedModule Id ="Sandbox" />
<DependedModule Id ="CustomBattle" />
<DependedModule Id ="StoryMode" />
</DependedModules>
<SubModules />
<Xmls>
<XmlNode>
<XmlName id ="CraftingPieces" path ="custom_crafting_pieces" />
<IncludedGameTypes>
<GameType value ="Campaign" />
<GameType value ="CampaignStoryMode" />
<GameType value ="CustomGame" />
<GameType value ="EditorGame" />
</IncludedGameTypes>
</XmlNode>
</Xmls>
<Xmls>
<XmlNode>
<XmlName id ="Items" path ="custom_items" />
<IncludedGameTypes>
<GameType value ="Campaign" />
<GameType value ="CampaignStoryMode" />
<GameType value ="CustomGame" />
<GameType value ="EditorGame" />
</IncludedGameTypes>
</XmlNode>
</Xmls>
</Module>
結果
クラフト武器ではパーツデータが上書きされていたので、Backsword を所持していればそのまま変化が確認できましたが、新しいアイテムとして定義したものは、何とかしてアイテム自体を入手しないとなりません。
アイテムが自然生成されるのを待つなんてことはやってられませんので、手っ取り早く
チート を使いましょう。
方法は
当該ページ を見てもらうとして、チートを有効化した状態で
マップ 上でインベントリーを開くと、「Chu-ko-nu」というアイテムが見つかるはずです。
使用してみると、ちゃんと連射できます。初弾以外はレティクルが消えてしまうのと、セミオートでしか撃てないのがちょっと残念ですが。
ちなみに、この方法で改造したアイテムを入手するとセーブデータに記録される訳ですが、その状態から MOD を抜いたとしても、アイテムが Trash Item (ゴミアイテム) に化けるだけで、セーブデータが使えなくなるといったような甚大な被害はありません。
中級編
初級編では、既存パーツの性能を上書きする形でクラフト武器を改造していました。
しかしその方法だと、微調整レベルの MOD ならばまだしも、大幅に性能を変えている場合、改造武器を使っているユニットがそれなりの強化/弱体化をされることになってしまいます。
これを避け、プレイヤーだけが使えるアイテムにするためには、非クラフト武器のときと同じように「新しいアイテムとして定義する」手法をとります。
既存のパーツを流用してプレイヤー専用の新規パーツを作る
パーツを定義する
初級編で作った Backsword の MOD を変えていきます。
+
custom_crafting_pieces.xml
<?xml version ="1.0" encoding ="utf-8" ?>
<CraftingPieces>
<!-- id と weight を変更 -->
<CraftingPiece id ="CustomItems_sturgian_blade_5"
name ="{=bGfs8gNv}Northern Backsword Blade"
tier ="3"
piece_type ="Blade"
mesh ="sturgian_blade_5"
culture ="Culture.sturgia"
length ="68.2"
weight ="0.35" >
<PieceUsages unavailable_usages ="" />
<BladeData stack_amount ="3"
physics_material ="metal_weapon"
body_name ="bo_sword_one_handed"
holster_mesh ="sturgian_blade_5_scabbard_5" >
<!-- damage_factor を変更 -->
<Thrust damage_type ="Pierce"
damage_factor ="5.4" />
<!-- damage_factor を変更 -->
<Swing damage_type ="Cut"
damage_factor ="7.2" />
</BladeData>
<!-- BonusAgainstShield を追加 -->
<Flags>
<Flag name ="BonusAgainstShield"
type ="WeaponFlags" />
<Flag name ="Civilian"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="2" />
</Materials>
</CraftingPiece>
</CraftingPieces>
と言っても、ID を変えただけです。
ただ、これだけでは、この新しく定義したパーツはどこからも参照されていません。
既存の Backsword が既存のパーツから構成されているように、自分専用の Backsword は、新しく定義したパーツで構成されるように定義してやらなければなりません。
改造パーツを武器の部品とする
[Bannerlord インストールフォルダー]\Modules\SandBoxCore\ModuleData\spitems\weapons.xml
を開き、Backsword の <CraftedItem> 以下の要素をコピーして custom_items.xml に貼り付けます。
すでに連弩の定義があるので、その下にでも貼り付けてください。
+
custom_items.xml
<?xml version ="1.0" encoding ="utf-8" ?>
<Items>
<Item>
<!--
ここには連弩の定義
-->
</Item>
<!-- ID を変更 -->
<CraftedItem id ="CustomItems_sturgia_sword_2_t3"
name ="{=FQHaFsyQ}Backsword"
crafting_template ="OneHandedSword"
culture ="Culture.sturgia" >
<Pieces>
<!-- custom_crafting_pieces.xml で定義したパーツを使う -->
<Piece id ="CustomItems_sturgian_blade_5"
Type ="Blade"
scale_factor ="100" />
<Piece id ="sturgian_guard_2"
Type ="Guard"
scale_factor ="100" />
<Piece id ="sturgian_grip_4"
Type ="Handle"
scale_factor ="100" />
<Piece id ="sturgian_pommel_3"
Type ="Pommel"
scale_factor ="100" />
</Pieces>
</CraftedItem>
</Items>
<CraftedItem> には新しい ID を与え、刃の <Piece> として自分で定義したパーツが設定してあります。
クラフティング・テンプレートを設定する
パーツは定義したし、それを部品に設定もしたし、とうとう完成か? と行きたいところですが、あと一つだけやることがあります。
<CraftedItem> の crafting_template 属性の設定です。これを適切に行わないと、クラフティングシステムに改造パーツを組み込んだことにならないため、クラフト武器が生成されません。
通常、鍛冶場で武器を作る際には、片手剣や両手斧などのカテゴリーを選んでからパーツを選ぶという流れになっていますが、この「カテゴリー」に相当するのがクラフティング・テンプレートです。
テンプレートは
[Bannerlord インストールフォルダー]\Modules\Native\ModuleData\crafting_templates.xml
で定義されています。
ファイルを見てみると、各カテゴリーでどのパーツを使えるのかや、最大性能などがズラズラと書かれています。
クラフティング・テンプレートにパーツを組み込むには、
既存テンプレートを改変して、パーツを追加する
自作武器専用のテンプレートを新たに作る
の2パターンが可能です。
前者は、改造パーツを他の既存パーツと自由に組み合わせてクラフティングできるようにする場合、後者は、改造パーツを自分の決めた組み合わせのみでクラフティングさせたい場合に採用するといいでしょう。
今回は、既存テンプレートの改変パターンで作っていくことにします。
Backsword は片手剣なので、OneHandedSword テンプレートに改造パーツを追加してやりましょう。
+
custom_crafting_templates.xml
<?xml version ="1.0" encoding ="utf-8" ?>
<!-- WeaponUsageData order is fixed, don't change it. -->
<CraftingTemplates>
<CraftingTemplate id ="OneHandedSword"
item_modifier_group ="sword"
item_holsters ="sword_left_hip_3:sword_left_hip:sword_left_hip_2:sword_back"
piece_type_to_scale_holster_with ="Blade"
hidden_piece_types_on_holster ="Blade"
default_item_holster_position_offset ="0,0,-0.1" >
<PieceDatas>
<!-- 長いので省略 -->
</PieceDatas>
<WeaponUsageDatas>
<WeaponUsageData id ="OneHandedSword" />
</WeaponUsageDatas>
<StatsData>
<!-- 長いので省略 -->
</StatsData>
<UsablePieces>
<!-- パーツを追加 -->
<UsablePiece piece_id ="CustomItems_sturgian_blade_5" />
<UsablePiece piece_id ="empire_blade_1" />
<UsablePiece piece_id ="empire_noble_blade_1" />
<!-- 長いので省略 -->
</UsablePieces>
</CraftingTemplate>
</CraftingTemplates>
<!--
<StatsData>
<StatData stat_type="Weight" max_value="7.0" />
<StatData stat_type="WeaponReach" max_value="300" />
<StatData stat_type="ThrustSpeed" max_value="200" />
<StatData stat_type="SwingSpeed" max_value="200" />
<StatData stat_type="ThrustDamage" max_value="500" />
<StatData stat_type="SwingDamage" max_value="500" />
<StatData stat_type="Handling" max_value="200" />
<StatData stat_type="FollowUp" max_value="200" />
<StatData stat_type="MissileDamage" max_value="500" />
<StatData stat_type="MissileSpeed" max_value="200" />
<StatData stat_type="Accuracy" max_value="100" />
</StatsData>
-->
MOD ファイルを作成するいつもの手順で、OneHandedSword の <CraftingTemplate> を抜き出し (親要素を忘れずに)、パーツを追加します。
このファイルの名前は custom_crafting_templates.xml とでもしておきましょう。
また新しい MOD ファイルができた訳ですから、例によって SubModule.xml にも記述します。
結果
チートインベントリーを開いてみると、Backsword が2つに増えており、既存武器と MOD 武器が別個のアイテムとしてゲーム内に存在していることがわかります。
鍛冶場では、片手剣のカテゴリーに改造パーツが追加されています。
既存の片手剣カテゴリーに追加したということは、この刃は Backsword としてだけでなく、他の片手剣用パーツと自由に組み合わせてクラフティングできるようになったことを意味します。
独自の組み合わせの武器を作る
5ch の MOD スレで「斧の Blade を Guard として使い、ハルバードを作りたい」という書き込みを見かけました。
このアイデアを拝借して、通常ではあり得ないパーツの組み合わせでの武器作成について説明していきます。
使用するパーツを決める
鍛冶場か、Modding Kit の Resource Browser (Crafting) で、使いたい形状のパーツを見繕います。
この際、Blade の部位には Blade として使われているパーツを選ばなくてはならない、という制約はありません。今はあくまで形状 (メッシュ) を選んでいるだけです。
今回は、ハルバードを例にするということで、槍の穂のパーツ、斧のパーツ、長柄の Handle、適当な Pommel で構成されることとなるでしょう。
選んだパーツの名前 (またはメッシュ ID) はどこかにメモしておきます。
例では、穂に Menavlion Head、斧に Spiked Battle Axe Blade を選びました。
パーツの改造
パーツを選んだら、その中で改造が必要なのかはどれかを考えます。
ハルバードは振る+突くの武器なので、<Thrust> と <Swing> 両方を持っている穂を選んであれば改造は必要ありませんが、そうでない場合は改造が必要です。
斧は、元々 Blade だったのを Guard に転用する訳ですから改造が絶対に必要です。
柄と石突は、まあ改造は要らないでしょう。
改造が必要なパーツの <CraftingPiece> 以下の要素をコピペします。
+
custom_crafting_pieces.xml
<?xml version ="1.0" encoding ="utf-8" ?>
<CraftingPieces>
<CraftingPiece>
<!--
ここには Backsword Blade の定義
-->
</CraftingPiece>
<!-- id と name を変更
is_default を追加 -->
<CraftingPiece id ="CustomItems_spear_blade_7"
name ="{=!}Halberd Spearhead"
tier ="4"
piece_type ="Blade"
mesh ="spear_blade_7"
length ="52.924"
weight ="0.3656"
is_default ="true" >
<PieceUsages unavailable_usages ="TwoHandedPolearm_Bracing" />
<BladeData stack_amount ="3"
physics_material ="wood_weapon"
body_name ="bo_spear_b" >
<Thrust damage_type ="Pierce"
damage_factor ="2.8" />
<Swing damage_type ="Cut"
damage_factor ="3.5" />
</BladeData>
<Materials>
<Material id ="Iron4"
count ="1" />
</Materials>
</CraftingPiece>
<!-- id, name, piece_type を変更
is_default を追加 -->
<CraftingPiece id ="CustomItems_axe_craft_25_head"
name ="{=!}Halberd Axe Blade"
tier ="4"
piece_type ="Guard"
mesh ="axe_craft_25_head"
distance_to_next_piece ="13.9"
distance_to_previous_piece ="4"
weight ="0.8"
is_default ="true" >
<PieceUsages unavailable_usages ="" />
<BuildData piece_offset ="-8" />
<!-- BladeData を削除 -->
<Flags>
<Flag name ="CanBePickedUpFromCorpse"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="3" />
</Materials>
</CraftingPiece>
</CraftingPieces>
改造パーツには新しい ID と名前が与えてあります。
斧は piece_type を Guard に変更し、刃ではなくなったことで不要になる <BladeData> を削除しました。
それと、テストの際に面倒なので、どちらにも is_default (パーツのアンロック不要) 属性を追加しました。
クラフティング・テンプレートの作成
クラフティング・テンプレートのことを考えた場合、既存の長柄武器カテゴリーに斧ガードを追加してしまうと、槍の穂だけでなく、例えばピッチフォークの先端などとも組み合わせられるようになってしまうので、ちょっとおかしいですよね。
そういった場合には、自作武器専用のカテゴリーを作るのがいいでしょう。
ハルバードは長柄武器なので、長柄武器テンプレートである TwoHandedPolearm をベースにして MOD を作成します。
+
custom_crafting_templates.xml
<?xml version ="1.0" encoding ="utf-8" ?>
<!-- WeaponUsageData order is fixed, don't change it. -->
<CraftingTemplates>
<CraftingTemplate>
<!--
ここには Backsword 用テンプレートの定義
-->
</CraftingTemplate>
<!-- ID を変更 -->
<CraftingTemplate id ="CustomItems_HalberdTemplate"
item_modifier_group ="polearm"
item_holsters ="polearm_back:polearm_back_2:polearm_back_3:polearm_back_4"
default_item_holster_position_offset ="0,0,-0.30"
use_weapon_as_holster_mesh ="true" >
<PieceDatas>
<!-- 長いので省略 -->
</PieceDatas>
<WeaponUsageDatas>
<!-- 長いので省略 -->
</WeaponUsageDatas>
<StatsData>
<!-- 長いので省略 -->
</StatsData>
<!-- 使用可能パーツを変更 -->
<UsablePieces>
<UsablePiece piece_id ="CustomItems_spear_blade_7" />
<UsablePiece piece_id ="CustomItems_axe_craft_25_head" />
<UsablePiece piece_id ="spear_handle_1" />
<UsablePiece piece_id ="default_polearm_pommel" />
</UsablePieces>
</CraftingTemplate>
</CraftingTemplates>
<!--
<StatsData>
<StatData stat_type="Weight" max_value="7.0" />
<StatData stat_type="WeaponReach" max_value="300" />
<StatData stat_type="ThrustSpeed" max_value="200" />
<StatData stat_type="SwingSpeed" max_value="200" />
<StatData stat_type="ThrustDamage" max_value="500" />
<StatData stat_type="SwingDamage" max_value="500" />
<StatData stat_type="Handling" max_value="200" />
<StatData stat_type="FollowUp" max_value="200" />
<StatData stat_type="MissileDamage" max_value="500" />
<StatData stat_type="MissileSpeed" max_value="200" />
<StatData stat_type="Accuracy" max_value="100" />
</StatsData>
-->
TwoHandedPolearm だったテンプレートの ID が変更してあります。
<UsablePieces> は、自作パーツ2種を追加し、アンロック不要の柄とデフォルトの石突以外は削除しました。
<UsablePiece> をどれだけ残すかで、既存パーツとの互換性が決まります。
上の例のように、完全に自分が決めたパーツの組み合わせだけに限定してもいいですし、変な組み合わせにならない程度にパーツを残して、クラフティングの選択肢を増やすのもありです。
ただし、各部位につき最低1パーツは残しておかないとカテゴリー選択時にクラッシュします。たとえ Pommel を使わないとしても、空データである "default_polearm_pommel" まで消してしまうのはダメです。
さて、ここまでで一度ゲーム内での変化を見てみましょう。
<CraftingPiece> の is_default 属性は新規ゲーム作成時にしかチェックされないため、セーブゲームのロードではなく必ず新規開始にしてください。
鍛冶場で Free Build のカテゴリーを見てみると、何やら細かい文字が書かれているものがあります。
「テンプレート名のテキストデータが無い」とエラー表示されていますが、ゲーム内テキストを定義するにはプログラミングが必要となってくるので、とりあえず無視します。
+
C# MOD が作れる人向け
Native\ModuleData\module_strings.xml と同じ形式でゲーム内テキストの定義ファイルを作成し、
<?xml version ="1.0" encoding ="utf-8" ?>
<base xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd ="http://www.w3.org/2001/XMLSchema" type ="string" >
<strings>
<string id ="str_crafting_template.CustomItems_HalberdTemplate" text ="{=!}Halberd" />
</strings>
</base>
TaleWorlds.CampaignSystem.CampaignGameStarter.LoadGameTexts() で読み込みます。
using System ;
using TaleWorlds.CampaignSystem ;
using TaleWorlds.Core ;
using TaleWorlds.Library ;
using TaleWorlds.MountAndBlade ;
namespace LoadGameTexts
{
public class SubModule : MBSubModuleBase
{
private const string ModName = "CustomItems" ; // MOD 名に応じて変更
private const string XmlName = "module_strings" ; // 必要なら変更
protected override void OnGameStart( Game game, IGameStarter gameStarterObject)
{
base . OnGameStart ( game, gameStarterObject) ;
if ( game
. GameType is Campaign
) {
string path = $"{BasePath.Name}Modules/{ModName}/ModuleData/{XmlName}.xml" ;
try
{
( ( CampaignGameStarter) gameStarterObject) . LoadGameTexts ( path) ;
}
catch ( Exception e)
{
InformationManager
. DisplayMessage ( new InformationMessage
( $
"Failed to load XML: {e.Message}" ) ) ; }
}
}
}
}
DLL の保存場所は CustomItems\bin\Win64_Shipping_Client です。
SubModule.xml の <SubModules> も記述します。
<SubModules>
<SubModule>
<Name value ="LoadGameTexts" />
<DLLName value ="LoadGameTexts.dll" />
<SubModuleClassType value ="LoadGameTexts.SubModule" />
<Tags>
<Tag key ="DedicatedServerType" value ="none" />
<Tag key ="IsNoRenderModeElement" value ="false" />
</Tags>
</SubModule>
</SubModules>
エラーテキストはともかくとして、ハルバード専用カテゴリーの作成はうまくいきました。
開いてみると、一応、指定パーツで構成されたハルバードっぽいものが表示されています ……が、よく見ると槍の穂が浮いてしまっていますね。
どうやら、パーツの位置調整が必要なようです。
パーツの微調整
パーツの位置に関係してそうな属性は、
<CraftingPiece> の distance_to_next_piece と distance_to_previous_piece
<BuildData> の piece_offset
あたりでしょうか。
piece_offset はそのままの意味で、パーツの位置オフセット です。
本来ならば斧のヘッドと柄がきれいに並んでいるところを、ヘッドの位置を -8 することで柄が刺さっているように見せている訳ですね。
distance の方は、「自分からどれだけ離れた場所に次のパーツを置くか」「前のパーツからどれだけ離れた場所に自分を置くか」ということなんでしょうが、distance_to_next_piece はともかくとしても、distance_to_previous_piece と piece_offset の違いがハッキリとは分かりませんでした。
distance_to_previous_piece="4", piece_offset="0" にするのと
distance_to_previous_piece="0", piece_offset="4" にするのでは
見た目は全く同じになりますが、性能は変わります。どうも重心に影響しているっぽいです。
この辺は実際に数値をいじって変化を見たうえで調整していくしかないと思います。
その際、いちいちセーブデータをロードするのは面倒ですから、
チート コマンドを使いましょう。
crafting.reload_pieces CustomItems custom_crafting_pieces
と入力することで、custom_crafting_pieces.xml が再読み込みされ、値の変更が即座に反映されます。
あと、ハルバードにしてはやや短いですが、そこは custom_crafting_template.xml で他の柄パーツとの互換性を持たせることによって、もう少し長い柄も選べるようにすればいいだけです。
いじくり回した末にオフセットはこんな感じになりました。
+
custom_crafting_pieces.xml の最終形
<?xml version ="1.0" encoding ="utf-8" ?>
<CraftingPieces>
<CraftingPiece>
<!--
ここには Backsword Blade の定義
-->
</CraftingPiece>
<!-- id と name を変更
is_default を追加 -->
<CraftingPiece id ="CustomItems_spear_blade_7"
name ="{=!}Halberd Spearhead"
tier ="4"
piece_type ="Blade"
mesh ="spear_blade_7"
length ="52.924"
weight ="0.3656"
is_default ="true" >
<PieceUsages unavailable_usages ="TwoHandedPolearm_Bracing" />
<BladeData stack_amount ="3"
physics_material ="wood_weapon"
body_name ="bo_spear_b" >
<Thrust damage_type ="Pierce"
damage_factor ="2.8" />
<Swing damage_type ="Cut"
damage_factor ="3.5" />
</BladeData>
<Materials>
<Material id ="Iron4"
count ="1" />
</Materials>
</CraftingPiece>
<!-- id, name, piece_type, distance_to_next_piece, distance_to_previous_piece を変更
is_default を追加 -->
<CraftingPiece id ="CustomItems_axe_craft_25_head"
name ="{=!}Halberd Axe Blade"
tier ="4"
piece_type ="Guard"
mesh ="axe_craft_25_head"
distance_to_next_piece ="-18"
distance_to_previous_piece ="0"
weight ="0.8"
is_default ="true" >
<PieceUsages unavailable_usages ="" />
<!-- piece_offset を変更 -->
<BuildData piece_offset ="17" />
<!-- BladeData を削除 -->
<Flags>
<Flag name ="CanBePickedUpFromCorpse"
type ="ItemFlags" />
</Flags>
<Materials>
<Material id ="Iron4"
count ="3" />
</Materials>
</CraftingPiece>
</CraftingPieces>
結果
以上で完成です。
ただし、鍛造時にちゃんと自分で名前を付けないと、エラーテキストをもとにした名前になってしまいます。
それによって不具合が生じるようなことはないでしょうが、注意してください。
ゲーム内での様子
まあ、穂首の部分がやけに細かったり、斧にトゲが生えてたりと微妙な点もありますが、既存パーツのメッシュを流用している以上はやむを得ないところです。
上級編
完全にオリジナルな武器を作る
メッシュとかテクスチャーとかを自分で用意できるかた向け。筆者はそっち方面の知識が皆無なので、有識者の執筆に期待。
最終更新:2021年10月24日 14:00