次の方法で共有


マルチプレイヤー タスク

このトピックでは、2015 マルチプレイヤーの使用に関連する特定のタスクを実装する方法について説明します。

このトピックでは、以下の内容を説明します。

マルチプレイヤー セッション ディレクトリ(MPSD) セッション変更通知をサブスクライブする

注意

セッションの変更をサブスクライブするには、関連付けられているプレイヤーがセッションでアクティブであることが必要です。 セッションの /constants/system/capabilities オブジェクトでは、connectionRequiredForActiveMembers フィールドも true に設定する必要があります。 このフィールドは、通常、セッション テンプレートで設定します。 詳細については、「マルチプレイヤー セッション テンプレート」と「マルチプレイヤー セッション ディレクトリの概要」を参照してください。

MPSD セッション変更通知を受信するには、タイトルで次の手順に従います。

  1. 同じユーザーが行うすべての呼び出しに、同じ XblContextHandle オブジェクトを使用します。 サブスクリプションは、このオブジェクトの有効期間に関係します。 ローカル ユーザーが複数いる場合は、各ユーザーに対して個別の XblContextHandle オブジェクトを使用します。

  2. XblMultiplayerAddSessionChangedHandlerXblMultiplayerSessionSubscriptionLostHandlerのイベント ハンドラーを実装します。

  3. 複数のユーザーの変更をサブスクライブする場合は、不要な作業を避けるためのコードを XblMultiplayerAddSessionChangedHandler イベント ハンドラーに追加します。 XblMultiplayerSessionChangeEventArgs::Branch プロパティと XblMultiplayerSessionChangeEventArgs::ChangeNumber プロパティを使用します。 これらのプロパティを使用すると、最後に表示された変更を追跡し、それ以前の変更を無視できます。

  4. XblMultiplayerSetSubscriptionsEnabled を呼び出して、サブスクリプションを許可します。

  5. ローカル MPSD セッション オブジェクトを作成し、その後でそのセッションをアクティブとして参加させます。

  6. XblMultiplayerAddSessionChangedHandler に各ユーザーの呼び出しを行います。通知するセッション変更の種類を指定します。

  7. このトピックの「MPSD セッションの更新」セクションの説明に従って、セッションを MPSD に書き込みます。

次のフロー チャートは、前の手順で説明したイベントをサブスクライブしてマルチプレイヤーを開始する方法を示しています。

前の手順で説明したイベントをサブスクライブしてマルチプレイヤーを開始する方法を示すフロー チャートの画像。

重複するセッション変更通知の解析

同じセッションの通知をサブスクライブしている複数のユーザーがいる場合、そのセッションに変更を加えるたびに、各ユーザーのショルダー タップがトリガーされます。 これらのショルダー タップの 1 つを除いてすべてが重複しています。

タイトルは、セッション内のすべてのユーザーに通知をサブスクライブすることをお勧めしますが、タイトルは、すでに通知されている変更を無視する必要があります。 これを行うには、Branch プロパティと ChangeNumber プロパティを使用します。

複数のショルダー タップを検出するには、次のようにします。

  • 評価された各 Branch プロパティ値の最新の ChangeNumber プロパティ値を保存します。

  • ショルダー タップの ChangeNumber プロパティ値がその Branch プロパティ値の最新の保存値よりも高い場合は、ショルダー タップを処理してから、最新の ChangeNumber プロパティ値を更新します。

  • ショルダー タップに、その Branch プロパティ値に対してより高い ChangeNumber プロパティ値がない場合は、ショルダー タップの処理をスキップします。 この変更は既に処理されています。

注意

ChangeNumber プロパティ値は、セッションではなくプロパティ値によって Branch 追跡する必要があります。 Branch プロパティ値は、セッションの存続期間内に変更され、ChangeNumber プロパティ値をリセットできます。

このトピックの先頭に戻る。

MPSD セッションの作成

注意

