Как я могу внедрить деревья диалогов в мою игру?


51

Каков наилучший способ реализовать систему дерева диалогов в моей игре? Я хочу, чтобы NPC дал игроку различные наборы ответов, некоторые из которых могут появиться только тогда, когда у игрока есть предмет или произошло предыдущее событие.


2
BOUNTY специально для хороших идей о том, как обрабатывать переводы триггерных фраз и текста NPC. Так что NPC может понимать и говорить на разных языках в зависимости от игрока, который начал разговор. Даже при использовании подхода строительных блоков в gamedev.stackexchange.com/questions/31/… не очень хорошая идея иметь логику внутри текстовых репозиториев. Но их разделение усложняет понимание кода.
Хендрик Браммерманн

Ответы:


17

Деревья диалогов должны быть сделаны с использованием XML. Вы сохраняете условия для ответов и ответов во вложенных деревьях со ссылкой на файл сценария, если вам нужно сделать что-то более сложное.

Вы должны держать сценарии и диалоги отдельно, особенно если вы собираете RPG, у которой есть метрическая тонна разговоров. Затем вы можете использовать библиотеку типа simpleXML для чтения файла XML.

Схожий вопрос по SO с примером: https://stackoverflow.com/questions/372915/game-logic-in-xml-files


+1 за XML. Гораздо лучше, чем встраивание в сам код, позволяет вносить изменения без перекомпиляции кода и является стандартным форматом, который может быть прочитан некоторыми мощными редакторами.
AttackingHobo

34
XML - это просто формат (и, IMO, плохой). На самом деле этот ответ говорит: «Создайте небольшой предметный язык, который содержит базовую логику и потоки, но в основном состоит из вашего диалога, и анализируйте его». Таким образом, я согласен с этим ответом.
Ipsquiggle

5
Точно, XML - это просто контейнер, вы также можете (и определенно более читабельный и редактируемый человеком) реализовать это, используя Lua или другие языки сценариев.
LearnCocos2D

4
XML дорогой для анализа и занимает много памяти. Хорошо использовать его в качестве формата хранения, но я бы написал утилиту, которая преобразует деревья диалогов в двоичный формат, который используется во время выполнения. Если вы работаете на ПК и не заботитесь об использовании памяти, это может быть хорошо, но на любой другой платформе стоимость памяти будет вам не по карману.
BigSandwich

1
-1 для XML. Я согласен с @Ipsquiggle и @BigSandwich
o0 '.

20

Я хотел бы изучить встраивание языка сценариев, такого как lua ​​или ruby, и кодирование диалоговых взаимодействий в этом.

Таким образом, скрипт диалога может выглядеть так:

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!"

Это также хорошо работает для кодирования ИИ и других простых вещей, которые полезно настроить во время выполнения. Вы даже можете добавить редактор, встроенный в ваше приложение, который можно вызывать при запуске в режиме отладки (или в качестве пасхального яйца).


1
Я предпочитаю это прямому XML, так как вы можете добавить логику. Но я бы сказал, что сам текст должен быть скорее в XML, чем в коде. (проще редактировать, локализовать на другие языки и т. д.).
Иан

если вам нужна локализация / более легкое редактирование, вы можете обернуть текст в функцию, которая записывает вложенный текст в отдельный файл, такой как функция / макрос tr (QString) в Qt. pepper.troll.no/s60prereleases/doc/linguist-hellotr.html
Nailer

Что мешает вам использовать атрибуты или дополнительные теги в XML для симуляции логики здесь?
lathomas64

16

В игре Stendhal мы используем конечный автомат для реализации NPC.

На следующей диаграмме показан небольшой пример из руководства по написанию квестов .

FSM с состояниями IDLE, ATTENDING и QUEST_OFFERED

В начале, NPC находится в состоянии ожидания и может ходить. Игрок может начать разговор, сказав «привет», и NPC перейдет в состояние ATTENDING. В этом состоянии он отвечает на вопросы о своей «работе» и предлагает игровую «помощь». Игрок может попросить квест, и NPC перейдет в состояние QUEST_OFFERED, ожидая, когда игрок примет («да») или отклонит («нет») его.

Мы определили набор условий, которые могут быть прикреплены к переходам. Например, завершение квеста возможно только в том случае, если выполнено PlayerHasItemWithHimCondition .

