Разработка ремейка методами чайника 9. Создание острова, архитектура диалогов и квестов
Диалоги
О, диалоги… на мой взгляд, наиболее плохо реализованная часть игры. Как в технической, так и в геймплейной части. Чтобы понять почему в технической, то достаточно посмотреть на код:
Вашему взгляду представлен код диалога с хозяином таверны, внутри которого прописаны условия под всевозможные квесты, города и т.д. Ну т.е. чтобы добавить или изменить какой-то квест, нужно будет модифицировать множество файлов, проставить множество условий с риском сломать базовую логику. В общем это никуда не годится…
Почему же мне не нравится геймплейная часть? Да потому что это выглядит как обычные субтитры! А субтитры должны добавляться как вспомогательная часть, поверх озвучки и отображения эмоций персонажа на экране. В корсарах же, у персонажей нет эмоций, по понятным техническим причинам. А значит, было бы вполне логично добавлять своеобразные вставки рассказчика, что-то типа: “В его глазах читался неистовый силы гнев, способный утащить на морское дно самого дьявола!”. Но тогда текущее диалоговое окно не вписывается в этот концепт…
Однако у этой системы есть и весьма интересные фишки. Например рандомные фразы, зависимость на репутацию героя и система раздражения НПЦ. Это добавляет живости миру, а значит должно быть сохранено. Единственное что, от системы блокирования разговора с разозлившимся НПЦ, я все же решу отказаться. Просто потому, что таким образом можно случайно заблочить какой-нибудь квест, или привести к другим неприятным последствиям.
В общем, нам нужно чтобы диалоговая система была гибкой, имела наглядное представление структуры диалога, возможность динамического встраивания дополнительных диалогов на основе квестов, а также легкий вызов скриптов для взаимодействия с миром. К сожалению, готового решения на рынке либо нет, либо я плохо искал… однако есть очень мощный инструментарий, который позволяет создать то, что я хочу видеть!
Это очень мощный инструмент построенный на стейт машинах! Каждый блок можно кастомизировать добавляя ему пользовательские поля, которые затем используются в логике диалога. Более того, это решение также отлично подходит для создания квестовой логики, что нам только на руку. Ну и разумеется его можно применить для написания логики ИИ, боевой системы и т.д. К сожалению, продукт имеет много подводных камней, некоторые действия могут привести к фаталам и вылету движка. Но на безрыбье…
Не буду описывать все те оттенки коричневого, через которые пришлось пройти, чтобы подобрать набор полей и нод, которые будут работать максимально идентично оригинальной игре и легко расширяться, а затем это все еще заставить работать. Так что остановлюсь просто на показе того, как в целом можно будет построить диалог с неписями, наподобие конструктора.
Я создал несколько нод для обычного диалога:
- Dialogue Node - просто выводит фразу от имени NPC.
- Dialogue Reputation - выводит фразу от имени NPC в зависимости от репутации героя.
- Dialogue Memory Node - выводит разные фразы от имени NPC по очереди
- Dialogue Choice - фраза от ГГ
- Dialogue Choice Reputation - фраза от ГГ в зависимости от репутации
- Dialogue Memory Choice - разные фразы ГГ по очереди
Каждая нода позволяет указывать несколько вариантов текста выбирающегося рандомным образом.
И еще несколько нод, для диалогов куда можно интегрировать квестовые диалоги:
- Integration Node - инкапсулирует в себе логику получения активных квестов и редиректа на них
- Integration Choice Node - идентично первому, но представляется игроку как вариант выбора
- Dialogue Agent - просто прослойка для удобного реюза группы выборов.
- Link to parent node - вызывается из квестового диалога, чтобы система знала что делать дальше, продолжать диалог с NPC или закрыть диалог.
Вот пример, как это выглядит в сборке хозяина таверны:
Квесты
Хорошо, теперь немного отойдем в сторону, и займемся созданием архитектуры квестов.
- Talk with… - устанавливаем нам неочевидную задачу поговорить с кем-то. Допустим это может быть случайный разговор с прохожим. В дальнейшем мы можем через журнал рассказать игроку, с кем он должен поговорить.
- Add Note To Journal - тут я думаю все понятно
- Possessed on ship - срабатывает когда игрок садится на свой корабль
- … в дальнейшем тут будут ноды на убийство цели, достижения какой-то локации и так далее.
Еще есть специальная нода подключаемая только к задачам на диалог - On Talk Node. В ней можно указать что нужно сделать, если пользователь выберет один из вариантов диалога. А еще каждой такой ноде можно указать срок сдачи(только я пока что не сделал логики его провала…)
Помимо прямых квестовых задач, я так же добавил ноды, которые производят действия:
- Give Item - дает игроку какую-то вещь, или отнимает
- Spawn Character - создает в мире NPC с заданными характеристиками
- Spawn Ship - создает в мире корабль, работает в связке со Spawn Character
Теперь мы можем написать максимально простую логику:
Сперва говорим с человеком в порту > получаем запись в журнал после окончания диалога > говорим с хозяином таверны(при определенном выборе - получаем 5000 песо, а также с помощью метки и указании названия диалоговой ноды, запоминаем какой выбор был сделан на будущее) > делаем запись в журнал > ждем посадки на корабль > спавним противника..
А вот так выглядят диалоги с NPC для этого квеста:
Все что остается сделать, чтобы запустить квест - это добавить его в список доступных квестов, и тогда он автоматически подключится для всех необходимых NPC. Все что необходимо знать для создания квестов - это название интеграционных нод у персонажа, куда можно встроить новый диалог. И теперь каждому конкретному квесту можно выделять свою папку!
А вот небольшая видео демонстрация на манекенах:
Пока что это просто манекены без анимаций, но в будущем, я хочу добавить возможность воспроизводить анимации из диалогов. И тогда в сочетании с описанием рассказчика, должно получится очень интересно. Но это не точно…
На сим я кончаю эту статью. Если вам она понравилась, то буду благодарен за ваши комментарии, вопросы или советы!
Я, наверное, ретроград, но мне не нравится.
Каждый инструмент избовляет тебя от части возможностей, взамен делая за тебя часть работы.
Конкретно этот выглядит так, будто он избавляет от части возможностей, взамен заставляя работать больше. Я не вижу преимущества в стрелочке с условием, вместо "if" в коде, в этом случае, в отличие, например, от Behavioral Tree или Animation Blueprint.
В моем ретроградном представлении, должен существовать "глобальный" набор квестовых переменных, а дальше все управляться скриптами. При грамотной организации кода (а не ужасе на скриншоте), должно получиться емко, коротко и удобно.
Вот тебе пример создания диалогового окна для персонажа в одной малоизвестной игре.
До третьей главы у него можно по клику на диалог "чекак?" взять квест. В процессе выполнения другого квеста получить информацию. А во всех остальных случаях ничего не значащий ответ.
Коротко, емко, удобно, вариативно, и нет никакого миллиарда стрелок.
Бесспорно, у вашего подхода есть плюсы. Но лично я не сторонник размазывания переменных по всему проекту. Это удобно если у вас много квестов которые друг с другом связаны, но в моем случае квесты по большей части унитарны.
+ в вашем кейсе, если придется менять диалоги, то придется менять и комментарии. А если в диалоге разные текста в зависимости от репутации и рандома...
В целом я считаю что диалоги и квесты - это не те вещи, которые должны решаться кодом. Даже непрограммист после краткого экскурса должен смочь сделать квест в моем понимании. Делать это через код - сильно прибавляет к порогу входа, среду разработки установи, IDE настрой...
Так что это скорее вопрос точки зрения и стоящих задач.
Сразу докину, как выглядит код "сдачи" квеста:
один инструмент стоит 18к рублей, другой 22к
40к чтобы сделать как-то ниже среднего
про gaea знаешь? https://quadspinner.com/
можно бесплатно создать до 1к ландшафт любой, хоть остров
Не пробовал... но я уже не буду новый инструмент изучать)
Молодчик. Круто, что движешься вперёд и проект продвигается!
Один вопрос. Хули так мало фепесов?