新入社員のための大規模ゲーム開発入門 サーバサイド編 2015
TRANSCRIPT
自己紹介
・佐々木 亨基 ( ささき としき )・ゆきこ yukicon・ Twitter:@yukiconEx・株式会社インフィニットループ所属・制御系から Web 業界に転向・学生時代の夢は理科の先生・ゲームがつくりたくてプログラマに・一旦は諦め一般のプログラマに・その後夢が叶って今はゲーム開発・超適当・のんびりゆったりまいぺーす
インフィニットループについて
・北海道札幌市にあるシステム開発会社 約 120 名(契約スタッフ・アルバイト含む)で活動中 社長も含め、ほぼ全員がエンジニア
・主な開発実績(主にサーバサイドを担当) ブラウザ三国志 (2009) 戦国 IXA(2010) Lord of Knights(2012) Vim 検定 (2012) PHP 検定 (2013) 勇者と 1000 の魔王 (2014) ソリティ馬 (2014) クラウド勤怠アプリシュキーン (2014)
ゲーム開発って…難しそうどんな事してるかわからなくて怖い自分なんかでは無理
新卒はもちろんWeb 系の業務経験がある人でもそう考えがち
実際は知らないだけそんなに怖いものじゃない!
幽霊の正体見たり枯れ尾花
はじめに
一般的な Web サービス開発案件と同じ
LAMP 構成LinuxApacheMySQLPHP 、 Perl 、 Python
言語は PHP 、 Perl 、 Ruby など様々やってる事はなんであっても変わらない
ゲームってどんな風に出来てるの?
アプリの仕組みによってWeb サーバから返すレスポンスの種類が違う
・ HTML 型一般的なサイトと同じく HTML を返すブラ三や Mobage 、 GREE の携帯ゲーム
・ API 型HTML ではなく JSON を返すFlash 、 Ajax 、スマホのネイティブアプリなどのクライアントが存在今はこちらが主流
ゲームってどんな風に出来てるの?
アプリの仕組みによってWeb サーバから返すレスポンスの種類が違う
・ソケット通信型コネクションを確立しておきお互いに好きなタイミングで通信するサーバ側から能動的に送信可能なのが特徴リアルタイム制が求められる場面で使用される
ゲームってどんな風に出来てるの?
API が返す JSON とは
[{"name":"Pz.Kpfw. V Pantherr","gun":"7,5 cm KwK 42 L\/70","weight":"44.8t","speed":"55","armor":"80","type":"MIDDLE_TANK"},{"name":"Jagdpanther","gun":"8,8 cm PaK 36 L\/56","weight":"45.5t","speed":"55","armor":"80","type":"TANK_DESTROYER"},{"name":".Kpfw. VI Tiger","gun":"8,8 cm PaK 36 L\/56","weight":"57t","speed":"40","armor":"100","type":"HEAVY_TANK"},{"name":"Pz.Kpfw. Tiger II","gun":"8,8 cm KwK 43 L\/71","weight":"69.8t","speed":"38","armor":"180","type":"HEAVY_TANK"},{"name":"Jagdtiger","gun":"12,8 cm PaK 44 L\/55","weight":"75t","speed":"38","armor":"250","type":"TANK_DESTROYER"}]
ゲームってどんな風に出来てるの?
API 型のゲーム
ゲームってどんな風に出来てるの?
Web
http://example.jp/userInfo?user_id=1000
サーバサイドの担当はここ
JSON
クライアントサイドFlash 、 Ajax 、スマホのネイティブアプリ
API
チームで開発を行いチームで運用をやっている企画は絶対のような明確な上下関係はない役割分担はあるが相互理解が大事
例えば開発→企画「この計算式バランス悪くないですか?」
言われたまま実装するだけでなくブラッシュアップの手助けとなるので遠慮なく意見を言う
運用→インフラ「イベントやるのでサーバ増強お願いします」
イベントはアクティブ率が上がるというチームとしての共通認識
開発体制
APIの開発
サーバ開発 クライアント開発
■パラメータ・ユーザ ID
■ レスポンス・ユーザ名・レベル
相談して API の仕様を決める
こんな感じでいきましょう いきましょう
サーバ主導で決めるかクライアント主導で決めるかはプロジェクトによって異なる
API を実装
APIの開発
// ユーザ情報取得$user_info = getUserInfo($_GET['user_id']);
// 必要な情報を配列に入れる$response = array(
'name' => $user_info['name'],'level' => $user_info['level'],
);
// JSONで返すecho json_encode($response);
でけた
テストを書いておくと今後便利
APIの開発
もう手で確認しなくて済む
$ phpunit UserInfoTest
I
Time: 0 seconds, Memory: 3.50Mb
OK, but incomplete or skipped tests!Tests: 1, Assertions: 0, Incomplete: 1.
アップデート
開発
テスト
ステージング
本番
ここで開発最新ソース、最新データで動作する環境開発者各個人が手元のソースで実行最新ソースで Fix前のマスタデータの確認開発中のため動作が不安定なのは当然
アップデート
ここでも確認テストが通った安定版のソースで動作する本番にかなり近い環境これ以降ソースの変更は無くそのため本番と同じソースで稼働している本番で不具合があった場合の再現確認もここ
開発
テスト
ステージング
本番
メンテナンスについて
・定期メンテナンスアップデートのため毎週か毎月に一回などゲームを止め定期的に行われる予定されたメンテナンス
・緊急メンテナンス今しなければいけないが止める必要がある更新をする場合や発生した不具合による被害が広がらないようにする場合など止めた方が良い場合には止めてしまう重要なインフラではなくゲームなので、ある意味では止めても良いアップデートが頻繁な事からどうしても予期せぬ不具合が発生する確率が上がるのも事実
・無停止メンテナンスゲームを止めずに動かしたままアップデートする事裏当てなど呼び名は様々
アップデート
・データ不整合を防ぐためしっかりとロックする1 人がボスを叩いている間はボスの情報を行ロックSELECT * FROM t WHERE id = 1000 FOR UPDATE
データ不整合
データ
AB
他の人使っちゃダメ
B は A のロック解放を待つデータをロック
・ロック範囲に気をつけるロック範囲が広すぎると並列処理性能に影響が出るロック範囲は最低限にしておくべきMySQL の場合はインデックスを使ってロックするインデックスが効かないと事実上のテーブルロックになる
・デッドロックに気をつけるデータ不整合を恐れてロックを増やしすぎると起こりがちロックするテーブルの順番を統一するなどして対策するただしどんなに注意しても起こる時は起こるその場合はループしてやり直すように実装する
データ不整合
どうやらこんなシンプルなクエリが問題らしい
負荷が高まる
SELECT * FROM t WHERE c2 = 'XXX';SELECT * FROM t WHERE c2 = 'YYY';SELECT * FROM t WHERE c2 = 'ZZZ';
どうやらこんなシンプルなクエリが問題らしい
負荷が高まる
SELECT * FROM t WHERE c2 = 'XXX';SELECT * FROM t WHERE c2 = 'YYY';SELECT * FROM t WHERE c2 = 'ZZZ';
よく見るとインデックスが使われていない!このままでは夜のピークタイムは越えられないインデックスをつけるため緊急メンテへ
※MySQL5.6 からは動かしながらインデックスが追加できるようになりました
・ユーザは負荷に敏感一般的な Web サイトと比べ、ユーザの操作量は段違いに多い一般的な Web サイトで許される程度の”ちょっと重いな”が毎日の操作で積み重なるとイライラいつもと比べて重いとイライラ→ユーザ離脱
レスポンスが遅いとゲームは成り立たない!
負荷が高まる
・インデックスを意識するレコード数が多いテーブルではインデックスの効かないクエリは極端な負荷になる
CREATE TABLE t (id int(11) AUTO_INCREMENT,c1 varchar(10),c2 varchar(10),PRIMARY KEY (id),KEY c1 (c1)
)
主キーSELECT * FROM t WHERE id = 1000;インデックスがついているSELECT * FROM t WHERE c1 = 'AAA';インデックスがついていないSELECT * FROM t WHERE c2 = 'BBB';
負荷が高まる
×
○
○
・無駄な処理はしない特に DB アクセスはデリケート何度も同じクエリを発行したりループ内で何度もクエリを発行したりしない
×SELECT * FROM t WHERE id = 1;SELECT * FROM t WHERE id = 2;SELECT * FROM t WHERE id = 3;SELECT * FROM t WHERE id = 4;
○SELECT * FROM t WHERE id IN (1, 2, 3, 4);
負荷が高まる
起こるタイミングは不定ただどうやらDB サーバのディスク I/O がネックになっている
調査を進めるとDB容量の増大によりメモリ内で処理しきれなくなったためディスクアクセスが多発しているのが原因だった
データベースの肥大化
・サービス運用を続ければユーザは増え続ける当然データも増え続けるユーザ数が多ければ多いほどデータ増加は激しい
・インデックスがメモリに乗らなくなると突然重くなる順調に捌けているように見えてもある日突然重くなるという事が起こる
データベースの肥大化
・設計段階から破綻しないように考えておく際限なしに溜まり続けるデータが無いようにするメールは最新 50 件のみ保存行動ログ情報の有効期限は 1ヶ月テーブルパーティショニングの検討水平分割 (Sharding) の検討まずそうならこうするという対策を必ず考えておき詰まないように
・定期的に監視をする最もレコード数が多いテーブルは何レコードくらいか最も容量の大きなテーブルは何GB くらいか現在の DB容量とメモリの関係はどれくらいか
データベースの肥大化
・ゲームとは長く付き合う事になる開発期間よりもサービス期間の方が長いまた、リリース後も頻繁にアップデートが行われる→設計ミスなどの技術的負債はプロジェクトを苦しめ続ける 小さな事でも長く長く効いてくるので結果的には大問題
・開発はチームで行っている好き勝手に書くと場所ごとに別物になってしまい混乱を招く自分以外が改修する事も多い→属人化した読めないコードでは成り立たない
動けば良いやではダメ!
コードが難解
・可読性、保守性の意識をプログラミングの基本ではあるが案件的に重要度が高いコーディング規約の遵守特別な理由が無ければトリッキーな実装は避ける他人が読んでも理解出来るかどうかを考える1年後の自分は他人なので、 1年後に見てもわかるように
・レビューしてもらう最初は誰でもわからないのが当然こんな実装にしてみたいと思うんですけどの設計段階から実際に書いたコードまでチームの先輩にレビューしてもらい学んでいくレビューには自分の考えをしっかり持って臨むこと
コードが難解
・恐れずにリファクタリングする技術的負債は返済しなければ溜まる一方触るのが怖いかもしれないが放っておくともっと面倒な事になるつらいなと感じる事があったら放置せず修正する癖をつける他の場所に同じようなコードがあるなら合わせて修正する方針について心配なら先輩に相談すると吉自動テストを用意するとリファクタリングのリスクはぐっと下がる
・こだわり過ぎるのもいけない理想を追い求めすぎてもままならないチーム内に思想の違う人が居たり、ついてこれない人が居たり必要以上に工数がかかってしまったり自分としては正しくなくても、チームとして正しいなら受け入れよう郷に入っては郷に従え理想と現実の狭間で上手く生きる
コードが難解
今挙げた 4 つの問題に共通する事は全てエンジニアの設計・実装が悪くて起こるという事
日々の心構え、意識によってのみ防ぐ事ができる今動いているから良いのではなく後々こんな問題が起こるのでは?という意識が大事なのだと学んだメガネ君でした
運用失敗あるある
これで一人前!
ゲーム開発といってもそんなに特殊な事はないただし・開発をチームで行っている・アップデートを繰り返し長期運用するこの 2点については意識しておく必要がある
そして何よりも面白いユーザの反応がダイレクトに見える、届く関わったゲームにプレイヤーとして参加する喜び他の案件では得難い体験
最後に
インフィニットループでは、エンジニアを募集しています最近は特に U ターン・ I ターンに力をいれています
・社長も含めほぼ全員がプログラマで技術者に優しい環境・勤務地は北海道札幌市、他の拠点への転勤などは無し・おいしい食べ物、自然いっぱい、花粉少ない・短い通勤時間、徒歩や自転車で通勤が可能・涼しい!! [NEW]
PHP 開発エンジニアスマホ開発エンジニアMySQL エンジニアインフラエンジニア
おまけ :求人募集 (1)
実際に U ターン・ I ターンを行った 3 人の生の声が聞けます
・東京のゲーム会社で働いていた S氏が U ターン転職で戻ってきたという例・子育てを機に故郷の北海道に帰ってきたという Y氏の例・神奈川出身、京都在住の M氏が北海道のファンになり、札幌に就職するという例
おまけ :求人募集 (2)
弊社のブログでスライドが公開されています。
好きな場所で働くということ。~U ターン、 I ターンの良さ~
http://www.infiniteloop.co.jp/blog/2015/06/osc2015-uiturn/
「OSC 北海道 U ターン」で検索