NMORPG Notları: Multiplayer
4 min read

NMORPG Notları: Multiplayer

NMORPG bir sene önce, bugünkünden çok daha fazla özellik içeriyordu. Devasa bir harita, otomatik oluşturulan bitki örtüsü, karakter özelleştirme, nesnelerle etkileşim ve çoklu kullanıcı desteği ile 2021 başında herkese açık bir sürüm çıkarabileceğini sanıyordum.

gRPC ve Golang ile MMO yapabilir miyim derken başladığım RPG maceramda, ilk prototipten bu yana ellemediğim multiplayer desteğinin çok sıradan senaryolarda bile çalışmayacağını anladığımda, vaktimi NMORPG'nin M'sine ayırmaya karar verdim ve olaylar gelişti...

Prototipte, kullanıcı haritaya tıklayarak ilerliyor ve gitmek istediği koordinat basit bir gRPC mesajı ile sunucuya bağlı herkese iletiliyordu. Area of Interest desteği için erkendi, kullanıcının farkedemeyeceği kadar uzak mesafedeki karakterlere ait bilgilerin gönderilmemesi gibi optimizasyonlar ile uğraşmadan evvel onlarca kullanıcıya ulaşmam gerekiyordu.

Sunucudan gelen her veriye güvenebilirdim, otorite sunucuya aitti, her komut sunucuda kontrol ediliyordu. İstemcilerin ağ paketlerini değiştirip diğer istemcileri kandırması pek mümkün değildi. gRPC sayesinde hareket, atak ya da büyü gibi komutların kullanıcıya ulaşamaması gibi bir ihtimal de yoktu, o yüzden interpolation & extrapolation ile sunucudan eksik gelen hareket bilgisini kullanıcı ekranında akıcı hale getirmeye çalışmak için vakit harcamama gerek yoktu.

Farketmediğim başka, büyük bir problem vardı: Bir oyuncu koşma komutunu gönderdikten sonra, başka bir oyuncu giriş yaparsa koşma bilgisini bu kullanıcıya nasıl göndermem gerektiğine dair en ufak bir fikrim yoktu.

Sadece komutları tüm istemcilere göndermek yetmeyecek, belirli aralıklarla )eğer değişiklik varsa) kullanıcılara ait hareket bilgilerini tüm oyunculara bildirmek bir zorunluluktu ve bu mesaj trafiğini arttıracağından hem Area of Interest, hem de interpolation & extrapolation ile yüzleşmem gerekecekti.

Bir oyuncuya ait bilinen son konum bilgisi sunucuya geldikçe, koşma animasyonunu ve karakterin konumunu yeterince eksiksiz bir şekilde diğer oyunculara ait ekranlarda gösterebilmek için oyun tarafında mutlaka hareketi interpolate etmeliydim. Elde ne varsa bırakıp bunu nasıl yapacağımı öğrenmeye de, C# kodunu yazmaya da vakit yokken, en başında yapmam gereken şeyi yapmaya karar verdim: Hazır bir çözüm kullanmak.

Ne kullanacağıma karar verme kısmı, uygulama kısmından daha uzun sürdü. Unity 2020'de kullanabileceğim network çözümlerini tek tek denerken, MLAPI'nin Unity tarafından satın alındığını öğrendim ve diğer çözümlerle vakit kaybetmek yerine MLAPI'yi entegre etmeye başladım. Bu sırada, birçok şey öğrendim.


MLAPI özetle, sunucuya bağlanan her kullanıcı için önceden hazırladığınız oyuncu karakterini sahneye yerleştiriyor ve bunu tüm kullanıcılara bildiriyor. Her oyun, sadece kendine ait olan karakteri yönetecek ufak bir kod parçası ile karakteri haritada istediği gibi koşturup, animasyonlarını bu harekete göre değiştirirken; MLAPI bu hareketleri ve animasyonları tüm kullanıcılara iletip diğer taraftaki görüntünün "eninde sonunda" aynı görünmesi sağlıyor.

