Membangun dunia terbuka di browser, bagian 2: Fisika di Worker dan kekhawatiran akan latensi input
Oleh Oleg Sidorkin, CTO dan Co-Founder Cinevva
Baru di sini? Gunakan panduan seri. Panduan tersebut menjelaskan apa itu spike dan menautkan semua bagiannya.
Jika Anda cukup lama mengembangkan game multipemain di browser, pada akhirnya Anda akan menemui perdebatan ini.
"Fisika di worker menghasilkan arsitektur yang rapi. Fisika di thread utama terasa lebih aman."
Keduanya bisa benar. Yang penting adalah respons kontrol dan latensi saat menerima input nyata.
Spike 2 dibuat untuk menjawabnya dengan pengukuran, bukan opini.
Buka Spike 2 di tab baru ↗ · Lihat kode sumber
Kami menggunakan kembali medan dari Spike 1 dan mengintegrasikan Rapier ke dalam module worker khusus. Status input dikirim ke worker di setiap frame, simulasi dijalankan di sana, dan posisi otoritatif dikirim kembali ke renderer.
Metrik utamanya adalah latensi dari input hingga gerakan terlihat serta waktu langkah fisika. Kami juga mengamati jitter selama gerakan normal, lonjakan saat berlari cepat, dan ritme lompatan.
Hasilnya lebih baik dari perkiraan. Dengan bentuk dan frekuensi pesan yang kami gunakan, batas worker tidak menjadi faktor dominan dalam latensi. Kontrol tetap terasa langsung, dan hanya itulah yang akan dipedulikan pemain.
Salah satu tantangan pada fase ini adalah risiko salah menafsirkan hasil. Setelah mendapatkan hasil yang sukses, tim sering kali menggeneralisasi secara berlebihan dan menganggap pertanyaan tentang arsitektur telah tuntas selamanya. Padahal tidak. Kami hanya memvalidasi satu skenario konkret dan satu profil perangkat keras. Spike berikutnya tetap harus menguji ulang asumsi ketika beban GPU dan streaming berubah.
Spike ini juga meningkatkan proses kerja kami. Kami mulai menampilkan telemetri waktu di HUD secara default untuk spike interaktif. Hal itu mengubah percakapan tim dari "rasanya ada yang tidak beres" menjadi "alur ini menambah 1,2 ms."
Di bagian 3, kami membahas eksperimen yang kurang menarik tetapi mencegah kejutan mahal di kemudian hari: beban broadcast, keterbatasan perangkat seluler, dan keandalan pembuatan perilaku.
Teknologi yang dibahas dalam bab ini
Rapier. Mesin fisika yang ditulis dalam Rust dan dikompilasi menjadi WebAssembly untuk digunakan di browser. Rapier menangani rigid body, collider, joint, character controller, dan raycasting dengan performa 2–3 kali lipat dibandingkan implementasi native. Untuk dunia terbuka, Rapier menyediakan character controller pemain (berjalan di medan, menaiki anak tangga, meluncur di lereng), tabrakan objek, raycasting untuk interaksi, dan trigger volume. Lihat dokumentasi Rapier dan panduan teknologi 3D browser kami tentang fisika.
Web Workers. Thread browser yang menjalankan JavaScript (atau Wasm) di luar thread utama. Menjalankan simulasi fisika di worker berarti pemanggilan world.step() yang berat tidak memblokir rendering. Thread utama mengirimkan status input ke worker di setiap frame melalui postMessage dan menerima kembali posisi otoritatif. Penalti latensinya berasal dari dua perjalanan pesan tersebut (~0,1–0,5 ms per perjalanan di desktop). Manfaatnya adalah thread render tidak pernah terhenti akibat deteksi tabrakan. Transferable object (transfer ArrayBuffer) menghilangkan overhead penyalinan untuk array posisi berukuran besar.
WebAssembly (Wasm). Format instruksi biner yang berjalan di browser dengan kecepatan mendekati native. Rapier, Havok, dan Recast semuanya dapat dikompilasi menjadi Wasm. Langkah fisika di Rapier-Wasm biasanya memerlukan 0,5–2 ms untuk beberapa ratus body, dibandingkan 5–15 ms untuk implementasi JavaScript yang setara. Modul Wasm dimuat sebagai berkas .wasm yang diambil bersama kode perekat JavaScript. Lihat spesifikasi WebAssembly.
Latensi input-ke-visual. Waktu antara penekanan tombol dan perubahan visual yang dihasilkannya di layar. Agar gerakan terasa "langsung", latensi ini harus tetap di bawah ~80 ms. Dalam konfigurasi fisika berbasis worker, rantainya bersifat aditif:
event keydown (thread utama), postMessage ke worker dan kembali lagi (
Bagian 2 dari 12.
Sebelumnya: Bagian 1 - Kami memulai dengan mencoba merusaknya
Berikutnya: Bagian 3 - Spike yang tidak mencolok tetapi menyelamatkan kami
Panduan seri: /id/blog/2026-02-25-open-world-browser-series-guide