VRSNS上でオンライン対戦格闘ゲームを制作してみてわかったこと(同期編)
ムシコロリと申します。
自分は趣味でVRChat上で動くゲームをいくつか制作しているのですが、今回はオンライン対戦ボクシングゲームを制作しました。
その際に気を付けること等のメモを簡単に忘備録として書いておきます
1.正常な動作とユーザーの納得感は違う
オンラインゲーム特有の問題として、ユーザー間の同期問題が一番に挙げられます。今回製作した格闘ゲームジャンルは特に顕著で、「自分の画面では当てたのに相手にダメージが入ってない」「自分の画面では相手の攻撃を避けたのに自分にダメージが入った」等の問題があるとすぐにユーザーは気づき、ゲームに対して不満を持ちます。
実際、自分が制作している最中にもその現象は発生し、「当たった」「当たってない」の声が上がることもしばしばありました。
今回は「ユーザー間の同期方法」「ユーザーの環境差」を簡単に書いていこうと思います。
2.ユーザー間の同期方法
オンラインゲームでは様々な企業が四苦八苦してユーザー間の同期をとっています。特に格闘ゲームではその判定がシビアです。以下に簡単な例と参考ページを添付します。
・完全同期型/キー入力同期方式(VF5)
参考ページ:https://www.4gamer.net/games/105/G010549/20100905002/
・ロールバック方式(ストV)
参考ページ:https://news.yahoo.co.jp/articles/0245017f99faa7b449faa82fe44adfcf887e4f1c
色々ありますが、今回自分が採用したのは「キー入力同期方式」になります。トラッキングデータの取得はVRChatがやってくれるので、「ユーザーがどのボタンを押した(どの行動をした)」を最速で同期してしまえば理論上は「VRChat上で最も同期が優れたゲーム」になるという理屈で制作しています。(といっても、同環境で2クライアント起動しても、0.5秒程度のトラッキング遅延があるので完全ではない)
その「最速で同期」を実現するために、まずVRChatの同期処理速度を調査しました。
VRChat特有の同期方法には大きく分けて二通りあります。
処理同期:「このクラスのこの関数を全員に実行させる」
変数同期:「この変数をユーザー間で同期する(オーナーと同じにする)」
実験の結果、入力ボタンのフラグや体力等の単純な同期であれば「変数同期の方が処理同期よりも0.2秒程度速い」ということがわかりました。(変数同期:0.2秒程度 処理同期:0.4秒程度)
なので、ユーザー間の同期処理は最低限にしつつ、入力に重点を置いて変数を同期する方法をとりました。周期的な変数の同期は一切せず、値が変化した時のみ「オブジェクトオーナー(VRChat特有のオブジェクトの持ち主的な概念)」がデータを全員に送信することで実現が可能になりました。
3.ユーザーの環境差
ゲームが置いてあるのがオンラインSNSなので、ユーザーごとのPCスペックや回線、HMDの通信方式が大きく異なります。これはゲーム上から弄ることができない不変のものであるため、その差をどうにかして最小にする必要がありました。
まずユーザーのPCスペックに関してはワールドの軽量化が最優先事項として挙げられます。最も単純な解決方法かつ解決方法がインターネットにいくらでも転がっているため、今回は省略いたします。
回線速度はどうしようもないため、同期処理を最小限で実装することが考えられます。
意外と最も影響が大きかったのが、HMD-PC間の通信方式でした。
結論から書くと、表示とトラッキング反映が最も早いのがQuest単機でした。
Virtual Desktop + Steam VRまたはQuest Link + Steam VRが遅いという結果です。
アプリが二つ噛んでいるので当然といえば当然ですが、「格闘ゲームを作らなかったら一切気にしていなかっただろうな……」といった気持ちです。
近々開催されるボクシング大会では、できるだけSteam VRを嚙ませないレギュレーションでゲームを行います。
PC単体
quest単体
PC有線-quest VRC
PC無線-quest VRC
PC有線-quest Steam VR
--------ここより下にvive とindexが入る-----
PC無線-quest Steam VR
PC無線-quest VD
※VD/Steam VRに関しては、設定等の動的ビットレートの制限などにより多少の順位の変動はあり
4.納得感とは/まとめ
製作者がどれだけ同期問題を気にして作っていても同期問題は発生します。
なので、「ユーザーが納得できる仕様」「ゲームバランス」の間で最も気にしていたのが「ダメージの入るタイミング」です。
(1).受ける側主観で「当てられた」時にダメージが発生する
攻撃側からすると「当たっただろ今の!?」となる可能性は上がるが、避けメインの方の満足度は高い
(2).攻撃側主観で「当てた」時にダメージが発生する
避けメインの方からすると「当たってないだろ今の!?」となる可能性が上がるが、攻撃している方は気持ちいいし、エフェクトが出るタイミングがバッチリ
(3).第三者から見て「当たったのを見た」時にダメージが発生する
他者から見ると公平だが、プレイヤーとしては当たってるか当たってないかわからない。未来予測ゲー
客層的に多いのは(2)の方式を好む方だったので採用しました。
これからもまだ調査を重ねてより優れた同期方法を模索していこうと思います