TCP yerine Reliable UDP kullanmanın, ağdaki gecikmelerin ve paket kayıplarının tüm oyunu değil, yalnızca bazı nesne ve karakter hareketlerini etkileyecek olması gibi bir avantajı var. Arada kaybolan paketler olduğunda, interpolation & extrapolation ile hareketteki boşluklar hesaplanıyor ve çok da yapay olmayan bir görüntü elde edilmesi sağlanıyor.

Siz koşma tuşuna bastığınızda, ekranınızda karakterin koştuğunu ve haritada yer değiştirdiğinizi görürken, bu bilgi diğer oyunculara gidene kadar kimse yer değişikliğinden haberdar olmuyor, ve bu yan yana iki ekranda oyunu oynayan oyuncularda görüntü farkına sebep oluyor. Nahoş bir görüntü, ama oynanabilirlik açısından çok da rahatsız edici değil. "Eninde sonunda" karakterler haritada aynı noktada görünüyor.

FPS/RPG/RTS harici bir oyun geliştiriyorsanız, mesela bir boardgame, hareketi iki tarafta da çok az farkla göstermek mümkün: Hareket et mesajı sunucuya ulaşıncaya kadar oyuncunun kendisine bile hareket göstermemek. Lakin bir RPG'de bunu istemezsiniz. Form doldururken, her karakterin önce sunucuya gitmesi, sonra da sizin ekranınızda belirmesi gibi.


Büyü ve ataklarda ise, bu türden bir gecikme hiç adil olmayabilir. Siz büyü yapmaya başladığınızda ve diğer oyuncular bunu görene kadar siz çoktan büyüyü tamamlamış ve saldırıya başlamış olabilirsiniz.

Bunu çözmek için, görsel açıdan rahatsız etmeyen ve ping süresine göre değişse de, koşma animasyonlarına göre çok daha ufak gecikmeli bir yöntem kullanıyorum.

Kullanıcı büyü yapmaya başladığında, kendi ekranında karakterin büyüye hazırlandığını hemen görüyor. Animasyon senkron sistemi, diğer kullanıcıların ekranında aynı animasyonun oynamasını sağlıyor ve bir süre sonra tüm oyuncular (ilk oyuncu dahil) tekrar eden bir "casting" animasyonu seyrediyor.

Büyü animasyonu başlamadan biraz evvel, sunucuya büyü yapıldığına dair bir mesaj gidiyor ve sunucu "casting" süresi kadar bekleyip her kullanıcıya "şimdi casting tamamlandı" diyor. Yan etki olarak, ilk kullanıcı için büyü yapma süresi kendi ping süresi kadar uzun görünüyor.

Ping süresi, oyuncunun koşma hızına bağlı olarak, karakterin yerini bir metre geriden göstermeyle sonuçlanırken, büyülerde çok daha tahammül edilebilir durumda.


Bu tür hilelerin görsel açıdan rahatsız edici olmaması ve teknik olarak sunucu ve istemciyi zorlamaması için, bazı tasarım kararları vermek ve oyun dünyasında kabul görmüş bir "gameplay" sunmak gerekiyor. Yaşasın büyülü ortamlar, doğal olmak ya da doğal göstermek gibi bir kaygı yok.

NMORPG'de tercih ettiğim, ya da mecbur kaldığım yöntem, gecikmeyi dert etmeden koşma hareketini herkese bildirmek ama büyülerin senkronizasyonunda görevi sunucuya atarak adil bir yapı kurmaya çalışmak oldu.

Oyunu iki ekranda yan yana açıp ilk denemeleri yaparken, 2004 yılında çıkan World of Warcraft'daki büyü sistemi ile kıyaslama yapmak ve 16 sene geriden gelerek benzer hileleri kullanmak eğlenceliydi.

Sırada HP, mana, hasar bilgisi gibi değişimleri senkron etme ve nesneler arası etkileşimi herkese bildirme var. Bakalım hangi hilelere başvurmak gerekecek.