ゲームエンジン開発を支える技術

33.7K Views

July 15, 22

スライド概要

Game Creators Conference 2016の講演で使用したスライドです。

『最新のゲームエンジン開発を支える技術』 - 是松 匡亮 / 齊藤 俊介

profile-image

株式会社カプコンが誇るゲームエンジン「RE ENGINE」を開発している技術研究統括によるカプコン公式アカウントです。 これまでの技術カンファレンスなどで行った講演資料を公開しています。 【CAPCOM オープンカンファレンス プロフェッショナル RE:2023】  https://www.capcom-games.com/coc/2023/ 【CAPCOM オープンカンファレンス RE:2022】  https://www.capcom.co.jp/RE2022/ 【CAPCOM オープンカンファレンス RE:2019】  http://www.capcom.co.jp/RE2019/

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

ゲームエンジン開発を 支える技術 CIの使い方とWebサービスの提供 株式会社カプコン 是松 匡亮 / 齊藤 俊介

2.

はじめに • 題材 • カプコンで開発を進めている 新しいゲームエンジンの開発環境 • 新しいゲームエンジンの資料 • 『いまどきのゲーム制作環境』- 市山裕介/是松匡亮 • https://cedil.cesa.or.jp/cedil_sessions/view/1303

3.

第一部 CIの運用とWEBサービス

4.

第一部 / アジェンダ • 導入 • CIの運用紹介 • 見てもらえるCIへ • Webサービスの提供

5.

導入 CI(継続的インテグレーション)の 必要性

6.

困っていたこと • 出社して仕事を始めようとしたらビルドエラー • ビルドは通るが起動しない • 起動するがバグでゲームが始まらない これらが当たり前のように発生

7.

CI黎明期 • 深夜に自動ビルドをするbatを作成 • エラーの検出は1日1回 • 実行テストは行わない • PCは1台のみ • 実施前よりもビルドが通りやすくなった

8.

CI黎明期 • 要求 • 日中も頻繁にビルドを行う • 全プラットフォームの全ビルド構成 • 実行テストを行う • テストに合格したものは配布する • ビルド履歴を確認できる • 自作をするには要求が多すぎる

9.

CIツール • Jenkinsを採用 • https://jenkins-ci.org/ • 採用理由 • プラグインによる機能拡張が容易 • 日本語の情報が入手しやすい • SlideShare, Qiita, ブログ, ... • 当時やりたかったことが簡単にできた

10.

CIの運用紹介 コミットから配布まで

11.

コミット / 全体像 Developers Repository CI

12.

コミット / リポジトリへの送信 Developers Repository CI

13.

コミット / CIの起床 Developers Repository CI

14.

コミット / 構成 • svnを採用 • post-commitスクリプトを利用することが可能 • gitの場合はpost-updateが適切 • post-commitスクリプトでJenkinsを起床 wget http://jenkins/job/BuildEngine/buildWithParameters?BRANCH_NAME=trunk • 現場で採用しているスクリプトは附録ページにあります

15.

ビルド / 全体像 Repository CI Server Developers

16.

ビルド / ビルドの実行 Repository CI Server Developers

17.

ビルド / ビルドの実行 • リポジトリから指定されたブランチをビルド • 開発者と同じ.slnをビルド • 複数台のスレーブPCが並行してビルドを行う • 複数のプラットフォーム • x64, PlatformA, PlatformB, ... • プラットフォームごとにすべての構成 • Debug, DebugOpt, Profile, QA, Ship • タイトルの要請に応じたカスタム構成 • レンダリングモジュールの差し替え, 社外貸出, etc.

18.

ビルド / 結果の取り扱い Repository CI Server Developers

19.

ビルド / 結果の取り扱い / 成功時 Repository CI Server Developers

20.

ビルド / 結果の取り扱い / 成功時 • ビルドしたバイナリをNAS上に配置 • バイナリのMD5とリビジョンをサーバーに登録 • バイナリのMD5 と リビジョンの相互参照が可能 • ‘dev’属性としてマーク • テストに移行

