Peningkatan Performa: Global Invalidation VALORANT

Inilah cerita yang menjelaskan cara tim Performance VALORANT meningkatkan performa klienmu.

Halo! Aku Aaron Cheney, Software Engineer di tim Performance VALORANT. Performa adalah komponen utama dalam mempertahankan integritas kompetitif VALORANT, dan tim kamilah yang bertanggung jawab untuk memantau, merawat, serta meningkatkan performa server sekaligus klien.

Kami tak sabar untuk menggambarkan pembaruan pada fitur yang telah dikembangkan selama beberapa bulan: Global Invalidation. Kami akan membahas detailnya segera, tetapi pertama-tama, mari kita perhatikan seperti apa dampak fitur ini pada performa klien sejak Patch 4.03.

Peringatan spoiler: dampaknya lumayan keren.

global-invalidation-live-data_ID.jpg

Global Invalidation telah memberi peningkatan yang signifikan untuk sebagian besar pemain. Bahkan, inilah peningkatan performa terbesar pada klien sejak peluncurannya.

Meski diagram-diagram ini kelihatan menarik—kami senang akan hasilnya—penting untuk memahami arti diagram tersebut. Kami bekerja dengan set data yang besar dan kompleks; mengorganisasi, memfilter, dan mengontrol data yang membantu kami memahami pengalaman pemain. Inilah yang perlu diingat untuk memahami gambaran besarnya:

  • Diagram tersebut menerangkan “patch” vs. “FPS rata-rata”; makin tinggi angkanya, makin bagus.
  • Tiap garis mewakili konfigurasi perangkat keras umum (pasangan CPU+GPU) dari para pemain. Saat menganalisis data performa, kami menganggap pasangan ini sebagai penanda terpenting untuk performa yang diharapkan. Mesin dengan pasangan CPU+GPU yang sama digabungkan dalam diagram-diagram ini.
  • Sampel datanya diambil dari dua antrean: Unrated dan Competitive. Karena keduanya merupakan mode game paling populer di VALORANT, kami sangat berusaha untuk memahami dan menyempurnakan performa di area tersebut.
  • Kami mengecualikan game yang tidak memiliki persis 10 pemain. Ini memastikan datanya tidak berantakan (game dengan jumlah pemain yang lebih sedikit performanya lebih baik).

RANGKUMAN GLOBAL INVALIDATION

global-invalidation-summary-flow_ID.jpg

Global Invalidation menghasilkan peningkatan hingga 15% untuk klien CPU-bound (umumnya komputer spek menengah hingga tinggi). Peningkatan ini terwujud atas upaya dari berbagai tim dan diselesaikan dalam waktu berbulan-bulan. Proses kami dalam mengenali area game yang siap dioptimalkan membuahkan hasil, dan pengelolaan risiko di sepanjang jalan membantu memastikan pengalaman yang stabil bagi para pemain.

Mereka yang Mendapat Manfaat dan Mengukur Ekspektasi

Berdasarkan metrik live kami, Global Invalidation telah menghasilkan peningkatan hingga 15% untuk konfigurasi klien yang CPU-bound (umumnya komputer spek menengah hingga tinggi).

Meski tren menaik kentara dalam agregatnya, ini tidak mewakili gameplay dari momen ke momen. Selain itu, hal ini tidak menjamin bahwa tiap komputer dengan perangkat keras yang sama akan mendapatkan hasil yang sama.

Ini artinya performa dasar untuk VALORANT pada komputer CPU-bound secara umum telah meningkat, tetapi bagaimana tepatnya performa komputer tertentu milikmu akan tergantung pada sejumlah faktor yang bersifat unik.

MEMAHAMI GLOBAL INVALIDATION

Sebelum bisa menjelaskan sekilas dengan tepat tentang Global Invalidation, terlebih dahulu kami perlu menjelaskan sedikit tentang elemen UI di Unreal Engine.

Widget dan Struktur Pohon

Elemen UI (yang juga dikenal sebagai Widget) dibuat dari balok susun yang lebih kecil menggunakan struktur pohon. Struktur pohon adalah analogi dari sistem file yang ada pada komputermu. Sebuah Widget dapat memiliki "child" dalam jumlah berapa pun (seperti folder yang bisa menampung file dalam jumlah berapa pun).

Balok susun ini dapat dikombinasikan untuk membuat Widget yang kompleks. Penghitung amunisi, misalnya, terdiri atas berbagai bagian, dan pohonnya akan terlihat seperti ini:

