46
ポコロンダンジョンズと リアルタイム通信 クライアント編 Grenge 袴田 大貴

ポコロンダンジョンズとリアルタイム通信 -クライアント編-

Embed Size (px)

Citation preview

Page 1: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

ポコロンダンジョンズと  リアルタイム通信  

-­‐‑  クライアント編  -­‐‑

Grenge 袴田  大貴

Page 2: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

自己紹介 •  袴田  大貴 (Hakamata Daiki) •  株式会社グレンジ所属 •  ポコロンダンジョンズ  クライアントエンジニア •  リリース前から現在まで

https://www.facebook.com/D.hakamata

Page 3: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

ポコロンダンジョンズ

Page 4: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

アプリ紹介 •  なぞるパズルRPG パズルブロック「ポコロン」をなぞって主人公を動かし、敵を攻撃してダンジョンを攻略!

•  1000種を超える装備, モンスター

•  大4人の協力プレイ「共闘」

Page 5: ポコロンダンジョンズとリアルタイム通信 -クライアント編-
Page 6: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

アジェンダ

1.  構成 2.  同期方法 3.  具体例 4.  確率で発生する事象 5.  待ち合わせ 6.  再接続と強制同期 7.  まとめ

Page 7: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

1.  構成

Page 8: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

構成図

curl  (h+ps) WebSocket  (wss)

(詳細はサーバサイドの塚原さんの発表で…)

Page 9: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

リアルタイム通信 n プロトコル  WebSocket : ブラウザでは定番  UDP : MMOでよく使われる  RUDP : UDPとTCPの良いとこどり  HTTP : ポーリング

n ミドルウェア  Node.js : すべての処理を自前で実装, JavaScript  Photon : クラウドあり, C#, WIndowsServer  モノビットエンジン : クラウドあり, C++, LinuxServer

Page 10: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

クライアント構成 n ゲームエンジン

      Cocos2d-x v3.2.0

n 使用言語

Page 11: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

ソケット通信 n  iOS

    AZSocketIO       [ SocketRocket, AFNetWorking ]

n  Android

    Socket.IO-Client for Java       [ Java-WebSocket ]

どちらも独自に改造済み

Page 12: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

AZSocket Socket.IO-­‐‑Client for  Java

GRWebSocket

ポコロンダンジョンズ

実装構成

Page 13: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

発生した問題 •  バックグラウンド時の通信維持 •  ソケットライブラリのメモリリーク •  ソケット切断後GC多発 •  特定端末(Nexusなど)専用対応 •  意図的な切断と偶発的な切断の区別 •  通信保証 (再送) •  再接続

Page 14: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

ソケット通信Libの改修 n  iOS  host, port, pathによる接続先設定  SSL対応  切断/再接続処理

n  Android  SSL対応  SSLContextのプロトコル複数対応  切断処理 (GC多発)  JNI/マルチスレッド対応  イベント名+JSONデータ送受信

Page 15: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

2.  同期方法

Page 16: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

同期方法 n クライアント分散方式  サーバが中継, 各クライアントが処理 n イベント同期  特定のイベントをトリガとして同期  演算に必要なデータを送受信

なぞった!

中継役

Page 17: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

その他の同期方法 n サーバ集中方式  入力をサーバに送信し、サーバが処理  結果を各クライアントに配信 n リプレイ再生  クライアント側は演算せず、再生のみ n フレーム同期  毎フレームに同期を行う

Page 18: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

端末間の同期 •  盤面の色, 配置 •  敵の情報 •  プレイヤー, 召喚モンスターの情報 •  被ダメ/与ダメ •  ターン数 •  ドロップ情報 全てをやり取りするとデータ量多い!

Page 19: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

端末間の同期 •  ポコダン  は  ターン制 → 他プレイヤーの操作を自端末で再現すればデータ量削減

(2,  4),  (2,  5),  (3,  6) をなぞった

再現します

Page 20: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

通信保証

受領通知が来るまで一定間隔で再送 サーバ→クライアントの場合も同様

①送信

②受領通知

•  端末間ではなく端末-サーバ間で保証

Page 21: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

3.  具体例

Page 22: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

部屋生成〜クエスト開始

①部屋生成要求 ②接続確立&部屋情報同期

n ホスト

Page 23: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

部屋生成〜クエスト開始

①部屋一覧要求

②部屋参加要求

n ゲスト

③接続確立&部屋情報同期

Page 24: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

クエストの流れ

プレイヤーターン開始

なぞる A.スキル

なぞったマスを 歩きながら攻撃

C.スキル

敵ターン開始

移動前行動

