deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Samurai Vengeance, 1000 bölümlük bir aksiyon oyununu 650 KB'lık tek bir HTML dosyasına sığdırıyor

Bir geliştirici, Samurai Vengeance adlı, on boss'lu 1000 bölümlük samuray aksiyon platform oyununu düz JavaScript, CSS ve canvas'tan oluşan tek bir 650 KB'lık HTML dosyası olarak yayınladı — motor yok, build adımı yok; elbette birkaç pürüz dışında.

Samurai Vengeance, 1000 bölümlük bir aksiyon oyununu 650 KB'lık tek bir HTML dosyasına sığdırıyor

Bir geliştirici, 1000 bölüm, on boss, üçlü vuruş kombosu, parede ve dash içeren, yan kaydırmalı samuray aksiyon platform oyunu Samurai Vengeance'ı neredeyse tamamen tek bir index.html dosyası olarak yayınladı. Geliştiricinin dev.to'daki yazısına göre dosya yaklaşık 650 KB ve kabaca 8.800 satır düz JavaScript, CSS ve markup'tan oluşuyor; oyun herhangi bir oyun motoru ve build adımı olmadan HTML canvas üzerine çiziliyor. Tek dosya tercihi bilinçli bir karar: ilk oyun olarak hiçbir yapılandırma gerektirmiyordu — dosyayı aç, bir satırı değiştir, yeniden yükle — ve dağıtım, statik bir sayfayı Netlify'a yüklemekten ibaretti.

Üç canvas, sınırlı pixel ratio

Sayfa üç tam ekran canvas'ı üst üste diziyor: biri paralaks arka plan için, biri oynanış için, biri de hava ve ön plan efektleri için. Bu ayrım, her katmanın farklı bir render maliyeti taşımasını sağlıyor. Yüksek yoğunluklu telefon ekranlarında canvas'lar cihaz pixel ratio'suna göre ölçekleniyor ama 2 ile sınırlanıyor; çünkü üç katman da her kareyi yeniden çiziyor ve pixel doldurma işi ratio'nun karesiyle artıyor — 3x ratio, 2x'inkinden iki kattan fazla pixel işlemek demek; geliştiriciye göre bu fark, kol mesafesinde tutulan bir telefonda zor fark edilir bir fark yaratıyor.

Görseller aslında dosyanın içinde değil

Tek dosya iddiasının büküldüğü yer burası. Boyanan görseller on dört ayrı PNG atlası olarak geliyor — oyuncu, ninja düşmanlar, okçular ve manzara için birer tane, ayrıca her boss için bir tane. Her atlas animasyon karelerinden değil vücut parçalarından oluşan bir sayfa; koddaki bir tablo her parçaya atlas koordinatlarını ve eklemdeki bir pivot noktasını veriyor, boyanan parçalar ise hiç görsel yokken karakterleri canlandıran prosedürel bir iskeletin üzerine çiziliyor. Her karakterin tamamen prosedürel bir çizim yolu da var; hiçbir atlas yüklenmezse oyun tek satır log kaydediyor ve o karakteri prosedürel bırakıyor — eksik bir dosya çökme yerine zarif biçimde düşünüyor.

Bu geri düşüm başlangıçta bant genişliğine mal oldu. Atlaslar başlangıçta hiç var olmayan bir sprites/ klasörü istiyordu; bu yüzden her ziyaret bir 404 ile başlıyor, üstelik hiç yapılmamış üç sprite sheet de her seferinde isteniyordu. Çözüm, önce site kökünü denemek ve kullanılmayan sheet'leri devre dışı bir bayrağın ardına koymak oldu.

Ses dosyası olmayan bir film müziği

