PLAYERUNKNOWN'S BATTLEGROUNDS NEWS

DEV.BLOG

【開発】サーバーパフォーマンス改善

2018.08.24

プレイヤーの皆さん、こんにちは。

 

何故サーバーのパフォーマンスが重要なのかは深く考えなくてもご存知かと思います。「PUBG」が使っているUnreal Engineはクライアントサーバーモデルに基づくため、すべてのクライアントに各Actorに対するステータス情報がサーバーを通じてアップデートされなければなりません。

※ここでのActorとは、Unreal Engineで使われる概念でキャラクター、建物、背景、プレイヤーの視点からマップを見るために使用されるカメラなどのゲームレベル内に配置されるオブジェクトを言います。

 

サーバーパフォーマンスは普通、サーバーのFPS(Frame Per Second 又は frame-rate, tick-rate)で測定することになります。サーバーのパフォーマンスが高くなると1フレーム毎にかかる時間が減少し、その時間が減るほどサーバーのレスポンスが高くなります。

 

サーバーレスポンスは「ネットワークディレイ」とも表現します。このレスポンスが高くなるほど(またはネットワークディレイが減るほど)軽くて快適なゲームプレイを提供できます。なぜならサーバーのレスポンスが早いほど“自分が行った行動が他の人の画面で反映されるまでにかかる時間”が減るからです。例えば、自分が発射した弾が他のプレイヤー達の画面により早く反映されるということです。プレイヤーの皆さんがよく語る瞬間的に切断される現象を減らすにはサーバーのレスポンスタイムを短くしなければなりません。

 

Update #14(5月31日(木)ライブサーバーアップデート)を通じた改善事項

 

Update #14 前、ネットワーク処理構造と示唆 

 

Update #14 前、本来のUnreal Engineは下記のような流れでネットワーク処理が行われます。

 

 

まず上記ネットワーク処理の流れを説明いたします。「Net Dispatch」段階ではクライアントで受信されたパケットがサーバーで処理されます。この段階では銃の発射、キャラクターの移動などが処理されます。この時処理された内容は効率、適合性によってRPC(Remote Procedure Calls)Replication、この2つの中、1つの形態で他のクライアントに流れます。その後、物理シミュレーションと同じサーバーにてゲームロジック処理が「Simulate & Render」段階で行われ、その処理の結果は「Net Flush」段階を通じてすべてのクライアントに転送されます。

 

上記構造では「Net Dispatch」段階で処理されたRPCがすぐに転送されず、Buffer待ちの状態となります。その後、「Net Flush」段階で現在Bufferに保存されている内容がすべてのクライアントに転送され、Bufferは空になります。

 

この構造のままだと「Net Dispatch」から「Net Flush」に到達する前「Simulate & Render」段階を経由してからRPCが転送されるため、それだけのディレイが発生します。Unreal Engineがこういった構造となっている理由はUDPに転送されるパケット数を最小化するためだと思われます。パケット数が最小化されるとネットワークをより効率よく活用できるからです。

 

変更されたネットワーク処理構造と改善

しかしパケット数を減らすことよりも、ディレイを減らしてレスポンスを高めることが「PUBG」では優先的だと判断してUpdate#14では下記のように構造を変更しました。「Simulate & Render」前に「Net Send Flush」という段階を追加しました。

 

 

Net Send Flush」段階ではBufferに保存されていたUDPデータがすべて転送され空になります。これを通じてディレイ時間が「Simulate & Render」にかかる時間ほど減少されます。「Net Send Flush」段階ではずっとqueueとして滞留していたデータが処理されます。

 

このような構造変更を通じて「Net Send Flush2」、「Net Flush」の合計2回のネットワークアップデートが転送されることでUpdate#14からNetwork Update Rateが2倍に増加しました。(これでサーバーのtick-rateが2倍になったと推測がありましたが、そうではなく、サーバーFrame処理の途中にNetwork Updateがもう一回転送されNetwork Update Rateが60tick-rateになりました。)

 

この結果はユーチューバーBattle(non)senseのUpdate#14関連映像でも確認することができます。

 

下記表を確認すると、40名のプレイヤーが生き残った時点でGunfire(発砲)の平均ディレイが94.5msecから77msecと18%減少されています。

 

 

Update #19(8月8日(水)ライブサーバーアップデート)を通じた改善事項 

 

Update #19 以前のプロファイリング結果、新しいアクセス方法

 

PC Update #19前の2018年6月25日、90名のプレイヤーが生き残った時点で測定したプロファイル情報はこうなります。

Function

Value

Total frame time

106.4 msec

Tick-rate

9.3

Net Dispatch

41.8 msec

Simulate & Render

18.9 msec

Net Flush

43.2 msec

 

 

Net Flush」段階でかかる時間が43.2msecで、全体frame時間の41%になることがわかります。この時間の大部分は各ActorをクライアントにReplicationさせるための「serialize」にかかる時間になります。

 

Serializeはネットワークを通じてActor達の状態をクライアントに転送できるようにデータをメモリへ順次使用する過程です。

上記プロファイリング結果を基に最適化方法について考え、こういった結論になりました。“ReplicationされるActor(特にCharacter)の数を減らせられれば、全体のNet Flush時間が大幅に減少する。”

 

