Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

2015/08/08に行われたオープンソースカンファレンス2015 Kansai@Kyotoのセミナーで使われたスライド資料です。
(2014年のOSC北海道のスライドをベースに作成しています)

Infiniteloop

August 16, 2023
Tweet

More Decks by Infiniteloop

Other Decks in Programming

Transcript

  1. 自己紹介 ・佐々木 亨基 ( ささき としき ) ・ゆきこ yukicon ・

    Twitter:@yukiconEx ・株式会社インフィニットループ所属 ・制御系から Web 業界に転向 ・学生時代の夢は理科の先生 ・ゲームがつくりたくてプログラマに ・一旦は諦め一般のプログラマに ・その後夢が叶って今はゲーム開発 ・超適当 ・のんびりゆったりまいぺーす
  2. 一般的な Web サービス開発案件と同じ LAMP 構成 Linux Apache MySQL PHP 、

    Perl 、 Python 言語は PHP 、 Perl 、 Ruby など様々 やってる事はなんであっても変わらない ゲームってどんな風に出来てるの?
  3. アプリの仕組みによって Web サーバから返すレスポンスの種類が違う ・ HTML 型 一般的なサイトと同じく HTML を返す ブラ三や

    Mobage 、 GREE の携帯ゲーム ・ API 型 HTML ではなく JSON を返す Flash 、 Ajax 、スマホのネイティブアプリ などのクライアントが存在 今はこちらが主流 ゲームってどんな風に出来てるの?
  4. 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_D ESTROYER"},{"name":".Kpfw. VI Tiger","gun":"8,8 cm PaK 36 L\/56","weight":"57t","speed":"40","armor":"100","type":"HEAVY_T ANK"},{"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_D ESTROYER"}] ゲームってどんな風に出来てるの?
  5. API の開発 サーバ開発 クライアント開発 ▪ パラメータ ・ユーザ ID ▪ レスポンス

    ・ユーザ名 ・レベル 相談して API の仕様を決める こんな感じでいきましょう いきましょう サーバ主導で決めるかクライアント主導で決めるかは プロジェクトによって異なる
  6. API を実装 API の開発 // ユーザ情報取得 $user_info = getUserInfo($_GET['user_id']); //

    必要な情報を配列に入れる $response = array( 'name' => $user_info['name'], 'level' => $user_info['level'], ); // JSON で返す echo json_encode($response); でけた
  7. テストを書いておくと今後便利 API の開発 もう手で確認しなくて済む $ phpunit UserInfoTest I Time: 0

    seconds, Memory: 3.50Mb OK, but incomplete or skipped tests! Tests: 1, Assertions: 0, Incomplete: 1.
  8. データ不整合 HP 500/1000 攻撃ログ A の攻撃 300 ダメージ B の攻撃

    600 ダメージ C の攻撃 500 ダメージ ボスが死んでない!
  9. データ不整合 HP 500/1000 攻撃ログ A の攻撃 300 ダメージ B の攻撃

    600 ダメージ C の攻撃 500 ダメージ これだけが有効になっている
  10. ・データ不整合を防ぐためしっかりとロックする 1 人がボスを叩いている間はボスの情報を行ロック SELECT * FROM t WHERE id =

    1000 FOR UPDATE データ不整合 データ A B 他の人使っちゃダメ B は A のロック解放を待つ データをロック
  11. どうやらこんなシンプルなクエリが問題らしい 負荷が高まる SELECT * FROM t WHERE c2 = 'XXX';

    SELECT * FROM t WHERE c2 = 'YYY'; SELECT * FROM t WHERE c2 = 'ZZZ'; よく見るとインデックスが使われていない! このままでは夜のピークタイムは越えられない インデックスをつけるため緊急メンテへ ※MySQL5.6 からは動かしながらインデックスが追加できるようになりました
  12. ・インデックスを意識する レコード数が多いテーブルでは インデックスの効かないクエリは極端な負荷になる 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'; 負荷が高まる × ◦ ◦
  13. ・無駄な処理はしない 特に 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); 負荷が高まる
  14. ・設計段階から破綻しないように考えておく 際限なしに溜まり続けるデータが無いようにする メールは最新 50 件のみ保存 行動ログ情報の有効期限は 1 ヶ月 テーブルパーティショニングの検討 水平分割

    (Sharding) の検討 まずそうならこうするという対策を必ず考えておき詰まないように ・定期的に監視をする 最もレコード数が多いテーブルは何レコードくらいか 最も容量の大きなテーブルは何 GB くらいか 現在の DB 容量とメモリの関係はどれくらいか データベースの肥大化
  15. ・可読性、保守性の意識を プログラミングの基本ではあるが案件的に重要度が高い コーディング規約の遵守 特別な理由が無ければトリッキーな実装は避ける 他人が読んでも理解出来るかどうかを考える 1 年後の自分は他人なので、 1 年後に見てもわかるように ・レビューしてもらう

    最初は誰でもわからないのが当然 こんな実装にしてみたいと思うんですけどの設計段階から 実際に書いたコードまで チームの先輩にレビューしてもらい学んでいく レビューには自分の考えをしっかり持って臨むこと コードが難解
  16. 実際に U ターン・ I ターンを行った 3 人の生の声が聞けます ・東京のゲーム会社で働いていた S 氏が

    U ターン転職で戻ってきたという例 ・子育てを機に故郷の北海道に帰ってきたという Y 氏の例 ・神奈川出身、京都在住の M 氏が北海道のファンになり、札幌に就職するという例 おまけ : 求人募集 (2) 弊社のブログでスライドが公開さ れています。 好きな場所で働くということ。 ~ U ターン、 I ターンの良さ~ http://www.infiniteloop.co.jp/blog /2015/06/osc2015-uiturn/ 「 OSC 北海道  U ターン」で検索