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: