集団テンプレートのレコードには下記の項目がある。
(1) 集団テンプレート ID: 他のファイルから このレコードを特定するために使われる。
ID の手前に接頭子 pt_ が自動的に付加される。
(2) 名前。
(3) フラグ群。指定可能なフラグは header_parties.py を参照のこと。
(4) メニュー。この集団に出会った時に表示するメニューの ID。値が 0(あるいは定数 no_menu)なら、デフォルトの遭遇システムが使われる。
(5)勢力。
(6) 性格フラグ群。header_parties.py に説明あり。 (訳注: 度胸(大胆さ)、攻撃性、悪漢か否かなど。)
(7) 兵種スタックのリスト。各スタックのレコードは、次のような 4 項目からなる。
(7.1) 兵種 ID。
(7.2) このスタックに登録できる兵の最小人数。
(7.3) このスタックに登録できる兵の最大人数。
(7.4) 隊員フラグ群(省略可)。pmf_is_prisoner を指定すると、そのメンバーが囚人であることを意味する。
注意: スタックは最大 6 個まで。
この module_party_templates.py は、冒頭から(定数定義などは無く)通常の Python のリスト「party_templates = [」が始まります。その中の最初の数件のレコードは、ゲーム・エンジンに密接に対応するテンプレートなので、書き換えてはいけません(その旨 コメントがあります)。module_parties.py のレコードと よく似ていますが、互換性は ありません。例えば、下記の集団テンプレートを見て下さい。
("village_farmers","Village Farmers",icon_peasant|pf_civilian,0,fac_innocents,merchant_personality,[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
これは、ゲーム中に誰もが遭遇したことのあるテンプレートです。このテンプレートが定めている集団は「村の農民」という名の区分でくくられ、民間人であり、ゲーム内で臆病に振る舞い、この区分には「農夫」(farmar)と「農婦」(peasant woman)という 2 つの兵種が属し、それぞれを収めるスタックがあります。このレコードの各項目の内訳は次のようになっています。
(1) 集団テンプレート ID = "village_farmers"
(2) 名前 = "Village Farmers"
(3) フラグ群 = icon_peasant, pf_civilian
(4) メニュー = 0
(5) 勢力 = fac_innocents
(6) 性格フラグ群 = merchant_personality
(7) 兵種スタックのリスト:
(7.1) 兵種 ID = trp_farmer, trp_peasant_woman
(7.2) 兵の最小人数 = 5 farmers, 3 peasant women
(7.3) 兵の最大人数 = 10 farmers, 8 peasant women
(7.4) 隊員フラグ群(省略可) = 指定なし, 指定なし
一つの集団テンプレートに指定できる兵種スタックは、最大 6 個までです。(module_parties.py で宣言する party も同じです。)
party と party template を混同しないようにして下さい。簡単に言うと、party template(集団テンプレート)は、マップ上に集団を生成するための一連のガイドラインです。そこが両者の一番大きな違いです。party はマップ上で一意の「具現化されたもの」(entity)であるのに対し、テンプレートは このゲームの世界に物理的に存在せず、集団(party)を生成するためのガイドラインのリストとしてのみ機能します。だから、party_id を指定するような特定の命令に、party_template_id を渡しても機能しません。
テンプレートを基に生成された集団は一意(ユニーク)である必要はありません。同じテンプレートを基にした集団が多数存在する可能性があります (訳注: 「基にしている」だけであって、生成された各集団の「位置」や「増減した結果の現在の構成員」は互いに異なります。一つのテンプレートから生成された集団に共通なのは「名前」や「性格」です。例えばどの隊商も名前は「隊商」です。一方、party モジュールのほうは「集落・施設」のような静的なものだけを(多くの MOD が意図的に)置き、そこにはテンプレート機能が無いので、結果的に「集落や施設」は全てが一意です。)。それぞれには、プレイヤーのレベルと、テンプレートで定義された最小または最大の人数制限に応じた、ランダムな数の兵種(troop)が含まれます。
もし この web 文書の最初のほうも読んで、色々なレコードに慣れているなら、ここのレコードの第 6 項目「性格フラグ群」は他とは少し毛色が違うことにお気づきでしょう。
性格フラグ群
上のレコードの内訳でも示したように、「性格フラグ群」という項目ではワールド・マップ上の集団の振る舞いを指定します。度胸(Courage)と攻撃性(Aggressiveness)に独自の値を指定したり、そういう値を含んだ merchant_personality のような(事前に定義済の)複合的な性格を指定したりできます。複合的な値の定義は header_parties.py を読めば確認できるし、下記でも一覧してあります。個々の度胸や攻撃性の値も同ファイルで定義されています。
定数 merchant_personality は、このモジュール・ファイルの至るところで使われます。この性格を持つ集団は「友好的」で、敵を攻撃したり、弱い集団を襲撃したりしません。これは、aggressiveness_0 を含んでいるからです。soldier_personality のように aggressiveness_8 を含む集団は「好戦的」です。これにより、一定の条件下で(攻撃側の勢力と防御側の勢力との関係が悪く、攻撃側の勢力が多勢に無勢でない場合)他の集団を攻撃するようになります。
度胸は、集団が別のより大きな集団からいつ逃げるかを決定するための値です。度胸が高いということは、人数が少し不利でも、すぐに背を向けて逃げることが少なくなる、ということを意味します。merchant_personality の集団の度胸は 8、soldier_personality の集団の度胸は 11 です。
これらの値は 0~15 などの範囲で、必要な動作を隊テンプレートに精度よく設定できます。ただし、MOD 開発の初心者は定義済の定数を使えば充分で、大抵の状況を作り出すことができます。
最後に、賊(bandit)のテンプレートには、盗賊性(banditness)という性格があり、付近の他集団を常に獲物と見なし、獲物が大量の金銭や交易品を運んでいると、攻撃します。理想を言えば、賊の集団が兵士集団を攻撃しないよう、攻撃性を下げるか人数を減らすなど調整すべきです。注: 隊テンプレート・モジュールには banditness フラグを直接指定している箇所が見当たらないかもしれませんが、bandit_personality で間接的に指定されています。これについても headers_parties.py で確認して下さい。
集団同士が互いに近づくか逃げるかに関して、「攻撃性」や「度胸」(それと「盗賊性」など)の値が正確に どう機能するかについては、ハード・コーディングされているので、(AI 集団の経路探索と同様で)変更できません [1]。
指定で可能な性格フラグ:
- courage_x(度胸)。集団の度胸レベル x は最小値 4 から始まり、この場合、とても臆病で、自分たちより ずっと小規模な敵集団からも逃げます。レベル 8 なら中くらいの度胸です。最高の度胸レベル 15 の集団は非常に勇敢で、ずっと大きな敵集団と戦う意欲があります。
- aggressiveness_x(攻撃性)。集団の攻撃性レベル x の最小値は 0 で、全く攻撃的ではなく、他集団を積極的に攻撃することはありません。反対に、攻撃性レベル 15 の集団は とても攻撃的です。
- banditness(盗賊性)。上述。
定義済の複合的な性格として下記を使えます。後ろに自由に追加することもできます。
soldier_personality = aggressiveness_8 | courage_9
merchant_personality = aggressiveness_0 | courage_7
escorted_merchant_personality = aggressiveness_0 | courage_11
bandit_personality = aggressiveness_3 | courage_8 | banditness
集団テンプレートの新規レコード追加
もちろん、新たな集団テンプレート(の行)を作ることもできます。それらが正しく使われるように、module_constants.py に新しく slot_faction_reinforcements_YOURLETTER というスロットを定義するとよいです。スクリプト "initialize_faction_troop_types" に必要な処理を書いて当該集団を出現させるようにしておき、出現させる時期に別のスクリプトから呼び出します。コードのどの辺りを編集すべきかは、module_scripts.py 内の slot_faction_reinforcements_a を ざっと検索すると、見つかります。変更すべきことは さほど多くなく、定数でスロットを宣言し、新しいテンプレートを作ることぐらいです [2]。
- 脚注と出典:
- [1] Caba`drin, Modding Q&A.
- [2] Caba`drin, Modding Q&A.