Geliştirici Günlüğü #33: Oyun gününe göre satır seçimi

Kısaca: MKA Engine, modların tekrarlanan sistem işini yalnız oyun gününe göre seçilen kayıtlarda çalıştırmasını sağlıyor. Mod gün ve işlem kuralını belirliyor; motor eşleşen satırları sunuyor, oyunun kuralını seçmiyor.
Geliştirici Günlüğü #32 nüfus hareketi isteklerinin ne zaman görünür olduğunu anlatıyordu. Bu günlük, bir sistemin yalnızca işi hazır olan kayıtları nasıl bulabildiğine bakıyor.
Gün gelince hangi kayıtlar işlenmeli?
Strateji oyunlarında her köy, grup veya ülke aynı anda işlenmek zorunda olmayabilir. Örneğin her grubun bir sonraki olay günü tutulabilir. Günü geldiğinde grup büyür ya da başka bir mod işi yürütür. Kayıt tablosunda her satır bir grubu, alanlar da o grubun değerlerini ve sıradaki gününü tutar. Sistem, bu kayıtlar üzerinde tekrar eden işi yürüten oyun kuralıdır.
Bir sistem bütün satırları dolaşıp her satırın gününü kontrol edebilir. Fakat yalnız birkaç grup hazırsa, diğer gruplar için de aynı tarih kontrolü yapılır. Ayrıca “günü geldi” iki anlama gelebilir: yalnız bugünün işlerini çalıştırmak veya bugüne eşit ve daha eski işleri birlikte ele almak. Örneğin günü geçince anlamını yitiren bir duyuru ilk kuralı, gecikse de tamamlanması gereken bakım işi ikinci kuralı gerektirebilir. Gecikmiş olayın atlanıp atlanmayacağı oyun tasarımıdır; motor bunu tahmin etmemelidir.
İki gün kuralıyla eşleşen kayıtları seçmek
Mod, kendi tablosundaki sayısal gün alanı için bir değer dizini kurar. Dizin, satırları bu alandaki değere göre bulmaya yarar; oyun kuralının kendisi değildir. Sistem de aynı tablodaki dizinli alanı seçme ölçütü olarak kullanır. Başka bir modun tablosundan alan seçilemez; seçim kurulum sırasında bildirilir.
Mod iki basit gün kuralından birini seçebilir. Tam eşleşme yalnızca bugünün satırlarını getirir. “Bugün veya daha önce” kuralı ise geçmiş tarihi olan, henüz ele alınmamış işleri de kapsar. Bu seçim, sistemin çalıştığı oyun gününe göre yapılır. Duyurunun yalnız belirli bir günde görünmesi gerekiyorsa tam eşleşme; kaçırılmış bir bakım işinin de sürmesi gerekiyorsa geçmiş günleri içeren kural uygundur. Bir sistem için tek bir gün karşılaştırması tanımlanır; daha karmaşık koşulları mod kendi işinde değerlendirir.

