Як працюють діалогові дерева?


20

Тобто, що пов’язано з тим, що і як рухатись між рядками мови, коли закінчується підрозмова?

Якщо у вас є будь-які приклади базового діалогового дерева в C #, опублікуйте їх.


Я думаю, що було б здорово мати dialog-treeтег.
user1306322

Запит на зразки коду зазвичай не сприймається сприятливо.
MichaelHouse

Якщо є кілька зразків коду з діалогового дерева 101, якими варто поділитися, це не може зашкодити.
user1306322

Проблема полягає в тому, що цей сайт стосується отримання правильних відповідей на запитання. Це не для збору зразків коду.
MichaelHouse

Ось чому речення починається з "якщо". Але те, про що я прошу, - це пояснення того, як діалогові рядки з'єднуються між собою таким чином, щоб їх можна було ефективно перевести в код. Зрештою, я збираюся написати це на C #.
user1306322

Відповіді:


24

Назва "дерево діалогу" трохи вводить в оману - вони, як правило, прості спрямовані графіки , а не просто дерева . Основна структура даних таких графіків зазвичай складається з якихось "даних" для вузлів, які представляють точки, в яких ми знаходимося в розмові, і посилань з них на інші вузли, які представляють те, що говорять і роблять учасники і, можливо, мати на них умови для обмеження їх видимості чи сценаріїв для виконання різних додаткових дій. Зазвичай одним із вузлів є початковий вузол за замовчуванням (типовими мітками для цього є "ROOT", "START" та "GREETING"), і вузли, які не мають дійсних посилань, що ведуть від них, закінчують розмову.

У більшості випадків графік представлений в пам'яті як перелік Nodeструктур даних, кожна з яких має щонайменше ідентифікатор та список 0..n Linkструктур даних. Список може бути локальним для NPC або глобальним; другий випадок кращий, якщо у вас є багато загальних NPC, з якими можна поговорити для інформації, але не пропонуйте конкретних розмов самостійно. Система сама знаходить стартовий вузол розмови для NPC, запам'ятовує свій ідентифікатор як поточний ідентифікатор розмови, представляє поточні посилання гравця, який вибрав (або "[закінчити розмову]", якщо немає дійсних посилань) і чекає вхід. Коли гравець вибирає посилання, відображаються пов'язані рядки діалогу та запускаються будь-які пов'язані сценарії.

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


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

введіть тут опис зображення


+1 Якщо згадати правила та умови на посиланнях, простого орієнтованого графіка часто недостатньо, і все може ускладнитися, коли вам вони потрібні.
Лоран Кувіду

+1 Мені подобається ця структура краще. Хоча я б не рекомендував це як перший пропуск. Я б почав з чогось більш простого. Це, безумовно, краща ціль для стрільби.
MichaelHouse

+1 Для дуже детальної відповіді. Це згодом може стати для мене корисним.
Мартон

Це зображення мені дуже допомогло, але мені потрібно задуматися, чому DialogueLine відокремлений від Посилання? Чи не кожне посилання має власний текст відповіді? І куди б пішов текст NPC? Чи не було б сенсу мати його у вузлі?
Кайл Баран

@Danjen У цій структурі посилання може мати декілька DialogueLines, можливо, від різних символів, поки не з’явиться наступний вибір діалогу. Тут також іде текст NPC. Коли рядки повторюються, різні Посилання можуть обмінюватися DialogueLines, можливо, переупорядковуючи їх у своєму списку (Вектор), замінюючи їх частини різними рядками, додаючи завивки тощо.
Мартін Сойка

16

Діалогові дерева створюються із спрямованою структурою графа .

введіть тут опис зображення

Графік проходить на основі діалогових рішень, які приймає гравець. Параметри діалогу, надані користувачеві, надходять із країв, які визначають шляхи до інших діалогових вузлів.

Напрямні графіки - це основна структура даних. Їх легко реалізувати, і ви, швидше за все, захочете їх реалізувати самостійно. Оскільки ви хочете пристосувати графік до потреб вашого діалогу.