21.

ビルド / 結果の取り扱い / 成功時 / 実装 • バイナリのコピーはrobocopy • バイナリのファイルパスや属性は phpで受け口を作り、情報をMongoDBに格納 • phpへの送信はC#のコマンドラインツールを実装 • System.Web.WebClientクラスで10行程度

22.

ビルド / 結果の取り扱い / 失敗時 Repository CI Server Developers

23.

ビルド / 結果の取り扱い / 失敗時 • 開発者にエラーを通知 • メールによる通知は廃止 • リアルタイム性を重視 • チャットに流す • Skype for Business, IRC, Slack, ...

24.

ビルド / 結果の取り扱い / 失敗時 / 実装 • エラー監視プロセスをJenkinsのジョブに登録 • 業務時間の開始から終了までの間、毎日実行 • 情報取得はJenkins Remote access APIを利用 • チャットツールへの通知は Lync APIを利用 CI Watch dog Developers

25.

テスト / 全体像 Server CI Server Developers

26.

テスト / テストの実行 Server CI Server Developers

27.

テスト / テストの実行 • 事前に定義されている動作テストを実行 • 起動, ゲームの実行, メモリリークテスト • スクリプトビルドの互換性テスト • API変更はObsolete属性による移行期間設置をルール化 • 内製テストスイート • エンジンの挙動を非侵入的にテスト • テスト結果はJUnit形式で出力

28.

テスト / 結果の取り扱い Server CI Server Developers

29.

テスト / 結果の取り扱い / 成功時 Server CI Server Developers

30.

テスト / 結果の取り扱い / 成功時 • サーバー上の属性を格上げ • ‘dev’から’stable’へ • シンボルサーバーに登録 • .dmpのデバッグ時にローカルシンボルが不要になる • “symstore”で検索 • 配信開始

31.

テスト / 結果の取り扱い / 失敗時 Server CI Server Developers

32.

テスト / 結果の取り扱い / 失敗時 • 開発者にエラーを通知 • ビルド失敗時と同様

33.

配布 / 全体像 Server Users

34.

配布 • ‘ブランチ名+構成+属性’で管理 • ‘trunk__81f16f39_00000000_stable’ • ユーザーはクライアントツールを通じて取得 • 取得する構成はタイトルごとに定義される • 参考 • アップデートは1日あたり15回 • trunkへのコミットは20回

35.

まとめ Repository Developers CI Server Users

36.

見てもらえるCIへ 遭遇した問題と解決した方法

37.

CI導入の先にあったもの • 現場の歓迎する声 • 手動のデプロイが不要に • 従来は動作テストとリリースが手動 • エンジンのビルドはエンジンチーム任せ • 従来はタイトル開発者が自席でエンジンをビルド • 新たな問題 • チャットに情報を流しても対処されるまでが長い

38.

観察していてわかったこと • 「どこを見たらよいのかわからない」 • 普段のビルドツールとは見た目が違うので戸惑う • “Jenkins”というだけで身構えてしまう人もいる • Jenkinsのページは開いてくれている • 対処が遅いのではなく、失敗理由がわかりづらい • スレーブPCやビルドツールの問題も発生する • 「Jenkinsよくわからない」に拍車を掛けてしまった

39.

出来上がったもの • Jenkins上の情報を まとめたページ • 構成ごとに 配布中バージョン ビルド中バージョン コミットログ を表示

40.

出来上がったもの • Jenkins上の情報を まとめたページ • 構成ごとに 配布中バージョン ビルド中バージョン コミットログ を表示

41.

出来上がったもの / ビルドエラー時 • エラーと警告を表示 • 異常だと一目でわかる • ログをパースして 関連する行のみを表示 • 誰にでも理解できる • Visual Studioと同じ

42.

出来上がったもの / テストエラー時 • ビルドエラーと 見た目を統一 • よくあるテスト失敗の 場合は解決策も提示

