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 エクスポートがサポートされていないため対象外です。
インストール
Section titled “インストール”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 エディターで次の手順を実行します:
- AssetLib タブを開く
- Framedash Telemetry SDK を検索し、バージョン
0.1.8を選択する - Download、続けて Install を選択する。
addons/framedash/を選択したままにして、アドオンがres://addons/framedash/にインストールされることを確認する
GitHub から手動でインストール
Section titled “GitHub から手動でインストール”リリースバージョンに固定する場合や CI で使用する場合は、Framedash Godot SDK リポジトリをクローンします:
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/ にコピーします。
どちらかの方法でインストールしたあと、次の手順を実行します:
- C# ソリューションを 1 回ビルドする。これで
.csproj/.slnが生成され、アドオンがコンパイルされて autoload 型が利用可能になる - Godot エディターで Project > Project Settings > Plugins を開く
- 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"); }}endpointUrl と buildId は任意です。endpointUrl を省略すると https://ingest.framedash.dev/v1/events が使われます。
自動収集されるデータ
Section titled “自動収集されるデータ”SDK は次のデータを自動収集します:
- FPS / フレームタイム: 実時間のフレームデルタから算出
- メモリ: Godot の static memory
- GPU / レンダー CPU 時間:
RenderingServerが報告する直近フレームの値 - ゲームスレッド時間:
_processに費やされた時間
session_start は初期化時に、perf_heartbeat は 10 秒ごとに送信されます。
カスタムイベント
Section titled “カスタムイベント”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 } });イベントのフラッシュ
Section titled “イベントのフラッシュ”トラックしたイベントはメモリにバッファされ、30 秒間隔、またはバッチが 100 件か 100 KB に達した時点のいずれか早いほうで自動的にフラッシュされます。 長時間動くゲームでは手動でフラッシュする必要はありません。
短命な実行やヘッドレス実行は、次の自動フラッシュより前に終了することがあります。
その場合は Flush() を明示的に呼び、送信が確認できるまでプロセスを生かしておいてください(詳細ログには HTTP の結果が出力されます)。
Flush() は非同期の送信を開始するだけで、最後の送出はプロセスの終了に合わせて行われます。
そのため、同じ行で終了せず、Flush() を呼んでから少し間を置いて終了してください。
Godot SDK 0.1.5 以降は、正常なシャットダウン時にバッファを同期的に排出します(上限 2.5 秒)。
オフラインキューはないため、この時間内に送信が失敗したイベントや、強制終了で残ったイベントは失われます。
詳細はトラブルシューティングを参照してください。
TelemetrySDK.Instance.Flush();プレイヤー識別子 (任意)
Section titled “プレイヤー識別子 (任意)”デフォルトではイベントは匿名で送信されます。ログイン後に 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_start、perf_heartbeat)はサンプリングの対象外です。
マップロード時間の計測
Section titled “マップロード時間の計測”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 の前は何もしません。
ディスク I/O メトリクス
Section titled “ディスク I/O メトリクス”Godot SDK 0.1.4 以降で利用できます。
SDK はディスク読み取りのカウンターを、io.read_bytes、io.read_time_ms、io.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);メモリカテゴリメトリクス
Section titled “メモリカテゴリメトリクス”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_heartbeat は map_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、タイムアウト)を意味します。
イベントが届かない場合はトラブルシューティングを参照してください。
ヘッドレス / CI
Section titled “ヘッドレス / CI”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 でビルドします。
dotnet buildコンパイルされたアセンブリは .godot/mono/temp/bin/Debug/ に生成されます。
プラグインは Initialize が自分で生成できる autoload を登録するだけなので、ヘッドレス実行ではエディター UI からプラグインを有効にする必要はありません。
イベントが届かない場合はトラブルシューティングを参照してください。
CI / 自動セッション
Section titled “CI / 自動セッション”自動テストやプロファイリング実行では、セッション全体にタグを付け、各イベントが 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_ID、FRAMEDASH_GIT_BRANCH、FRAMEDASH_GIT_COMMIT、FRAMEDASH_TEST_SCENARIO を読み取ります。
TelemetrySDK.Instance.BeginAutomatedSessionFromEnvironment();// ... 自動シナリオを実行する ...TelemetrySDK.Instance.EndAutomatedSession();自動セッションは、セッション内のすべてのイベントに build_id の上書きと ci.branch / ci.commit / ci.scenario 属性を付与します。
これがビルド比較(perf-diff)の CI ゲートに使われます。
イベントの source は変わりません。
SDK 自身の自動イベント(session_start、perf_heartbeat)は source=automated のまま、Track イベントは source=player のままで、これは CI でも通常のプレイでも同じです。
パイプライン全体は CI プロファイリング を参照してください。
次のステップ
Section titled “次のステップ”- データモデル: テレメトリデータの構造
- トラブルシューティング: イベントが表示されないとき
- ヒートマップ: 収集したデータの可視化