狠狠撸

狠狠撸Share a Scribd company logo
スマホアプリにおけるマルチ
プレイアクションゲーム開発
の実例紹介
株式会社アカツキ
田中 勇輔
自己紹介
? 田中 勇輔 @csouls
? 株式会社アカツキ CTO
? Rubyとかインフラとか開発マネジメントが得意。
たまにC++
今日话すこと
オンラインゲームをど
のようにして作るのか?
オンラインアクション
ゲームの実装の実例
オンラインゲームをどのよう
にして作るのか?
何を作ったのか?
? メザマシフェスティバル
? 2Dスクロールアクション + ソーシャルゲーム
? 一人プレイの冒険と、最大四人プレイのフェスバト
ル
フェスバトル
? リアルタイム非同期4人同時プレイ
奪い合いアクションゲーム
? 動きやモーション、ダメージ、アイ
テム取得/使用などのイベントを4人
で連携しあう
リアルタイム
? コンピューターの文脈では「すぐにやること」でも
「早く処理すること」でもなく、「ある処理に対し
て一定時間内に必ず結果を返すこと」
? オンラインゲームの世界では、1フレーム(1/60,
16.7ms)で同期する(様に見せる)こと
同期型と非同期型
? 同期型/非同期型: ここでは、全てのユーザで見える
世界が同じものを「同期」、違うものを「非同期」
とします
同期
Player1
Server
Player2
F1 F2 F3 F4 F5
同期 同期
? 一定の間隔で通信内容を同期?演算し、同じ世界を表示
※ フレーム同期、サーバ中継型の場合
表示表示
表示 表示
同期
? 格闘ゲームやRTS
? 他にもターンベースで同期する形や、サーバを中継
しない形も存在する
? 同期でしか実現できないことも多いが、通信/処理
速度が遅い端末がいたら、世界が止まる
非同期
Player1
Server
Player2
F1 F2 F3 F4 F5
? それまでに通信できたものを演算し、すぐに表示
表示 表示 表示 表示
表示 表示 表示 表示
非同期
? MMO RPG等
? 通信レイテンシの差によってイベントの到達順序が
入れ替わったりするので、必要であれば順序制御を
行う必要がある
同期と非同期
? ゲームデザイナー/エンジニアが考えること
? 何を同期して何を非同期にするか
? 通信のラグをどうカバーするか
? 通信量や計算量をどのようにして少なくするか
モバイル環境
※ OpenSignal ネットワーク統計データより
レイテンシ DL Speed UP Speed 信頼度
4G
DOCOMO 52 ms 5 Mb/s 1.3 Mb/s 86%
KDDI 40 ms 7.5 Mb/s 1.7 Mb/s 86%
SoftBank 35 ms 11.3 Mb/s 1.8 Mb/s 86%
3G
DOCOMO 616 ms 1.1 Mb/s 0.2 Mb/s 84%
KDDI 259 ms 0.8 Mb/s 0.1 Mb/s 88%
SoftBank 576 ms 1.4 Mb/s 0.3 Mb/s 83%
参照元: http://opensignal.com/networks/日本
モバイル環境
? ネットワークレイテンシ: 30~700ms
? Google Play サポート端末数: 7,319?
(Android OS Ver4.1以上)
モバイル環境
? バラバラな環境の中で、1/60秒(16ms)で動作してい
るゲームループを遅延することなく、うまくアクショ
ンが同期するように見せる
? 1アクションのデータサイズは多くても数十~百
Byteちょっとなので、そこまで大きな問題にはなら
ない。レイテンシが辛い
非同期オンラインアクション
バトル
? フェスバトルで実現したかったことは、キャラク
ターを任意のタイミングで自由に動かせること、4
人で一緒に遊べること
非同期オンラインアクション
バトル
? PvP -> 奪い合いバトル
? PvPだとアクションを同期する必要があり、モバイ
ル環境下で4人分の位置とアクションを遅延なく同
期するのは難しいと考えた
同期方式
? 非同期クライアント分散処理型
? メザマシフェスティバルでは、サーバは中継役(リ
フレクト型)で、ほぼ全ての処理をクライアントに
任せている
同期項目(一部)
同期項目 処理
ゲーム開始 全てのユーザが接続したので、ゲームを開始
時刻 チート対策のため、時刻とレイテンシのチェック
操作キャラ座標位置 ユーザーの位置とボスの位置を同期
モーション ユーザーの操作演出(ジャンプ、回避、攻撃等)
ダメージ ユーザー、敵の受けたダメージを反映
ポイント 取得したオーブの数を同期
アイテム取得 アイテムの取得を同期
アイテム使用 アイテムの使用を同期
ゲームオーバー ユーザーが画面からいなくなる
コンティニュー ユーザーが復帰する
ゲーム終了 結果画面を表示
位置同期システム
? プレイヤーがラグを感じるポイントはどこかという
と、「キャラの座標位置の同期」
? シンプルに座標位置を通信してそのまま処理すると、
他のプレイヤーが常にワープしながら動いている様
な見え方になる
位置同期システム
? PSO2: 歩き始めた時に結果をある程度決めてしまう
(※ CEDEC2010 セガの節政さんの公演より)
? メザマシフェスティバル: ジャンプ中に微妙な移動
ができるため、結果が1通信で決まらない
? ワープさせずに位置を合わせるためには、位置同
期の仕組みをうまく考える必要がある
位置同期システム
? 対応として、同期イベントをキューとしてためてお
き、シミュレーションする方式をとった
? 最新のキューとその一つ前を用いて計算
? 「現在、どの速度で、どの位置にいるか」の情報を
通信して、キューの間の位置及び速度の補完を行い、
現在のプレイヤー位置を求める
? 計算コストが少ないアルゴリズムを実装
位置同期システム
※特许出愿中の内容
※特许出愿中の内容
同期システム
? 補完の計算コストが少ない
? 同期の間隔がバラバラで予測しづらい動きの場合は、
速く(遅く)動いたりする
? レイテンシが一定であれば、うまく补完できる
同期システム
? 間隔をどれくらいにするか?
? たくさん同期しすぎていたら捌き切れない。次の
キューで補完されるが、荒くなる。短いと、ばら
つきが多くなる
? たどり着いたのは、3回/1秒
同期システム
? つまり、0.3秒 + 必ずかかるレイテンシの時間だけ
前の世界をシュミレートしている
? PvPは実現できないが、フェスバトルの内容であれ
ば、うまく全員がリアルタイムにアクションしてい
るように見える
チート対策
チート対策
? ゲームデザインとして、ボスは最后に倒した人が2
人いたら、どちらも恩恵を受けられるようにした
? 10秒遅延していると、10秒間ボスを殴れる。遅延
しているユーザーが有利になる!
? レイテンシの閾値を越えるとエラーにする + 時
刻を途中で書き換えらえれたら検知する仕組みを
実装
チート対策
? 取得したオーブ数をメモリ上で改ざんされる問題
? 改ざんされた場合、ハッシュ値で検知してエラーと
なる仕組みを実装
使っている技术やサービス
インフラ
Load Balancer
? EC2のtagをもとに、各クラスタ(lobby/game
server)の各ノードごとのコネクション数を毎秒取
得、RedisのSortedSetで保管/更新
? APIサーバーからリアルタイムで最も接続数の少な
いノードを読み出し、クライアントにエンドポイン
トを返す
Autoscaling Server
? 設定した閾値に応じてサーバーを自動で追加/縮小
? 追加は最短で3分に一度、縮小は1時間に一度のス
パンに制限
? 縮小は深夜帯のみトリガー
? 追加より縮小の方がリスクを伴うためシビアに設
定
Autoscaling Server
? ゼロダウンタイム
? Socket.ioプロセスが立ち上がり接続が確立でき
るまでLB側で有効なノードとして認識しない
? 縮小は、ノードに対するユーザーからの接続がな
い状態でしかトリガーされない
LBとAutoscaling Serverの可用性
? Multi-AZ && 自動FailOver
? Lobbyクラスタ用LB、Gameクラスタ用LBの2台構成、別
AZに配備
? それぞれがお互いをSocket.ioプロセスベースで監視し
合い、障害発生時に一方がもう一方の機能を吸収する
形で自動FailOverを行う
? サーバーが復旧した際は自動FailBack
監視
? CloudWatch + Slack連携
? 破壊的なイベント発生時やサーバーの状態を定期
的にSlackで通知
LB状態通知 Autoscale結果通知
LoadBalancerはELB
ではなく、独自実装
LB実装の経緯
? Socket.ioとELBの相性が悪い
? ELBのTCP Listenerを使った場合、Socket.ioのコ
ネクション確立に必要なStickySessionがサポート
されておらず、handshakingが確立できない
LB実装の経緯
? 対処の一つとしては、ELBの下にnginx
やHAProxyを立ててip-hashでバランス
することでstickinessを担保する?
→ しかし、ELBの下にさらにnginx立
てて??は辛い。
https://medium.com/@Philmod/load-balancing-websockets-on-ec2-1da94584a5e9
LB実装の経緯
? Proxy運用コスト…。
? そもそもnginxだとupstreamの動的変更が出来ない
(※)ため、ぶら下がるec2インスタンスの変更に手動
対応が必要 → オートスケール実現不可?
※ 実際は有償版のnginxPlus購入で可能なようだが、結局追加モジュー
ルを書く必要がある。?
→ 今回の実装方法に至る
実装した結果
? LBが直接ユーザーからのコネクションを受けることがない
ため、障害点になるリスクが低い
? 本質的な部分(※)の実装は薄く、モジュール化可能?
※ 各ノードの任意の状態(コネクション数やCPU使用率など)を常時監視し、設
定した閾値に応じて任意のスクリプトをトリガー
? 今回のsocket.ioのようなニッチなケースに限らず、http以
外のプロトコルでAutoscalingさせたい時等に使える
? SPDY/HTTP2やwebRTC等
最后に
まだまだ改善したいことがあります
? パフォーマンス
? 特にマルチプレイ中のCPU使用率が高すぎる。?
コツコツとチューニングしていく必要がある
? 操作性
? 「片手持ち」の条件下でできる限りのことはやっ
てみたが、お客様はもっと良いものを求めている
WE ARE HIRING!
http://aktsk.jp/recruit/
or @csouls
ありがとうござい
ました!

More Related Content

スマホアフ?リにおけるマルチフ?レイアクションケ?ーム开発の実例绍介