Як я можу реалізувати діалогові дерева у своїй грі?


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

Я б розглядав вбудовану мову сценаріїв на зразок луа чи рубіну та кодування діалогових взаємодій у цьому.

Таким чином діалоговий скрипт може виглядати так:

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

Це також добре працює для кодування AI та інших простих речей, корисних для налаштування під час виконання. Ви навіть можете додати редактор, вбудований у свою програму, який можна викликати під час роботи з налагодження (або як писанка).


1
Я віддаю перевагу цьому прямому XML, оскільки ви можете додати логіку. Але я б сказав, що сам текст, мабуть, повинен бути в XML, а не в коді. (простіше редагувати, локалізувати на інших мовах тощо).
Iain

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

Що не дозволяє використовувати атрибути чи додаткові теги в XML, щоб імітувати логіку тут?
lathomas64

16

У грі Stendhal ми використовуємо скінчену машину для впровадження NPC.

На наступній схемі показаний невеликий приклад із того, як писати навчальний посібник .

FSM зі станами IDLE, ATTENDING та QUEST_OFFERED

На початку NPC перебуває в стані простою і може ходити. Гравець може почати розмову, сказавши "привіт", і NPC перейде до стану "УВАГА". У такому стані він відповідає на питання про свою "роботу" і пропонує певну гру "допомога". Гравець може попросити квест, і NPC перейде в стан QUEST_OFFERED, чекаючи, коли гравець прийме ("так") або відхилить ("ні") його.

Ми визначили набір умов, які можна приєднати до переходів. Наприклад, виконати квест може бути можливим лише за умови дотримання PlayerHasItemWithHimCondition .

Після виконання переходу NPC може сказати деякий текст та / або виконати дію. Аналогічно умовам, ми визначили багаторазовий набір дій, таких як EquipItemAction, який використовується, щоб дати винагороду квесту гравцеві.

За допомогою AndCondition , OrCondition та NotCondition можна комбінувати кілька умов . Зазвичай для завершення квесту потрібно виконати ряд дій, тому існує і клас MultipleActions .

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


5

Ви можете ознайомитись з інструментом Dlgedit з відкритим кодом 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
Це Луа, а не LUA. :)
RCIX

2
Я зробив це тільки для тебе, чоловіче. ;)
Девід МакГрау

4

Якщо ви використовуєте XML, переконайтеся, що ви створили невеликий інструмент для редагування файлу XML. Інакше ти зійдеш з розуму.


Якщо вже не існує інструменту для його редагування, тоді безглуздо використовувати його в першу чергу: також створіть свій власний формат!
o0 '.

3

Якщо у вас досить глибокий набір діалогових дерев, використовуйте ChatMapper . У них є повнофункціональна безкоштовна версія, і інструмент дозволяє експортувати діалогові дерева в XML. Я використовував його, і це прекрасний спосіб візуалізації та організації складних дерев діалогів.


1

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


1

Я думаю, що ви використовуєте свою власну мову скриптів для керування цим типом гри (якщо ні, то слід). Потім розгорніть свій скрипт і для обробки діалогів.
Ви можете працювати з іншими змінними гри під час створення логіки діалогів. Ігрові двигуни схожі на Lego. Ви запрограмовані лише цеглини, а сценарій їх використовує. Не має значення, чи ви робите якийсь інтерпретатор сценарію чи компілятор. Але сценарій завжди корисний.


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

У грі ви знаходите ідентифікатор і намагаєтеся відповідати id та умові.

Потрібно моделювати умови та дії. За об'єктами, функціональними вказівниками, XML ...

Добрий редактор діалогу також буде корисний.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.