Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ポコロンダンジョンズとリアルタイム通信 -クライアント編-
Search
CyberAgent SGE Engineer
May 20, 2016
Programming
0
300
ポコロンダンジョンズとリアルタイム通信 -クライアント編-
https://atnd.org/events/76070
の発表資料です
CyberAgent SGE Engineer
May 20, 2016
Tweet
Share
More Decks by CyberAgent SGE Engineer
See All by CyberAgent SGE Engineer
SREチームの立ち上げから5年間とこれから
sgeengineer
0
1.8k
サムザップにおけるNotionの 活用事例とPHPでのNotionAPIを利用した仕組み構築の紹介
sgeengineer
0
2k
Laravel OctaneをどうしてもPharで運用したい話
sgeengineer
2
2.5k
大規模Unityゲーム開発の設計事例 〜ドメイン駆動設計とDIコンテナを導入した一年を振り返る〜 / cedec2021-ddd
sgeengineer
2
14k
ロボットを動かすビジュアルプログラミングでできることはPHPでもできる!
sgeengineer
0
1.7k
PHP8版!Swooleのフレームワークを比べてみた
sgeengineer
1
2.7k
「戦国炎舞 -KIZNA-」で行ったAWSのコスト最適化の話
sgeengineer
0
1.8k
AirtestとPocoとOpenSTFによるUnity製スマートフォン向けゲームの実機自動テスト環境構築とその利用方法
sgeengineer
0
5.1k
PHPでgRPCって どこまでいけるの?
sgeengineer
0
4.9k
Other Decks in Programming
See All in Programming
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
160
テストから始めるAgentic Coding 〜Claude Codeと共に行うTDD〜 / Agentic Coding starts with testing
rkaga
12
3.6k
Discover Metal 4
rei315
2
130
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
5
1.1k
RailsGirls IZUMO スポンサーLT
16bitidol
0
180
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
250
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
770
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
920
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
730
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
630
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
440
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
3
760
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
7
510
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
Building Adaptive Systems
keathley
43
2.7k
How to Ace a Technical Interview
jacobian
277
23k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
It's Worth the Effort
3n
185
28k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Why Our Code Smells
bkeepers
PRO
336
57k
We Have a Design System, Now What?
morganepeng
53
7.7k
Facilitating Awesome Meetings
lara
54
6.4k
Transcript
ポコロンダンジョンズと リアルタイム通信 -‐‑ クライアント編 -‐‑ Grenge 袴田 大貴
自己紹介 • 袴田 大貴 (Hakamata Daiki) • 株式会社グレンジ所属 • ポコロンダンジョンズ
クライアントエンジニア • リリース前から現在まで https://www.facebook.com/D.hakamata
ポコロンダンジョンズ
アプリ紹介 • なぞるパズルRPG パズルブロック「ポコロン」をなぞって主人公を動かし、 敵を攻撃してダンジョンを攻略! • 1000種を超える装備, モンスター • 最大4人の協力プレイ「共闘」
None
アジェンダ 1. 構成 2. 同期方法 3. 具体例 4. 確率で発生する事象 5.
待ち合わせ 6. 再接続と強制同期 7. まとめ
1. 構成
構成図 curl (h+ps) WebSocket (wss) (詳細はサーバサイドの塚原さんの発表で…)
リアルタイム通信 n プロトコル WebSocket : ブラウザでは定番 UDP : MMOでよく使われる RUDP
: UDPとTCPの良いとこどり HTTP : ポーリング n ミドルウェア Node.js : すべての処理を自前で実装, JavaScript Photon : クラウドあり, C#, WIndowsServer モノビットエンジン : クラウドあり, C++, LinuxServer
クライアント構成 n ゲームエンジン Cocos2d-x v3.2.0 n 使用言語
ソケット通信 n iOS AZSocketIO [ SocketRocket, AFNetWorking ] n Android
Socket.IO-Client for Java [ Java-WebSocket ] どちらも独自に改造済み
AZSocket Socket.IO-‐‑Client for Java GRWebSocket ポコロンダンジョンズ 実装構成
発生した問題 • バックグラウンド時の通信維持 • ソケットライブラリのメモリリーク • ソケット切断後GC多発 • 特定端末(Nexusなど)専用対応 •
意図的な切断と偶発的な切断の区別 • 通信保証 (再送) • 再接続
ソケット通信Libの改修 n iOS host, port, pathによる接続先設定 SSL対応 切断/再接続処理 n Android
SSL対応 SSLContextのプロトコル複数対応 切断処理 (GC多発) JNI/マルチスレッド対応 イベント名+JSONデータ送受信
2. 同期方法
同期方法 n クライアント分散方式 サーバが中継, 各クライアントが処理 n イベント同期 特定のイベントをトリガとして同期 演算に必要なデータを送受信 なぞった!
中継役
その他の同期方法 n サーバ集中方式 入力をサーバに送信し、サーバが処理 結果を各クライアントに配信 n リプレイ再生 クライアント側は演算せず、再生のみ n フレーム同期
毎フレームに同期を行う
端末間の同期 • 盤面の色, 配置 • 敵の情報 • プレイヤー, 召喚モンスターの情報 •
被ダメ/与ダメ • ターン数 • ドロップ情報 全てをやり取りするとデータ量多い!
端末間の同期 • ポコダン は ターン制 → 他プレイヤーの操作を自端末で再現すればデータ量削減 (2, 4), (2,
5), (3, 6) をなぞった 再現します
通信保証 受領通知が来るまで一定間隔で再送 サーバ→クライアントの場合も同様 ①送信 ②受領通知 • 端末間ではなく端末-サーバ間で保証
3. 具体例
部屋生成〜クエスト開始 ①部屋生成要求 ②接続確立&部屋情報同期 n ホスト
部屋生成〜クエスト開始 ①部屋一覧要求 ②部屋参加要求 n ゲスト ③接続確立&部屋情報同期
クエストの流れ プレイヤーターン開始 なぞる A.スキル なぞったマスを 歩きながら攻撃 C.スキル 敵ターン開始 移動前行動 移動中行動
移動後行動
クエスト中 (送信) n ターンの操作権限者が送る情報 • プレイヤ番号 • 行動タイプ (なぞり/スキル/リタイア/コンティニュー) •
コマンドインデックス (送信情報のシーケンシャル番号) • (なぞり情報) • (使用したスキル情報)
プレイヤー : 2 コマンド : 0 タイプ : なぞり始め なぞり
: (1, 4) プレイヤー : 2 コマンド : 1 タイプ : なぞり中 なぞり : (2, 4) ・・・ プレイヤー : 2 コマンド : 5 タイプ : なぞり終わり
クエスト中 (受信) n なぞり始め 盤面を暗転 n なぞり中 なぞり情報を元に光るラインを再現 n なぞり終わり
なぞりルートを確定 「送信者側の端末で起きた事象を自身の端末で再現」
4. 確率で発生する事象は どうする? クリティカル, 回避, 状態異常 etc…
乱数(擬似乱数) 乱数生成器 シード値 : A 乱数列 x1, x2, x3, x4,
x5, … 乱数生成器 シード値 : B 乱数列 y1, y2, y3, y4, y5, … 同一のシード値で初期化すれば、同一の乱数列が得られる
乱数同期 乱数生成器 乱数生成器 乱数生成器 乱数生成器 シード:X 全端末で同じ乱数列
複数の乱数生成器 n 可能な限りズレを抑止するために乱数生成器は複数 キャラクター毎に専用の乱数生成器 演出用の非同期の乱数生成器
乱数生成器 n メルセンヌ・ツイスター <random>ヘッダ 決定的 周期が長い 一様分布 高速 GRRandomUtility とライブラリ化して使用
OSとSTL n iOS libc++ (LLVM C++ standard library) n Android
APP_STL := gnustl_static [Application.mk] C++標準ライブラリが異なるので、そのままではシード値 を同期しても生成される乱数列が異なる
OSとSTL n AndroidをiOSに揃える NDKのリファレンス APP_STL := c++_static (cocos2d-x v3.2の推奨NDKバージョンは r9d
ですが r10dを使用)
5. 待ち合わせ
待ち合わせ Ready Ready Ready 待ち合わせ開始をサーバに通知
待ち合わせ AllReady AllReady AllReady 部屋の人数分揃ったらクライアントに通知
6. 再接続と強制同期
意図的/偶発的な切断 n 意図的な切断 専用のイベントをサーバに送信してから切断 これによって偶発的な切断と区別が可能 ・偶発的切断の発生件数検証 ・ゲーム内の通知メッセージ出し分け
疎通ロスト判定 Verification Verification 1P 2P 3P 疎通確認データを送信
疎通ロスト判定 VerificationResult 疎通を確認できたプレイヤーリストが返却 VerificationResult VerificationResult 疎通確認プレイヤーリスト 1P, 3P
疎通ロスト判定 n 疎通ロストしたプレイヤーがターン操作権限を持ってい た場合、ターンをスキップする n (共通の仕様として)スキップ3回で部屋からキック マナーの悪いプレイヤーの排除 安定した通信環境のプレイヤーのプレイを保護
再接続 1. 偶発的切断発生 2. 一定時間、再接続を試みる 3. 再接続に成功したら、クエスト復帰 キャリア回線とWi-Fiの切り替わりなど瞬断は起こりうる 「通信は切れるもの」として対策をする
強制同期 n 検証用の盤面情報を相互に送受信し、差異があった場合 はホスト権限者の盤面に強制的に揃える n 中断セーブデータ シングルプレイの仕組み クエスト情報をJSONに書き出しファイルに保存 シングルプレイで使用している中断セーブデータを流用 差異が生じたらホストのデータに全員ロールバック
7. まとめ
まとめ n 複数のプレイヤの情報を互いに送受信しつつ整合性を保 つ、のがリアルタイム通信によるゲームのキモ n ゲーム性に合わせた技術/同期方式を選定するのが重要 n 通信時間がどうしても発生するので、データ量は可能な 限り削減する