Steamworks ドキュメンテーション
Steam Matchmaking & Lobbies

概要

Steam のピアツーピアマッチメイキングはロビーの概念に基づいて構築されています。 ロビーはチャットルームのように Steam のバックエンドサーバー上に存在します。 ユーザーは新しいロビーの作成、ロビーとデータの関連付け、そのデータに基づいたロビーの検索、ロビーへの参加、ロビーで他のユーザーとの情報共有等を行うことができます。 1 つのロビーは最大 250 人までのユーザーを収容することができますが、ほとんどのゲームでロビーにいるユーザー数は、2 ~ 16 人です。 スキルベースのマッチメイキングはこのシステムを土台にして構築されています。

Steam のピアツーピアマッチメーキング API はユーザーが一緒にプレイする相手を探すための関数セットです。 マッチメイキング関数はすべて ISteamMatchmaking に含まれ、各関数のパラメーターについての詳細が記述されています。 ロビーはユーザーやゲーム サーバーのように、1 つの SteamID により識別されます。 Steamworks の事例にはロビーの完全実装例が含まれています。

マッチメイキングプロセスの流れ

一緒にプレイするグループを作成する一般的なモデルは次の通りです。
  1. ユーザーがゲーム内でマルチプレイヤーでのプレイとマルチプレイヤーの種類 (ルール、シナリオ等) を選択します。
  2. ロビー検索 API を使用して、ゲームがルールのセットに類似性のあるロビーを検索します。
  3. ロビーが見つかると、ゲームはそのロビーに参加します。ロビーが見つからない場合、新しいロビーが作成されます。
  4. ゲームを開始するのに十分なプレイヤーが集まるまで、ユーザーはロビーで待機します。 ロビーメンバーの間で、プレイしたいキャラクターやユーザーごとの設定等のデータが通信されます。 ロビーで定めるべきルール (たとえば、あるキャラクターをプレイできるのは 1 人のみ等) がある場合、ロビー所有者のみが決定権を持ちます。
  5. ロビーと関連したユーザーインターフェイスが存在することがあります。存在する場合は、ロビーメンバー同士のチャットメッセージ送信にロビーデータ通信機能を使えます。 ボイスデータも送信できますが、その際は Steam ネットワーキング API の使用が必要です。
  6. ゲーム開始の準備ができると、すべてのユーザーはゲームサーバーに参加するか、ホストになるよう選出されたユーザーに接続し、その後ロビーを退出します。 すべてのユーザーがロビーを出ると、そのロビーは自動的に破棄されます。

ロビーの検索

ゲームにロビーを検索させるには、ISteamMatchmaking::RequestLobbyList を呼び出します。
この関数は非同期で、リクエストの状態を追跡する SteamAPICall_t ハンドルを返します。 ユーザーの Steam バックエンドの接続状況によりますが、この呼び出しには 300 ミリ秒から 5 秒かかり、タイムアウトは 20 秒です。
返される結果の数は LobbyMatchList_t 呼び出し結果に含まれ、次にISteamMatchmaking::GetLobbyByIndex を使用してすべてを反復処理し、それらの ID を取得します。
最大 50 までの結果を返すことができますが、通常は2、3程度です。 結果は設定されたフィルターで近いものを基準に、地理的距離順に返されます。 デフォルトで存在する唯一のフィルターは、既に満員になっているロビーは返さないというもので、距離フィルターは k_ELobbyDistanceFilterDefault (周辺) にセットされています。 フィルターの追加にはRequestLobbyListを呼び出す前に、一つ以上のフィルタ関数を呼び出す必要があります:

ロビーの作成

ユーザーが参加できる既存のロビーが見つからないときに、新しいロビーが作成されます。
ISteamMatchmaking::CreateLobby を呼び出して結果を待ちます。 呼び出し結果の成否に関わらず、LobbyCreated_t 構造体内のロビーの SteamID が返されます。その ID はロビーのメタデータの設定に使用できます。 ロビー作成後、まず最初に行うのは、他のゲームクライアントがそのロビーを探せるように、ロビーについてのデータを設定することです (以下参照)。

ロビーへの参加

検索またはフレンドを通して適切なロビーが見つかると、ISteamMatchmaking::JoinLobby を使い、LobbyEnter_t の呼び出し結果を待ちます。 ロビーに入ると、ロビーデータ API を使用して、ロビーについての詳細を取得し、表示内容を決定します (表示するものがある場合)。

ユーザーがロビーに参加またはロビーから退出する場合、LobbyChatUpdate_t コールバックがオーナーを含むロビー内すべてのメンバーに送信されます。

ロビー内のユーザーへの反復処理には以下を使用します:

