新入社員のための大規模ゲーム開発入門 サーバサイド編
-
Upload
infiniteloop -
Category
Technology
-
view
19.479 -
download
0
description
Transcript of 新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編
株式会社インフィニットループ佐々木 亨基
2014/06/14 OSC Hokkaido 2014
自己紹介
・佐々木 亨基 ( ささき としき )・ゆきこ yukicon・ Twitter:@yukiconEx・株式会社インフィニットループ所属・制御系から Web 業界に転向・学生時代の夢は理科の先生・ゲームがつくりたくてプログラマに・一旦は諦め一般のプログラマに・その後夢が叶って今はゲーム開発・超適当・のんびりゆったりまいぺーす
インフィニットループについて
・北海道札幌市にあるシステム開発会社 約 100 名(契約スタッフ・アルバイト含む)で活動中 社長も含め、ほぼ全員がエンジニア
・主な開発実績(主にサーバサイドを担当) ブラウザ三国志 (2009) 戦国 IXA(2010) 英雄クエスト (2010) Lord of Knights(2012) フォトバトラー (2012) Vim 検定 (2012) PHP 検定 (2013) ソードオブナイツ (2014)
新作ゲーム「勇者と 1000 の魔王」iPhone AppStore で好評配信中!
こういうゲームをつくるお話です
インフィニットループについて
ゲーム開発って…難しそうどんな事してるかわからなくて怖い自分なんかでは無理
新卒はもちろんWeb 系の業務経験がある人でもそう考えがち
実際は知らないだけそんなに怖いものじゃない!
幽霊の正体見たり枯れ尾花
はじめに
ゲームはどんな風に動いているのかゲーム開発とはどんなものなのかを知る
開発については具体的な手法やノウハウではなく心構えや概念的な話がメイン
今日のお話
■ ゲームってどんな風に出来てるの?
■ 開発の流れ
■ 安定運用のための心構え
お題目
ゲームってどんな風に出来てるの?
一般的な Web サービス開発案件と同じ
LAMP 構成LinuxApacheMySQLPHP 、 Perl 、 Python
言語は PHP 、 Perl 、 Ruby など様々やってる事はなんであっても変わらない
ゲームってどんな風に出来てるの?
アプリの仕組みによってWeb サーバから返すレスポンスの種類が違う
・ HTML 型一般的なサイトと同じく HTML を返すブラ三や Mobage 、 GREE の携帯ゲーム
・ API 型HTML ではなく JSON を返すFlash 、 Ajax 、スマホのネイティブアプリなどのクライアントが存在今はこちらが主流
ゲームってどんな風に出来てるの?
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 、スマホのネイティブアプリ
Flash ゲームの通信を firebug で覗いてみるとAPI と通信してるのが良くわかる
ゲームってどんな風に出来てるの?
リロードせずAPI と何度も通信
レスポンスは JSON文字列
開発の流れ
ある日新入社員が入ってきました彼はメガネをかけていたのであだ名はメガネになりました
名前 : メガネPHP+MySQL を少し触れる程度個人での開発しかやった事がなくチーム開発は初めて
開発の流れ
メガネ君はサービス開始からもうすぐ 1年経つプロジェクト X に配属される事になりました
開発の流れ
プロジェクト Xサービス開始から 1年
開発の準備
開発サーバのアカウントをもらい開発サーバに ssh でログイン
開発の準備
開発
ログイン
開発サーバは共用なので他の人も使っている
開発の準備
開発
個人ごとに VM を立てているプロジェクトもある
開発の準備
VM VM
VM VM
その場合は VM のイメージをもらい手元で起動して開発を行うVirtualBox + Vagrant などを使用
開発の準備
VM
ソースはバージョン管理システムで中央管理中央レポジトリからソースを落とすsvn 、または git を使用
開発の準備
レポジトリ
svn ならsvn checkout
git ならgit clone
変更したら中央レポジトリを更新
開発の準備
レポジトリ
svn ならsvn commit
git ならgit push
エディタはなんでも良いと言われましたがねこび~んが可愛いので NetBeans にしました
開発の準備
ソースを触れる、動かせる状態になったため開発に加わる事が出来るようになりましたがメガネ君に開発のイメージを持ってもらうために開発体制と API の開発について説明します
開発体制
プロジェクト X は大きめのプロジェクトなので結構な人数が関わっています
・プロジェクトマネージャー・企画・運用・デザイナー・クライアント開発・サーバ開発・インフラ担当・テスト (QA)
開発体制
・プロジェクトマネージャー意思決定タスク管理その他チーム運用が円滑になるように雑用
・企画ゲームの企画立案、仕様策定
・運用所謂運営チームお問い合わせ対応動向調査
開発体制
・デザイナー画面デザインエフェクト作成
・クライアント開発クライアントサイド実装ユーザの目に触れる部分
・サーバ開発サーバサイド実装目に見えない裏方
開発体制
メガネ君はここ
・インフラ担当サーバ構築リソース監視
・テスト (QA)ゲームのテスト、デバッグQuality assurance(品質保証 )
開発体制
チームで開発を行いチームで運用をやっている企画は絶対のような明確な上下関係はない役割分担はあるが相互理解が大事
例えば開発→企画「この計算式バランス悪くないですか?」
言われたまま実装するだけでなくブラッシュアップの手助けとなるので遠慮なく意見を言う
運用→インフラ「イベントやるのでサーバ増強お願いします」
イベントはアクティブ率が上がるというチームとしての共通認識
開発体制
ゲームへの理解は業務知識最低限全機能を知るくらいにはプレイをする
本気過ぎてトッププレイヤーになるメンバーも当然本番でチートはご法度なのでみんな普通にガチプレイ
開発体制
API の開発
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の開発
動いてる気がする
APIの開発
サーバ開発 クライアント開発
クライアント
実装の済んだ最新のクライアントを受け取る
どうもです 最新版です
Flash なら開発サーバに設置スマホアプリなら開発端末にインストール
APIの開発
つなぎ込みの確認
動いてる気が しますね
yukicon
レベル :27
開発に加わるようになったメガネ君担当した機能のテストもすんなり終わり遂に本番にアップされる時が来ました
アップデート
プロジェクトによっても異なるが本番環境に至るまでの環境は 4 つほど
・開発環境・テスト環境・ステージング環境・本番環境
アップデート
アップデート
開発
テスト
ステージング
本番
ここで開発最新ソース、最新データで動作する環境開発者各個人が手元のソースで実行最新ソースで Fix前のマスタデータの確認開発中のため動作が不安定なのは当然
アップデート
ここでテストある程度安定版のソースで動作する環境テスト部隊が操作してデバッグを行うアップされた直後では動作はするがバグがある状態
開発
テスト
ステージング
本番
アップデート
ここでも確認テストが通った安定版のソースで動作する本番にかなり近い環境これ以降ソースの変更は無くそのため本番と同じソースで稼働している本番で不具合があった場合の再現確認もここ
開発
テスト
ステージング
本番
アップデート
最後にユーザがプレイする環境
開発
テスト
ステージング
本番
メンテナンスについて
・定期メンテナンスアップデートのため毎週か毎月に一回などゲームを止め定期的に行われる予定されたメンテナンス
・緊急メンテナンス今しなければいけないが止める必要がある更新をする場合や発生した不具合による被害が広がらないようにする場合など止めた方が良い場合には止めてしまう重要なインフラではなくゲームなので、ある意味では止めても良いアップデートが頻繁な事からどうしても予期せぬ不具合が発生する確率が上がるのも事実
・無停止メンテナンスゲームを止めずに動かしたままアップデートする事裏当てなど呼び名は様々
アップデート
予定されているのは定期メンテナンスのみ
アップデート
定期メンテ 定期メンテ 定期メンテ
定期メンテナンス後に不具合が見つかったため無停止メンテで対応
アップデート
定期メンテ 定期メンテ 定期メンテ
無停止メンテ
済
もひとつおまけに対応細かい事なら定期メンテナンスに回す事もある
アップデート
定期メンテ 定期メンテ 定期メンテ
無停止メンテ
無停止メンテ
済
データが異常となったユーザが居る事が判明対象ユーザが増え続けているため緊急メンテナンスを開始
アップデート
定期メンテ 定期メンテ 定期メンテ
無停止メンテ
無停止メンテ
済済
緊急メンテ
後日無停止メンテにより補填対応
アップデート
定期メンテ 定期メンテ 定期メンテ
無停止メンテ
無停止メンテ
済済
緊急メンテ
無停止メンテ
いざ本番となるとやはりいろいろと起こりアップデートの大変さを知ったメガネ君しかし同時に刺激的でもあり安定運用のために頑張ろうと決意するのであった
安定運用のための心構え
ゲームはリリースしてからの運用が長い!
ブラウザ三国志2009年 7月 15 日正式サービス開始
もう少しで 5周年
安定運用のための心構え
リリースして終わりではないではリリース後にどんな事が起こるのか?
人間は痛みで覚える生き物良くある失敗から失敗しないための心構えを学ぶ
運用失敗あるある
良くある失敗その 1
運用失敗あるある
データ不整合
運用失敗あるある
?=
ある日、メガネの所属するプロジェクト X にユーザから問い合わせが
データ不整合
データ不整合
HP 500/1000
攻撃ログA の攻撃 300ダメージ
B の攻撃 600ダメージ
C の攻撃 500ダメージ
ボスが死んでない!
データ不整合
HP 500/1000
攻撃ログA の攻撃 300ダメージ
B の攻撃 600ダメージ
C の攻撃 500ダメージ
これだけが有効になっている
データ不整合
メガネの実装が悪い!
・同時処理が多く行われる人気のあるボスに多くのユーザが殺到同じユーザを 2 人が同時に攻撃など→テスト時は発見が困難なデータ不整合が発生 設計の段階からエンジニアが意識する必要がある
データ不整合
・データ不整合を防ぐためしっかりとロックする1 人がボスを叩いている間はボスの情報を行ロックSELECT * FROM t WHERE id = 1000 FOR UPDATE
データ不整合
データ
AB
他の人使っちゃダメ
B は A のロック解放を待つデータをロック
・ロック範囲に気をつけるロック範囲が広すぎると並列処理性能に影響が出るロック範囲は最低限にしておくべきMySQL の場合はインデックスを使ってロックするインデックスが効かないと事実上のテーブルロックになる
・デッドロックに気をつけるデータ不整合を恐れてロックを増やしすぎると起こりがちロックするテーブルの順番を統一するなどして対策するただしどんなに注意しても起こる時は起こるその場合はループしてやり直すように実装する
データ不整合
良くある失敗その 2
運用失敗あるある
負荷が高まる
運用失敗あるある
!
ある日のメンテナンス後明らかに普段よりも DB サーバの負荷が高くなりレスポンス速度が悪化
負荷が高まる
どうやらこんなシンプルなクエリが問題らしい
負荷が高まる
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);
負荷が高まる
良くある失敗その 3
運用失敗あるある
データベースの肥大化
運用失敗あるある
ある日、突然レスポンス速度が悪化前回のメンテナンスからは結構日にちが経っており直前に原因となりそうなアップデートもない
データベースの肥大化
起こるタイミングは不定ただどうやらDB サーバのディスク I/O がネックになっている
データベースの肥大化
起こるタイミングは不定ただどうやらDB サーバのディスク I/O がネックになっている
調査を進めるとDB容量の増大によりメモリ内で処理しきれなくなったためディスクアクセスが多発しているのが原因だった
データベースの肥大化
データベースの肥大化
なんかもう全部メガネが悪い!
※初期設計が悪いのでメガネは悪くありません
・サービス運用を続ければユーザは増え続ける当然データも増え続けるユーザ数が多ければ多いほどデータ増加は激しい
・インデックスがメモリに乗らなくなると突然重くなる順調に捌けているように見えてもある日突然重くなるという事が起こる
データベースの肥大化
・設計段階から破綻しないように考えておく際限なしに溜まり続けるデータが無いようにするメールは最新 50 件のみ保存行動ログ情報の有効期限は 1ヶ月テーブルパーティショニングの検討水平分割 (Sharding) の検討まずそうならこうするという対策を必ず考えておき詰まないように
・定期的に監視をする最もレコード数が多いテーブルは何レコードくらいか最も容量の大きなテーブルは何GB くらいか現在の DB容量とメモリの関係はどれくらいか
データベースの肥大化
良くある失敗その 4
運用失敗あるある
コードが難解
運用失敗あるある
function isError($id){
:::
return array($data1, $data2);}
!?
・ゲームとは長く付き合う事になる開発期間よりもサービス期間の方が長いまた、リリース後も頻繁にアップデートが行われる→設計ミスなどの技術的負債はプロジェクトを苦しめ続ける 小さな事でも長く長く効いてくるので結果的には大問題
・開発はチームで行っている好き勝手に書くと場所ごとに別物になってしまい混乱を招く自分以外が改修する事も多い→属人化した読めないコードでは成り立たない
動けば良いやではダメ!
コードが難解
・可読性、保守性の意識をプログラミングの基本ではあるが案件的に重要度が高いコーディング規約の遵守特別な理由が無ければトリッキーな実装は避ける他人が読んでも理解出来るかどうかを考える1年後の自分は他人なので、 1年後に見てもわかるように
・レビューしてもらう最初は誰でもわからないのが当然こんな実装にしてみたいと思うんですけどの設計段階から実際に書いたコードまでチームの先輩にレビューしてもらい学んでいくレビューには自分の考えをしっかり持って望むこと
コードが難解
・恐れずにリファクタリングする技術的負債は返済しなければ溜まる一方触るのが怖いかもしれないが放っておくともっと面倒な事になるつらいなと感じる事があったら放置せず修正する癖をつける他の場所に同じようなコードがあるなら合わせて修正する方針について心配なら先輩に相談すると吉
・こだわり過ぎるのもいけない理想を追い求めすぎてもままならないチーム内に思想の違う人が居たり、ついてこれない人が居たり必要以上に工数がかかってしまったり自分としては正しくなくても、チームとして正しいなら受け入れよう郷に入っては郷に従え理想と現実の狭間で上手く生きる
コードが難解
今挙げた 4 つの問題に共通する事は全てエンジニアの設計・実装が悪くて起こるという事
日々の心構え、意識によってのみ防ぐ事ができる今動いているから良いのではなく後々こんな問題が起こるのでは?という意識が大事なのだと学んだメガネ君でした
運用失敗あるある
これで一人前!
ゲーム開発といってもそんなに特殊な事はないただし・開発をチームで行っている・アップデートを繰り返し長期運用するこの 2点については意識しておく必要がある
そして何よりも面白いユーザの反応がダイレクトに見える、届く関わったゲームにプレイヤーとして参加する喜び他の案件では得難い体験
最後に
インフィニットループでは、エンジニアを募集しています
・社長も含めほぼ全員がプログラマで技術者に優しい環境・勤務地は北海道札幌市、他社出向などは無し・おいしい食べ物、自然いっぱい、花粉少ない、涼しい・短い通勤時間、徒歩や自転車で通勤が可能・ U ターン、 I ターン大歓迎
・ PHP 開発エンジニア・スマホ開発エンジニア・ MySQL エンジニア・インフラエンジニア
求人募集
ご清聴ありがとうございました