この記事は、英語 wiki (LAST EDITED BY Artyom Zuev, 2024年6月2日)を基に加筆・修正したものです
この記事は公式記事を翻訳したもので、便宜的な補助資料として作成されました。最新の情報は原文を参照し、原文と訳文に矛盾があれば原文に従ってください。訳文の誤りや矛盾により生じるトラブルや損失について一切の責任を負いません。
翻訳: @ichihito_ohi、2024年6月20日
このページでは、 Phantom Brigade における mod システムの設計について詳しく説明します。 Mod 開発者を対象としています。 Mod のインストール手順や一般的なガイドラインをお探しの場合は、上位階層の Modding ページ を参照してください。
設定ファイルが公開されているデータ駆動型構造のおかげで、 Phantom Brigade は常に直接改造することができます。インストール先フォルダ内のファイルを変更することで、シナリオ変更、装備のバランス再調整、新しい機体やローカライズの追加などは可能です。しかし、この改造アプローチにはいくつかの問題と制約があります:
この新しい mod システムはこれらの問題すべてを解決するための試みです。これは、改造可能な他の人気 Unity ゲームの mod システムの設計にかなり近いものです。 Mod 開発を初めるには、 AppData/Local/PhantomBrigade/Mods
フォルダを開いてください。バージョン 1.1 以前のゲームでは追加の手動セットアップ(Mods
フォルダと Settings/mods.yaml
の手動作成)が必要でしたが、現在は必要なくなりました。
フォルダが見つけられない場合、あなたの PC で Windows エクスプローラーの設定がフォルダを非表示にしている可能性があります。詳細は次の web ページを参照してください。Windows の隠しファイルと隠しフォルダを表示する - Microsoft サポート
または、メイン・メニューの MOD タブで「ローカルモッド」ボタンを押すとフォルダが開きます。
Mods/MyMod1
、 Mods/MyMod2
…のように mod は別々のフォルダにします:
親ディレクトリ配下の mod フォルダの例。
それぞれの mod フォルダには、 mod の内容について基本的な情報をゲームに伝える metadata.yaml
ファイルが必ず必要で、これにより読み込みと mod 管理 UI の描画が可能になります
上記フィールドをすべて備えた metadata.yaml の例。
メイン・メニューでは、 mod フォルダ内で検知された mod をすべて確認できます:
メイン・メニューの MOD タブの例。いくつかの mod が有効になっている。
ゲームは起動時に mod を適用します。 Mod をインストール、無効化、再有効化した場合は、ゲームを再起動して影響を確認する必要があります。
Mod には異なるコンテンツ・タイプを含めることができます。これらは mod フォルダ内でサブフォルダとして分けられ、その存在は metadata.yaml
内で宣言します。対応するコンテンツ・タイプは時間を経て拡張され、設定やローカライズ、画像などが含まれます。
includesConfigOverrides
ConfigOverrides/
これは、 Configs フォルダを直接編集するのとよく似た、最も単純な種類の mod コンテンツです。
Mods/[ModName]/ConfigOverrides
以下に複製すると、ファイルを置き換えたり新しく追加したりできます。.yaml
ファイルを改造した物である必要があり、まったく同じ場所に配置する必要があります。Mods/[ModName]/ConfigOverrides/DataDecomposed/Equipment/Part_Presets/my_new_weapon.yaml
に追加するとゲームはそれを読み込みます。Mods/[ModName]/ConfigOverrides/Data/Settings/simulation.yaml
に配置すると、ゲームはそのバージョンのグローバル設定を使用した状態で起動します。Data
と DataDecomposed
フォルダの内容のみ対応しています。 Configs
の中には他にもファイルがありますが、現時点ではこの mod コンテンツ・タイプで改造することはできません。 Config overrides を用いた mod 適用は PB/Configs ディレクトリのファイルを直接改造するディスク操作ではなく、 DataLinker
および DataMultiLinker
データマネージャーの読み込み段階における挿入操作です。ですが、通常みなさんが改造したいであろうファイルは上書き可能です―それ以外のファイルはごく少数で改造には適していません。(古いバイナリファイル、現在のデータベースシステムより前から存在する使われていない設定など)includesConfigEdits
ConfigEdits/
このコンテンツ・タイプを使うと、複数の mod による同一ファイルの改造やアップデート時のファイル構造変化に耐性のある、よりきめ細やかな改造が可能になります。
Mods/[ModName]/ConfigEdits
に複製して、既存のパスおよびファイル名と一致するように .yaml
ファイルを配置してください。simulation.yaml
には何百ものパラメータが含まれており、物理シミュレーション設定の部隊サイズや戦利品生成の倍率など何かしらを変更するため、様々な mod がこれを改造しようとするでしょう。squadSize
と呼ばれる行を改造する一行だけの simulation.yaml
ファイルを持ち、また別の mod が複数フィールドの変更を指示する simulation.yaml
ファイルを持つということが可能です―そしてすべての変更がシームレスに統合されます。まるで本作の設定のすべての項目やフィールドをそれぞれ個別の .yaml
や個別のフォルダのように扱えるようになり、非常に的を絞った変更が可能になります。Config edits の形式は比較的単純です。
removed
を true
に設定してください。(例えば、あなたの mod が武器の部品を置き換え、既存の武器をゲームから削除する必要がある場合)edits
フィールドに記入してください。
List<T>
と同じように、必ず各行を -
で始めてください。- 'hidden: true'
これにより行内の任意の場所で予約文字 [1] が使えるようになります。:
で分割された二辺で構成されます―左辺が パス 、右辺が 値(バリュー) です。
squadSize
という名前の最上位フィールドを 3
という値に改造するには、次のように入力します:- 'squadSize: 3'
.
で区切ってください。―例えば、1層の入れ子になったフィールドの改造はこちら:- 'customPlayerSlot.spawnTagsUsed: true'
- 'states.no_hostiles.visible: false' # no_hostiles は辞書のキー
- 'unitChecks.0.value: 1' # 0 はリストの番号!
edits
フィールドは辞書型ではないので、同じパスについて複数回編集を繰り返すこともできます。例えば、 tags
コレクションを一度改造(何かを削除するなど)した後でもう一度改造(何かを追加するなど)しても、まったく問題ありません。string
, bool
, int
, float
, Vector2
, Vector3
, Vector4
true
との等価を用いて使用されます。int.TryParse
や float.TryParse
で想定されている文字列書式を参照してください。例を挙げると 6
や 8.62
などです。(3.1, 4, 7.2)
などです。!d
("default" の d)が専用の予約キーワードです。以下のように使用します:- 'customExitBehaviour: !d'
- 'field: 7' # 'field' という名前のフィールドを 7 で上書き
List<T>
の場合、以下の処理に対応しています:
- 'list.4: 7' # 'list' という名前のリストの4番を 7 で上書き
- 'list.0: 7 !+' # リストの一番最初に値が 7 の項目を挿入
- 'list.8: 7 !+' # リストの8番に値が 7 の項目を挿入(それ以上項目がある場合)または一番最後に挿入(項目が8個未満の場合)
- 'list.3: !-' # 3番の項目を削除
HashSet<string>
の場合、以下の処理に対応しています:
- 'tags: context_facility !+' # ハッシュセット 'tags' に文字列を 'context_facility' の挿入を試行
- 'tags: context_fort !-' # ハッシュセット 'tags' から文字列を 'context_facility' の削除を試行
Dictionary<T>
の場合、以下の処理に対応しています:
- 'dictionary.existing_key: true' # 辞書 'dictionary' のキー 'existing_keyin' に対応する値(バリュー)を 'true' で上書き
- 'dictionary.new_key: true !+' # 辞書にキー 'new_key' と対応する値 'true' の挿入を試行
- 'dictionary.existing_key: !-' # キー 'existing_key' に対応する項目の削除を試行
!+
- 新しい項目を追加!-
- 項目を削除!d
- 既定値に設定(参照型の場合 - null でない新規インスタンス)!n
- null に設定Color
フィールドの編集に対応していないincludesLibraries
Libraries/
これは、C#/Unity が依存する編集可能な中間言語(IL; interpreted language)によって可能になる非常に強力なタイプの mod コンテンツです。ゲームロジックにパッチを適用し新たなコードを実行できるライブラリをロードできる機能です。
Mods/[ModName]/Libraries/MyLibrary.dll
のような Libraries フォルダ内のアセンブリをすべて検出しようとします。ModLink
という特殊なクラスを継承しているクラスを探します―見つかった場合、インスタンス化され、データが入力され、特殊なエントリーメソッドが呼び出されます。ModLink
は mod 製作者にエントリーポイントを提供します。 OnLoad
メソッドのオーバーライドを宣言して、任意のコードを実行できます。 Mod のメタデータすべて(作業ディレクトリ、どの mod を操作しているか、他に何の mod がロードされているか)および Harmony patcher オブジェクトにアクセス可能で、 PB 内のコードを改造できるようになります。新規ライブラリの一般的な立ち上げ方法は以下の通りです:
0Harmony.dll
は、 Harmony web サイトの 2.1 リリース をダウンロードしてください(Phantom Brigade の今後のリリースで上層の Manage フォルダに直接含められる可能性があります)Assembly-CSharp.dll
、 Assembly-CSharp-firstpass.dll
、 System.dll
、 UnityEngine.dll
は、インストールフォルダ(例: PB/PhantomBrigade_Data/Managed/
)から入手してくださいEntitas.dll
は、インストールフォルダから入手してくださいModLink.cs
ファイルを作成してください
ModTest
のような、 metadata.yaml
の id
フィールドと一致する名前が理想的ですnamespace ModTest {}
ModLink
を継承するクラスを宣言してください。例:namespace ModTest
{
public class ModTestLink : ModLink {...}
}
OnLoad
のオーバーライドメソッドを宣言してください:public class ModTestLink : ModLink
{
public override void OnLoad (Harmony harmonyInstance) {...}
}
metadata
フィールドにアクセスして作業ディレクトリやどの mod がこのライブラリを読み込んでいるかなどの情報を取得したり、 ModManager.loadedMods
にアクセスして他の mod と連動したり、任意のゲーム内クラスにアクセスしたり、メソッドに渡された Harmony
オブジェクトを用いて独自のパッチ処理手順を実行したりすることができます。Patches
というプレーンクラスを宣言してください
public class Patches
{
[HarmonyPatch (typeof (PhantomBrigade.GameController), MethodType.Normal)]
[HarmonyPatch ("Initialize")]
public class ModPatch
{
public static void Prefix() {...}
public static void Postfix() {...}
}
}
OnLoad
のオーバーライドを宣言してその中で base.OnLoad (harmonyInstance)
の呼び出しをコメントアウトしない限り、自動的に上記のパッチがすべて適用されます。includesTextures
Textures/
このコンテンツ・タイプを使うと、既存のテクスチャーを上書きしたり使用可能なテクスチャーセットを拡張したりすることができます:
Mods/[ModName]/Textures
に配置してください。PhantomBrigade_Data/StreamingAssets/UI
を参照してください)StreamingAssets
内のテクスチャーを調べるか以下を参照してください)Textures/UI/OverworldEvents
Configs/DataDecomposed/Overworld/Events
フォルダ) DataContainerOverworldEvent
の steps
にある image
フィールドで制御されます)Textures/UI/OverworldEntities
Configs/DataDecomposed/Overworld/Entities
フォルダ) DataContainerOverworldEntityBlueprint
の image
フィールドで制御されます)Textures/UI/PilotPortraits
Textures/UI/Sprites
includesLocalizationEdits
LocalizationEdits/
このタイプのコンテンツペイロードによって、ローカライゼーション・データベースにテキストを追加できるようになります。 Confgs/Data
や Configs/DataDecomposed
のデータファイルにプレイヤーが目にするテキストが含まれることはまれ(今後さらにまれになるでしょう)ですが、これはそのような方法でテキストを格納するとローカライゼーションや容易なテキスト改造の可能性が妨げられるためです。ゲーム内テキストのほとんどは最終的に、 Configs/Text
内のローカライゼーション・データベースに格納され、言語別のバージョンに分割される予定です。ただし、これは mod にひとつの問題を引き起こします―新しいアイテムを追加し、そのテキストが本体データ設定に含まれていない場合に、どうやってプレイヤーが目にするテキストを追加すれば良いのでしょうか?
例えば、新しいスラスター・サブシステムを追加する場合、それに名前と説明文をつけたいはずです。しかし、ゲームがローカライゼーションに対応したため、名前と説明文はサブシステムの設定ファイルからは取得されません―ゲームは internal_aux_thruster_mod
のようなサブシステムの名前を取り、 internal_aux_thruster_mod__name
や internal_aux_thruster_mod__text
のようにローカライゼーション・キーを決定し、それらのキーを用いてロードされた言語の適切なテキスト領域からテキストを取得しようとします。(例: Configs/Text/English/Sectors/equipment_subsystems.yaml
)このテキスト領域を改造する機能がないと、ユーザー向けの名前・説明文を新しいアイテムにつけることができません。
このタイプのコンテンツをどのように使うかは上記のスクリーンショットで抜粋していますが、念のため、手順を踏んで概要を示します:
ConfigOverrides\DataDecomposed\Equipment\Subsystems
に internal_aux_thruster_mod.yaml
という新しい設定ファイルを含んでいるとします。そのようなファイルは元のゲームには存在しません―つまり、新しいアイテムであり、改造された物ではありません。ゲームはそれにテキストを表示できません。ResolveText
メソッドを読むことで、それぞれのアイテムについてどのテキスト領域でどんなテキスト・キー・パターンが使われているかわかります。Configs\Text\English\Sectors
で internal_aux_thruster_hotrod
のような既存のサブシステムの名前を探すことで、そのようなテキストがどのファイルに格納されていて、どのようにテキスト・キーが構成されているかを見ることができます。ConfigOverrides
フォルダと同じ場所に LocalizationEdits
という新しいフォルダを追加してください。英語ローカライゼーションに追加したい新規の文字列ふたつ(名前と説明文)を宣言しているファイルをそのフォルダの equipment_subsystems
のテキスト領域に追加してください。それは、あなたが調べたようにサブシステム用のテキストがここに格納されているからです。includesLocalizationEdits
フラグを mod のメタデータに含まれば、完了です―新しいアイテムがプレイヤー用のテキストをゲーム中で表示するようになります!内部的には、ゲームが言語データベースと言語ごとに登録されたキーを読み込むたびにローカライゼーション設定が適用されます。つまり:
MyMod\LocalizationEdits\English\equipment_subsystems.yaml
ファイルを作成してプレイヤー向けの英語テキストを追加する一方で、二番目のファイル MyMod\LocalizationEdits\Japanese\equipment_subsystems.yaml
を作成して日本語ローカライゼーションに対応することができます。または、ある mod 向けの特定言語ローカライゼーションを含む別の拡張 mod を作成することもできます。例:このアイテムはゲーム本体には存在せず mod で追加されたものですが、スクリーンショットで示されているように、独自の名前と説明文がゲームで適切に表示されています。
includesLocalizations
Localizations/
このコンテンツ・タイプを使うと、ゲームに新規ローカライゼーションを追加することができます。一般的な原理は以下の通りです:
Configs/Text
から公式の英語フォルダ English を MyMod/Localizations
にコピーして、ローカライズする言語に名前を変更してください。例: MyMod/Localizaions/French
yaml ファイル上での翻訳作業が困難な場合は、有志が制作した yaml/csv 変換ツールの利用をご検討ください。
GitHub - ichihito-ohi/PhantomBrigade-Translation
特記:
> data.toggle-localization-debug
Assembly-CSharp
を開いて DataContainer
クラスを継承しているファイルで ResolveText という名前のメソッドを探すことをお勧めします。ゲーム内データベースの大部分はこのようなメソッドでテキストのローカライズを処理しており、それを読むことでローカライゼーション・キーがどのように生成されてデータ・キーの中からどのように使われているかわかるようになるでしょう。これは上述のローカライゼーション編集 mod においても役立ちます。ゲームログに注意してください―何らかの問題が起きた場合に mod マネージャーから多くの情報が含まれていたり、すべて上手く動作した場合に読み込みが成功したことを確認したりすることができます。接頭辞 "Mod Manager" がついたメッセージをログの一番初めに向けて探してください。ログを表示するには、 Shift + F11 を押すか、アプリケーションのデータフォルダにあるログファイルを開いてください。
Mod の開発中は、 AppData/Local/PhantomBrigade/Settings
フォルダの debug.yaml
にある developerMode
を有効化して、追加オプション、デバッグ情報、コンソールコマンドにアクセスできるようにすると役に立つ場合があります。
開発者モードまたは mod が有効なゲームからのバグとクラッシュの報告は BYG に処理されないことに注意してください。
リストの番号(index)は0から始まる ↩︎
https://docs.microsoft.com/dotnet/core/tutorials/library-with-visual-studio ↩︎
移動基地,敵施設,パトロール部隊など ↩︎