valorant-ui-example_ID.jpg

Ketika disatukan semuanya, balok susun penghitung amunisi akan terlihat seperti ini:

valorant-ui-elements_ID.jpg

(Garis luar berwarna merah di atas ditonjolkan demi kejelasan. Pada praktiknya, banyak di antara garis luar tersebut yang tumpang tindih.)

Ketika satu Widget atau lebih berubah dalam struktur pohon tersebut, beberapa Widget lain bisa terpengaruh. Misalnya, jika sebuah Widget dipindah ke posisi baru pada layar, semua Widget di bawahnya juga perlu memperhitungkan ulang posisinya. Perubahan ini dikelola oleh suatu sistem yang disebut “Invalidation”, yang akan dibahas di bagian selanjutnya.

Invalidation

Invalidation adalah mekanisme yang digunakan Unreal Engine untuk mengindikasikan ketika Widget tertentu telah berubah dan perlu diperbarui.

Widget perlu divalidasi untuk beragam sebab: animasi, warna, opasitas, ukuran, urutan, teks, gambar, dan properti lain yang bisa berubah karena sesuatu terjadi di dalam game. Ketika perubahan ini terjadi pada sebuah Widget, ia menjadi “Invalidated”, yang menandakan bahwa Widget perlu diperbarui.

Proses ini bisa menjadi agak rumit lagi karena Widget bisa memiliki beberapa jenis invalidasi. Beberapa jenis invalidasi ini termasuk:

  • Layout - Ketika ukuran Widget berubah (sangat berat).
  • Paint - Ketika tampilan Widget telah berubah, tetapi ukurannya tidak.
  • Child Order - Ketika urutan Widget telah berubah di dalam pohon (yang juga berarti perubahan Layout, dan oleh karenanya juga berat).
  • Visibility - Ketika visibilitas Widget telah berubah, entah menjadi tak terlihat atau terlihat (yang juga berarti perubahan Layout, dan oleh karenanya juga berat).

Jenis invalidasi ini digunakan untuk menandai jenis operasi apa yang harus dijalankan untuk menggambarnya dengan benar.

Ini lebih rumit lagi ketika sebuah Widget bergantung pada Widget lain. Widget diatur ke dalam tingkatan-tingkatan, dan tata letaknya tergantung pada sejumlah faktor. Melakukan invalidasi pada satu Widget mungkin mengharuskan invalidasi pada sejumlah Widget terkait agar bisa digambar dengan benar. Misalnya, jika beberapa Widget diatur ke layout vertikal (misalnya, Panel Sosial berisi daftar temanmu), lalu urutan Widget berubah (misalnya, seorang temanmu online), semua Widget dalam layout vertikal tersebut harus diperbarui.

Sistem seperti ini memiliki beberapa tujuan:

  • Invalidasi sesedikit mungkin Widget. Ini mengurangi jumlah Widget yang harus diperbarui agar digambar dengan benar.
  • Hanya invalidasi Widget ketika diperlukan. Invalidasi Widget dengan tidak tepat membuang-buang siklus CPU yang berharga.
  • Saat Widget tidak diinvalidasi, simpan hasilnya untuk menggambar cepat pada tiap frame. Jika tidak ada yang berubah, siklus CPU bisa disimpan.

Itulah sekilas di balik layar untuk memahami bagaimana Widget diperbarui dan apa saja yang dapat menyebabkan invalidasi. Selanjutnya, kita akan melihat cara para pengembang menjalankannya.

Invalidation Boxes

Unreal Engine menyediakan komponen—yang disebut Invalidation Box—untuk mengelompokkan beberapa Widget. Semua Widget yang dimuat dalam satu Invalidation Box dicegah agar tidak dilewatkan, dicentang, atau di-paint. Sebaliknya, hasilnya disimpan dalam vertex buffer.

Tiap salah satu Widget dalam Invalidation Box diinvalidasi, data yang di-cache akan diabaikan dan Widget akan diperbarui serta di-paint lagi. Menyegarkan cache mungkin berat untuk satu frame, tetapi hasil yang diamortisasi jauh lebih baik dalam jangka panjang.

