Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı

Aslında benim dünyam iş modellerinin nesne yönelimli dillerle buluştuğu birçok yazılım prensibinin uygulanıp teknik borçların da yer aldığı devasa bir evren. Hal böyle olunca insan ister istemez arada bir düzen dışına çıkıp bambaşka maceralara dalmak istiyorum. Ben bunun için ağırlıklı olarak farklı programlama dillerini öğrenmeye çalışıyorum. Java, Ruby, Python ve Go bunlardan bazıları. Ancak en ciddi seviyede ilgilendiğim bir diğer dil Rust. Onunla yaklaşık 3 yıldır hararetli bir şekilde ilgilenmekteyim ve bana kalırsa bir programlama dilini öğrenmenin en eğlenceli yanı onunla oyunlar yazmaya çalışmak. [Daha fazla]

Matematik ve Oyun Programlama - Missile Command - Final

Hiçbir ödül veya karşılık beklemeden kendinizi iyi hissetmek adına en son ne yaptığınızı hatırlıyor musunuz? Bu öyle değişik bir iç motivasyon ki kendinizi bir amaca adayarak hareket etmenizi sağlıyor. Karşılaşılan engeller engel olmaktan çıkıyor ve anlamak istediğiniz şeyler haline geliyor. En azından ben birkaç haftadır böyle hissediyorum. Cevval bir oyun programcısı olmak ya da akademide bu alana dair dersler vermek gibi bir amacım yok ama çok güçlü bir iç motivasyonum var; öğrenmek… [Daha fazla]

Matematik ve Oyun Programlama - Missile Command - Bölüm 2

Bir önceki programımızda Atari'nin efsane oyunlardan Missile Command'in arkasındaki matematik enstrümanları incelemeye başlamıştık. İkinci bölümde ise zeminin orta noktasına ve şehrin biraz yukarsına füze bataryamızı yerleştiriyoruz. Bu füze bataryası, oyuncu mouse imlecini ekranda hareket ettirdikçe oraya doğru dönecek bir çizgiden ibaret esasında. Oyuncu mouse imlecinin olduğu yerde sol tuşa tıklarsa da bataryanın namlu ucundan bu noktaya doğru sevimli ve mavi renkte minik bir dörtgen fırlıyor. Herhangi bir zamanda sahnede sadece üç tane mermi oluyor. Hatta füze bataryası 30 derecenin altına veya 150 derecenin üstüne hareket edemediği gibi ateş de edemiyor. Diğer yandan mermi, mouse ile tıklanan ilk noktaya vardığında sahneden kaldırılıyor. Mermiler belli bir hızda ama şehre inen füzelerden azıcık daha hızlı şekilde hareket ediyorlar. [Daha fazla]

Matematik ve Oyun Programlama - Missile Command - Bölüm 1

Uzun bir süredir Rust programlama dili ile hobi amaçlı uğraşıyorum. Son birkaç aydırda Rust tarafında kullanılan oyun motorlarını kurcalamaktayım. Ancak birkaç haftadır amacım oyun programlamada kullanılan temel matematik enstrümanları öğrenmek. Bana göre bu alanda ilerleyebilmemin en iyi yolu bilinen oyunların birer klonunu yazmaya çalışmak. Onca vektör, açı, nokta çarpım problemini işledikten sonra ilk gözüme kestirdiğim zamanın efsane Atari oyunlarından olan Missile Command. Kaynaklara göre seksenli yılların en kült oyunlarından birisi olarak karşımıza çıkıyor. Oyunda ekranın üst kısmında rastgele açılarda ve sayıda füzenin üssümüze inişine şahit oluyoruz. Oyuncu üssün tam orta yerinde duran füze rampasında ateş ederek şehre inen füzeleri patlatmaya çalışıyor. Görüntü tamamen piksel hareketlerinden oluşmakta ve benim asıl ilgilendiğim oyunun arkasındaki olası matematik hesaplamalar. [Daha fazla]

