v1.1.2
本ドキュメントは CSAR モジュール に関するドキュメントです。 CSAR モジュール は Diarkis ランタイム・ライブラリ と Diarkis-Module の上位レイヤーにあたり、Diarkis の低レイヤーの機能を組み合わせて一般的なゲームやアプリの実装モデルを想定した機能を提供し、より使いやすくしたライブラリです。
1. Authority
CSAR におけるオーソリティ(authority)とは、ゲームの正当な状態(state)を決定し、他の参加者に対してその状態を配信する権限を持つエンティティを指します。authority の位置づけは Dedicated Game Server (DGS)、ホストクライアント型(listen server/authoritative peer)、メッシュ型などのネットワークトポロジーやゲームの要件によって変わります。
ゲームロジック(authority が行うべき検証や意思決定)はアプリケーション側で実装する必要があります。つまり、どの入力を受け入れるか、どのように競合を解決するか、チート検知のアルゴリズムや最終的な状態更新はアプリケーションの責任です。
2. ゲームセットアップ
CSAR では以下に示すゲームのセットアップを指定することができます。authority の有無や他のユーザーとの接続方法に違いがあります。
StartAsDgsServer
Server-Authoritative (サーバー権威型) のネットワークを構築します。DGS として起動し、このプロセスが authority を持ちます。全状態の最終決定者であり、クライアントはサーバーの通知に従います。
JoinAsDgsClient
DGS に接続するためのクライアントとして起動します。DGS のゲームを構築するには StartAsDgsServer と JoinAsDgsClient が必要です。
HostClient
Client-Authoritative (クライアント権威型) のネットワークを構築します。いわゆる Host-Client モデルのゲームのためのセットアップです。DGS を用いずにリレーサーバ (Room) や P2P を用いて他のユーザーたちと接続します。クライアントの内1人が authority を持ちゲームロジックを担います。authority を持つクライアントをホストと呼びます。ホストがゲームから切断された場合はマイグレーションによりゲームを継続することができます。
Mesh
DGS を用いずにリレーサーバ (Room) や P2P を用いて他のユーザーたちと接続します。単一の authority を置かず、全ユーザーが対等なクライアントとして振る舞います。
DetachedAuthority
Client-Authoritative (クライアント権威型) のネットワークを構築します。DGS を用いずにリレーサーバ (Room) や P2P を用いて他のユーザーたちと接続します。ある1人のユーザーが authority を担いますが、そのユーザーは authority を持つのみでクライアントとしては振舞いません。専用サーバーを使うことなく StartAsDgsServer と JoinAsDgsClient の関係に似たネットワークを構築することができます。DGS の開発段階で使用することを想定しています。
Offline
Diarkis サーバーとの接続や他のユーザーとの接続をすることなく、HostClient のホストとして動作します。主にシングルプレイヤーやテスト向けです。
2.1. NetworkType
HostClient
もしくは Mesh
セットアップの場合に限り、Room を使用したリレー通信と P2P 通信の使い方を指定することができます。
Room & P2P
内部的に Room に入室して、 Room 経由の Relay 通信 と P2P を利用して通信します。P2P で通信できるユーザーとは P2P で通信し、P2P で通信できないときは Room 経由で通信します。どの経路で通信しているか意識しないで使用することができます。
Room
内部的に Room に入室して、 Room 経由の Relay 通信のみを利用して通信します。
3. ゲームインスタンス
DGS を含めユーザー間でデータの送受信を行うグループを表す概念です。 CSAR を使用して通信を行うユーザーは同じゲームインスタンスに参加する必要があります。
3.1. ゲームインスタンス ID
ゲームインスタンス ID は同時に動作しているすべてのゲームインスタンスの中で一意でなければなりません。異なるセットアップで同じ ID を使用すると問題が発生します。
同じ ID を同時に使わないでください。たとえば
HostClient
とMesh
セットアップを同じ ID で同時に開始しないでください。ID を再利用する場合は、前のインスタンスが完全に終了してからにしてください。
セッションごとに UUID(GUID)や十分にランダムな文字列を生成して使うのが安全です。
テスト目的で短い固定文字列(例: "test")を使うのは、ローカルや開発環境だけにしてください。
4. CSAR に接続する流れ
CSAR に接続し、他のユーザーと通信を行うための手順について説明します。
初期化処理
ConnectionManager
のインスタンスを作成します。ConnectionManager
は CSAR の機能にアクセスするためのインターフェイスです。内部に DiarkisInterface
をもっており、この機能を使用して CSAR の機能を提供します。DiarkisInterface
は ConnectionManager
の初期化時に外部から渡すインターフェイスもあり、ユーザーが作成したものを使用することも可能です。
Diarkis サーバへ接続
ConnectionManager::ConnectDiarkisServer
で Diarkis サーバへ接続します。本 API の初期化時にコンフィグとして接続先のサーバのアドレスなどを設定します。接続処理の結果は DiarkisConnectionEvent
で受け取ることができ ConnectionManager::AddServerConnectCallback
で呼び出されるコールバックを設定することができます。
ゲームインスタンスの開始
Diarkis サーバへ接続完了後、ConnectionManager::StartGameInstance
でゲームインスタンスを開始することができます。それぞれのユーザーが参加したいゲームセットアップを設定し、同じゲームインスタンス ID を指定して ConnectionManager::StartGameInstance
を実行することにより同じゲームインスタンスに参加することができます。
5. インゲームセッション中のユーザー管理とデータ送受信
HostClient
セットアップの場合を例にゲームの開始から終了までの流れを説明します。
ゲームインスタンスの開始処理
ゲームインスタンス開始処理の結果は GameInstStartEvent
で受け取ることができ ConnectionManager::AddGameInstStartCallback
で呼び出されるコールバックを設定することができます。また、ゲームインスタンスに参加した結果、自分がゲームのホスト役となった場合、ゲームサーバの処理の開始を要求する LaunchHostProcess
イベントが発生します。 このイベントはゲームサーバの処理を新たに開始する必要がある、ゲームインスタンスの開始時と後述するホストマイグレーション時に発生します。 ユーザはこのイベントのコールバックをトリガーとしてゲームサーバの開始処理を行うことができます。 LaunchHostProcess
イベントは ConnectionManager::AddLaunchHostProcessCallback
で呼び出されるコールバックを設定することができます。
参加ユーザーの情報取得
ゲームインスタンスに自分以外のユーザーが接続すると UserConnect
イベントが発生します。UserConnect
イベントは ConnectionManager::AddUserConnectCallback
で呼び出されるコールバックを設定することができます。 ゲームインスタンスから自分以外のユーザーが離脱すると UserDisconnect
イベントが発生します。UserDisconnect
イベントは ConnectionManager::AddUserDisconnectCallback
で呼び出されるコールバックを設定することができます。 ゲームインスタンスに参加しているユーザーは ConnectionManager::GetConnectedClients
もしくは ConnectionManager::GetConnectedUsers
で取得することが可能です。詳細は API ドキュメントをご参照ください。
データの送受信
SendToHost/SendToClient
を使用します。この API で送信したデータは DataToHost/DataToClient
イベントで受け取ることができ、ConnectionManager::AddDataToHost/AddDataToClient
で呼び出されるコールバックを設定することができます。
終了処理
ゲームインスタンスから離脱するには ConnectionManager::ExitFromGameInstance
を使用します。 ゲームインスタンスから離脱すると ConnectionManager::ExitFromGameInstance
を実行したユーザーは GameInstExit
イベントで離脱したことを受け取ることができ、ConnectionManager::AddGameInstExitCallback
で呼び出されるコールバックを設定することができます。
ゲームインスタンスから離脱後、ConnectionManager::DisconnectDiarkisServer
を使用して Diarkis サーバから切断します。
ホスト役かどうかの判断
ConnectionManager::IsHost
で自身がホスト役になっているかどうかを確認することができます。
6. HostClient セットアップにおけるホストマイグレーションのフロー
HostClient
セットアップで動作している場合、CSAR は既存のホスト役が不在となった場合でも新たなホスト役を選任してホスト役を切り替える事 (ホストマイグレーション) でゲームを継続することができます。Mesh
や DGS を用いたゲームでは機能しません。ホストマイグレーションは、主に次のような状況で発生します:
ホストがゲームインスタンスから退出した場合や、アプリのクラッシュなどによりネットワークから切断された場合
ConnectionManager::TransferHost
の実行により、ホストの役割が他のクライアントに委譲された場合
ホストマイグレーションは以下のフローで実行されます。
ホストの状態の保存
ホストマイグレーションに備えて、ホスト役だけが持っているマスターデータの情報を Diarkis サーバー 上に保存することが可能です。 ConnectionManager::StoreGameState
を呼び出すことで任意のバイト列を 10 KiB まで保存することができます。
クライアントの場合
ホスト役が認識できなくなった場合、HostOffline
イベントが発生します。 HostOffline
通知後、CSAR は 自動的に新たなホスト役に接続する処理を開始します。その後、新たなホスト役が決定し、通信の準備が完了すると HostMigrationComplete
イベントが発生します。
HostOffline
イベントは ConnectionManager::AddHostOfflineCallback
で、HostMigrationComplete
イベントは ConnectionManager::AddHostMigrationCompleteCallback
でそれぞれ呼び出されるコールバックを設定することができます。
新しいホストの場合
新しくホスト役として選出された場合、クライアントの側のイベントに加えて LaunchHostProcess
イベントが発生します。 このイベントでは新たにホスト役として選出されたことの通知とともに前任のホスト役が ConnectionManager::StoreGameState
で保存したデータがあればそのデータを取得することが可能です。このデータをもとにアプリ側でホスト役の状態を復元することで、ホストが他のコンピュータに移動しても保存時の状態を復帰することできます。ConnectionManager::GetConnectedClients
で取得できるホスト役から見たクライアントのリストも、この時点で接続しているクライアントが返るようになります。
7. ゲームインスタンスのライブマイグレーション
HostClient
もしくは Mesh
セットアップのみ使用可能です。Diarkis サーバーがスケールインなどによってシャットダウンされる際に稼働中のゲームインスタンスがある場合、ゲームインスタンスを別な Diarkis サーバーにマイグレートすることでゲームを継続することが可能です。
GameInstanceOffline イベント
Diarkis サーバーのプロセスがシャットダウンされる際にサーバーはクライアントに offline になる旨を通知します。クライアント側では GameInstanceOffline
イベントがトリガーされます。GameInstanceOffline
イベントはゲームインスタンスを構成するクライアントのうち1人だけにトリガーされます。ホストクライアント型のゲームであればホスト役で、メッシュ型のゲームであれば誰か1人が自動で選ばれそのクライアントでトリガーされます。
GameInstanceOffline
イベントを受信したクライアントは ConnectionManager::MigrateGameInstance
を実行することでマイグレーションを開始することができます。マイグレーションが開始されるとゲームインスタンス内の全てのクライアントが自動で新しい Diarkis サーバーに再接続します。
以下は GameInstanceOffline
イベントのコールバック実装の例です。
void OnGameInstanceOffline(const GameInstanceOfflineEventArgs& args)
{
// Call MigrateGameInstance at the appropriate timing according to the app-side implementation to migrate the GameInstance.
// アプリ側の実装に合わせて、適したタイミングで MigrateGameInstance を呼び出して GameInstance の移動を行ってください。
DiarkisUtils::Print("Start migrate game instance...");
gManager->MigrateGameInstance();
}
なお、ConnectionManager::MigrateGameInstance
を実行して再接続処理が開始すると現在接続しているサーバーと切断されるため一時的に通信できなくなります。 切断が発生するタイミングは ConnectionManager::MigrateGameInstance
を実行するタイミングでコントロールすることができますので、アプリケーションの都合に合わせて調整してください。
GameInstanceMigrationStart イベント
ゲームインスタンスのマイグレーションが開始されると GameInstanceMigrationStart
イベントが全てのクライアントでトリガーされます。GameInstanceMigrationComplete
イベントがトリガーされるまで他のクライアントと通信することはできません。
GameInstanceMigrationComplete イベント
新しいサーバーに接続しゲームインスタンスのマイグレーションが完了すると GameInstanceMigrationComplete
イベントが全てのクライアントでトリガーされます。このイベントが成功した場合、他のクライアントとの通信が可能になります。
8. その他の機能
Authority とメッシュ型の共存
ゲームインスタンスを HostClient
で初期化後に ConnectionManager::AllowSendDataBetweenClients
を使用することで同時にメッシュ型の通信を使用することができるようになります。 この機能はデフォルトでは無効になっており、明示的に有効化する必要があります。ゲームインスタンスが開始された後にConnectionManager::AllowSendDataBetweenClients
を true
で呼び出すと SendBroadcast
, SendMulticast
, SendUnicast
を実行してホスト役を介さずクライアント間でデータをやり取りすることができるようになります。これらのデータはDataToUserCallback
で受信することができます。また、ConnectionManager::GetConnectedUsers
で他のクライアントの UID を取得することが可能になります。
最終更新
役に立ちましたか?