15-4. 最適化

最適化

パフォーマンス最適化はプレイヤー体験を大きく左右する要素です。ゲームがスムーズに動作することで、ユーザーの満足度が向上し、より多くのプレイヤーを引きつけることができます。以下で、Robloxのパフォーマンス最適化について、重要な点を見ていきます。

負荷の箇所を正確に見極める(2:8の法則)

パフォーマンスに関する問題は、ゲーム全体に散らばっているわけではなく、特定の箇所に集中していることが多いです。20%のコードや機能が80%のパフォーマンス問題を引き起こすことがあり、この原則は2:8の法則(パレートの法則)として知られています。最適化の取り組みでは、この20%の部分を特定し、改善に集中することが重要です。

負荷の種類

CPU負荷(計算負荷)

CPU負荷は、スクリプトの計算処理や物理シミュレーションなどの計算による負荷です。複雑な計算や多数のオブジェクトの処理、複雑な形状の物理処理などにより負荷があがります。CPU負荷が上がるとフレームレートの低下を引き起こし、カクついたり、ネットワーク同期にも影響を与えるなど、体験の質が著しく低下します。

メモリ負荷

メモリ負荷は、アセットやデータ構造が消費するメモリ量によって生じます。高精細なアセット(テクスチャやメッシュ)を利用することで負荷が上がります。Robloxは少し古いスマートフォンなど、メモリ量が小さい端末でも動作を期待されることもあり、特に大規模なゲームでは、適切なメモリ管理が重要となります。

ロード負荷

ロード負荷は、ゲームの起動時や新しいエリアへの移動時にアセットを読み込む際に発生します。これは、特に初回のロード時間に影響します。大規模で容量の大きいマップであるほど、起動が遅くなりえたり、スパイクが発生しやすくなります。

主な負荷のポイント

物理シミュレーション

物理エンジンの計算は、複雑な多くの物理オブジェクトが関与する場合、大きなCPU負荷を引き起こします。以下のようなことを意識して、実装・最適化を行います。
  • 物理挙動が不要なオブジェクトにはアンカーを設定し、不必要な物理シミュレーションを避けます。
  • シンプルなコリジョン形状(CollisionFidelity)を使用して物理計算を簡略化します。
  • 必要以上に物理挙動や物理拘束を増やさないようにします。

描画(レンダリング)

複雑なメッシュ構造のオブジェクトが多数あるような複雑なシーンではレンダリング計算負荷が高まります。また、複雑なメッシュ、高精細なテクスチャはメモリ使用量を増加させます。また、Robloxエンジンは現状オクルージョンカリングを実施しません。そのため見えないと判定できる不要な描画物を除去することも有効となります。以下のような点を考慮します。
  • 品質の許す限り、ポリゴン数の少ないメッシュ、解像度の低いテクスチャを使用します。
  • ModelのLOD設定を利用して、距離に応じてオブジェクトの詳細度を調整します。
  • 半透明オブジェクトや影などの描画計算が複雑になる表現を避けます。
  • 描画不要なオブジェクトを非表示化します。

高精細なアセットの利用

高精細なテクスチャやメッシュを使用することで、メモリ使用量が増加し、ロード時間が長くなり、描画計算負荷も高まります。また、同じメッシュなどに別なアセットIDを登録して異利用するとインスタンス化が阻害され、無駄に重複したメモリ使用をすることにつながります。
  • テクスチャの解像度を適切に調整し、必要ない高精細テクスチャを避けます。
  • アセットの再利用を促進し、同一の高精細アセットを複数回ロードしないようにします。
  • アセットの圧縮を施すことで、容量を削減します。

高負荷Script

毎フレームの更新処理で複雑な処理を行ったり、1フレーム内で大規模なループ等の負荷が高い処理を行うと処理がブロックされCPU負荷が高まります。ブロックしないように、taskによる分散や、サーバー・クライアント適切側での処理をすることが重要です。
  • 毎フレーム更新よりもイベント駆動型のプログラミングを採用し、必要な時にのみスクリプトが実行されるようにします。
  • ループや大規模なデータ処理を避け、効率的なアルゴリズムを使用します。
  • 高負荷な処理は、可能な限りクライアント側で行うなどして処理を分散します。
  • taskや、マルチスレッド化により処理の分散します。

多数のHumanoidの利用

Humanoidオブジェクトは複雑な処理を伴うため、多用するとパフォーマンスに影響を与えます。また、移動やアニメーションなどの動きを伴うことでレプリケーションコストも高まります。
  • 必要以上にHumanoidの数を増やさないようにします。
  • キャラクターのAIや動作をシンプルに保ち、計算負荷・レプリケーションを軽減します。
  • NPCの同時数を制限し、プレイヤーの近くにのみNPCが存在するように設計します。

レプリケーション(データ同期)

ネットワーク経由でのデータ同期は、大量のオブジェクトや頻繁な更新になどにより、ネットワーク負荷とCPU負荷を増加させます。特にサーバー側の変更は基本的にすべてのクライアントへレプリケートされるため、サーバー側での多数の頻繁な更新はネットワーク負荷を上昇させ、体験に大きな影響を及ぼす場合があります。
  • ネットワークを介して送信するデータ量を最小限に抑えます。
  • データの更新頻度を制限し、必要な時にのみデータを同期します。
  • クライアントとサーバー間でのデータ圧縮を活用して、送受信するデータ量を減らします。

負荷の特定方法

  • パフォーマンスダッシュボード:ブラウザでエクスペリエンス全体のパフォーマンスを観測できます。
  • マイクロプロファイラー:エクスペリエンス実行中のフレームごとの詳細な処理時間を時系列データで確認できます。
  • 開発者コンソール:実行中エクスペリエンスのパフォーマンス情報やログを確認できます。
これらのツールを用いることで、ゲームのパフォーマンスに影響を与えている具体的な問題点を特定し、効果的な最適化戦略を立てることができます。パフォーマンス最適化は継続的なプロセスであり、ゲーム開発のあらゆる段階で注意を払う必要があります。

参照すべき情報

最適化は、特に大規模なエクスペリエンスにおいて重要となります。対処としては高度なトピックともなるため、実際に取り組む際には以下の公式ドキュメントなどを参照して最新情報を踏まえて取り組んでください。