前置き
この前、格ゲーのネットコードについて解説記事を書きました。
自分で記事を書いてて思ったのですが、格ゲーに限らず決定論的にマルチプレイヤーゲームが作れたらかなりアドバンテージが大きいなという事です。
個人的に特にメリットが大きいと感じるのは、決定論的ゲームはネットワークマルチ時に、お互いの入力だけを送信し合えば済むので、チート耐性が高い事です。
フォトナやフォールガイズは公式専用サーバを用意してチート耐性を高めてますが、その代わり、メチャクチャサーバ代が高くつくという代償を払ってます。
(まあ、仮にフォトナやフォールガイズを決定論的実装で作ったとしても、各クライアント上でそれぞれ数十人分全員のプレイヤーの動きをシミュレートさせるのは負荷的に無理なのでいずれにしろバトロワは公式専用サーバが必要になりそうですが)
決定論的なゲームなら、サーバ代を安く抑えつつ(Epic Online Servicesならタダ)、チートも防ぐことが出来ます。
意外と見過ごされがちな点ですが、個人レベルで作るゲームは、リリース後の”運用サポートコスト”は最低限に抑えるべきです。
例えば個人でFPSを作ったとして、ゲームのチート耐性が低いと、ゲームが人気になるとチーターが湧いてきます。
まあ、一般的な対応としてはゲーム内に違反者報告機能を組み込んで、ゲームユーザーが開発者に通報できるようにして、開発者がチーターをバンするような流れを作る感じでしょうか。
しかし、よく考えてみてください。
それってメッチャ大変じゃないですか?
開発者は通報された人をどんどんバンしちゃっていいんでしょうか?
でも誤通報だったらどうしますか?誤ってバンされたらユーザーは当然怒ります。
じゃあサーバから試合のログデータを引っ張り出してホントにチートがされたっぽいか確認しますか?しかし、個人レベルのゲームでそこまでしっかりログを収集して蓄積できてないかも。
仮にできていたとしても、通報された人全員に対してこんな作業をイチイチやってたらキリがありません。ずっとチーターのバン作業に追われ続けて、開発作業はストップしてしまいます。本当にこんな作業がしたくてゲーム作ったんだっけ?
実際の例を上げますが、例えばどうぶつタワーバトルでもゲームのバグを利用して不正にレートを上げた人を開発者がバンした結果、twitterで揉めるといった事態も起きてます。
こういうトラブルが何度も起きると開発者は本当に疲弊してしまいます。
そういうわけなので、個人開発ゲームではなるべく運用サポートコストがゼロになるように設計した方がいいわけです。
一番いいのは、マルチプレイヤー機能なんて実装しなくて済むならしないに越した事はありません。
そうは言っても、これからはマルチプレイヤーが当たり前時代なので、そういうわけにもいきません。
開発者がサポートに追われて疲れるのは、チーターが湧いてくるのが原因で、チーターが湧いてくるのはゲームにチート耐性が無いのが原因です。
なので、決定論的なゲームにして、そもそも原理的にチート不可能にすれば、解決です。
そんな訳で、今回の記事ではあらためて決定論的ゲームのメリット、デメリットを考察して、決定論的ゲームを作るための課題、現在取り得る決定論的ゲーム開発の選択肢について考えてみます。
ちなみに、決定論的ゲームの考え方というのは格ゲーのネットコードの考え方と同じです。格ゲーネットコードの記事で”遅延ベースのネットコード”と呼んでいたものは、”決定論的ロックステップ”とも呼ばれていて、”ロールバックネットコード”と呼んでいたものは”決定論的ロールバック”とも呼ばれてます。
決定論的ゲームのメリット
このブログでは今まで何回も書いてきてる事なのでさっくりと流します。
・”決定論的ロックステップ”や”決定論的ロールバック”のネットコードを実現するために必要。
・普通は各プレイヤーの”状態”を送信し合うので、状態値を改竄すればチートできてしまうが、決定論的ゲームでは各プレイヤーの”入力”だけを送信し合うので、チートできない。
・入力データは小さいので通信帯域を節約できる。
・ロールバックを実装すれば遅延無しでキャラを操作できる。
決定論的ゲームのデメリット
これもさっくり流します。
・そもそもゲームを決定論的に作るのが技術的に難しい。
・全てのクライアント端末が、全プレイヤーのシミュレートを処理する必要があるので、格ゲーみたいにプレイヤー数が少ない場合はともかく、プレイヤー数が増えてくると計算負荷がどんどん大きくなって、無理になってくる。特に何フレームもロールバックする時はキビしい。
よってフォトナみたいな多人数バトロワは処理負荷的に無理。
決定論的ゲームを実現するための課題
これも格ゲーネットコードの記事で書いたので流します。
・決定論的な物理エンジン実装が必要
・固定フレームレート実装が必要
・浮動小数点問題の解決が必要
決定論的ゲームを実現するための手段
さて、そろそろ本題に入っていきます。
決定論的ゲームを実現するための手段って何があるんだっけ?
私が軽く調べた限りでは、3つの方法があるようでした。
・格ゲーならUFE2を使う
・Photon Quantumを使う
・DOTSとUnity Physicsを使う
ちなみに、3つの方法はどれもUnityでの方法です。
Unreal Engineで決定論的ゲームを実現する方法は調べた限り無いようでした。
UnityとUE以外については調べてません。なんか他に簡単で有力な方法を知ってる方がいればむしろ教えてください。
ちなみに、決定論についてEpic創業者のティム・スウィーニー氏じきじきにコメントしているフォーラムがありました。
「Unreal Engineのどのバージョンでも決定論について話題が出るけど、たしかに決定論的にゲームエンジンを設計しておけばそれは可能だったかもしれないけど、UE4はそうしてないんだよ。UE4では素直にレプリケーション使ってね。現在のインターネットは十分な帯域幅があるから大丈夫だよ」みたいな感じの事を仰られてます。
まあ私としては帯域よりもチート耐性を問題にしてるんですが。
ついでに触れておきますが、例えばオセロのゲームを作る場合、別にオセロはお互いの打ち手を送信し合えば済むので、何も考えなくても決定論的に作れると思います。物理の同期とか要らないですからね。
この記事では物理エンジンが必要になるようなゲームのケースについて述べてます。
まあそういう訳で、3つの決定論的ゲームの実現方法についてそれぞれ見てみましょう。
UFE2(Universal Fighting Engine 2)を使う
格ゲーネットコードの記事でも書いた通り、作るのが格ゲーなら素直にUFE2を使えば良いと思います。
Photon Quantumを使う
格ゲー以外のゲームを決定論的に作るなら、Photon Quantumが選択肢に上がってきます。
Quantumには、独自の決定論的な物理エンジンが実装されてます。
フレームレートについては固定30fpsか60fpsの2択が選べます。
そして、独自の数学ライブラリも用意されていて、浮動小数点の代わりに固定小数点を用いる形になるので、浮動小数点問題も解決されてます。
デフォルトでロールバック機能が実装されてます。
かなり素晴らしいですね。もうこれでいいじゃん!と思っちゃうところですが、実は問題があります。
それは、Quantumを使用するためのコストが結構でかい事です。
Quantumを使うには、Gaming CircleというPhotonのサブスクサービスに加入する必要があります。
今まで、このGaming Circleのサブスク代は月額1000ドルでした!
高すぎ!
今まで私的にはQuantumが眼中に入らなかった理由はこれです。
さらに、QuantumではCCUベースで別料金がかかってきます。
1CCUあたり月額0.5ドルです。(ただしGaming Circleで500CCUまで無料サービスが付いてきます。250ドル相当)
こんなわけなので、今まで個人開発者としては高すぎて選択肢に入ってこなかったQuantumですが、実はもうすぐ個人開発者は月額250ドルでGaming Circleに入れるプランが追加されることが予告されてます。
まあ250ドルでも高いっちゃ高いですが、1000ドルよりはマシになりました。
ちなみにGaming Circleではいろんなジャンルのゲームテンプレートにもアクセスできます。
もっと詳しい詳細についても書きたいんですが、Quantumはサブスクに入らないとまったくSDKやドキュメントにアクセスできないので、宣伝されている以上の情報は完全に謎に包まれていますので分かりません。
ちなみに、Gaming Circleのサブスクを解約したらどうなるの?というと、まずSDKはダウンロードできなくなりますし、UnityにインポートしたSDKも動作しなくなる?らしいです。
つまりQuantumで一度ゲーム開発を開始しちゃうと、そう簡単には解約できなくなる点に注意です。
さすがにビルドしたランタイムのゲームは解約しても動作するようですが。
私がここで物申しておきたいのは、PhotonCloudのビジネスモデルについてです。
PhotonはPUNもQuantumもFusionも、ネットワークライブラリとリレーサーバ課金が抱き合わせ商法でセットで売られてます。
まあ商売なんだからしょうがないですが、個人的にはもうEpic Online Servicesで無料のリレーサーバが提供されてる今となってはPhotonのリレーサーバにお金払うのイヤなんですよね…。
というわけで、Quantumを使わないで決定論的ゲームを作る方法も探ってみたいと思います。
DOTSとUnity Physicsを使う
UnityのDOTSって、実は結構決定論を志向してます。
DOTS向けに開発中の物理エンジン、Unity Physicsはかなり決定論的です。
惜しいのは、浮動小数点問題が残ってる点で、これにより、アーキテクチャの異なるCPU間では浮動小数点の演算結果に違いが出て、決定論的では無くなります。
実は、この問題を回避した方がいます。
↑こちらの方が改造したバージョンのUnity Physicsでは、クロスアーキテクチャの完全な決定論が実現されているらしいです。
リポジトリはこちら↓
https://github.com/Kimbatt/unity-deterministic-physics
どのように実現したかというと、SoftFloatという浮動小数点演算をソフトウェア上で行うライブラリを組み込んで、Unity Physics内の浮動小数点演算を全てSoftFloatに置き換えたという訳です。
決定論的になったのは嬉しいですが、代償として、ハードウェア浮動小数点演算の最適化の恩恵を受けられないので、シミュレーション速度は1/2~1/4程度まで低下してしまったそうです。
まあ遅くはなったものの、逆に言えばそれくらいの低下で済んでるので、使い方次第では問題無いでしょう。
物理エンジンが決定論になったのはいいとして、Burstについても見ていきましょう。
BurstについてはUnityは昔から「決定論になる予定です!」と宣伝してましたが、いまだに全然決定論になってません。
https://forum.unity.com/threads/burst-compiler-deterministic-floats.522856/
まず、浮動小数点がクロスアーキテクチャでの決定論に対応してません。これについてはUnityの人の言い方だと、「実装する予定はあるけど今忙しいから当分実装しない気がする」くらいのテンションっぽいです。
さらに、浮動小数点問題が解決したとしても、JobSystemやらなんやらで、マルチスレッドをバリバリ駆使したゲームで、スレッド実行順とかが絡んできちゃうし、本当に決定論的なゲームなんて可能なんだっけ?という問題もあるそうです。
こうして見ると、DOTSで決定論的ゲームを作るのも、まあ少なくともDOTSが完成してからじゃないと難しいのかもですね。
DOTSっていつ完成するんだっけ?というと、さあ、本来もう完成してるハズでしたが、実際は3年後か5年後か…。
私もせっかくなのでDOTSでの決定論について触って検証してみようとしましたが、そもそもECSがサーパリ分かんなくて諦めました。誰か検証された方がいましたら教えてください。
Unity PhysicsがECSからしか触れないのもなんか腹立ちますね。GameObjectから触りたい…。
ちなみに、格ゲーネットコードの記事で、「Unityで固定フレームレートを実現するのは難しいかも…」と書きましたが、その後ググったら簡単に実現する方法がありました。
http://kagring.blog.fc2.com/blog-entry-75.html
Time.captureFramerateに値を設定すると、固定フレームレート的な挙動になるようです。
例えばこの値を60にした場合、「現在のフレーム時間が16.6ms未満だったら、16.6ms経過するまで待機」という挙動になり、固定フレームレートのゲームの挙動になります。
多分Time.deltaTimeの値も16.6ms固定になると思います。
まとめ
そんなわけで、今回の記事では決定論的なゲームを作る方法を探ってみました。
自分の印象としては、格ゲーならとりあえずUFE2使えばいいけど、格ゲー以外なら、価格面などの条件が合うならPhoton Quantum使えば良さそう。
そうでなければDOTSを頑張ればもしかするといけるかもしれない。
という感じでしょうか。
とは言え、DOTSを頑張って改造して決定論にするなんて、そんな事が簡単にできるんだったらUnityチームだってとっくにやってるはずなわけで、だからかなり大変かもしれないですね。
自力で未知の領域で手探りで頑張るよりは、決定論的ゲームは今の時点では諦めて、普通にゲーム作っちゃう方が無難な気もしますね。
決定論的実装の方法が確立されて、情報が出回りだしたら改めてその時に検討し直すといったところでしょうか。
これまで散々、UE5に移行するぞ移行するぞ!と言っては来たものの、もしUnityで決定論的ゲームが作れるなら、決定論とEOSを組み合わせればサーバ代がゼロかつチート耐性も付くという、聖杯になり得るわけで、そこで未練が生じていたので今回調べてみました。
まあ、今のところは難しいらしいと分かれば、心置きなくUE5で普通にマルチプレイヤーゲーム作ればいいかなと思いました。
Quantum使うとEOSが使えなくなるからタダじゃなくなりますしね。
そんなわけでしたが、この記事が参考になれば幸いです。