1 puan yazan GN⁺ 2024-05-09 | 1 yorum | WhatsApp'ta paylaş

xkcd'nin "Machine" Geliştirme Notları

İlk fikir

  • Mart sonuna kadar fikir üzerinde düşündükten sonra Nisan başında karar verilen fikir
  • "Something Awful kullanıcılarının yaptığı blueball GIF'i gibi döşeme tabanlı dev bir düzenek yapabilir miyiz? Herkes küçük bir kareye katkıda bulunacak."
  • Başta fikir tam olarak şekillenmiş gibi geliyordu, ancak gerçekten konuşmaya başlayınca hâlâ verilmesi gereken çok sayıda karar olduğunu fark ettiler
  • Topun nereden çıkacağı, herkesin aynı makineyi görüp görmediği, amacın ne olduğu, oyuncuların nasıl etkileşime gireceği gibi temel noktalarda farklı düşüncelere sahiptiler

Önceki denemelerden öğrenilenler

  • Kullanıcı üretimi içerik odaklı interaktif çizgi roman yapma deneyimi vardı
    • Lorenz: Okurların panel metinlerini yazarak şakayı ve hikâyeyi geliştirdiği bir exquisite corpse çalışması (çok eğlenceliydi)
    • Collector's Edition: Okurların xkcd arşivine gizlenmiş çıkartmaları bulup paylaşılan tuvale kalıcı olarak yapıştırdığı bir oyun (istenen sonucu vermedi)
      • Başta boş bir merkez haritayla başlamak kaosa yol açtı
      • Çıkartma yerleştirme konusunda teşvik az olduğundan, bireysel davranışlarla olay örgüsünü ilerletmek zordu ve sadece basit desenler oluştu
      • Genel bir hikâye ya da hedef yoktu ve çıkartmaların birbirleriyle ilişkisi de belirsizdi
  • Ortak bir tuvalin başarılı olması için insanlara neler yapılabileceğini örneklerle göstermek ve paylaşılan bir bağlam ile amaç sağlamak gerekiyor

Kısıtların tasarlanması

  • Büyük bir bilye düşürme makinesi yapmaya karar verdikten sonra fazla sayıda seçenekle karşı karşıya kaldılar
  • 100x100 boyutunda bir grid kullanmaya karar verdiler
    • İstemci tarafında 10 bin döşemeyi gerçek zamanlı simüle etmek riskli görünüyordu
    • Oyuncuların doğrudan iletişim kurmadan karmaşık bir makinenin alt bölümlerini nasıl yapacağı ve ayrık döşemeler birleştirildiğinde bunun çalışıp çalışmayacağı belirsizdi
  • Birçok düşünce deneyi sonunda 3 temel ilke belirlendi:

1. Doğruluğu feda etme pahasına bile oyuncu ifadesini en üst düzeye çıkarmak

  • Makine ne kadar öngörülebilir olmalı?
    • Tüm sistemi sunucuda çalıştırmak ya da tek tek döşemeleri doğrulamak da düşünüldü, ancak prototip editörde kaotik bilye çarpışma düzenlerini kolayca üretmenin mümkün olduğu görüldü
    • Bilyeler engellenmeden düz çizgide hareket etmiyorsa öngörülemez makineler üretmek kolaylaşıyordu
  • Makinenin öngörülebilirliğini artırmak, oyuncu özgürlüğüyle çelişiyordu
    • Sıkışık geliştirme takvimi de daha az tahmin/simülasyon gerektiren yaklaşımı tercih etmelerine yol açtı
  • Son derece deterministik olmayan ya da bozuk makineler dahil, oyunculara çok esnek bir üretim özgürlüğü vermeye karar verdiler
    • Kısıtların karşılanıp karşılanmadığını denetlemek ve uygunsuz içeriği kaldırmak için aktif moderasyon gerekiyordu

2. Uyumlu ve değiştirilebilir makineleri teşvik eden katı kısıtlar sağlamak

  • Moderasyon gerekliliği ve öngörülemez oyuncu makineleri, tersine daha fazla düzen ihtiyacını doğurdu
  • Başta giriş/çıkışları tamamen serbest biçimli düşünmüşlerdi, ancak moderasyon sürecinde ilk döşemelerin değiştirilmesinin büyük çaplı arızalara yol açabileceğini fark ettiler
  • Aynı döşeme alanında birden fazla oyuncunun uyumlu tasarımlar yapabilmesi için yeterince güçlü kısıtlar tasarlandı
    • Robustness ilkesi uygulandı: "Gönderdiğinde tutucu ol, aldığında hoşgörülü ol"
  • Giriş/çıkış kısıtları koyabilmek için baştan tüm makine haritasına ihtiyaç vardı
    • Harita üretimiyle makinenin zorluk seviyesi ayarlanabildi (basit 1 giriş 1 çıkıştan karmaşık 4 giriş 4 çıkış birleşmelerine kadar)
  • Gerçek zamanlı geri bildirim vermek için döşemelerin aldıklarına yakın bir hızda bilye çıkarması şart koşuldu
    • Bilyeleri yutan ya da geciktiren makineler kısıtlandı
    • Döşemeler rastgele giriş hızlarıyla kaos testine tabi tutuldu
  • "Makineyi bir süre çalıştır ve ortalamada kısıtları karşılayıp karşılamadığını kontrol et" ilkesi benimsendi