Motor seçilen satırların listesini sisteme verir. Mod bu listedeki kayıtları işlemelidir; listenin kapsadığı aralıktaki her satırın seçilmiş olduğu varsayılmamalıdır. Satır seçimi sistemin okuma ve yazma izinlerini genişletmez. Seçilecek satır yoksa yapılacak satır işi de yoktur.
Seçim sistemin çalışmasından önceki kayıt durumuna dayanır. Önceki adımlardaki yazılar, yeni kayıtlar ve silinmeler sonraki seçime yansır. Sistem bir kaydın gününü kendi çalışması sırasında ileri alırsa o kayıt aynı işlem sırasında yeniden seçilmez. Dizin kaydedilmiş oyuna ek bir veri olarak yazılmaz; kayıttaki değerlerden türetilir ve oyun yüklenirken yeniden kurulur.
Buradaki gün, yıl-ay-gün biçiminde bir metin karşılaştırması değil, oyunun simülasyon takvimindeki gün değeridir. İçerik bir olayı takvimde “şu yılın şu ayının şu günü” diye tarif ediyorsa, modun bu tarihi oyunun takviminden gün değerine çevirmesi gerekir. Böylece satırdaki gün ile motorun o adımdaki gününü aynı ölçekte karşılaştırır. Takvim türünü oyun seçer; mod da bu takvimin tarih dönüşümünü kullanarak alanına hangi sayıyı yazacağını belirler. Alanın sayısal olması tek başına doğru tarih anlamını garanti etmez: bir içerik başka başlangıç gününe göre sayı tutarsa seçim yine bu sayıları karşılaştırır, fakat modun kastettiği takvim olayıyla eşleştiği söylenemez.
Kılavuz örneği seçim kuralını nasıl kullanıyor?
Kılavuz örneğinde mod, gruplar için sıradaki işlem gününü tutuyor. Günü bugün veya daha eski olan grupların değeri artırılıyor ve sonraki gün ileri alınıyor. Örnekte kullanılan 30 günlük aralık yalnızca örnek modun tercihi; MKA Engine’in varsayılan nüfus kuralı değil. Aynı mekanizma başka bir oyunda belirli günlerde duyuruya, gecikmiş kaydı ele almaya veya farklı dönemli bir hesaplamaya hizmet edebilir. Motor günü ve yapılacak işi belirlemiyor, seçme mekanizmasını sağlıyor.
Duyuru, gecikmiş iş ve yeniden yüklenen kayıt
İlk durumu bir tarihli duyuruyla düşünelim. İçerik yazarı her duyuruya görünmesi gereken oyun gününü verir. Sistem tam eşleşme isterse yalnız o günün kaydı seçilir. Böylece tarihini kaçırmış bir duyuru, sonradan çalıştırılan adımda kendiliğinden güncelmiş gibi ele alınmaz. Duyurunun gecikince de gösterilmesi gerekiyorsa karar değişir: yazar “bugün veya daha önce” kuralını seçebilir. Bu seçim duyuruyu gerçekten gösterecek metni üretmez; yalnızca sistemin hangi kayıtları işleyeceğini belirler. Görünürlük, metin ve oyundaki sonuç hâlâ o modun işidir.
İkinci durum, oyunun birkaç takvim gününü tek seferde ilerletmesidir. Diyelim ki bir kayıt için işlem günü mevcut günden önce kaldı ve oyun bir sonraki çalışmasında o tarihi geçmiş durumda. Tam gün kuralı eşitlik aradığı için bu satırı seçmez. “Bugün veya daha önce” kuralı ise eski tarihin hâlâ ele alınması gereken bir işi anlattığını kabul ederek satırı seçebilir. Bu, atlanan her olayın çalıştırılacağına dair bir genel garanti değildir. Kuralın amacı gecikmiş işi yakalamaktır; mod satıra baktığında işin hâlâ anlamlı olup olmadığını kendi alanları ve oyun mantığıyla değerlendirmelidir. Gününü geçmiş duyuru ile gecikince de tamamlanması gereken bakım işinin ayrıldığı yer tam burasıdır.
Üçüncü durum, kayıtlı bir oyunun yeniden yüklenmesidir. Dizin ayrıca saklanan bir oyun verisi değildir; motor, kayıt tablosundaki gün alanlarından onu oyun yüklenirken yeniden kurar. Bu nedenle mod yazarı, seçimin dayanağı olan gerçek gün değerini kendi kayıtlarında doğru tutmalıdır. Kayıtlı satır “sıradaki iş günü” olarak önceki tarihi taşımaya devam ediyorsa, yeniden kurulan dizin de o değeri temel alır; “bugün veya daha önce” seçimi onu yine uygun bulabilir. Mod işi tamamlandıktan sonra tarihi ileri taşıyorsa sonraki seçim o güncellenmiş değeri görür. Dizin bu işi kendisi tamamlandı diye işaretlemez ve mod adına yeni bir gün yazmaz.
Bu üç örnek aynı mekanizmanın üç farklı tasarım kararını görünür kılar: yalnız tam gün eşleşmesi, gecikmiş işlere izin veren seçim ve yeniden yüklemede mevcut kayıt değerlerinden devam. Bunlar belirli bir oyunun hazır duyuru, bakım veya kayıt sistemi değildir; mod yazarının hangi tarih anlamını seçeceğini anlatan örneklerdir. Hangi seçeneğin doğru olduğu, içeriğin gün alanını nasıl kullandığına bağlıdır.
Eşleşen satırlar aralık değil, ayrı kayıtlardır
Bir sistemin aldığı liste, takvimdeki kayıtların kesintisiz bir parçası olmak zorunda değildir. Örneğin bir tabloda erken tarihli iki grup, daha sonraki tarihli başka bir grup ve aralarında bugüne uyan tek bir grup olabilir. Sistem yalnızca kurala uyan satırları işler; listenin ilk ve son kaydı arasında kalan her satırın da seçildiğini varsaymak doğru olmaz. Motor seçilen satırları artan satır sırasıyla verir. Paralel çalışmada bu sıra, her iş parçasının kendi listesinde korunur; boş listeye sahip parça çağrılmaz.
Buradaki “iş parçası”, motorun bir sistem çağrısında ele aldığı satır dilimidir. Mod yazarı sistemden seçilmiş satır listesini ister ve işini o listedeki satırlarla sınırlar. Listenin başlangıç ve bitiş değerleri tek başına bütün aralığın seçildiği anlamına gelmez; belirleyici olan seçilmiş satır listesidir. Böyle okumak özellikle sıralı veride önemlidir: artan sıra, aynı seçilmiş kayıtların düzenli biçimde sunulmasıdır; oyun dünyasındaki coğrafi, tarihî veya önem sırası değildir.
Bu sıralı görünüm, modun sonuçlarının oyun içindeki anlamını kendiliğinden sıralamaz. Örneğin seçilen kayıtlar satır kimliğine göre artan sırada gelir; bu düzen, en eski tarihten en yeniye, en büyük nüfustan en küçüğe veya haritanın kuzeyinden güneyine sıralama demek değildir. İçeriğin bu tür bir önceliğe ihtiyacı varsa, mod yazarı ilgili alanı ayrıca okuyup kendi kararını vermelidir. Gün seçimi yalnız tarih koşulunu karşılayan satırları bulur.
Seçim anı da bu görünümün parçasıdır. Sistem, kendisi çalışmadan önce mevcut olan uygun kayıt kümesiyle başlar. Bir önceki adımda mod bir grubun gününü değiştirmiş, yeni bir grup eklemiş veya bir kaydı kaldırmışsa sonraki seçim bu değişmiş tabloyu temel alır. Buna karşılık seçilen satırlar üzerinde çalışan sistem, aynı çağrı içinde bir satırın gününü ileri aldığında o kayıt mevcut listenin içinden yeniden seçilmez. Böylece yazar, bir döngünün ortasında yaptığı tarih değişikliğinin o döngünün giriş kümesini baştan oluşturduğunu varsaymamalıdır.
Örneğin bir takvim adımının önceki aşamasında mod, bir grubun planlanan bakım gününü bugün olarak güncellemiş olsun. Seçim bu adımdan sonra yapılırsa grup bugünkü iş kümesine girebilir. Sistem o grubu ele alıp bir sonraki bakım gününü ileri taşıdıktan sonra, aynı seçim çalışması yeni tarih değerini kullanarak ikinci kez dolaşmaz. Sonraki seçim ise önceki sistem yazılarını görür. Bu ayrım, “bu adımda hazır olan kayıtlar” ile “işlemden sonra yeni tarihe taşınan kayıtlar” arasındaki farkı açık tutar.
Bu görünüm ayrıca mod yazarına basit bir kontrol sorusu verir: seçilen her satır için hangi alanı okuyacak, hangi alanı değiştirecek? Sistem kurulurken beyan edilen okuma ve yazma alanları bu iş için geçerlidir; satır seçimi yeni alanlara erişim izni vermez. Örneğin sistemin yalnız sıradaki günü değiştirecek biçimde kurulması, seçilmiş satırları bulma olanağını nüfus, hazine veya başka bir alanı değiştirme yetkisine dönüştürmez. İşin gerektirdiği alanlar sistem tanımında açık olmalıdır.
Bu yaklaşım bir olay kuyruğu gibi tamamlanma durumu tutmaz. “Bugün veya daha önce” kuralıyla seçilen kayıt, mod gününü değiştirmezse sonraki adımda yeniden uygun kalabilir. Tek seferlik işte mod kendi durumunu güncellemeli veya sıradaki günü ileri taşımalıdır. Benzer biçimde tam gün kuralı, günü geçmiş işleri kendiliğinden yakalamaz.
Günün anlamını oyun ve mod belirler
Dizini ve gün kuralını açıkça bildirmek, motorun her sayısal alanı tarih sanmasını önler. Oyun içeriği hangi günün iş anlamına geldiğini, mod ise bu gün geldiğinde hangi işlemin yapılacağını belirler. Motor yalnızca seçilen kayıtları bulur. Böylece tam gün ve gecikmiş iş davranışı oyun tasarımında kalır; sistemin işi de görünür olur.
Mod yazarı açısından seçim, kurulumda bir kez ilan edilen bir ilişki olarak okunmalı: alan sayısal olmalı, aynı mod tablosunda bulunmalı, dizin önce kurulmalı ve sistem bu alanı seçme ölçütü olarak kullanmalıdır. Seçim kaydı sistem başladıktan sonra başka bir alanı tarih gibi yorumlamaz. Bir sistemin seçim kuralı tek bir karşılaştırmadır; örneğin “bugün veya daha önce”. Hem belirli bir aralığı hem de ikinci bir koşulu isteyen mod, bu karmaşık mantığı seçimin içinde varmış gibi varsaymamalı; seçilen satırlar üzerinde kendi oyun koşulunu değerlendirmelidir.
Kurulum ile çalışma anını ayırmak da hataları önler. Dizin ve seçim kurulurken kayıt ve alan ilişkisi doğrulanır. Çalışma sırasında sistem kendi seçilmiş satırlarını alır. Bu listeyi başka bir modun tablosuna taşımak veya seçimi yapan sistem dışındaki bir çağrıdan istemek aynı özellik değildir. İçeriği hazırlayan kişi de takvim değerlerinin anlamını açıklamalıdır: alan bir sonraki bakım gününü mü, tek seferlik olay tarihini mi tutuyor? Bu ayrım açık olduğunda gecikmiş kayıtların neden seçileceği ya da neden dışarıda kalacağı takip edilebilir.
Bu kararı gözden geçirirken yazar, birkaç farklı tarih durumunu kendi oyun kuralıyla karşılaştırabilir: tam bugünkü kayıt, daha önceki bir gün, daha ileri bir gün; ayrıca oyun adımı doğrudan kayıt tarihinin üzerinden ilerlediğinde beklenen sonuç. Bunlar motorun her tasarım için aynı davranışı seçmesini istemez. Tam tersine, içeriğin niyet ettiği gecikme politikasını açık etmek için sorulacak örnek durumlardır. Bir duyurunun geç kalınca gösterilmesi mi, yoksa yalnız tarihinde geçerli olması mı gerektiği; bakım işinin sonraki adımda da bekleyip beklemeyeceği içerik tasarımında karara bağlanmalıdır.
Seçim hangi işi üstlenmez?
Dizin oyun yüklenirken yeniden kurulan ek bir arama düzenidir. Bu değişiklik için süre veya bellek ölçümü yayımlanmadı; dolayısıyla hız kazancı iddiası yok. Seçim, özellikle hazır kayıtların yalnızca bir bölümü olduğunda sistemin işlediği satırları sınırlayabilir. Her satırın günü gelmişse sisteme yine çok sayıda kayıt sunulur; bu nedenle dizinin her oyun ve tablo boyutunda toplam süreyi düşürdüğü sonucuna varamayız.
Seçim alanı modun kendi tablosunda dizinlenmiş olmalı ve sistem aynı tablodaki alanı kullanmalıdır; geçersiz alan seçimi reddedilir. Seçili satır listesi yalnızca bu seçimi tanımlayan sistem çalışırken istenebilir; başka bağlamda istenirse mod durur. Motor yanlış gün kuralını veya modun iş mantığını düzeltmez.
Gerçek oyun takviminde yanıtlanacak sorular
Bir sonraki adım, bu seçimi gerçek bir oyun içeriğinin takvimine bağlamak: hangi işin hangi gün hazır olduğunu, gecikince nasıl ele alındığını ve seçilen kayıt üzerinde ne değiştiğini birlikte göstermek.
Sık sorulanlar
Bu seçim kuralı her kaydın işlem gününü belirler mi?
Hayır. Oyun veya mod gün değerini yazar; motor bu değere uyan satırları seçer. Olayın ne zaman hazır olacağı oyun kuralında kalır.
Tam gün ile “bugün veya daha önce” arasındaki fark nedir?
Tam gün yalnızca bugünün kayıtlarını seçer. Diğer kural, günü geçmiş kayıtları da kapsar.
Mod başka bir tablodan satır seçebilir mi?
Hayır. Dizin ve sistem aynı mod tablosuna ait olmalıdır. Bu seçim başka modun kayıtlarını kapsamaz.
Dizin oyun kaydında saklanır mı?
Hayır. Oyun yüklenirken kayıtların gün değerlerinden yeniden kurulur.