Invalidation Box merupakan bagian penting dalam menunjang performa UI VALORANT, terutama saat kami mendekati peluncuran. Namun, hal ini tidak sepenuhnya tanpa pengorbanan:

  • Para pengembang harus memahami Widget mana yang merupakan kandidat bagus untuk dikelompokkan dalam sebuah Invalidation Box. Widget apa pun yang diperbarui secara reguler tidak cocok untuk hal ini.
  • Penempatan Widget dalam sebuah Invalidation Box membutuhkan kerja manual dari seorang pengembang. Hal ini tidak mungkin dilakukan untuk tiap Widget di dalam game, dan oleh karenanya, para pengembang harus memahami Widget mana yang layak ditempatkan dalam Invalidation Box.

Untuk informasi lebih lanjut tentang Invalidation Box, baca dokumentasi Epic.

Nah, sudah ada cukup konteks untuk membahas Global Invalidation!

Global Invalidation Telah Hadir

Di titik ini, kamu mungkin berpikir, “Kenapa tidak masukkan saja tiap elemen UI ke dalam Invalidation Box yang global?” Yah, sebenarnya itulah Global Invalidation (kurang lebih).

Global Invalidation bertujuan untuk secara signifikan meningkatkan performa UI di keseluruhan game sembari mengurangi kerja manual yang dibutuhkan dari para pengembang untuk menempatkan Widget di dalam Invalidation Box masing-masing. Inilah yang paling baik di antara yang terbaik.

Namun, hingga UE4.25 (versi Unreal Engine yang digunakan VALORANT), Global Invalidation tidak secara universal didukung di semua jenis Widget. Versi yang lebih baru dari Unreal Engine telah diperbaiki, tetapi VALORANT tidak bisa langsung memanfaatkannya. Selain itu, kami tidak tahu betul seberapa cepat VALORANT berkembang karena Global Invalidation.

Di sinilah awal kerja kami.

MENGAPA KAMI MEMUTUSKAN UNTUK MELAKUKANNYA?

Pada akhir Juli 2021, tim kami memutuskan untuk melakukan testrun dengan Global Invalidation selama uji permainan internal. Perubahan minor dilakukan untuk memperbaiki beberapa bug agar uji permainan bisa berhasil selesai. Namun, kami tahu bug akan bermunculan selama uji permainan, dan itu memang ditemukan.

Di akhir uji permainan, ada sekitar 20 bug—dan itu baru yang kelihatan jelas. Ada bug yang lebih tak kentara dan berbahaya yang menunggu ditemukan, belum termasuk beberapa bug pencilan yang belum secara spesifik diuji.

Namun, apakah Global Invalidation memang memberi peningkatan performa? Tentu saja.

Berdasarkan analisis terhadap data yang dihasilkan dari satu uji permainan, ditemukan bahwa UI lebih cepat ~35%. (Catatan: UI hanyalah sebagian objek dari satu frame.)

Namun, kami masih punya banyak pertanyaan:

  • Berapa lama waktu yang dibutuhkan untuk memperbaiki semua bug?
  • Tim apa saja yang bertanggung jawab atas tugas tersebut?
  • Apakah hal ini lebih diprioritaskan daripada tugas yang sudah direncanakan lainnya? Untuk memenuhi rilis konten reguler, jadwal kami sering diatur berbulan-bulan sebelumnya, dan tugas baru–bahkan tugas yang seseru ini–sulit untuk disisipkan ke dalam jadwal tersebut.
  • Apakah perbaikan bug mengalihkan perhatian dari peningkatan performa? Perbaikan untuk semua bug akan memerlukan banyak perubahan kode, yang masing-masing berpotensi menyebabkan UI menjadi makin berat.
  • Kapan kami harus mengerjakan tugas ini? Dengan mengetahui bahwa Global Invalidation secara aktif sedang dikembangkan di versi-versi baru Unreal Engine, kami perlu mempertimbangkan timeline untuk mengintegrasikan perubahan dari Epic.

Pada akhirnya, kami memutuskan bahwa tugas tersebut layak karena beberapa alasan.

Integrasi Unreal Engine dan Pertimbangan Waktu

Meskipun Unreal Engine 4.26 dan 4.27 telah membuat kemajuan signifikan pada Global Invalidation, VALORANT dijalankan pada jadwal integrasi yang ditunda. Alasan kami tidak menggunakan “bleeding edge” ialah untuk mengelola risiko dan memastikan stabilitas untuk para pemain.

Karena menurut jadwal kami akan tetap menggunakan Unreal Engine 4.25 selama beberapa bulan mendatang, ini artinya para pemain tidak akan bisa memanfaatkan peningkatan performa ini hingga lebih dari satu tahun. Kami tak menyukai hal ini.