43.

出来上がったもの / CIエラー時 • CI側の問題は別枠扱い • 迷わずCI担当者を 呼んでもらえるように • CI担当者いなくても ビルドフローを リセット可能 • 時間のロスと引き換え

44.

出来上がったもの / 実装 • Jenkins の Remote access API を活用 • ほとんどの情報をJSON形式で取得可能 • php で json_decode() するだけ • CIエラーか否かの判定はログのパースで行う • svnコミットログは php 内で参照 • Svn::log()

45.

得られた効果 • 狙い通り • すぐにエラーを直してもらえるようになった • CI担当者としてのメリット • Jenkinsを明確に意識させる必要がなくなった • Jenkins側を複雑なジョブ構成をしても困らない • Jenkins上の様々なデータを集約可能 • ビルドフロー上は関連のないジョブの状態をまとめて表示

46.

まとめ • Jenkinsの標準UIは万人受けしない • 慣れてもらうまでの時間が長い • シンプルなUIは受け入れられやすい • エラーを放置したい人はいない • できるだけ早くエラー内容を確認できる手段が重要

47.

Webサービスの提供 欲しい情報へのアクセスを手軽に

48.

Webサービスのススメ • Webサービス化は業務効率を高める • 人の問題 • Webブラウザを立ち上げることに抵抗がない人が多い • デジタルネイティブ世代 • デバイスの問題 • WebはデバイスやOSを選ばない • スマートフォン、タブレット端末、PC • ビルド状態の確認以外にも様々なページを運用

49.

更新情報 / 動機 • 通知メールを後から探すのが大変 • 関係のないメールまで結果に含まれてしまう • 探す人の検索能力に依存する • 検索機能をエンジンチームから提供 • 不要な情報が入り込む余地が無い

50.

更新情報 / Webページ

51.

更新情報 / Webページ

52.

更新情報 / 実装 • フォームからPOSTされた内容を メール送信した直後にMongoDBへ登録 • 表示と検索には DataTables を採用 • サーバーはMongoDBの格納データを全部返す • Webブラウザ内でフィルタリング • 5,000+件の更新内容でもストレスなく検索可能

53.

更新情報 / 効果 • 概ね好評 • タイトル開発者に多く利用されている • チャットツールで引用されるようになった • 以前:「○○さんがメールを送信されていたような」 • 現在:「http://.../ で報告されていますよ」

54.

更新情報 / 今後の課題 • SVNとの連携が薄い • 「このリビジョンについては告知がされていない」 という問題の検出ができない

55.

クラッシュレポート / 動機 • クラッシュ時のメール通知を行っていた • 数十件のメールが毎日のように届く • 同じ箇所でクラッシュしたメールも大量に届く • 過去のクラッシュ情報の検索と追跡が困難 • 修正状況を確認することができない • きちんとデータベースで管理するべき

56.

クラッシュレポート / Webページ

57.

クラッシュレポート / Webページ

58.

クラッシュレポート / Webページ

59.

クラッシュレポート / Webページ

60.

クラッシュレポート / 実装 • メールの代わりにサーバーへ情報をPOST • サーバーはMongoDBに書き込み • 同一案件があればマージ • スタックトレースを比較 • WebページはMongoDBの内容を表示 • 基本は更新情報のページと同じ • 修正状況の更新があれば報告者にメール通知 • 「調査を開始しました」、「修正されました」

61.

クラッシュレポート / 効果 • 同一案件のマージは効果が絶大 • 開発者も修正する気になる • 再発案件の検出も可能に • 進捗の通知メールは利用者を安心させる • メール通知の時は送りっぱなしだった • クラッシュレポートを送信するモチベーションに

62.

クラッシュレポート / 今後の課題 • 案件マージの限界 • 似ている案件をマージすることができない • スレッドごとスタックトレースは異なる • 異なるプラットフォームのマージが困難