Для відображення для деяких вузлів можуть бути дотримані спеціальні умови. Наприклад, гравцеві потрібна навичка мовлення вище X. Або гравцеві потрібно виконати місію Z, перш ніж він зможе просуватися по одній гілці діалогу. Або їм потрібно запитати щось 4 рази, перш ніж NPC обговорить це з ними. Ці функції будуть підлаштовані під вашу гру. Але варто згадати, коли ви реалізуєте обхід вузла та ребер. Звичайно, завжди найкраще починати з найпростішої форми і будувати звідти.


Я просто не можу зрозуміти, що робити у таких випадках, як "Ньютон-бід". Наприклад, як встановити порядок цих рядків у коді, не повторюючи їх.
user1306322

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

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

7

Я створив просту діалогову систему: http://iki.fi/sol/d3/ сам "двигун" наразі є звичайним c, але дані, видані редактором, досить прості у використанні будь-якою мовою. Інструмент виводить XML, JSON і нестандартний бінарний формат.

Основна концепція досить проста:

Ти в лабіринті закручених маленьких уривків, однаково

Кожен вузол (який я називаю "карткою", як і вищезгаданий аналог) діалогового вікна складається з тексту запитання та нуля або більше відповідей. Кожна з відповідей веде до іншої картки.

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

Це майже все, що потрібно робити майже про будь-який діалог в грі. "Текст запитання" може бути простим текстом, або це сценарій для анімації або щось подібне.


4

Ви можете використовувати TreeSharp та дерева поведінки для моделювання діалогової системи. TreeSharp - це бібліотека, яка забезпечує просту реалізацію дерева поведінки. IA боти для wow зроблені з цим, так що він зрілий ... :)

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

Я використовував мозковий редактор, щоб зробити його візуально ... але наприкінці він створює код C # на основі дерев ...

http://www.youtube.com/watch?v=6uGg6bUYyUU


2

Ви хочете направити (можливо, циклічний) графік.

Ви будете моделювати вузли як об’єкти, і всі вихідні стрілки у вузлі графа теж моделюються як окремі об'єкти. Вузол має список вихідних стрілок, і кожен об’єкт "стрілки" має текст для відображення та посилання на пункт призначення. Не впевнений, але я думаю, що на об'єкти C # завжди посилаються, тому ви просто створіть спочатку об'єкти, а потім, коли ви створюєте об'єкти зі стрілками, підключіть той самий об’єкт до поля призначення двох стрілок. (У C ++ ви б використовували тип посилання чи вказівника, вузол та вузол *)

Для завантаження таких речей з диска зазвичай кожен вузол надає унікальний ідентифікаційний номер, а потім завантажує всі вузли в масив, де індекс - це унікальне число. Потім стрілки серіалізуються, записуючи число, а не власне об'єкт.

Завантажуючи стрілку, ви використовуєте масив та ідентифікатор, щоб отримати посилання на вузол, на який вказує. Якщо ви два рази виписали об'єкт, ви отримаєте два окремих об’єкти, які просто виглядають однаково, що, мабуть, не те, що ви хотіли.

Обробка діалогового дерева стає дуже простою. Ви просто помістіть кореневий вузол у currentNodeзмінну, відображаєте все так чи інакше, а тоді, коли буде зроблений вибір, встановіть rootNodeпризначення пункту призначення стрілки. У псевдокоді:

Node&    currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
    stage.displayNode( currentNode );
    currentNode = stage.waitForUserToChoose();
}

1

Нещодавно мені довелося розробити щось подібне за допомогою Node, і вибрав дуже базову структуру текстового файлу, щоб представити спрямований графік вузлів розмови.

Отриманий код та формат тексту ви можете побачити на:

https://github.com/scottbw/dialoguejs

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

(Сам код у GPL, btw)


Питання задає C #.
Сет Баттін

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