3. Makine ilk 30 saniye içinde kararlı duruma ulaşmalı

  • Moderatörün ne kadar süre izlemesi gerektiği sorusu ortaya çıktı
    • Tüm makinenin moderasyon süresini hesapladılar (10 bin döşeme için 83,3 saat)
    • 30 saniye içinde kararlı duruma geçmesi yönünde keyfi bir karar aldılar
  • Bilyelerin 30 saniye sonra kaybolması sağlandı
    • Başta zaman aşımı yoktu, bu yüzden oyuncular oyunu öğrenirken bilyeler birikiyor ve ekranı dolduruyordu
    • Etkin rigid body sayısı arttıkça fizik simülasyonu yavaşlıyordu
    • Bilyeler eğlenceden çok engel hâline geliyordu
  • Bilye süre sonu sayesinde makine zamanla hata biriktirmez oldu
    • Moderatör yalnızca 30 saniye izleyerek çoğu bilyenin nereye gidebileceğini anlayabiliyordu

Simülasyon ve hipergerçeklik

  • Machine mimarisindeki iki büyük zorluk:
    1. Yukarıdaki tasarım kısıtlarıyla farklı döşemeleri birbirine bağlayıp bütün bir makine oluşturmak işe yarayacak mı?
      • Bunu doğrulamak için birkaç küçük harita üretip çözdüler
    2. Devasa makineyi sunucuda ya da istemcide gerçek zamanlı çalıştırmak mümkün değilse, bunu nasıl gösterecekler?

Kaydırırken tek bir bilyeyi takip etmeyi mümkün kılmak hedefleniyordu

  • Tüm makine simüle edilmese bile, oyuncunun gördüğü alanın çevresi simüle edilmeliydi
  • Başta sonsuz haritada yalnızca görünen alanı simüle etmeyi denediler
    • Oldukça iyi çalıştı, ancak kaydırma sırasında döşemeler simülasyona boş başlangıç durumuyla giriyor ve akışta boşluklar oluşuyordu
  • Boş döşemeler yerine, sanki hâlihazırda etkinlik varmış gibi görünmesi gerekiyordu

İkinci zorluk: döşemelerin anlık görüntüsünü yalnızca kararlı duruma ulaştıktan sonra almak ve bunların yalnızca kaydırmayla görünmeden hemen önce var olmasını sağlamak

  • Son çizgi romanda görüntü kırpmayı kapatılmış görünüm (CSS overflow:hidden, contain:paint devre dışı):
    • Anlık görüntüleri fark ettiniz mi? Özellikle dikkat etmezseniz fark etmek zor
    • Yalnızca render edilen döşemeler fizik simülasyonunda gerçekten var
    • Görüntü optimizasyonu: Sadece görünüm alanındaki bilyeler gösteriliyor, ama simülasyon tüm döşeme aralığında yürütülüyor
    • Makinenin üst kısmını taklit etmek için simülasyonun en üst satırında bilyeler oluşturulup besleniyor (giriş kısıtlarının beklenen hızına göre)
  • Moderasyon UI'ına anlık görüntü oluşturma eklendi
    • Moderatör, bir döşemeyi onaylamadan önce en az 30 saniye beklemek zorunda
    • Onay düğmesine basıldığında anlık görüntü oluşturuluyor
    • Moderatör isterse makine iyi görünene kadar biraz daha bekleyebiliyor
  • Anlık görüntü yaklaşımı beklenenden de iyi çalıştı
    • Makinede biriken hataları sıfırlamak gibi olumlu bir etkisi oldu
    • Kaydırırken görülen döşemelerin ilk izlenimi, moderatörün beğendiği temiz ve iyi bir durum oluyor
    • Gerçekte uzun süre izlendiğinde birçok makine bozulabiliyor ya da dağıtabiliyor, ancak keşfetmeye devam ettikçe yeni anlık görüntülere girildiğinden bunu görmek gerekmiyor
  • Çizgi romandaki kaydırılan makine gerçek değil. Hipergerçek
    • Tümü aynı anda simüle edilmiyor, ama bu aslında daha iyi bir sonuç veriyor

