新入社員のための大規模ゲーム開発入門 サーバサイド編 2015

94
新入社員のための大規模ゲーム開発入門 サーバサイド編 2015 株式会社インフィニットループ 佐々木 亨基 2015/08/08 OSC Kansai@Kyoto 2015

Upload: infiniteloop

Post on 21-Aug-2015

289 views

Category:

Technology


3 download

TRANSCRIPT

新入社員のための大規模ゲーム開発入門 サーバサイド編

2015

株式会社インフィニットループ佐々木 亨基

2015/08/08 OSC Kansai@Kyoto 2015

自己紹介

・佐々木 亨基 ( ささき としき )・ゆきこ 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 サーバから返すレスポンスの種類が違う

・ソケット通信型コネクションを確立しておきお互いに好きなタイミングで通信するサーバ側から能動的に送信可能なのが特徴リアルタイム制が求められる場面で使用される

ゲームってどんな風に出来てるの?

アプリの仕組みによってWeb サーバから返すレスポンスの種類が違う

今日は扱いやすい API 型の話が中心

ゲームってどんな風に出来てるの?

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

Flash ゲームの通信を firebug で覗いてみるとAPI と通信してるのが良くわかる

ゲームってどんな風に出来てるの?

リロードせずAPI と何度も通信

レスポンスは JSON文字列

開発の流れ

ある日新入社員が入ってきました彼はメガネをかけていたのであだ名はメガネになりました

名前 : メガネPHP+MySQL を少し触れる程度個人での開発しかやった事がなくチーム開発は初めて

開発の流れ

メガネ君はサービス開始からもうすぐ 1年経つプロジェクト X に配属される事になりました

開発の流れ

プロジェクト Xサービス開始から 1年

開発の準備

開発サーバのアカウントをもらい開発サーバに ssh でログイン

開発の準備

開発

ログイン

開発サーバは共用なので他の人も使っている

開発の準備

開発

個人ごとに VM を立てているプロジェクトもある

開発の準備

VM VM

VM VM

その場合は VM のイメージをもらい手元で起動して開発を行うVirtualBox + Vagrant などを使用DB は phpmig などマイグレーションツールで同期

開発の準備

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の開発

もう手で確認しなくて済む

$ phpunit UserInfoTest

I

Time: 0 seconds, Memory: 3.50Mb

OK, but incomplete or skipped tests!Tests: 1, Assertions: 0, Incomplete: 1.

APIの開発

サーバ開発 クライアント開発

クライアント

実装の済んだ最新のクライアントを受け取る

どうもです 最新版です

Flash なら開発サーバに設置スマホアプリなら開発端末にインストール

APIの開発

つなぎ込みの確認

動いてる気が しますね

yukicon

レベル :27

開発に加わるようになったメガネ君担当した機能のテストもすんなり終わり遂に本番にアップされる時が来ました

アップデート

プロジェクトによっても異なるが本番環境に至るまでの環境は 4 つほど

・開発環境・テスト環境・ステージング環境・本番環境

アップデート

アップデート

開発

テスト

ステージング

本番

ここで開発最新ソース、最新データで動作する環境開発者各個人が手元のソースで実行最新ソースで Fix前のマスタデータの確認開発中のため動作が不安定なのは当然

アップデート

ここでテストある程度安定版のソースで動作する環境テスト部隊が操作してデバッグを行う自動テストの実行もここアップされた直後では動作はするがバグがある状態

開発

テスト

ステージング

本番

アップデート

ここでも確認テストが通った安定版のソースで動作する本番にかなり近い環境これ以降ソースの変更は無くそのため本番と同じソースで稼働している本番で不具合があった場合の再現確認もここ

開発

テスト

ステージング

本番

アップデート

最後にユーザがプレイする環境

開発

テスト

ステージング

本番

メンテナンスについて

・定期メンテナンスアップデートのため毎週か毎月に一回などゲームを止め定期的に行われる予定されたメンテナンス

・緊急メンテナンス今しなければいけないが止める必要がある更新をする場合や発生した不具合による被害が広がらないようにする場合など止めた方が良い場合には止めてしまう重要なインフラではなくゲームなので、ある意味では止めても良いアップデートが頻繁な事からどうしても予期せぬ不具合が発生する確率が上がるのも事実

・無停止メンテナンスゲームを止めずに動かしたままアップデートする事裏当てなど呼び名は様々

アップデート

予定されているのは定期メンテナンスのみ

アップデート

定期メンテ 定期メンテ 定期メンテ

定期メンテナンス後に不具合が見つかったため無停止メンテで対応

アップデート

定期メンテ 定期メンテ 定期メンテ

無停止メンテ

もひとつおまけに対応細かい事なら定期メンテナンスに回す事もある

アップデート

定期メンテ 定期メンテ 定期メンテ

無停止メンテ

無停止メンテ

データが異常となったユーザが居る事が判明対象ユーザが増え続けているため緊急メンテナンスを開始

アップデート

定期メンテ 定期メンテ 定期メンテ

無停止メンテ

無停止メンテ

済済

緊急メンテ

後日無停止メンテにより補填対応

アップデート

定期メンテ 定期メンテ 定期メンテ

無停止メンテ

無停止メンテ

済済

緊急メンテ

無停止メンテ

いざ本番となるとやはりいろいろと起こりアップデートの大変さを知ったメガネ君しかし同時に刺激的でもあり安定運用のために頑張ろうと決意するのであった

安定運用のための心構え

ゲームはリリースしてからの運用が長い!

ブラウザ三国志2009年 7月 15 日正式サービス開始

6周年を迎えてもまだまだ元気

安定運用のための心構え

リリースして終わりではないではリリース後にどんな事が起こるのか?

人間は痛みで覚える生き物良くある失敗から失敗しないための心構えを学ぶ

運用失敗あるある

良くある失敗その 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 ターンに力をいれています

・社長も含めほぼ全員がプログラマで技術者に優しい環境・勤務地は北海道札幌市、他の拠点への転勤などは無し・おいしい食べ物、自然いっぱい、花粉少ない・短い通勤時間、徒歩や自転車で通勤が可能・涼しい!! [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 ターン」で検索 

ご清聴ありがとうございました