kdenologue

たまに何か作ります。

JustRainのワールドアクセス解析

f:id:kden:20191210125828p:plain 本記事は、VRChatアドベントカレンダー2019の15日目の記事です。

adventar.org

前日は hatsuca さんの「ワールドギミック関連でなにか書きます」でした。イワシの謎技術にはいつも白旗を揚げさせていただいております.

TL;DR

GASとGoogle DataPortalでサーバレスになんちゃってVRCワールドアクセス解析を作りました.

本文

さてさて,去る2019年8月に公開した拙作ワールド「JustRain」について,今回はアクセス解析の話をしようと思います.ワールド自体のコンテンツは今回は主題ではないので,ざっくり説明すると「自アバターにも当たり判定がある雨が降っているワールド」です.公開直後はそこそこ話題だったんじゃないのかなーと思います.

今回のテーマ,アクセス解析ですが,ヨツミフレームさんがすでに一年前にやっているので,実のところあまり目新しい話にはなりません.僕の場合はこんなふうにやって,こんな感じでしたよ~という記事を書いていこうと思います.

y23586.net

今回,ワールドを公開するにあたってなにか面白い事をしたいなーという思いがありました.一方で,ワールドギミック周りで色々勉強していた僕は,Panoramaって要はHTTPアクセスよな~ということをようやく理解し始めていました.ここで,Panoramaが走った瞬間のログを取れば入場記録が取れるのか,と思ったのでした.しかしながら,自前でサーバーを持っているわけでも借りているわけでもなく,このために新たに借りるのもなんだかなという気がしたので,なるべく外部サービスを組み合わせてやろうというお気持ちになりました.そこで今回利用したのが,Googel App ScriptとGoogle Data Portalです.

GASでログの記入

Google App Script(以下,GAS)は,かんたんなスクリプトを実行するだけの環境を借りれるサービスです.Googleが提供している他のサービス,例えばスプレッドシートなどとの連携がしやすく,かんたんで時間のかからない処理は無料で実行できるというメリットがあります.

僕自身は.以前は「自分の管理しているアバター一覧をスプレッドシートに保存する」というスクリプトを書いたことがあり,その応用を考えました.VRChatとGASの連携は,すでに何人もやられているの(それこそ去年のアドベントカレンダーなど)で,GASなにそれおいしいのみたいなVRCプレイヤーはそちらを参考にすると大まかな機能の把握がしやすくて良いかなと思います.

qiita.com

qiita.com

といっても,今回必要なのは「アクセス日時を記録するだけ」なので,複雑なスクリプトは必要ありません.機能の中心となるのは,GASのWebApp機能です.これは,ざっくり言えば「スクリプトに対してURLが割り当てられ,そのURLにアクセスするとスクリプトが実行される」という機能です.VRC_PanoramaはHTTPアクセスを行うものなので,画像ファイルではなくこの実行用URLを登録しておくことで,ワールドアクセス時(ないしアタッチされているオブジェクトのspawn時)に任意のGASスクリプトを実行できます.

手順は,リファレンスの「Deploying a script as a web app」を見るとわかりますが,ウェブアプリとして公開するボタンを押すだけです.このとき,(単純にPanoramaでアクセスした際に)実行される関数は doGet(e) という名前であることが必須です.

この中身に,任意のスプレッドシートに好きなように文字列を書き込むスクリプトを書いておけば,晴れてアクセスが有ったときにスプレッドシートが更新されるという仕組みができます. あとの処理で使いやすいように,更新日時や謎のカウント(あとで足し算して使うもの)なんかを記入しておけばよいかと思います.ちょっとゴミが混じっていますが,こんな感じのコードを書くとスプレッドシートに反映されます.

function doGet(e) {
  
  // spread sheetのシート設定
  var sp_url = "https://docs.google.com/spreadsheets/d/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/edit#gid=0";
  var spreadsheet = SpreadsheetApp.openByUrl(sp_url);
  var sheet = spreadsheet.getSheetByName("シート1");
  
  var now = new Date();
  var date = Utilities.formatDate(now, 'Asia/Tokyo', 'yyyy/MM/dd');
  var time = Utilities.formatDate(now, 'Asia/Tokyo', 'HH:mm:ss');
  var time_h = Utilities.formatDate(now, 'Asia/Tokyo', 'HH');
  var time_m = Utilities.formatDate(now, 'Asia/Tokyo', 'mm');
  var data = [[date, time, true, time_h, time_m, "1"]];
  
  sheet.insertRows(2);
  sheet.getRange(2,1,data.length,data[0].length).setValues(data);
  
}

f:id:kden:20191210123945p:plain
どんどん加筆されていく

Google Data Portal でログの可視化

