Open Match 超入門

Jin Naraoka
google-cloud-jp
Published in
9 min readDec 28, 2019

--

この記事は Google Cloud Japan Customer Engineer Advent Calendar 2019 の 22日目の記事です。

TL;DR

Open Match はオープンソースのマッチメイクフレームワークで、スケーラブルで拡張性のあるマッチメーカーを簡単に構築することができます。
また、本番環境で大規模に動かす際の多くの課題を取り除きつつ、開発者がどのようにマッチメイクするかをコントロールできるようにデザインされています。

…なのですが、Open Match は専用の用語が多かったり、ちょっと試すのにも実装が必要になるなど、Agones に比べると正直なところとっつきにくく難しいと感じていました(ごめんなさい。。)
しかしながら、Open Match の v0.8.0 でドキュメントが大幅に改善されましたので、これを頼りにまずは超入門として、用語の整理を中心に Open Match を読み解いていこうと思います。

Open Match の用語

まずはこの記事の最大の目的である(個人的に整理したかった)Open Match 固有の用語について書いていきます。

Ticket

マッチをリクエストしたプレイヤー(もしくはプレイヤーグループ)を表す、Open Match における基本的なマッチメイクのエンティティ。

Ticket Pool (Pool, Player Pool)

Ticket (プレイヤー) を例えば、ゲームモードやランクごとにグルーピング (Pool) するために使われるフィルターのセット。

フィルターの種類としては以下のようなものがある。

  • double range (浮動小数の範囲)
  • string equals (文字列の一致)
  • tag present (タグの有無)

使用例)

  1. Ticket 作成時に Ticket の SearchFields にフィルタしたい (グルーピングしたい) 数値や文字列やタグを設定する
  2. MatchProfile (後述) の Pool を設定する。この PoolTicket の SearchFields に対するフィルタのセットになっている
  3. Match Function (後述) が MatchProfile を使用してマッチを作成する

MatchProfile

マッチの仕様を表し、プレイヤーを選択する条件を示すのに使われる。
Match Function がマッチを作成するのに必要となる以下のような情報を持つ。

  • プロファイルの名前。作成されたマッチがどのプロファイルから作成されたものかを識別する。
  • マッチの対象となる TicketPool。各 Pool はプレイヤーがどの Pool に属するかをフィルタするための条件を持つ。
  • Roster (オプション) (後述)。名前付きの Tiket ID グループ。

Roster

Ticket ID の名前付きコレクション。マッチの Ticket に所属するチームやそのサブチームなどをラベルづけするために使うことができる。
また、「バックフィル」や「参加中」などマッチの現在の状態を表すのにも使うことができる。

Assignment

Ticket に対するゲームサーバーの割り当てを表す。
Open Match から Ticket の作成元に返却される情報で、IP アドレス、ポート番号などゲームサーバーへの接続情報が含まれる。

Open Match のコンポーネント

次に Open Match を構成する/に必要となるコンポーネントについて見ていきます。
コンポーネントの種類としては「Core Components」「Customized Components」「External Components」の 3 つに分けることができます。

Core Components

Kubernetes 上でホストされる一連のサービスで gRPC/HTTP 経由で提供される Open Match のコア機能。

Open Match フロントエンド

Ticket の作成、削除、現在の状態取得などに使用される、 Tikcet の管理機能を提供する。

Open Match バックエンド

マッチ作成のコア機能を提供する。 MatchProfile を受け取り、リクエストされたプロファイルにあったマッチを返す。

MMLogic

Match Function が state storage から Ticket をクエリするためのヘルパー API。

Customized Components

Open Match を使用してカスタムのマッチメーカーを構築するために、以下のコンポーネントのカスタマイズが必要になる。

Match Function

マッチメイクロジックのコアとして実装されるコンポーネント。
Open Match バックエンドはマッチを作成するようリクエストを受けた時、Match Function をトリガする。Match Function は MatchProfile を受け取り、 MMLogic からプロファイルにあう Ticket を取得して、マッチを返却する。

Evaluator

