Slow Roads, tarayıcıda 3D'nin şaşırtıcı özelliklerini öne çıkararak hem oyuncuların hem de geliştiricilerin ilgisini nasıl çekiyor?

Bu basit sürüş oyununun sonsuz, işlemsel olarak oluşturulmuş manzarasıyla WebGL'nin potansiyelini keşfedin.

Slow Roads, sonsuz şekilde rastgele oluşturulan manzaralara odaklanan, WebGL uygulaması olarak tarayıcıda barındırılan bir sürüş oyunu. Birçok kişi için bu kadar yoğun bir deneyim, tarayıcı bağlamının sınırlı olması nedeniyle yersiz görünebilir. Bu projeyle ilgili hedeflerimden biri de bu tutumu düzeltmekti. Bu makalede, web'de 3D'nin göz ardı edilen potansiyelini vurgulama misyonum kapsamında performans engelini aşmak için kullandığım tekniklerden bazılarını ayrıntılı olarak anlatacağım.

Tarayıcıda 3D geliştirme

Slow Roads'u yayınladıktan sonra geri bildirimde tekrar tekrar "Bunun tarayıcıda mümkün olduğunu bilmiyordum" yorumunu gördüm. Bu duyguyu paylaşıyorsanız kesinlikle azınlıkta değilsiniz. 2022 JS Durumu anketine göre, geliştiricilerin yaklaşık% 80'i henüz WebGL ile deneme yapmadı. Özellikle tarayıcı tabanlı oyunlar söz konusu olduğunda bu kadar potansiyelin göz ardı edilmesinin utanç verici olduğunu düşünüyorum. Slow Roads ile WebGL'i daha fazla öne çıkarmayı ve belki de "yüksek performanslı JavaScript oyun motoru" ifadesinden çekinen geliştiricilerin sayısını azaltmayı umuyorum.

WebGL birçok kişi için gizemli ve karmaşık görünebilir ancak son yıllarda geliştirme ekosistemleri, son derece yetenekli ve kullanışlı araçlar ve kitaplıklar haline geldi. Artık ön uç geliştiricilerin, bilgisayar grafikleri konusunda daha önce deneyim sahibi olmasalar bile 3D kullanıcı deneyimini çalışmalarına dahil etmesi hiç olmadığı kadar kolay. Lider WebGL kitaplığı olan Three.js, React çerçevesine 3D bileşenler getiren react-three-fiber gibi birçok genişletmenin temelini oluşturur. Artık Babylon.js veya PlayCanvas gibi, aşina bir arayüz ve entegre araç zincirleri sunan kapsamlı web tabanlı oyun düzenleyiciler de mevcut.

Ancak bu kitaplıkların dikkate değer faydalarına rağmen, iddialı projeler sonunda teknik sınırlamalarla karşılaşır. Tarayıcı tabanlı oyun fikrine şüpheyle yaklaşanlar, JavaScript'in tek iş parçacıklı ve kaynak açısından sınırlı olduğunu öne sürebilir. Ancak bu sınırlamalarla başa çıkmak, gizli değeri ortaya çıkarır: Başka hiçbir platform, tarayıcı tarafından sunulan anında erişilebilirlik ve geniş uyumluluğu sunmaz. Tarayıcı uyumlu herhangi bir sistemdeki kullanıcılar, uygulama yüklemelerine veya hizmetlerde oturum açmalarına gerek kalmadan tek tıklamayla oynamaya başlayabilir. Geliştiricilerin, kullanıcı arayüzü oluşturmak veya çok oyunculu modlar için ağ bağlantısını yönetmek üzere güçlü ön uç çerçevelerinden yararlanmanın zarif rahatlığını da unutmamak gerekir. Bence bu değerler, tarayıcıyı hem oyuncular hem de geliştiriciler için mükemmel bir platform haline getiren unsurlardır. Slow Roads'un gösterdiği gibi, teknik sınırlamalar genellikle bir tasarım sorununa indirgenebilir.

Yavaş yollarda sorunsuz performans elde etme