Google Data Portal は,スプレッドシートの内容やGoogle Analyticsのデータなどのいろいろなデータを入力として,グラフとしてビジュアライズできるサービスです.これが,コーディングなしでブラウザ画面だけでできるというのも大きな強みで,他にも複数のデータソースに対して同時にアクセスできるなどの細かい点も使いやすさに貢献していると思います.ログの可視化というと,自前でpythonを走らせる,エクセルでファイルを開くなどの様々な手法がありますが,凝ったことはせずに手軽にデータを見に行きたいということでこのツールを使うことにしました.というか,存在を知らなかったので使ってみたかった.

相変わらず細かいセットアップは他のサイトを参照してもらうほうが良いと思うのでここでは記述しませんが,大まかなサービス構成はここでも触れておこうと思います.

  • データソースとフィールド

    表示するにあたって利用するデータがどこにあるかを指定します.今回は,先程のGASで更新しているスプレッドシートを参照することになります.また,そのソースの中にはどういうデータがあって,それは実際のところどういう意味なのか等を指定する必用があります.

f:id:kden:20191210131328p:plain
データソースの設定画面

f:id:kden:20191210131405p:plain
フィールドの設定画面

  • レポート

    データソースをグラフ等として表示する部分を担います.これは,「白紙のページに対してグラフを配置→そのグラフの表示に使うデータを先程のデータソースから選択する」という作業を繰り返すことで完成します.

f:id:kden:20191210131758p:plain
グラフをページに追加

例えば,時系列でアクセス数をプロットするとこのようになります.これは,公開直後(2019/8/22)から執筆時点(2019/12/10)までの日付ごとのアクセス数グラフです. f:id:kden:20191210132033p:plain このとき,ディメンションは日時(YYYY/MM/DD)で,指標はアクセス数の合計としてあります.先のGASスクリプト中の var data = [[date, time, true, time_h, time_m, "1"]]; というコードのうち,謎の 1 は,ここで合計を取ることで「その日ごとの合計を算出して表示」という処理を行うための布石でした.

一通りグラフを配置し終えたら,右上の「ビュー」ボタンを押すことで編集状態を終えます.このとき,グラフによってはマウスオーバーで細かい情報を見ることができたりします.

f:id:kden:20191210132536p:plain
日付ごとの値がマウスの位置に応じて表示される

色々プロットしてみる

ここまでVRChatのVの字出てきたっけなみたいな状態なので,実際にアクセスログをDataPortal上だけで色々表示してみた様子をお届けします.といっても.一番のネタバレは先にも出した全期間のアクセス数グラフなんですが.

ちなみに面倒だったので全データが一つのスプレッドシートに書き込まれています.ひどい実装だ.約3万行ありますが,直接スプレッドシートを開く必要なしに,DataPortalで数秒待つだけでグラフが表示されます.

全期間のグラフ

f:id:kden:20191210132937p:plain

  • 指数関数に減っていく様子がよくわかります.
  • 基本的に凸凹していてノイズが多いので,この日はどうとかいった分析は難しそう.
    • Vket3(2019/9/21~25)や落マケ(9/26~10/2)での落ち込みはあるとは言いにくい.
    • ただ10/24前後はちょっと人多そうな見た目はしている.

直近30日間のグラフ

f:id:kden:20191210133605p:plain

  • やはり休日は微妙に多い傾向にある気がする.

2019/12/09のログ

f:id:kden:20191210133701p:plain

  • 横軸は時間.0~23時.
  • やはり日本時間の夕方以降のほうが人が来ている.

時間帯別のログ

f:id:kden:20191210134111p:plain

  • 8月からの 全データ を横軸は時間,0~23時で累積したもの.
  • ゴールデンタイムは20時~25時くらいか.
    • 29時までには別のところに行く,という傾向がありそう.

f:id:kden:20191210134332p:plain

  • こっちは同じように 11月の アクセス数を累積したもの.
  • ピーク終わりは少し早くにシフトしている.寝る前にいるワールドは別のところになったのだろうか.

諦めたこと

  • IPアドレスの記録はできない

    残念ながらGASはアクセス元のIPアドレスの記録に対応していないらしく,ヨツミさんのようなIPベースで処理して遊ぶということはできません.AWSとかに移行するといいと思います.

    7年前からIP取れるようにしてくれって言われている様子→ログイン - Google アカウント

    これはあくまで肌感覚というか神からのお告げですが,アクセス元としてJPが多いのはもちろん,KOやプレイヤー分母の多いUSも多かったのかな~~と思います.

  • 滞在時間はとれなさそう

    上記IPの問題が解決されたら,ワールドから出ていったのをトリガーにしてPanoramaをスポーンなどさせれば取れそうな気はします.(それでもワールドの最後の一人が退出したときって発火しないような気がする)

  • インスタンスの詳細まではわからない

    次に紹介するWEBページの情報も含めて,インスタンス数やその中の滞在メンバー数,アカウント情報なんかは何もわかりません.言い換えると今回は「このアカウントはどうこうしている」みたいな個々の情報は一切取れないということになります.以前は取れたんですけどね.