既定では、最初のメンバーが参加したときに MPSD セッションが作成されます。 タイトル ロジックが参加時にタイトルが存在するか存在しないかを予期している場合は、セッション更新時に適切な書き込みモードの値を書き込みメソッドに渡すことができます。

タイトルは、新しいセッションを作成するために次のことを行う必要があります。

  1. 新しいXblContextHandle オブジェクトを作成します。 タイトルは、このオブジェクトを 1 回作成し、保存して、ソース コード全体の必要に応じて再利用します。 特にセッションサブスクリプションを使用する場合は、まったく同じコンテキストを使用する必要があります。

  2. XblMultiplayerSessionCreateHandle を使用して新しいXblMultiplayerSessionHandleを作成し、MPSD が新しいセッションを作成するために必要なすべてのセッション データを準備します。

  3. セッションを MPSD に書き込む前に、必要な変更を行います。 たとえば、XblMultiplayerSessionJoin への呼び出しを使用して、メンバーがセッションに参加する場合、クライアントは、要求を更新するために呼び出し時に参加するように MPSD に通知する隠しローカル要求データを追加します。

  4. ローカルでの変更が終了したら、このトピックの「MPSD セッションの更新」セクションの説明に従って MPSD に書き込みます。

  5. MPSD から新しい XblMultiplayerSessionHandle オブジェクトを受け取り、多くのフィールドに入力します。

  6. 今後は新しいセッション オブジェクトを使用してください。 新しいセッションを作成するための非表示の要求を含む古いコピーを破棄します。

フラット C API

auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*.

    XblMultiplayerSessionHandle sessionHandle;
    HRESULT hr = XblMultiplayerWriteSessionResult(asyncBlock, &sessionHandle);
    if (SUCCEEDED(hr))
    {
        // Process multiplayer session handle.
    }
    else
    {
        // Handle failure.
    }
};

XblMultiplayerSessionReference ref;
pal::strcpy(ref.Scid, sizeof(ref.Scid), SCID);
pal::strcpy(ref.SessionTemplateName, sizeof(ref.SessionTemplateName), SESSION_TEMPLATE_NAME);
pal::strcpy(ref.SessionName, sizeof(ref.SessionName), SESSION_NAME);

XblMultiplayerSessionInitArgs args = {};

XblMultiplayerSessionHandle sessionHandle = XblMultiplayerSessionCreateHandle(XUID, &ref, &args);

auto hr = XblMultiplayerSessionJoin(
    sessionHandle,
    memberCustomConstantsJson.c_str(),
    initializeRequested,
    joinWithActiveStatus);
    
 hr = XblMultiplayerWriteSessionAsync(xblContextHandle, sessionHandle, XblMultiplayerSessionWriteMode::CreateNew, asyncBlock.get());
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
    // If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
    asyncBlock.release();
}

詳細については、以下を参照してください。

このトピックの先頭に戻る。

MPSD セッションのアービターを設定する

タイトルは、次の手順を使用して、作成済みのセッションのアービターを設定します。

注意

メンバーがセッションに参加して、そのユーザーのセキュリティで保護されたデバイス アドレスを含めるまで、メンバー (ホスト候補) のデバイス トークンは利用できません。

  1. MPSD からホスト候補用のデバイス トークンを取得するには XblMultiplayerSessionMembersを呼び出します。

    注意

    セッションが SmartMatch マッチメイキングによって作成された場合、クライアントは MPSD から使用可能なホスト候補を使用して XblMultiplayerSessionHostCandidates を呼び出すことができます。

  2. ホスト候補のリストから必要なホストを選択します。

  3. MPSD のローカル キャッシュにデバイス トークンを設定するには XblMultiplayerSessionSetHostDeviceToken を呼び出します。 ホスト デバイス トークンを設定する呼び出しが成功すると、ローカル デバイスのトークンがホストのトークンに置き換わります。

  4. ホスト デバイス トークンを設定しようとしたときに HTTP/412 ステータス コードを受信した場合は、セッション データをクエリします。 ホスト デバイス トークンがローカル コンソール用であるかどうかを確認します。 ローカル本体用でない場合は、別の本体がアービターとして指定されています。

    注意

    HTTP/412 は標準的なエラーを示していないので、クライアントはその他の HTTP コードとは切り離して HTTP/412 ステータス コードを処理する必要があります。 このステータス コードの詳細については、「マルチプレイヤー セッション ステータス コード」を参照してください。

  5. このトピックの「MPSD セッションの更新」セクションの説明に従って、セッションを MPSD のセッションを更新します。

    注意

    より良いアルゴリズムがない場合、クライアントでは、他にホストが設定されていない場合に、各ホストが自分自身をホストとして設定しようとする greedy algorithm (貪欲法) を実装できます。 詳細については、「マルチプレイヤー セッションの高度なトピック」の「セッション アービター」セクションを参照してください。

