Boltのマッチメイキング
Photon Boltはネットワークゲーム開発の高水準SDKです。このようなソリューションにおける主な機能の1つに、マッチメイキング性能があります。言い換えれば、離れた場所にいたり、異なるデバイスのプレイヤー同士が一緒に遊べるように、オンラインセッションで繋げる処理を行うことができるということです。
Boltでもそれは変わらず、一連のシンプルかつパワフルなAPIを提供してルームの管理を行い、複数のプレイヤーが参加し一緒にプレイできるゲームルームを維持するゲームを簡単に開発者が作成できるようにしています。
Photon Bolt
におけるマッチメイキング性能の主なAPIエントリは、Bolt.Matchmaking.BoltMatchmaking
クラスを通して使用されます。
Boltセッションの管理、Photon Cloudサービスを使用したゲームルームの作成と参加を処理しています。
このドキュメントでは、BoltMatchmaking
ユーティリティクラスを使用した開始の方法を説明しています。
こちらから、APIリファレンスも参照ください。
BoltマッチメイキングAPI
BoltMatchmaking.CurrentSession
: このピアが接続している現在のセッションを取得します。BoltMatchmaking.CreateSession(string sessionID, IProtocolToken token, string sceneToLoad)
: 現在実行中のプラットフォームを使用してセッションを作成します。BoltMatchmaking.UpdateSession(IProtocolToken token)
: 現在のセッション設定をアップデートします。BoltMatchmaking.JoinSession(UdpSession session, IProtocolToken token)
: リファレンスとしてUdpSession
を使用しセッションに参加します。BoltMatchmaking.JoinSession(string sessionID, IProtocolToken token)
: 名前でセッションに参加します。BoltMatchmaking.JoinRandomSession(IProtocolToken token)
: ランダムにセッションに参加します。BoltMatchmaking.JoinRandomSession(UdpSessionFilter sessionFilter, IProtocolToken token)
: フィルターつきでランダムにセッションに参加します。
現在のセッションを取得する
ピアが接続している現在のルームの確認は、カスタムプロパティもしくは何らかの追加情報などを探している場合、実用的なルーティーンとなります。このデータはBoltMatchmaking.CurrentSession
を通して開示され、呼び出だされるのはセッションに接続した後のみである必要があります。
以下はこの情報の取得方法例です。
C#
using Bolt.Matchmaking;
// ...
void Update()
{
if (Input.GetKeyDown(KeyCode.I) && BoltNetwork.IsRunning)
{
var session = BoltMatchmaking.CurrentSession;
BoltLog.Warn(session.HostName);
var photonSession = session as PhotonSession;
if (photonSession != null)
{
BoltLog.Warn("IsOpen: {0}, IsVisible: {1}", photonSession.IsOpen, photonSession.IsVisible);
foreach(var key in photonSession.Properties.Keys)
{
BoltLog.Warn("{0} = {1}", key, photonSession.Properties[key]);
}
}
}
}
// ...
セッションを作成しアップデートする
マッチメイキングは、ルームの作成が開始地点です。セッションがなければ、ゲームは始まりません。
Photon Boltでは、サーバークライアント間アーキタイプを使用しています。このアーキタイプではサーバーがゲームの実行の管理、クライアント間のデータ交換を行い、セッションの公開をすることで他のプレイヤーが参加できるようになります。
セッションを作成するには、以下のようにBoltMatchmaking.CreateSession
を呼び出します。
C#
// ...
void SetupSession(string map, int gameType)
{
if (BoltNetwork.IsServer)
{
string matchName = Guid.NewGuid().ToString();
// If you use Photon custom properties
var customToken = new Bolt.Photon.PhotonRoomProperties();
customToken.AddRoomProperty("m", map);
customToken.AddRoomProperty("t", gameType);
// Or if you use your own custom IProtocolToken
var customToken = new MyServerToken();
customToken.map = map;
customToken.gameType = gameType;
BoltMatchmaking.CreateSession(
sessionID: matchName,
sceneToLoad: map,
token: customToken
);
}
else
{
BoltLog.Warn("Only the server can create sessions");
}
}
// ...
ゲームのプレイ中、サーバーはセッションに関連するメタデータの更新も行うことができます。
ゲームをプレイしているクライアントやマッチングに参加する可能性のあるその他のクライアントがパブリックに使用することのできる、現在のゲームの一般設定を共有する場合に有用です。
このセッション情報をアップデートするには、BoltMatchmaking.UpdateSession
を呼び出すだけです。以下を参照してください。
C#
// ...
void UpdateSession(string map, int gameType)
{
if (BoltNetwork.IsRunning && BoltNetwork.IsServer)
{
// If you use Photon custom properties
var updateToken = new PhotonRoomProperties();
updateToken.AddRoomProperty("m", map);
updateToken.AddRoomProperty("t", gameType);
// Or if you use your own custom IProtocolToken
var updateToken = new MyServerToken();
updateToken.map = map;
updateToken.gameType = gameType;
BoltMatchmaking.UpdateSession(updateToken);
}
else
{
BoltLog.Warn("Only the server can update sessions");
}
}
// ...
セッションに参加する
マッチメイキングプロセスはクライアントが参加するセッションを探しているときに実行します。
Photon Boltでは provides a variate of way to do this. 以下で、より多くのプレイヤー数でより楽しくゲームを遊んでもらうように導入したすべての方法論について説明します。
UdpSession
をリファレンスとして使用し参加する
他のゲームセッションに接続する一番基本的な方法です。 When implementing a Bolt.GlobalEventListener
を実装する場合、使用できるセッションのリストが更新されるたびに呼び出されるSessionListUpdated(Map<Guid, UdpSession> sessionList)
コールバック関数へのアクセスを取得します。
この方法では、セッションにあらゆる種類のフィルタリングをかけられます。クライアントにどのように表示するか、完全に自由に決めることができます。
UdpSession
リファレンスを使用して、BoltMatchmaking.JoinSession
を呼び出し、任意でIProtocolToken
をパスして接続処理の間に使用されるようにします。
C#
public class Menu : Bolt.GlobalEventListener
{
// ...
public override void SessionListUpdated(Map<Guid, UdpSession> sessionList)
{
Debug.LogFormat("Session list updated: {0} total sessions", sessionList.Count);
foreach (var session in sessionList)
{
UdpSession photonSession = session.Value as UdpSession;
// Photon Session
PhotonSession photonSession = udpSession as PhotonSession;
if (photonSession != null)
{
// Those custom data comes from the PhotonRoomProperties Token
object value_t = -1;
object value_m = -1;
if (photonSession.Properties.ContainsKey("t"))
{
value_t = photonSession.Properties["t"];
}
if (photonSession.Properties.ContainsKey("m"))
{
value_m = photonSession.Properties["m"];
}
BoltLog.Info("Joining Session with custom data {0}/{1}", value_t, value_m)
}
// Optional IProtocolToken
var userToken = new UserToken();
userToken.user = "user";
userToken.password = "secret";
BoltMatchmaking.JoinSession(photonSession, userToken);
}
}
// ...
}
セッション名で参加する
Photon Boltはまた、クライアントが識別子(サーバー上でセッションを作成するのに使用したのと同じID)を利用してルームに参加するのをサポートしています。
ある状況では、クライアントは追加されるセッションのリストを待たずに、入るゲームを探す場合もあります。例えば「フレンドを招待する」システムを実装済みまたは使用している場合、これが解決策となるでしょう。
このような方法でセッションに接続することは、特定のゲームに参加する一番手軽な代替案となります。
これはBoltMatchmaking.JoinSession
のオーバーロードで、UdpSession
を受信する代わりに、ルーム識別子を含んだ文字列を受信します。IProtocolTokenを
受信することもできます。
以下の例を参照してください。
C#
// ...
void JoinSession(string sessionID, string user, string password)
{
if (BoltNetwork.IsRunning && BoltNetwork.IsClient)
{
var userToken = new UserToken();
userToken.user = user;
userToken.password = password;
BoltMatchmaking.JoinSession(sessionID, userToken);
}
else
{
BoltLog.Warn("Only a started client can join sessions");
}
}
// ...
ランダムにセッションに参加する
一部のカジュアルゲームではゲームプレイにほんの何通りかのバリエーションしかなく、プレイヤーはできるだけ早くゲームに参加したいと思っています。
そのような場合、タスクの遂行としてランダムセッションへの参加は面白いアプローチになります。
BoltMatchmaking.JoinRandomSession
メソッドを使用すると、Photon Boltは、できるだけ早く ルームを埋めようとしながら、入れるセッションのどれかへの参加を試みます。
残りの Join
手順と同じパターンに従ってIProtocolToken
オブジェクトをオペレーションにパスする選択肢もあります。
C#
void JoinRandomSession(string user, string password)
{
if (BoltNetwork.IsRunning && BoltNetwork.IsClient)
{
var userToken = new UserToken();
userToken.user = user;
userToken.password = password;
BoltMatchmaking.JoinRandomSession(userToken);
}
else
{
BoltLog.Warn("Only a started client can join sessions");
}
}
重要なこととして、参加できるルームがなかった場合、Room Join Timeout
値(Bolt Settings
で設定可能)のあとにこのプロセスは機能しなくなり、Bolt.GlobalEventListener.SessionConnectFailed()
コールバックが呼び出されます。
フィルターつきでランダムにセッションに参加する
BoltMatchmaking.JoinRandomSession
機能の拡張版です。UdpSessionFilter
クラスのインスタンスを受信するオーバーロードメソッドも含んでいます。
このオブジェクトはランダム参加のプロセス制御に使用され、ユーザーにfillモード選択を許可し (詳細は こちら)、カスタムパラメータを使用して参加できるルームをフィルタリングします。
このメソッドを使用して参加した場合、フィルターが正常に動作するにはBolt.Photon.PhotonRoomProperties
をトークンとして使用し、カスタムプロパティを使用してセッションを作成する 必要がある ことに注意してください。
以下は、パラメータに基づき、またIProtocolToken
を使用してデータをクライアントからサーバーに運ぶランダムセッションの簡単なサンプルです。
C#
void JoinRandomSession(string user, string password, string map, int gameType)
{
if (BoltNetwork.IsRunning && BoltNetwork.IsClient)
{
var userToken = new UserToken();
userToken.user = user;
userToken.password = password;
UdpSessionFilter filter = new UdpSessionFilter();
filter.FillMode = UdpSessionFillMode.Random; // Fill, Random or Serial
filter["m"] = map;
filter["t"] = gameType;
BoltMatchmaking.JoinRandomSession(filter, userToken);
}
else
{
BoltLog.Warn("Only a started client can join sessions");
}
}
マッチメイキングメタデータ
Photon Boltと統合されたプラットフォームの中には、実行中の統合に特化したメタデータを生成できるものがあります。
ほとんどの場合、これはカスタム情報であり、すべてのプラットフォームで利用できるわけではありません。
これを念頭に置いて、 BoltMatchmaking
ユーティリティクラスに新しいフィールド CurrentMetadata
を含めました。これは、アクティブなプラットフォームによって公開されるメタ情報を含む辞書です。
利用可能なデータのリストは時間の経過とともに増える可能性があります。新しい情報をリクエストしてください。
例えば、以下にPhoton Cloudプラットフォーム( PhotonPlatform
)を使用しているときにピアが接続されている現在のリージョンを公開しました。
C#
public string GetCurrentRegion()
{
if (BoltMatchmaking.CurrentMetadata != null && BoltMatchmaking.CurrentMetadata.ContainsKey("Region"))
{
return BoltMatchmaking.CurrentMetadata["Region"] as string;
}
return null;
}
現在利用可能なメタデータ:
PhotonPlatform
: