フロム・ソフトウェアが語るデバッグメニュー最適化テクニック。ネットワークを活用し、ロード待ちが13秒→15ミリ秒以下に【CEDEC2023】

2023.11.01
CEDEC注目記事ゲームづくりの知識ゲームの舞台裏講演レポートCEDEC2023プログラム
この記事をシェア!
Twitter Facebook LINE B!
Twitter Facebook LINE B!

国内最大規模のゲーム業界カンファレンス「CEDEC2023」が、2023年8月23日(水)から8月25日(金)までの日程で開催されました。初日となる8月23日には、フロム・ソフトウェア R&Dセクション チーフプログラマー 清水 俊宏氏が登壇。「ゲームの外から操作する柔軟なデバッグメニューシステム」と題する講演が行われました。

デバッグメニューの概要から、従来の自社デバッグメニューの問題点に対するアプローチまで解説された本講演をレポートします。

TEXT / wvigler

EDIT / 神谷 優斗

目次

清水氏は2012年にフロム・ソフトウェアに入社。ゲームプログラマーセクションで『DARK SOULS Ⅱ』などの開発に関わった後、2017年からはR&Dセクションで開発基盤ライブラリなどに携わっています。

フロム・ソフトウェアのデバッグメニューに見られる2つの特徴

一般に、デバッグメニューはデバッグ作業を効率化するメニューUIを指します。実行中のゲームに対する内部プロパティの確認・編集や、デバッグ機能の呼び出しなどが主な機能です。

下記画像では、デバッグメニューからHPのプロパティを編集しています。緑色の数字で示されたデバッグメニュー上のHPを編集すると、ゲーム内のHP(赤いゲージ)に反映されます。

プロパティの確認・編集機能があることで調整が容易になる

また、下記画像ではエネミーを生成するデバッグ機能を呼び出しています。リストから生成機能を選択すると、甲冑を着たプレイヤーの隣にエネミーがスポーンします。

この機能は、エネミーAIの調整に加え、アニメーションや表示に問題がないかを確認する作業に活用されています。

数万のデバッグ項目を一元管理

フロム・ソフトウェア特有のデバッグメニューには、「デバッグ項目が階層構造で構成されている」「ゲーム内のほとんどの要素をデバッグメニューに登録している」という2点の特徴があります。

利用者は、文字列のリストから使用するデバッグ機能を選択する

マップやパラメータ、イベントなど、2~4万にも及ぶゲーム内要素をほぼすべてデバック項目として登録している

膨大な項目×登録処理の重さで負荷が爆発

前述のデバッグ項目数が多い特徴は、登録時の高い処理負荷と相まって「ロードが遅い」などの問題点を抱えていました。

ほかにも、エラーの原因が分かりにくいなどの問題が多数あった

特に起動時やマップ入場時には、数万件のデバッグ項目の登録・破棄に加え、それぞれにメモリ管理登録先の探索などの重い処理が行われていました。そのため、起動時に十数秒、マップへの入場やワープを行うと数秒の待ち時間が発生していたとのこと。

また、スレッドセーフでない構造もロード時間を長くしていました。スレッドセーフでない場合は並列処理が行えず、シングルスレッドで処理する必要が生じます。そのため、処理完了までの待ち時間がさらに増加します。

並列処理(左)では負荷を分散できる一方、シングルスレッド(右)では重い処理がボトルネックになってしまう

システムを刷新し、13秒のロード待ちを1f未満まで短縮

従来のデバッグメニューシステムで生じていた処理負荷やロード時間の長さなどの問題に対応するために、新たなデバッグメニューシステムを根本から作り直すことになりました。

登録・破棄をゲームループで行わないように

ロードの長さの改善では、最初に旧デバッグメニューにおける負荷の高い処理を特定するための調査が行われました。

調査の結果、メモリ操作やインスタンスの初期化を伴う登録・破棄プロセスが特に重いことが判明。一方で、プロパティの編集や適用は、各操作に対応して実行される処理であるため負荷は軽微だったそうです。

