パフォーマンスのヒント

パフォーマンスは、アプリケーションにマルチプレイヤー・コンポーネントを流動的かつシームレスに統合するために欠くことができない部分です。 そのため、ここではPhotonで開発する際に覚えておくべきヒントのリストをまとめました。

サービスを定期的に呼び出す

クライアントのライブラリはサーバーに接続し続けるためにLoadBalancingPeer.Serviceへの定期的な呼び出しに依存しています。 サービスの呼び出し間の大きな停止は、クライアントが接続を維持できないため、タイムアウトの切断につながります。

データのローディングは、メインループで1秒未満の間隔でアップデートがおこなわれていない場合に一般的に生じる状況です。ローディングや接続で問題が生じていたり接続が切れてしまっている場合でも、サービスが呼び出されることを確認してください。 この問題を見落とすと、問題の識別や再現が難しくなります。

アップデート vs トラフィック

1秒間ごとのアップデート数を増加させることで、ゲームがより流動的かつ最新のものとなります。 一方、トラフィックが劇的に増加する場合があります。 オペレーションを呼び出すたびに、他のプレイヤー向けにイベントを作成する可能性がある点に留意して下さい。

モバイルクライアント上で、1秒間に4個から6個のオペレーションをおこなうことは問題ありません。 3Gデバイスでも、非常に遅いネットワーキング実装を使用している場合があります。 1秒あたりに送信するアップデート数を減らすことで、動作が速くなる場合があります。

PCベースのクライアントの場合は、大幅に高速化することが可能です。 これらのクライアントに対しては、限界値のフレームレートを設定して下さい。

トラフィックの最適化

トラフィックの問題を避けるには、送信量を減らします。 送信量を減らすには、いくつかの方法があります:

必要以上に送信しない

必要な分だけ通信してください。 関連する値のみを送信し、それらの値から出来る限り派生させてください。

状況に応じて、送信するものを最適化してください。 何を送信するべきか、また送信頻度を考慮するようにしましょう。 重要でないデータは同期によって強制的に再計算される場合を除き、同期されたデータ、またはゲームの進行内容にもとづいて受信側で再計算されるべきではありません。

例:

  • RTSでは、発生時に複数のユニット向けに「オーダー」を送信できます。 これは1秒間に10回の頻度で各ユニットに位置、回転、速度を送信するよりもはるかに効率的です。

    1500 archersを参照してください。

  • シューティングゲームでは、発射は位置と方向として送信してください。 銃弾は通常、直線で飛びます。このため、100ミリ秒ごとにそれぞれの位置を送信する必要はありません。 銃弾が何かに当たった場合、または銃弾が「非常に多くの」ユニットを通過した後には、銃弾をクリーンアップすることができます。

  • アニメーションは送信しないでください。通常は、プレイヤーの入力やアクションからすべてのアニメーションを派生することができます。 アニメーションを送信すると遅延が発生する可能性が十分にあり、プレイが遅延すると非常に不自然な印象を与えます。

  • デルタ圧縮を使用してください。前回の送信から変更があった値のみを送信してください。 受信側での値を平滑化するため、データ補間を使用してください。 この方法は無理に同期をおこなうよりも望ましく、トラフィックを軽減します。

送信量を抑える

やり取りする型とデータ構造を最適化してください。

例:

  • 小さな整数の場合には、intではなくbyteを使用してください。可能であれば、floatではなくintを使用してください。
  • stringのやり取りを避け、なるべくenumやbyteを使用してください。
  • 送信されるものが明確でない限り、カスタムの型をやり取りしないでください。

静的なデータ、またはよりサイズの大きなデータをダウンロードするには、別のサービスを使用してください(例:マップ)。

Photonはコンテンツ配信システムとして構築されていません。 HTTPベースのコンテンツシステムを使用したほうがコストを抑えられ、管理も容易です。 最大転送単位(MTU)よりも大きなものはすべて分割され、複数の信頼性の高いパッケージとして送信されます(完全なメッセージへと再構成する必要があります)。

送信頻度を抑える

  • 送信レートを下げてください。できれば、10未満に下げることを推奨します。 この設定は、当然のことながらゲームプレイに応じて異なります。 この変更はトラフィックに大きく影響します。

ユーザーのアクティビティや、やり取りするデータにもとづいて、適応送信レートや動的送信レートを使用できます。この設定もトラフィックに大きく影響します。

  • 可能な場合には信頼性を低くして送信してください。 新たなアップデートをすぐに送信する必要がある場合、通常は信頼性の低いメッセージを使用できます。 信頼性の低いメッセージは、繰り返しを発生しません。 例:FPSでは、通常プレイヤーの位置は信頼性を低くして送信されます。

データの作成と消費

「トラフィック」のトピックに関連した問題として、受信側の末端で消費可能な量のデータしか生成されない問題が挙げられます。 パフォーマンスやフレームレートが受信イベントに追い付いていけない場合、それらは実行される前に古くなってしまいます。

最悪のケースでは、一方の側が受信側の末端を壊すほど多くのデータを生成します。 開発中には、クライアントの待ち行列の長さに注意してください。

信頼性の低いコマンドの実行を制限

クライアントが受信メッセージをしばらくディスパッチしなくても(例:ローディング中に)、クライアントはすべての受信とバッファリングをおこないます。 他のプレイヤーのアクティビティーに応じて、クライアントは追いつくまでに膨大な処理をおこなう必要があります。

単純化するため、クライアントは信頼性の低いメッセージを特定の長さに自動的にカットします。 結果的に最新メッセージをより早く取得でき、アップデートされていない箇所は最新のメッセージにすぐに置換されます。

この制限はデフォルトが20の(PUN内も同じ)LoadbalancingPeer.LimitOfUnreliableCommands経由で設定されています。

データグラムのサイズ

データグラムのコンテンツのサイズは、すべてのデバイス上で起動させるために1,200バイトに制限されています。

1,200バイトにはヘッダーからのすべてのオーバーヘッド(「バイナリプロトコル」を参照してください)、サイズおよび型の情報(「Photonでのシリアル化」を参照してください)が含まれます。これによって、実際の純粋なペイロード数は大幅に減少します。

データがどのように構築されたかによって異なりますが、純粋なペイロードデータが1KB未満の場合には単独のデータグラムにおさまると考えて問題ありません。

1,200バイトよりも大きなオペレーションやイベントは分割され、複数のコマンドで送信されます。 これらは自動的に信頼性が高くなり、受信側は完了時にこれらの大きなデータチャンクを再構成し、ディスパッチできます。

大きなデータ「ストリーム」は、ディスパッチされる前に多くのパッケージから再構成する必要があるため、レイテンシーに大きく影響します。 これらは個別のチャネルに送信可能なため、(低い)チャネル番号の「投げ捨て」位置アップデートには影響しません。

 ドキュメントのトップへ戻る