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 の有無や他のユーザーとの接続方法に違いがあります。

GameInstanceSetup
説明

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 通信の使い方を指定することができます。

NetworkType
説明

Room & P2P

内部的に Room に入室して、 Room 経由の Relay 通信 と P2P を利用して通信します。P2P で通信できるユーザーとは P2P で通信し、P2P で通信できないときは Room 経由で通信します。どの経路で通信しているか意識しないで使用することができます。

Room

内部的に Room に入室して、 Room 経由の Relay 通信のみを利用して通信します。

3. ゲームインスタンス

DGS を含めユーザー間でデータの送受信を行うグループを表す概念です。 CSAR を使用して通信を行うユーザーは同じゲームインスタンスに参加する必要があります。

3.1. ゲームインスタンス ID

ゲームインスタンス ID は同時に動作しているすべてのゲームインスタンスの中で一意でなければなりません。異なるセットアップで同じ ID を使用すると問題が発生します。

  • 同じ ID を同時に使わないでください。たとえば HostClientMesh セットアップを同じ ID で同時に開始しないでください。

  • ID を再利用する場合は、前のインスタンスが完全に終了してからにしてください。

  • セッションごとに UUID(GUID)や十分にランダムな文字列を生成して使うのが安全です。

  • テスト目的で短い固定文字列(例: "test")を使うのは、ローカルや開発環境だけにしてください。

4. CSAR に接続する流れ

CSAR に接続し、他のユーザーと通信を行うための手順について説明します。

初期化処理

ConnectionManager のインスタンスを作成します。ConnectionManager は CSAR の機能にアクセスするためのインターフェイスです。内部に DiarkisInterface をもっており、この機能を使用して CSAR の機能を提供します。DiarkisInterfaceConnectionManager の初期化時に外部から渡すインターフェイスもあり、ユーザーが作成したものを使用することも可能です。

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::AllowSendDataBetweenClientstrue で呼び出すと SendBroadcast, SendMulticast, SendUnicast を実行してホスト役を介さずクライアント間でデータをやり取りすることができるようになります。これらのデータはDataToUserCallback で受信することができます。また、ConnectionManager::GetConnectedUsers で他のクライアントの UID を取得することが可能になります。

最終更新

役に立ちましたか?