プラグインで作業しているときに、プラグインを Stingray に再ロードして、最新の変更をテストしなければならない場合があります。
エンジンおよびエディタ内のセッションをいつでもシャット ダウンして、変更するファイルを再コピーし(たとえば、エンジンの .dll ファイルをエンジンのプラグイン フォルダに再コピーし)、すべてを再起動することができます。ただし、これは必要以上に面倒で、時間のかかる作業です。ほとんどの場合は、プラグインをシャットダウンしなくても、「ホット再ロード」してエディタおよびエンジンを更新し、最新のコンテンツを使用することができます。
エディタで[F5]キーを押します。こうすると、エディタはすべてのプラグイン フォルダを再スキャンして、最新バージョンの .stingray_plugin 記述子ファイルからすべてのプラグインを再ロードします。
プラグインからエディタに HTML パネルまたは JavaScript モジュールが追加されている場合は、[Alt]+[F3]キーを押して JavaScript 環境全体をゼロから再起動しなければならない場合もあります。こうすると、プラグインが提供するすべてのスクリプト モジュールおよび HTML ビューが再初期化されて、最新の変更が表示されるようになります。
プラグインがリソース ライブラリとしてマウントしたフォルダ内にある任意のアセットを追加または変更した場合、エディタは変更を自動的に検出して、リソースを再コンパイルする必要があります。これらのリソースを使用可能にするために特殊な操作を行う必要はありません。いつでも[F5]キーを押して、エディタを強制的に更新することができます。
現在、レベルをテストしたり、プロジェクトを実行している場合は、エディタ内のリソースを更新しても、ゲームを実行しているエンジンが追加または変更されたアセットの更新版を使用するようになるとは限りません。エンジンによって実行中のプロジェクトにリソースが既にロードされている場合は、最初にロードされたこれらのアセットの本来のバージョンが引き続き使用されます。エンジンを更新して、アセットの最新のコンパイル済みバージョンを使用する場合は、エディタのステータス バーからエンジンに refresh コマンドを送信します。詳細については、このページを参照してください。
エディタを開かないでコンパイル済みデータからプロジェクトを実行する場合、またはプロジェクトのスタンドアロン配置版のビルドから実行している場合は、変更されたアセットをホット再ロードすることができません。自分のアセットをコンパイルして、再ロードメッセージをゲームに送信するには、エディタを開いておく必要があります。
エンジンは自動的に .dll プラグインの最新バージョンをホット再ロードできます。エンジンは、既にロードされたプラグインの新しいバージョンを検出し、かつ、そのプラグインがホット再ロード関数を PluginApi で実装していることを検出すると、自動的に古いバージョンの .dll をロード解除して、新しいバージョンをロードします。
プラグイン、およびホット再ロードと互換性のあるビルド プロセスを設定するには、次の手順に従います。
エンジンは、更新されたバージョンのプラグインをロードするときは、常に、クリーンな状態から始まります。プラグインの古いバージョンによって計算または保存されていたものはすべて、再ロード処理中に失われます。ただし、多くのケースでは、プラグインは再ロード後に単純に再計算することができない保存されたデータ(プラグインの現在の状態、ゲーム ワールド内で発生した単位レコードなど)に依存しています。
したがって、エンジンは、プラグインがこの種の状態情報をキャッシュし、ロード解除されるときに保存して、再ロード後に更新バージョンのプラグインに渡すために使用できるインタフェースを提供します。
PluginApi は、プラグインで実装する必要がある次の 2 つの関数を定義しています。
PluginApi::start_reload(): エンジンは、現在のバージョンのプラグインをロード解除する直前に、この関数を呼び出します。この関数は、保存する必要があるすべての状態情報を含む単一のメモリ ブロックのポインタを返します。このブロックの割り当てと、プラグインが中断された場所から再開するために必要なすべてのデータのパッケージ化はユーザの責任で行います。
プラグインで状態情報を維持する必要がない場合、たとえば、単に Lua になんらかの新しい自己完結型の関数を公開したり、フロー ノードを実装したりするだけの場合などは、start_reload() から Null を返すことができます。
PluginApi::finish_reload(): エンジンは、更新バージョンのプラグインをロードした直後に、この関数を呼び出します。この関数は、start_reload に返されたポインタを受け取ることで、メモリ ブロックを解凍し、start_reload によって格納された内容に基づいて状態を再初期化できます。通常はその後、次の再ロードまでは必要ないので、ブロックの割り当てを解除します。
さらに、プラグインが必要なエンジン API を再取得できるように、エンジンはこの関数に get_engine_api 関数を渡すことに注意してください。サンプル プラグインと同様に、プラグインがその setup_game() 関数の中でポインタをエンジン API に保存していて、これらの初期化を別の関数(たとえば init_apis())に移す場合は、この関数を setup_game() および finish_reload() の両方で呼び出します。
コンパイル済み .dll ファイルが、エンジンが更新プラグインをスキャンするフォルダ内に配置されるようにするには、プラグインのビルド プロセスを設定する必要があります。
既定では、エンジンは、その実行可能ファイルの位置の下のサブフォルダ plugins のみをスキャンします。
次の 2 つの方法のいずれかで、追加のフォルダをスキャンできます。
Lua から、stingray.PluginManager.add_hot_reload_directory() を呼び出します。プロジェクトの Lua スクリプトまたはコンテンツ プラグインに、この Lua 呼び出しを含めることができます。ただし、このパスは通常、特定のマシンのファイルシステムに依存し、開発段階でプラグインをテストする場合のみ必要になるため、指定したプロジェクトのホット再ロードを有効にする必要がある場合は、エディタのステータス バーからこの関数を実行する方が便利である可能性があります。詳細については、このページを参照してください。
エンジンを開始するときに、コマンド ラインで --plugin-dir <folder_name> パラメータを渡します。エディタから起動することにより、プロジェクトをテストしている場合は、[Connections] パネルでこのコマンド ラインを設定できます。詳細については、このページを参照してください。このコマンド ラインは、[Run Project] を使用してプロジェクトを起動するときに常に使用されます。[Test Level] 実行時に使用されるコマンド ラインは、現在設定することはできません。
エンジンにロードされた .dll ファイルがある間、そのファイルはロックされています。除去または上書きはできません。つまり、プラグインの以前のバージョンが既に存在している場合は、ホット再ロード フォルダにプラグインの .dll をコンパイルまたはコピーすることはできません。
しかし、ロードした .dll ファイルの名前を変更できます。このため、新しいファイルを追加する前に、既存の .dll ファイル(および、ある場合はその .pdb ファイル)を移動するように、プラグインのビルド前ステップを設定することで、再ロード プロセスをスムーズにすることができます。
たとえば、次のようになります。
del *.old rename ${plugin}.dll ${plugin}.dll.old rename ${plugin}.pdb ${plugin}.${timestamp}.pdb.old del *.old
Visual Studio デバッガは、シャットダウンされるまで、すべての .pdb ファイルをロックし続けることに注意してください。プラグインを再ロードするときに、エンジンにデバッガが接続されている場合は、使用中の .pdb ファイルを除去または上書きできません。そのため、ビルドで新しい .pdb ファイルを作成できるようにビルド前ステップで古いファイルの名前を変更するときには、タイムスタンプを使用して、古いファイルの名前を固有のファイル名に変更できることを確認します。
ホット再ロードは、コードおよびアセットの小規模な反復をテストするときに、システムのシャットダウンおよび再ロードに時間を浪費する必要がない、非常に効率的で便利な方法です。ただし、ホット再ロードにはいくつかの制限事項があり、どのような場合でも適切に動作するとは限りません。
たとえば、最初に初期化するときに、プラグインが何らかの処理を行うとしましょう。後で、この初期化シーケンスに何か他の処理を追加する必要があることがわかりました。ところが、プラグインを再ロードしても初期化コードは再実行されず、プロジェクトは以前の時点から実行し続けます。したがって、このような初期化時間に依存する新しいコードは、予測どおり機能しない可能性があります。
ホット再ロードは通常、パラメータや設定に対する微調整、または既存のコード ブロック内の小規模な変更をテストする必要がある場合に最適に機能します。行った変更が大規模であるほど、更新後に問題が生じるリスクが高まります。
リソースのホット再ロードの詳細については、こちらを参照してください。ゲームの Lua 環境に Lua コードを再ロードする場合は、このページも参照してください。