サバイバルキッズのマルチプレイヤーネットワークインフラの内部

この夏、サバイバルキッズはNintendo Switch™ 2の初日リリースとして開始されました。このゲームはUnity 6上で完全に構築されており、Unityの初のエンドツーエンド開発プロジェクトで、パブリッシャーパートナーのKONAMIと密接に協力しました。
新しいプラットフォームでの初日開発は大きな挑戦ですが、このプロジェクトを構築した小さな内部チームには、何十年もUnityやゲームに携わってきた経験豊富なUnity開発者が含まれていました。このブログは、ゲームがどのように作られたか、どのようにこの作業がUnityの制作検証へのコミットメントを促進したか、さらに他のUnityゲーム開発者が自分のプロジェクトに適用できる教訓について掘り下げる進行中のシリーズの一部です。
これは、サバイバルキッズの制作に関するチームの教訓を掘り下げる進行中の舞台裏シリーズの最初のエピソードです。
Nintendo Switchは任天堂の商標です。
サバイバルキッズはUnity内の非常に小さなチームによって構築されました。コアグループは、さまざまな分野の約10人の開発者(アーティスト、エンジニア、デザイナー)で構成されていました。ピーク時には、他のUnityチームから参加した人々も加わり、約20人になりました。例えば、私たちのレンダリングエンジニアであるスティーブンは、私たちと多くの時間を過ごしましたが、常にプロジェクトに参加していたわけではありません。
小さなチームとして、いくつかの利点がありました。エンジニアは非常に経験豊富で、私たちのほとんどは20年以上にわたり主にAAA分野でゲームを作ってきたため、多くの教訓を学び、多くの間違いを犯してきました。もちろん、私たちはほとんどがここに長い間いるため、Unityに非常に精通しています。
私たちの中には、Professional Services/Accelerate SolutionsのようなUnityサポートチームの一部として顧客プロジェクトに取り組んだ経験がある者もいます。現在はUnity Studio Productionsです。私たちは顧客にプロジェクトを最適化する方法をアドバイスし、プロジェクトチームに埋め込んで一緒に作業し、難しい技術的問題を解決する手助けをするので、スタジオがしばしば犯す間違いとそれを修正する方法に非常に精通しています。サバイバルキッズに取り組むことで、プロジェクトを設計し、最初から正しい方向に進めることができました。なぜなら、すべての落とし穴がどこにあるかを知っていたからで、それが私たちの多くの時間とリソースを節約しました。
今日は、ゲームのネットワークアーキテクチャについて掘り下げたいと思います。私たちはUnityを使用してマルチプレイヤーネットワーキングを推進し、サバイバルキッズはプレイヤーに同じネットワーキング基盤からゲームをプレイするさまざまな方法を提供します。さあ、これがどのようにまとめられたのかを掘り下げてみましょう。これがあなたのプロジェクトにも役立つことを願っています。

