VRChatで個展を開く(その2・運営と来場者の記録)

2018年9月22日・23日にVRChatで開催した個展「1%の仮想」は2024人の方(IPアドレス数でカウント)にご来場いただき、無事終了しました。本当にありがとうございました!

こちらの記事では今回のイベントで得られたVRChatにおけるイベント開催の知見を書き連ねます。個展のテーマや技術的な解説はまた今度。

インスタンス作成・管理

VRChatにおける「インスタンス」とは、「あるワールドのデータを基礎として人やワールド内ギミックを同期させる機構」のことで、いわゆる「部屋」です。例えば「1%の仮想」では30人を収容するインスタンスを最大で12インスタンスほど作成して運営しました。

現在のVRChatにおいて、大規模イベントを開催するための一番の課題はおそらく「インスタンス管理」です。なぜインスタンス管理が大変かというと、現在のVRChatの仕様上、

  • インスタンスの作成・削除は明示的に管理できない(特定のインスタンスIDに人が1人以上入った瞬間にインスタンスが生成され、人がいなくなると削除される)
  • VRChat内でインスタンスを生成する際、インスタンスIDがランダムに生成される(+その一部であるハッシュ値が表示されない)ので「一度VRChatで作成したインスタンスに入り直す」ことが困難
    • 仮にインスタンスIDが分かったとしても、VRChat内では「IDを入力して入室する機能」がない
  • インスタンス内の全員のコントローラが異常な挙動になる現象がまれに起こる(いわゆる「インスタンス破壊」)
  • 特定のインスタンスに入るには「その中にいる人にJoinする」か「IDを指定してVRChatを再起動する」必要がある
    • 前者は「誰がどのインスタンスIDにいるか」はJoin時に表示されず、一回移動してみて確認するしかない
    • 後者はVRChatから一回フォーカスを外してウェブブラウザ等を操作する必要があるため特にVR環境では相性が悪い。またIDを知っていればインスタンスに誰でも入れてしまう
  • 特定のインスタンスの人数を(VRChat内では)把握できない

というなんでこんな雑な仕様が放置されてるのか分からない仕様になっているためです。(「フレンドがいるインスタンスの一覧表示」くらいAPIまわりを一切変更せずにクライアント側のみで実装できるはずなのに、ハロウィンイベントを優先する運営は一体……)

現状従来のイベントがどのようにインスタンス管理をしているかというと、フレンド数が多い人をビーコンとしてインスタンスに常駐してもらい、事前にその情報を告知することでどのインスタンスにも入れるようにすることが一般的です。例として、「1%の仮想」の前日に開催されたバーチャルお月見宴会では10インスタンスを12人で管理していました1

採用した運営方法

「1%の仮想」ではどうしたかというと、「私がインスタンスを転々とする」+「VRChat APIを駆使して全インスタンスの人数を把握する」ことで複数のインスタンスを作成しました。

まず、事前準備として、ワールドIDやユーザIDからVRChatの起動リンクを用意しておきます。今回は、vrchat.netのインスタンスID作成ツールは機能が貧弱なのと、vrchat://で始まる起動アドレスは括弧が含まれていてEvernote等のメモツールが正常なリンクとして認識しないため、坪倉さんのツールへのURLを用意しました。これを12個分手元のメモに貼り付けておき、「OVRdrop経由でリンクをクリックしてブラウザを開く」→「起動ボタンを押してVRChatを(再)起動+インスタンス作成」とすることで2トリガーを引くだけでインスタンスを移動できます。(Evernote云々の話は本質的ではなくて、要は起動リンクを手元ですぐ発動できるようにしておく、という話です)

また、各インスタンスの人数を把握するために、APIを使って全インスタンスの人数を把握するツールも作成しました。
現在インスタンスの詳細(人数等)を確認する手法は

の二通りがありますが、Public化されていないワールドでは上の方法では(たとえインスタンス自体がPublicであっても)取得できません。よって前述のようにインスタンスIDを固定し、下のAPIを叩くことでインスタンス内を監視していました。ちなみに、このスクリプトは某Webサーバでcronで回して画像を生成し会場にVRC_Panorama経由で表示していましたが、これはブラウザでも普通に見れるのでOVRdropで簡単に確認できます。

別の方法としてauth/user/friendsからも非Public化ワールドのインスタンスIDが取れるのでこの方法ではIDを固定する必要はなくなりますが、

  • インスタンスから直接のフレンドがいなくなってしまうと中を確認できなくなる
  • メインアカウントのパスワードをサーバに平文で置いておくのがこわい(worlds/[ID]/[INSTANCEID]はそのワールドの作者でなくても取得可能)

という理由で使用しませんでした2

当日の運用

当日は、以下のルールに従ってインスタンスを移動していました。

  1. 21時前後に第一インスタンスに移動する
  2. 人数が15〜20人になったあたりで新たなインスタンスに移動する(インスタンスの収容人数を30人としてこれ以降はフレンドへのJoinで増えると想定)
  3. 移動の際、人数が10人以下まで減ったインスタンスがあればそのインスタンスに移動する

