Живой диалог с NPC. Чат или меню?

Когда я только начинал делать парсерные игры, ответ был для меня очевиден — ну конечно же чат с NPC! Ограниченное меню с вариантами меня тогда вообще не интересовало. Подождите-ка, а ведь в парсерных играх уже используется ASK-TELL система, вида: “спросить Машку про Дашку”, “рассказать Машке про Наташку”. Может не стоит изобретать велосипед? Решил попробовать эту систему в игре “Рыбак-рыбака”. Там был диалог с рыбаком в лодке. Не знаю как другие, но я не мог никак догадаться, о чем можно было его спросить и рассказать. Большинство попыток заканчивались провалом, так и не смог пройти это место, пока не увидел исходники и ключевые слова. Когда в других играх видел подобную систему, то практически сразу расстраивался — не хочу в новой игре таких сложностей! Всё-таки надо чатик делать. Будет красивый диалог, если что робот сам подскажет о чем беседовать и получиться легче. Немного покумекав, понял, что этого нужен чат-бот. Кое-как скрестив с одним из плееров, удалось связать чат-бота с моделью парсерного мира, игра вышла в свет.

Народ не понял крутость AI, я не понял почему народ не понял, и в итоге, мощная задумка провалилась. Потом мне самому стало ясно, и я прекратил всякие эксперименты с диалогом. Сейчас, мой выбор всегда в сторону менюшного диалога. Всё дело в передаче игрового опыта. Автор закладывает фиксированные реплики и диалог может стать справочником, системой управления виртуальным персонажем или некой встроенной миниигрой. Существует много руководств, как писать такие диалоги — это старый добрый проверенный подход. Останавливаться на нём не будем. Давайте посмотрим трудные моменты “живого” диалога через строку ввода с примерами из игры “Космический шпион”.

Сложность программирования реплик.

Для создания и отработки команд одного бота уйдёт масса сил и времени, а тестировать придётся огромное количество веток. Современные движки чат-ботов требуют вдумчивого подхода и с наскока не получиться одолеть такой барьер. Неудачный диалог с лифтёром:

>где моя каюта?
Даже не знаю что вам ответить
>сколько всего лифтов?
Да, лифт считается самым безопасным.
>как мне попасть на станцию?
Не совсем понятно что имелось ввиду
>что мне делать?
Не могу точно ответить
>расскажи про дачу
Не могу точно ответить
Человек стал относиться к боту как к справочному пособию по всему игровому миру и сюжету и стал пытать несчастного болванчика.

Связь с моделью внешнего мира.


Это отдельный вопрос, так как по-хорошему надо сделать боту доступ к информации о текущем состоянии предметов (игрок взял ключ?) и разрешение управления (открыть дверь после правильной ветки диалога). Решается болезненно, долго и сложно. Во время реализации столкнулся с такой бедой — движок после того, как топик был пройден, сработали нужные хуки, не мог к нему вернуться. Поэтому если человек в какой-то момент переедет на другую тему, то уже не вернутся на предыдущую и бот не сможет выполнить манипуляцию с миром.

Навести игрока на “правильное русло”.


Когда начинают общаться с ботами, зачастую включается “внутренний тестировщик”, который пытается проверить границы системы и задаёт дурацкие вопросы, не имеющие отношения к игровому миру. Нужно каким-то образом дать понять о чем должна происходить беседа и делать ненавязчиво. В “Космическом шпионе” это делалось за счет механизма перехвата инициативы (бот начинал гнуть свою линию, невзирая на реплики игрока), иногда воспринималось хорошо, иногда не очень, вот как было в разговоре со специалистом:

>хватит на меня пялиться, урод!
Если бы у меня было лазерное ружье, то ты бы побегал по станции, - сказал специалист и ухмыльнулся
>ты козел
Как думаешь, будет сегодня заварушка?
>ты скотина
Скучно, однако, без заварух
>закончим диалог
Ну и сколько ты будешь со мной трещать? Займиси делами!

Разговор без предыстории.