これを踏まえ、非同期処理を活用して処理をゲームループ外に逃がす構造が検討されました。「多少遅延してもよい処理」や「ゲームの情報を直接参照する必要のない処理」などは別スレッドで実行し、ゲームループのスレッドではゲームの実行に必要最低限の処理のみ行う設計です。

旧デバッグメニューではゲームループ側からデバッグメニューの登録・破棄処理が呼び出されると、処理が終了するまでゲームループが停止します。

同様に、プロパティが変化した際はゲームループ側からデバッグメニューに編集処理をコール。編集の結果をゲーム側に反映するコールバックを待つ間はゲームループが停止します。

ゲームループを止めていた処理のうち、登録・破棄・編集の大部分が別スレッドに逃がせることが分かったとのこと。

もとのスレッドでの処理は、操作の呼び出しや結果の適用のみにできる

調査結果をもとに、新デバッグメニューの構造を検討した結果、処理を「クライアント」「サーバー」「ゲームシンク」の3つのカテゴリに分割するシステムが考案されました。

クライアント:ユーザーの操作を受け取り、処理の呼び出しを行う

サーバー登録・破棄・編集処理などの移譲先。別スレッドで実行される

ゲームシンク:編集によって変更されたプロパティをゲームへ適用する

動作イメージ。処理の呼び出しはコマンドを発行する形式に変更している

ゲーム側で操作があった場合、「クライアント」から「サーバー」に向けてコマンドを発行します。「サーバー」はコマンドを受け取ると、実際のデバッグ処理として登録・破棄・編集を実行。結果としてゲームに値の変更が必要になった場合、「サーバー」から「ゲームシンク」に向けて通知を行い、「ゲームシンク」がゲームに値を適用します。

カテゴリを分割することにより、ゲームループでの実行は負荷の軽い「クライアント」と「ゲームシンク」のみにできます。重い処理を担う「サーバー」は専用のスレッドで実行されるため、ゲームループへの影響を減らせます。

デバッグをネットワークから遠隔で実行

従来のシステムは、処理全体が1つのプロセス・PCで完結するのを想定して設計されていました。

新たなシステムは処理をスレッドに分けたことで、処理を別のプロセスに移譲できます。それに伴い、スレッド間のやり取りをネットワークに対応させるのみで、容易にデバッグ作業を遠隔操作できるようになりました。

サーバーの処理をネットワークにある別のPCに逃がせるだけでなく、サーバー側からゲームを操作することも可能に

ネットワークによる遠隔操作には、次に挙げる2点のメリットがあると清水氏は言います。

1つは、プラットフォームなどの動作環境に依存せず、同じ操作感でデバッグできる点です。

フロム・ソフトウェアでは、マルチプラットフォーム開発が基本とのこと。しかし、プラットフォームごとに異なる仕様や操作感に合わせてデバッグメニューを調整するのは技術的なコストの高い作業です。加えて、数年ごとに新しい世代への対応が必要となります。

この課題は、PCから各プラットフォームを遠隔操作できるようにすることで解決可能です。加えて、サーバーなど描画の行われない環境に対してデバッグできるのも付加価値となります。

2つめは、自動テストの実現です。

デバッグメニューに登録されるゲーム内のほとんどの要素を遠隔で操作できれば、自動テストをゲーム外から実行できます。クライアントから順番に操作を送信すれば実行できるため、スクリプトなどで自動テストが記述できます。

新デバッグメニューに遠隔操作機能を導入するにあたって、まずは社内の通信ライブラリを使用してコマンドの送受信をネットワーク上で行えるように変更。ネットワークを経由した、プロセスや機材をまたいだ運用が実現できます。

さらに、サーバー側を複数のクライアント受付に対応。これにより、さまざまな機材やプロセスから遠隔操作できる状態となりました。

処理は先に接続されたクライアントから順に実行される

新デバッグメニューにおける処理の流れ

新しいデバッグメニューの使用例として挙げられたのは、HP(ステータス)登録時のサーバー・クライアント間での動作です。