63.

その他 / 動機 • 世の中のサービスは便利なものが多い • SlideShare, wandbox, Shadertoy, ... • 社内からアップロードはできない • 社内にも欲しい • 開発中エンジンの機能紹介もスライドでやりたい • 異なるコンパイラで挙動を確認したい • シェーダーも書きたい

64.

その他 / Webページ

65.

その他 / Webページ

66.

その他 / Webページ

67.

その他 / 効果 • 思っていたよりも多くの利用者が訪問 • UIに不自由があっても使ってもらえる • アウトプットの場を求めている人が多かった • 情報のアウトプットに抵抗感のない人が多い • スマートデバイスとSNSが浸透したことのメリット • 純粋に研究を行いたい人にも好評

68.

第一部のまとめ • CIを導入することで手動作業を廃止 • 安定した環境を利用者に提供 • 見てもらえるCIは専用のWebページから • Jenkinsの情報を開発者フレンドリーな形へ • 社内Webサービスでやりたいことを形にする • 開発者のアウトプットしたい気持ちを無駄にしない

69.

第二部 エンジン採用タイトルを サポートするCI

70.

アジェンダ 1.複数構成のデプロイ 2.エンジンに依存するツールの自動更新 3.CIマシンでのダンプ解析 4.自動プロファイル 5.エンジン開発者と利用者のビルドエラーフロー

71.

CIの運用紹介 複数構成のデプロイ

72.

基本のCIビルドパイプラインのおさらい CI Build Test エンジン開発者 トランクにコミット エンジン利用者 エンジン配布

73.

複数構成の必要性 エンジン利用者A 全部の機能が入った マスターのエンジンが 欲しい CI Build Test エンジン利用者B XXXミドルウェアは いらないから 除外して欲しい エンジン利用者C セキュリティの都合で ネットワーク系の機能を 全て除外して欲しい

74.

ブランチでの提供 エンジン利用者A 全部の機能が入った マスターのエンジンが 欲しい トランク コミット エンジン開発者 エンジン利用者B CI 各ブランチ コミット Build Test XXXミドルウェアは いらないから 除外して欲しい エンジン利用者C セキュリティの都合で ネットワーク系の機能を 全て除外して欲しい

75.

CIでの提供 エンジン利用者A 全部の機能が入った マスターのエンジンが 欲しい トランク コミット エンジン利用者B CI エンジン開発者 Build Test XXXミドルウェアは いらないから 除外して欲しい エンジン利用者C 各構成用の変更を加え、 各構成の数だけ エンジンを生成 セキュリティの都合で ネットワーク系の機能を 全て除外して欲しい

76.

複数構成デプロイの主な処理 1. 必要な構成設定を作成 2. コミット時に構成の数だけCIのジョブを発行 3. 各CIジョブの最初でワークスペースのデータに対 して構成設定の適応 4. 各CIジョブは各構成のエンジンをデプロイ

77.

構成の切り分け方針 • 基本はマクロでの各機能のON・OFF • .h .csproj .batなどのファイルを自動生成 • ソリューションから不要な設定の削除 • .sln .csprojから該当のビルド設定・参照設定を排除

78.

構成設定の作成ツール

79.

CIジョブの発行 構成の数だけ 下流ジョブを生成 Build Job A トランク コミット Start Job CI エンジン開発者 Build Test Build Job B Build Job C

80.

デプロイまでのフロー CI Build Job A Test Job A エンジン利用者 Build Test 取得した構成を元に ソースコードの自動生成 設定ファイルから不要な構成の削除 各ユーザーが望む構成で エンジンを配布

81.

CIの運用紹介 エンジンに依存する ツールの自動更新

82.

エンジンに依存するツール エンジンコードを 参照している 依存関係にある エンジン ツール

83.

ツールの自動更新 ツール 依存しているコードが 更新されたら 自動的にツールをビルドして コミット CI エンジン開発者 トランクにコミット

84.

