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

Cygamesにおける次世代ハイエンドコンソール向けゲームエンジンの開発 ~最高のコンテンツを...

Cygames
September 08, 2017

Cygamesにおける次世代ハイエンドコンソール向けゲームエンジンの開発 ~最高のコンテンツを支えるゲームエンジン~

2017/08/30 CEDEC 2017

Cygames

September 08, 2017
Tweet

More Decks by Cygames

Other Decks in Technology

Transcript

  1. © 2017 Cygames, Inc. サマリー • Cyllista Game Engine の紹介

    • ゲーム開発者がイテレーションを速く回せる ようにするための取り組み 2
  2. © 2017 Cygames, Inc. 自己紹介 • 多胡 順司 • 株式会社

    Cygames • 技術本部 Cyllista Game Engine 統括マネージャー 3
  3. © 2017 Cygames, Inc. Cyllista Game Engine 6 内製統合型ゲームエンジン ランタイム

    + エディタ ハイエンドコンソール向け PlayStation 4
  4. © 2017 Cygames, Inc. エンジンの目標 • ハードウェアの性能を最大限に引き出す – ジョブシステム –

    データ指向設計 • http://tech.cygames.co.jp/archives/2843/ 9 ハードウェアが最高のパフォーマンスを出せる
  5. © 2017 Cygames, Inc. エンジンの目標 • コンテンツ制作者 – ゲームデザイナー、レベルデザイナー –

    アーティスト – サウンドデザイナー – QA – ゲームエンジニア • エンジン開発者 11 ゲーム開発者が最高のパフォーマンスを出せる
  6. © 2017 Cygames, Inc. エンジンの目標 13 最高のゲームエンジン ハードウェアが 最高のパフォーマンスを 出せる

    ゲーム開発者が 最高のパフォーマンスを 出せる 今回はこちらの話 が中心!
  7. © 2017 Cygames, Inc. ゲーム開発者 14 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 • エンジニア • エンジニア • ゲームデザイナ • アーティスト • サウンドデザイナ
  8. © 2017 Cygames, Inc. ゲーム開発者 15 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 モジュール化 テスト駆動開発 開発ツール ユーザーコード 開発効率の最適化 アセットシステム アセット プレビュー 開発言語の統一 コードの自動整形 ビルド時間の短縮
  9. © 2017 Cygames, Inc. エンジン開発者向け 16 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 モジュール化 テスト駆動開発 開発ツール ユーザーコード 開発効率の最適化 アセットシステム アセット プレビュー 開発言語の統一 コードの自動整形 ビルド時間の短縮
  10. © 2017 Cygames, Inc. モジュール • 依存は下向きの一方向 – 相互依存不可 •

    モジュールごとに DLL化 19 Core Gfx … Game Tool Kit Anm Col Snd
  11. © 2017 Cygames, Inc. モジュール化の利点 • ユーザー視点 – 必要なモジュールだけを取り出して利用可能 •

    開発者視点 – ビルド時間の短縮 • 依存しているモジュールだけで開発可能 • 開発しているモジュールだけがリンク対象 20
  12. © 2017 Cygames, Inc. テスト駆動開発 • テストを書く 24 // MySystem.h

    // MySystem.cpp // MySystemTest.cpp // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); }
  13. © 2017 Cygames, Inc. // MySystem.h // MySystem.cpp テスト駆動開発 •

    テストが失敗する 実装を書く 25 // MySystem.h class MySystem { }; // MySystem.cpp MySystem* MySystemGet() { return nullptr; } // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); }
  14. © 2017 Cygames, Inc. // MySystem.cpp MySystem* MySystemGet() { return

    nullptr; } テスト駆動開発 • テストが通る 最低限の実装を書く 26 // MySystem.h class MySystem { }; // MySystem.cpp class MySystemImpl : public MySystem { }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); }
  15. © 2017 Cygames, Inc. // MySystemTest.cpp void MySystemTest() { MySystem*

    mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); } テスト駆動開発 • 新たなテストを書く 27 // MySystem.h class MySystem { }; // MySystem.cpp class MySystemImpl : public MySystem { }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); MyObject* obj = mySystem->createObject(); ASSERT_TRUE(obj != nullptr); }
  16. © 2017 Cygames, Inc. // MySystem.h class MySystem { };

    // MySystem.cpp class MySystemImpl : public MySystem { }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } テスト駆動開発 • テストが失敗する 実装を書く 28 // MySystem.h class MyObject { }; class MySystem { virtual MyObject* createObject() = 0; }; // MySystem.cpp class MySystemImpl : public MySystem { virtual MyObject* createObject() { return nullptr; } }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); MyObject* obj = mySystem->createObject(); ASSERT_TRUE(obj != nullptr); }
  17. © 2017 Cygames, Inc. // MySystem.cpp class MySystemImpl : public

    MySystem { virtual MyObject* createObject() { return nullptr; } }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } テスト駆動開発 • テストが通る 最低限の実装を書く 29 // MySystem.h class MyObject { }; class MySystem { virtual MyObject* createObject() = 0; }; // MySystem.cpp class MyObjectImpl : public MyObject { }; class MySystemImpl : public MySystem { virtual MyObject* createObject() { return new MyObjectImpl(); } }; static MySystemImpl g_mySystem; MySystem* MySystemGet() { return &g_mySystem; } // MySystemTest.cpp void MySystemTest() { MySystem* mySystem = MySystemGet(); ASSERT_TRUE(mySystem != nullptr); MyObject* obj = mySystem->createObject(); ASSERT_TRUE(obj != nullptr); }
  18. © 2017 Cygames, Inc. TDD の利点 • コードが安定する – CI

    (Jenkins) などで常時実行 • ユーザー視点での API の設計 • リファクタリングの障壁が下がる – コードがさらに安定 30
  19. © 2017 Cygames, Inc. cybuild コマンド • cybuild update –

    ソースコード・ツール・アセットの更新 • cybuild test <module> – モジュールのテスト • cybuild push – ソースコード・ツール・アセットのサブミット 38
  20. © 2017 Cygames, Inc. cybuild によるテスト駆動開発 • cybuild test Gfx

    premake build run – Gfx モジュールのビルド・テストの実行 • cybuild test Gfx premake build run -p ps4 – PlayStation 4 版のテスト • cybuild test Gfx premake --open – sln ファイルを開く 39
  21. © 2017 Cygames, Inc. cybuild の主な機能 • モジュールのテスト • ドキュメント生成

    • エディタの起動 • 中間ファイルの削除 • ファイルの変更状態の表示 42
  22. © 2017 Cygames, Inc. cybuild の利点 43 ツールのヘルプ • “-h”

    オプション • コマンド一覧 CI での実行 • そのまま組み込み すべてのツールを ひとつに! • 迷わない • 覚えることは ひとつ Doxygen
  23. © 2017 Cygames, Inc. プログラミング言語の統一 45 C++ • エンジンランタイム •

    速度の要求される アセット変換処理 Python • ツール • レベルエディタ • cybuild • アセット変換処理
  24. © 2017 Cygames, Inc. Python の利点 • ツールの配布が容易 – VCS

    (Perforce) に submit するだけ – 使う側は sync するだけ 47
  25. © 2017 Cygames, Inc. Python の利点 • コードの共有が容易 – 内製コードのモジュール化

    – import すればすぐに利用可能 48 from cy import log log.info(‘hello world!’)
  26. © 2017 Cygames, Inc. Python の利点 • テスト駆動開発 49 import

    unittest class MyModuleTest(unittest.TestCase): def test_do_something(self): self.assertTrue(…)
  27. © 2017 Cygames, Inc. ゲームプログラム開発者向け 55 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 モジュール化 テスト駆動開発 開発ツール ユーザーコード 開発効率の最適化 アセットシステム アセット プレビュー 開発言語の統一 コードの自動整形 ビルド時間の短縮
  28. © 2017 Cygames, Inc. ユーザーコードの開発効率 57 Core Gfx … Game

    Tool Kit Application Anm Col Snd テスト駆動開発 テスト駆動開発 + ?
  29. © 2017 Cygames, Inc. ユーザーコードはC++ 58 利点 • 速い •

    詳細な最適化が可能 • イテレーションが遅い • コンパイル • リンク • 読み込み 欠点
  30. © 2017 Cygames, Inc. Runtime Compiled C++ (RCC) 59 プログラムを実行中に

    C++ コードを更新可能 http://runtimecompiledcplusplus.blogspot.jp/
  31. © 2017 Cygames, Inc. RCC の原理 • RccObject クラス –

    RCC の最小単位 62 // MyActorA.cpp class MyActorAImpl : public MyActorA, public RccObject { ... }; // RccObject.h class RccObject { virtual void initialize() = 0; virtual void terminate() = 0; virtual void* getInterface(InterfaceId) = 0; virtual void serialize(Serializer*) = 0; };
  32. © 2017 Cygames, Inc. RCC の原理 • RccObject は システムで管理

    64 MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorA MyActorB MyActorC MyActorC MyActorC MyActorA
  33. © 2017 Cygames, Inc. RCC の原理 • .cpp ファイルの変更 を検出

    • 変更された .cpp を コンパイル • 一時的な .dll に リンク 65 MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorA MyActorB MyActorC MyActorC MyActorC MyActorA MyActorA’ .cpp tmp.dll
  34. © 2017 Cygames, Inc. RCC の原理 • 古いインスタンスを シリアライズ 66

    MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorA MyActorB MyActorC MyActorC MyActorC MyActorA MyActorA’ .cpp tmp.dll Serializer Serializer Serialize
  35. © 2017 Cygames, Inc. RCC の原理 • 不要になった RccObject を削除

    67 MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorB MyActorC MyActorC MyActorC MyActorA’ .cpp tmp.dll Serializer Serializer Deserialize
  36. © 2017 Cygames, Inc. RCC の原理 • 新しいコードから 新しいRccObjectを 生成

    • 古い状態を デシリアライズ 68 MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorB MyActorC MyActorC MyActorC MyActorA’ .cpp tmp.dll Serializer Serializer Deserialize MyActorA’ MyActorA’
  37. © 2017 Cygames, Inc. RCC の原理 • 新しいコードで動作 • 古いコードは

    利用されない 69 MyActorA .cpp MyActorB .cpp MyActorC .cpp MyApp.exe MyActorB MyActorC MyActorC MyActorC MyActorA’ .cpp tmp.dll MyActorA’ MyActorA’
  38. © 2017 Cygames, Inc. RCC サンプル 70 // RccObject の生成

    RccObjectHandle actorHandle = rccSystem->createRccObject(MY_ACTOR_A); // ハンドルからインターフェースを取得 MyActorA* actor = actorHandle.getInterface<MyActorA>(); // 処理の呼び出し actor->act();
  39. © 2017 Cygames, Inc. RCC サンプル 71 // MyActor.cpp class

    MyActorAImpl : public MyActorA, public RccObject { virtual void initialize(); virtual void terminate(); virtual void* getInterface(InterfaceId id) { if (id == MY_ACTOR_ID) { return static_cast<MyActorA*>(this);} return nullptr; } virtual serialize(Serializer* serializer); // MyActorA virtual void act(); };
  40. © 2017 Cygames, Inc. RCC の制限 • 外部関数呼び出しの制限 – inline

    / virtual 関数のみ • システム関数 – グローバル関数は virtual にできない – グローバル関数はシステムクラスのメンバ関数に – すべてのシステムクラスを SystemTable に登録 – SystemTable 自体のアドレスは tmp.dll 読み込み後に .dll 側の コードに渡す 72 MySystem* mySystem = SystemTableGet()->getMySystem(); mySystem->doSystemThings();
  41. © 2017 Cygames, Inc. エンジン API • すべての API を

    RccObject から呼び出し可能 73 inline • 軽量な関数 • 頻繁に呼び出される 関数 virtual • 複雑な関数 • 実装を隠蔽する 必要がある関数
  42. © 2017 Cygames, Inc. RCC の利点・欠点 利点 • 高速なイテレーション •

    SystemTable での API の一覧性 • コンパイル時間の短縮 – リンカがなにもしない • Visual Studio で デバッグ可能 欠点 • virtual 呼び出しの オーバーヘッド • 専用のシリアライズ処理 の実装の必要性 74
  43. © 2017 Cygames, Inc. ビルド時間 • 有効行数 40万行のフルビルド – エンジンコード

    + アプリケーションコード (13万行) – その他ライブラリコード 77 30秒
  44. © 2017 Cygames, Inc. ゲームコンテンツ開発者向け 82 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 モジュール化 テスト駆動開発 開発ツール ユーザーコード 開発効率の最適化 アセットシステム アセット プレビュー 開発言語の統一 コードの自動整形 ビルド時間の短縮
  45. © 2017 Cygames, Inc. アセットフロー 84 元データ ファイル 中間 ファイル

    実機用 ファイル アーカイブ ファイル エクスポート コンバート コンバート
  46. © 2017 Cygames, Inc. アセットコンバートフロー 85 Maya ファイル .ma モデル

    中間ファイル .imdl モデル ランタイムファイル .mdl アーカイブファイル .arc マテリアル 中間ファイル .imtl コリジョン 中間ファイル .icol コリジョン ランタイムファイル .col PSD ファイル .psd テクスチャ 中間ファイル .itex テクスチャ ランタイムファイル .tex マテリアル ランタイムファイル .mtl
  47. © 2017 Cygames, Inc. アセットのバージョン管理の問題点 • ファイルサイズが大きい • ファイル数が多い –

    更新処理に非常に時間がかかる • 依存が複雑 – 多数のファイルから依存されているファイルの更新が重い 87
  48. © 2017 Cygames, Inc. メタファイル • アセットの関係性の情報を保持 • 単一ディレクトリ以下にまとめる 89

    中間 ファイル 実機用 ファイル アーカイブファイル メタファイル メタファイル メタファイル
  49. © 2017 Cygames, Inc. バージョン管理 • 中間ファイルとメタファイルのみ バージョン管理 • 実機用ファイルとアーカイブファイルは

    中間ファイルから生成する 90 中間 ファイル 実機用 ファイル アーカイブファイル メタファイル メタファイル メタファイル
  50. © 2017 Cygames, Inc. アセットコンバートフロー 91 .imdl .mdl .arc .imtl

    .icol .col .itex .tex .mtl .imdl.meta .mdl.meta .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta 中間 実機用 アーカイブ
  51. © 2017 Cygames, Inc. アセットコンバートフロー 92 .imdl.meta .mdl.meta .arc.meta .mtl.meta

    .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta 中間 実機用 アーカイブ
  52. © 2017 Cygames, Inc. アセットコンバートフロー • アーカイブファイルをリクエスト 93 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc リクエスト 中間 実機用 アーカイブ
  53. © 2017 Cygames, Inc. アセットコンバートフロー • メタファイルの情報から 必要な実機用ファイルをリクエスト 94 .imdl.meta

    .mdl.meta .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc .mdl .col .tex .mtl 中間 実機用 アーカイブ
  54. © 2017 Cygames, Inc. アセットコンバートフロー • 更に必要な中間ファイルリクエスト 95 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc .mdl .col .tex .mtl .imdl .imtl .icol .itex 中間 実機用 アーカイブ
  55. © 2017 Cygames, Inc. アセットコンバートフロー • 中間ファイルは VCS から取得 96

    .imdl.meta .mdl.meta .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc .mdl .col .tex .mtl .imdl .imtl .icol .itex 中間 実機用 アーカイブ
  56. © 2017 Cygames, Inc. アセットコンバートフロー • コンバート処理 97 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc .imdl .imtl .icol .itex .mdl .col .tex .mtl 中間 実機用 アーカイブ
  57. © 2017 Cygames, Inc. アセットコンバートフロー • コンバート処理 98 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .imdl .imtl .icol .itex .mdl .col .tex .mtl .arc 中間 実機用 アーカイブ
  58. © 2017 Cygames, Inc. アセットキャッシュ • コンバート処理を毎回するのは重い • コンバート結果をキャッシュ –

    コンバート情報をハッシュ化した単純な key-value – ローカルキャッシュ – サーバーキャッシュ • キャッシュにヒットしなければ コンバート – 結果はローカル・サーバーに登録 100
  59. © 2017 Cygames, Inc. アセットキャッシュ • アーカイブファイルをリクエスト 101 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta .arc リクエスト 中間 実機用 アーカイブ
  60. © 2017 Cygames, Inc. アセットキャッシュ • キャッシュを取得して完了 102 .imdl.meta .mdl.meta

    .arc.meta .mtl.meta .col.meta .tex.meta .imtl.meta .icol.meta .itex.meta ローカル キャッシュ サーバー キャッシュ .arc 中間 実機用 アーカイブ
  61. © 2017 Cygames, Inc. 中間ファイル • 専用バイナリフォーマット – 出力処理の高速化 –

    読み込み処理の高速化 • プレビュー専用のモードを用意 – 表示に影響しない最適化を無効化 108
  62. © 2017 Cygames, Inc. 専用フォーマット vs FBX • 100,000トライアングルのモデルの エクスポート

    + コンバート時間 [msec] 109 0 100 200 300 400 500 600 700 800 900 1000 専用フォーマット FBX x3.6 高速!
  63. © 2017 Cygames, Inc. まとめ 111 エンジン 開発者 ゲームプログラム 開発者

    ゲームコンテンツ 開発者 モジュール化 テスト駆動開発 開発ツール ユーザーコード 開発効率の最適化 アセットシステム アセット プレビュー 開発言語の統一 コードの自動整形 ビルド時間の短縮
  64. © 2017 Cygames, Inc. まとめ 112 Cyllista Game Engine は

    ゲーム開発者が 最高のパフォーマンスを発揮できることを 徹底的に追求しています!!!