Допустим, пробежали вы пол-карты с топором, рубили драконов направо-налево, и повстречалась вам эльфийская принцесса. Как вы начнете диалог? Привет, как дела? Что-новенького? А может быть в предыстории было сказано что вы десять лет бок о бок сражались, а потом она убежала в своё королевство? И тут игрок принимает решение, что будет говорить с ней как великий и славный паладин 80-уровня, с отыгрышем роли, или как Вася с пятого подъезда с симпатичной блондинкой. В меню таких проблем нет, у вас четкие выборы с авторской атмосферой.
Диалог как функция. Очень часто ставят NPC для одной небольшой функции — дать справку или указание на следующее задание, для такого случая придётся ухищряться с игнорированием всех реплик игрока и сводя к стандартным ответам. Некрасиво.

Невозможность передачи подтекста сцены.

Вот это очень тонкий момент, которым страдает не только общение с ботами, но и между людьми в текстовом чате. Во время диалога всегда есть определённый контекст, который при живом общении передаётся невербально, а при чтении книг за счет описания эмоций. Cравните чатик героя и его старого друга:
— Привет! Как дела?
— Нормально.
Первая возможная сцена:
— Привет! Как дела? — Герой хоть и сказал фразу бодро но стоял как-то неуверенно. Сложно было смотреть в глаза старому другу, которого тот не видел несколько лет.
— Нормально. — Друг широко улыбнулся. Мягкий звук шагов и он встал рядом, как в былые времена. Лёгкий хлопок по плечу окончательно взбодрил героя.
Второй вариант:
— Привет! Как дела? — герой торопясь на очередную встречу, чуть не сбил по пути старого друга.
— Нормально. — Друг широко улыбнулся. Его кулаки крепко сжались, а потом расслабились. Он так и не простил былую обиду, но найдёт подходящее время для того, чтобы свести счёты.
Понятно, что пример не совсем корректный, но принцип остаётся — в рамках одного диалога, может быть бесконечное количество вариаций подтекстов. Чат это всё стирает, а вот реализация через меню позволяет лёгко. В визуальных новеллах еще можно передавать эмоции через аватарки и нарисованных персонажей.

Выводы

Как вы поняли, теперь я сторонник менюшных диалогов в любых текстовых играх. Большинство приведенных проблем субъективные и основаны на личном опыте использования парсера и движка чатботов. Скорее всего есть научные статьи с более точными формулировками и определениями, не знаю, так не углублялся в предмет. Надеюсь в будущем придумают комфортную диалоговую систему как для авторов, так и для игроков.

Скачать

Итак, кому интересно, я сделал отдельную сборку для двух чатботов из игры “Космический шпион” под Windows.
Чат-бот лифтёра: cloud.mail.ru/public/Ey5g/qHFHnyEQF
Чат-бот специалиста: cloud.mail.ru/public/EP3D/ZNbvYbhKW
Они полностью готовы для общения, просто запускаете исполняемый файл и вводите в зеленое поле текст, нажатием Enter или кнопкой отправляете движку. На всякий случай приведу отличие этих ботов от стандартных:
  • Движок chatscript. Боты на этом движке получали премию Лёбнера в 2014, 2015 году (из наиболее свежих результатов).
  • Ориентированность на сюжет. Бот обладает небольшим количеством знаний в рамках сюжета игры.
  • Перехват инициативы. Бот не просто выдаёт фразу, в ответ, а может сам попробовать построить диалог.
  • Общение с определённой целью. Игрок разговаривает с ботом не просто так, а чтобы добиться какого-то эффекта, например чтобы пройти тест в ходе беседы или больше спрашивать, чтобы показать свой интерес к теме и бот ему открыл какую-нибудь дверь.

7 комментариев

Oreolek
Так и не понял, чем не понравилась ASK-TELL система. Чатбот не сможет одновременно реалистично вести диалог и намекать на доступные ключевые слова, а вот обмен по одной реплике с малоразговорчивым NPC — это достаточно удобно, если геймдизайн нормальный.