Oyun Geliştirmede Kullanılan Temel Matematik Enstrümanlar

Oyun sahasına ekranın sağından gelip düz ve çapraz bir çizgide ilerledikten sonra dairesel hareketle devam edip rastgele zamanlarda ateş eden uzay gemisinin kodlamasını öğrenirken ortaya döküken kosin��s ve sinüs çağrıları sonrası ise şöyle bir durup düşünmeye başladım. Öncesinde kağıt kalem alıp biraz karalama yapmalıydım. Bugünün popüler oyun motorlarından Unity, Unreal Engine gibilerinin çoğu fizik motorlarından ışıklandırmaya, gölgeleme efektlerinden çarpışma hesaplamalarına, izdüşümsel kamera bazlı 2D sahalardan sıçrama efektlerine kadar pek çok şeyin temel hesaplamasını hazır olarak sunmakta. Hatta IDE desteği sunanlar çok daha öne çıkmakta. Ancak oyun programlamanın temellerinde her zaman olduğu gibi matematik var ve bu atlanmaması gereken bir mevzu... [Daha fazla]

Rust Pratikleri - Value Moved Here

Sıklıkla vurguladığım üzere Rust programlama dili bellek yönetimi ve güvenliği konusunda son derece hassas kurallar içeriyor. Değişken sahipliği kuralları ve ödünç alma kontrolcüleri(Ownership, borrow checker) olası bir çok bellek probleminin henüz derleme aşamasındayken önüne geçilmesini sağlıyor ancak dilin öğrenme eğrisini de oldukça dikleştiriyor(En azından ilk zamanlarda) Esasında C,C++ türevi sayabileceğimiz Rust bir Garbage Collector mekanizması kullanmaması belleğin iç dinamiklerini daha iyi bilmemizi de gerektiriyor. Stack ve heap özelinde değişkenlerin nasıl tutulduğu, yer ayarlamalarının nasıl yapıldığını bilmek programcı açısından oldukça önemli. Bu sayede pek çok derleme zamanı hatasını anlamlandırmak kolaylaşıyor. Bu yazıdaki amacımız Rust öğrenenlerin sıklıkla yakalandığı "Value borrowed here after move" hatasını bellek çalışma prensipleri kapsamında özetlemek. [Daha fazla]

Rust Pratikleri - State Tasarım Kalıbı

Belli bir akış içerisinde ele alınan nesneler belli durumlara sahiptirler. Bu durumlar arasındaki geçişler için fonksiyonlardan yararlanılırken bazı kuralların işletilmesi de istenebilir. Örneğin belli bir duruma sahipken diğer bir duruma geçilmesini engelleyen karar mekanizmaları ve koşullar söz konusudur. Hatta programın belli bir t anında içinde bulunabileceği durumlar bellidir. Nesne yönelimli dillerde bu gibi ihtiyaçlar için davranışsal(Behavioral) kalıplardan olan State tasarım deseni sıklıkla kullanılır. Hatta oyun programlamada State Machine türevli motorlarda nesne durumlarının yönetimi için bu desene ait pratikler söz konusudur. [Daha fazla]

Rust ile Oyun Programlama

Uzun süredir Rust programlama dilini öğrenmeye çalışıyorum. Bu yolda yürürken çevrimiçi eğitim materyalleri, blog yazıları ve bültenler haricinde birincil kaynak olarak da kitapları kullanmayı tercih ediyorum. Diğer yandan bir programlama dilini iyi seviyede öğrenmenin bana göre iki yolu var; var olan ürünlerin benzerini yazmak ya da oyun geliştirmeye çalışmak. Bazı yayınlar programlama dilini oyun yazarak öğretmeye çalışıyorlar. Takip ettiğim Herbert Wolverson'un Hands-on Rust: Effective Learning through 2D Game Development and Play isimli kitap da bunlardan birisi. Çok efsane bir öğrenim deneyimi olduğunu ifade edebilirim. [Daha fazla]

Rust Pratikleri - Trait Objects