このトピックの先頭に戻る。

タイトルのライセンス認証を管理する

Xbox One (以降) では、プロトコルのアクティブ化中に CoreApplicationView.Activated イベントが発生します。 マルチプレイヤー API のコンテキストでは、ユーザーが招待を承諾するか、他のユーザーに参加したときに、このイベントが発生します。 これらのアクションは、参加するユーザーをターゲット ユーザーとのゲームプレイに加えることにより、タイトルが対応する必要があるアクティベーションをトリガーします。

注意

タイトルでは常に新しいアクティベーション引数を予期する必要があり、長さに関するコーディングを行わないようにする必要があります。

タイトルのライセンス認証を行うには、次の主な手順を実行する必要があります。

  1. CoreApplicationView.Activated イベントのイベント ハンドラーをセットアップします。 このハンドラーは、タイトルが既に実行されている場合でも、プロトコルのアクティブ化が発生するたびにトリガーされます。

  2. タイトルのライセンス認証で、セッションを開始し、セッション変更通知を購読します。 詳細については、このトピックの「MPSD セッション変更通知のサブスクライブ」を参照してください。

  3. アクティブなユーザーとしてセッションに参加します。 詳細については、このトピックの「タイトルのアクティブ化から MPSD セッションに参加する」を参照してください。

  4. プロファイル UI を使用して表示されるアクティビティ セッションとしてロビー セッションを設定します。 詳細については、このトピックの「ユーザーの現在のアクティビティを設定する」を参照してください。

  5. ユーザーをアクティブとしてゲーム セッションに参加させます。 これで、ユーザーはピアに接続してゲームプレイまたはロビーに入ることができます。

次のフロー チャートは、タイトルのアクティブ化を処理する方法を示しています。

タイトルのアクティブ化を処理する方法を示すフロー チャートの画像。

このトピックの先頭に戻る。

ユーザーを参加可能にする

ユーザーを参加可能にするには、タイトルで次の手順を行う必要があります。

  1. セッション オブジェクトを作成し、必要に応じて属性を変更します。

  2. アクティブなユーザーとしてセッションに参加します。 詳細については、このトピックの「タイトルのアクティブ化から MPSD セッションに参加する」を参照してください。

  3. ユーザーがセッション アービターに指定されているかどうかを確認します。

  4. ユーザーがアービターではない場合は、手順 7 に進みます。

  5. ユーザーがアービターの場合は XblMultiplayerSessionSetHostDeviceToken を呼び出します。

  6. XblMultiplayerWriteSessionAsyncの呼び出しを使用して、セッションの書き込みを試行します。

  7. セッションをアクティブなセッションとして設定します。 詳細については、このトピックの「ユーザーの現在のアクティビティを設定する」を参照してください。

次のフロー チャートは、ゲーム中にユーザーが他のプレイヤーに参加できるようにするための手順を示しています。

ゲーム中にユーザーが他のプレイヤーに参加できるようにするための手順を示すフロー チャートの画像。

このトピックの先頭に戻る。

ゲームへの招待を送信する