В крайнем случае есть подход из ранних игр Fallout, где одновременно включены диалоговое меню и «спросить его о чём-нибудь». Там тоже можно додуматься до ключевых слов по контексту и диалогам.
alastochkin
Смотри, я не видел хороших примеров ASK-TELL в русскоязычных играх. Если во время работы с объектами на локации в квестах идёт «угадай глагол», потом «угадай глагол + объект», то с NPC «угадай спросить/рассказать/показать (описанные объекты в локации+невидимые объекты+абстрактные понятия)». Комбинаций становится очень много и большая вероятность что человек не построит правильно фразу. Может быть для любителей хардкорных парсеров это не большая проблема, для то попсового направления более критично. Тяжело сделать NPC по такой системе, чтобы он выполнял много функций и был удобен в общении.
Oreolek
По такой логике я не встречал хороших примеров киберпанка в русских парсерах, значит, киберпанк — не стоящий жанр. Просто есть иностранные парсеры, и подглядывать как сделано там — это нормально.

Когда комбинаций становится много, а сложность завышать не хочется, надо упрощать форму. В случае «угадай глагол + объект» это движение к урезанному парсеру, в случае диалогов — это чёткая форма команды разговора. То есть, одна команда на всё: «спросить NPC о ТЕМА». Например, на этом полностью построена Galatea. Можешь спросить обо всём, что видишь, или о чём услышал в разговоре. Была ещё какая-то игра, где ты вместо вопросов показываешь на предметы, но я не помню уже какая.
Комментарий отредактирован: 6 июня 2018, 17:22
alastochkin
Как по мне, аналогия некорректная. Киберпанк — отдельный жанр литературы, нельзя сказать, что жанр не стоящий, а диалоги — игровая механика, которую авторы стараются реализовать в каждой игре, где есть NPC. Хорошо, я понял твою точку зрения, спорить дальше не буду, посмотрю как сделана Galatea и, если напишешь в комментах, другие игры с хорошим диалогом, тогда может изменю своё мнение.
Borzik
Антон, я вот лично попробовал написать парсерную игру потому, что много менюшек на один экран не запихнешь — людей с одной стороны раздражает скролить, а с другой они банально могут не обратить внимание на то, что если прокрутить ниже, то можно выбрать другие варианты ответа.

Диффузность общения проблема, не спорю и контекстные меню могут это решить, однако в их логике сам черт ногу сломит — отследить, протестировать — кошмар, кошмар!

У меня из знакомых, в интернете в том числе, все оказались жесткими ролевиками. Им надо, что бы игра позволяла быть собой. И они говорят, что нафиг парсер, если он не дает делать вообще все что хочешь и если он не дает говорить вообще о чем хочешь. На всякий чих не наздравствуешься. Они должны по идее записать мне лог, но нет у большинства такого желания — помочь доработать игру под себя.

Мне понравилось в «Детективных загадках», что ты можешь написать предложение, а игра его проанализирует и отреагирует. То есть предложение разбирается по словам и ищет нужные учитывая многочисленные синонимы. Но там все же не было общения, там нам предлагали дать ответ на задачу.

Когда выстраиваешь линию общения с npc и моделируешь ситуацию очень тяжело попасть в среднее арифметическое. Игрок не об этом хочет с ним говорить и не такая у него система приоритетов, как у персонажа игры. Тут уже какая-то литературная инженерия начинается. А кто в этом дока?

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

Демки посмотрю.

P.S. Упс, я думал, что ник можно будет указать отдельно. Ну ладно, буду Борзиком :)))
alastochkin
Уважаемый Борзик! Я ни в коем случае не хотел задеть чьи-то авторские чувства. Кроме своей работы и «Рыбак-рыбака», никого конкретно не имел ввиду, просто делюсь опытом и соображениями. На самом дела рад, что столько комментариев к статье. Опять же, в статье речь шла про текстовую игру, где диалог выступает не как основная механика, а как способ общения с NPC для выполнения квестов. Если делать чисто «диалоговую игру», то можно хоть самостоятельно парсить, ASK-TELL или чатбота использовать — все усилия уйдут на отладку общения.
Немного непонятно, чем сложно делать логику с контекстным меню. Строишь дерево реплик и подпираешь флагами, для активации реплик. Вот пример из игры «Фуга. Начало пути», где используется специальная диалоговая библиотека для TADS (аналогичные есть для Inform):

