These constants are used in various files.
If you need to define a value that will be used in those files, just define it here rather than copying it across each file, so that it will be easy to change it if you need to.
(訳注: 訳すと、「これらの定数は様々なファイルから使われます。それらのファイルで使用される値を何か定義したければ、そこへ直接書くのではなく、このファイルで定義するだけで、必要に応じて簡単に変更できます。」。本文でも後述されるように、実際に 複数ファイルから使われるような定数をここで共通化し一括管理できます。)
module_constants.py は、定数ばかり書かれた単純なファイルです。この web 文書の 「開発言語の書式」の「変数」の項 を既に読んでいるならおわかりでしょう。ここで定義された定数は、他所で定義された定数と全く同様に機能します。でも、複数のモジュール・ファイルで共用される定数は、モジュール システムが常にその場所を認識できるように、この module_constants.py で定義すべきです。また、必要に応じていつでも定数の値を変更できる、整理されたアクセスし易い一覧としても機能します。ここでの変更が、その定数を使用する全ての命令とスクリプトに直ちに影響するので、該当する数値を地道に探して置換する必要がありません。例えば、
hero_escape_after_defeat_chance = 80
を
hero_escape_after_defeat_chance = 50
に変えると、hero_escape_after_defeat_chance を使っている命令やスクリプトが影響を受け、この定数を 80 ではなく 50 として扱います。
このファイルには、kings_begin = "trp_kingdom_1_lord" や kings_end = "trp_knight_1_1" のような範囲開始終了マーカーも含まれます。例えば兵種を新しく実装する場合なら、王、商人、 傭兵など module_troops.py 内の どの行に追加べきかを、これら xxxx_begin や xxxx_end で決めています。
スロットは、この定数モジュールで定義するのが うってつけです。「開発言語の書式」の「スロット」の項 を既にお読みかもしれませんね。スロットは いくつかのオブジェクトの種類(兵種、勢力、隊、クエストなど)に複数個 割り当てることができ、そこへ特定の値を格納できます。スロットは、MOD システムからはインデックスとして扱われ、xxxxx_get_slot / xxxxx_set_slot という命令 (ここで「xxxxx」は quest や item などの語)を使ってゲーム内に存在する様々なオブジェクトのデータを配列形式で取得したり保存したりできます [1]。 例として、クエストのスロット番号の定義が並んでいる箇所を見てみましょう。
###################################################
## QUEST SLOTS
###################################################
slot_quest_target_center = 1
slot_quest_target_troop = 2
slot_quest_target_faction = 3
slot_quest_object_troop = 4
##slot_quest_target_troop_is_prisoner = 5
slot_quest_giver_troop = 6
slot_quest_object_center = 7
slot_quest_target_party = 8
slot_quest_target_party_template = 9
slot_quest_target_amount = 10
slot_quest_current_state = 11
slot_quest_giver_center = 12
slot_quest_target_dna = 13
slot_quest_target_item = 14
slot_quest_object_faction = 15
slot_quest_convince_value = 19
slot_quest_importance = 20
slot_quest_xp_reward = 21
slot_quest_gold_reward = 22
slot_quest_expiration_days = 23
slot_quest_dont_give_again_period = 24
slot_quest_dont_give_again_remaining_days = 25
###################################################
左辺は各スロットに付けた名前、右辺はスロット番号です。名前により、スロットの用途が わかり易くなります。例えば、slot_quest_xp_reward なら、クエストの完了によって得られる経験値の量を保存する場所で、ゲーム・エンジンも使うので、意味を変更できません。MOD のコード側では slot_quest_xp_reward と数値 21 のどちらを使っても同じことですが、番号よりも名前のほうが理解し易いでしょう。 (訳注: 理解と言っても、コメントが少ないので、意味を推測するしかありません。この例のように reward が付いていれば xp が「経験値」だと想像できますが、そうでない xp もあるかもしれません。)
スロットを追加したい場合、新しいスロットを任意の値として定義するだけです。右辺の値が大きすぎると、そのインデックスまでメモリを予約することになり、実行速度に悪影響があります。既存の値を別名で定義し直すこともできます。ゲーム・エンジンは数値だけを解釈するからです。アイテム・スロットは Native では滅多に使われませんが、例えば銃のようなアイテムなら、食品や本と同じようにスロットを使えます。後は どこからでも (item_set_slot, "itm_gun", slot_item_xxxx, val) のような命令を使って値を保存できます (訳注: ここで「xxxx」は、例えば基本価格なら base_price という語で、左辺つまり識別子全体では slot_item_base_price のように定義されます。上記クエストの場合に識別子が slot_quest_ で始まっているように、物品の識別子は slot_item_ で始まります。また、item_set_slot 命令は header_operations.py 内で定義され、当該行のコメントにパラメータの説明があります。)。スロットに格納する値 val は常に数値です。ただし、別のオブジェクトへの参照、例えば module_sounds.py の snd_lyhyt のようなものも あり得ます。この引用符のない参照は id_sounds.py で生成されたインデックス値を取得しますが、引用符で囲まれた参照は 競合を避けるために元の値をビットシフトしている可能性があることに注意して下さい [2] (訳注: ここで val が数値だというのは、ゲーム・エンジンが読む *.txt での話です。例えば文字列をスロットに格納したい場合、ソース・コード *.py 内では その文字列を引用符でくくって指定し、「コンパイル」後にそれが純粋な数値(quick_strings.txt 内の行などへのインデクス)に変換されます。詳しくは Strings のページなどを参照して下さい)。
ここで実装された定数を、参照する側のファイルでは、先頭で「from module_constants import *」を指定することで module_constants.py の参照を宣言します。さもないと、コンパイル時にエラーになり得ます。
- 脚注と出典:
- [1] Somebody, Modding Q&A.
- [2] Somebody, Modding Q&A.