コンテンツにスキップ

Godot SDK

Framedash Godot SDK (C# アドオン) を使用して、パフォーマンステレメトリを自動収集する方法を説明します。

  • Godot 4.3 以上の .NET (C#) ビルド。標準の GDScript 専用ビルドでは C# アドオンをコンパイルできません。
  • .NET 8 SDK 以降(net8.0 をターゲットにできる SDK であれば可。アドオンは net8.0 をターゲットとするゲームアセンブリにビルドされます)
  • Web (HTML5) エクスポートは、Godot 4 の .NET Web エクスポートがサポートされていないため対象外です。

SDK は Godot Asset Library(エディター GUI)から、または GitHub から手動(スクリプト / CI 向け)でインストールできます。 CI やスクリプトでのセットアップでは、Asset Library の手順がエディター GUI を必要とするため、下の手動インストールを使ってください。

Godot Asset Library(エディター GUI)

Section titled “Godot Asset Library(エディター GUI)”

SDK は Godot Asset Library で公開されています。 この方法は GUI 専用です。 Godot エディターで次の手順を実行します:

  1. AssetLib タブを開く
  2. Framedash Telemetry SDK を検索し、バージョン 0.1.8 を選択する
  3. Download、続けて Install を選択する。addons/framedash/ を選択したままにして、アドオンが res://addons/framedash/ にインストールされることを確認する

リリースバージョンに固定する場合や CI で使用する場合は、Framedash Godot SDK リポジトリをクローンします:

Terminal window
git clone --branch v0.1.8 --depth 1 https://github.com/crane-valley/framedash-godot-sdk.git

再現性のあるビルドのため、既定ブランチを追いかけるのではなくリリースタグ(v0.1.8)に固定します。クローン後、プロジェクトに addons/ ディレクトリがなければ作成してから、リポジトリの addons/framedash/ フォルダーを res://addons/ にコピーします。

どちらかの方法でインストールしたあと、次の手順を実行します:

  1. C# ソリューションを 1 回ビルドする。これで .csproj / .sln が生成され、アドオンがコンパイルされて autoload 型が利用可能になる
  2. Godot エディターで Project > Project Settings > Plugins を開く
  3. Framedash Telemetry SDK を有効化

プラグインを有効にすると、Framedash autoload singleton が登録されます。起動直後の _Ready() などで SDK を一度だけ初期化します:

using Framedash;
using Godot;
public partial class GameBootstrap : Node
{
public override void _Ready()
{
TelemetrySDK.Initialize(
apiKey: "your-api-key",
buildId: "1.0.0");
}
}

endpointUrlbuildId は任意です。endpointUrl を省略すると https://ingest.framedash.dev/v1/events が使われます。

SDK は次のデータを自動収集します:

  • FPS / フレームタイム: 実時間のフレームデルタから算出
  • メモリ: Godot の static memory
  • GPU / レンダー CPU 時間: RenderingServer が報告する直近フレームの値
  • ゲームスレッド時間: _process に費やされた時間

session_start は初期化時に、perf_heartbeat は 10 秒ごとに送信されます。

TelemetrySDK.Instance.Track(
eventName: "player_death",
mapId: "map_01",
position: playerNode.GlobalPosition);

カテゴリ属性や数値メトリクスを付ける場合:

using System.Collections.Generic;
TelemetrySDK.Instance.Track(
eventName: "player_death",
mapId: "map_01",
position: playerNode.GlobalPosition,
attributes: new Dictionary<string, string> { { "cause", "fall_damage" } },
metrics: new Dictionary<string, float> { { "health", 0f } });

トラックしたイベントはメモリにバッファされ、30 秒間隔、またはバッチが 100 件か 100 KB に達した時点のいずれか早いほうで自動的にフラッシュされます。 長時間動くゲームでは手動でフラッシュする必要はありません。

短命な実行やヘッドレス実行は、次の自動フラッシュより前に終了することがあります。 その場合は Flush() を明示的に呼び、送信が確認できるまでプロセスを生かしておいてください(詳細ログには HTTP の結果が出力されます)。 Flush() は非同期の送信を開始するだけで、最後の送出はプロセスの終了に合わせて行われます。 そのため、同じ行で終了せず、Flush() を呼んでから少し間を置いて終了してください。 Godot SDK 0.1.5 以降は、正常なシャットダウン時にバッファを同期的に排出します(上限 2.5 秒)。 オフラインキューはないため、この時間内に送信が失敗したイベントや、強制終了で残ったイベントは失われます。 詳細はトラブルシューティングを参照してください。

TelemetrySDK.Instance.Flush();

デフォルトではイベントは匿名で送信されます。ログイン後に SetPlayerId を呼ぶと、以降のイベントにプレイヤー識別子を関連付けられます:

TelemetrySDK.Instance.SetPlayerId(playerId);

ランタイムのサンプリングオーバーライド

Section titled “ランタイムのサンプリングオーバーライド”

SDK はグローバルなサンプリングレート(既定は 1.0 = 全件保持)を適用します。 高頻度なイベントは、実行時にグローバルレートを上書きするイベント名ごとのレートを個別に設定できます。

Framedash.TelemetrySDK.Instance.SetEventSamplingRate("ai_pathfind_step", 0.05f); // 約 5%
Framedash.TelemetrySDK.Instance.RemoveEventSamplingRate("ai_pathfind_step"); // グローバルに戻す

SetEventSamplingRate(string eventName, float rate) はレートを [0, 1] にクランプして設定し、RemoveEventSamplingRate(string eventName) はそのオーバーライドを削除します。 自動収集されるイベント(session_startperf_heartbeat)はサンプリングの対象外です。

Godot SDK 0.1.4 以降で利用できます。 SDK はシーンやレベルの読み込みにかかった時間を計測し、map_load イベントとして報告できます。 このイベントはビルド比較(perf-diff)のリグレッションゲートと、ダッシュボードのロード時間チャートに使われます。

自分で制御するロードを BeginMapLoad / EndMapLoad で囲みます。

TelemetrySDK.Instance.BeginMapLoad("Level_01");
// ... シーンを読み込む ...
TelemetrySDK.Instance.EndMapLoad();

BeginMapLoad は、ポーズやタイムスケールの影響を受けない単調増加クロックでタイマーを開始します。 EndMapLoad はそれを止めてイベントを送出します。 EndMapLoad の前に再度 BeginMapLoad を呼ぶと、保留中の計測は置き換えられます。

カスタムローダーやストリーミングローダーで既に時間を計測している場合は、その値を直接報告できます。

TelemetrySDK.Instance.ReportMapLoad("Level_01", 1234f); // ロード時間(ミリ秒)

ReportMapLoad は、loadTimeMs が NaN、無限大、または負の値のとき、そのサンプルを丸ごと破棄します(クランプはしません)。

どちらの経路も、metrics["load_time_ms"]attributes["map_name"] を持つ map_load イベントを送出します。 このイベントは意図的に map_id を空にしているため、空間ヒートマップとアクティベーションゲートの対象外になります。 これらの呼び出しは任意のスレッドから安全に行え、例外を投げず、Initialize の前は何もしません。

Godot SDK 0.1.4 以降で利用できます。 SDK はディスク読み取りのカウンターを、io.read_bytesio.read_time_msio.read_ops というメトリクスキーで perf_heartbeat イベントに付与できます。 各値は前回の heartbeat からの差分で、実際にサンプルが取得できてから初めてキーが付きます(ゼロ埋めはしません)。 他のパフォーマンスメトリクスと同様に、io.* は perf-diff / builds-compare のリグレッションゲートとダッシュボードのチャートに使われます。 io.* のしきい値アラートはありません。

Godot には自動のディスク I/O ソースがないため、ReportIoSample で自分でサンプルを供給します。

TelemetrySDK.Instance.ReportIoSample(bytes: 1048576, readTimeMs: 3.2f, ops: 12);

Godot SDK 0.1.5 以降で利用できます。 SDK は heartbeat の周期でメモリカテゴリ別の使用量をサンプリングし、perf_heartbeat イベントに mem.* メトリクスとして自動的に付与します。 値は Godot の Performance モニターから取得し、オプトインは不要です。

  • mem.vram:使用中のビデオメモリ(バイト)。
  • mem.textures:テクスチャが占めるビデオメモリ(バイト)。
  • mem.buffers:バッファが占めるビデオメモリ(バイト)。

読み取り値が 0 以下のときは、そのキーを付けません。 キーがないことは未収集を意味し、0 として送ることはありません。

これらのキーは perf_heartbeat に加えて、位置情報付き(map_id が空でない)イベントにも付与されます。 perf_heartbeatmap_id が空で空間ヒートマップのグリッドに入らないため、セルごとのメモリヒートマップを作れるよう、同じサンプルを位置情報付きイベントにも載せます。 位置情報付きイベントに載るのは heartbeat の周期で更新されるキャッシュ済みサンプルです。

呼び出し側が渡したメトリクスキーは、キーの衝突時も容量の面でも常に優先されます。 mem.* が埋めるのは取り込み上限(メトリクス 50 件)に残った枠だけで、まず mem.vram から入ります。

プラグインが登録する autoload は TelemetrySDK.cs のコード既定値で生成されるため、Project Settings から [Export] フィールドを直接編集するモデルではありません。通常は TelemetrySDK.Initialize(...) で設定してください。

TelemetrySDK スクリプトを自分の scene node に追加して独自の autoload scene として使う場合のみ、Inspector から API キー、endpoint、sampling rate、camera rotation などの [Export] フィールドを設定できます。

最初の統合では、詳細ログを有効にして送信を確認してください。

TelemetrySDK.Instance.VerboseLogging = true;

トランスポート失敗時はリトライの梯子を記録します。例: [Framedash] Retry 1/3 in 1.0s (HTTP 0)HTTP 0 は API による拒否ではなく、トランスポートレベルの失敗(DNS、TLS、タイムアウト)を意味します。 イベントが届かない場合はトラブルシューティングを参照してください。

Godot のエディター Build は、C# プロジェクトの .csproj / .sln を生成します。 godot --headless --build-solutions --quit は既存のソリューションをビルドしますが、一度もビルドしていないプロジェクトでは初回の .csproj / .sln を生成できません。 CI 専用の新規プロジェクトでは、終了コード 0 でエラーもなく完了しながら、プロジェクトファイルを何も書き出さないことがあります(4.6.3 mono で確認)。 そのため、最初のビルドをヘッドレスで行うことはできません。

エディターで一度も開いていない CI 専用プロジェクトでは、先に自分でプロジェクトファイルを作成してください。 プロジェクト直下に <project>.csproj を手で作成し、Sdk="Godot.NET.Sdk/<engine version>" を指定して net8.0 をターゲットにします。 Godot.NET.Sdk のバージョンは、ビルドに使う Godot のバージョンに合わせてください。

<Project Sdk="Godot.NET.Sdk/4.6.3">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
</Project>

エディターで少なくとも一度プロジェクトを開けるなら、そこで Build を 1 回クリックし、生成された .csproj / .sln をコミットする方法もあります。

プロジェクトファイルを用意したら、.NET SDK でビルドします。

Terminal window
dotnet build

コンパイルされたアセンブリは .godot/mono/temp/bin/Debug/ に生成されます。 プラグインは Initialize が自分で生成できる autoload を登録するだけなので、ヘッドレス実行ではエディター UI からプラグインを有効にする必要はありません。

イベントが届かない場合はトラブルシューティングを参照してください。

自動テストやプロファイリング実行では、セッション全体にタグを付け、各イベントが CI のビルドとその branch / commit / scenario を持つようにします。 テストのエントリーポイントで、自動セッション API を一度だけ呼び出します。

using Framedash;
// 引数はすべて任意です。
TelemetrySDK.Instance.BeginAutomatedSession(
buildId: "build-123",
branch: "main",
commit: "abc1234",
scenario: "nightly");
// ... 自動シナリオを実行する ...
TelemetrySDK.Instance.EndAutomatedSession();

完全なシグネチャは void BeginAutomatedSession(string buildId = null, string branch = null, string commit = null, string scenario = null) です。 CI では BeginAutomatedSessionFromEnvironment() を使うと便利です。 これは framedash run-profile-test が書き出す環境変数 FRAMEDASH_BUILD_IDFRAMEDASH_GIT_BRANCHFRAMEDASH_GIT_COMMITFRAMEDASH_TEST_SCENARIO を読み取ります。

TelemetrySDK.Instance.BeginAutomatedSessionFromEnvironment();
// ... 自動シナリオを実行する ...
TelemetrySDK.Instance.EndAutomatedSession();

自動セッションは、セッション内のすべてのイベントに build_id の上書きと ci.branch / ci.commit / ci.scenario 属性を付与します。 これがビルド比較(perf-diff)の CI ゲートに使われます。 イベントの source は変わりません。 SDK 自身の自動イベント(session_startperf_heartbeat)は source=automated のまま、Track イベントは source=player のままで、これは CI でも通常のプレイでも同じです。 パイプライン全体は CI プロファイリング を参照してください。