この記事は cluster Advent Calendar 2019 7日目の記事です。
昨日は弊社webエンジニアのわらび餅さんによる『ここ1年でclusterのwebがどう変わったか』でした。webチームは機能開発はもちろん、開発環境の改善にも大きなチャレンジをしているのが本当にすごいなと、横から見て思っていました!
改めまして、こんにちは。クラスターのハトこと、ねおりんです。Unityが得意なタイプのエンジニアです。
最近は、先日発表された大規模アップデートに向けて開発をしています。
さて大規模アップデートとともにアーカイブ機能の終了も発表され、今週機能の公開を終了しました。
本記事では、アーカイブの仕組みについて解説しつつ、アーカイブ機能がアップデートにどのように影響するのか、開発者視点から説明することができればと思います。
想定読者は、
- clusterのアーカイブ機能をお楽しみいただいていた方
- アーカイブ機能の仕組みを知りたい方
- (アーカイブ機能を実装してみたい方)
としています。主にエンジニアではない読者に読みやすいよう、技術的な詳細を割愛したり、実際の実装とは異なる部分が多分にあります。ご了承ください。
clusterは(リアルタイムで)どうやって動いてるか
まずは、リアルタイムのイベントでclusterがどう動いているのかを簡単に説明します。
これは多くのネットワークゲームと同じですが、基本はクライアント(皆さんのパソコンにインストールしてもらっているアプリケーション・ソフトウェア)同士が、サーバーを介してメッセージを送り合います。
たとえば、自分の位置を示すために、自分のIDと三次元座標をサーバーに送ります。
これを受け取ったサーバーは、同じルームにいる全員に転送します。
さらにこれを受け取った各クライアントは、なるほどこの人はここだな、とアバターを動かして描画し、その位置にいるように見えるわけです。
他にも音声やエモーション、コメント、スライドなどなど、いろいろな種類の情報がありますが、だいたい同じです。(めちゃくちゃ大雑把です!)
clusterのアーカイブはどうやって動いていたか
さて、ここからアーカイブの話です。
記録と再生の2段階にわけて説明していきます。
まず記録は、前述したメッセージをサーバーが時間とセットにして保存していきます。
再生は、まずサーバーが保存しておいたファイルをもらいます。
そして記録されている時間を見ながら、そのメッセージを受け取った体にします。
ちなみにこのファイルですが、イベントによって1GB以上になることもあります。
この大きなファイルのダウンロードが終わらないと再生開始できないのは辛いですよね。
そこで、このファイルを数秒分ずつに分割し、逐次ダウンロードしながら再生することで、すぐに視聴開始できるようにしています。(リアルタイムのときと同様に会場データのダウンロードは待つ必要があります)
もし動画のストリーミング再生を知っていれば、それと同じような仕組みです。
また公開には至らなかった機能ですが、この仕組みによって YouTube ライブのように開催中イベントの後追い再生も可能になっています。
イベントへの途中入室とシーク(戻し・送り)
ここまでの説明では、動画でのライブ配信やアーカイブとほとんど変わりないようにも見えるかもしれません。
しかし、シークについて考えると、3Dアーカイブならではの事情が現れてきます。
シークの基本的な方針は、一旦諸々の状態をリセットして、その時間に入室したときの状態を再現するというものです。
リセットは、会場をリロードしたり、Vアイテムを一度すべて片付けたり、といったことです。それから再度ファイルを読み直すことで戻し・送りを実現しています。
前節でダウンロード待ちを回避するためにファイルを分割していると書きましたが、これが実はシークにも役立っています。
このファイルの分割単位が、シークできる最小単位となっているのです。
このアーカイブファイルは、単純に途中から読み始めても完全にそのときの状態を再現することはできません。映像と違って、毎フレームの状態が完全に記録されているわけではないためです。(それをすると、ファイルのサイズが1GBどころではなくなってしまいます!)
リアルタイムのイベントでは、例えばコメントやVアイテムなどの数が多いものは、そのときに表示されるべきものすべてが都度送られてくるわけではなく、追加分だけが送られてきます。最初に入室したときにのみ、クライアントがサーバーへ問い合わせて表示すべきものをすべて教えてもらうことで、イベントの途中で入室しても過去のコメントが見えるようになっています。
アーカイブでは、分割された各ファイルの先頭に、その時間にシークしたときに表示すべき過去の情報を書いておき、シークしたときにはそれを読むことでその時の状態を再現する、という方法を取っています。
アーカイブ機能のアップデートへの影響
アーカイブ機能が、リアルタイムで送受信しているメッセージを保存しておいて、それを読んで再生しているイメージはなんとなく理解いただけたでしょうか?
さて、開発を進めていると、送るメッセージの形式が変わったり、内容が増えたり減ったりします。
また、メッセージの内容は変わらなくても、受け取ったときの動作を変更したくなるときもあります。
まずメッセージの内容を変えたときにどうするかというと、2つ選択肢があります。
- アーカイブのデータを新しい形式に対応するように変換する
- クライアントが新しい形式と古い形式両方を受け取れるようにする
これまでのアップデートでは、どちらの方法も採用したことがあります。
そしてメッセージを受け取ったときの動作を変更するときも、2つ選択肢があります。
- アーカイブのときは(元イベントの時期によって)動作が以前のままになるようにする
- 動作が変わることを許容する(動作が変わっても破綻しないことを確認する)
これは基本的に2を採ってきました。
実際にあった例としては、アバターの挙動を調整した際に、過去のイベントのアーカイブでも同様にアバターの挙動が変わったことなどが挙げられます。
このように、機能追加や変更の際、アーカイブが大丈夫かを常に考え、場合によって追加の実装をする必要がありました。これによって機能開発のコストが増大していました。
見落としがあってアーカイブが正しく再生できなくなってしまうこともありましたが、アーカイブの数は日々増えていくため、そのすべてを随時チェックするのも現実的ではありません。
もちろんこれらのリスクは事前にわかっていたものではあります。
映像と違ってフォーマットは定まっておらず、それを自分たちで作り、毎週のように変えていく中で、アーカイブも維持し続けるという大きなチャレンジではありましたが、タイムマシンは人類にはまだ早かったかな……というのが個人的な感想です。
まとめ
clusterのリアルタイムとアーカイブの仕組み、そして過去のイベントのアーカイブを維持し続けることが開発へ影響する事項について書きました。
この維持にかかるコストが無視できないほどの変更になるということで、裏を返せばそれなりの大規模アップデートということになります。そういった面では大いにご期待いただければと思います。
今回は、技術的な詳細には触れずになるべく説明を平易にすることに努めたため、エンジニアの読者には物足りなかったかもしれません。なにかしらの登壇機会などがあれば、今度は技術的な詳細について話したいので、いい感じの会があれば呼んでください。
明日は、ほびわんさんの『clusterSDKレイヤーの話(仮』です。
そういえば、レイヤーについてはドキュメントに記載がないのでは……? (転載させてもらおう!) 楽しみです!