- 1999 yapımı RollerCoaster Tycoon, neredeyse tamamen assembly diliyle yazılmış bir simülasyon oyunu olarak, binlerce konuğu gerçek zamanlı işlerken bile istikrarlı performansı korudu
- Geliştirici Chris Sawyer, yüksek seviyeli diller yerine düşük seviyeli kontrolü seçerek CPU işlem verimliliğini en üst düzeye çıkaran son nesil assembly oyunlardan birini ortaya koydu
- Hayran projesi OpenRCT2 sayesinde, orijinal oyunun ince ayarlı optimizasyon kalıpları ve bellek tasarrufu teknikleri tersine mühendislikle analiz edildi
- Oyun, bit kaydırma işlemleri ve veri türlerinin ayrıntılı şekilde bölünmesi ile işlem hızını ve önbellek verimliliğini artırırken, yol bulma derinliği sınırlaması ve çarpışma hesaplarını kaldırma sayesinde büyük ölçekli simülasyonu mümkün kıldı
- Bu yapı, teknik kısıtları yaratıcı biçimde kullanan bir optimizasyon klasiği olarak, bugün bile tasarım aşamasında gereksiz hesaplamaları ortadan kaldıran yaklaşımın önemini gösteriyor
RollerCoaster Tycoon’un optimizasyon yapısının analizi
- 1999’da çıkan RollerCoaster Tycoon(RCT), neredeyse tamamen assembly (Assembly) ile yazılmış; binlerce ajanı gerçek zamanlı simüle ederken dönemin donanımında istikrarlı kare hızları koruyabilen bir oyun olarak değerlendiriliyor
- Alman oyun podcast’i Stay Forever’da ele alınan içerik temel alınarak, Chris Sawyer’ın nasıl bu kadar uç seviyede optimizasyon elde ettiği somut biçimde inceleniyor
- Orijinal kaynak kodu yayımlanmış değil, ancak hayranların geliştirdiği OpenRCT2 projesi üzerinden kod yapısı ve optimizasyon teknikleri tersine mühendislikle doğrulanabiliyor
-
Assembly tabanlı performans maksimizasyonu
- RCT, C ya da C++ yerine assembly ile yazıldığı için, dönemin diğer oyunlarına göre çok daha ayrıntılı performans kontrolü sağlıyordu
- Örneğin Doom (1993) büyük ölçüde C ile yazılmışken, RCT neredeyse tamamen assembly ile gerçekleştirildi
- Bu yaklaşım 1990’ların sonlarında zaten nadir hale gelmişti ve RCT, son büyük assembly oyunlarından biri olarak görülüyor
- O dönemde derleyicilerin otomatik optimizasyonu sınırlı olduğundan, elle optimizasyon performansta büyük fark yaratıyordu
-
OpenRCT2 üzerinden kod analizi
- OpenRCT2, hayranların orijinal oyunu tamamen yeniden uyguladığı bir açık kaynak proje; orijinal varlıkları aynen kullanırken %100 uyumluluğu koruyor
- İlk sürümler, orijinal kodla neredeyse aynı davranışı yeniden üretiyordu; daha sonra çeşitli iyileştirmeler eklendi
- Bu proje sayesinde orijinal koddaki ince ayarlı optimizasyon kalıpları görülebildi
-
Veri türlerinin ayrıntılı bölünmesi — bellek tasarrufu
- RCT, para verisinin boyutunu duruma göre farklı şekilde saklıyor
- Örnek: toplam park değeri için 4 baytlık değişken, dükkân fiyatı için 1 baytlık değişken kullanılıyor
- Bu ayrım, bellek tasarrufu ve önbellek verimliliğini artırmak içindi; modern CPU’larda performans farkı neredeyse kalmadığından OpenRCT2’de tek tip 8 baytlık değişkenle birleştirildi
-
Bit kaydırma ile matematiksel işlem optimizasyonu
- Kodda
NewValue = OldValue > işlemi, 2’nin kuvvetlerine bölme işleminin yerine kullanılıyor
- Bu tür optimizasyonlar yalnızca çarpma/bölme 2’nin kuvveti olduğunda mümkün olduğundan, oyundaki formüllerin de bu koşula göre tasarlandığı anlaşılıyor
- Yani CPU işlem verimliliğini gözeten matematiksel yapı, daha oyun tasarımı aşamasında kurulmuş
-
Performansı gözeten oyun tasarımı
- RCT’de Chris Sawyer hem programcı hem de tek oyun tasarımcısı olduğu için, performansı tasarım aşamasından itibaren hesaba katan bir yapı kurabildi
- Bunun en temsilî örneği konuk (Pathfinding) sistemi
- Çoğu simülasyon oyununda konuklar hedef belirleyip rota ararken, RCT’de konuklar rastgele dolaşıp tesadüfen bir eğlence aracını keşfediyor
- Bu yöntem, büyük ölçekli yol bulma hesaplarını baştan kaçınan bir yapı sunduğu için binlerce konuğun aynı anda işlenmesini mümkün kılıyor
- Yol bulmanın gerekli olduğu durumlarda (ör. bakım görevlisinin arızalı bir eğlence aracına gitmesi) arama derinliği sınırı uygulanarak kare hızı düşüşü önleniyor
- Normal konuklar yalnızca 5 kavşağa kadar arama yapıyor, bakım görevlileri ise 8’e kadar
- Harita satın alan konuklarda arama sınırı 7’ye çıkıyor
- Bu sınırlar, basit bir teknik taviz değil; oynanış öğelerine doğal biçimde entegre edilmiş bir optimizasyon yapısı
-
Kalabalık işleme ve çarpışmadan kaçınmanın atlanması
- RCT, konuklar arası çarpışma ya da kaçınma hesaplarını tamamen kaldırıyor
- Binlerce konuk aynı yol karesini paylaşabiliyor
- Bunun yerine çevredeki nüfus yoğunluğu izleniyor ve kalabalık arttığında konuğun mutluluğu düşecek şekilde tasarlanıyor
- Böylece oyuncu yine kalabalığı yönetmek zorunda kalıyor, ama hesaplama yükü çok daha düşük oluyor
- Bu yaklaşım, karmaşık fizik hesaplarını kaldırırken oyun deneyimini koruyan tipik bir örnek olarak değerlendiriliyor
-
Modern geliştirmeye verdiği mesajlar
- RCT’nin optimizasyonu, teknik kısıtları yaratıcı biçimde kullanan bir örnek olarak görülüyor
- Bugün de benzer bir yaklaşım mümkün, ancak programcılarla tasarımcılar arasında sıkı işbirliği gerekiyor
- Bazen teknik bir problemi çözmeye çalışmak yerine, problemin kendisini tasarım aşamasında ortadan kaldırmak çok daha büyük performans kazanımı sağlayabiliyor
2 yorum
Lütfen RollerCoaster Tycoon'u çok sevin.
Hacker News yorumları
Warcraft 1, 2 ve StarCraft'ın hepsi 2'nin kuvveti olan birim harita boyutları kullanıyordu
Bu sayede yavaş 386/486 CPU'larda bölme ve çarpma yerine shift işlemleriyle hız kazanılabiliyordu
Harita render etme, sprite'lar, fontlar, sis efektleri gibi şeyler binlerce satır assembly ile işleniyordu; geri kalanı ise C ile yazılmış, taşınabilirliği yüksek koddu
Blackthorne örneğinde SNES, Genesis ve DOS sürümleri ayrı ayrı farklı assembly ile elle port edilmişti; PC sürümünde ise VGA Mode X için 100 bin satırlık render kodu makrolarla üretilmişti
Bu deneyimler sayesinde Blizzard, “assembly çok fazla geliştirme süresi yiyor” dersini çıkardı
Comanche: Maximum Overkill ise tamamı assembly ile yazılmış voksel tabanlı bir helikopter simülatörüydü; korumalı moda port etmesi çok zor olduğu için sonraki sürümlerde poligon render etmeye geçildi
EA, Command & Conquer serisinin kaynak kodlarını yayımladı ama Tiberian Sun ve Red Alert 2 dahil değildi
Keşke StarCraft da tarihsel koruma açısından yayımlansaydı
O andan itibaren oyunlara tamamen kapıldım
Acaba demoscene tarafında da yer almış mıydı, merak ediyorum
Ben WC3 çıkışı civarında kısa süreli danışman olarak bulunmuştum
Yazıda da geçtiği gibi, tasarımcı ve programcının aynı kişi olduğu durumlarda ortaya çok daha etkileyici işler çıkıyor gibi görünüyor
Büyük şirketlerin hiyerarşik yapısında da sonuçta yeterince insan yüklenince bir şeyler ortaya çıkıyor, ama gerçekten yaratıcı sonuçlar çoğu zaman tek bir kişinin zihninde bütünleşiyor
Yapay zeka geliştirme araçlarının geleceği de belki böyle bir ‘tek kişilik geliştirme çağına’ dönüş olabilir
Oyun tasarımcılarının hâlâ sayısal özellikleri dikkate alması gerekiyor
İyi tasarımcılar, işlem verimliliği ya da hassasiyet gibi etkenlerin oyun dengesini etkilediğini bilir
Bugün bunları görmezden gelen çok geliştirici var ama bu da oyun kalitesindeki düşüşün gizli nedenlerinden biri olabiliyor
Bugün toplama yaklaşık 1 cycle, çarpma 3 cycle, bölme 12 cycle civarında; üstelik birden fazla işlem aynı anda paralel yürütülebiliyor
Eski Pentium döneminde bu 46 cycle sürüyordu ve saat hızı da 100MHz'ti
Günümüzde bellek yerleşimi çok daha önemli — tek bir cache miss 100 ila 1000 cycle kaybettirebilir
int[]üzerinde işlem yapmak,Monster[]'dan çok daha hızlıdırHız, doğruluk, depolama boyutu ve karmaşıklık arasında ödünleşimler var
Toward an API for the Real Numbers gibi makaleler, bu tür sorunları aşamalı olarak çözmeye çalışan yaklaşımlar sunuyor
Kayan nokta hataları, interval arithmetic, sembolik işlemler gibi farklı yöntemler var ama sonuçta ödünleşimleri anlamazsanız sorun sizi yakalar
Örneğin Fumito Ueda, 『Shadow of the Colossus』'ta teknik uygulanabilirliği dikkatle değerlendirmişti; Doom da yaratıcılık ile tekniğin birleşimiydi
İlgili röportaja bakılabilir
Bug, hikâye tutarlılığı ve sürükleyicilik daha önemlidir
Elbette frame drop fazlaysa kalite düşer, ama hedef donanımda akıcı çalışıyorsa iyileştirme başka alanlara odaklanmalıdır
Thumb-2 komutlarıyla sabitleri anında yükleyebilecek şekilde ayarlayıp bellek stall'larını önlemiştim
Bu sayede rastgele sayılar hızlı ve verimli şekilde kullanılabiliyordu ve tüm testleri geçmişti
Ama daha sonra Cortex-M0'a geçilince bu kod kaldırıldı
Teknik kısıtları oyun mekaniğine dönüştürme kısmı ilginçti
『The Legend of Zelda』daki Blood Moon sistemi aklıma geldi
“/8 yerine >>3 kullanırsan bölmeden tasarruf edersin” açıklaması modern derleyiciler için doğru değil
Türler uygunsa derleyici bunu zaten otomatik olarak shift işlemine optimize eder
“İkilik sistemde sola shift etmek sayıyı iki katına çıkarır” açıklamasını görünce şaşırdım
2026'da böyle temel bir kavramın yeniden yabancı gelmesi gerçekten ilginç
“Derleyici 2'nin kuvvetiyle çarpmayı shift'e dönüştürmez” sözü eski bir şaka
2000'lerde bile derleyiciler bu tür kodları görünce esneyecek kadar bunu zaten doğal olarak optimize ediyordu
Keyifle okudum. RCT ile ilgili olarak şu kaynakları da öneririm
Büyük stüdyolarda teknik kısıtları oyunun karakteristik özelliğine dönüştürmenin mümkün olup olmadığını merak ediyorum
Hikâye anlatımında engellerin anlatıyı ilginç kılması gibi, tek kişilik geliştiriciler de teknik sınırlamaları yaratıcı unsurlara çevirebilir
Örneğin bug ya da glitch'leri bir mini oyun olarak yeniden yorumlamak gibi yaklaşımlar akla geliyor
RCT'nin pathfinding kısmını görünce Marcel Vos'un YouTube videosu aklıma geldi
RCT'nin iç işleyişini derinlemesine inceleyen pek çok video yüklüyor