Untuk detail selengkapnya tentang opini VALORANT terhadap peningkatan Unreal Engine, kunjungi utas Twitter ini dari Tech Lead di VALORANT, Marcus Reid.

Peningkatan Performa yang Diketahui

Global Invalidation mewakili sesuatu yang unik dalam hal kerja performa: nilai terukur. Kami mengukur potensi kenaikan selama uji permainan internal, dan jalur untuk menghasilkan nilai tersebut (sebagian besar) jelas.

Kerja performa itu sulit. Ini permainan dalam ukuran inci, bukan mil; perubahan bertahap secara umum membantu untuk meningkatkan performa seiring berjalannya waktu, dan jarang ditemukan satu perubahan yang mampu menghasilkan kenaikan dalam dua digit. Optimasi ini terlalu bagus untuk dibiarkan begitu saja.

Bahkan setelah memperhitungkan penurunan kenaikan karena perbaikan bug, Global Invalidation adalah peluang terbaik bagi kami untuk menghasilkan kenaikan yang signifikan untuk para pemain dalam kurun waktu yang wajar.

BAGAIMANA CARA KAMI MENYELESAIKAN KERJA INI?

Meski eksperimen awal pada Global Invalidation dimulai akhir Juli 2021, upaya yang sesungguhnya pada stabilisasi fitur baru dimulai akhir September 2021.

Integrasi Selektif untuk Perubahan Epic

Integrasi penuh Unreal Engine 4.26 dan 4.27 tidak tersedia, tetapi karena Epic telah secara aktif mengerjakan Global Invalidation, kami memutuskan untuk menggali di antara ribuan perubahan dan mengidentifikasi perubahan mana yang mungkin akan membawa kami makin dekat dengan Global Invalidation yang stabil dan sepenuhnya berfungsi.

Integrasi perubahan secara parsial adalah tugas yang menantang. Penting untuk memodifikasi fitur mesin inti sesedikit mungkin untuk mempertahankan stabilitas sambil menarik ke perubahan yang tepat dari Epic. Semua kerja ini dilakukan dalam cabang yang terpisah dari cabang VALORANT utama untuk mencegah dampak ke pengembang lain.

Setelah secara selektif mengintegrasikan perubahan Epic ke mesin kami, beberapa minggu dihabiskan untuk memperbaiki bug sebanyak mungkin sambil mempersiapkan integrasi Global Invalidation ke dalam cabang VALORANT utama. Suatu waktu, sebuah toggle dibuat agar kami bisa cepat mengaktifkan dan menonaktifkan fitur tersebut (andaikan sesuatu yang buruk terjadi).

Dengan banyak bug yang sudah diperbaiki, dan dengan berbagai perubahan Epic dari 4.26 dan 4.27, kami menggabungkan cabang terisolasi tersebut kembali ke cabang utama.

Menemukan Kesamaan di Antara Bug

Meskipun banyak bug dengan Global Invalidation bermunculan dalam berbagai cara, akar masalahnya sering bisa dilacak kembali ke satu masalah. Inilah bug yang paling penting untuk diperbaiki. Dengan melakukan hal tersebut, berbagai masalah bisa dihilangkan dengan satu perubahan saja. Satu perubahan, misalnya, memperbaiki 10+ bug yang tersebar di dalam game. Analisis yang cermat terhadap akar masalah mengarahkan ke solusi tangguh yang meningkatkan keterandalan dan kestabilan Global Invalidation.

Identifikasi Bug, Perbaiki Bug, Lakukan Uji Permainan, dan Terus Ulangi

Beberapa minggu dan bulan berikutnya berisi siklus reguler pengaktifan Global Invalidation sebelum uji permainan, mengidentifikasi serangkaian bug, penonaktifan Global Invalidation setelah uji permainan, dan memperbaiki bug-bug tersebut.

developer-bug-fix-flow_ID.jpg

Di tiap iterasi, makin sedikit bug yang dilaporkan. Kami terus melakukannya hingga aliran stabil bug di awal berubah mengecil, dan pada akhirnya akan berhenti.

Di akhir November 2021, semua masalah utama diatasi dan Global Invalidation secara umum stabil.