以下でも書きますが、最終的に各インスタンス最大30人くらいの人数になっていたようです3。また、今回の規模のイベント程度であればインスタンス作成の間隔は10〜15分くらいだったので(回線落ちやバッテリー切れなどの事故が起きなければ)1人でもビーコンの役割を果たすことができます。第一インスタンスは人が集まりやすい傾向にある(最速で入りたい人+その人にJoinする人が多い)ので10人前後で移動してもよかったかも……

ちなみに、このイベントへの参加方法として「ウェブサイトに置いたリンクからの参加」も一応は想定していました。こちらは、

  • インスタンスへの収容人数を完全に分散可能
  • 参加者が私にフレンド申請する必要がない

というメリットがあるのですが、逆に

  • インスタンスの外部的要因(VRC_Panorama)で全インスタンスに不具合が起こった時に収拾がつかなくなる
    • 「私一人にJoinする」方法の場合、私がプライベートインスタンスに逃げれば入場を一時停止できる
  • ウェブサイト経由で参加する例があまりないので参加のハードルが上がる
  • Steamの起動オプションが表示されないので「VR持ってるけどデスクトップで参加する」ことができなくなる

という理由があり、特に1つ目は致命的だったので見送りました。

参加者の分析

前述のようにインスタンス内の人数はAPIで取得しており、また5分ごとのデータを随時保存するようにスクリプトを組んだので参加者の解析ができます(「誰がどこのインスタンスに何分滞在したか」とかもバッチリ取れてます)。

以下は簡単な分析結果です。以降のイベントの参考になれば幸いです。
ちなみに、イベント自体の概要は以下のようになります。

  • 名目:メディアアート展覧会
  • 開催期間:2018/9/22、23 21:00〜24:00
    • 終了時刻は「25時くらいまではインスタンスにいるように努力する」とアナウンス
  • 告知期間:2018/9/16〜23(@y23586経由)
    • フォロワー数:1300人前後
    • 告知ツイートのエンゲージメント:600fav・300RT前後
  • 参加方法:y23586か会場内フレンドにJoin
  • スタッフ:y23586(フレンド数:450人前後)
  • ワールド収容人数:30人
  • 同時開催イベント:Virtual Festival 2018Virus生放送(トラブルにより23日に延期)、その他たくさん

ちなみに、総開催期間中(観測できる範囲で全インスタンスが消滅するまで)の来場者数は1801人(ユニークユーザ名数)〜2024人(IPアドレス換算)でした。両者で200人くらい乖離があるのは、前者が「私が立てたインスタンスのみで5分間隔のスキャンに引っかかった人」、後者が「いずれかのワールドロード直後にVRC_Panoramaを発火させた人」を集計対象としているためで、前者は「5分以内に退出した人」や「私以外の人が立てたインスタンスや私がVRChat内で立てたインスタンス(二日目の25時頃)に来た人」が含まれていません4

また、APIの仕様上「人がいなくなったインスタンスは最後の1人の情報が残り続ける」ようだったため(実際には確認していませんが、1日経ってもどのインスタンスも1〜3人いるというデータになっているためこう判断しました)、人数が1〜3人から変化しなくなった午前5時以降のデータは無視して集計しました。

人数の動向


インスタンスごとの人数の動向(積み上げ、上が1日目、下が2日目)です。1〜10インスタンス目くらいまでは上記のルール通りに運用して30人前後が埋まっているのがわかります。また、開催時間は24時までとしていましたが24時以降にもかなりの人数が残っていました(総滞在時間の53%(1日目)、48%(2日目))。瞬間接続人数の最大値は227人(2日目の22時半頃)でした。


インスタンスの生成時刻を0としたときの人数の動向(0〜5分のラグあり、上から#1〜#12インスタンス)です。点線はインスタンス自体の標準収容人数として設定した30人です(VRChatの仕様上、これを少し超えてもなぜか入室できる)。
インスタンスによって100分程度で人がいなくなったり500分近く維持されたりとまちまちです。

滞在時間


滞在時間のヒストグラムです(最長滞在者を除外)。
平均滞在時間は60分、中央値は40分でした。実際に数値化してみるとだいたいの人にはしっかり楽しんでもらえたようで何よりです。
ちなみに、最大滞在時間は675分でした。一体誰フレームなんだ……


今話題のいわゆる「トラスト値」ごとの滞在時間です(ここでのトラスト値名は内部で使用されている名称で、現在ベータ版で実装が予定されている表示機能とは異なる可能性があります)。ノリでプロットしてみた割には、わりとトラスト値の高さ(左のほうが高い)と滞在時間に正の相関があるようなないような……5


おまけとして、来場者のもつトラスト値の割合です。参考までに。

  1. 私も会場デバッグ前にちょっとだけ参加していました
  2. 某ーストクラブの旧チェッカーはこっちの手法を使っている?
  3. どんなワールドでもだいたい30人を超えたあたりでPC性能の低い人から離脱・クラッシュがはじまるので自明な話ではありますが……
  4. 二日目終了後にねこますさん・坪倉さんらに来場いただいたのですが、そのときにも結構来場者が増えたと思います……
  5. 「トラスト値」は「廃人度」とほぼ一致する概念であるとは考えられているので別に不思議な結果ではないと思います