Müzik dosyaları da yok. Soundtrack, Web Audio API ile canlı olarak üretiliyor ve birçok koto ve shamisen müziğinde kullanılan beş notalı miyako-bushi dizisinde (Re, Mi-bemol, Sol, La, Si-bemol) yazılmış. Her enstrüman osilatör, filtre ve gürültüden kurulu küçük bir fonksiyon: bir koto tınısı, bir shamisen, nefesli bir shakuhachi, perde düşen bir sinüs artı filtrelenmiş gürültüden yapılan bir taiko davulu ve bir düşük pad. Zamanlama, bir lookahead zamanlayıcısına dayanıyor — 25 ms'lik bir aralık, notaları yaklaşık 150 ms önceden ses saatine kuyruğa ekliyor — böylece bir kare takılrsa bile müzik ritmini koruyor ve boss teması, boss ikinci fazına geçtiğinde hızlanıyor ve davul ekliyor. Ses efektleri de kısa sentezlenmiş tonlar.

Yerel kayıtlar ve gizlilik dostu bir sayaç

İlerleme hesap gerektirmeden kaydediliyor: temel kayıt localStorage'daki tek bir JSON nesnesi (sv5 anahtarı, eski oyuncular ilerlemelerini korusun diye eski sv4'e geri düşümle), her okuma ve yazma try/catch'e sarılmış durumda; böylece gizli gezinmedeki depolama hataları oyunu asla durdurmuyor. İsteğe bağlı oturum açma, ilerlemeyi Firebase Firestore üzerinden eşitliyor ve oyuncuyu bir leaderboard'a ekliyor; SDK Google'ın CDN'inden yükleniyor.

Firebase Analytics yalnızca onaydan sonra başladığı ve Netlify istek sayaçları üç saniyelik bir geri dönüşü kırk dakikalık bir oturumdan ayıramadığı için geliştirici minimal bir sayaç kurdu. Sayfa, sade ve izinli listeye alınmış olay adlarını — arrived, start, bölüm geçişleri, death, quit, eğitim adımları — günlük tam sayı toplamlarını Firestore'a kaydeden bir Netlify fonksiyonuna gönderiyor; cookie, tanımlayıcı ya da IP adresi yok. Olaylar 1.2 saniyelik bir zamanlayıcıyla toplulaştırılıyor ve bir CORS preflight'ını atlatan text/plain içerik türüyle navigator.sendBeacon aracılığıyla iletiliyor. Kuyruk pagehide'da boşaltılıyor, arrived olayı ise sayfa görünür olana kadar erteleniyor; çünkü bağlantıları arka planda ön yükleyen uygulamalar bu sayıyı şişiriyordu.

Tek dosyanın bedeli

Ödünler açıkça söylenmiş. Her değişiklik 650 KB'lık sayfanın tamamını yeniden gönderiyor; sunucu no-cache gönderdiği için değişmemiş bir sayfa tam indirme yerine 304'e mal oluyor ve bu, ölçümlü barındırma bant genişliğinde önemliydi. 8.800 satırda gezinmek göz atmak değil aramak demek; bazı hatalar da iki bölümün birbirinden kopmasından kaynaklandı — bir hit box bir yerde tanımlanmışken slash efekti başka bir yerdeki farklı sayılardan çiziliyordu. Çizim kodundaki bir hata bir zamanlar oyunu tamamen durduruyordu; döngü artık draw ve update'i ayrı try bloklarına sarıyor, böylece kötü bir kare yalnızca kötü bir kare olarak kalıyor. Geliştiricinin deyişiyle "tek dosya" gerçekte oyun kodunun tek dosyası demek.

Neden önemli

Proje, vanilla web platformu özelliklerinin — canvas, Web Audio, localStorage, sendBeacon — bir motor, framework veya araç zinciri olmadan eksiksiz, ticari hissiyatlı bir oyunu ne kadar uzağa taşıyabileceğinin somut bir kanıtı. En az bunun kadar yararlı olan da taşınabilirlik örüntüleri: görseller için prosedürel geri düşümler, kare başına hata yalıtımı, savunmacı depolama erişimi ve kimseyi izlemeden "bunu oynayan oldu mu?" sorusunu yanıtlayan bir analitik yaklaşımı. Her türden küçük web projeleri için bu teknikler doğrudan aktarılabilir.

  • #javascript
  • #html5-canvas
  • #web-audio-api
  • #game-dev
  • #web