React ve DOM ile binlerce bilye render etmek

  • Rapier fizik motoru üzerine kuruldu
    • Güçlü dokümantasyonu, kullanışlı temel yapı taşları için temiz API'si ve Rust implementasyonu (tarayıcıda WASM olarak çalışıyor) sayesinde etkileyici performans sundu
    • Başta Rapier'in determinizm garantisi cazip gelmişti, ancak sunucu tarafı simülasyon yapılmadı
  • Rapier üstüne özel bir React context olan <PhysicsContext> yazıldı
    • Rapier fizik nesnelerini oluşturup React component lifecycle içinde yönetti
    • Fizik ya da çarpışma yüzeyi olan, yerleştirilebilir her nesne için "widget" component'leri geliştirmeyi kolaylaştırdı
    • React burada basit ve kirli bir scene graph görevi gördü
    • Görünüm kaydırılırken döşeme yükleme/boşaltma basitleşti: bir döşeme unmount edildiğinde tüm fizik ve DOM temizleniyor
    • Bonus olarak hot reloading'i fast refresh'e bağlamak kolaylaştı (çarpışma şekillerini ayarlamak için gerçekten çok iyiydi)
  • React context yaklaşımının bir başka avantajı:
    • Fizik hook'ları <PhysicsContext> içinde değilse noop oluyor
    • Bu sayede moderasyon UI'ında statik döşeme önizlemeleri render etmekte kullanılabildi
  • Rapier nesnelerini oluşturmak için hook yerine component kullanmış olmayı isterdi (react-three-rapierın yaptığı yaklaşım)
    • React diffing ile daha iyi uyuşuyor (bağımlılıklar değiştiğinde useEffect, önceki instance'ı kaldırıp yeniden oluşturuyor)
  • Machine tamamen DOM kullanılarak render edildi
    • Geliştirmenin başlarında performans açısından DOM render etmenin sınırlarına dayanma endişesi vardı
    • Fazla yavaşlarsa PixiJS ya da canvas'a geçmeleri bekleniyordu, ancak DOM ile ne kadar ileri gidilebileceğini görmek istediler
  • Render performansı optimizasyonu:
    • Frame loop, fizik simülasyonu olan widget'lara doğrudan stil uyguluyor
      • React'in diff işlemi yalnızca scene graph üzerinde yapısal değişiklik olduğunda çalışıyor
    • Başta bilyeleri React ile

1 yorum

 
GN⁺ 2024-05-09
Hacker News yorumu

Çeşitli yorumlar bir araya getirildiğinde, özetle şu içerik ortaya çıkıyor:

  • XKCD'nin 1 Nisan şakası etkinliği olan "The Incredible Machine", 1 Nisan boyunca süren işbirlikçi bir bulmaca oyunuydu
    • Kullanıcılar, fizik motoruyla uygulanmış makine öğelerini kullanarak bulmacaları çözebiliyor, ayrıca kendi bulmacalarını hazırlayıp gönderebiliyordu
    • Ancak ilerleyiş biçimine dair açıklamalar yetersiz olduğu için ne olduğunu tam anlayamayan kullanıcıların da epey fazla olduğu görülüyor
  • Bulmaca oyununun biçimi, eski bir DOS oyunu olan "The Incredible Machine" ile benzerlik taşıyor
    • Sınırlı sayıdaki makine parçalarını kullanarak belirli bir hedefe ulaşma mantığına dayanıyor
  • Geliştirme sürecinde Rapier fizik motoru kullanıldı, ancak özyinelemeli bir hata nedeniyle çökmeler de yaşandı
  • Etkinlik bittikten sonra da kişinin hazırladığı bulmacayı paylaşabileceği bir kalıcı bağlantı özelliğinin iyi olacağı yönünde görüşler dile getirildi
    • Depolama alanı sorunu nedeniyle zor olabilir; bu yüzden JSON'u Base64 ile kodlayıp URL parametresi olarak aktarma yöntemi önerildi
  • Sadece 3 haftada bu ölçekte bir projeyi tamamlamış olmak, etkileyici bir başarı olarak değerlendiriliyor
  • XKCD'nin Randall Munroe adlı tek bir kişi tarafından yürütüldüğü sanılıyordu, ancak birden fazla kişinin dahil olmuş gibi görünmesi bazılarında şaşkınlık yarattı
  • Etkinliğe dair daha ayrıntılı bilgiler Reddit, Explain XKCD, Github deposu gibi yerlerde bulunabilir