移動中行動

移動後行動

Page 25: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

クエスト中  (送信) n ターンの操作権限者が送る情報 •  プレイヤ番号 •  行動タイプ (なぞり/スキル/リタイア/コンティニュー) •  コマンドインデックス (送信情報のシーケンシャル番号) •  (なぞり情報) •  (使用したスキル情報)

Page 26: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

プレイヤー  :  2 コマンド  :  0 タイプ  :  なぞり始め なぞり  :  (1,  4)

プレイヤー  :  2 コマンド  :  1 タイプ  :  なぞり中 なぞり  :  (2,  4)

・・・

プレイヤー  :  2 コマンド  :  5 タイプ  :  なぞり終わり

Page 27: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

クエスト中  (受信) n なぞり始め  盤面を暗転 n なぞり中  なぞり情報を元に光るラインを再現 n なぞり終わり  なぞりルートを確定 「送信者側の端末で起きた事象を自身の端末で再現」

Page 28: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

4.  確率で発生する事象は  どうする?

クリティカル,  回避,  状態異常  etc…

Page 29: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

乱数(擬似乱数)

乱数生成器シード値  :  A

乱数列 x1,  x2,  x3,  x4,  x5,  …

乱数生成器シード値  :  B

乱数列 y1,  y2,  y3,  y4,  y5,  …

同一のシード値で初期化すれば、同一の乱数列が得られる

Page 30: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

乱数同期

乱数生成器

乱数生成器

乱数生成器

乱数生成器

シード:X

全端末で同じ乱数列

Page 31: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

複数の乱数生成器 n 可能な限りズレを抑止するために乱数生成器は複数

キャラクター毎に専用の乱数生成器

演出用の非同期の乱数生成器

Page 32: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

乱数生成器 n メルセンヌ・ツイスター <random>ヘッダ 決定的 周期が長い 一様分布 高速 GRRandomUtility とライブラリ化して使用

Page 33: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

OSとSTL n  iOS  libc++ (LLVM C++ standard library) n  Android  APP_STL := gnustl_static [Application.mk] C++標準ライブラリが異なるので、そのままではシード値を同期しても生成される乱数列が異なる

Page 34: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

OSとSTL n  AndroidをiOSに揃える

NDKのリファレンス APP_STL := c++_static (cocos2d-x v3.2の推奨NDKバージョンは r9d ですが r10dを使用)

Page 35: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

5.  待ち合わせ

Page 36: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

待ち合わせ

Ready Ready

Ready

待ち合わせ開始をサーバに通知

Page 37: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

待ち合わせ

AllReady AllReady

AllReady

部屋の人数分揃ったらクライアントに通知

Page 38: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

6.  再接続と強制同期

Page 39: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

意図的/偶発的な切断 n 意図的な切断  専用のイベントをサーバに送信してから切断

これによって偶発的な切断と区別が可能 ・偶発的切断の発生件数検証 ・ゲーム内の通知メッセージ出し分け

Page 40: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

疎通ロスト判定

Verification Verification

1P 2P 3P

疎通確認データを送信

Page 41: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

疎通ロスト判定

VerificationResult

疎通を確認できたプレイヤーリストが返却

VerificationResult

VerificationResult

疎通確認プレイヤーリスト 1P,  3P

Page 42: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

疎通ロスト判定 n 疎通ロストしたプレイヤーがターン操作権限を持っていた場合、ターンをスキップする

n  (共通の仕様として)スキップ3回で部屋からキック

マナーの悪いプレイヤーの排除 安定した通信環境のプレイヤーのプレイを保護

Page 43: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

再接続 1.  偶発的切断発生 2.  一定時間、再接続を試みる 3.  再接続に成功したら、クエスト復帰

キャリア回線とWi-Fiの切り替わりなど瞬断は起こりうる 「通信は切れるもの」として対策をする

Page 44: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

強制同期 n 検証用の盤面情報を相互に送受信し、差異があった場合はホスト権限者の盤面に強制的に揃える

n 中断セーブデータ  シングルプレイの仕組み  クエスト情報をJSONに書き出しファイルに保存

シングルプレイで使用している中断セーブデータを流用 差異が生じたらホストのデータに全員ロールバック

Page 45: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

7.  まとめ

Page 46: ポコロンダンジョンズとリアルタイム通信 -クライアント編-

まとめ n 複数のプレイヤの情報を互いに送受信しつつ整合性を保つ、のがリアルタイム通信によるゲームのキモ

n ゲーム性に合わせた技術/同期方式を選定するのが重要

n 通信時間がどうしても発生するので、データ量は可能な限り削減する