Bir Windows Forms uygulaması düşünelim ya da bir web sayfası. Hatta birden fazla bileşenden (component) oluşan bir mobil uygulama arayüzünü...Temelde ana kontrol üstüne eklenen başka tekil ve karma kontrollerden oluşan bir bütün söz konusudur. Şimdi de ana saha üzerine gelen bu kontrollerin nasıl çizilebildiğini düşünelim. Bir motor büyük ihtimalle belli ortak davranışlara sahip olan bileşenleri, ortamın istediği kıvamda (örneğin HTML olarak) çizme görevini üstlenir. Hatta bu sistemlerde bileşen ağacı öyle bir tasarlanır ki, geliştiriciler isterlerse kendi bileşenleri de tasarlayıp çalışma zamanı motorunun kullanımına sunabilir. [Daha fazla]

Rust Pratikleri - OOP

Yılların .Net geliştiricisi olunca insan, ister istemez Rust, Go gibi dillerde nesne yönelimli dünyanın karşılıklarını arıyor. Encapsulation, Inheritance, Polymorphsym gibi. Bu konuda araştırmalar yaparken birkaç şey öğrendi tabii ve C# ile yazdığım bazı şeyleri Rust tarafında karşılamak istedim. Sonuçta ortaya şu an okumakta olduğunuz pratik çıktı. Ben daha çok kalıtım ve çok biçimli nesne davranışı konularına eğilmeye çalıştım. Dilerseniz hiç vakit kaybetmeden örneklerimize geçelim. [Daha fazla]

Rust Pratikleri - Değişkenleri Kopyalayarak veya Referans Olarak Taşımak

Bu pratikte içinde başka bir enum sabiti kullanan bir enum sabitinin bir fonksiyonda parametre olarak kullanılmasında oluşabilecek Value Moved Here sorununa bakıyoruz. Cümle biraz karışık oldu :D Öyleyse örnek üstünden ilerleyelim. Kod tarafında ilk olarak sorunsuz bir ortam tesis edeceğiz. Problemi oluşturacağız. Ardından iki farklı yolla duruma açıklık getireceğiz. [Daha fazla]

Rust Pratikleri - Wordle Oyunu

Doğruyu söylemek gerekirse mobil oyunlarla çok fazla aram yok. Yine de etkileyici grafikleri olmasa da insanları saatlerce esir edebilenlerin nasıl yazıldığını merak etmiyor da değilim. Geçtiğimiz günlerde The Pragmatic Programmers mecrasından Herbert Wolverson'un Wordle isimli popüler bir oyunun Rust ile nasıl yazılacağını anlattığı şu yazısına denk geldim. E boş durur muyum? Adım adım tatbik etmeye karar verdim. Nitekim bu yolculuk Rust ile ilgili birçok şey öğretecekti bana. Her şeyden önce pratik yapacaktım. İşte bu yazıda izlediğim adımları ve kendi yorumlarımı bulabilirsiniz. [Daha fazla]

Rust Pratikleri - Aynı Anda Sadece Tek Bir Değiştirilebilir Referans Olabilir

Thread'ler ve eş zamanlı iş parçacıkları işin içerisine girdiğinde karşımıza çıkan önemli konulardan biriside mutable türden referansları nasıl kullanacağımızdır. Malum bu thread'ler aynı veri üzerinde değişiklik yapmak isteyebilirler. Data Races oluşmaması Rust'ın temel ilkelerinden birisidir ve bunun en büyük sebebi bellek ortamını güvenli halde koruyabilmektir. Dolayısıyla belleğin referans edilen bölgelerinin bu thread'ler içerisinde yazma amaçlı ele alınması durumlarında kod biraz karmaşıklaşabilir. Öncesinde kuralın ne olduğunu dile getirelim; Rust bir t anında birden fazla mutable referans oluşturulmasına izin vermez, buna müsaade edecek şekilde kodlama yapmamızı engeller. Elbette konuyu anlamanın en güzel yolu basit bir örnek üzerinden ilerlemekle mümkün. Öyleyse başlayalım. [Daha fazla]

