[Tips] カスタムパラメータによる送信量・頻度の軽減

目次

  概要
  カスタムパラメータによる送受信処理の特性
  Tips(1) : 頻繁に変化するパラメータはカスタムパラメータで管理しない
  Tips(2) : シーン静的オブジェクトで共有される、更新頻度の低い情報は、ルームカスタムパラメータで送信した方が速い
  Tips(3) : 特定プレイヤーの所有物(prefab)で常時共有される、更新頻度の低い情報は、プレイヤーカスタムパラメータで送信した方が速い


概要

ルームカスタムパラメータ、およびプレイヤーカスタムパラメータを利用したパフォーマンス改善方法について

  ここでは、MUN における RPCメッセージ、およびオブジェクト同期の送受信処理について、
  別アプローチからのパフォーマンス改善方法として、「カスタムパラメータ」を使ったテクニックについて紹介します。


カスタムパラメータによる送受信処理の特性

開発者による任意の情報を送受信する方法として、現時点で「最速」の手段

  MUN のRPCメッセージ、およびオブジェクト同期通信における送受信制御を利用する場合、
  以下の理由により、あるクライアントから送信されてから、特定のクライアントが受信するまでのタイムラグに差が生じます。
1. RPCメッセージ送信、およびオブジェクト同期送信は、命令の実行から実際に送信されるまでにタイムラグが発生する。
   1) RPCメッセージの場合、MonobitNetwork.sendRate で指定されたフレーム間隔で送信するため、
      そのフレームに到達するまでの間送信されない。
   2) オブジェクト同期通信の場合、MonobitNetwork.updateStreamRate で指定されたフレーム間隔で送信するため、
      そのフレームに到達するまでの間送信されない。

2. RPCメッセージ受信、およびオブジェクト同期受信は、受信から実際の反映までにタイムラグが発生する。
   1) RPCメッセージの場合、受信側メソッドを保持するインスタンスを探索する処理に時間が掛かり、
       かつそのメソッドを SendMessage() でコールするため遅延実行される。
   2) オブジェクト同期通信の場合、OnMonobitSerializeView() メソッドを保持するインスタンスを探索する処理に時間が掛かり、
       かつそのメソッドを SendMessage() でコールするため遅延実行される。
          ※ オブジェクト同期通信の方がRPCメッセージ通信よりも探索時間は短いが、それでも時間が掛かる。

  これに引き換え、ルームカスタムパラメータおよびプレイヤーカスタムパラメータは、以下の特性を持ちます。
1. ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、命令の実行から実際に送信されるまでの遅延は
   送信命令実行フレームから1フレーム以内である。
   → RPCメッセージやオブジェクト同期の送信に比べて、遅延時間が短い。

2. ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、受信から実際の値反映までにタイムラグが発生しにくい。
   → 値自体は受信到達フレームから1フレーム以内にて即時反映される。
   → OnMonobitCustomRoomParametersChanged() メソッド、およびOnMonobitPlayerParametersChanged() メソッド を保持するクラスがある場合、
     インスタンスを探索する処理に時間が掛かり、かつそのメソッドを SendMessage() でコールするため遅延実行される場合があるが、
     この2つの接続コールバックメソッドがない場合、ほぼ処理負荷は掛からない。。

  そのため、いち早くルーム内外のクライアント間で情報共有したい場合、ルームカスタムパラメータ、およびプレイヤーカスタムパラメータによる
  送受信処理が現行最速と言えます。

カスタムパラメータによる送受信による弊害と制約

  「最速」と聞いただけで、あたかもカスタムパラメータによる通信だけで良いように見えますが、当然のことながらカスタムパラメータには弊害と制約があります。
  そのなかで最も比重が高いのが以下の3点です。
1. ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、一部の変更であろうとも全てのパラメータを送受信しあう特性を持つ。
   → カスタムパラメータの容量が大きすぎる場合、かつ変更するパラメータの頻度がまちまちの場合、
     無駄に送受信しあうために多大な通信負荷がかかりやすい。

2. ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、全てのルーム内プレイヤーが共有する情報である。
   → RPCメッセージにおける「MonobitTargets.All」などによる拡散方法しかできず、
     特定のプレイヤーに対してのみ、という送信手段は取れない。

3. ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、全てのルーム内プレイヤーが自由に変更できる情報である。
   → ルーム内プレイヤーであれば誰でも自由に数値変更できるため、情報の安全性に欠け、
     セキュリティホール(チート)の温床となりやすい
  そのため、カスタムパラメータでは、原則として以下のような情報の送受信を取り扱うことしかできません。
