cedec 2015: playgroundとluaによる...
TRANSCRIPT
このスライドはCEDEC2015で発表した「PlaygroundとLuaによる大規模モバイルオンラインゲーム開発のレベルアップ」の「Part III 通信周りのレベルアップ」の部分です。
スライド全体はhttps://cedil.cesa.or.jp/cedil_sessions/view/1345をご覧ください。
発表原稿 :https://gist.github.com/hasipon/155f3bb80f3a314ee96f
はじめに
Playgroundでゲーム作るよ
背景
HTTPサーバ
クライアント(ブラウザ)
HTML
ガラケー向けゲーム
背景
スマホ向けゲーム
HTTPサーバ
クライアント(Playground)
JSON踏襲⇒
HTTPサーバ
クライアント(ブラウザ)
HTML
ガラケー向けゲーム
背景
スマホ向けゲーム
HTTPサーバ
クライアント(Playground)
JSON踏襲⇒
HTTPサーバ
クライアント(ブラウザ)
HTML
ガラケー向けゲーム
サーバ開発
サーバ開発
クライアント開発
通信API
サーバ開発
クライアント開発
通信API設計
わかりやすい役割分担
わかりやすいスケジュール
通信API
通信API設計とは?
→こんな感じのもの
リクエスト先 main.php/my/changeName/リクエスト内容 { "name":"新しい名前" }レスポンスデータサンプル { "before_name":"以前の名前", "after_name":"新しい名前" }
設計の踏襲
ガラケー向けゲーム
HTML生成はサーバ側↓
基本的に操作するたびに通信
スマホ向けゲーム
設計の踏襲
ガラケー向けゲーム
HTML生成はサーバ側↓
基本的に操作するたびに通信
スマホ向けゲーム
基本的に操作するたびに通信
踏襲
発生した問題
ガラケー向けゲーム
HTML生成はサーバ側↓
基本的に操作するたびに通信
スマホ向けゲーム
基本的に操作するたびに通信
踏襲
海外向けゲームだったので
サーバを米国に
発生した問題
ガラケー向けゲーム
HTML生成はサーバ側↓
基本的に操作するたびに通信
スマホ向けゲーム
基本的に操作するたびに通信
踏襲
日本から遊ぶと
通信待ちがひどい
海外向けゲームだったので
サーバを米国に
なぜ通信待ちがひどいのか
● 操作するたびに通信しているから
通信頻度が多すぎる
● RTT が 180ms 程度あった
● 物理的に限界がある
どうやって通信待ちをごまかすか
サーバ開発
クライアント開発
通信API設計
どうやって通信待ちをごまかすか
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
どうやって通信待ちをごまかすか
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
大規模な改修
どうやって通信待ちをごまかすか
「スケジュール上
開発終盤なので急ぎで」
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
大規模な改修
今ここ
どうやって通信待ちをごまかすか
「スケジュール上
開発終盤なので急ぎで」
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
大規模な改修
今ここ
「スケジュール上
開発終盤なので急ぎで」
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
大規模な改修
短期的成果を得るために場当たり的
対応
今ここ
どうやって通信待ちをごまかすか
「スケジュール上
開発終盤なので急ぎで」
ここから見なおさなくては…
サーバ開発
クライアント開発
通信API設計
大規模な改修
短期的成果を得るために場当たり的
対応
今ここ
場当たり的対応
場当たり的対応
場当たり的対応
積み重なる
場当たり的対応
どうやって通信待ちをごまかすか
小規模な修正すら困難になっていく…
場当たり的対応
場当たり的対応
ガラケー向けゲーム
HTML生成はサーバ側↓
基本的に操作するたびに通信
スマホ向けゲーム
基本的に操作するたびに通信
踏襲これが良くなかった →
反省点
最初から、操作するたびに
通信しないように設計したい
対策
操作するたびに通信しないようにするには?
対策
操作するたびに通信しないようにするには?
→ 通信結果をキャッシュしよう
対策
通信APIの種類ごとにキャッシュしてみる
API 1 API 2 API 3
キャッシュ キャッシュ
発生した問題
他のAPIのレスポンスに影響を与えるときなどに
キャッシュ間の不整合が発生する
API 1 API 2 API 3
キャッシュ キャッシュ
影響不整合
発生した問題
他のAPIのレスポンスに影響を与えるときなどに
キャッシュ間の不整合が発生する
API 1 API 2 API 3
キャッシュ キャッシュ
影響不整合
クライアントの複雑化に伴って
修正コストが増大していく…
反省点
通信APIの種類ごとにキャッシュしてみる
API 1 API 2 API 3
キャッシュ キャッシュ
↑ これが良くなかったなぜ通信APIの種類ごとなのか?
反省点
キャッシュ実装はクライアント開発の領域
→サーバ開発から切り離してしまった
API 1 API 2 API 3
キャッシュ キャッシュ
サーバ開発
クライアント開発
キャッシュ実装と
サーバ開発を統合できないか?
MVVMとサーバ
View ViewModel Model
クライアント
MVVMとサーバ
View ViewModel Model
クライアント
サーバ
サーバとの通信はModelの役割
MVVMとサーバ
View ViewModel Model
クライアント
サーバ
クライアント開発 サーバ開発
MVVMとサーバ
View ViewModel Model
クライアント
サーバ
こうあるべきではないか?
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
クライアント開発が通信つなぎこみ
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
クライアント開発が通信つなぎこみ
サーバ開発が通信つなぎこみ
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
クライアント開発に通信APIを提供
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
クライアント開発に通信APIを提供
クライアント開発にModelの関数を提供
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
ViewModelに影響しない通信APIの変更がサーバ開発に閉じる
開発体制の変更
サーバ開発
クライアント開発
サーバ
キャッシュ
サーバ
Model
従来の開発体制 現在の開発体制
ViewModel
ViewModelに影響しない通信APIの変更がサーバ開発に閉じる
通信頻度削減のための
修正がしやすくなる
Modelの構成
API 1 API 2 API 3
キャッシュ キャッシュ
従来の方法 サーバ
Modelの構成
API 1 API 2 API 3
現在の方法
Model
サーバ
Modelの構成
API 1 API 2 API 3
現在の方法
Model
関数1 関数2
状態1 状態2
サーバ
Modelは状態と関数から構成される
Modelの構成
API 1 API 2 API 3
現在の方法
Model
関数1 関数2
状態1 状態2
サーバ
Modelの関数はViewModelにデータを加工して渡す
Modelの構成
API 1 API 2 API 3
現在の方法
Model
関数1 関数2
状態1 状態2
サーバ
Modelの関数はサーバと通信する
Modelの構成
API 1 API 2 API 3
現在の方法
Model
関数1 関数2
状態1 状態2
サーバ
Modelの関数は状態を変更する
比較
API
キャッシュ
従来の方法
API
状態
現在の方法
Model
あまり変わってない…?
比較
API
キャッシュ
従来の方法
API
状態
現在の方法
Model
設計順序が変わっている
先
後
後
先
比較
API
キャッシュ
従来の方法
API
状態
現在の方法
Model
先
後
後
先
Modelの状態の設計に合わせてサーバを設計できる
通信内容やサーバの処理を効率化しやすい
Modelの実装と
サーバ開発を統合できた!
難しい点 (1)
サーバ開発者もクライアントで動作するコードを書く必要がある
難しい点 (1)
サーバ開発者もクライアントで動作するコードを書く必要がある
→ サーバ開発者もLuaを書く
難しい点 (1)
サーバ開発者もクライアントで動作するコードを書く必要がある
→ サーバ開発者もLuaを書く
→ がんばる
難しい点 (1)
サーバ開発者もクライアントで動作するコードを書く必要がある
→ サーバ開発者もLuaを書く
→ がんばる
→ 純粋なLuaに閉じるようにする
難しい点 (2)
サーバ開発者とクライアント開発者の両方が
クライアントで動作するコードを書く
難しい点 (2)
サーバ開発者とクライアント開発者の両方が
クライアントで動作するコードを書く
→ ひとつの機能に同時に両者が関わる
難しい点 (2)
サーバ開発者とクライアント開発者の両方が
クライアントで動作するコードを書く
→ ひとつの機能に同時に両者が関わる
→ UIとロジックの分離がより厳密に要求される
難しい点 (2)
サーバ開発者とクライアント開発者の両方が
クライアントで動作するコードを書く
→ ひとつの機能に同時に両者が関わる
→ UIとロジックの分離がより厳密に要求される
→ そもそも分離していないのは、smart UI アンチパターン
難しい点 (3)
通信API設計の変更頻度が上がる
難しい点 (3)
通信API設計の変更頻度が上がる
→クライアントとサーバの対応関係が複雑になる
難しい点 (3)
通信API設計の変更頻度が上がる
→クライアントとサーバの対応関係が複雑になる
→ソースコードリポジトリ統合
ソースコードリポジトリ統合
従来 クライアントリポジトリの
アセットによる肥大化
クライアントとサーバの
対応関係は人間が判断
アセット
クライアント
サーバ
ソースコードリポジトリ統合
現在 アセットリポジトリ独立で
クライアントのブランチ切り替えも高速に
同じブランチなら
対応関係があると
考えて良い
アセット
クライアント
サーバ
良かった点(1)
当初の目的通り、通信頻度削減に成功
→ クライアント側でのデータ保持を前提に
サーバ・通信APIを設計してあるので、
クライアントで保持したデータを
積極的に利用でき、通信頻度が下がる
良かった点(2)
クライアント・サーバにまたがる修正が簡単に
→クライアントへの影響を気にして
修正を躊躇するケースが減った
良かった点(3)
クライアント・サーバ統合テストの導入・自動化
→サーバだけのテストでは
クライアント側のデータ保持がカバーされない
→テスト自動化の観点からもソースコードリポジトリ統合は良かった
レベルアップまとめ
● レベル1○ 操作するたびに通信しないようにするには、
最初からちゃんと設計しないと難しいことがわかった
● レベル2○ キャッシュの実装は複雑化すると難しいことがわかった
● レベル3○ Model開発とサーバ開発を統合できた