新しいデバッグメニューでは、デバッグが呼び出されてもゲーム側では実際のデバッグ処理は行われません。クライアント対応するコマンドをコマンドバッファに書き込み、今後の操作のためのハンドルをゲーム側に渡します

コマンドバッファへの書き込みは単純なコピーであるため、ゲームスレッドへの負荷は大きくありません。また、スレッドセーフな処理であるため、並列して実行できます。

サーバー側ではコマンドバッファからコマンドを読み取り、実際の処理を行います。この例ではハンドルに対してパスを割り当てて高速にアクセスできるようにした後、デバッグ項目の作成、作成時のメモリ確保・初期化などの処理が行われます。

続いて、ゲームシンクによる同期を含む、値の書き換え処理の例が紹介されました。

サーバー側で管理しているデバッグ項目の値が書き換えられた際、サーバーはゲームシンクに対する適用処理のコマンドをコマンドバッファに書き込みます。そして、ゲームシンクはコマンドバッファからコマンドを読み取り、ゲーム側に適用します。

クライアント・サーバー・ゲームシンクのやりとりにコマンドバッファを介することで、非同期での実行を実現しています。

改善の結果、ロードの待ち時間はほぼ無くなったとのこと。起動時のロードを想定した4万件のデバッグ項目作成では、13秒かかっていたロード待ちが1フレーム未満に収まっています。

複雑な階層や操作手順を、リンクで共有できるように

デバッグメニューの刷新に伴い、「操作感の統一」や「ロード待ち時間の短縮」などのほかにも複数の改善が実施されました。

講演では、URI(※)を使ったクエリコマンドを中心に、新たに導入した3つの機能が紹介されました。
※ Web上の場所を表す「URL」と、Web上の名前を表す「URN」の総称

共有しやすいよう、デバッグ項目の階層をリンク化

多数のデバッグ項目が階層化されている同社のデバッグメニューの場合、デバッグ項目の場所を把握しきれないことも多かったそう。

そのため、ほかのメンバーにどの階層に目的の項目があるかを尋ねるシチュエーションが頻発していたと言います。このフローでは、教える側は書き起こす手間、教えられる側はメニュー項目を探す手間が発生します。

そこで、新デバッグメニューではリンクでデバッグ項目を共有できるようにして手間を軽減しています。

リンクを介したやり取りには、後述する2つの機能が必要でした。

1つは、「デバッグ項目をリンクとしてコピーする」機能です。デバッグメニューのウィンドウ情報をゲーム側で受け取り、URIコマンドへと加工。加工後はクリップボードに適用し、チャットツールなどで受け渡せるようにします。

もう1つは、「リンクを実行する」機能です。ゲーム側はクライアントに対してリンク処理を要求。URIコマンドの解析はサーバー側で行われ、コマンドに対応した処理が実行されます。

なお、URIコマンドはプロパティ名の変更に対して安全な構造になっているそうです。

URIコマンドを使用した、デバッグ手順の再現

URIコマンドは、デバッグ操作の再現にも使用されています。

同社がこれまでに開発してきたタイトルは、イベントの確認に必要なイベントフラグやキーアイテムの入手、ステータスなどの事前準備が多い傾向にあり、デバッグにも大きな工数が発生していました。

そこで、デバッグメニューで行った操作をURIコマンドとして記録し、再現できるようにすることで、イベント確認のコストを削減しています。

生成されるURIコマンドは、値の代入などデバッグメニューのすべての操作に対応しています。そのため、一連の操作を1つずつURIコマンドとして記録することでデバッグ手順が再現できます。URIコマンドは1行のリンクに結合し、同じリンクを2度実行するのを避けています。

清水氏はURIコマンドを使用した理由として、もとよりほぼ全ての処理に対応しているため実装コストが低い点、バイナリデータより可読性・互換性を担保しやすい「テキストベース」である点、手順をリンクとして共有できる点を挙げました。

操作は、サーバーでの実行・適用時に記録されます。その際、「デバッグ項目のパス」と「結果の代入コマンド」がURIコマンドに整形されるとのこと。

