Geliştirici Günlüğü #32: Sistemlerde nüfus hareketi

Kısaca: MKA Engine artık modların sistem işlerinde nüfus taşıma isteklerini kuyruğa almasına izin veriyor. Motor istekleri sistem çalışırken hemen uygulamak yerine oyun adımının sınırında, sistemler tamamlandıktan sonra ele alıyor. Böylece mod yazarı bir grup üzerinde kuralı kendi sisteminde hesaplayabiliyor; oyunun seçtiği göç koşulları veya taşınacak miktar motor tarafından belirlenmiyor.
Sorun ne idi?
Bir strateji oyunu nüfusu çoğu zaman kişileri tek tek değil, aynı yerde yaşayan veya benzer özellikleri paylaşan gruplar hâlinde takip eder. Bu grupların büyüklüğü, bulundukları yer ve oyunun önem verdiği diğer nitelikler birlikte çalışır. Bir oyun, örneğin kırsal bir gruptan kentteki bir gruba doğru hareketi kendi kurallarıyla hesaplayabilir. Motorun işi bu kararın doğru olup olmadığına karar vermek değil; oyunun ve modun verdiği bilgilerle bu değişikliği tutarlı biçimde uygulamaktır.
Mod, oyuna yeni kural veya içerik ekleyen bir uzantıdır. Geliştirici Günlüğü #26'da modların nüfus ve pazar hesaplarına erişmesini ve ilk büyük ölçek ölçümünün sınırlarını anlattık. Buradaki soru daha dardır: Sistem işi hareket isteği verdiğinde motor bunu nerede ve ne zaman uygular?
MKA Engine işin farklı türlerini farklı zamanlarda çalıştırır. Sistem, çoğunlukla her kayıt veya grup için ayrı hesap yapan iştir; örneğin her nüfus grubu için oyunun verdiği koşulları değerlendirebilir. Kanca ise bir adımın sonunda daha geniş resmi ele alan, birden çok grubun sonucunu bir araya getirebilen iştir. Oyuncunun verdiği bir komut veya zamanlayıcı da bu ikinci, adım sınırındaki çalışma yoluna girer. Bu ayrım motorun iş paylaşımını anlatır; oyunun hangi kuralı seçeceğini belirlemez.
Daha önce nüfus hareketi istekleri kanca, komut veya zamanlayıcı sırasında verilebiliyordu. Bir sistem her grup için ayrı karar üretiyorsa, hareket kararını başka bir kancaya taşıması gerekiyordu. Bu her oyun için yanlış bir düzen değildi: Toplam bir sonucu hesaplayıp sonra uygulamak isteyen içerik yazarı kancayı tercih edebilir. Ancak hareket isteği zaten tek bir grubun hesabından çıkıyorsa, araya ek bir aktarım adımı koymak zorunlu bir mimari tercih hâline geliyordu.
İki işi ayırmak gerekir: hangi grupların inceleneceğini seçmek ve seçilenler için hareket isteği vermek. Motor, işaretlenmiş canlı kayıtları sıralı biçimde listeleyebilen ayrı bir yol da sağlar; bu listeleme sistem hareketi için zorunlu değildir. Mod kendi arama döngüsünün yerine bu listeyi kullanabilir, ancak motor yine işaret alanını tarar.
Nasıl çözdük?
Mod yazarı artık bir sistem çalışırken nüfus hareketi isteği verebiliyor. Sistem, üzerinde çalıştığı gruplara ve okuma iznine sahip olduğu bilgilere göre oyunun kuralını değerlendirebilir. Örneğin oyun, bir gruptan belirli bir yer değişikliği istemeye karar verirse mod bu isteği sistem işinin içinden kuyruğa koyar. Motor, isteğin kaynağını ve biçimini denetler; ama hangi grubun taşınacağına, hangi yere gidileceğine veya oyunun hangi eşiklerde hareket başlatacağına mod karar verir.
Kuyruğa alınan istek, sistem çağrısı sürerken nüfus tablosunu değiştirmez. Sistemler işlerini bitirince motor adım sınırına ulaşır. Bu noktada başarılı sistem işlerinden kalan hareket istekleri toplanır ve modun sonraki kancalarından önce uygulanır. Bu sınırı, bir toplantı sırasında herkesin ortak listeye değişiklik yazması ve toplantı bitince listenin tek seferde güncellenmesi gibi düşünebiliriz. Benzetmenin sınırı şudur: Gerçek oyun tablosunda hangi verilerin değişeceğini oyunun kuralları ve modun gönderdiği istek belirler.

