WebGLで複数ウィンドテスト行う際のTIPS

オンラインマルチプレイゲームのテストは大変です。
今回はWebGLを使ったブラウザメタバースエンジン「Vket Cloud」を使った開発で、なるべく多くのウィンドウでマルチプレイテストした際の知見を共有します。

# オンラインマルチプレイのデバッグの難しさ
他者起因による不特定多数から通信が発生する為、想定外の挙動を起こしたり、最悪負荷スパイクが発生してクライアントやAPIが落ちる、なんてこともあります。
単なる座標同期APIの負荷テストであれば、通信をエミュレートするBOTを投入すればいいです。
一方でワールドによっては独自に実装されたギミックによって、接続数が増えることで負荷が増大することもあったり、「個々の機能では問題無いのが、特定のギミックを実装するために機能を組合わせたら不具合が起きる」といったケースもあったり。BOTだけではカバーできないことが多々あります。
1人でワールドに入っても問題なかったのが、2人・3人で接続すると問題が起きたり。
10人程度であれば問題無かったのに、100人で接続すると明らかになる課題が発見されたり。
300人で接続したら今まで問題無かったところで問題が起きるようになったり・・・。
事前にパターンを網羅することは困難で、とにかく作られたワールドでテストを繰り返すことが大事です。

# PC上の制限
ブラウザが使えるWebGLリソースは、OSがブラウザごとに割り当てています。
つまりChromeでVketCloudワールドを複数開いたりYouTubeなどWebGLを使うページを平行して開くと、CPUやメモリ、GPUに余裕があっても動作が重くなり、FPSが著しく下がります。
体感としては、同一ブラウザでVketCloudワールドを４つ開くと動作が重くなります。
Chromeのウィンドウで重たくなっても、別にEdgeやFirefoxでVketCloudワールドを開くと、PCのリソースに余裕があれば軽快に動作します。
また、使うブラウザを分けなくてもユーザープロファイルを分けることで別ブラウザとして扱うことができます。

**例：同じPC上で、単一プロファイルと分けた場合**
| 単一プロファイル | プロファイル分けた |
| ---- | ---- |
| ![同プロファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184803/165e94d7-1fa0-5642-c94a-c636fb60dc6e.png) | ![別プロファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184803/8cf86565-4d17-70d9-1e45-a4e609dd5485.png) |
| 8～9fps | 30～40fps |


Chromeを例にすると、ショートカットを作成し、プロパティから「リンク先」欄の後ろに--user-data-dirを追加することでプロファイルを分けることができます。
```
"C:\Program Files\Google\Chrome\Application\chrome.exe" --user-data-dir=C:\Users\hogehoge\Documents\TestClient\ChromeData\1
```
![chromeShortcut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184803/df1e69ae-5aad-7801-0642-2721aa7a6712.png)

# 求められるPCスペック
重要なのはビデオメモリ・CPUコア数・RAMメモリ・GPU性能の順です。
GPU性能はそこまで求められず、Intel UHD Graphicsでも十分。
単一PCで多くのVketCloudワールドを開く場合、まず最初にボトルネックになるのはビデオメモリです。ここが枯渇するとWebGLが機能しなくなり、FPSがガクッと下がり、まともに動かなくなります。
つまり専用ビデオメモリが決まっているdGPUよりも、RAMメモリの数だけ増やせるiGPUの方にアドバンテージが有ります。

次に必要となるのがCPUのコア数です。
内部でどういった処理が行われてリソースが消費されるかわからないのですが、CPUのコア数が多いほど同時に立ち上げられるワールドが多くなります。
逆に、どんなにRAMメモリ・ビデオメモリ・GPUリソースに余裕があっても、一定数以上開くとFPSが下がります。

![Ryzen4800H_RTX3060.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184803/785190c7-979b-7661-f7cf-fdb68d414f67.png)
*Ryzen7 5800H(8コア) + RTX3060Laptopだと6ウィンドウまでは19~21fpsを維持できたが、それ以上になると15fps前後、12ウィンドウ開くと半分くらいが1桁fpsになった*

このことからコア数が多く、そこそこのGPUを積んでいて、バランスのいい価格帯となるとintel core i5-14500でした。
![i514500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184803/9362d301-b0d4-381a-e7a5-3167f2763dfc.png)
*ワールドを13個開いても、13~22fpsの２桁fpsを維持することができた*

ゲーミングノート（core i7-12650H + RTX4050）でも14ウィンドウが限界だったことを鑑みると、iGPUだけで完結するcore i5-14500 はだいぶコスパがいいです。

# .batで半自動化
大規模接続ワールドの動作確認のためには、なるべく多くのPCから複数ウィンドウを開いてテストが必要です。
そうなると前述のようにChromeショートカットリンクの手作業で作るのは手間が掛かります。
なので以下の.batファイルを作って、クリックしたら`profileCount`の数だけ`url`を開くようにすると少し楽になります。
```
@echo off
:: 開きたいURL
set url="https://sample.com/main.html?worldid=test&roomid=takusan_setsuzoku_xxxxxx"

:: プロファイルの数（1から指定した数までの連番）
set profileCount=3

:: Chromeの実行ファイルパス
set chromePath="C:\Program Files\Google\Chrome\Application\chrome.exe"

:: バッチファイルが置かれているフォルダを取得
set baseDir=%~dp0ChromeData

:: ループでChromeを起動
for /L %%i in (1,1,%profileCount%) do (
    start "" %chromePath% --user-data-dir=%baseDir%\%%i %url%
    timeout /nobreak /t 1 >nul
)
```

# おわり
当初の見込みでは、より性能のいいGPUを積んだRyzen7 5800H(8コア) + RTX3060Laptopの方が優位だと思っていましたが、GPUが弱くてもコア数が多いcore i5-14500の方が有利というのが意外でした。
もっと条件をそろえて、パーツを組み替えながら検証したいところでしたが、ひとまずプロジェクト走りながら得た知見の共有でした。