サバイバルキッズは、シングルプレイヤー、ローカル協力プレイ、友達とのオンラインプレイなど、いくつかの方法でプレイできます。ニンテンドースイッチ™ 2では、プレイヤーはGameShareを使用して、別のニンテンドースイッチ2や元のスイッチにビデオをストリームし、テレビやデバイスで誰かとマルチプレイヤーをプレイすることができます。これは本当にクールです。
私たちは、すべてのそれと他の組み合わせを駆動するセットアップを望んでいました。例えば、1台のテレビで画面分割をしている2人のプレイヤーが、別のテレビで画面分割をしている2人のプレイヤーと一緒にプレイすることができます。つまり、2台のデバイスを使用して4人のプレイヤーがいるということです。その柔軟性は、さまざまな方法でプレイを可能にするために、私たちが本当に設計したかったものです。
これを実現するために、エンティティ用ネットコードを選択しました。私たちがサバイバルキッズのコンセプトをKONAMIに提案した後、私たちはすぐにプロトタイピングに入り、私たちのマルチプレイヤーゲームの楽しさを見つけました。私たちは、エンティティ用ネットコードをバックエンドネットワークとして使用する方法の概念実証として以前に書いた既存のプロジェクトを出発点として使用し、その上にゲームオブジェクトレイヤーを書いて、Prefabやアニメーションを活用しました。チームの全員がエンティティでの作業経験を持っていたわけではなかったので、私たちはゲームオブジェクトとMonoBehaviourを一緒に使用することに決めました。
私たちは、ゲームオブジェクトとMonoBehaviourにゲームプレイロジックを保持したいとも考えていました。なぜなら、それらはプロトタイピングを非常に簡単にするからです。このセットアップでは、物を組み合わせてスクリプトを書いたり、インターネットからスクリプトをダウンロードしたり、プロトタイピング用のアセットストアパッケージを使用したりできます。私たちはその迅速な反復と自由を望んでいましたが、エンティティ用ネットコードがパフォーマンスの高いネットワークレイヤーを提供してくれることも気に入っていました。私はすでにいくつかの顧客プロジェクトや個人の研究プロジェクトでそれを使用していたので、その品質レベルが私たちが望むゲームプレイのレベルを駆動できることを知っていました。
私たちが最初に始めた約3年前、ゲームオブジェクト用ネットコードは存在していましたが、特にクライアント側の予測に関して、私たちが望むいくつかの機能がまだ不足していました。クライアント側の予測を使用すると、サーバーとクライアントの間に遅延がある場合、クライアントはサーバーが何をするかを予測し、瞬時にそれを実行します。これにより、プレイヤーの操作が遅延があっても反応が良く感じられます。プレイヤーが移動したり何かをしたりしたことをサーバーが教えてくれるのを待つ必要はありません。すでにそれを行っています。それは、エンティティ用ネットコードが最初から持っていたものです。
プロトタイピングのために、私たちは基本的にすでに持っていたプロジェクトを取り上げて飛び込みました。私たちは簡単なことから始めました。物を拾ったり、木を切ったりして、徐々にゲームプレイの一部を具体化し始めました。私たちはまだプロトタイピング中だったので、コードの品質についてあまり心配していませんでした。私たちは楽しさを見つけようとしており、「誰にでもサバイバル」というゲームの柱を見ていました。私たちはサバイバルゲームを望んでいましたが、それが非常に難しいまたは厳しいものであってほしくありませんでした - このジャンルの本当に楽しくてエキサイティングな部分を抽出しようとしていました。
私たちは自問しました:人々はクラフトやリソース収集の何を愛しているのか?彼らは何に気にしないのか?それが、プレイヤーがリソースをどのように取得し、どのようにそれを一つの場所から別の場所に移動させ、どのようにクラフトを行うかを定義するのに役立ちました。私たちは、GameObjectsとMonoBehavioursを使用してプロトタイピングと反復を迅速に行うことでそれをすべて解決しました。
私たちはその小さな概念実証デモから始めたので、最初からインターネットアドレスで接続できました。コンピュータのIPを使用して接続することは可能でしたが、私たちはUnityのリレーサービスも使用しました。これは、クラウドのリレーサーバーでゲームをホストできるものです。リレーを使用すると、誰でも参加コードを使用してそのゲームに参加でき、VPNや既知のIPなしで自宅やオフィスから接続できます。それにより、週次のプレイテストのリズムに入ることができました - そして私たちは職場や自宅のネットワークでそれを行っており、さまざまな接続速度でゲームプレイとともにネットワークアーキテクチャをストレステストできました。最終的に、私たちはリレーを本番環境で維持しました。
私たちは公開されたパッケージにできるだけ近く保つよう努めました。パッケージの1つにバグを見つけた場合、それを特定し、パッケージをローカルに持ち帰り、修正しようとしました。時々、私たちはその後Slackに行き、UnityのNetcodeチームに問題と修正を説明するメッセージを送りました。彼らはそれを受け取り、PRを行い、時には最終版に組み込むことができました。私たちは必ずしも修正に関与していませんでしたが、本番環境で作業することで、彼らがまだ見つけていないいくつかの問題を発見しました(ただし、時には彼らが私たちが考えたよりも良い修正をすでに持っていたり、私たちが間違って使用していると言われたりしました)。

このようにリモートでリレーを通じて開発したため、リリースに近い後になってオフラインモードを追加しました。オフラインモードはネットワークソケットを開かず、プロセス内ドライバーと呼ばれるものを使用します。それは実質的にサーバーとクライアントを持つネットワークのように振る舞いますが、同じプロセス内で実行され、お互いに通信します。ネットワークを通じて送信するのではなく、クライアントに直接送信します。それはプロセス内接続と呼ばれ、実際のバイトがネットワークを横断するのを待つ必要がないため非常に速いですが、ゲームプレイと同じフローを通過します。
このように作業することで、異なるバージョンをコーディングする必要はありませんでした - これは私たちのシングルプレイヤーモードとマルチプレイヤーモードです。シングルプレイヤーとオフラインは依然としてネットワークゲームですが、ネットワークを使用しないだけです - すべて内部で発生します。
これは基本的に、私たちがどこでも使用できる1つのコードアーキテクチャを持っていることを意味しました。ただし、そのコストは、ホスティングまたはシングルプレイヤーのときに、サーバーとクライアントをシミュレートしているため、両方を同時に実行するパフォーマンスの課題を作成することです。専用サーバーを使用すると、サーバーはどこかのサーバーファームに移動する可能性があるため、必要なのはクライアントと呼ばれるもので、すべてを見栄え良くし、サーバーが通信しているものに応答します。しかし、シングルプレイヤーでは、シミュレーションしているため、ゲームは両方を行う必要があり、どこかの専用サーバーにただ座っていることはできません。
それは、サーバーとクライアントが同じゲーム、同じフレームに座り、良好な解像度で毎秒60フレームの目標を達成できるように最適化するという、私たちの最大のパフォーマンスの課題の1つになりました。その目標は私たちにとって非常に重要でした。
私たちのブログシリーズの他のインストールをチェックして、サバイバルキッズの制作を深く掘り下げてください:
- "サバイバルキッズ"からのグラフィックスとレンダリングのヒント
- "サバイバルキッズのレベルレイアウトと地形のワークフロー"
シリーズの第4回目で最終投稿にご期待ください。マルチプレイヤーの物語の第2部では、Nintendo Switch 2での分割画面プレイとGameShareを可能にするためにこのネットワークアーキテクチャをどのように開発したかを掘り下げます。
Unityで作成されたプロジェクトについて詳しく知るには、リソースページを訪れてください。
