> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GDK と Steamworks の概念上の違い

> Steam からタイトルを移植する際に、GDK C API と Steamworks インターフェイスのシングルトンがコードをどのように構造化し、状態を管理し、ゲームの実行方法を期待するかを比較します。

Steamworks と XBOX Game Development Kit (GDK) には、構造、API のパターン、目的に関して多くの違いがあります。このトピックではそれらを概説します。

## XBOX Game Development Kit (GDK) には API シングルトンがない

Steamworks は、各 API 機能セットがインターフェイスとして定義されるパターン（たとえば、すべてのユーザー統計関数は `ISteamUserStats` インターフェイスにあり、リモート ストレージは `ISteamRemoteStorage` にある）に従います。そのインスタンスは、API がコード内でゲームによって初期化されるとすぐに利用可能になります。ゲーム開始時に初期化される Steamworks API シングルトンがこれらの関数を提供し、アプリケーションの存続期間中の状態を追跡します。

これは、C API を好む XBOX Game Development Kit (GDK) API には当てはまりません。API データの多くのコンテキストと現在の状態は、ゲーム自体が保持し、さまざまな API 関数に渡す必要があります。たとえば、XBOX services でユーザーを認証した後、ゲームは XBOX services コンテキスト ハンドルとユーザー ハンドルを保持する必要があります。この情報を取得するために使用される API は、Steamworks のようにゲームの存続期間中それらを「記憶」しません。したがって、ゲーム クラスにメンバー変数を追加するか、ゲーム内でこれらのハンドルを追跡する必要があります。

## 非同期関数とコールバック

Steamworks の非同期関数は、`STEAM_CALLBACK` マクロまたは `CCallResult` 変数を使ってサブスクライブできるイベントをトリガーします。指定されたイベント構造体タイプに対応するイベントが発火すると、指定されたメソッドが呼び出され、イベント構造体が単一の引数として提供されます。この構造体には、API が返した結果と、呼び出しの結果を処理するために必要になる可能性のある事前に利用可能なコンテキスト情報が含まれます。たとえば、`ISteamUserStats::DownloadLeaderboardEntries` を呼び出すには、コールバック関数で `SteamLeaderboard_t` ハンドルが必要で、これを `ISteamUserStats::DownloadLeaderboardEntries` に渡します。これは、定義したコールバック メソッドにパラメーターとして渡される `LeaderboardScoresDownloaded_t` 構造体のメンバーとして取得できます。

XBOX Game Development Kit (GDK) では、すべての非同期アクションは異なるパターンに従います: [`XAsyncBlock`](/reference/system/xasync/xasync_members) 構造体を作成し、必要に応じてタスク キューに割り当て、次に非同期 API メソッドを呼び出します。その API 呼び出しが完了すると、[`XAsyncBlock`](/reference/system/xasync/xasync_members) のメンバーとして定義されたコールバック関数が発火し、非同期ブロックへのポインターが単一の引数として提供されます。コールバック関数内で情報にアクセスする必要がある場合、非同期ブロックのコンテキスト ポインター メンバーを使用してそれを行うことができます。Steam とは異なり、このコンテキスト構造体の情報は自動的には提供されません — 自分で構築する必要があります。前の例を使用して、コールバック関数内でデータのセットへのアクセスが必要な場合、次のコード例のように行うことができます。

```cpp theme={null}
MyClass::SimpleContextExample()
{
    // ...
    struct MyContext 
    {
        MyHandle_t handle;
        std::shared_ptr<MyClass> instance;
    }

    // myHandle が呼び出し関数で必要となるハンドルを含む変数と仮定します。
    auto contextPtr = std::unique_ptr<MyContext>(new MyContext{ myHandle, shared_from_this() });
    XAsyncBlock async = std::make_unique<XAsyncBlock>();
    async->context = contextPtr.get(); 
    async->callback = [](XAsyncBlock *async)
    {
        std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // XAsyncBlock* の所有権を引き継ぐ        
        std::unique_ptr<MyContext> contextPtr{ static_cast<MyContext*>(asyncBlock->context) }; // コンテキストの所有権を引き継ぐ。        

        auto handle = contextPtr->handle;
        // これで他の API 呼び出しにハンドルを使用できます。
    };

    HRESULT hr = SomeAsyncFunction(arg1, arg2, asyncBlock.get());
    if (SUCCEEDED(hr))
    {
        // 呼び出しが成功したので、コールバックが所有権を引き継ぐため、XAsyncBlock* と context* の 
        // std::unique_ptr の所有権を解放する。
        // 呼び出しが失敗した場合、std::unique_ptr は所有権を保持し、XAsyncBlock* と context ブロックを削除する。
        asyncBlock.release();
        contextPtr.release();
    }
}
```

<Note>
  前の例では、コールバック関数が必要に応じてインスタンス メソッドを呼び出したり、メンバー変数にアクセスしたりできるように、`shared_from_this()` を介して `this` へのポインターも含めています。存続期間の問題により、生ポインターを渡す際は非常に注意してください。また、コールバックで 1 つの変数へのアクセスのみが必要な場合、単純に非同期ブロックの `context` ポインターの値をその値へのポインターに設定し、構造体を定義する必要なく、コールバックでその値の型にキャストするだけで済むことにも注意してください。
</Note>

Steamworks はまた、`SteamAPI_RunCallbacks` 関数を使用して、ゲームのコードが一定の間隔でコールバックを発火することを要求します。これは XBOX Game Development Kit (GDK) では必要ありません。デフォルトのスレッド プール タスク キューを使用している場合、コールバックはタスク キューによってディスパッチされた非同期タスクが完了した後にトリガーされます。