Bug yang Terlihat
  • Astra membuat game-nya crash - Pada suatu titik, tiap pemain Astra mengalami crash saat memasuki game. Bug ini diperbaiki setelah integrasi perubahan dari Epic.
  • Beberapa inheritance crash - Beberapa inheritance dalam C++ adalah subjek yang rumit. Tanpa terlalu membahas detail, singkatnya, urutan destructor dalam class tertentu tidak tereksekusi dengan benar sehingga menyebabkan crash. Cukup dengan menukar 2 baris kode untuk mengubah urutan inheritance, masalahnya teratasi. Untuk membaca lebih lanjut tentang multiple inheritance, lihat halaman ini.
  • Audio chat yang berulang - Saat berada di menu, bar chat memutar suara saat kamu mengarahkan kursor di atasnya. Sebuah bug menyebabkan audionya diputar beberapa kali dalam satu detik, yang membuat jengkel semua orang. Perbaikan terhadap bug ini melibatkan pemahaman atas pengaturan waktu aktivitas mouse yang diterima Widget beberapa kali dalam sebuah frame.

    Metodologi Uji Coba

    Salah satu elemen Global Invalidation yang membuat kami sangat berhati-hati (dan cermat dengan uji coba) ialah Global Invalidation memengaruhi semua aspek game. Sungguh.

    Daftar temanmu? Tentu saja. Tombol yang kamu tekan untuk masuk antrean? Itu juga. Menu pengaturan? Jelas. Persentase headshot? Yah ...

    Poinnya, elemen UI ada di sepanjang game, dan itu sering membawa informasi penting untuk para pemain. Mengacaukan bahkan satu elemen UI tersebut tidak bisa diterima.

    Dengan tujuan ini, departemen QA kami membuat rencana uji coba dengan beberapa strategi untuk membangun keyakinan bahwa Global Invalidation berfungsi sesuai harapan.

    Uji Coba Vertical Slice

    “Vertical slice” VALORANT mewakili jalur utama yang umumnya diambil para pemain, mulai dari peluncuran klien, mengantre pertandingan, bermain satu game penuh, hingga interaksi dengan layar di akhir game. Dengan berfokus pada elemen penting pada game, QA bisa secara cepat menguji elemen game yang paling sering digunakan dan mengindentifikasi masalah sejak dini.

    Uji Coba Destruktif

    Saat uji coba vertical slice berakhir, uji coba destruktif dimulai. Jenis uji coba ini dimaksudkan untuk mengidentifikasi masalah off-nominal, sering kali dengan memodifikasi faktor eksternal (seperti ping jaringan, frame rate, alt-tabbing, dll.). Dibekali dengan seperangkat alat internal, QA menghabiskan beberapa minggu untuk melakukan uji coba destruktif.

    Uji Coba Edge Case

    Banyak bagian dari VALORANT yang hanya dialami oleh persentase kecil pemain. Beberapa bagian game hanya pernah dirasakan satu kali (misalnya, Pengalaman Pemain Baru). Bagian-bagian game tersebut memang jarang dilintasi, tetapi ini tidak membuatnya tak penting. Mengidentifikasi dan menguji semua edge case dapat membantu menemukan kesalahan-kesalahan yang tersembunyi.

    Uji Coba PBE (Public Beta Environment)

    PBE adalah capaian besar untuk Global Invalidation.

    • Ini untuk pertama kalinya pemain luar bisa mengetes fitur tersebut. Artinya, Global Invalidation bisa diuji dalam kondisi “real world” atau nyata.
    • PBE mewakili beragam spesifikasi perangkat keras. PBE dengan sengaja mencakup rentang spek mulai dari yang rendah hingga tinggi, dan pengujian bersama pemain dengan rentang yang luas seperti ini membantu kami membangun kepercayaan diri dalam seberapa baik performa Global Invalidation di sepanjang basis pemain yang lebih besar.

    Setelah pengujian PBE selama akhir pekan, tanggal 22–23 Januari 2022, kami yakin bahwa Global Invalidation tidak mengganggu integritas dan kenaikan performanya sejalan dengan prediksi kami.

    Peluncuran Global Invalidation

    Setelah meluncurkan Global Invalidation dengan Patch 4.03, kami memantau secara teliti laporan para pemain atas bug. Data performa juga diawasi ketat demi mengonfirmasi bahwa estimasi kami sesuai dengan hasil. Pada akhirnya, Global Invalidation merupakan keberhasilan besar bagi para pemain, dan kami harap kamu menyukai peningkatan frame time-nya.

    Kini dengan hadirnya Global Invalidation di luar sana, tim Performance akan kembali bekerja demi lebih banyak peningkatan. Sampai jumpa lain waktu, dan selamat berburu kill!