Який найкращий спосіб застосувати систему діалогового дерева у своїй грі? Я хочу, щоб NPC дав гравцеві різні набори відповідей, деякі з яких можуть з'являтися лише тоді, коли у гравця є предмет або відбулася попередня подія.
Який найкращий спосіб застосувати систему діалогового дерева у своїй грі? Я хочу, щоб NPC дав гравцеві різні набори відповідей, деякі з яких можуть з'являтися лише тоді, коли у гравця є предмет або відбулася попередня подія.
Відповіді:
Діалогові дерева слід робити за допомогою XML. Ви зберігаєте умови для відповідей та відповіді у вкладених деревах із посиланням на файл сценарію, якщо вам потрібно зробити щось більш складне.
Ви повинні тримати сценарії та діалогове вікно окремо, особливо якщо ви збираєте RPG, який має метричну тону розмов. Потім ви можете використовувати бібліотеку типу simpleXML для читання файлу XML.
Існує подібне запитання щодо SO із прикладом: https://stackoverflow.com/questions/372915/game-logic-in-xml-files
Я б розглядав вбудовану мову сценаріїв на зразок луа чи рубіну та кодування діалогових взаємодій у цьому.
Таким чином діалоговий скрипт може виглядати так:
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 та інших простих речей, корисних для налаштування під час виконання. Ви навіть можете додати редактор, вбудований у свою програму, який можна викликати під час роботи з налагодження (або як писанка).
У грі Stendhal ми використовуємо скінчену машину для впровадження NPC.
На наступній схемі показаний невеликий приклад із того, як писати навчальний посібник .
На початку NPC перебуває в стані простою і може ходити. Гравець може почати розмову, сказавши "привіт", і NPC перейде до стану "УВАГА". У такому стані він відповідає на питання про свою "роботу" і пропонує певну гру "допомога". Гравець може попросити квест, і NPC перейде в стан QUEST_OFFERED, чекаючи, коли гравець прийме ("так") або відхилить ("ні") його.
Ми визначили набір умов, які можна приєднати до переходів. Наприклад, виконати квест може бути можливим лише за умови дотримання PlayerHasItemWithHimCondition .
Після виконання переходу NPC може сказати деякий текст та / або виконати дію. Аналогічно умовам, ми визначили багаторазовий набір дій, таких як EquipItemAction, який використовується, щоб дати винагороду квесту гравцеві.
За допомогою AndCondition , OrCondition та NotCondition можна комбінувати кілька умов . Зазвичай для завершення квесту потрібно виконати ряд дій, тому існує і клас MultipleActions .
Хоча реальна реалізація Stendhal страждає від того, що вона не може легко перекладатися на інші (людські) мови, я думаю, що загальна концепція є хорошою.
Я думаю, що для додавання в переклади ви все ще можете використовувати 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>" ];
Дані керують вашими персонажами за допомогою скриптів LUA або навіть файлів XML. Під час взаємодії з NPC, захопіть доданий до нього файл, прочитайте його, налаштуйте будь-які змінні гри, які, можливо, були запущені, та виправдайте дійсну відповідь.
Найбільший прибуток від цього таким чином - ви можете легко зайти та маніпулювати діалоговим вікном, додати нові символи тощо. Ви також уникаєте мутизувати свою кодову базу спеціальною логікою в обробці кожного конкретного випадку.
Якщо у вас досить глибокий набір діалогових дерев, використовуйте ChatMapper . У них є повнофункціональна безкоштовна версія, і інструмент дозволяє експортувати діалогові дерева в XML. Я використовував його, і це прекрасний спосіб візуалізації та організації складних дерев діалогів.
Якщо ваші діалоги мають будь-яку складність, найголовніше, що вам знадобиться для впровадження діалогу, це спосіб зрозуміти складність вашої взаємодії. Я рекомендую який-небудь редактор Node для візуалізації цього, хоча я не маю жодної хорошої відкритої системи, яку б рекомендувати.
Я думаю, що ви використовуєте свою власну мову скриптів для керування цим типом гри (якщо ні, то слід). Потім розгорніть свій скрипт і для обробки діалогів.
Ви можете працювати з іншими змінними гри під час створення логіки діалогів. Ігрові двигуни схожі на Lego. Ви запрограмовані лише цеглини, а сценарій їх використовує. Не має значення, чи ви робите якийсь інтерпретатор сценарію чи компілятор. Але сценарій завжди корисний.
Простий автомат може зробити:
(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 ...
Добрий редактор діалогу також буде корисний.