Rust Programlama Dili için "Hello World"

Yakın zamanda yazılımcılardan oluşan bir ekibe Rust programlama dili ile ilgili bildiklerimi anlattım. Bunu yaparken örnek bir program kodu üzerinden ilerledim. İlk etapta neyi nasıl anlatacağım konusunda hiçbir fikrim yoktu. Sonrasında doğaçlama ilerlemeye ve yolda karşımıza çıkacak sorunlar üzerinden dili tanıtmaya karar verdim. Derken anlattıklarımı bir video haline getirsem iyi olabilir diye düşündüm. Pek tabii Rust dilini yeni öğrenen birisi olarak bunu 1 saatlik bir zaman diliminde yapmak pek mümkün değil. Yine de ilerisi için iyi bir hazırlık oldu. Belki ilgi duyan arkadaşlar için yol gösterici de olur. Deneysel amaçla gerçekleştirdiğim bu görsel derste aşağıdaki konulara değindim. [Daha fazla]

Rust Pratikleri - HTTP Sunucusu Yazmak/Yazmaya Çalışmak

Bir HTTP sunucusu yazmaya ne gerek var diyebilirsiniz. Öyle düşünmeyin. Bir programlama dilini öğrenmenin en iyi yolu, var olan yapıları o dille yazmaya çalışmaktır. Hangi dil ya da platform olursa olsun ortada dolaşan yüzlerce HTTP server zaten var. Ancak nasıl çalıştıklarını anlamak için de yine yeniden yazmakta yarar var. Bugünkü pratiğimizde Rust dilini kullanarak bir HTTP server nasıl yazılabilir incelemeye çalışacağız. Esasında sadece minik bir başlanıç yapacağız. Nitekim bir HTTP sunucusunun görevleri çok geniş olabilir. Sonuçta IIS Server yazmayacağız ancak genel felsefeyi öğreneceğiz. [Daha fazla]

Rust Pratikleri - Serde, Json ve Biraz Eğlence

Sanıyorum ki JSON veriler ile çalışmaya programlama dili, ortam yoktur. Sonuç itibariyle bir takım verileri düzenli, standart ve insan gözüyle okunabilir bir formatta tutmanın en iyi yollarından birisi JSON. Öncesinden gelen XML formatına göre daha az yer tutması da cazibesini artırmaktadır. Tabii günümüzde BSON gibi sıkıştırılabilir ve çok daha hızlı yol alabilen seçenekler de mevcut ama rust dilini öğrenirken bunun pratiğini yapmadan olmaz. Bu noktada işimizi epey kolaylaştıran bir kütüphane olduğunu ifade edebilirim. Serde isimli çatı(ki framework olarak işaret ediliyor) JSON ile çalışma konusunda epey popüler. [Daha fazla]

Rust Pratikleri - Lifetimes Mevzusu

Rust'ın özellikle Garbage Collector kullanılan dillerden çok farklı olduğunu bellek yönetimi için getirdiği kurallardan dolayı biliyoruz. Ownership, borowwing gibi hususlar sayesinde güvenli bir bellek ortamını garanti etmek üzerine ihtisas yapmış bir dil. Bunlar pek çok dilde otomatik yönetildiği için Rust'ı öğrenmek zaman alabiliyor. Zor konulardan birisi de Lifetimes mevzusu. Bu konuyu esasında sevgili Bora Kaşmer ile başladığımız 45 Byte sohbetlerinde dile getirmek istiyorum. Lakin çok basit bir örnek gerekiyor ve String türü ile literal string arasındaki fark bu işi anlatmak için biçilmiş kaftan. Hiç vakit kaybetmeden proje iskeletini oluşturarak devam edelim. [Daha fazla]

Rust Pratikleri - GDB ile Debug İşlemleri