Bu sıralama aynı adım içinde hangi verinin görüldüğünü de açıklar. Sistem aşamasındaki bir okuma, o aşamada kuyruğa alınmış hareketleri görmez; motor hareketleri aşama bittikten sonra işler. Dolayısıyla sistem, kuyruğa gönderdiği isteği hemen geri okuyup yeni konuma göre aynı aşamada ikinci bir karar veremez. Bu, nüfus hareketinin oyunda gerçekleşmediği anlamına gelmez; değişikliğin işin hangi aşamasında görünür olduğunu tanımlar. Mod yazarı zincirleme kararlarını bu sıraya göre kurmalıdır.
Motor istekleri paralel çalışan iş parçalarından herhangi birinin önce bitmesine göre uygulamıyor. Sistem ve sistemin işlediği parçalar için sabit bir sıra kuruyor; bir parçanın kendi istekleri de verildiği sırada kalıyor. Böylece işlemlerin sonucu, iş parçacıkları farklı hızlarda tamamlandı diye değişmek zorunda kalmıyor. Burada “aynı sonuç” ifadesi yalnızca bu nüfus hareketi yolunun kaynaklarda belirtilen sıralama kuralına ilişkindir; başka oyun kurallarının tamamına dair bir eşitlik veya deterministik simülasyon garantisi değildir.
Motor her istekte kaynak grubun canlı olup olmadığını, hedef yerin geçerliliğini ve değişiklik türünün tanımlı olup olmadığını denetler. Bu denetim, göç kararının oyuna uygunluğunu değil, motorun isteği mevcut verilerle uygulayıp uygulayamayacağını kapsar. Geçersiz bir istek çağrıyı reddettirir.
Küçük bir örnekle düşünelim. Bir strateji oyununda, belirli bir pazar bölgesinde iş arayan nüfus grupları başka bir yere taşınmaya uygun olabilir. Bu, bu motor değişikliğinin hazır getirdiği bir oyun kuralı değildir; içerik yazarının seçebileceği temsili bir kuraldır. Modun sistemi her grup için pazar erişimini veya oyunun başka bir koşulunu değerlendirir. Koşulu karşılayan grup için hareket isteği oluşturur. Motor, istekleri iş sürerken değil adım sınırında uygular. Oyunun kancası bundan sonra yeni konumlara göre toplamları hesaplayabilir.
Başka bir hesaplamanın yeni konumu kullanması gerekiyorsa, onu hareketlerin uygulandığı sınırdan sonraya planlamak gerekir; değilse mod kuralı değişikliği sonraki adımda kullanabilir.
Bir sistem içindeki liste, yalnız o iş parçasının eriştiği canlı grupları kapsar ve işaret alanı sistem için okunur olarak tanımlanmış olmalıdır. Kancadaki bariyer çağrısı daha geniş tabloyu görebilir. Ancak aynı çağrı işaret alanına yazı bekletmişse, listeleme isteği reddedilir; motor eski listeyi sessizce döndürmez. Bu nedenle işaret yazısını ve listelemeyi ayrı çağrılara koyup, listeyi yazı görünür olduktan sonra istemek gerekir.
Ne gördük?
Türkçe ve İngilizce mod kılavuzları sistem hareketi, aşama görünürlüğü ve listeleme sınırlarını açıklıyor. Kod da istekleri kaynakların tarif ettiği sırayla uygulıyor.
Bu taslağı hazırlarken testler çalıştırılmadı; dolayısıyla test sonucu bildirmiyoruz.
İncelenen kaynaklarda aynı dünya ve iş yüküyle yeni süre karşılaştırması yok. Taşınan grup sayısı adım süresini tek başına göstermez; bu yüzden hızlanma veya bellek kazancı iddiası kurmuyoruz. Somut gelişme, hareket isteğinin doğrudan sistem işinden verilebilmesidir.
Neden böyle seçtik?
Sistem işleri paralel yürüdüğünde tamamlanma anları iş parçacıklarının hızına göre değişebilir. Motor istekleri bu yarışa göre uygulamak yerine tanımlı sırada ele alır; böylece sonucun iş parçacıklarının bitiş hızına bağlanması önlenir.
Sistem, her grup için ayrı kural hesabına; kanca ise birden çok grubun toplamına veya adımın genel sonucuna uygundur. Oyuncu komutu ve zamanlayıcı da kendi tetik koşulunda çalışır. Mod yazarı çağrı yolunu hız varsayımına göre değil, kuralın kapsamı ve çalışma zamanına göre seçer; çelişen hareketlerin oyun açısından sonucu da modun tasarım kararıdır. Kanca, komut ve zamanlayıcı yolları kullanılmaya devam eder.
Bedeli ne?
İstekler sistem aşaması boyunca görünmez; mod aynı aşamada yeni konumu okuyamaz. Her iş parçasının istek üst sınırı vardır: aşılırsa o parça başarısız olur ve kendi kuyruğundaki hareketler atılır. Sınır kişi sayısını değil, istek sayısını kapsar.
Sırada ne var?
Kaynaklarda bu yeteneği kullanan hazır bir oyun kuralı veya aynı koşullarda yeni ölçüm yok. Anlamlı bir sonraki değerlendirme, gerçek bir oyun kuralı ve onun ölçülebilir etkisi için ayrı kanıt oluştuğunda yapılabilir.
Sık sorulanlar
Motor artık nüfusun ne zaman göç edeceğine karar veriyor mu?
Hayır. Motor modun gönderdiği hareket isteğini uygular. Hangi grubun hangi koşulda taşınacağını oyun ve modun kuralı belirler.
Yeni hareket yolunda grupları ayrıca işaretlemek gerekiyor mu?
Hayır. Sistem kendi işlediği gruplar için isteği doğrudan üretebilir; işaretli grup listesi, seçim için ayrı bir kolaylıktır.
Kancalarla verilen hareket istekleri kaldırıldı mı?
Hayır. Kanca, komut ve zamanlayıcıdaki mevcut yollar duruyor. Yeni olan, hareket isteğinin bir sistem işinden de verilebilmesidir.
Bu değişiklik sistem yolunu hızlandırdı mı?
Aynı koşullarda yapılmış yeni bir süre ölçümü yok. Bu nedenle hızlanma iddiasında bulunmuyoruz.
Daha önce modlar için nüfus ve pazar işlemlerini anlattığımız Geliştirici Günlüğü #26 bu değişikliğin bağlamını verir. MKA Engine, geliştirici günlükleri ve iletişim sayfalarından diğer çalışmaları da inceleyebilirsiniz.