タイトルでは、次の方法でプレイヤーがゲームへの招待を送信することを可能にできます。

  • ロビー セッションの招待を送信する。
  • 一般的な Xbox プラットフォームの招待 UI を使用して、ゲーム セッションの参照と共に招待を送信します。

プレイヤーにゲームへの招待を送信するには、タイトルで次の手順を行う必要があります。

  1. 招待しているゲーム プレーヤーを参加可能にします。 詳細については、「このトピックでユーザーを参加可能にする」を参照してください。

  2. ロビー セッション経由、または invite UI を使用して、招待を送信するかどうかを決定します。

  3. ロビー セッションを使用している場合は、XblMultiplayerSendInvitesAsyncの呼び出しを使用して招待を送信します。 このメソッドでは、XGameUiShowPlayerPickerAsyncを呼び出してゲーム内 UI 名簿を作成する必要がある場合があります。

  4. Invite UI を使用している場合は XGameUiShowSendGameInviteAsync を呼び出して、招待 UI を表示します。

  5. リモート プレーヤーが参加した後に、ローカル プレーヤーの XblMultiplayerAddSessionChangedHandler を処理します。

  6. リモート プレーヤーには、タイトルのライセンス認証コードを実装します。 詳細については、このトピックの「タイトルのアクティブ化を管理する」を参照してください。

次のフロー チャートは、招待を送信する方法を例示しています。

招待状の送信方法を示すフロー チャートの画像。

このトピックの先頭に戻る。

ロビー セッションからゲーム セッションへの参加

Windows 10 デバイスのゲームプレイ セッションが大きいセッションではない場合は、trueuserAuthorizationStyle 機能が設定されている必要があります。 その結果、joinRestriction プロパティを none にすることはできません。つまり、セッションを直接公開に参加させることはできません。

一般的なシナリオでは、ロビー セッションを作成してプレイヤーを集め、それらのプレイヤーをゲームプレイ セッションまたはマッチメイキング セッションに移動します。 ただし、ゲームプレイ セッションが公開されていない場合、ゲーム クライアントは joinRestriction 設定を満たさない限りゲームプレイ セッションに参加できません。 ほとんどの場合、このシナリオには制限が厳しすぎます。

これを解決するには、転送ハンドルを使ってロビー セッションとゲーム セッションをリンクします。 この操作を行うには、次の操作を行います。

  1. ゲーム セッションを作成するときに、XblMultiplayerSetTransferHandleAsync API を使用して、ロビー セッションとゲーム セッションをリンクする転送ハンドルを作成します。

  2. 転送ハンドルの GUID を、ゲーム セッションのセッションの参照の代わりにロビー セッションに格納します。

  3. タイトルがロビー セッションからゲーム セッションにメンバーを移動する必要がある場合、各クライアントはロビー セッションの転送ハンドルを使用して、XblMultiplayerWriteSessionByHandleAsync API 使用のゲーム セッションに参加します。

  4. MPSD は、ロビー セッションを検索し、転送ハンドルを使ってゲーム セッションに参加しようとしているユーザーがロビー セッションにも存在することを確認します。

  5. ロビー セッションに存在するメンバーであれば、ゲーム セッションにアクセスできます。

このトピックの先頭に戻る。

タイトルのアクティベーションからの MPSD セッションへの参加

ユーザーが Xbox シェル UI を使用してフレンドのアクティビティに参加する、または招待を受け入れることを選択すると、タイトルは、ユーザーが参加を希望するセッションを示すパラメーターを使ってアクティブ化されます。 タイトルは、このアクティベーションを処理し、対応するセッションにユーザーを追加する必要があります。