CIの運用紹介 CIマシンでのダンプ解析

85.

クラッシュ時のフロー クラッシュ エンジン スタックトレースなどから クラッシュの概要を作成し サーバーに送信 上記の処理に必要なDLL等が存 在しない環境でエンジンが使用 されることがある エンジン開発者

86.

CIでのダンプ解析 クラッシュ エンジン エンジン開発者 サーバーにダンプファイルを アップロード CI上でダンプファイルを解析して 結果をJson形式で返す CI

87.

CIの運用紹介 自動プロファイル

88.

多様なエンジン構成 プラットフォームA プラットフォームB Debug Release マスターエンジン シーン A シーン B シーン C XXXミドルウェアなし エンジン ネットワークなし エンジン Master プラットフォームC

89.

早期発見したい問題 特定の構成・特定のシーンの 処理速度がいつの間にか低下している ・CIによる自動的なプロファイル

90.

自動プロファイルのフロー CI エンジン 内製プロファイラでの プロファイル プロファイルの結果を ファイルサーバーと MongoDBに保存

92.

CIの運用紹介 エンジン開発者と利用者の ビルドエラーフロー

93.

エンジン開発者のビルドエラーフロー トランクにコミット ビルド エラー CI エンジン開発者 失敗を通知 トランクはエラー状態 修正されるまで ビルドは通らず エンジンも配布されない

94.

エンジン開発者と利用者のデータ更新関係 エンジン開発者 エンジン利用者 ビルドが通らない環境を 配布されても困る CI エンジンプログラマ タイトルプログラマ 正常なCIビルドフローを おこなったリビジョンのみ配布 エラーが出たら解決されるまで 全てのデータ更新が止まる アーティスト ここのデータ更新は いつでも素早く行いたい CIで更新を止めるのは イテレーション速度の低下 につながる

95.

エンジン利用者のビルドエラーフロー トランクにコミット ビルド エラー CI エンジン利用者 失敗を通知 コミットそのものが 取り消される トランクは常に コンパイルが通る状態 テスト等の厳密な 動作チェックはせず イテレーション速度を重視

96.

第二部のまとめ ・複数構成のデプロイ マクロ定義での切り分けで自動化対応 ・利用者の更新をロックしないビルドエラーフロー

97.

LICENSE • Microsoft Cloud and Enterprise Symbol Set Version 2.3 • https://www.microsoft.com/en-us/download/details.aspx?id=41937 • https://azure.microsoft.com/en-us/documentation/articles/architecture-overview/ • Jenkins Logo Artworks • Jenkins project (http://jenkins-ci.org/)

98.

本編で解説しきれなかったこと 附録

99.

post-commit スクリプト(CentOS 6.3で運用) REPOS="$1" REV="$2" # ----------------------------------------# BRANCH NAME EXTRACTION. # ----------------------------------------LOOKDIRS=`svnlook dirs-changed -r $REV $REPOS` LOOKFILES=`svnlook changed -r $REV $REPOS` MESSAGE=$(svnlook log $REPOS -r $REV) IFS=/ ary=($LOOKDIRS) if [[ $LOOKDIRS == trunk* ]] then branchName=${ary[0]} elif [[ ( $LOOKDIRS == branches/releases* ) ]] then ary2=($LOOKDIRSFILES) branchName=branches%2freleases%2f${ary2[2]} Fi # -----------------------------------------# CANCEL BUILD TRIGGER IF MESSAGE SAYS SO. # -----------------------------------------if [[ ( $MESSAGE == *¥[ignore¥]* ) ]] then branchName="" elif [[ ( $MESSAGE == *¥[docs¥]* ) ]] then branchName="" fi # -----------------------------------------# INVOKE JENKINS. # -----------------------------------------if [[ -n "$branchName" ]] # NOP then wget -O /dev/null http://jenkins.yours.com/job/BuildEngine/build?token=startBuild¥&BRANCH_NAME=$branchName Fi