Skip to content

Tarayıcıda açık dünya inşa etmek, bölüm 2: Worker üzerinde fizik ve giriş gecikmesi korkusu

Cinevva CTO'su ve Kurucu Ortağı Oleg Sidorkin tarafından

Burada yeni misiniz? Seri rehberine göz atın. Rehber, spike'ın ne olduğunu açıklıyor ve tüm bölümlere bağlantılar sunuyor.

Yeterince uzun süre tarayıcı tabanlı çok oyunculu oyun geliştirirseniz, eninde sonunda şu tartışmayla karşılaşırsınız.

"Fiziği bir worker'da çalıştırmak temiz bir mimaridir. Fiziği ana iş parçacığında çalıştırmak daha güvenli hissettirir."

İkisi de doğru olabilir. Önemli olan, gerçek girdiler altında kontrollerin nasıl hissettirdiği ve gecikmedir.

Spike 2, bu soruyu görüşlerle değil, ölçümlerle yanıtlamak için geliştirildi.

Spike 2'yi yeni bir sekmede açın ↗ · Kaynak kodunu görüntüleyin

Spike 1'deki araziyi yeniden kullandık ve Rapier'ı özel bir modül worker'ına entegre ettik. Girdi durumu her karede worker'a gönderildi, simülasyon orada ilerletildi ve yetkili konum verisi render sistemine geri iletildi.

Temel metriklerimiz, girdiden görünür harekete kadar geçen gecikme ile fizik adımının süresiydi. Ayrıca normal hareket, kısa süreli deparlar ve art arda zıplamalar sırasında oluşabilecek titreşimleri de izledik.

Sonuç beklediğimizden daha iyiydi. Kullandığımız mesaj yapısı ve gönderim sıklığıyla worker sınırı, gecikmenin baskın kaynağı olmadı. Kontroller hâlâ anında tepki veriyormuş gibi hissettirdi; oyuncuların önemseyeceği tek şey de buydu.

Bu aşamadaki zorluklardan biri, sonuçları yanlış yorumlama riskiydi. Başarılı bir sonucun ardından ekipler genellikle aşırı genelleme yapar ve mimari sorunun sonsuza dek çözüldüğünü varsayar. Oysa çözülmüş değildi. Yalnızca belirli bir senaryoyu ve donanım profilini doğrulamıştık. Daha sonraki spike'larda GPU ve veri akışı baskısı değiştiğinde varsayımlarımızı yeniden sınamamız gerekecekti.

Bu spike, geliştirme sürecimizi de iyileştirdi. Etkileşimli spike'larda zamanlama telemetrisini varsayılan olarak HUD üzerinde göstermeye başladık. Böylece ekip içindeki konuşmalar "bir tuhaflık var"dan "bu işlem yolu 1,2 ms ekledi"ye dönüştü.

  1. bölümde, ileride pahalı sürprizlerle karşılaşmamızı önleyen daha az gösterişli deneyleri ele alıyoruz: yayın yükü, mobil kısıtlamalar ve davranış üretiminin güvenilirliği.

Bu bölümde değinilen teknolojiler

Rapier. Rust ile yazılmış ve tarayıcıda kullanılmak üzere WebAssembly'ye derlenen bir fizik motorudur. Katı cisimleri, çarpışma şekillerini, eklemleri, karakter kontrolcülerini ve ışın izlemeyi yerel performansın 2-3 katına varan hızlarda işler. Rapier, açık dünyalar için oyuncu karakter kontrolcüleri (arazide yürüme, basamak çıkma ve eğimlerde kayma), nesne çarpışmaları, etkileşimler için ışın izleme ve tetikleyici hacimler sağlar. Rapier belgelerine ve fizik hakkındaki tarayıcı 3D teknoloji rehberimize bakın.

Web Workers. JavaScript'i (veya Wasm'ı) ana iş parçacığının dışında çalıştıran tarayıcı iş parçacıklarıdır. Fizik simülasyonunu bir worker'da çalıştırmak, ağır bir world.step() çağrısının render işlemini engellememesi anlamına gelir. Ana iş parçacığı, girdi durumunu her karede postMessage aracılığıyla worker'a gönderir ve yetkili konumları geri alır. Gecikme maliyeti, iki mesaj geçişidir (masaüstünde her biri yaklaşık 0,1-0,5 ms). Avantajı ise render iş parçacığının çarpışma algılama nedeniyle hiçbir zaman duraklamamasıdır. Aktarılabilir nesneler (ArrayBuffer aktarımı), büyük konum dizilerindeki kopyalama yükünü ortadan kaldırır.

WebAssembly (Wasm). Tarayıcılarda yerel uygulamalara yakın hızda çalışan ikili bir komut biçimidir. Rapier, Havok ve Recast'in tümü Wasm'a derlenebilir. Rapier-Wasm'daki fizik adımı, birkaç yüz cisim için genellikle 0,5-2 ms sürerken eşdeğer JavaScript uygulamasında bu süre 5-15 ms'dir. Wasm modülleri, JavaScript bağlayıcı koduyla birlikte getirilen .wasm dosyaları olarak yüklenir. WebAssembly spesifikasyonuna bakın.

Girdiden görüntüye gecikme. Bir tuşa basılması ile bunun sonucunda ekranda oluşan görsel değişiklik arasındaki süredir. Hareketin "anında" gerçekleşiyormuş gibi hissedilmesi için bu sürenin yaklaşık 80 ms'nin altında kalması gerekir. Worker üzerinde çalışan bir fizik düzeninde zincirdeki süreler birbirine eklenir:

L=tinput+2tmsg+tstep+trender+tvsync

keydown olayı (ana iş parçacığı), worker'a ve ardından geri gönderilen postMessage (2tmsg), fizik adımı, render sisteminin yeni konumu uygulaması ve son olarak bir sonraki vsync. Her bir terim tek başına küçüktür (masaüstünde her mesaj geçişi yaklaşık 0,1-0,5 ms), ancak süreler üst üste eklenir. Bu nedenle mimari şemasına güvenmek yerine L değerini doğrudan ölçtük.


12 bölümden 2.'si.
Önceki: Bölüm 1 - İşe onu bozmaya çalışarak başladık
Sonraki: Bölüm 3 - Bizi kurtaran gösterişsiz spike'lar
Seri rehberi: /tr/blog/2026-02-25-open-world-browser-series-guide