タイトルの手順は次のとおりです。

  1. CoreApplicationView.Activated イベントのイベント ハンドラーを実装します。 これは、タイトルのライセンス認証を通知します。

  2. ハンドラーが起動したら、IActivatedEventArgs.Kind プロパティを確認します。 Protocol に設定されている場合は、イベント引数を ProtocolActivatedEventArgs クラスにキャストします。

  3. ProtocolActivatedEventArgs オブジェクトを検査します。 ProtocolActivatedEventArgs.Uriプ ロパティに示されている URI が inviteHandleAccept(受け入れられた招待に対応) または activityHandleJoin(シェル UI を介した結合に対応) のいずれかに一致する場合、URI のクエリ文字列を解析します。 これは、キーと値のペアを持つ通常の URI クエリ文字列としてフォーマットされ、次のフィールドを抽出します。

    • 招待を承諾した場合:
      1. handle
      2. invitedXuid
      3. senderXuid
    • 参加の場合:
      1. handle
      2. joinerXuid
      3. joineeXuid
  4. XblMultiplayerSetSubscriptionsEnabled のを含める必要がある、タイトルのマルチ プレーヤー コードを開始します。

  5. ローカル XblMultiplayerSessionHandle オブジェクトを作成するには XblMultiplayerSessionCreateHandleを呼び出します。

  6. セッションに参加するには XblMultiplayerSessionJoin を呼び出します。 参加をアクティブに設定するには、次のパラメーター設定を使用します。

    • memberCustomConstantsJson = null
    • initializeRequested = false
    • joinWithActiveStatus = true
  7. 参加後、セッションが変更されたときにタップして XblMultiplayerSessionSetSessionChangeSubscription を呼び出します。

  8. 手順 3 に記載されているとおり、取得したハンドルを使用して XblMultiplayerWriteSessionByHandleAsync を呼び出します。 ユーザーがセッションのメンバーになり、セッションのデータを使用してゲームに接続できるようになりました。

このトピックの先頭に戻る。

ユーザーの現在のアクティビティの設定

ユーザーの現在のアクティビティは、タイトルの Xbox ダッシュボードのユーザー エクスペリエンスに表示されます。 ユーザーのアクティビティは、セッションまたはタイトルのアクティベーションを通じて設定できます。 後者の場合、ユーザーはマッチメイキングを通じて、またはゲームを起動してセッションを開始します。

注意

セッションを介して設定されたアクティビティは、XblMultiplayerClearActivityAsyncを呼び出すことで削除できます。

ユーザーの現在のアクティビティとしてセッションを設定するには、タイトルが XblMultiplayerSetActivityAsyncを呼び出します。 これはセッションのセッション参照を渡します。

タイトルのライセンス認証を使用してユーザーの現在のアクティビティを設定する方法については、このトピックの「タイトルのアクティブ化から MPSD セッションに参加する」を参照してください。

このトピックの先頭に戻る。

MPSD セッションの更新

注意

タイトルがマルチプレイヤー API を使用して既存のセッションを更新する場合は、セッションの書き込みを呼び出すまで、ローカル コピーを扱うことになるので注意してください。

既存のセッションを更新するには、タイトルは次の条件を満たす必要があります。

  1. 必要に応じて現在のセッションに変更を加えます。たとえば、XblMultiplayerSessionLeaveを呼び出します。

  2. すべての変更が完了したら、次のいずれかの方法を使用して、ローカルの変更を MPSD に書き込みます。

    他のタイトルも変更できる共有部分に書き込むには、書き込みモードを XblMultiplayerSessionWriteMode::SynchronizedUpdate に設定します。 詳細については、「マルチプレイヤー セッション ディレクトリ」の概要トピックの「セッション更新の同期」セクションを参照してください。

    書き込みメソッドは参加をサーバーに書き込み、最新のセッションを取得して、そのセッションから他のセッション メンバーと本体のセキュア デバイス アドレス (SDA) を検出します。 これらの本体間でネットワーク接続を確立する方法の詳細については、「Xbox One の Winsock の概要」を参照してください。

  3. 古いローカル セッション オブジェクトを破棄します。 最新の既知のセッション状態に基づいて今後の処理を実行できるように、新たに取得したセッション オブジェクトを使用します。

このトピックの先頭に戻る。

MPSD セッションからの退出

