final fantasy record keeper の作り方
DESCRIPTION
第二回DeNAゲーム開発勉強会のスライドです https://atnd.org/events/58433TRANSCRIPT
FINAL FANTASY Record Keeperの作り方
株式会社ディー・エヌ・エー
Japan リージョン ゲーム事業本部
新井 英資 [email protected]
©2014 SQUARE ENIX CO.,LTD / DeNA Co.,Ltd. All Rights Reserved.
自己紹介• 新井 英資
• FINAL FANTASY Record Keeper (FFRK)
リードエンジニア
• 2011 年入社 4年目
• 以前はアルバイトで iOSアプリを作ったり
• インフラやミドルウェアとチームを繋ぐ人
• 出来ないことを出来るようにします
今日お話すること
• FFRKというゲームを作ってみた話
• FFRKのアーキテクチャの話
• FFRKの運用周りの小話
FFRK というゲームを作ってみた話
FFRKについて• iOS/Android™向けにリリース( 2014/09/25)
• 株式会社スクウェア・エニックスとの共同開発タイトル
• 全 FFシリーズのバトルをドット絵で再現
• 懐かしくて新しい FINAL FANTASY
• システム開発は DeNA
• おかげ様でとても好評
デモ
• 実際の本番アプリの動画を再生します
開発当初の要件• アプリで作りたい– リッチなアニメーションを再生
• コンテンツ更新をコントロールしたい– アプリ更新無しでのイベントリリース
• これまでの既存リソースを使いたい– Kickmotor( D.O.T.、三国志ロワイヤル)
– ブラウザゲー用の内製フレームワーク
ハイブリッドアプリ• WebViewレイヤと OpenGLレイヤの 2層構造
– リッチな表現は OpenGLで描画
• WebViewBridge– WebView上の JSからネイティブの関数を実行
WebViewWebView
OpenGLOpenGL
ここはWebView
ここは OpenGL
WebView上の JS実装• MVCフレームワークの導入
– フロントもきちんと構造化して実装
• Backbone.js + RequireJS
– 利用実績を考慮
• Underscore template
– JSTにコンパイルして使う
バトルの実装• FFの ATB …を再現するには
– 待機、詠唱、攻撃、などの状態制御
• JSでステートマシンを実装– ネイティブアニメ描画とバトルロジックを分離
• アニメーションは Deferredチェーン– ネイティブからの描画コールバックを待って次へ
• ボス毎にステートマップを作成– 多彩なボスの行動制御
FFRKを作ったぞ!
よしリリースだ!
リリース 1ヶ月前の出来事
• CBTの結果–重い
–熱い
• 10fpsを切るもっさりバトル
• スクロール出来ないアイテムリスト
• 充電しながらプレイしても電池が減る
orz
パフォチュー祭りWebView編
• Chromeでのプロファイリング
–無駄な処理を徹底的に洗い出す
–レイアウト構造からの見直し
• ネイティブと同等のレベルへ
これが
こう
これが
こう
パフォチュー祭りネイティブ編
• 各 OpenGL描画 APIのコールスタックを精査
• 無駄な描画 APIコールを減らす– 頂点数 0での描画
– 無駄に広い描画領域
• 同じテクスチャを参照する描画をまとめる• Android2.X系でも 30fps出るように
– ドローコールは 4分の 1まで削減
これが
こう
ハイブリッドで作るメリット
• イベントドリブンなゲーム運用が出来る
– クライアント申請期間に左右されない
– 究極的には JSを変えれば全く別のゲームを作れる
• Chromeや Safariでデバッグ出来る
– ビルドをし直す必要が無くて便利
とはいえ• アクション性の高い要素は難しい
– WebViewBridgeでのレイテンシ
• 所詮はWebView
– HTMLテンプレート読み込み途中で止まったり
– ひっそりと再読み込みボタンを置く悲しみ
• OSバージョンによる挙動の違い
– 主に Android™
– 主に Android™
FFRK のアーキテクチャの話
ざっくり概要
クライアント構成
ネイティブアニメーション
• アニメーションプレイヤー– 内製ツールで作成したアニメデータを
Cocos2d-xで再生する
• 細かなアニメ制御– データでの制御
– マスタでの制御
– JSでの制御
ネイティブキャッシュ(図解)キャッシュ機構キャッシュ機構
httpdhttpd
ディレクトリディレクトリ
ダウンローダダウンローダ
WebView
持っていないアセットのみをサーバからとってくる
ネイティブキャッシュ• WebViewからもネイティブからも透過的にアクセス
– Mongooseを使いアプリ内部でプロキシサーバを立てる
– http://127.0.0.1:12345/hoge?url=file&ver=abcde
– キャッシュが無ければサーバから取得( cURL)
• キャッシュさせるもの– 大体何でも
• cssについては少し工夫– 保存時に画像 URLを置換してキャッシュサーバを向ける
• ビルドに抱き込むアセットも同様にアクセス可能
FFRKの運用周りの小話
高負荷対策• リリース後わりとすぐに TVCM開始
– 急増するユーザ(現在:登録者数 300万人超)
– 荒ぶるWebサーバ
• 迅速な負荷対応– シャード DBを追加投入
– Webサーバを順次投入
– 参照を slaveに逃がせる所は逃がす
• サービス停止すること無く乗り切りました
マスタ管理• Google Spreadsheet で一括管理
• Google Apps Script
– マスタ間での値のマッピング
– csvでの吐き出し
• マスタ作成フロー
– 開発環境でロード
– マスタのテスト
– Jenkins経由で github:Eに Pull-Request
ChatOps• IRC + Jenkins + Hubot
– Jenkinsが失敗していると全員怒られる
• Hubotが管理するもの
– Jenkinsでのビルド状況
– 検証環境の状態
– その他余計な機能多数
まとめ• FFRKはハイブリッドアプリ
– WebViewとネイティブの両レイヤで最適化
• FFRKの特徴的機構– アニメーションプレイヤー
– ネイティブキャッシュ
• FFRKの運用は終わりなき改善の旅
– 高負荷対応
– マスタ管理
– ChatOps
突然の謝辞
• たくさんのエンジニアにご協力頂きました
– インフラチームの皆さん
– ミドルウェアチームの皆さん
– パフォーマンスチューナーの皆さん
– 開発チームの皆さん
• ありがとうございました!!
ご静聴ありがとうございました