記録した操作は、デバッグ項目へのリンクと同様にメールなどで共有できるほか、ショートカットから呼び出すことも可能です。

Luaによるスクリプト制御への対応

多くの自動テストはURIコマンドでカバーできる一方で、URIコマンドでは難しい柔軟な制御にはC++などのコンパイル必須の言語が使われており、手間がかかっていました。

そこで、社内ライブラリが充実しているLuaに対応し、より手軽にスクリプトによる柔軟なテストが可能としました。

遠隔操作に関する今後の展望

最後に、清水氏はデバッグメニューの遠隔操作に関する今後の展望を2つ明かしました。

自動操作によるテスト機能の実装

1つは、未達成となっている自動テストの実現です。

今後実現したい自動テストの一例として、エネミー生成の自動チェックが挙げられました。実現できれば、ゲーム上でエネミーを生成し、不足している設定やデータがないかを自動的にチェックできます

「エネミー生成」から「エラーチェック」、「問題があれば担当者に連絡して修正を促す」までの一連の流れを全エネミーにおいて網羅的に行う

清水氏は、これらのテストについて「今後は新規に用意したスクリプト機能で簡単に量産できる環境に持っていきたい」と話しています。

各エディタからのデバッグに対応

もう1つは、各コンソールへの遠隔操作をエディタからの操作に対応させることです。

これには、同社が使用している複数のエディタとの連携にかかる実装コストの重さを、新デバッグメニューによって軽減する狙いがあります。

同社は統合的なエディタではなく、領域ごとに異なるエディタを使用している

清水氏は、通信プロトコルを統一できる点や、デバッグメニューにすでに実装されているエディタ連携機能をそのまま利用できる点から、エディタを通した遠隔操作には価値は十分にあると語りました。

ゲームの外から操作する柔軟なデバッグメニューシステム - CEDEC2023フロム・ソフトウェア 公式サイト
wvigler

アンリアルエンジンにハマり、ぷちコンでゲーム作ってた男。映像編で2連覇したことも。
昔はよくアーケードゲームとかやってました。
一番やり込んだのは「ケツイ ~絆地獄たち~」「戦国BASARAX」あたり。ローグライトゲームとかも好きです。

関連記事

ゲームプログラミングにおけるデザインガイド、ユニティ・テクノロジーズ・ジャパンが日本語版の電子書籍を無料公開
2024.09.30
『ゼルダの伝説 ティアーズ オブ ザ キングダム』地上から地底、空へ拡張された広大なハイラル世界を“途切れなくシームレス”に移動させるための技術【CEDEC2024】
2024.09.04
Unity Technologies、プログラマー向けデザインガイドの電子書籍をアップデート。ストラテジーなど4種のパターンが追加され、Unity 6対応に
2024.07.26
Epic Gamesが開発中のプログラミング言語「Verse」って知ってる?編集部員が感じる2つの特徴「ロールバック」「非同期処理」などを解説
2024.06.12
Apple、統合開発環境「Xcode 16」のベータ版をリリース。予測的コード補完エンジンや、処理負荷を可視化する「flame graph」の実装など
2024.06.11
「シェーダー最適化入門」、サイバーエージェントのゲーム・エンタメ技術組織が新設ブログで公開
2024.06.10

注目記事ランキング

2024.11.14 - 2024.11.21
VIEW MORE

連載・特集ピックアップ

イベントカレンダー

VIEW MORE

今日の用語

フォワードシェーディング(Forward Shading)
フォワードシェーディング オブジェクト毎にライティングの計算を行い、その計算結果を描画するレンダリング手法。フォワードレンダリングともいう。ディファードシェーディング(Deferred Shading)に比べてポストプロセスの自由度は低いが、(何も物を配置しなかった際にかかる)最低限の描画コストが低く、アンチエイリアス処理などにおいてフォワードシェーディングの方が有効な分野も存在する。
VIEW MORE

Xで最新情報をチェック!