JavaScript oyun motorunu sebepsiz yere C'ye taşımak
(phoboslab.org)- 2010 tarihli JavaScript motoru Impact'in yapısını yeniden canlandıran high_impact, 2D aksiyon oyunları için bir C motoru ve Windows, Mac, Linux ile Web için WASM desteği sunuyor
- Impact, iOS'un Flash'ı dışlama akımı içinde Canvas2D ile de web oyunu yapılabildiğini göstermek için oluşturulmuş bir motor; $99 ücretle satılıp 3.000'den fazla lisans sattıktan sonra ücretsiz açık kaynak olarak yayımlandı
- Yeni motor; karo haritası, varlıklar, fizik·çarpışma, sprite animasyonu, metin ve sesi bir araya getiren küçük bir framework ve SDL ya da Sokol backend'i kullanıyor
- Uygulama; sabit boyutlu varlık deposu, QOI/QOA varlıkları, tek bir hunk belleği, OpenGL·yazılım renderer'ı ve JavaScript tabanlı Weltmeister seviye editörüyle sadeliği koruyor
- Biolab Disaster ve Drop, mevcut JS kaynak koduna yakın biçimde taşınıp çalıştırılabildi; platform ve renderer genişletmeleriyle farklı sistemlere yayılabiliyor
high_impact'e genel bakış
- high_impact, 2D aksiyon oyunları için küçük bir oyun motoru
- C ile yazıldı ve Windows, Mac, Linux, Web için WASM olarak derleniyor
- 2010'daki JavaScript oyun motoru Impact'ten ilham alıyor; adı da C'nin yüksek seviyeli bir dil sayıldığı döneme gönderme yapıyor
- MIT lisansıyla yayımlandı ve kaynak kodu GitHub'da yer alıyor
Impact'in ortaya çıkış arka planı
- Nisan 2010'da Steve Jobs, iOS'ta Flash'ı desteklemeyeceğini açıklayan "Thoughts on Flash" adlı açık mektubu yayımladı
- O dönemde Flash, tarayıcı eklentisi tabanlı web oyunları ve animasyon kültürünün merkeziydi; Newgrounds ve Kongregate gibi siteler Flash içeriklerine büyük ölçüde bağımlıydı
- Android'in Flash desteği sorunluydu ve Adobe'nin de mobildeki dezavantajları gidermeye yönelik ciddi bir çaba göstermediği değerlendiriliyordu
- "Flash yoksa tarayıcı oyunu da yok" algısı vardı; ancak Canvas2D API
<canvas>üzerinde görsel ve şekil çizebiliyordu - Canvas2D, Apple/Safari tarafından masaüstü widget'larını render etmek için geliştirildi; daha sonra Google ve Mozilla tarafından desteklendi, Microsoft'un Internet Explorer'ı ise geride kaldı
- Bu akış içinde Biolab Disaster üretildi ve bunun için oyun motoru ile seviye editörü de birlikte geliştirildi
Impact'in satışı ve kullanım örnekleri
- Impact, kod temizliği ve dokümantasyonun ardından $99 fiyatla satışa çıktı; ücretli satış kararına tepki gösterenler oldu ama sonuçta 3.000'den fazla lisans satıldı
- Impact ile birçok web oyunu yapıldı ve ticari çapraz platform yapımlarda da kullanıldı
- Yaşam döngüsünün son döneminde Impact ücretsiz açık kaynak olarak yayımlandı
- high_impact, Impact'i bu kez JavaScript yerine C ile sıfırdan yeniden yapan bir proje
Neden C?
- C, basit ama derinliği olan bir dil ve bu yönüyle "öğrenmesi kolay, ustalaşması zor" oyunlara benziyor
- Çeşitli projeler üzerinden C'ye olan ilgi zamanla yeniden güçlendi
- Aslında Impact, Godot, Unreal, Unity gibi motorlarla aynı ölçekte değildi; ama birçok oyun için sağlam bir temel olarak çalıştı
- Impact'i C ile yeniden yazmak da keyifli bir egzersiz olarak başladı
Motor yapısı ve varlıklar
- high_impact olabildiğince basit biçimde uygulandı ve mümkün olduğunca az kodla kurulması hedeflendi
- Temel işlevler, özgün JavaScript motoruyla aynı
- Karo haritası yükleme
- Oyun nesneleri olan varlıkları oluşturma·güncelleme·çizme
- Varlıklar arası fizik ve çarpışma işleme
- Çarpışma haritasıyla çarpışma işleme
- Sprite sheet animasyonu
- Metin çıktısı
- Efekt sesi ve müzik çalma
- Bir kütüphaneden çok framework yapısına yakın; oyun mantığı framework'ün içinde yazılıyor
- En altta bir
platformbackend'i bulunuyor ve şu anda SDL ya da Sokol ile derleniyor - Oyun kodu bir veya daha fazla "scene" içine yerleştiriliyor; scene, işlev işaretçileri barındıran bir struct
engine_set_scene(&scene_game)çağrısından sonra motor yeni scene'i ayarlıyorscene_game.init()bir kez çağrılıyorscene_game.update()vescene_game.draw()her karede çağrılıyor
- Karo haritası ve başlangıç varlıkları
.jsondosyalarından yüklenebiliyor ya da dinamik olarak oluşturulabiliyor - Seviye formatı olarak JSON seçilmesinin nedeni, özgün Impact ile geriye dönük uyumluluk sağlamak
- high_impact, görseller için QOI; ses ve müzik için QOA kullanıyor
- Demo oyunun Makefile'ı PNG'yi otomatik olarak QOI'ye, WAV'ı da QOA'ya dönüştürüyor
- Böylece ayrı görsel·ses kod çözücü kütüphanelerini eklemeye gerek kalmıyor
- İleride başka varlık formatları da desteklenebilir; ancak QOI/QOA'nın sadeliği proje yönüyle iyi örtüşüyor
Varlık sistemi
- Tüm varlıklar; konum, hız, boyut gibi high_impact'in ihtiyaç duyduğu özellikleri içeren aynı
entity_t structyapısını paylaşıyor - Tüm varlıkların bayt boyutu aynı olduğu için depolama ve yönetim basitleşiyor
- Bir varlığı hareket ettirmek için hız ya da ivme ayarlanıyor, geri kalanını motor hallediyor
- Makrolarla temel varlık struct'ına oyuna özel özellikler eklenebiliyor
- Biolab Disaster, varlık türlerine özel struct'lar içeren bir
unionkullanıyor - Drop ise ek özellik tanımlamaya ihtiyaç duymuyor
- Biolab Disaster, varlık türlerine özel struct'lar içeren bir
- Her varlık türünün, işlev işaretçileri sağlayan bir
entity_vtab_tsunması gerekiyorupdateher karede çağrılıyortouch, koşulları sağlayan başka bir varlıkla çakışıldığında çağrılıyor- Tüm girdiler isteğe bağlı
- Varlık deposu sabit boyutlu
- Varsayılan etkin varlık sayısı 1.024
ENTITIES_MAXtanımıyla değiştirilebiliyor- Motor, 64k varlığa kadar rahatça işleyebiliyor
- Bir kareden uzun süre varlık referansı tutmak için
entity_ref_tkullanılıyorentity_ref_t,uint16_t idveindexalanlarına sahip bir structentity_by_ref()ile yeniden işaretçiye çözümlenebiliyor- Aynı depo adresine farklı bir varlığın gelip gelmediği ayırt edilebiliyor
uint16_tindeks nedeniyle etkin varlık üst sınırı 64k ile sınırlı
- C'de basit OOP, sınıflar ve tekli kalıtım benzeri yapıları kurmak biraz tuhaf olsa da high_impact bunu olabildiğince rahat hale getirmeye çalışıyor
- Varlık mantığını türe göre tek bir yerde toplama şeklindeki "naif" OOP yaklaşımı, şimdiye kadar yapılan oyunlarda hem anlaşılır oldu hem de iyi çalıştı
Çarpışma algılama ve tepki
- Basit çarpışma işleme, yalnızca yeni konuma gidilip gidilemeyeceğini kontrol edip gidilemiyorsa durdurma yaklaşımını kullanır; ancak hızlı nesnelerde garip davranışlar ortaya çıkabilir
- 2D platform oyununda oyuncu yerden 16px yukarıdaysa ve bir sonraki harekette zeminin içine girecekse, havada durup sonraki karede yeniden aşağı inmesi yumuşak iniş gibi görünebilir
- high_impact, varlık kutusunu karo haritası üzerinde izleyerek tam çarpışma noktasını hesaplıyor
- Bu yöntem, basit evet/hayır testinden daha karmaşık ama sonuçları daha iyi ve eğimli karoları da işleyebiliyor
- Karoya çarptıktan sonra kalan hızla ikinci bir izleme gerekebiliyor
- Örneğin zemine çapraz çarpıldığında
vel.ydeğeri0olurkenvel.xkorunuyor ve nesne zeminde kayabiliyor
- Örneğin zemine çapraz çarpıldığında
- Varlıklar arası çarpışmalar ayrı ele alınıyor
- Parçacıklar karo haritasıyla çarpışabilir ama diğer varlıklarla çarpışmayacak şekilde ayarlanabilir
- Hareketli platformlar diğer varlıklarla çarpışabilir ama çarpışma tepkisiyle hareket ettirilmemelidir
- Broad phase çarpışma algılama, varlıkları
pos.xdeğerine göre sıralıyor- Önceki kareden ötürü çoğu zaten büyük ölçüde sıralı olduğundan insertion sort maliyeti düşük kalıyor
- Sıralamadan sonra soldan sağa taranıyor ve yalnızca
pos.xilepos.x + size.xarasındaki varlıklar kontrol ediliyor
- Bu sweep and prune yöntemi, benzer x konumlarında çok sayıda varlık üst üste gelmediği sürece hızlı çalışıyor
- Kutu yığınları gibi çok sayıda varlığın aynı x konumunda toplandığı senaryolar en kötü durumu oluşturuyor
- Dikey shoot'em up gibi başka eksenin daha uygun olduğu durumlarda
#define ENTITY_SWEEP_AXIS yile sweep ekseni değiştirilebiliyor
Render
- high_impact şu anda bir OpenGL renderer'ı ve tamamlanmamış bir yazılım renderer'ı içeriyor
- Tüm render işlemleri çok ince bir API üzerinden geçiyor ve gerçek çizim çağrıları tek bir işlevde toplandığı için başka backend'leri uygulamak görece kolay
- Ek render backend'lerinin desteklemesi gereken temel işlevler; başlatma, kapatma, ekran boyutunu ayarlama, kareyi hazırlama·bitirme ve quad çizme
- Doku işlemleri için mark, reset ve create işlevleri de gerekiyor
- Özellik seti basit; yalnızca quad çizilebiliyor ve shader efektleri kullanılamıyor, ama motorun amacı için yeterli
- Yazılım renderer'ı 140 satırlık koddan oluşuyor ve yalnızca eksenlere hizalı quad'ları destekliyor
- OpenGL renderer'ı, bir kareyi tek bir OpenGL draw call içine sığdırmaya çalışıyor
- Tüm quad'lar büyük bir buffer'da toplanıp
glDrawElements()ile tek seferde gönderiliyor - Tüm dokular tek bir texture atlas içinde birleştirilerek texture yeniden bağlama işlemlerinden kaçınılıyor
- Tüm quad'lar büyük bir buffer'da toplanıp
- Texture atlas eski bir yaklaşım ve bazı dezavantajları var; ama bindless texture her yerde desteklenmediği için tercih ediliyor
- high_impact yalnızca tek bir texture atlas destekliyor; ancak boyutu
#defineile ayarlanabiliyor- Mobil GPU'lar genelde 8k×8k doku destekliyor
- Modern masaüstü GPU'ların 32k×32k'ye kadar destek sunduğu görülüyor
- Biolab Disaster ve Drop, 512×512 atlas kullanıyor
Ses
- Ses çıkışı SDL2 veya Sokol tarafından ele alınıyor; motor ise yükleme·kod çözme ve birden çok sesi karıştırma işini yapıyor
- Ses sistemi, örnekleri tutan
sound_source_tile o anda çalan sesi temsil edensound_tolarak ikiye ayrılıyor - Bu sistem, wipEout yeniden yazımı sırasında geliştirilen sisteme dayanıyor ve QOA verisini ihtiyaç anında açabiliyor
- Her şey statik olarak ayrılıyor
- Yüklenebilecek source sayısı sabit
- Aynı anda çalabilecek sound sayısı sabit
- Çalması biten sound'lar otomatik atılıp yeniden kullanılıyor
- Seslerde ses seviyesi, sağ-sol pan ve pitch değiştirilebiliyor
- Pitch değeri negatif verilirse ses tersten çalıyor
- Değişken pitch için gereken yeniden örnekleme, en yakın komşu enterpolasyonu kullanan düşük kaliteli bir yöntemle yapılıyor
Bellek yönetimi
- high_impact, oyun kullanıcı tarafından oluşturulan varlıklar içermediği sürece ihtiyaç duyulan bellek miktarının tam olarak bilinebileceğini varsayıyor
- Motor, "hunk" adı verilen tek bir bayt dizisini statik olarak ayırıyor ve high_impact'in kullandığı bellek bununla sınırlı
- Hunk boyutu
#define ALLOC_SIZEile ayarlanabiliyor - Hunk içinde bellek iki yöntemle ayrılıyor
- Önden yukarı doğru büyüyen bir bump allocator ya da arena, oyun varlıklarını·varlıkları·mevcut scene verisini tutuyor
- Sondan aşağı doğru büyüyen geçici allocator ise
malloc()vefree()gibi çalışıyor; örneğin görseli açtıktan sonra GPU'ya göndermeden önce geçici depolama için kullanılıyor
- Bump allocator birden fazla "high water mark" tutuyor ve belirli anlarda otomatik geri sarabiliyor
- Bump ile ayrılan belleği açıkça
free()etmek gerekmiyor - Kavramsal yaşam süresi
game,scene,frameolarak ayrılıyor- İlk scene ayarlanmadan önce ayrılanlar yalnızca program kapanırken serbest bırakılıyor
scene.load()sırasında ayrılanlar scene sona erdiğinde serbest bırakılıyor- Scene çalışırken ayrılanlar karenin sonunda serbest bırakılıyor
- Varlık türüne özel
load()işlevleri, bir scene'de hangi varlığın kullanılacağının önceden bilinmemesi nedeniyle 1. aşamada çağrılıyor - Ek ayırma bağlamları
alloc_pool()ile sarılabiliyor; bu, içerdebump_mark()ilebump_reset(mark)için kısa bir kullanım sağlıyor
Weltmeister seviye editörü
- Özgün Impact'te Weltmeister adlı bir seviye editörü vardı ve high_impact buna da yer veriyor
- Hâlâ JavaScript ile yazılmış durumda ve özgün kaynak kodun büyük kısmını kullanıyor; ancak modern tarayıcı özelliklerine uygun olacak şekilde güncellendi
- Weltmeister tamamen bağımsız çalışıyor
- Seviye yapımına başlamak için
weltmeister.htmldosyasına çift tıklamak yeterli - Eskiden dosya yükleme·kaydetme için PHP veya NodeJS tabanlı bir backend API gerekiyordu
- Artık FileSystemAPI ile belirli bir klasöre erişim izni istenebiliyor
- Seviye yapımına başlamak için
- Safari ve Firefox, özellikle showDirectoryPicker() için henüz tam destek sunmadığından Chrome tabanlı bir tarayıcı gerekiyor
- Weltmeister, C kaynak dosyalarını okuyup varlık türlerini topluyor
- high_impact, editörün anlayabildiği ama C kodunda hiçbir şey yapmayan makrolar sunuyor
EDITOR_SIZE(X, Y): editördeki boyut, varsayılan(8, 8)EDITOR_RESIZE(RESIZE): editörde yeniden boyutlandırma izniEDITOR_COLOR(R, G, B): editörde kutu rengi, varsayılan(128, 255, 128)EDITOR_IGNORE(IGNORE): editörde oluşturulabilirlik durumu
Demo oyunlar
- high_impact'in gerçekten bir oyun motoru olarak çalışıp çalışmadığını doğrulamak için özgün Impact oyunlarından ikisi C'ye taşındı
- Taşıma işlemi, mevcut JS kaynak kodunu adeta bir "harf çevrimi" yapar gibi aktarmaya yakındı ve mevcut varlıklar yeniden kullanıldı
- Zorluğun az olması, high_impact'in amaçlandığı gibi çalıştığının göstergesi sayılabilir
-
Biolab Disaster
- Özgün Impact'in çıkış oyunuydu
- Yandan kaydırmalı bir Jump'n'Gun oyunu
- Kaynak kodu github.com/phoboslab/high_biolab adresinde
- Özgün JS sürümü playbiolab.com üzerinde sunuluyor
-
Drop
- Oldukça basit bir arcade oyunu
- Kaynak kodu github.com/phoboslab/high_drop adresinde
- Özgün JS sürümü impactjs.com/drop/ adresinde
- Mevcut en yüksek skor olarak 26789 Points gösteriliyor
Genişletilebilirlik
- high_impact, geleneksel oyun motorlarında olduğu gibi oyuna özel kodun ekleme odaklı yazıldığı bir yapıya sahip
- Motor kaynak kodunu değiştirmek gerekmeyebilir; ancak yapı yeterince basit tutulduğu için gerekirse motor kodunu doğrudan değiştirmek de mümkün
- Platform ve renderer katmanları, kodun geri kalanını değiştirmeden genişletilebilecek şekilde tasarlandı
- İlgilenenler için Vulkan, DirectX, Metal renderer'ları ile PSX, N64, Dreamcast gibi platform backend'leri desteği içeren pull request'ler memnuniyetle karşılanıyor
- C ile yazıldığı için her yerde çalışabilmesi hedefleniyor
1 yorum
Hacker News yorumları
Yaptığım programlama işlerinden en çok şey öğrendiklerimin önemli bir kısmı Impact sayesinde olmuştu.
Impact gerçekten zamanının çok ilerisindeydi ve 3000 lisans sahibinden biri olmakla gurur duyuyorum. Yaptığım en iyi satın almalardan biriydi; gerçekten baştan sona tamamladığım tek oyunu da Impact ile yapmıştım.
Lisansa kaynak kodun dahil olmasını sevmiştim; ihtiyacıma göre motoru ve editörü bizzat değiştirdim. Bunun etkisiyle birkaç yıl boyunca kendi JS oyun motorumu geliştirdim ama asıl oyunu bitirmeyi erteledim; yine de bu süreçte çok şey öğrendim ve game jam'ler için de çok sayıda oyun yaptım.
Impact'in yerel iOS desteği Ejecta'dan da ilham almıştım, ama o dönemde Android'de çalışmaması canımı sıkıyordu; bu yüzden motorumu webview olmadan Android'de çalıştırmak için V8'e yönelik JVM binding'leri yaptım ve WebGL'in bir kısmını uyguladım. Yayınladığım V8 binding deposu beklenmedik şekilde ticari yazılımlarda kullanılmaya başladı: https://github.com/namuol/jv8
Impact'in iş modelinden ilham alıp özel bir GitHub deposuna erişim satmaya dayalı, bootstrapped bir startup bile denedim; ama o hikâye uzar. Her neyse, Impact'in C portuyla “modern” web'e uygun şekilde güncellendiğini görmek içimi ısıtıyor ve hoşuma gidiyor. Web için tuhaf bir dönem demek isterdim ama web'in tuhaf olmadığı bir zamanı hatırlamıyorum.
CrossCode harika bir oyun. Web teknolojileri kullandığını biliyordum ve Nintendo Switch donanımında bu kadar iyi performans vermesi beni sürekli şaşırtmıştı.
Bu motorun da bunda bir ölçüde payı vardır diye düşünüyorum.
Bence bu, durumu daha da havalı kılıyor. Geliştiricinin motoru kendi oyununa göre değiştirebilmesi güzel; aynı şekilde high_impact de “özellikleri tamamlanmış” bir oyun motorundan ziyade kullanışlı bir başlangıç noktası olarak görülmeli.
İlginç bir anekdot olarak, herkes Switch sürümünü istiyordu ama teknik sınırlamalar nedeniyle ekip “Hedgehag'ler uçmayı öğrendiğinde CrossCode Switch'e çıkacak” diye yanıt vermişti: https://www.radicalfishgames.com/?p=6581
Sonunda port gerçekleştiğinde “A switch in attitude” adlı ek bir görev eklendi ve beklendiği gibi uçan hedgehag'ler ortaya çıktı: https://www.radicalfishgames.com/?p=6668
“Thoughts on Flash”, web platformunu en çok ihtiyaç duyduğu anda, yani tek bir yazılımın hâkimiyetinin yavaş yavaş büyüdüğü dönemde kurtarmış olabilir.
Bunun içinde, Windows'un çok daha büyük kullanıcı tabanına öncelik verdiği için MacOS desteğini ihmal ediyor gibi görünen Adobe'ye yönelik bir memnuniyetsizlik de vardı sanırım. Örneğin Mac sürümü her zaman Windows sürümünün gerisinde kalıyordu.
Jobs, Adobe'nin Apple'a katkıda bulunduğu kadar Apple'ın da Adobe'yi mümkün kıldığını hissetmiş olabilir; ama bu daha çok bir tahmin. Oyunun kendisi gerçekten çok pürüzsüz görünüyor.
Yalnız assembly'ye kadar yakın değil; daha derine inmeye iten yönde bazı şeyleri azaltıp sadeleştirmeye çalışıyorum.
Kurumsal iş hayatından çıkıp bir gün yan projelere ciddi biçimde dalmak isteyen biri olarak, ücretli hâle getirip kendi kendini döndürebilen kısmı daha fazla duymak isterim.
Normalde eğlence için yaptığım bir işten para alma fikri tuhaf biçimde yük gibi geliyor; ama bunun sevdiğim işi tam zamanlı yapmamı sağlayabileceğini de biliyorum.
Bu yüzden bu fikrin neden yük gibi geldiğini anlamak önemli. Yaygın nedenler arasında çevrendekilerin sık sık vazgeçirmesi, yapmak istediğin şeyi iyi uygulayacak beceriye sahip olmamak, yardım istemekten utanmak ya da karşı tarafa zahmet olacakmış gibi hissetmek, işinin değerlendirilmesinden korkmak, mevcut gelirin sağladığı “güvenliği” kaybetmek — özellikle bakmakla yükümlü olduğun kişiler varsa — sayılabilir.
Çoğu durumda bunlar çok iyi gerekçeler olmaktan ziyade, belli ölçüde yeniden ayar gerektiren ve bu yüzden “risk” gibi hissettiren şeylerdir; bu da konfor alanını terk etmeyi zorlaştırır. Böyle bir zihin yapısında her fırsat risk gibi görüneceği için gerçekten yapmak istediğin işe başlamak için uygun zamanı bulmak çok zorlaşır.
Bununla bağlantılı olarak, ilginç bulduğun işi yapıp dünyaya göstermek önemlidir; ama bunu geçimini sağlayan bir işe dönüştürmek bambaşka bir zorluktur. Çoğu insan sevdiği işi meslek hâline getiremez; getirse bile ödeme yapan müşterilerin beklentileri ve geliri sürdürme baskısı o sevgiyi elinden alabilir. Yapma demiyorum; sadece atlamadan önce bilinmesi iyi olacak bir nokta.
Neredeyse hiç kullanmadığım HN hesabıma giriş yapacak kadar, birkaç yıl önce Biolab Disaster'ı tekrar tekrar oynamıştım ama adını unutmuştum.
Tesadüfen yeniden bulmuş olmak epey acayip.
Normalde ben bunu çok daha olumsuz ifade ederdim. Çünkü “framework”ü yalnızca başka şeylerle pek iyi geçinemeyen bir kütüphane olarak görüyordum.
Yine de bu kadar ikna edici, olumlu bir ifade duymak hoş.
İhtiyacınız olan şeylerin %99’unu gerçekten iyi halleden, zengin ve iyi tasarlanmış bir framework kullanmak keyifliydi. Kendi kodumu eklemek de şimdiye kadar yaptığım geliştirmeler arasında en kolay olanlardan biriydi; öylece çalışıyordu. Sihir gibiydi, hâlâ özlüyorum.
Benim ideal framework anlayışım, içeride bir kütüphane ya da birlikte çalışan kütüphaneler bütünü olması ve framework niteliğinin mümkün olduğunca az olması.
Örneğin Qt bir framework’tür ve Qt “beni çağırır”; ama Qt olay döngüsünü başlatmadan ya da QObject üzerine derinlemesine düşünmeden de QPainter kodu çalıştırabilirsiniz. İdeal olarak, sinyaller ve slotları tamamen benimsemeden de olay döngüsünü kullanabilmek gerekir; yalnızca kullanım hissi o kadar iyi olmayabilir.
Bu her zaman mümkün değildir ve her zaman değmez de; ama diğer koşullar eşitse hiç framework olmamasını tercih ederim.
Oyun motorlarında bir miktar framework’e neden ihtiyaç duyulduğunu anlıyorum. Telefonlar veya konsollar gibi sıra dışı platformlara derlerken motorun derleme sürecine, hatta bazen libc ile ilgili kısımlara kadar dahil olması gerekir; dolayısıyla sadece bir Win32 çalıştırılabilir dosyası üretip buna PlayStation oyunu diyemezsiniz.
QOI kayıpsız dosya biçimini 7Zip ile birleştirmek, kayıpsız PNG’den daha iyi performans veriyor. Şaşırtıcı bir çalışma.
“for No Reason” belki de oyuncunun pil ömrüne saygı göstermek içindi.
Bellek yönetimi kısmını sevdim. Arena tahsisi gerçekten çok basit.
Kullandığım oyuncak web sunucusu da başlangıçta arenalarla başlamıştı; ama kısa süre sonra belleği artırıp azaltmaya aslında hiç gerek olmadığını fark ettim.
Şimdi gereken belleği en başta tek parça halinde ayırıyor, sonra her modülün kullanacağı parçalara bölüyorum. Programlama yaparken çoğu zaman keyfî miktarda belleğe ihtiyaç duyabileceğimizi varsayıyoruz, ama bu şart değil.
Birçok şeyin aslında net sınırları vardır; geri kalanlar için de çoğu zaman sınırlar tanımlanabilir. Bunları tek tek sayınca ne kadar belleğe ihtiyaç olduğunu anlarsınız. Böyle sınırları önceden düşünmek ve tanımlamak eğlenceli, güven verici ve sağlıklı bir tasarruf alışkanlığı kazandırıyor.
Boş bir vektörden başlayıp bellek ayırmadan binlerce öğe eklerseniz elbette öyle olabilir. Ama gerçekten gereken maksimum değeri bulup önceden ayırma yapabileceğiniz çok fazla durum var; o zaman her şey yoluna giriyor.
union ile polimorfik tipte bir ENTITY veri yapısı oluşturma biçimini gerçekten beğendim. Tasarımı iyi.
C ile hâlâ uğraşmayı seviyorum. İlk öğrendiğim dildi ve birkaç yıl boyunca gerçekten çok zorlanmıştım. Orijinal yazıda da söylendiği gibi C yalın bir dil olduğu için harika; isterseniz istediğiniz kadar derine inebilirsiniz.
Oyun eski Commander Keen havası verdiği için hoşuma gitti; Carmack’in 3D öncesi dönemde yaptığı o seriyi bir zamanlar epey severdim.