フォートナイトチームはじめに数ある提携企業からデバイスを厳選し、8月9日にSamsungデバイスでフォートナイトのAndroid版ベータがローンチを迎えました。その数日後には様々な携帯電話メーカーの中から、対象となる一部のAndroidデバイスを所有するユーザーへの招待状の送付を開始しました。このベータ版からは、パフォーマンス、セキュリティ、デバイスの互換性、フォートナイトインストーラーによるAndroidデバイスへのゲームの提供などに関して多くのことを学びました。この記事では、ローンチに伴う技術面に関する詳細や現在の取り組み、Android版の今後の見通しについて切り込んでいきます。統計データAndroid版のフォートナイトは非常に話題を呼び、ローンチからの21日間で2300万人以上がAndroid版ベータに参加し、1500万人以上がAPKをインストールしました。現在はまだ招待されたプレイヤーのみを対象としている段階ですが、招待制からの転換方法はiOS版ベータのものと似ています。クロスプレイ対応のゲームを全てのプラットフォームでリリースするというのは、ある種特別な困難を伴いました。モバイルデバイス向けにゲームをスケールダウンする場合、通常はそのプラットフォームのパフォーマンスに合わせてコンテンツあるいは仕様を簡略化します。ドローコールを減らすために、カメラに近いオブジェクトを削除することもあります。フォートナイトでは、Android版のプレイヤーがPC版やコンソール版のフレンドと同じマッチに存在することもあるため、ゲームプレイに影響を及ぼすあらゆる物にレンダリングを行う必要がありました。バトルロイヤル」のAndroid版の開発を進めてきました。リリースの実現に向けた作業の大部分はレンダリングパフォーマンス、安定性、メモリに充てられましたが、その一方でAndroidハードウェア、OSバージョン、ドライババージョンの数の膨大さと多様性が主なハードルとなりました。フォートナイトをAndroidへ移植するにあたり、各提携企業との連携は欠かせませんでした。なければ移植は実現不可能だったでしょう。フォートナイトをモバイル向けにプロファイルおよび最適化するため、Samsungと密に協力しました。世界各地に点在するEpicのオフィスにSamsungのエンジニアが派遣され、両社のエンジニアが協力して最適化やパフォーマンス分析を行ったほか、主にVulkanレンダラー向けに様々なコードを変更しました。専用の装置を搭載したテスト用端末やSamsung独自のツールにより、パフォーマンスやメモリのボトルネック、およびその対処方法を究明することができました。Samsungデバイスのユーザーに向けて、シームレスかつ安全なインストールプロセスを実現できるよう共に作業にあたりました。Googleからもエンジニアが派遣され、重要な最適化やメモリリークの特定を共に行ったほか、AndroidのOpenGL向けの適切なフレームペーシングの実装にもあたりました。Googleのエンジニアは非常に優秀で、素晴らしいAndroidエコシステムの開発および改善に熱意を持って取り組んでくれました。Technologies、Razer、HiSiliconなど多くの提携企業とも協力してフォートナイトのテストおよび最適化を行いました。フラグメンテーションAndroidエコシステムは複数のメーカーが製造する端末を基礎とします。それぞれの端末はシステム・オン・チップ(SOC)を基にデザインされ、CPUやGPUコアの設定も含まれています。GPU内蔵)があります。OSを搭載しており、ほとんどのメーカーはスケジューラや電源管理機能をカスタマイズしています。同じGPUのデバイスでもグラフィックドライバのバージョンが異なるのです。その結果、基盤となるハードウェアが同一でありながらパフォーマンス性能が全く異なり、それぞれに異なる不具合が発生するケースがあります。発売から2年までのデバイスに関しては、驚くことにAndroidの最新バージョンの使用率が予想よりも高くなっていました。7(Nougat)は8%弱、2015年以前にリリースされたバージョンは0.5%未満となっています。発売から2年以上のデバイスに関しては、これらの数字は大幅に低下しています。したデバイスについては、メーカーがカスタマイズしたアップデートをリリースする必要があり、そのためにはほとんどのケースにおいて、世界各地の様々な無線通信事業者との連携が不可欠となるでしょう。Engineでは階層的なデバイスプロファイルシステムを採用しています。システム開発にあたり、まず4段階のパフォーマンスプロファイル(低、中、高、エピック)を作成しました。これらのプロファイルはエンジン内のスケーラビリティ設定を調節し、異なるパフォーマンス性能を持つデバイス上でのゲームの起動を可能にします。「低」では視認距離が制限され、オプションのグラフィック機能を全て無効にしています。「エピック」では全ての機能が有効となり影や葉なども表示され、視認距離も最長となっています。これらは最新のデバイスが対象となっています。G72など)も搭載されています。これらはハードウェアの性能に最も適切なパフォーマンスプロファイルを選択すると共に、特定のハードウェアに必要な最適化またはトラブル回避を可能にします。XLなど)を対象とするプロファイルも存在します。これらにより、特定のデバイスでさらなる最適化やトラブル回避が必要となった場合に対処が可能となります。ゲームの起動時に、デバイスモデル、OSバージョン、グラフィックドライババージョンなどのプロパティを確認し、適用するデバイスプロファイルを決定します。レンダリングパフォーマンス適切なフレームレートを維持するうえで、レンダリングに伴うCPUコストは最大のパフォーマンスボトルネックとなっていました。そのため、AndroidのグラフィックドライバにはPCやiOSよりも多くの時間をCPUに費やして作業に取り組んでいます。S9のAdrenoバージョンなど)では、毎フレーム1500ドローコールを処理できますが、それ以前のデバイスでは処理数が大幅に低下します。中級デバイスで必要な処理数は平均で約600ドローコール、それ以下のデバイスでは平均400程度となります。今年の前半にiOSへ移植した際、フレームごとにレンダリングが必要なオブジェクトの数をすでに減らしていたため、別の選択肢を模索する必要がありました。ドローコールをまとめてインスタンス化する方法も試したところ一定の成果はあったものの、コードの複雑度に見合うものではありませんでした。OpenGLレンダラーへ様々な最適化を施したことにより複数の改善が見られましたが、驚くことに一番目立った改善点はメモリの最適化、即ちエミュレートされたユニフォームバッファでした。ES2にも使用されています。シェーダーをコンパイルする際、シェーダーに必要な定数を全て特定して配列し、それをシェーダーが読み取ります。ユニフォームバッファの定数をどこに集め、配列としてどこに配置するかをエンジンに伝えるマッピングテーブルも格納しています。起動中、ユニフォームバッファをCPUのアクセシブルメモリへ保管し、マッピングテーブルを使用してそれらを一時バッファへコピーし、単一のglUniform4fvファンクションコールで全ての定数をアップロードします。不思議なことに、エミュレートされたユニフォームバッファのコードパスによってドライバへの作業時間を大幅に節約することができました。ドライバ内部でも上記のような挙動が行われ、それによって作業がスムーズになったのでしょう。少ないリソースの作成およびバインディングを行っていたことから、ドライバでのバッファ管理の記帳時間が短縮された可能性もあります。いずれにせよ、上記の方法によって一部のケースではドライバコストが10~15%低下しました。VulkanVulkanはAndroid向けの最新型グラフィックAPIであり、パフォーマンスおよびハードウェアへのローレベルアクセス用に設計されています。2016年、Samsungと提携してProtoStarを公開し、AndroidのハイパフォーマンスグラフィックAPIの可能性を示しました。フォートナイトでは毎フレーム多数のオブジェクトが描画されるため、Vulkanは最適と思われましたが、そう簡単にはいきませんでした。現在のところ、AndroidにおいてVulkanの対応は必須ではないため、エコシステム全体でVulkanが使えるようになるのはまだ先のことでしょう。現在は致命的な不具合が発生しなかった最新のハードウェアのみに的を絞っているものの、初期のVulkanドライバでは複数の不具合およびパフォーマンストラブルを検知したため、ほとんどのデバイスにおいてVulkanよりもOpenGLのほうが高速かつ安定するという結論に至りました。これは決して想定外ではありません。OpenGLの最適化および改善には10年もの月日が費やされています。VulkanはOpenGLよりも複雑なAPIであるため、同程度の完成度へ到達するまでにはまだ時間がかかるでしょう。9(Adreno)はVulkanに対応しています。Samsungのエンジニアと協力したことで、UE4のVulkan対応へ向けた最適化を、OpenGLよりも平均20%速い作業速度で進めることができました。今後もハードウェアの提携企業と連携して他のデバイスへのVulkan対応化作業を進めていき、Android版のプレイヤーによりクオリティの高いゲーム体験を届けると共に、Vulkanドライバのパフォーマンス改善に努めていきます。メモリメモリは厄介な問題で、手を焼いています。コンソール向けのゲームを丸ごとモバイルに移植するだけでなく、フォートナイトには次々と新コンテンツも投入されるため、当然ながらメモリは圧迫されます。した事情から、メモリの最適化については息の長い取り組みを行っています。そこに立ちはだかるのが、他のプラットフォームにはない、Android独自の問題です。Androidには、これさえクリアすれば大丈夫という単一のメモリ予算がありません。積んでいるメモリの容量はデバイスごとに異なり、バックグラウンドで動いているアプリケーションの種類も違います。メモリを使いすぎたときにアプリケーションを終了させるタイミングの決め方も、おそらく同じではないでしょう。したメモリ予算を問い合わせるためのAPIは存在しません。1つのデータポイントとして、私たちはメモリテスト中にマッチに入り、OSによってプロセスが終了させられるまで、メモリの割り当てを行ってみました。強制終了する前に合計4GBのうち3GBのメモリを割り当てられました。2では、合計3.6GBのメモリのうち、割り当てられたのは1.8GBだけでした。グラフィックドライバは特にそうですが、システムは私たちに代わって大量のメモリを割り当てます。UE4にリクエストすると、全てのメモリをOSから直接追跡することができ、GPUのおよそのメモリ割り当ても調べられるのですが、ドライバがどこにメモリを割り当てているのか、そこまで具体的なことは分かりません。実際に実験をして確かめてみたところ、ドライバがフォートナイトに割り当てていたメモリは、大部分がシェーダーに使われていました。先ほど、エミュレートされたユニフォームバッファの最適化について触れましたが、これに力を入れたのはメモリに関する理由からです。OpenGLは、ユニフォームバッファのどの要素についても、アプリケーション側でロケーションのクエリができることを要求します。例を挙げると、OpenGLに対して、Primitiveユニフォームバッファ内にあるLocalToWorldのマトリクスに対するオフセットを求めることができます。これに対応するため、ドライバは一部のメタデータ(オフセットテーブルなど)をメモリに残す必要があります。これには各要素の名前のストリングが含まれるのですが、全てのプログラムについてこうした作業を行わなければなりません。フォートナイトでは幅広い種類のシェーダーを使っています。通常のプレイセッションをとっても、エンジンが使っているシェーダープログラムは約2000種類に上ります。ドライバは、こうしたシェーダープログラムそれぞれの内部でメタデータを蓄積しており、それが積み重なることで大量のメモリを消費していたようです。エミュレートされたユニフォームバッファを用いることで、400MB以上のメモリ節約に成功しました!Androidで最初にフォートナイトをリリースした当初、内部で行ったテストでは、対象デバイスのメモリ制限に収まるという結果が出ていました。Googleマップのナビゲーションをオンにして、音楽をストリーミングしながらテストしたのですが、問題なくフォートナイトで遊べることを確認できていました。ところが実際にローンチしてみると、メモリ不足でクラッシュしたり低パフォーマンスに悩まされるユーザーが続出してしまったのです。Android端末はメモリ不足の状態になると、使われていないアプリケーションを閉じてリソースを解放しようとします。世の中にはバックグラウンドでの挙動が思わしくないアプリケーションやサービスがたくさんあって、そういう類のものはOSが終了させても再起動してしまいます。Androidがメモリを確保するためにアプリを閉じても、閉じたはずのものが再起動して以前と同じ量のメモリを消費してしまうのです。悪いことに、アプリケーションの起動や終了という動作はCPU時間を消費します。したがって、メモリを解放するどころか、逆に不要なCPUリソースまで使ってしまうことになるのです。私たちはテストのプロセスを見直し、多くのユーザーが利用している一般的なアプリケーションをインストールして、それも起動しておくようにしました。すればこの手の問題をもっと早く見つけられます。いえ、メモリ使用量の削減が必要なことに変わりはなく、迅速にその目処をつける必要がありました。しながら、メモリが4GB以上ある新しいQualcommのSnapdragonデバイスにて、「高」か「エピック」の設定を使用しているユーザーに問題を絞り込めました。差が出る主な要因はシェーダーメモリのようでした。応急処置として影を無効にしたところ、ある程度問題を緩和できました。すると、変数がシャドウマップの参照やフィルタリングをしなくてよくなるので、必要なシェーダーの数が少なくなりました。シェーダー用にLRUキャッシュも用意し、このキャッシュにより現在のシーンのレンダリングに必要なシェーダープログラムだけをメモリに残せるようになります。他のシェーダープログラムは圧縮されてメモリに保存され、必要になれば解凍してドライバに戻す仕組みです。次のステップ私たちは現在、対応中の全デバイスでゲームを快適に動作させることを優先課題として位置付けており、十分なメモリを確保できるようになればビジュアル品質と安定性を両方とも改善できます。そのあとは、サウンドなどの互換性の問題に取り組んでいきます。5.40では多くのデバイスでサウンドの問題が修正されており、より多くのデバイスに対応するための道筋が整いました。設定を一段と充実させて、ユーザー側でより細かな調整ができるようにしたいとも考えています。クオリティとパフォーマンスのトレードオフも実施する予定です。Vulkanの対応も引き続き改善を行って、いずれは他のデバイスにも展開しようと考えています。今後もUE4とドライバの両方について、私たちはデバイスのメーカーと最適化の取り組みを続けていくということです。長い目で見れば、Vulkan対応とドライバの改善に向けた投資は、プレイヤーの皆さんにより良いパフォーマンスをお届けすることにつながります。Androidでリリースされる全てのUE4のゲームにも、パフォーマンス向上の恩恵が及ぶでしょう。古い端末や動作の遅い端末への取り組みも続けていきますが、過去にさかのぼり過ぎるのも現実的ではありません。最上位のモバイル端末は毎年、前の年と比べて動作が50%速くなっています。フォートナイトは、2年前の端末では許容範囲の速さで、1年前の端末なら十分な速さで、今年リリースされた端末では文句なしの速さで動きます。4.20でかなりの部分が実装されています。残りも次回4.21のリリース時に実装される見込みですし、今後行われる最適化についても、UE4のデベロッパーの皆様と引き続き共有していきます。マルウェアとの戦いフォートナイトのAndroid版リリースを正式に発表する以前から、「Android版フォートナイト」をうたう不正なウェブサイトが存在していました。この手のウェブサイトはマルウェアや詐欺の温床です。した動きが目に余るようになってきたこともあり、私たちはウェブサイトそのものや関連するホスティングプロバイダ、それを宣伝する広告や動画の根絶に乗り出しました。そのウェブサイトが実際にマルウェアを拡散させているかどうかにかかわらず、私たちはAndroid版フォートナイトの全ての配信を、その疑いがあるものを含めて、不正な行為とみなします。Games公式のフォートナイトインストーラーだけです。現時点までに、当社は「Android版フォートナイト」をうたう47の不正なウェブサイトを相手にアクションを起こしました。その多くは、よからぬことを企む同じ運営元が運営しているようです。私たちはこうした取り締まりを続けます。Epicが誇る不正対策のパートナー(インターネットサービスプロバイダ、ブラウザやアンチウイルスソフトの会社などが含まれます)とのネットワークを活用し、こうしたウェブサイトを閉鎖に追い込んだり、アクセスを制限していきます。ご参考までに、これらのパートナーは、次のようなブラウザ内アラートを出すことができます。私たちは内部に専任のチームを用意し、新たなマルウェアウェブサイトが現れたら即座に見つけられるよう、そのようなウェブサイトを積極的に探しています。加えて、IPと不正防止を専門とする外部機関を雇用し、取り締まりの取り組みを拡大しました。このパートナーシップにより、怪しげなURLで登録された新たなドメインを発見、監視することが可能になります。仮にこうしたウェブサイトが悪意あるウェブサイトに発展した場合、Epicは訴訟を含む適切な措置を取ることが可能です。まとめAndroid版フォートナイトは業界初の偉業を多数実現しました。コンソール/PC用ゲームのAndroid移植版として、初めて完全なクロスプレイと互換性に対応。Playストアを通さずにリリースされたゲームとして、初の大ヒット作となりました。取り組み自体も素晴らしいものでしたし、その過程で多くのことを学べました。短期間で1500万人を超えるAndroidユーザーを得られたという事実から、このアプローチが正しいものであり、大成功する可能性があることがうかがえます。Engineデベロッパーの皆様にお届けします。この取り組みによって誰もが恩恵を得ることができるのです。することはできません。