mainMaster: TalkActor
       isAskedStudy = nil
       //Диалоговая часть
	choices = [
		['Спросить про обучение.', &askStudyFirst, (self.isAskedStudy==nil) ]
		['Спросить про обучение.', &askStudy, self.isAskedStudy ]
		['Еще раз спросить про испытания.', &askTask, self.isAskedStudy ]
		['Спросить про фугу.', &askFuga , self.isAskedStudy ]
		['Закончить.', &sayGoodbye]
	]
	askStudyFirst = {
	   "— Должен тебе сказать, мой юный ученик, что время твоего обучения закончилось. Твой долг - спасти нашу Долину от тирании. Надо отыскать провидца, который сможет тебе помочь. Я слишком стар чтобы выходить из кельи и буду помогать тебе через особую духовную связь. Сейчас я разрушу барьер и ты сможешь войти в комнаты испытаний, пройдя которые, ты завершишь подготовку. Испытания должны быть тебе посильны. Используй свою силу, хитрость, а в особых случаях фугу. ";
       self.isAskedStudy = true;
       barier.moveInto(nil);
       barierAh.solve;
	}
	askStudy = {
	   "— Ты уже окончил обучение, можешь отправляться во внешний мир в поисках спасения для нашей Долины.";
	}
	askTask = {
		"— Испытания должны быть тебе посильны. Самое главное - не используй фугу, когда встретишь первые препятствия! Ты должен пройти их самостоятельно, пользуясь только своей хитростью и ловкость. ";
	}
	askFuga = {
		"— Как я уже много раз говорил, фуга, есть путешествие в прошлое усилием одного лишь сознания. Увеличение концентрации приводит к более глубокому погружению, совершённые же физические действия выводят тебя ближе к точке отправления. Твои действия во время фуги, приводят к возникновению темпоральных копий, они остаются в том мгновении когда ты совершил действие и продолжают его до твоего ухода в прошлое или до конца фуги. Ты можешь увидеть их, и даже взаимодействовать с ними если снова вернёшься в то мгновение. Работа с копиями есть основа мастерства фуги. Не забывай, все действия совершённые тобой и копиями в прошлом оказывают влияние на настоящее. Но хватит слов. К испытаниям!";
	}
	sayGoodbye = {
		"- Спасибо, я о вас не забуду. \b";
		self.stopTalk;
		Me.travelTo(startroom);
	}
Комментарий отредактирован: 7 июня 2018, 16:02
Borzik
Ну лично меня демки чат ботов устраивают. Правда в случае со «специалистом» я стал жертвой хамского поведения:) Если игрок сам пишет дерзости, то выходит, что эта грубость ответная реакция, а если игрок вежлив и адекватен, то получается что мы уже имеем дело с характером npc или тем что он на взводе. Но так или иначе в контексте игры происходящее будет продиктовано ситуацией — взаимоотношениями npc и ГГ, например.

«Лифтер» на естественные вопросы дает естественные ответы. (Разговор с незнакомым человеком.) Разве что на невинный вопрос: Сколько сейчас времени? Ответил: Сколько нужно. Хотя вообще он бот мирный:)

Иногда мне кажется что в случае не предусмотренной темы разговора надо выдавать реакции вида: Вы хотели спросить про $noun, но передумали.

Совсем старое для игр «NPC ничего не знает об этом» выглядело очевидной затычкой, зато все вопросы сразу отпадали.

То что бот ничего не знает про рынок Форекс нормально.

Диалоговое дерево может стать настоящей болью, если там очень много разветвленных тем и надо возвращаться на много уровней выше, а так же в том случае, если разговор с одним персонажем откроет или закроет реплики другого. Ляпнули что-то не то и о чем-то npc уже не захочет говорить, возможно даже общение на те же темы пойдет в другом ключе. Представь, что есть одна история, но мы можем последовательно проходить ее за разных персонажей, участников этой истории. Мало того, что от этого вроде бы знакомая история может сильно измениться на уровне восприятия, так и поступки, слова ГГ будут влиять на прохождение за других. Я именно про такой случай. Это не игра построенная на общении, а игра в которой выборы реплик так же влияют на динамическую систему.

А касательно авторских итогов топика, так почему не попробовать что-то другое, если не устраивает текущее положение дел. Я совершенно не против и даже с удовольствием посмотрю на результат. Менюшные диалоги классика. В некоторых старых РПГ помимо менюшек можно было попробовать спросить про что-то свое, но то была опция.