オンラインゲーム 10年の進化と同期方式の選び方

オンラインゲームを作ろう!と思ったことがある方は、
こちらの講演記事を1度は見たことがあるのではないでしょうか。

www.4gamer.net

こちらの講演は、具体例を交えながら非常に分かりやすくオンラインゲームの主な同期方式が説明してあり、
2024年現在でもオンラインゲームの基礎を学ぶ資料として真っ先に名前を上げる最高の資料です。
しかしながら講演は2010年のものであり、オンラインゲームはこの10年余りで進化しています。

この辺りの進化の話を簡単にまとめつつ、オンラインゲームの同期方式の選び方を紹介します。

(上記講演記事の知識/用語を前提としているため、先に上記記事をお読みください。)

オンラインゲームの民主化について

技術の話をする前に。

近年、「マルチプレイヤーゲーム」と聞いてオフラインの画面分割ゲームを想像する人はいないと言って良いほど
オンラインゲームは民主化されてきました。
人々は当たり前のようにマルチプラットフォームでマイクラを遊び、Fortniteでは100人同期、
Steamでワンコインで売っているゲームもオンライン対応しててビビります。

製作側に目を向けると、
UnityであればPhoton、Unreal Engineなんてもう標準でオンラインゲームを作れる仕組みが整っています。
マイクラのMODや、UEFNなんて、ほぼ知識ゼロでオンラインゲームが作れます。

オンラインゲームは、遊ぶ側も作る側もどんどん民主化が進んでいることが分かります。

が!
何も考えずに作ると「急に他の人が吹っ飛ぶんだけど!」「めっちゃカクつく!」「ホスト有利すぎ!」など、
"ちゃんと動く" オンラインゲームを作るには、まだ少し専門知識が必要です。
この記事を読んで、作りたいゲームにあった同期方式を選びましょう。

10年でなにが進化したの?

ラグ

世界の「ラグ」は、通信環境の改善により多少はマシになったものの
光の速さは10年前から変わっていないため、依然として存在しています。

帯域

帯域はラグに比べたら大きく進化しました。
3G回線でゲームをするユーザーは減り、光回線(と同等レベルの回線)は流行り、
Wi-Fiの性能は上がっています。
10年前と比べるとゲームに使える帯域は大きく増加しました。

CPU

10年も経つとユーザーの端末やサーバーのCPU性能はもう雲泥の差。
CPUをぶん回して誤魔化す力技が使えるようになりました。
Fortniteの100人捌けるサーバー、ロールバックによる再計算など。

ロジック

上記講演内で触れられている

敵の動きを同期させるのは技術的に困難とのことで,「モンスターハンター」といった近年のゲームでも,おそらく同期は取られていない。

これも、最近のモンハンワールドモンハンライズでは雑魚敵まで同期されています。
これは通信帯域の増加もありますが、いかに誤魔化しつついい感じに同期するか、
という知見が溜まってきたのも大きいのではないかと思います。

それぞれの同期方式の進化

非同期型/サーバー集中処理型

最近どんなゲームで使われているかというと、分かりやすいのがFortniteVALORANT
依然としてFPS/TPSで大流行り。
あとはLoLなんかのMOBAも。

上記講演内では「帯域が問題になりがち」と記載がありますが、
これはネットワーク環境の進化によってだいぶ変化しました。
その結果、Fortniteでは100人分のデータを集め、サーバーで各プレイヤーの処理を行い、
それぞれのプレイヤーに必要な情報だけを送信する。なんてことが可能になったわけですね。

VALORANTの当たり判定についての記事はめちゃくちゃ面白いし、
Forniteがどうやって100人分同期しているかもめちゃくちゃ面白いのですが、細かい話は割愛します。
なぜなら、こんなゲームサーバーを置いておけるのは大企業だけだし、
そんな大企業な方はこんなブログ読んでないと思うので・・・。

どんな時に選ぶか

他の選択肢を試した上で「ああ・・・自分で建てるしかないな・・・」となった方だけがお使いください。
具体的には「厳密な判定が必要なe-Sportsを作るんだ!」「100人でバトロワしたい!」
「MMO作りたい!」「ホストがいなくても良い世界が作りたい!」「チートは何が何でも絶対許せん!」
という方以外、一回この選択肢は忘れましょう。

非同期型/クライアント分散処理型

一番流行ってて、最初に選択肢に上がるのがこれ。
特にインディーゲームで大流行り。
なぜなら、UnityでPhoton(PUN/Fusion)を使ったり、
Unreal Engineを素直に使っていると、自動的にこの方式になるからです。
(世の中の「簡単にオンラインゲーム作れるぜ!」ってライブラリは大体これ。)
(Unreal Engineはコードほぼそのままでサーバー集中処理型にも出来るのが凄い!)

帯域増加の恩恵はもちろん、
優先度の低いオブジェクトは自動的に同期頻度を下げる、通信圧縮技術などの進化の恩恵も受けて、
なんか適当にやっても"それっぽく"動きます。

実装について

"それっぽく"動くまでは一番早く、実装も楽なんですが、
個人的には、ちゃんと動くようにするのはそこそこ大変という印象です。
「ラグってもカクカクしないようにしたい」「物理オブジェクトが吹っ飛んでいった!」
「このコードはホストで動くんだっけゲストで動くんだっけ?」「ゲストはどこまでデータ持ってるんだっけ?」
「ラグって通信順序が変わるとバグる」などなど、
ちゃんと基盤を整えないと「1人プレイの時は動いてたのにオンラインだとバグる」が頻発しがちです。

