Oyunumda bir iletişim ağacı sistemi uygulamanın en iyi yolu nedir? Bir NPC'nin, oyuncuya yalnızca bir öğeye sahip olduğu veya önceki bir etkinlik gerçekleştiği zaman ortaya çıkabilecek farklı yanıt gruplarını vermesini istiyorum.
Oyunumda bir iletişim ağacı sistemi uygulamanın en iyi yolu nedir? Bir NPC'nin, oyuncuya yalnızca bir öğeye sahip olduğu veya önceki bir etkinlik gerçekleştiği zaman ortaya çıkabilecek farklı yanıt gruplarını vermesini istiyorum.
Yanıtlar:
Diyalog Ağaçları XML kullanılarak yapılmalıdır. Daha karmaşık bir şey yapmanız gerekirse yanıtların koşullarını ve iç içe geçmiş ağaçlardaki yanıtı bir komut dosyasına referans olarak saklarsınız.
Senaryoları ve diyalogu ayrı tutmalısın, özellikle de tonlarca konuşmaya değer bir RPG hazırlıyorsan. XML dosyasını okumak için simpleXML gibi bir kütüphane kullanabilirsiniz.
SO ile benzer bir soruya bir örnek daha var: https://stackoverflow.com/questions/372915/game-logic-in-xml-files
Lua ya da yakut gibi bir betik dili eklemeye ve buradaki diyalog etkileşimlerini kodlamaya çalışırdım.
Böylece bir iletişim komut dosyası gibi görünebilir:
switch showDialog "Why don't you just leave me along!", "Okay", "But I found your dog!"
case 1:
showDialog "And stay gone!"
case 2:
if playerHasObject "dog"
showDialog "Thank you!"
else
showDialog "Liar!"
Bu aynı zamanda AI kodunu ve çalışma süresi boyunca ince ayar yapabileceğiniz diğer basit şeyleri kodlamak için de işe yarar. Hata ayıklama modunda (veya bir Paskalya Yumurtası olarak) çalıştırırken çağrılabilecek, uygulamanızın içinde yerleşik bir düzenleyici bile ekleyebilirsiniz.
Oyunda Stendhal, NPC'leri uygulamak için sonlu bir durum makinesi kullanıyoruz.
Aşağıdaki diyagramda görevler öğreticinin nasıl yazılacağına ilişkin küçük bir örnek gösterilmektedir .
Başlangıçta, NPC bir IDLE durumundadır ve dolaşıyor olabilir. Bir oyuncu "merhaba" diyerek sohbete başlayabilir ve NPC ATTENDING durumuna geçecektir. Bu durumda “işi” ile ilgili sorulara cevap verir ve bazı oyunlarda “yardım” sunar. Oyuncu bir görev isteyebilir ve NPC, oyuncunun kabul etmesini ("evet") veya reddetmesini ("hayır") bekleyerek QUEST_OFFERED durumuna geçecektir.
Geçişlere eklenebilecek bir dizi koşul tanımladık . Örneğin, bir görevi tamamlamak yalnızca bir PlayerHasItemWithHimCondition ile karşılaşıldığında mümkün olabilir .
Bir geçiş yapıldıktan sonra NPC bir miktar metin söyleyebilir ve / veya bir eylem yürütebilir. Koşullara benzer olarak, oyuncuya bir görev ödülü vermek için kullanılan EquipItemAction gibi tekrar kullanılabilir bir eylemler kümesi tanımladık .
AndCondition , OrCondition ve NotCondition kullanılarak birden fazla koşul birleştirilebilir . Genellikle, görev tamamlandığında yapılması gereken çok sayıda eylem vardır, bu yüzden bir MultipleActions sınıfı da vardır.
Stendhal'daki gerçek uygulama diğer (insan) dillerde kolayca çevrilememekle sıkıntı çekse de, genel kavramın iyi olduğunu düşünüyorum.
Açık Kaynak RPG motoru Adonthell'in Dlgedit aracına bir göz atabilirsiniz . Çok gelişmiş ve ihtiyacınız olan her şeyi içermelidir (kaynaklar dahil;)
Bence çeviriler eklemek için hala yukarıda belirtildiği gibi mantık için XML kullanabilirsiniz . Bu tür bir karmaşıklığa girerken, kendi diyalog aracınızı yazmalısınız. Diyalog metniniz, görüntülemek istediğiniz dile bağlı olarak değiştirebileceğiniz bir veritabanının anahtarı olarak saklanır.
Örneğin şunları yapabilirdiniz:
<dialogue id="101" condition="!npc.carsFixed">
<message>Localize.FixMyCar</message>
<choices>
<choice condition="hero.carFixingSkill > 5" priority="7" id="Localize.Sure">
<command>hero.carFixingSkills += 1</command>
<command>npc.carFixed = true</command>
<command>hero.playSmokeAnimation()</command>
<command>nextDialogue = 104</command>
</choice>
<choice condition="hero.carFixingSkill <= 5" id="Localize.CantFix">
<command>nextDialogue = 105</command>
</choice>
<choice id="Localize.FixYourself">
<command>npc.likesHero -= 1</command>
</choice>
</choices>
</dialogue>
Daha sonra görev metin oluşturucusunun "Localize.FixMyCar" yerine uygun bir şekilde çevrilmiş olan metni değiştirmesini istersiniz.
Aracınız, oynatıcının düzenlenebilir ham XML ile birlikte seçilebilir bir dilde ne göreceğini gösterir.
Benzer şekilde, başvurduğunuz örnekten böyle bir şey kullanabilirsiniz :
npc.add(ConversationStates.ATTENDING,
ConversationPhrases.QUEST_MESSAGES,
null,
ConversationStates.QUEST_OFFERED,
Localization[ "BringMeABeer" ],
null);
Anahtarlarınız yeterince açıklayıcıysa, metnin tamamının olmaması bir sorun olmamalıdır.
Böyle bir şey de yararlı olabilir:
Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];
Veri, karakterlerinizi LUA komut dosyaları ve hatta XML dosyaları ile yönlendirir. Bir NPC ile etkileşime geçtiğinde, ona bağlı olan dosyayı al, oku, tetiği olabilecek oyun değişkenlerini ayarla ve geçerli cevabı ver.
Bu şekilde yapmanın en büyük kazancı, kolayca içeri girip diyaloğu değiştirebilir, yeni karakterler ekleyebilir, vb. Ayrıca, her bir durumu ele alırken kod tabanınızı özel bir mantıkla karıştırmaktan kaçınırsınız.
Çok derin bir iletişim ağacı kümeniz varsa , ChatMapper'ı kullanın . Tam özellikli bir ücretsiz sürümü var ve araç, iletişim ağaçlarınızı XML'e aktarmanıza olanak tanır. Kullanıyorum ve karmaşık diyalog ağaçlarını görselleştirmek ve organize etmek için mükemmel bir yol.
Diyaloglarınız herhangi bir karmaşıklığa sahipse, diyalog uygulaması için ihtiyaç duyacağınız en önemli şey, etkileşimin karmaşıklığını anlamanın bir yoludur. Bunu önermek için iyi bir açık sistemim olmasa da, bunu görselleştirmek için bir tür Düğüm editörü öneririm.
Bence bu senaryoyu yönlendirmek için kendi senaryo dilinizi kullanıyorsunuz (olmasanız da gerekir). Daha sonra komut dosyalarınızı da işlemek için genişletin.
Diyalog mantığı oluşturma sırasında diğer oyun değişkenleriyle çalışabilirsiniz. Oyun motorları Lego'ya benziyor. Sadece tuğlaları programladınız ve script bunları kullanıyor. Bazı script tercüman veya derleyici yapmak farketmez. Ancak script her zaman yararlıdır.
Basit otomat şunları yapabilir:
(dialogueline_id, condition) -> (next_id, response)
Böyle bir şeye benzeyebilir:
(1, troll is hungry?) -> (2, say "troll be hungry")
(2, player has bananas?) -> (3, say "hey, you have bananas!")
(3, ) -> (-1, (say "i like bananas, i take them and eat, you may pass, bye", remove bananas, feed the troll))
(2, player does not have bananas?) -> (-1, say "go away!!!")
Oyunda sen kimliği bulmak ve kimliği ve koşulu eşleştirmeyi deneyin.
Koşulları ve eylemleri modellemeniz gerekir. Nesnelere göre, işaretçiler, XML ...
İyi bir diyalog düzenleyicisi de kullanışlı olacaktır.