「PUBG」はUnreal engineの「Dedicated Server」を使用する他のゲームより何倍も多い、最大100名のプレイヤーが一緒にプレイするため、Actorの数が当然多いです。Actorが持つデータ数が多いのも問題ですが、それよりActor自体の数が多いことの方が問題でした。そこで総Actor数を減らす方法を悩みましたが、遠くにいるキャラクター達を低い頻度でReplicationすればどうかという考えに至りました。

 

遠方にいるキャラクターたちに対する変化となるのでゲームプレイには影響なくserializeされるActor数は大幅に減少、結果的にNet Flushにかかる時間も減らせるはずです。

 

開発: Replication Interleaving システム

上記の考えからスタートしてたどり着いた結論は、クライアントとActorの距離によってReplicationリクエストを適切な頻度でスキップする形のシステムを作ることでした。それでこのシステムの名称を「Replication Interleaving」にしました。まず強制的にActorがReplicationされる区間を分離して、その中で遠くにいるキャラクター達のReplication頻度を下げた時にどういう問題が発生するか、視覚的にどういう変化が起きるのかを分析しました。その後Replication頻度を下げた時に発生する問題を解決して、従来のReplication頻度の4分の1レベルまで減らしてもゲームプレイに大きな影響はないという結論になりました。

 

完成されたReplication Interleavingシステムは下記のように実装されました。

・距離によって何フレームの間Replicationをスキップするか決定する。

・3段階まで設定でき、1段階は1 フレームをスキップして、2段階は2フレームをスキップ、3段階は3 フレームをスキップする。

 

このシステムを実装してから段階別の適切な距離値を探すためQAチームで関連テストを行いました。3 フレームをスキップした際にキャラクターの挙動に異常がみえる現象が起きたのでテスト後3段階は使わないようにしました。現在の段階別に適用された値は下記になります。

 

・1段階:70m以上の距離にいるキャラクターに対して1フレームスキップ

・2段階:400m以上の距離にいるキャラクターに対して2 フレームスキップ

(参考:上記内容は現在適用済みの内容で、今後サーバーパフォーマンスを改善したり動きをスムーズにしたりするために設定された値を変更する可能性があります。)

 

改善結果

このシステムを適用してからサーバーパフォーマンスが20%向上しました。下記データはNAサーバーで85名が生き残った時tick-rateを推定した結果です。このアップデートを通じて18.5だったサーバーtick-rateが22.9となり約22%向上しました。NAサーバーだけではなく他の地域でも平均20%以上のtick-rate向上が測定されました。

 

またレスポンスでも効果的な変化がありました。参考としてユーチューバーBattle(non)SenseのUpdate#19関連映像内の資料を引用します。

 

 

上記表を見ると、85名以上が生き残った時Gunfireの平均ディレイが149.4msecから61.6msecと58%減少されたことが確認できます。これはゲームの序盤で発生していた瞬間的なラグがかなり改善されたことを意味します。

 

Replication Interleavingだけではなく他の改善事項を通じて80名以上のプレイヤーが生き残った状態でサーバーtick-rateが20%上昇、Network Delayは50%減りました。

 

 

終わりに

「PUBG」がサービスをスタートしてから、何度かサーバーtick-rateを改善するための努力が行なわれました。ソフトウエア側の改善だけではなく、ハードウェアに対する改善も行ったことがあります。しかし、Update#19(8月8日(水)ライブサーバーアップデート)以前の何ヶ月間はプレイヤーの皆さんが体感できるとうな改善事項は多くなかったです。

 

今回FIX PUBG期間中、サーバーパフォーマンス改善作業の優先度をかなり上げました。このため色々なアイディアに対する研究やテストが行われています。

 

一つの機能を実装するためには事前に研究が必要で、実装後は多数の分析、検証などテストが必要です。こうやって一つの問題を改善するにも努力と時間がかなり必要となるため、短時間ですべての問題を解決することは難しいです。新しいことを実装しようとして間違ってしまったら大きな問題を起こす可能性もあります。そのためできるだけ安全に新しい機能を開発し適用しなければなりません。

 

上記の改善事項を適用後、現在は「Net Dispatch」段階の最適化を研究しています。分析の結果、大体の時間がキャラクターの移動処理に使われており、これらを最適化できる可能性を確認しました。キャラクターの移動が「PUBG」ではゲームプレイに大きな影響を与えます。この最適化作業のせいでキャラクターの移動に問題が起きないよう慎重に作業を行っていきたいと思います。

 

最適化のためいくつかのテストを行っており、テスト後このアイディアが適用された場合は現在41.8msecの「Net Dispatch」時間が50%以下になることを見込んでいます。この内容を適用して安定するまでは1か月以上の作業時間が予想されます。実装にむけて最善を尽くすように、そして完成させられるように努力致します。

 

我々の最大の目標はゲームスタートから終了までサーバーtick-rateが常に30を維持することです。この目標を果たして、より快適なバトルロイヤルを提供するため努力致します。

 

ご拝読いただきありがとうございました。

Head of Development, PUBG Amsterdam