После выполнения перехода NPC может сказать какой-нибудь текст и / или выполнить действие. Подобно условиям, мы определили повторно используемый набор действий, такой как EquipItemAction, который используется, чтобы дать игроку награду за квест.

Несколько условий могут быть объединены с использованием AndCondition , OrCondition и NotCondition . Обычно по завершению квеста нужно выполнить ряд действий, поэтому есть и класс MultipleActions .

Хотя реальная реализация в Stendhal страдает от того, что ее трудно перевести на другие (человеческие) языки, я думаю, что общая концепция хороша.


5

Вы можете взглянуть на инструмент Dlgedit движка Open Source RPG Adonthell . Он очень продвинутый и должен содержать все, что вам нужно (включая источники;))


5

Я думаю, что для добавления в переводы вы все равно можете использовать XML для логики, как указано выше . Когда вы попадаете в такую ​​сложность, вы должны написать свой собственный инструмент для диалога. Текст вашего диалога будет храниться как ключ к базе данных, которую вы можете поменять в зависимости от языка, который вы хотите отобразить.

Например, вы могли бы иметь:

<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>

Затем вам нужно было бы заменить текстовое средство визуализации квеста "Localize.FixMyCar" соответствующим образом переведенным текстом.

Ваш инструмент будет отображать то, что игрок увидит на выбираемом языке вместе с редактируемым необработанным XML.

Точно так же вы можете использовать что-то вроде этого из приведенного вами примера :

npc.add(ConversationStates.ATTENDING,
        ConversationPhrases.QUEST_MESSAGES, 
        null,
        ConversationStates.QUEST_OFFERED, 
        Localization[ "BringMeABeer" ],
        null);

Если ваши ключи достаточно наглядны, отсутствие полного текста не должно быть проблемой.

Нечто подобное может быть полезным:

Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];

4

Данные управляют вашими персонажами с помощью скриптов LUA или даже файлов XML. Когда вы взаимодействуете с NPC, возьмите файл, который к нему прикреплен, прочитайте его, отрегулируйте любые игровые переменные, которые могли быть вызваны, и сгенерируйте правильный ответ.

Самый большой выигрыш от этого - то, что вы можете легко входить и манипулировать диалогом, добавлять новые символы и т. Д. Вы также избегаете путаницы в своей кодовой базе со специальной логикой в ​​обработке каждого случая.


1
Это Луа, а не Луа. :)
RCIX

2
Я сделал это только для тебя, чувак. ;)
Дэвид Макгроу

4

Если вы используете XML, убедитесь, что вы создали небольшой инструмент для редактирования файла XML. В противном случае вы сойдете с ума.


Если инструмент для его редактирования уже не существует, использовать его бессмысленно: создайте свой собственный формат!
о0 '.

3

Если у вас довольно глубокий набор диалоговых деревьев, используйте ChatMapper . Они имеют полнофункциональную бесплатную версию, а инструмент позволяет вам экспортировать ваши диалоговые деревья в XML. Я использую его, и это отличный способ визуализации и организации сложных диалоговых деревьев.


1

Если ваши диалоги имеют какую-либо сложность, самое важное, что вам нужно для реализации диалога, - это способ понять сложность вашего взаимодействия. Я рекомендую некоторый редактор Node для визуализации этого, хотя у меня нет хороших открытых систем, чтобы рекомендовать.


1

Я думаю, что вы используете свой собственный язык сценариев для управления играми такого типа (если нет, то должны). Затем разверните свой сценарий для обработки диалогов.
Вы можете работать с другими игровыми переменными при создании логики диалогов. Игровые движки похожи на лего. Вы запрограммировали только кирпичи и скрипт использует их. Неважно, если вы сделаете какой-нибудь скрипт-интерпретатор или компилятор. Но скрипт всегда полезен.


0

Простой автомат может сделать:

(dialogueline_id, condition) -> (next_id, response)

Это может выглядеть примерно так:

(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!!!")

В игре вы найдете идентификатор и попробуйте сопоставить идентификатор и условие.

Вам нужно смоделировать условия и действия. По объектам, указателям на функции, XML ...

Хороший редактор диалогов тоже пригодится.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.