より詳細な制御を行うには、手動タスク キューを使用する場合に `XTaskQueueDispatch` を呼び出して、非同期タスクを特定のスレッドに手動でディスパッチできます。これはより複雑で、これがどのように行われるかの詳細はこのガイドの範囲外です。コード サンプルを含む XBOX Game Development Kit (GDK) が非同期 API 操作をどのように処理するかの詳細については、[非同期プログラミング モデル](/build/core-features/common/async/async-programming-model) を参照してください。

## タイトル管理 API の Source of Truth

Steamworks では、API はそれに触れるほぼすべての値の単一の Source of Truth です。たとえば、ユーザー統計は API から取得され、`ISteamUserStats::GetStat`/`ISteamUserStats::SetStat` からの値に基づいて計算され、これらの値を自分で他のどこかに保存することは要求されません。

XBOX Game Development Kit (GDK) の実績と統計 / リーダーボード API はどちらも、より柔軟でシンプルな呼び出しを希望する開発者向けにタイトル管理のオプションを提供します。名前が示すように、タイトル管理 API の値はタイトルによって管理されます。これらの値の単一の Source of Truth はゲームであり、値をどこにでも（たとえば、セーブ ファイル、クラウド ストレージ、サード パーティのバックエンド サーバー）保存できます。XBOX network（XBOX Live とも呼ばれる）サーバーに保存された値は、時折更新するスナップショットとして使用できますが、実行時の単一の Source of Truth にすべきではありません。

タイトル管理の stats / achievements の代替オプションは、event-based stats / achievements です。これらはテレメトリ イベントを使用してユーザーの実績進行状況を更新したり、統計を再計算したりし、XBOX services を Source of Truth と見なします。stats と achievements にどの API を使用するかは、Partner Center のゲームの **Gameplay Setting** ページで選択できます。

これに関する詳細については、[Event-based と title-managed Stats](/services/xbox-services/player-data/stats-leaderboards/index) および [Event-based と title-managed Achievements](/services/xbox-services/player-data/achievements/index) を比較するトピックの説明を参照してください。これらの API は、以前の名前である *Stats/Achievements 2013 (event-based)* および *Stats/Achievements 2017 (title-managed)* で参照されることがあります。

## XBOX Game Development Kit (GDK) はマルチプラットフォーム

Steamworks API を利用するゲームは、常に Steam を通じて起動されると仮定できるため、API は初期化時にゲームをプレイしているのが誰かに関するコンテキストを注入できます。XBOX Game Development Kit (GDK) を使用するゲームは、XBOX コンソール上で実行されるゲーム、XBOX Gaming App を使用する PC 上、または任意の数のデバイスとランチャーで使用できます。

したがって、Steam で自動的に利用可能ないくつかのコンテキストは、XBOX Game Development Kit (GDK) では手動で初期化する必要がある場合があります（たとえば、ユーザーのアイデンティティ）。この情報にアクセスするには、このガイドの [GDK の初期化](/build/steam-porting-guide/initializing-the-gdk) トピックの手順に従うことができます。これは、Microsoft アカウント / ゲーマータグでユーザーを認証する手順を提供します。これはまた、XBOX Game Development Kit (GDK) の関数の中に、コンソール シナリオに合わせて調整されており、PC には類似のない、`XUser` API の複数ユーザー サインイン サポートのようなパラダイムがあることを意味します。

## パッケージ化

Steam のほとんどのゲームは、Steamworks 管理ポータルでゲーム情報を設定し、SDK をダウンロードし、必要なファイルをインポートし、コード内で API を初期化するだけで Steamworks API 関数を使用できます。これらの手順を行った後、ゲームは、ゲーム エンジン エディターなど、起動される場所から Steamworks API と統合されます。

XBOX Game Development Kit (GDK) API が動作するには、ゲームを最初にパッケージ化する必要があります。ゲームを正しくパッケージ化するには、ゲームの `MicrosoftGame.config` ファイルを編集し、XBOX Game Development Kit (GDK) の `MakePkg` ツールを使用してゲームの MSIXVC パッケージを作成する必要があります。これは、Developer Mode を有効にしている PC で Microsoft Store アプリとしてサイドロードできます。

これはまた、Steamworks ゲームとは異なり、XBOX Game Development Kit (GDK) 機能の一部は、ゲームをパッケージ化しない限り、ゲーム エンジン エディターやその他の開発時の環境では動作しないことを意味します。

パッケージ化の詳細については、以下のリソースを参照してください。

* [PC 向けパッケージングを始める](/build/core-features/common/packaging/overviews/packaging-getting-started-for-PC)
* [MicrosoftGame.config](/build/core-features/common/game-config/MicrosoftGameConfig-Overview)

## Unity ゲームの開発とテスト

Unity ゲーム エンジンでビルドされたゲームは、GDK Unity Plug-in を使用してタイトルを開発できます。このプラグインは、XBOX Game Development Kit (GDK) 提供品に含まれ、[XBOX Developer Downloads](https://aka.ms/gdkdl) ポータルにスタンドアロン アドインとしても提供されます。このプラグインには、ゲームの C# コードで XBOX Game Development Kit (GDK) 関数を呼び出せるようにする API ラッパーが含まれます。

GDK Unity Plug-in の詳細については、[PC 開発向け Unity を始める](/paths/unity/overview) を参照してください。


## Related topics

- [Steam 移植ガイド概要](/ja-jp/build/steam-porting-guide/overview.md)
- [Steam からの移植](/ja-jp/paths/porting/from-steam.md)
- [Stats と Achievements](/ja-jp/build/steam-porting-guide/features/stats-and-achievements.md)
- [Economy バージョン 2 (V2) の FAQ](/ja-jp/services/playfab/economy-monetization/economy-v2/faq.md)
- [イベントの概要](/ja-jp/services/xbox-services/player-data/stats-leaderboards/event-based/events/live-game-events.md)