Rust ile ilgili öğretilerde bellek yönetimi konusunu incelerken fonksiyon ve değişkenlere ait kapsamların bellekte nasıl açıldığını görmek için GNU Debugger'dan(kısaca GDB) yararlanıldığını gördüm. Kodu debug etmek deyince insanın aklına Visual Studio gibi gelişmiş IDE'lerin kolaylıkları geliyor ve bu nedenle GDB ilkel bir araç gibi görünebilir. Yine de rust kodunu terminalden adım adım işletmek ve bellek üzerindeki konumlandırmaları görmek(stack açılımlarını izleyip pointer'ları analiz etmek gibi) adına son derece faydalı bir araç. Rust dilinde ilerlemek isteyenlerin bilmesi ve kullanması gereken bir yardımcı. Öncelikle üzerine çalıştığım Ubuntu platformuna yüklemem lazım. Bu arada GDB ile ilgili detaylar için şu adrese bakılabilir. [Daha fazla]

Rust Pratikleri - Channels

Thread'ler aralarında haberleşmek için kanallardan(channels) yararlanır. Rust dilinde bu amaçla built-in modüllerinden olan mpsc(multi-producer single-consumer) paketi kullanılır. Bu paket aslında FIFO(First-In First-Out) ilkesine göre çalışan tipik bir kuyruk yapısıdır. Kanallar yardımıyla örneğin iki thread arasında bir kanal açıp tek yönlü olarak mesaj göndermek mümkündür. Böylece bir thread'den diğerine çeşitli verileri aktarabiliriz. Hatta asenkron ve olay güdümlü(event-driven) haberleşmeler tesis edebiliriz. Bir veri türünün kanalda akması için Send trait'ini uyarlamış olması gerekir. Primitive tiplerin hepsi bu davranışa sahiptir... [Daha fazla]

Rust Pratikleri - Dokümantasyon

Bir programlama dilini iyi yapan ve onu öne çıkaran bazı önemli unsurlar vardır. İdeal bir söz dizimi oluşturulması için önerilerde bulunmak, kullanılan fonksiyon veya türlerle ilgili yardım dokümantasyonları sunmak, merkezi ve başarılı bir paket yönetim sistemine sahip olmak bunlar arasında sayılabilir. Rust dilindeki pek çok kural sayesinde bellek sahasının güvende kaldığı(memory safe), dangle pointer, data race, memory leak gibi sorunların oluşmadığı, performansı yüksek ve üstelik bütün bunlar için garbage collector benzeri mekanizmalara ihtiyaç duymayacak şekilde geliştirme yapmamız mümkün. Yine de idiomatic olarak ifade edilen ve dilin en ideal şekilde kullanılmasını tarifleyen ihtiyaç için yardım almamız gerekiyor. Bu anlamda cargo clippy en büyük destekçimiz. Ancak kaliteli kodlamanın olmazsa olmaz önemli özelliklerinden birisi de elbette verimli içerik sunan dokümantasyon. Özellikle yazdığımız kütüphaneleri herkesin kullanımına açmak istediğimiz senaryolarda bu konuya azami özeni göstermek lazım. [Daha fazla]

Rust Pratikleri - Multithreading

Uygulamalar işletim sistemlerince Process olarak ayağa kaldırılırlar. Bir process içerisindeki işleri birbirlerinden bağımsız olarak yapan thread'ler de söz konusu olabilir. Çoğu zaman çalıştırılabilir programın main fonksiyonu ile akan akış tek bir thread ile işleyişini sürdürür ama ihtiyaç dahillinde yeni thread'ler açmak gerekir. Rust için process içerisinde bir thread açmak oldukça kolaydır ve bellek tüketimi açısından maliyeti düşüktür. Ownership ve borrowing kuralları sayesinde bellek sahası güvende kalır ve özellikle data-race sorunları oluşmaz... [Daha fazla]

Rust Pratikleri - Loglama

Bugün bir redis, rabbitmq, kafka sunucusu başlattığımızda ya da docker container’ı içerisine komut satırı açtığımızda terminal ekranına akan sayısız log içeriği olduğunu görüyoruz. Bu loglar hataları görmek, uyarıları çabucak fark etmek açısından sistem programcıları için son derece kıymetli bilgilerden oluşuyor. Çok doğal olarak Rust ile yazılan uygulamalar içinden log yayınlamak isteyebiliriz ki Rust’ın asıl odağının sistem programlama olduğunu da düşünecek olursak bu gereklidir. Rust Pratiklerinin bu ilk bölümünde log ve env_logger küfelerini kullanarak basit anlamda loglamanın nasıl yapıldığını öğreneceğiz. [Daha fazla]

Programcıdan Programcıya Rust

İki yıl kadar önce bir merakla başladığım ama sonrasında takıntı haline gelen bir uğraş edindim; Rust programlama dili. Profesyonel iş yaşantımın neredeyse tamamında .Net platformu üstünde geliştirme yaptım ve halen daha maaşımı ondan kazanıyorum. Bazı zamanlar Python, Go, Ruby gibi dillere de baktım ama hep hobi olarak kaldılar. Rust içinse aynı şeyi söylemem zor. Onunla ilgili resmi dokümantasyonu takip edip birkaç satır kod yazmaya başladım ve derken sayısız derleme zamanı hatası ile karşılaştım. Bunların neredeyse büyük çoğunluğu borrowing, ownership, lifetimes gibi konularla ilintiliydi ve her biri Rust’ın temelde bilinmesi gereken demirbaşları. [Daha fazla]

Monolitik Uygulamalarda Teknik Borçlanma ile Mücadele (Teori)

Yazılımcı olmanın bir gerçeği de üretim ortamından gelen problemler ile uğraşmaktır belki de. Çalışmakta olduğumuz sistemlerin giderek büyümesi, iş kurallarının zamanla karmaşıklaşması, nasıl yapılır nereye bakılır bilgisinin ayrılan iş gücü nedeniyle eksilmesi, entegrasyon noktalarının çoğalması ve daha birçok sebepten ötürü bu kaçınılmazdır. Her birimiz yazılım yaşam süresi boyunca farklı tipte mimariler üzerinde çalışırız. Örneğin 2021 yılının ilk çeyreğinde hazırladığım ve yedi yüzden fazla kişinin katıldığı “Teknik Borç Farkındalık Anketi” isimli çalışmanın sonuçlarına göre beşimizden dördünün katmanlı mimari olarak adlandırdığımız monolitik sistemlerde görev aldığını söyleyebiliriz. Hele ki sektörde yirmi yılı deviren bir yazılım geliştirici iseniz (ki yine anket sonuçlarına göre neredeyse %40ımız 10 yaşından büyük ürünlerle çalışmış) böyle bir sistemle yolunuzun kesişmemiş olması pek mümkün değildir. [Daha fazla]

Effective Engine — Bir Uzay Macerası

Altunizade’nin bahar aylarında insanı epey dinlendiren yeşil yapraklı ağaçları ile çevrelenmiş caddesinin hemen sonunda, köprüye bağlanmadan iki yüz metre kadar öncesinde dört katlı bir bina vardır. Araba ile geçerken eğer kırmızı ışığa denk gelmediyseniz pek fark edilmez ama yürürken önündeki geniş kaldırımları ile dikkat çeker. Ana cadde tarafındaki yeşillikler binanın ilk katlarını gizemli bir şekilde saklar. Binanın bulunduğu adanın etrafı cadde ve ara sokaklarla çevrilidir. Bir sokağın karşısında yeni yapılmış hastane ile metro çıkışı, ana cadde tarafında ev yapımı tatlılarının kokusu ile insanı baştan çıkaran pastane, eczane, kuaför, camii ve minik bir park bulunur. Dört yola bakan diğer cadde tarafında ise eskiden karakol olan ama çok uzun zamandır kreş olarak işletilen bir komşu yer alır. [Daha fazla]