おまけ:WEBページのログ

  • 上の例ではGASは 「アクセスがあったら実行」としていましたが,他には定期実行という選択肢もあります.実はVRChatのWEBページで見れる情報(star数等)も記録してみました.あんまり頻繁に認証通すとアカウントがロックされます(2敗)

2019/2 補足:VRChat側のインスタンス管理方法が変わり,privateなインスタンスは人が消えても暫くデータとしては残るようになったらしく,この手法では滞在人数を正確に取れなくなりました・・・・(´・ω・`)

WEBページ側のアクセス数

f:id:kden:20191213101054p:plain
WEBページでの表示例

Panoramaで得られたアクセス数を累計していくことで,原理的にはワールドが読み込まれた総合回数を得ることができます.一方で,WEBページを見に行くと,ここにもアクセス数が表示されています.これらの値,実は一致していません.

f:id:kden:20191213095737p:plain
赤色はWEBページでのカウント,青色はPanoramaでのカウント

だいたいWEBページで得られる数のほうが1.5倍ほどになっていることがわかります.原因はまったく検討がつきません.なんなんでしょうね…

Star数

f:id:kden:20191213100129p:plain

11月頭頃に1000fav行ったようです.ありがとうございます.

おまけ2:落選マーケット

僕は運営側ではないのであくまでWEBページの数値を追いかけていただけですが,同じようにGASとデータポータルで落選マーケットの間の(WEBページ上での)アクセス数を見てみました.※このデータについて運営に問い合わせることはおやめください.僕がちまちま勝手に記録したものです.

f:id:kden:20191213101934p:plain

A/B会場だけ他の2会場に比べて多いことがわかります.そして,その比率は特段変わっているようにも思えません.原因のひとつに,会場自体のコンセプトが同じだと,1個め(=ABC順でAB会場)だけ見て終わるみたいな人が一定比率いるという可能性が考えられます.興味深いデータです.(しかしpanoramaのほうが信頼できるのであまりこのデータは信頼できないというのが個人の感想)

まとめ

以上,サーバレスになんちゃってアクセス解析をしてみたお話でした.正直1日100アクセス前後のデータを見ていてもそんなに面白くはないので,たくさん人が来るワールドを作るか,定番となっているようなワールドのデータを見てみたいですね.データを眺めるのはそれなりに好きですが,真面目な分析は得意ではないので,今回はこのへんにしておこうと思います.

宣伝

ワールドのアップデートします

ワールドにインタラクションできる曇る鏡を実装します.大体完成していて,Unity2018が来たら更新しようと思うので(と思って待ってたら11月終わってますが...)思い出したらまた訪れてみてください.

...と思ったらアドベントカレンダー12日担当の あずりて さんがよく似たものを出していましたね.仕組みも必然的にだいたい同じになります.まあ被るというのは不思議とよくあることです.

scrapbox.io

VRC技術市で解説を書くそうなので,これで実装の説明丸投げできますね!

シェーダー周りの解説本書きます

2月の15・16に開催される「VRC技術市」にJustRainの他のワールドギミックやシェーダー構成について解説する本を出します.正直本業の都合で間に合うか怪しいのですが,落とさないようにがんばります. 対象の読者層は,シェーダーの知識があんまりないとか,真面目な解説本読んで挫折したみたいな人で,具体的なコードをつらつら書くというよりは仕組み周りのざっくりとした解説に留めるみたいな方向性を考えています.(正直難しい・・・)

こういう内容知りたい~などあればお気軽に @2_sac までリプ投げてください!! マシュマロも空けてあります.コメントが多ければ多いほど落とす可能性が下がります.

かでんにマシュマロを投げる | マシュマロ

アバター等売ってます

kawaiiアバターとかバーチャルなニキシー管時計とか売ってます! どうぞお見知りおきをなにとぞなにとぞ.

sporadic-e.booth.pm sporadic-e.booth.pm

f:id:kden:20191210123256p:plain sporadic-e.booth.pm

おわり

明日は Tnohito さんによる「VRChatのイベントについて書きます」です.僕は生活周期もあってあんまりイベントに参加するほうではありませんが,気軽にコミュニティに入ったり交流できる状態は良いものだなーと思って見ています.


■余談 blenderと自作アバターで遊び始めてから大体一年経ちました.

kden.hatenablog.com