Slow Roads'un temel unsurları yüksek hızlı hareket ve pahalı sahne oluşturma olduğundan, sorunsuz performans ihtiyacı her tasarım kararımda belirleyici oldu. Ana stratejim, motorun mimarisinde bağlama dayalı kısayollar kullanılmasına olanak tanıyan basit bir oyun tasarımıyla başlamaktı. Bunun dezavantajı, minimalizm arayışında bazı kullanışlı özelliklerden ödün vermek anlamına gelir. Ancak bu yaklaşım, farklı tarayıcılar ve cihazlarda sorunsuz çalışan, özel ve son derece optimize edilmiş bir sistemle sonuçlanır.

Aşağıda, Slow Roads'un sade kalmasını sağlayan temel bileşenlerin dökümü verilmiştir.

Ortam motorunu oyun deneyimine göre şekillendirme

Oyunun temel bileşeni olan ortam oluşturma motoru, kaçınılmaz olarak pahalıdır ve bellek ile işleme bütçelerinin en büyük kısmını haklı olarak alır. Buradaki püf noktası, performanstaki ani artışlarla kare hızını kesintiye uğratmamak için ağır hesaplamayı planlayıp bir süreye dağıtmaktır.

Ortam, kameraya ne kadar yakın görüneceklerine bağlı olarak boyut ve çözünürlük açısından farklı geometri karolarından oluşur ("ayrıntı düzeyleri" veya LoD'ler olarak sınıflandırılır). Serbest dolaşan kameraya sahip tipik oyunlarda, oyuncunun gitmeyi seçebileceği her yerde çevresini ayrıntılı olarak göstermek için sürekli olarak farklı düzeylerde ayrıntılar yüklenip kaldırılmalıdır. Bu, özellikle ortamın kendisi dinamik olarak oluşturulduğunda pahalı ve israflı bir işlem olabilir. Neyse ki bu kural, kullanıcının yolda kalması gerektiğine dair bağlamsal beklenti sayesinde Yavaş Yollar'da tamamen altüst edilebilir. Bunun yerine, yüksek ayrıntılı geometri doğrudan rotayı çevreleyen dar koridor için ayrılabilir.

Yolun çok önceden oluşturulmasının, ortam oluşturmanın proaktif planlanmasına ve önbelleğe alınmasına nasıl olanak tanıdığını gösteren bir diyagram.
Yavaş yollardaki çevre geometrisinin tel çerçeve olarak oluşturulmuş görünümü. Bu görünümde, yolun iki yanındaki yüksek çözünürlüklü geometri koridorları gösterilmektedir. Ortamdaki hiçbir zaman yakından görülmemesi gereken uzak kısımlar çok daha düşük çözünürlükte oluşturulur.

Yolun orta çizgisi, oyuncunun gelişinden çok daha önce oluşturulur. Bu sayede, ortam ayrıntısının tam olarak ne zaman ve nerede gerekli olacağını doğru bir şekilde tahmin edebilirsiniz. Sonuç olarak, pahalı işleri proaktif olarak planlayabilen, her noktada gereken minimum miktarda iş üreten ve görünmeyecek ayrıntılar için hiçbir çaba harcanmayan yalın bir sistem elde edilir. Bu teknik, yalnızca yol tek ve dallanmayan bir yol olduğu için mümkündür. Bu, mimari kısayollara uyum sağlayan oyun oynama takasları yapmanın iyi bir örneğidir.

Yolun çok önceden oluşturulmasının, ortam oluşturmanın proaktif planlanmasına ve önbelleğe alınmasına nasıl olanak tanıdığını gösteren bir diyagram.
Yol boyunca belirli bir mesafeye bakarak ortam parçaları önceden alınabilir ve ihtiyaç duyulmadan hemen önce kademeli olarak oluşturulabilir. Ayrıca, yakın gelecekte tekrar ziyaret edilecek tüm parçalar, gereksiz yeniden oluşturma işlemlerini önlemek için tanımlanabilir ve önbelleğe alınabilir.

Fizik yasaları konusunda titiz olma

Ortam motorunun hesaplama talebinin ardından ikinci sırada fizik simülasyonu gelir. Slow Roads, mevcut tüm kısayolları kullanan özel ve minimal bir fizik motoru kullanır.

Buradaki en büyük tasarruf, öncelikle çok fazla nesneyi simüle etmekten kaçınmaktır. Dinamik çarpışmalar ve yok edilebilir nesneler gibi öğeleri göz ardı ederek minimal, zen bağlama yönelebilirsiniz. Aracın yolda kalacağı varsayımı, arazideki nesnelerle çarpışmaların makul bir şekilde göz ardı edilebileceği anlamına gelir. Ayrıca, yolun seyrek bir orta çizgi olarak kodlanması, yol yüzeyi ve koruyucu raylarla hızlı çarpışma algılama için zarif hileler sağlar. Bu hileler, hepsinin yolun merkezine olan mesafe kontrolüne dayanır. Bu durumda arazi sürüşü daha pahalı hale gelir ancak bu, oyun bağlamına uygun makul bir denge örneğidir.

Bellek kullanımını yönetme

Tarayıcı tarafından kısıtlanan bir başka kaynak olan JavaScript'in çöp toplanması özelliğine rağmen, belleği dikkatli bir şekilde yönetmek önemlidir. Bu nokta gözden kaçabilir ancak oyun döngüsü içinde küçük miktarlarda yeni bellek tanımlamak, 60 Hz'de çalışırken önemli sorunlara yol açabilir. Büyük çöp toplama işlemlerinin tamamlanması birkaç kare sürebilir ve bu da kullanıcının muhtemelen çoklu görev yaptığı bir bağlamda kullanıcının kaynaklarını tüketmenin yanı sıra belirgin takılmalara neden olabilir. Bu durumu önlemek için döngü belleği, ilk başlatmada sınıf değişkenlerine önceden ayrılabilir ve her karede geri dönüştürülebilir.

Slow Roads kod tabanının optimizasyonu sırasında bellek profilinin öncesi ve sonrası görünümü. Görünüm, önemli tasarruflar ve çöp toplama hızında düşüş olduğunu gösteriyor.
Genel bellek kullanımı neredeyse hiç değişmese de döngü belleğini önceden ayırmak ve geri dönüştürmek, pahalı çöp toplama işlemlerinin etkisini büyük ölçüde azaltabilir.

Geometriler ve ilişkili veri arabellekleri gibi daha ağır veri yapılarının ekonomik bir şekilde yönetilmesi de son derece önemlidir. Slow Roads gibi sonsuz olarak oluşturulan bir oyunda geometrinin çoğu bir tür koşu bandında bulunur. Eski bir parça uzaklara düştüğünde veri yapıları saklanabilir ve dünyanın yeni bir parçası için tekrar kullanılabilir. Bu, nesne havuzu olarak bilinen bir tasarım kalıbıdır.

Bu uygulamalar, kod basitliğinden ödün vererek yalın yürütmeye öncelik vermeye yardımcı olur. Yüksek performanslı bağlamlarda, kolaylık özelliklerinin bazen geliştiricinin yararı için istemciden nasıl ödünç aldığına dikkat etmek önemlidir. Örneğin, Object.keys() veya Array.map() gibi yöntemler son derece kullanışlıdır ancak her birinin döndürdüğü değer için yeni bir dizi oluşturduğu gözden kaçabilir. Bu tür kara kutuların iç işleyişini anlamak, kodunuzu sıkılaştırmanıza ve gizli performans düşüşlerinden kaçınmanıza yardımcı olabilir.

Prosedürel olarak oluşturulmuş öğelerle yükleme süresini azaltma

Oyun geliştiriciler için birincil endişe, çalışma zamanındaki performans olsa da web sayfasının ilk yükleme süresiyle ilgili genel aksiyomlar geçerliliğini korur. Kullanıcılar, bilinçli olarak ağır içeriklere erişirken daha anlayışlı olabilir ancak uzun yükleme süreleri, kullanıcı elde tutma oranını etkilemese bile deneyime zarar verebilir. Oyunlar genellikle doku, ses ve 3D model biçiminde büyük öğeler gerektirir. Bu öğeler, ayrıntıların azaltılabileceği yerlerde en azından dikkatlice sıkıştırılmalıdır.

Alternatif olarak, istemcide öğeleri prosedürel olarak oluşturmak, uzun aktarımlardan kaçınmayı sağlayabilir. Bu, yavaş bağlantı kullanan kullanıcılar için büyük bir avantajdır ve geliştiriciye oyununun nasıl oluşturulacağı konusunda daha doğrudan kontrol sağlar. Bu kontrol, yalnızca ilk yükleme adımı için değil, farklı kalite ayarlarına göre ayrıntı düzeylerini uyarlama konusunda da geçerlidir.

Yavaş yollardaki işlemsel olarak oluşturulmuş geometrinin kalitesinin, kullanıcının performans ihtiyaçlarına dinamik olarak nasıl uyarlanabileceğini gösteren bir karşılaştırma.

Slow Roads'taki geometrinin çoğu, ayrıntıları sağlamak için birden fazla doku birleştiren özel gölgelendiriciler ile işlemsel olarak oluşturulur ve basittir. Bunun dezavantajı, bu dokuların ağır öğeler olabilmesidir. Ancak küçük kaynak dokulardan daha fazla ayrıntı elde etmenizi sağlayan stokastik doku oluşturma gibi yöntemler sayesinde burada tasarruf için başka fırsatlar da vardır. Ayrıca, texgen.js gibi araçlarla dokuları tamamen istemcide oluşturmak da mümkündür. Aynı durum ses için de geçerlidir. Web Audio API, ses düğümleriyle ses oluşturmaya olanak tanır.

İşlemsel öğelerin avantajıyla ilk ortamı oluşturmak ortalama 3, 2 saniye sürer. Küçük ön indirme boyutundan en iyi şekilde yararlanmak için yeni ziyaretçileri basit bir açılış ekranıyla karşılayın ve pahalı sahne başlatma işlemini, onay düğmesine basılana kadar erteleyin. Bu, dinamik olarak yüklenen öğelerin aktarımındaki israfı en aza indirerek, atlanan oturumlar için kullanışlı bir arabellek görevi de görür.

Kullanıcıların% 60'ından fazlasının ilk üç saniyede yoğun bir şekilde yükleme işlemi gerçekleştirdiğini ve ardından hızlı bir düşüş yaşandığını gösteren yükleme sürelerinin histogramı. Histogram, kullanıcıların% 97'sinden fazlasının 10 saniyeden kısa yükleme süreleri gördüğünü gösterir.

Geç optimizasyona çevik bir yaklaşım

Slow Roads'un kod tabanını her zaman deneysel olarak değerlendirdiğim için geliştirmeye son derece çevik bir yaklaşım benimsedim. Karmaşık ve hızla gelişen bir sistem mimarisiyle çalışırken önemli darboğazların nerede oluşabileceğini tahmin etmek zor olabilir. Odak noktası, istenen özellikleri düzgün bir şekilde uygulamak yerine hızlı bir şekilde uygulamak ve ardından gerçekten önemli olan sistemleri optimize etmek için geriye dönük çalışmak olmalıdır. Chrome Geliştirici Araçları'ndaki performans profilleyici bu adımda çok faydalı oldu ve oyunun önceki sürümleriyle ilgili bazı önemli sorunları teşhis etmemize yardımcı oldu. Geliştirici olarak zamanınız değerlidir. Bu nedenle, önemsiz veya gereksiz olabilecek sorunlar üzerinde fazla düşünmediğinizden emin olun.

Kullanıcı deneyimini izleme

Tüm bu ipuçlarını uygularken oyunun gerçek dünyada beklendiği gibi performans gösterdiğinden emin olmanız önemlidir. Çeşitli donanım özelliklerini desteklemek, oyun geliştirmenin temel özelliklerinden biridir. Ancak web oyunları hem üst düzey masaüstü bilgisayarları hem de on yıllık mobil cihazları aynı anda kapsayan çok daha geniş bir kitleyi hedefleyebilir. Bu konuya en basit yaklaşım, kod tabanınızdaki en olası darboğazları (hem GPU hem de CPU yoğun görevler için) profilleyiciniz tarafından gösterildiği şekilde uyarlamak için ayarlar sunmaktır.

Kendi makinenizde profil oluşturma işlemi yalnızca belirli bir noktaya kadar etkili olabilir. Bu nedenle, kullanıcılarınızla geri bildirim döngüsünü bir şekilde kapatmak önemlidir. Yavaş Yollar için ekran çözünürlüğü gibi bağlamsal faktörlerle birlikte performansı raporlayan basit analizler çalıştırıyorum. Bu analizler, kullanıcının oyun içi form aracılığıyla gönderdiği yazılı geri bildirimlerle birlikte socket.io kullanılarak temel bir Node arka ucuna gönderilir. İlk günlerde bu analizler, kullanıcı deneyiminde yapılacak basit değişikliklerle azaltılabilen birçok önemli sorunu tespit etti. Örneğin, sürekli olarak düşük FPS algılandığında ayarlar menüsünün vurgulanması veya performans özellikle düşükse kullanıcının donanım hızlandırmayı etkinleştirmesi gerekebileceği konusunda uyarı gösterilmesi gibi.

İleride yavaş yollar

Tüm bu önlemleri aldıktan sonra bile, oyuncu tabanımızın önemli bir kısmı daha düşük ayarlarda oynamak zorunda kalıyor. Özellikle de GPU'su olmayan hafif cihazları kullananlar bu durumdan etkileniyor. Mevcut kalite ayarları, oldukça eşit bir performans dağılımına yol açsa da oyuncuların yalnızca% 52'si 55 FPS'nin üzerine çıkabiliyor.

Farklı eşlemelerde elde edilen ortalama saniyedeki kare sayısını gösteren, ayrıntı ayarına göre görüntüleme mesafesi ayarı ile tanımlanan bir matris. Dağıtım 45 ile 60 arasında oldukça eşit bir şekilde dağılmıştır. İyi performans için hedef 60'tır. Düşük ayarlarda olan kullanıcılar, yüksek ayarlarda olan kullanıcılara kıyasla daha düşük FPS görür. Bu durum, istemci donanımındaki farklılıkları vurgular.
Bu verilerin, tarayıcılarını donanım hızlandırması devre dışıyken çalıştıran kullanıcılar tarafından biraz çarpıtıldığını ve genellikle yapay olarak düşük performansa neden olduğunu unutmayın.

Neyse ki performansta tasarruf etmek için hâlâ birçok fırsat var. GPU talebini azaltmak için daha fazla oluşturma hilesi eklemenin yanı sıra, yakın gelecekte ortam oluşturmayı paralelleştirirken web işçilerini denemeyi umuyorum. Ayrıca, WASM veya WebGPU'yu kod tabanına dahil etmenin gerekli olduğunu fark edebiliriz. Açabileceğim her boşluk, daha zengin ve daha çeşitli ortamlar oluşturmamızı sağlayacak. Bu da projenin geri kalanı için kalıcı hedefimiz olacak.

Slow Roads, hobi projeleri arasında şaşırtıcı derecede ayrıntılı, performanslı ve popüler tarayıcı oyunlarının ne kadar olabileceğini göstermenin son derece tatmin edici bir yolu oldu. WebGL'ye olan ilginizi uyandırabildiysem teknolojik açıdan Slow Roads'un, WebGL'nin tüm özelliklerini gösteren oldukça basit bir örnek olduğunu bilmenizi isterim. Okuyucuları Three.js vitrinini keşfetmeye kesinlikle teşvik ediyorum. Özellikle web oyunu geliştirmeyle ilgilenenler webgamedev.com adresindeki topluluğa katılabilir.