見出し画像

Noraの技術解説+イベント開催感想

ゲーム開発者がブラウザ上でゲームの試遊展示をすることができるWebサービス「Nora」を作っています。
ちょうど本日2023/8/12、集英社ゲームクリエイターズCAMPさん主催のゲーム展示イベント「CAMPバーチャルエキスポ(β版)」がNora上で開かれました。

Noraは小規模ゲーム開発者に使ってもらうためのサービスですが、開発者さんから「どうやって動いてるの?」という声が挙がっているのをちらほら見かけるので、この記事では技術的な解説をしようと思います。開発の契機とかの話はゲームクリエイターズCAMPさん側に出ているインタビューがありますので、そちらをご覧いただくのがいいかと思います。


概要

出展者は専用クライアントアプリNoraHostを使用してNoraにゲーム画面を配信します。プレイヤーはブラウザからNoraにアクセスし、ゲーム画面を視聴することができます。


さらに、プレイヤーは自分のデバイスに接続したゲームパッドやタッチスクリーン上のバーチャルパッドを使用してゲームを操作することができます。ゲームの操作情報はリアルタイムにNoraHostに送信されていて、仮想ゲームコントローラデバイスを介してゲームに操作を反映します。クラウドゲーミング的な仕組みをユーザーのPCをホストにして実現するイメージです。

Webサーバー

フレームワークにNext.js、ORMにPrisma、バックエンドにMySQL、そのほか管理画面などもろもろをまとめてDocker Composeで動作させています。初期は生のNode.js + express + ejsというクラシックな構成だったのですが、思い立っていまどきの構成に乗せ換えました。自分のウェブサイトを未だに生HTMLで書いているような私ですが、Noraの開発を通してだいぶフロンティアとの距離が縮まったと思います。Reactにも慣れてきました。

映像配信

映像配信にはSkyWayを使っています。普段は無料枠で運用しています。

Noraの技術検証初期はcoturnをつかって自力でTURNサーバーを立てられないか試したりしていましたが、安定した映像配信や1対多配信のためのSFUサーバーの必要性もあり、専用サービスであるSkyWayを利用することにしました。WebRTCはリアルタイム通信にかかわる非常に広範な技術の集合体であり、独力でマスターするハードルの高さを実感したのも動機の一つです。WebRTCの巨大さはこことかここをみると実感できると思います。

しかし、このころの生WebRTCチャレンジで得られた知識や経験はSkyWay採用後にも大いに役立ちました。

NoraHost

出展者のPCで動かす専用アプリです。Electron/React製でWindows専用です。ゲーム画面のキャプチャ・配信と、プレイヤーの操作をゲームに反映する役割を担っています。

SkyWayの採用以前はUnityで開発していましたが、SkyWayはデスクトップPC用のネイティブSDKがなく、Electron上でJavaScript SDKを利用する方針に切り替えました。Electron=ChromiumはおそらくWebRTCクライアントとしても最も広く利用されているソフトウェアで、そこに乗っかるのは非常に安心感があり、今回の用途にマッチしていました。またブラウザベースであることから、ウィンドウキャプチャにかかわる機能等も簡単に利用することができました。

ただし一部の機能はElectron単体では実現できず、Node Native ModuleをC++で実装しています。

仮想ゲームパッド(ViGEm)

プレイヤーからWebRTCのDataChannelを通して受け取ったゲームパッド入力情報を、仮想ゲームパッドに反映することでゲームを操作します。これによりゲーム側は特別な対応をしなくても、ゲームパッド入力にさえ対応していれば試遊を行うことができます。仮想ゲームパッドにはViGEmというソフトウェアを使用しています。このViGEmはクライアントSDKがC++で提供されているため、ElectronとViGEmをブリッジするNative Moduleを実装することで動作させています。

プロセスオーディオキャプチャ

Electronの標準のウィンドウキャプチャAPIで得られる音声は、基本的にOS全体で鳴っている音声のループバックになります。これはNoraでボイスチャットを繋ぎながら試遊を行う際に不都合です(ブラウザのNoraで鳴っているボイスチャット音声が配信に乗り、ループする)。Windows上でのプロセス単位のオーディオキャプチャは長らく正規の手段では実現できなかったのですが、2021年ごろから新しくAPIができて実装可能になりました(最近OBSに入ったApplication Audio CaptureもこのAPIの登場を契機に実現しています)。実装当時は出たてのAPIでほとんどサンプルが無く手探りでの実装でしたが、これによりNoraHostの利便性は大きく向上しました。こちらもC++によるNative Moduleになっており、Native Moduleから受け取った音声サンプルをWeb Audio APIのAudioWorkletに流し、MediaStreamTrack化することでWebRTCのソースとして使用しています。
余談ですが、Discordとかは以前からウィンドウオーディオキャプチャを実現しており、やりようによっては可能だったようです。(たぶんDLLインジェクションとAPIフックをやっている気がします……)

NoraHost API (開発中)

仮想ゲームパッドを使用せず、ゲームにSDKを組み込むことで直接入力情報を適用することができる仕組みで、現在開発中です。
仮想ゲームパッドによる「ゲーム側に特別な対応が不要」という利点は失われますが、一方でより柔軟で安全な試遊を行うことができるようになります。たとえばゲームパッドだけでなくマウスやキーボードを使えるようにできますし、ViGEmに依存する必要が無いのでWindows以外のOSへの対応に向けた障壁もクリアすることができます。これは仮想ゲームパッドを置き換えるものではなく、代替機能として別途提供したいと考えています。

イベントを終えて

今回、初のイベント「CAMPバーチャルエキスポ(β版)」の開催に際しては、やはりNora自体の実績の少なさが不安要素でした。セキュリティに関しては事前にCAMPさん側から脆弱性診断のご提案をいただき丁寧に対応していただきました。一方でサーバーのキャパシティは足りるのかとか、映像配信のクオリティは快適なゲームプレイを保証できるかとか、事前に十分な検証を行うのが難しい要素もありました。本番では幸いにもサーバー自体のキャパシティに概ね不足はありませんでしたが、映像に関してはフレームレートの低下や遅延がゲームプレイに支障をきたした例もあったようで、残念な思いをさせてしまいました。
映像クオリティ低下の要因を特定して実際に改善を行っていくには、それこそWebRTCをより深く理解し、また幅広い環境でのデータの収集が必要になってくると思います。引き続き改善を目指したいと思います。

技術以外の部分では、単純にNoraがこれまでで最も大きな規模で活用されたのが嬉しかったです。インディーゲーム開発者というのはターゲットとしてはかなりニッチであり、Noraには日常的に使ってもらえるほどの大きい需要がないのが悩みの種でした。しかし、今回のCAMPバーチャルエキスポがイベントとしてしっかり盛り上がっているのを見ることができ、バーチャルなゲームの試遊展示イベントの可能性をこれまでより明確に示すことができたのはとてもよかったと思っています。出展者・参加者の皆様、大変ありがとうございました。

おわり

普段はUnityでゲームを作っている自分ですが、いろいろやっているうちにNora関係のコードは巨大化し、使われている技術もかなり広がってきました。技術的なチャレンジもたくさんあり、Web方面のスキルが拡大したので自分としてはとても良いプロジェクトになったなあと思う反面、自分ひとりで面倒を見れるのはこのくらいの規模が限界かな……という課題も感じています。Nora自体の今後の展開の仕方については引き続きよく考えたいところです。

ここまで読んでくださりありがとうございました!



この記事が気に入ったらサポートをしてみませんか?