ロビー内の別のユーザーについて情報を入手するには、フレンド API を使用します。詳細は フレンド、招待、ロビー を参照してください。

ロビーのメタデータ

ロビーのメタデータを使用すると、ロビーの名前、現在のマップ、ゲームモード、ゲームの現在の状態など、ロビーを自由に設定できます。

ユーザーは所属するロビーの最新データを自動的に入手します。 検索結果から返されたロビーでは、ユーザーは検索した時点でのロビーデータを入手します。 フレンドのロビーの場合は、ISteamMatchmaking::RequestLobbyData が呼び出され、完了するまではロビーデータを見ることはできません。

ロビーのデータに変更があると、すべてのロビーメンバーは LobbyDataUpdate_t コールバックを受け取ります。 (このコールバックは ISteamMatchmaking::RequestLobbyData コールが完了したことを知る方法と同じです。)

ロビーデータの入手または設定に使える関数があります。 ロビーデータを設定または削除できるのは、ロビーオーナーのみです。

メタデータの反復処理に使用する関数 (通常デバッグ用にのみ使用されます):

ロビーでは、他のメンバーが次の関数を使用して更新データを受信できるように、メンバーが独自のメタデータを設定することもできます。

ロビー内でのコミュニケーション

ロビー内で情報 (チャットメッセージ、ゲーム開始シグナル等) を送信するには、ISteamMatchmaking::SendLobbyChatMsg を呼び出してください。これはシンプルなバイナリメッセージをロビー内の全員に送信します。 ロビーメンバーは ISteamMatchmaking::LobbyChatMsg_t のコールバックを Listenする必要があります。 コールバックの受け取ってから、ISteamMatchmaking::GetLobbyChatEntry を使ってメッセージのコンテンツを取得できます。

フレンド、招待、ロビー

フレンド API を使ってフレンドが待機するロビーを見つけることができます:
int cFriends = SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); for ( int i = 0; i < cFriends; i++ ) { FriendGameInfo_t friendGameInfo; CSteamID steamIDFriend = SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate ); if ( SteamFriends()->GetFriendGamePlayed( steamIDFriend, &friendGameInfo ) && friendGameInfo.m_steamIDLobby.IsValid() ) { // friendGameInfo.m_steamIDLobby は有効なロビーで、参加またはRequestLobbyData() を使用してメタデータの取得が可能 } }

ISteamMatchmaking::InviteUserToLobbyでフレンドをロビーに招待できます。
そのユーザーはゲームに参加するためのリンクを含むチャットダイアログを受け取ります。 ユーザーがリンクをクリックすると、ゲームを起動していない場合には次のコマンドラインによってゲームが起動します:
+connect_lobby <64-bit lobby id>. Be sure your app implements ISteamApps::GetLaunchCommandLine so you can disable the popup warning when launched via a command line.

If the user is already in a game, a ISteamFriends::GameLobbyJoinRequested_t callback will be posted, which contains the Steam ID of the lobby the user wishes to join. It's up to your game to decide to obey it or not.

If you want the user to select from a list of friends to invite to a lobby, you can call ISteamFriends::ActivateGameOverlayInviteDialog.
This will activate the Steam in-game overlay to a dialog designed for inviting friends to the current lobby.

認証

Any user in a Steam lobby is already fully authenticated with the Steam back-end. There is no need for the game to do any more authentication steps with lobby users, unless it's looking to see if they're VAC banned (see Valve Anti-Cheat Technology). If a user tries to log in from a second location with the same account, their prior login will automatically be removed from any existing lobbies.

クリーンアップ

Once the game has started, each user can just leave the lobby with:
ISteamMatchmaking::LeaveLobby
Once all the users have left, the lobby is automatically destroyed on the back-end.

ロビーのヒント

  • 一般的に、必要な時だけロビーを作成してください。 例えば、ユーザーがフレンドをプレイに招待した時や、ロビーを必要とする手動操作がトリガーされた時です。
  • ロビーのメタデータを高頻度で更新しないでください。 検索に使用されるメタデータと値のみを追加してください。(例えば、ゲームの種類やゲームの状態など) ロビー検索は、利用可能な空きのあるロビーだけを検索するようにできているのでプレイヤー数を入れる必要はありません。
  • メタデータを探すためだけにロビーに参加しないでください。 ロビーメタデータは、すべてのロビー毎に別々にダウンロードできます。ゲームはそれを使って、ロビーのリストをユーザーに表示して選択させる、ユーザーが参加するロビーをゲームが自動で検索結果から決定できます。

他にも質問がありますか?

Ask questions on the Steam Matchmaking & Lobbies discussion forum.