Open Match では同じ Pool に対して Match Function を同時に実行することができるため、1 つの Ticket が複数のマッチに含まれることがある。Evaluator は Match Function が作成したこの複数のマッチを評価して重複を排除する。

External Components

ゲームサービスにはプレイヤーコネクションの取り扱いや専用ゲームサーバーとの連携など Open Match が提供するマッチメイク以外にもいくつかの機能が必要となる。
以下のサービスは Open Match と連携してゲーム特有のマッチメイクを実現するもので、Open Match には含まれないが、マッチメイクサービスの一部になるものである。

Game フロントエンド

ゲームクライアントからのマッチメイクリクエストを受け取り、 Assignment を返す。
Game フロントエンドではプレイヤーの認証、(プラットフォームサービスから)プレイヤーデータの取得などを行い、 Ticket の作成を通じて Open Match にマッチメイクのリクエストを行う。
また、作成した TicketAssignment のセットを確認し、セットされた際はこれをゲームクライアントに返す。

Director

Open Match から MatchProfile(のセット)にあうマッチを取得し、そのマッチで使用するゲームサーバーをゲームサーバーのアロケーションシステム(例えば Agones の Allocator Service)から取得する。
取得したゲームサーバーの情報(ゲームサーバーへの接続情報)から Open Match バックエンド を通じて Assignments を作成する。

マッチメイクの流れ

Open Match を構成するコンポーネントや用語がわかったので、マッチメイクがどのように行われるのか、各コンポーネント同士がどのようなやりとりをするのか、その流れをみてみましょう。

Open Match でのマッチメイクは大きく「マッチメイクリクエスト」「マッチの作成」「Assignment のセット」に分けられます。

マッチメイクリクエスト

  1. ゲームクライアントはマッチを見つけるために Game フロントエンド に接続して Assignment を要求
  2. Game フロントエンド はプレイヤーを検証。問題なければプレイヤー情報を(プラットフォームのサービスなどから)取得し、Open Match フロントエンドをコールしてこのプレイヤーの Ticket を作成

この段階で、プレイヤーを表す Ticket が( Ticket Poolの一部として)作成され、Open Match によるマッチメイクの対象となります。

マッチの作成

  1. DirectorMatchProfile にあったマッチを作成するよう、定期的に Open Match バックエンドFetchMatchesをコール
  2. Open Match バックエンドFetchMatchesMatch Function を実行
  3. Match Functionは Open Match Data Access API ( MMLogic) を通じて、 MatchProfileに設定されている Pool から、一致する全ての Ticketを取得
  4. Match Functionは取得した Ticket からマッチを作成
  5. Open Match バックエンドは作成したマッチを Director に返す

Assignment のセット

  1. Director はマッチに使うゲームサーバーのアロケーション(ゲームサーバーの確保と IP アドレス、ポート番号などの接続情報の取得)を専用ゲームサーバーにリクエスト
  2. Director はアロケートしたゲームサーバーへの接続情報を含む Assignment を作成
  3. Director は全ての Ticket に、作成した Assignment をセットするため Open Match バックエンドSetAssignment をコール
    これによって TicketAssignment が Open Match の State Store(デフォルトは Redis)にストアされる
  4. Game フロントエンドOpen Match フロントエンド から Assignment を取得してゲームクライアントに返す
  5. ゲームクライアントは Assignment 内の接続情報を使用して、ゲームサーバーに接続しゲームを開始する

おわりに

Open Match はどのようなコンポーネントから構成されるのか、Open Match 固有の用語が何を表しているのかを中心に読み解いてきました。
記事中でも軽く触れましたが、実際に Open Match を使うためには Game フロントエンド , Director , Match Function あたりをカスタマイズしたり、自分で実装したりする必要があります。また、 TicketAssignment の具体的なフォーマットや Agones と連携するにはどうしたらよいかも気になるところです。
これらについてもドキュメントを読み解きながら記事にできたらいいなぁと思っています。…つづく(かも)

--

--

Jin Naraoka
google-cloud-jp

Customer Engineer at Google Cloud. All views and opinions are my own.