ユーザーがセッションを終了できるようにするには、タイトルで次に追従する必要があります。

  1. ゲーム セッションのXblMultiplayerSessionLeave を呼び出します。

  2. このトピックの「MPSD セッションの更新」セクションの説明に従って、ゲーム セッションを MPSD のセッションを更新します。

  3. 必要に応じて、ロビー セッションの XblMultiplayerSessionLeave メソッドを呼び出し、そのセッションを更新します。

  4. ロビー セッションが必要な場合は、 XblMultiplayerRemoveSubscriptionLostHandlerXblMultiplayerRemoveSessionChangedHandlerを呼び出して、マルチプレイヤー API をシャット ダウンします。

次のフロー チャートは、セッションを終了してマルチプレイヤーをシャット ダウンする方法を示しています。

セッションを終了してマルチプレイヤーをシャット ダウンする方法を示すフロー チャートの画像。

このトピックの先頭に戻る。

マッチメイキング中に空きセッション スロットを埋める

マッチメイキング中にチケット セッションの空きスロットを埋めるには、タイトルで次のような手順に従う必要があります。

  1. マッチメイキング中に作成されたチケット セッションの最新のセッション状態にアクセスします。

  2. ロビー セッションからゲーム プレイに参加可能なプレイヤーを追加します。

  3. チケット セッションがいっぱいになっているかどうかを確認します。

  4. セッションがいっぱいの場合は、ゲームプレイを続けます。

  5. セッションがまだいっぱいでない場合は、このトピックのマッチ チケットの作成の説明に従って、マッチ チケットを作成します。 必ず、preserveSession パラメータを Always に設定してチケットを作成してください。

  6. マッチメイキングを続行します。 詳細については、「マッチメイキングの概要」を参照してください。

次のフロー チャートは、マッチメイキング中に空きセッション スロットを埋める方法を示します。

マッチメイキング中に空きセッション スロットを埋める方法を示す画像。

このトピックの先頭に戻る。

マッチ チケットを作成する

マッチ チケットを作成するには、マッチメイキング スカウトが次の条件を満たしている必要があります。

  1. スカウトは XblMatchmakingCreateMatchTicketAsync を呼び出し、チケット セッションの参照を渡します。 このメソッドは、MPSD のチケットセッションを読み取り、そのセッションのユーザーのマッチメイキングを開始します。 内部では、POST (/serviceconfigs/{scid}/hoppers/{hoppername})を呼び出します。

  2. マッチメイキング サービスがセッションのメンバーを新しいセッションまたは別の既存のセッションにマッチングする場合は、preserveSession パラメーターを Never に設定します。 タイトルがゲーム プレイを続行するためのチケット セッションとして既存のゲーム セッションを再利用できるようにするには、preserveSession パラメーターを Always に設定します。 マッチメイキング サービスは、送信されたセッションが保持され、一致したプレーヤーがそのセッションに追加されるようにします。

  3. CreateMatchTicketResponse オブジェクトで返された XblCreateMatchTicketResponse::EstimatedWaitTime を使用して、ユーザーによる、マッチメイキングの時間を設定します。

  4. 必要に応じて、応答オブジェクトで返却される XblCreateMatchTicketResponse::MatchTicketId を使用し、チケットを削除することで、セッションのマッチメイキングをキャンセルします。 チケットの削除には XblMatchmakingDeleteMatchTicketAsyncを使用します。

このトピックの先頭に戻る。

マッチ チケットの状態の取得

マッチ チケットの状態を取得するには、次を追従する必要があります。

  1. チケットセッションの XblMultiplayerSessionHandle オブジェクトを取得します。

  2. マッチメイキングで使用された XblMultiplayerMatchmakingServer オブジェクトにアクセスするには XblMultiplayerSessionMatchmakingServer を呼び出します。

  3. 一致するものが見つかった場合、XblMultiplayerMatchmakingServer オブジェクトをチェックして、マッチメイキング プロセスのステータス、セッションの標準的な待機時間、およびターゲット セッションの参照を特定します。