・ できる限り変更頻度の低い、かつ、膨大ではない情報の送受信
・ ルーム内プレイヤー全員に対し常に共有される情報の送受信
・ 悪質なプレイヤーからの情報改ざん(チート)に伴うシステムの弊害が発生しないような情報の送受信


Tips(1) : 頻繁に変化するパラメータは「カスタムパラメータ」で管理しないこと

膨大なデータによるカスタムパラメータの設定は、通信リソースを食いつぶす恐れがあります!

  ルームカスタムパラメータ、およびプレイヤーカスタムパラメータは、一部のデータを変更するだけで全体を送受信しあいます。
  オブジェクト同期通信のような差分送信機能はありませんし、RPCのように必要なパラメータだけを送信する機能もありません。


仮に1Mbyteのデータをルームカスタムパラメータ(またはプレイヤーカスタムパラメータ)に設定したとしましょう。

そのうちの1byteでも更新した場合、更新したフレーム後、自動的に 1Mbyte のデータを送信します。
60FPSのゲームで毎フレーム1byte更新しただけで、60Mbpsの通信帯域を必要とします。
明らかに非効率です。

  よって、カスタムパラメータのデータ総量は抑えるべきで、そういった設計が求められます。


Tips(2) : シーン静的オブジェクトで共有される、更新頻度の低い情報は、ルームカスタムパラメータで送信した方が速い

シーン静的オブジェクトの Update() メソッド内の RPC メッセージ送信、
および受信メソッド処理のルームカスタムパラメータ化

  シーン静的オブジェクト内の Update() メソッド内で monobitView.RPC() や monobitView.RpcSecure() を実行して RPC メッセージを送信し、
  その受信メソッドにて常時受信するような仕組みを作っている場合、RPCメッセージ送受信を使うよりもルームカスタムパラメータでの送受信の方が高速です。
    ※ 例外として、ボタン操作などの「特定条件下による」RPC メッセージの送信については、逆にルームカスタムパラメータ化した方が遅くなる場合があります。

  ただし、送信している情報は全てのルーム内プレイヤーが共有する情報ですので、MonobitTargets.All などの送信方法を用いているもののみ置換可能で、
  特定のプレイヤーに対する送信処理については、ルームカスタムパラメータ化は困難です。

  また、上述の通り膨大なサイズのデータや、チートの温床になりそうな機密性の高い情報などはルームカスタムパラメータ化は避けるべきです。

シーン静的オブジェクトの OnMonobitSerializeView() メソッドによる
オブジェクト同期送受信処理のルームカスタムパラメータ化

  シーン静的オブジェクト内の OnMonobitSerializeView() メソッド内実行しているオブジェクト同期の送受信処理については、
  OnMonobitSerializeView() を使うよりもルームカスタムパラメータでの送受信の方が高速です。

  ただし、こちらについても、膨大なサイズのデータや、チートの温床になりそうな機密性の高い情報などはルームカスタムパラメータ化は避けるべきです。


Tips(3) : 特定プレイヤーの所有物(prefab)で常時共有される、更新頻度の低い情報は、
      プレイヤーカスタムパラメータで送信した方が速い

特定プレイヤーの所有オブジェクトの Update() メソッド内の RPC メッセージ送信、
および受信メソッド処理のプレイヤーカスタムパラメータ化

  特定プレイヤーの所有オブジェクトの Update() メソッド内で monobitView.RPC() や monobitView.RpcSecure() を実行して RPC メッセージを送信し、
  その受信メソッドにて常時受信するような仕組みを作っている場合、RPCメッセージ送受信を使うよりもプレイヤーカスタムパラメータでの送受信の方が高速です。
    ※ 例外として、ボタン操作などの「特定条件下による」RPC メッセージの送信については、逆にプレイヤーカスタムパラメータ化した方が遅くなる場合があります。

  ただし、送信している情報は全てのルーム内プレイヤーが共有する情報ですので、MonobitTargets.All などの送信方法を用いているもののみ置換可能で、
  特定のプレイヤーに対する送信処理については、プレイヤーカスタムパラメータ化は困難です。

  また、上述の通り膨大なサイズのデータや、チートの温床になりそうな機密性の高い情報などはプレイヤーカスタムパラメータ化は避けるべきです。

特定プレイヤーの所有オブジェクトの OnMonobitSerializeView() メソッドによる
オブジェクト同期送受信処理のプレイヤーカスタムパラメータ化

  特定プレイヤーの所有オブジェクト内の OnMonobitSerializeView() メソッド内実行しているオブジェクト同期の送受信処理については、
  OnMonobitSerializeView() を使うよりもプレイヤーカスタムパラメータでの送受信の方が高速です。

  ただし、こちらについても、膨大なサイズのデータや、チートの温床になりそうな機密性の高い情報などはプレイヤーカスタムパラメータ化は避けるべきです。