Skip to content

Membangun dunia terbuka di browser, bagian 4: Streaming sebelum membuat medan yang canggih

Oleh Oleg Sidorkin, CTO dan Co-Founder Cinevva

Baru mengikuti seri ini? Gunakan panduan seri. Panduan tersebut menjelaskan apa itu spike dan menautkan semua bagiannya.

Streaming adalah tahap ketika proyek yang "terlihat bagus" biasanya mulai berantakan.

Anda bisa menyembunyikan banyak hal dalam satu frame diam. Anda tidak bisa menyembunyikan sendatan selama 40 ms saat melintasi batas chunk.

Kami sengaja menguji streaming sebelum membangun representasi medan tingkat lanjut. Dengan begitu, kami mendapatkan sinyal yang jelas tentang perilaku pemuatan dan penghapusan.

Spike 6 memvalidasi pergantian lingkungan sekitar dengan konten chunk sederhana.

Buka Spike 6 di tab baru ↗ · Lihat kode sumber

Kemudian kami beralih ke jalur medan yang sebenarnya dalam Spike 11: streaming chunk ketinggian dengan decoding di sisi worker dan penyempurnaan progresif dari grid sampel 17 menjadi 33, lalu 65.

Buka Spike 11 di tab baru ↗ · Lihat kode sumber

Urutan pengerjaan ternyata lebih penting daripada yang kami perkirakan. Jika kami langsung memulai dengan chunk ketinggian terkompresi, penyebab setiap sendatan akan sulit dipastikan. Apakah masalah decoding, pengunggahan tekstur, atau pembaruan geometri? Spike 6 menghilangkan satu lapisan ketidakpastian sebelum Spike 11 menambahkan kompleksitas.

Pelajaran praktis dari bagian ini kami terapkan pada spike-spike berikutnya. Kemacetan saat pengunggahan harus diukur secara langsung, bukan disimpulkan dari FPS rata-rata. FPS rata-rata menyembunyikan lonjakan waktu frame, padahal lonjakan itulah yang benar-benar dirasakan pengguna.

Pada bagian 5, kita memasuki pembahasan biaya visual, ketika vegetasi, shader medan, dan bayangan berjenjang bersaing memperebutkan anggaran frame yang sama.

Teknologi yang dibahas dalam bagian ini

Streaming berbasis chunk. Dunia dibagi menjadi grid yang terdiri dari chunk independen (biasanya berukuran 64x64 meter). Saat pemain bergerak, chunk di sisi belakang dihapus sementara chunk di sisi depan dimuat melalui streaming. Beginilah cara kerja sistem sel Skyrim: grid sel 5x5 dimuat di sekitar pemain dan diganti seiring pergerakan mereka. Versi browser menambahkan latensi jaringan ke dalam perhitungan, sehingga pre-fetching prediktif berdasarkan kecepatan pemain menjadi sangat penting. Lihat panduan arsitektur streaming kami.

Penyempurnaan heightmap secara progresif. Kirim medan dalam resolusi rendah terlebih dahulu, lalu sempurnakan. Ukuran grid ini tidak dipilih secara sembarangan: setiap tingkat merupakan grid (2k+1)×(2k+1), sehingga 17=24+1, 33=25+1, dan 65=26+1. Nilai +1 mempertahankan satu sampel bersama pada setiap batas agar chunk yang bersebelahan tetap sejajar, dan setiap tahap kurang lebih melipatgandakan jumlah sampel sebanyak empat kali (n2 bertambah saat panjang sisi digandakan). Grid 17x17 (ukuran minimum untuk chunk 64 m dengan jarak 4 m) berukuran sekitar 200 byte setelah dikompresi dan dapat langsung merender permukaan yang terlihat. Setelah itu, stream penyempurnaan 33x33, kemudian resolusi penuh 65x65. Setiap tingkat menambahkan sampel tanpa mengganti data sebelumnya. Pendekatan ini dapat dipetakan langsung ke cincin LOD geometry clipmap, tempat medan jauh menggunakan data beresolusi rendah dan medan jarak dekat menggunakan resolusi penuh. Lihat pemuatan chunk progresif.

Pengodean delta dan kompresi. Data heightmap dapat dikompresi dengan baik karena sel-sel yang bersebelahan memiliki nilai serupa. Pengodean delta menyimpan selisih antara setiap sel dan nilai prediksinya (rata-rata sel tetangga), sehingga nilai-nilai terkumpul di sekitar nol. Jika digabungkan dengan zlib atau brotli, chunk 65x65 menyusut dari ukuran mentah 8,4 KB menjadi 1–2 KB setelah dikompresi. Dengan presisi yang dikurangi untuk chunk jauh (8-bit alih-alih 16-bit), ukurannya menjadi 0,5–1 KB. Lihat kompresi data medan.

Pre-fetching prediktif. Memuat chunk sebelum pemain tiba. Jarak antisipasi harus mencakup jarak yang ditempuh pemain selama pemuatan chunk, dprefetch=vtload, sehingga jarak tersebut meningkat sesuai kecepatan: pada kecepatan berjalan (5 km/jam), lakukan pre-fetch 2 chunk ke depan (128 m); pada kecepatan berlari (15 km/jam), lakukan pre-fetch 4 chunk. Cincin pemuatan bergeser mengikuti arah kecepatan. Antrean prioritas mengurutkan permintaan tertunda berdasarkan urgensi dan membatalkan permintaan chunk yang telah dijauhi pemain. Lihat pre-fetching prediktif.


Bagian 4 dari 12.
Sebelumnya: Bagian 3 - Spike sederhana yang menyelamatkan kami
Berikutnya: Bagian 5 - Menganggarkan hal-hal yang mempercantik tampilan
Panduan seri: /id/blog/2026-02-25-open-world-browser-series-guide