Bu basit sürüş oyununun prosedürel olarak üretilmiş sonsuz sahnesiyle WebGL'nin potansiyelini keşfedin.
Slow Roads, süreçsel olarak oluşturulan sonsuz bir manzaraya odaklanan gündelik bir sürüş oyunudur. Tümü tarayıcıda bir WebGL uygulaması olarak barındırılır. Birçok kişi için bu tür yoğun bir deneyim, tarayıcının sınırlı bağlamında gözükmeyebilir. Hatta bu tutumu düzeltmeye çalışmak bu projedeki hedeflerimden biri olmuştur. Bu makalede, görevimdeki 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 bildirimin içinde tekrar eden bir yorum olduğunu gördüm: "Tarayıcıda bunun mümkün olduğunu bilmiyordum". Bu düşünceyi paylaşıyorsanız azınlık arasında olmadığınız kesin değildir. 2022 State of JS anketine göre, geliştiricilerin% 80'i henüz WebGL ile deneme yapmamıştır. Özellikle tarayıcı tabanlı oyunlar söz konusu olduğunda bu kadar çok potansiyelin kaçırılması benim için utanç verici. Yavaş Yollar ile WebGL'yi daha fazla gündeme getirmeyi ve belki de "yüksek performanslı JavaScript oyun motoru" ifadesine itiraz eden geliştiricilerin sayısını azaltmayı umuyorum.
WebGL, pek çok kişi için gizemli ve karmaşık görünebilir, ancak son yıllarda geliştirme ekosistemleri büyük ölçüde becerikli ve kullanışlı araç ve kitaplıklara dönüştü. Kullanıcı arabirimi geliştiricilerinin, bilgisayar grafikleri konusunda deneyimi olmasa bile, işlerine 3B kullanıcı deneyimini dahil etmeleri artık her zamankinden daha kolay. Önde gelen WebGL kitaplığı olan Three.js, 3D bileşenlerini React çerçevesine getiren react-three-fiber dahil olmak üzere birçok genişletme için temel oluşturur. Artık Babylon.js veya PlayCanvas gibi, tanıdık bir arayüz ve entegre araç zincirleri sunan kapsamlı web tabanlı oyun editörleri de var.
Ancak bu kitaplıklar son derece kullanışlı olsa da iddialı projeler zaman içinde teknik sınırlamalara tabi olur. Tarayıcı tabanlı oyun fikrine şüpheciler, JavaScript'in tek iş parçacıklı ve kaynak kısıtlamalı olduğunu vurgulayabilir. Ancak bu sınırlamalara göre hareket etmek gizli değerin kilidini açar: Tarayıcı tarafından etkinleştirilen anında erişilebilirlik ve kitle uyumluluğunu başka hiçbir platform sunmaz. Tarayıcı özellikli herhangi bir sistemdeki kullanıcılar, uygulama yüklemeye ve hizmetlerde oturum açmaya gerek kalmadan tek tıklamayla oynamaya başlayabilir. Geliştiricilerin kullanıcı arayüzü oluşturmak veya çok oyunculu modlarda ağ iletişimini yönetmek için güçlü kullanıcı arabirimi çerçevelerine sahip olmanın zarif rahatlığından bahsetmiyorum. Benim düşünceme göre, bu değerler, tarayıcıyı hem oyuncular hem de geliştiriciler için mükemmel bir platform haline getiriyor. Ayrıca, Slow Roads'ta da gösterildiği gibi, teknik sınırlamalar genellikle bir tasarım sorununa indirgenebilir.
Yavaş yollarda sorunsuz performans sağlama
Yavaş Yollar'ın temel unsurları yüksek hızlı hareket ve pahalı sahne üretimi içerdiğinden, sorunsuz performans ihtiyacı verdiğim her tasarım kararının altını çizdi. Ana stratejim, motorun mimarisi dahilinde bağlamsal kısayolların kullanılmasına olanak tanıyan sadeleştirilmiş bir oyun tasarımıyla başlamaktı. Bunun olumsuz tarafı, minimalizm arayışında olmasında güzel olan bazı özelliklerden ödün vermek anlamına gelir. Ancak farklı tarayıcı ve cihazlarda sorunsuz çalışan, özel olarak geliştirilmiş, hiper optimize edilmiş bir sistem elde edilir.
Aşağıda, Yavaş Yolları eğimli tutan temel bileşenlerin dökümü verilmiştir.
Oyunun etrafında çevre motorunu şekillendirme
Oyunun temel bileşeni olan ortam oluşturma motoru kaçınılmaz derecede pahalıdır ve bu nedenle bellek ve bilgi işlem bütçelerinin en büyük kısmını alır. Burada kullanılan püf noktası, yoğun hesaplamaların belirli bir süreye programlanması ve dağıtılması, böylece performanstaki ani artışlarla kare hızını kesmemektir.
Ortam, kameraya ne kadar yakın göründüklerine bağlı olarak boyut ve çözünürlük ("ayrıntı seviyeleri" veya "LoD'lar" olarak kategorize edilir) farklı geometrik parçalardan oluşur. Serbest dolaşım kamerası olan tipik oyunlarda, oyuncunun gitmek isteyebilecekleri her yerde etrafı ayrıntılı bir şekilde göstermesi için farklı LoD'lerin sürekli olarak yüklenmesi ve boşaltılması gerekir. Bu, özellikle ortamın kendisi dinamik olarak oluşturuluyorsa pahalı ve israflı bir işlem olabilir. Neyse ki, kullanıcının yoldan çıkmaması gerektiği beklentisi yavaş Yollar'da bu kural tamamen geçersiz kılınabiliyor. Bunun yerine, yüksek ayrıntılı geometri, rotanın doğrudan yanındaki dar koridor için ayrılabilir.
![Çok önceden yol oluşturmanın, çevre oluşturma sürecinin proaktif bir şekilde planlanmasına ve önbelleğe alınmasına ne kadar olanak sağlayabileceğini gösteren bir diyagram.](https://web.dev/static/case-studies/slow-roads/image/a-diagram-showing-genera-8bc6e65c0bba1.png?authuser=5&hl=tr)
Yolun orta çizgisi oyuncunun varıştan çok daha önce oluşturulur. Bu sayede ortam ayrıntısının tam olarak ne zaman ve nerede gerekli olacağına dair doğru tahminler yapılabilir. Bunun sonucunda, pahalı işleri proaktif olarak planlayabilen, her zaman için yalnızca gereken minimum miktarı üreten ve görülmeyecek ayrıntılar için boşa çaba harcamadan çalışan yalın bir sistem ortaya çıkar. Bu teknik yalnızca, yolun iki ayrı yere bölünmeyen tek bir yol olması nedeniyle mümkündür. Bu, mimari kesirlere uyum sağlayan oynanabilirlikten ödün vermenin iyi bir örneğidir.
![Çok önceden yol oluşturmanın, çevre oluşturma sürecinin proaktif bir şekilde planlanmasına ve önbelleğe alınmasına ne kadar olanak sağlayabileceğini gösteren bir diyagram.](https://web.dev/static/case-studies/slow-roads/image/a-diagram-showing-genera-a22a99a5764f2.png?authuser=5&hl=tr)
Fizik yasaları konusunda seçici olmak
Çevre motorunun bilişimsel ihtiyacından ikincisi fizik simülasyonudur. Yavaş Yollar'da, mevcut tüm kesirlere ulaşabilen özel, minimal bir fizik motoru kullanılmaktadır.
Buradaki en büyük tasarruf, en başta çok fazla nesne simüle etmekten kaçınmaktır. Dinamik çarpışmalar ve yok edilebilir nesneler gibi unsurları azaltarak minimum, zen bağlamına yönelin. Aracın yolda kalacağı varsayımı, arazideki cisimlerle çarpışmaların makul ölçüde göz ardı edilebileceği anlamına gelir. Ayrıca, yolun seyrek bir orta çizgi olarak kodlanması, yol yüzeyi ve bariyerlerle hızlı bir çarpışma tespiti için yol merkezine yapılan mesafe kontrolüne dayalı zarif hilelere olanak tanır. Bu durumda arazi sürüşü daha pahalı hale gelir ancak bu da oyunun bağlamına uygun adil ziyafet için başka bir örnektir.
Bellek ayak izini yönetme
Tarayıcı tarafından kısıtlanan başka bir kaynak olarak, JavaScript'in çöp halde toplanmış olmasına rağmen belleğin dikkatli bir şekilde yönetilmesi önemlidir. Bunu gözden kaçırmak kolay olabilir, ancak bir oyun döngüsünde küçük miktarda yeni bellek belirtmek bile 60 Hz hızda çalışırken önemli sorunlara yol açabilir. Büyük çöp toplama işlemleri, kullanıcıların kaynaklarını muhtemelen birden fazla iş yaptıkları bir bağlamda bitirmelerine ek olarak birkaç kare sürebilir ve fark edilir düzeyde takılmalara neden olabilir. Bunu önlemek için döngü belleği, başlangıçta sınıf değişkenlerinde önceden tahsis edilebilir ve her karede geri dönüştürülebilir.
![Yavaş Yollar kod tabanı optimizasyonu sırasında bellek profilinin öncesi ve sonrası görünümü, önemli tasarruflar ve atık toplama oranında düşüş olduğunu gösterir.](https://web.dev/static/case-studies/slow-roads/image/a-before-after-view-the-f870ec7d3c94f.png?authuser=5&hl=tr)
Geometrikler ve bunlarla ilişkili veri tamponları gibi daha ağır veri yapılarının ekonomik olarak yönetilmesi de son derece önemlidir. Slow Roads gibi sonsuz sayıda oluşturulmuş oyunda, geometrinin çoğu bir tür koşu bandında bulunuyor. Eski bir parça uzaklarda geriye düştüğünde, veri yapıları saklanabilir ve gelecekte daha sonra ortaya çıkacak bir parça için geri dönüştürülebilir. Bu tasarım kalıbı, nesne havuzu oluşturma olarak bilinir.
Bu uygulamalar, kod basitliğinden ödün vererek yalın yürütmenin önceliklendirilmesine yardımcı olur. Yüksek performans gerektiren durumlarda, kolaylık özelliklerinin bazen geliştirici yararı için istemciden ödünç alındığına dikkat etmek önemlidir. Örneğin, Object.keys()
veya Array.map()
gibi yöntemler son derece kullanışlıdır ancak her birinin kendi döndürdüğü değer için yeni bir dizi oluşturduğunu göz ardı etmek kolaydır. Bu tür kara kutuların iç işleyişini anlamak, kodunuzu sıkılaştırmanıza ve sinsi performans isabetlerinden kaçınmanıza yardımcı olabilir.
Prosedürle oluşturulan öğelerle yükleme süresini azaltma
Oyun geliştiricilerinin asıl önceliği çalışma zamanı performansı olmalıdır. Bununla birlikte, ilk web sayfası yükleme süresiyle ilgili olağan aksilikler geçerliliğini koruyor. Kullanıcılar, ağır içeriğe bilerek erişirken daha hoşgörülü olabilir, ancak uzun yükleme süreleri, kullanıcıları elde tutma oranında değilse bile, deneyim için zararlı olabilir. Oyunlar genellikle doku, ses ve 3D model biçiminde büyük öğeler gerektirir ve en azından, ayrıntılardan kaçınılabilecek yerlerde bu öğeler dikkatlice sıkıştırılmalıdır.
Alternatif olarak, müşteride prosedürlere göre öğeler oluşturmak, uzun aktarım işlemlerini daha en baştan önleyebilir. Bu, bağlantıları yavaş olan kullanıcılar için büyük bir avantajdır ve geliştiriciye yalnızca ilk yükleme adımı için değil, aynı zamanda ayrıntı düzeylerini farklı kalite ayarlarına göre uyarlama konusunda da oyunun yapısı üzerinde daha fazla doğrudan kontrol sağlar.
Yavaş Yollar'daki geometrinin büyük bir kısmı yöntemsel olarak oluşturulmuş ve basittir. Özel gölgelendiriciler, ayrıntıları göstermek için birden çok dokuyu birleştirir. Dezavantajı, bu dokuların ağır öğeler olabilmesidir. Bununla birlikte, stokastik doku oluşturma gibi yöntemlerle küçük kaynak dokulardan daha fazla ayrıntı elde edilebildiği için burada tasarruf fırsatları daha fazladır. Uç bir seviyede, texgen.js gibi araçlarla tamamen istemci üzerinde dokular oluşturmak da mümkündür. Aynısı ses için de geçerlidir. Web Audio API, ses düğümleriyle ses oluşturmaya olanak tanır.
Prosedürel öğelerin avantajı sayesinde, ilk ortamın oluşturulması ortalama olarak yalnızca 3,2 saniye sürer. Küçük, ön indirme boyutundan en iyi şekilde yararlanmak için basit bir başlangıç ekranı yeni ziyaretçileri karşılar ve pahalı olan sahnenin başlatılmasını olumlu bir düğmeye basılana kadar erteler. Bu aynı zamanda, hemen çıkılan oturumlar için uygun bir tampon görevi görür ve dinamik olarak yüklenen öğelerin boşa aktarılmasını en aza indirir.
Geç optimizasyon konusunda çevik bir yaklaşım benimseme
Yavaş Yollar'ın kod tabanını her zaman deneysel olarak düşünmüşümdür. Bu nedenle, geliştirme konusunda son derece çevik bir yaklaşım benimsemişimdir. Karmaşık ve hızla değişen bir sistem mimarisiyle çalışırken önemli performans sorunlarının nerede gerçekleşebileceğini tahmin etmek zor olabilir. Odak, istenen özellikleri sorunsuz yerine hızlı bir şekilde uygulamak ve ardından sistemleri gerçekten önemli olduğu noktalarda optimize etmek için geriye doğru çalışmak olmalıdır. Chrome Geliştirici Araçları'ndaki performans profil aracı bu adım için çok değerlidir ve oyunun önceki sürümlerindeki bazı önemli sorunları teşhis etmeme yardımcı olmuştur. Geliştirici olarak zamanınız değerlidir. Bu nedenle, önemsiz veya gereksiz hale gelebilecek sorunlar üzerine kafa yormaya zaman harcamadığınızdan emin olun.
Kullanıcı deneyimini izleme
Tüm bu hileleri uygularken oyunun normalde beklendiği gibi çalıştığından emin olmak önemlidir. Çeşitli donanım özelliklerini barındırmak, her oyun geliştirmenin temel unsurlarından biridir. Ancak web oyunları, aynı anda hem üst düzey masaüstü bilgisayarları hem de onlarca yıllık mobil cihazları kapsayan çok daha geniş bir yelpazeyi hedefleyebilir. Bu konuda en basit yaklaşım, profil oluşturucunuzun belirttiği gibi kod tabanınızdaki en olası performans sorunlarını (hem GPU hem de CPU yoğun görevler için) uyarlamaya yönelik ayarlar sunmaktır.
Ancak, kendi makinenizde profil oluşturmak yalnızca bu işlemi kapsayabilir. Bu nedenle, kullanıcılarınızla bir şekilde geri bildirim döngüsünü tamamlamanız önemlidir. Yavaş Yollar için, ekran çözünürlüğü gibi bağlamsal faktörlerin yanı sıra performansı da 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 Düğüm arka ucuna gönderilir. İlk günlerde bu analizler, sürekli olarak düşük bir FPS algılandığında kullanıcı deneyimindeki basit değişikliklerle giderilebilecek veya sürekli düşük bir FPS algılandığında ayarlar menüsünün vurgulanması veya performansın özellikle kötü olduğu durumlarda kullanıcının donanım hızlandırmayı etkinleştirmesi gerekebileceğine dair uyarıda bulunması gibi birçok önemli sorunla yakalandı.
İleride yavaş yollar
Tüm bu önlemleri aldıktan sonra bile oyuncu tabanının önemli bir bölümünün daha düşük ayarlarda, özellikle de GPU'su olmayan hafif cihazlar kullananlarda oynaması gerekiyor. Kullanılabilen kalite ayarları çeşitliliği yeterince iyi bir performans dağıtımı sağlasa da oyuncuların yalnızca% 52'si 55 FPS'nin üstünde başarı elde ediyor.
![Görüntüleme mesafesi ayarı ile ayrıntı ayarına göre tanımlanan ve farklı eşlemelerde saniyedeki ortalama kare sayısını gösteren bir matris. Dağılım, 45 ile 60 arasında oldukça eşit bir şekilde yayılır. 60, iyi performans için hedeftir. Düşük ayarlardaki kullanıcılar, yüksek ayarlardakilerden daha düşük bir FPS görme eğilimindedir. Bu da, istemci donanımı özelliklerindeki farklılıkları vurgular.](https://web.dev/static/case-studies/slow-roads/image/a-matrix-defined-view-di-5c73d8d72469c.png?authuser=5&hl=tr)
Neyse ki performans tasarrufu sağlamak için hâlâ birçok fırsat var. GPU talebini azaltmak için başka oluşturma numaraları eklemenin yanı sıra, yakın zamanda ortam üretimine paralel olarak web çalışanlarıyla denemeler yapmayı umuyorum. Zaman içinde kod tabanına WASM veya WebGPU'nun eklenmesi gerekli olabilir. Ayrılabileceğim her olası boşluk, daha zengin ve daha çeşitli ortamlara olanak tanıyacak ve bu, projenin geri kalanında nihai hedef olacaktır.
Hobi projeleri devam ederken Slow Roads; tarayıcı oyunlarının ne kadar şaşırtıcı derecede ayrıntılı, etkili ve popüler olabileceğini göstermenin son derece tatmin edici bir yolu oldu. WebGL ile ilgilendiğinizi çekmede başarılı olduysam, teknolojik olarak Yavaş Yollar'ın tüm özelliklerine ilişkin oldukça yüzeysel bir örnek olduğunu bilin. Okuyucuları Three.js vitrinini keşfetmeye davet ediyorum. Özellikle web oyunu geliştirmeyle ilgilenenler ise webgamedev.com topluluğuna hoş geldiniz.