こちらは、2018年4月17日に公開された以下のドキュメントを翻訳したものとなります。
Runbow: Online Multiplayer for PC, Xbox, PS4, WiiU, Switch & 3DS
Runbow by 13AM Gamesはローカル及びオンラインで最大9人まで同時に遊べる色彩鮮やかなプラットフォーム型アクションパーティーゲームです。現在、ニンテンドーWii U、Newニンテンドー3DS、PC用Steam、XBox Oneに対応しており、近日中にPS4とニンテンドースイッチへの対応版も公開予定です。
今からお話しするのは、13AがWii U用のオンラインマルチプレーヤー仕様を始めて実装したときの記録です。
9人のローカルプレイヤーから9人のオンラインプレイヤーへ
始めのころの課題は、9人のローカルマルチプレイヤーをオンラインでもプレイできるようにすることでした。シングルコンソールで1-4人程度のローカルプレイヤーをオンラインでプレイできるようにしたかったのです。これは2つの異なる配列が必要であるという結果にたどりつきました。配列の1つはローカルプレイヤー用で、コンソール内で接続しているコントローラーをトラッキングするためであり、もう一つは接続している全てのオンラインプレイヤーと同期させるためです。
プログラムの中には多くのインスタンスがありました。配列が入り組んでいたり、適切にアップデートされていないためにプレイヤーの数が間違ってしまう危険性がありました。QAの後の段階に入ってもまだ、ローカルのコントローラーがオンラインプレイヤーの動作に影響を与えるような、ローカルとオンラインのプレイヤーが入り混じるインスタンスがありました。
全体的に、変更しなければならないシステムがたくさんありました。どのローカルのコントローラーがオンラインメニューを操作できるのか、ということからstatsやアチーブメントを数える際にどのオンラインキャラクターをケアするべきなのかということまで多岐にわたりました。
ゲームへの参加
オフラインモードのゲームとは異なり、Runbowオンラインではゲームの最中に新規プレイヤーが参加することはできません。その理由は、プレイヤーの混乱を招く上に配列があまりにも複雑になってしまうからです。そこでサーバーに接続する前の段階でオンラインにするローカルプレイヤー数を選択するスクリーンを追加しました。これにより、参加時にAボタンが押される回数を数えなくても、配列が常にプレイする人数を把握するようになりました。
それでもなお、ゲームへの参加にはホストとゲスト間で発生する大量のRPCメッセージによるトラブルがつきものでした。プレイヤー数が少なければ問題はあまりありませんでしたが、プレイヤー数が増えるとメッセージ量も急増しました。例として、下記に挙げるのは新規プレイヤーの情報配信の手順です。
プレイヤーがゲストとして参加 ->ゲストが情報をホストに送信 ->ホストがセッション情報を更新、および送信 ->ゲストは情報が正しいか確認しホストに連絡 ->ホストは正しければ再度その情報を送信。
後半のステップはホストが接続を切り、完全な情報を持っていないプレイヤーが新しいホストになるようなケースで必要です。
何とかしてRPCの情報量を減らそうと、ステップ間に短いインターバルを設けることにしました。プレイヤーにとっては接続までの時間が長くなってしまいますが、ホストがすべての情報を確認するのに十分な時間がとれるようになりました。RPCが増えるのなら間隔も長くする、というのが衝突を避けデータロスを最小限まで減らす堅実な解決策です。これで、それぞれのWii Uを使って最大8人のプレイヤーが同時に参加するようなRunbow独特のケースにも対応できるようになりました。
キャラクター選択画面
プレイヤーが接続すると次にアクセスするキャラクター選択画面では、あまりに多くのメッセージが送られていました。ここではプレイヤーは使用するキャラクター、色、コスチュームを選択します。2人のプレイヤーが同じキャラクターを使用することを避けたかったので、あるキューを実装しました。それは、プレイヤーがLeftボタンかRightボタンを押すと、ホストに次の利用可能なオプションを確認するメッセージが送信され、ホストはリクエストをソートして一度に回答する、というものです。少しのタイムラグをもたらしましたが、許容範囲内でした。
このシステムでは、ホストは各プレイヤーがどのキャラクターやコスチュームを解除したか把握していることが求められます。この情報はコスチュームのリクエストと一緒に送信するには大きすぎるので、参加時のRPC送信に追加することにしました。送信情報を最小限にするため、ビット数ですべてのコスチュームやキャラクターが解除されたか認識できる3桁の整数に暗号化しました。
それにもかかわらず、送受信される情報はまだまだ大きすぎました。私たちが気づいたのは、シンプルな機能を一つ取り除くだけで情報量が大きく削減されるということです。それは、キャラクターを変更した後、どの色・コスチュームが選択されているかを記憶する機能でした。その設定をデフォルトに戻すだけで、情報量は改善されました。思ってもみなかったシステムが大きな負担になっていることがあるので、あらゆるシステムを洗い出してみることがとても重要です。
私たちが実装した最後のセキュリティ対策はオンラインルームをゲーム開始の5秒前にクローズすることです。通常、プレイヤーが参加すると、キャラクター選択のためタイマーが10秒間時間を追加しますが、最後の数秒にこれが発生すると、ホストがこの新しいプレイヤーの情報を更新する前に全員ゲームシーンに移行してしまうため、新しいプレイヤーは意図せずして観客になってしまっていました。
ネットワークシミュレーション
Runbowの開発サイクルの中でほとんどの間、オフィスに1~3台のWii U開発キットがありました。3台あれば、オンライン上ほとんどのケースを検証するのに十分でしたが、すべてを検証できるわけではありませんでした。そこで私たちはPCを使って開発キットを接続していたのですが、PCでのパフォーマンスがWii Uよりも優れていたので、この検証はWii U単独で接続したときの実際のパフォーマンスを完全な再現にはなりませんでした。
Photonのネットワークシミュレーションは、結果的に高レイテンシでやデータロスなど、より現実に近い環境でシミュレーションをするのに本当に便利でした。多くの場合、最悪のケースを想定し、システムをできる限り強固にするだけで済みました。
接続の中断
ネットワーキングにおいては、最も難しいことは標準的なものではなく、例外に対応することだと学んできました。プレイヤーをゲームに参加させるのが難しいわけではなく、8人のプレイヤーを同時にゲームに参加させることが難しいのです。おそらく、私たちが直面した中で最も難しかったのは予期しない切断でした。
改善したものの1つが、前述したホストの情報が正しいかゲストが確認し、間違いがあれば警告を出すというステップでした。ゲームプレイ中、各レベルの始めでこのステップを繰り返しますが、これがホストが最終レベルの途中で接続を中断したときにバグを引き起こす要因になっていました。新しいホストが時間内に気が付かず、ゲームがビルドの中で次のレベルをロードし続けると、最終的にオンラインでプレイされる予定ではなかったレベルまでいってしまいます。この解消に当たり、全てのゲームでレベル数をカウントし、高すぎる場合には接続を切ることにしました。一時的に新しいレベルのロード画面が表示されますが、すぐに消えます!
発売後
リリースした後でも、Runbowの開発、ネットワーキングの改良を続けました。発売後の大きな修正は、接続の悪いコンソールで生じる同期ズレを避けるため、レベル移行時間を長くしたことです。それによってゲームはわずかに遅くなりましたが、より信頼性の高いものになりました。数か月後には、Newニンテンドー3DS用の改修として移行時間はさらに長くなりました。
避けることはできたものの、根本的な改善ができなかったバグもありました。ゲームの終了後キャラクター選択画面に戻ると、なぜかネットワーク内の情報により余計なキャラクターが画面に表示され、ゆっくりと画面下部へと移動していくというものです。原因が全く分からなかったので、代替案として新しいゲームの開始時に短時間の接続のオンオフを入れることでこの問題を回避しました。
最後に、今回はしなかったものの次にRunbowと似たオンラインシステムをプログラミングする際には実施したいことについてお話します。それは、プレイヤーのキャラクターや色、コスチュームの選択を、ゲームに接続する前にすることです。これで技術的な問題のほとんどが解消されるだけでなく9人のプレイヤーが入り乱れる画面上で、誰がどのキャラクターなのかを認識しやすくなります。
全体的にみて、Runbowは刺激的な冒険でしたが、同時にとても大きくてやりがいのある案件でした。私たちは9人のチームでしたが、新卒とたった2人のネットワーキングの経験がほとんどないプログラマーで、ベースコードはゲームジャムの最中に書かれたゲームでした。幸いなことに、Unityを使うことでゲームをWii Uとポートし初めての9人体制のローカルゲームとすることができました。またPhotonの使用で手順が大幅に簡略化されました。たくさんの困難とは裏腹に、我々のプレイヤーベースはオンライン化を待ち望み、そしてその実現に感謝しています。私たちにとっても今後のプロジェクトに向けて勉強になりました。
Unai Cabezon
@basquegeek
13AM テクニカル・ナレーティブディレクター
コメント
0件のコメント
サインインしてコメントを残してください。