Programming in VRChat

VRChat でのプログラミングについて調べたことの書き溜め

Broadcast Types

Broadcast Types は、trigger システム において trigger の発生情報をどの範囲に送信するかの設定値。

f:id:naqtn:20180211063140p:plain

種類

選択可能な値を表にまとめる。

Broadcast Type name 列が選択可能な値で、それがどういう特性を持っているかをそれより左の列で記している。

to others: player is: buffered: Broadcast Type name note
NO - - Local Advanced opt.
YES
master
all Master Advanced opt.
last one MasterBufferOne Advanced opt.
no MasterUnbuffered Advanced opt.
owner
all Owner Advanced opt.
last one OwnerBufferOne
no OwnerUnbuffered
anyone
all Always Advanced opt.
last one AlwaysBufferOne default
no AlwaysUnbuffered
  • "to others", "player is", "buffered" の呼称は、この記事で理解を容易にするため独自につけたもの
  • "Advanced opt." と記したものはエディタ上で Advanced Mode のチェックがオンになっていないと選択できない。 追記:VRChat 2020.1.1 で Advanced Mode の選択UIは廃止されました ( "Advanced Mode" removed from Triggers, all options are now visible by default https://docs.vrchat.com/docs/vrchat-202011

f:id:naqtn:20180211063817p:plain f:id:naqtn:20180211063927p:plain

特性の意味

前掲の表の列をなす個別の特性について記述する。

他のプレイヤーに送信されるか(to others)

  • NO: その trigger が起きたプレイヤーの環境でのみ action が実行される
  • YES: 他のプレイヤーに送信され、それぞれの環境でも action が実行される

(他プレイヤーに送信する場合)誰が発生できるか(player is)

  • master : そのワールドの Master である場合のみ action が実行される
  • owner : そのオブジェクトの Owner である場合のみ action が実行される
    • Object の Spawn を実行したプレイヤーのことか?
  • anyone : プレイヤーが誰であるかは問わずにaction が実行される
    • (ドキュメントでの表現は "Always"。 条件が付かないので Always と命名したのだろうが、 プレイヤーの種別の話であり anyone と表現した方が分かりやすいので、この記事ではそのようにした。)

バッファに記録される量(buffered)

  • all : すべてのアクションが記録される。
  • last one : オブジェクトと trigger 種ごとに、最後の一つのみバッファに記録される。
  • no: バッファされない
    • (ドキュメントでは normal という表現になっている。分かりにくい。)

謎な仕様、注意

  • Action に SpawnObject を追加すると Broadcast Types 選択肢が消える
  • 操作ミスでAdvanced Mode チェックを一度切ってしまうと、選択肢が変化してしまう
  • trigger 種のうち Relay には Broadcast Types 指定が付かない
  • バッファに限界量はないのだろうか?

考察

明確な説明が無いが想像するに、 VRChat の個々のマシンでの実行時のワールドの生成と同期は次のような設計になっているのだろう。 (完全に筆者の想像なので間違っている可能性があるので注意)

  • バッファは、後から入ってきたプレイヤーにワールドで起きた出来事(action)を再実行するために記録しておく領域。
  • 後から入ってきたプレイヤーのマシンでは、まずワールドのアップロードされている初期状態がロードされ、 その後バッファのアクションが適用される。
  • プレイヤーが何か行動を行うと、
    1. まずはローカルマシンで trigger の発生から action 定義の特定が行われる。
    2. 定義に書かれている broadcast に従って必要に応じて他マシンに送付される
    3. 定義に応じてバッファに記録される。
    4. いずれにせよ受信したものを各環境は実行する。
  • (action が配送されているのか trigger が配送されているのかは未調査。ログを見ると判明しそうではある。)

アクションで実現している処理内容の性質によって、適切に選ぶ必要がある。 適切な選択を見つける設計的手順はまだ飲み込めていないが:

  • 素朴には「すべて」すれば、あとから参加したプレイヤーにとって、 既に居たプレイヤーが行ったことが再生され、同じ状態が生成される。
  • 大量の action が発生しうる場合には処理が重くなるので、すべてを送信するのは好ましくない。 ワールドの進行に必要な結果だけを送り出すのが望ましいだろう。
  • 例えば音の再生などリアルタイムでないと意味を持たない action ではバッファするのは不適切だろう。
  • だが過剰に取り除くと、既に居るプレイヤーとあとから参加したプレイヤーとで見ている世界にズレが起きうる。