利用者:Chirimen/Mod/PythonによるModの作成

提供: MTM-Gaming
移動先:案内検索

この文書は World of Tanks (通称 WoT) の Mod を Python (Python2) で作成するための情報をまとめています (作成中)。

Python で Mod を作成する

Python のバージョン

Python 2.7 系列を使用する。

Mod の組み込み

Mod の組み込み処理は res/scripts/client/gui/mods/__init__.py で行われる。

結果として res_mods/XXX/scripts/client/gui/mods (XXX は WoT クライアントのバージョン) に置かれた mod_*.pyc というパターンに該当する Python モジュールが動的に import される (import は Python の用語)。 res_mods/XXX というのは paths.xml で定義される WoT クライアントのリソース検索パスの先頭で、 mod_*.pyc も同じルールで検索される。 また、mod_*.pyc は辞書順で import されるので、 XVM のローダーである mod_.pyc が最初に import される Mod となる。

Mod ローダーである res/scripts/client/gui/mods/__init__.py は mod_*.py を import すべきモジュールと判定しないので、 Python で記述した Mod は mod_*.pyc にバイトコンパイルしておく必要がある。

バイトコンパイルはコマンドラインから -m compileall オプションで実行できる。例えば mod_sample.py をバイトコンパイルする場合は以下のようになる。

python -m compileall mod_sample.py


Mod の実行

全 Mod の import が行われた後、各 Mod の初期化ルーチンが呼び出される。

初期化ルーチンは init() である。 モジュールに init() が存在すれば呼び出されるし、なければ単に無視される。 ただし、ほとんどすべての Mod は動作の際に WoT 内の変数や関数を修正する処理が必要なのでここでしておくのがよいだろう。

モジュールの関数定義外の部分に処理を書くことで import 時に処理させることも可能ではあるが、 WoT クライアントの想定する Mod 処理とはフローが異なるようなのでおすすめはしない。

なお、初期化ルーチンと同様に終了ルーチンも存在し、こちらは fini() という名称である。 終了時にデータ保存やリソース解放などの処理が必要な場合はここで行うことができる。たぶん。


単純なサンプル

これはログファイル python.log に "Hello World!" を出力する単純な Mod の例である。

from debug_utils import LOG_CURRENT_EXCEPTION

def init():
    try:
        print('Hello World!')
    except:
        LOG_CURRENT_EXCEPTION()

スクリプトにエラーがあると WoT クライアントが起動しなくなるので、 上記のように try と except で例外処理する習慣をつけておくのがよいだろう。 LOG_CURRENT_EXCEPTION() は例外が発生した箇所の情報をログに出力してくれる。

WoT クライアント内で print の出力先は python.log に切換えられている。


ログメッセージの出力

単に Python の print で出力しても他のログ出力と同様に python.log に出力されるが、 ログ出力用のメソッドが用意されているのでそれを使うほうがいいだろう。

ログ出力用のメソッドは res/scripts/common/debug_utils.py でラップされており、 BigWorld.logTrace, BigWorld.logDebug, BigWorld.logInfo, BigWorld.logNotice, BigWorld.logNotice, BigWorld.logWarning, BigWorld.logError, BigWorld.logCritical, BigWorld.logHack が利用可能である。

これらのメソッドの詳細は不明だが、 res_bw/scripts/common/bwlogging.py では bwInternalLogFunction という変数に代入されており、 名称から想像するとこれらは BigWorld の内部関数である。

用例は bwInternalLogFunction(logCategory, finalMessage, logMetaData) であるので、第1引数がカテゴリ、第2引数が出力する文字列であることが推測できる。 第3引数はメタデータと考えられるが仕様は不明で、 各所の用例でも False が指定されている。

Python の Logger の仕様に準じていると仮定すると、 第3引数はスタックフレームなどデバッグ用の情報を渡すと考えられるが、 コードまたは用例の調査が必要である。


関連情報