自分はホストとゲストの実装はガッツリ別物としてしまう方が好みなんですが、
Unreal Engineのチュートリアルを見ても関数内のif文でホストかゲストか分ける、みたいな実装が多く、
本当にこれでFortnite作ってます・・・?という気持ちになります。めっちゃ混乱しない・・・?

どんな時に選ぶか

この方式でだいたいのゲームが出来ちゃいます。
(だからこそ、UEには標準で乗ってるのはこの方法だしFortnite上でいろんなゲームが実装されている。)
じゃあこれでいいじゃん。となりますが、出来ないことを一言でいうなら「厳密さ」。
格ゲーのような1フレーム1フレームの同期が大切なものは難しいですし、
レースゲームや横スクロールアクションも大きなズレを許容しないと厳しいです。

完全同期型/キー入力同期方式(コマンド入力同期方式含)

ようやく一番語りたいところに来ました!

これから急激に流行ると思っています。
というかコンシューマー機では大昔から沢山採用されてるので、
ようやくインディーでも手が出せる環境が整ったと言うべきでしょうか。

「クライアント分散処理型」で出来ないことはこれでやりましょう。
なんなら、出来ることもこれでやりましょう。

ロックステップ方式

上記講演内で紹介されているキー入力同期方式は「ロックステップ方式」や「ディレイ方式」と呼ばれる方法です。
ラグった時に相手プレイヤーだけでなく、ゲーム全体がカクカクしてフレームレートが下がる現象に遭遇したことありますよね。
そのゲームはロックステップで実装されています。
「通信品質に左右される」「多人数対応は難しい」というデメリットが記載されていますが、
それも「ロックステップ」と呼ばれる方法の中での話です。

10年前時点のキー入力同期方式は、ほぼ100%ロックステップだったと思います。(要出典)

ロールバック方式

ここ数年でキー入力同期方式の中でも「ロールバック」と呼ばれる手法が流行り出しました。
CPUの進化のおかげで複数フレームのシミュレーションをする余裕ができたからだと思っています。
ロールバック方式の内容については、こちらの動画をご覧ください。日本語字幕あります。
www.youtube.com

このロールバック方式は、ロックステップ方式のデメリットを克服しています。
通信品質に左右される → 遅延してもゲームが停止することはなく、クライアント分散処理型と同等に考えられる。
多人数対応は難しい → 誰か一人でも遅延したらゲームが停止するから言われていたこと。同様にこちらも問題が少なくなる。

実装について

キー入力同期方式は、非同期型より実装もシンプルかなーと思っています。
全員の端末に同じ入力データが来て全く同じものが動く。ただそれだけ。
自分がホストなのかゲストなのかなんて考える必要はありません。
まあシンプルとイージーは違うんですが・・・。

そもそもキー入力同期方式は使う帯域も少なく、
コンシューマー機のゲームだと昔からめちゃくちゃ採用されているのに、
インディーでは全くと言っていいほど見かけません。

これは、UnityやUnreal Engineで実装するのが難しかったのが原因だと考えています。
ユーザーごとにGameObjectやComponentの実行順が同じなのか保証できなかったり、
なんならfloatを使うだけでプラットフォームごとに計算結果が異なってしまうために、
同じ入力から同じ結果が得られるようにする手間が大きかったのです。

どんな時に選ぶか

「厳密さ」が必要な格ゲー、レースゲームなど。
物理演算がゲーム内容に大きな影響を及ぼすゲームなんかも、完全に同期されている方が都合が良いです。

横スクロールアクションでプレイヤー同士に当たり判定がある場合は、敢えてロックステップだったりします。
衝突判定がある他プレイヤーがワープすると不都合があるケースですね。

他にも、大量のオブジェクトを同期したい時もキー入力同期方式の方が良いケースがありそうです。
例えば、ヴァンサバをオンライン対応したい場合、大量の敵を真面目に同期するのは流石に2024年のインターネットでも厳しいです。
クライアント分散処理型で敵の同期は頻度を下げる(数秒に1回とか?)、10体程度を群として扱い同期する、諦めて同期しない。などの手法が考えられますが、
敵の動きが単純であるならキー入力同期方式でほぼ同期できるのではないでしょうか?
(このあたりはゲーム仕様によりそうですね。)

ロールバック方式の民主化

さて、ここまでをまとめると、
ロールバック方式にメリットはありそうですが実装が難しい。という話になります。

そんなところに現れたPhoton Quantum
独自の固定小数点型からECS、決定論的な物理演算まで実装してあり、
この上に実装するだけで勝手にロールバック対応のオンラインゲームが作れます。
これが無料で誰でも使えるようになったのはつい1年前の話。

PhotonシリーズならUnity用?と思われるかもしれませんが、
Unreal Engine用のPhoton Quantumも開発中とのことで、
どうやら数ヶ月以内にPreview版がリリースされるらしいです!
楽しみですね。

急にPhoton Quantumの宣伝記事みたいになりましたが、
キー入力同期方式、そして、ロールバック方式のこれからに期待です。
ゲーム部分の実装のシンプルさからも、インディーへの採用は増えていくのではないでしょうか。

おわりに

オンラインゲームを作るのは、なんだかんだ大変なことが沢山あって、
オフラインゲームの数倍工数がかかります。誇張なしに。1桁倍で済めばマシな方。
それでもみんなオンラインで遊べるのが当たり前だと思ってる!
楽しいよな!!!オンライン!!!!

光がもっと速くなることに期待!
10msで地球1週してくれれば60FPSで同期できる!!!!!!!
がんばれ光!!!!!

そんな現実逃避をしたくもなるものです。
みんなで頑張ろう!