Разработка ремейка методами чайника 9. Создание острова, архитектура диалогов и квестов

Доброго времени суток, господа корсары! Сегодня я расскажу вам как планировалось и осуществлялось… создание острова и квестово-диалоговая архитектура. Какими плагинами я воспользовался для создания ландшафта и диалоговой системы. И с какими проблемами пришлось столкнуться в процессе их встраивания в игру.

Зачем новый остров?

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

  • Создание острова не показалось мне сложной задачей, если воспользоваться специальными плагинами. Со зданиями сложнее, но их можно собрать как конструктор на основе оригинальных, либо использовать из готового пака.
  • Изначально я думал о том, чтобы постепенно переделывать локации и объединять их в единый открытый мир, но возникает проблема с квестами. Квесты целиком и полностью завязаны на идентификаторах локаций, и если они будут переноситься до объединения мира(а оно так и будет), то спустя какое-то время, сшивание мира будет казаться все более и более дорогой задачей. А значит, скорее всего, никогда не будет реализованной.
  • Я хочу сделать мир максимально бесшовным. Конечно абордажи так сделать скорее всего не получится, потому что не понятно как это должно выглядеть в случае условного мановара и тартаны. Но это не повод оставлять устаревшую локационную систему.
  • В конце-концов разработке присущ хаос, поэтому проект нужно постоянно видоизменять, чтобы кусочки пазла вставали в правильное положение. Локационная система никак в этот пазл не вписывалась.

Исходя из вышеперечисленного, я решил что создам остров с нуля. Конечно, это скорее всего не будет одобрено большим количеством игроков оригинальной игры старой закалки. Да и в целом, данным решением я ставлю под удар возможность использовать мои наработки как новую площадку для разработки корсаров. Ибо теперь не получится просто переносить старое на новое. Но таков путь!

Создание острова

Для начала нужно определиться, каким именно образом я могу создать остров. В процессе поисков полезных плагинов для разработки, я нашел интересное решение для создания ландшафта - Brushify.

Если вкратце, то оно позволяет строить уникальный ландшафт на основе пресетов, смешивать их между собой и модифицировать при необходимости. А также, менять вид поверхности, от красивой динамичной травы, до каменистых утесов и пустынь, путем простого рисования.

Как вы могли видеть в моих видеороликах, на стартовой локации находился остров Антигуа, поэтому я решил начать переработку именно с него. Но вот с чего начать…? Первое о чем я подумал - это масштабы. Насколько оригинальный остров большой? Сколько игроку потребуется времени на x1 скорости, чтобы его пробежать? Я создал новый ландшафт с максимальным размером 255x255, поставил персонажа на край карты и устроил ему пробежку на противоположную часть по диагонали. Получилось 10 минут на стандартной скорости бега, что весьма немало. Затем я примерил эту карту на не самый большой в игре остров, и получилось что он больше этой карты примерно в 2.5 раза. Стало понятно, что сохранить пропорции островов не выйдет, придется урезать масштабы. Уменьшив остров в 3 раза получилась такая картина:

В целом по основным путям можно будет пробежаться менее чем за 5 минут без ускорялок и спринта, что вполне допустимо. Значит о конях или быстром перемещении на нем можно не задумываться. Но теперь порт не сможет вмещать в себя большие эскадры, и это потенциально бьет по другим частям игры… как с этим быть, пока что непонятно.

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

Но мне не нравится на этой карте то, что прибрежная часть острова - как правило растительная. Это будет мешать пониманию где бухта для высадки, а где просто границы острова. Поэтому остров в целом будет окружен скалами, а места для высадки - отчетливо помечены пляжными зонами.

Теперь можно приступать к “рисованию”. Для того чтобы в целом соблюдать форму острова, я разместил старую модель на карте, и затем по контурам вставлял разные пресеты ландшафта, играясь с позиционированиями, масштабами, смешивая их друг с другом и так далее.

Я не буду описывать весь процесс в деталях, ибо там нет ничего интересного. Итоговые результаты вы могли видеть в этой мини статье:

Краткие фото/видео сводки с разработки методами чайника

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

Запускалось на RTX 3070 Laptop в энергосберегающем режиме с забитой памятью в 2к разрешении. Держит 60 кадров с просадками до 50 в среде пальм.

Диалоги

О, диалоги… на мой взгляд, наиболее плохо реализованная часть игры. Как в технической, так и в геймплейной части. Чтобы понять почему в технической, то достаточно посмотреть на код:

Вашему взгляду представлен код диалога с хозяином таверны, внутри которого прописаны условия под всевозможные квесты, города и т.д. Ну т.е. чтобы добавить или изменить какой-то квест, нужно будет модифицировать множество файлов, проставить множество условий с риском сломать базовую логику. В общем это никуда не годится…

Почему же мне не нравится геймплейная часть? Да потому что это выглядит как обычные субтитры! А субтитры должны добавляться как вспомогательная часть, поверх озвучки и отображения эмоций персонажа на экране. В корсарах же, у персонажей нет эмоций, по понятным техническим причинам. А значит, было бы вполне логично добавлять своеобразные вставки рассказчика, что-то типа: “В его глазах читался неистовый силы гнев, способный утащить на морское дно самого дьявола!”. Но тогда текущее диалоговое окно не вписывается в этот концепт…

Однако у этой системы есть и весьма интересные фишки. Например рандомные фразы, зависимость на репутацию героя и система раздражения НПЦ. Это добавляет живости миру, а значит должно быть сохранено. Единственное что, от системы блокирования разговора с разозлившимся НПЦ, я все же решу отказаться. Просто потому, что таким образом можно случайно заблочить какой-нибудь квест, или привести к другим неприятным последствиям.

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

Logic Driver Pro. Есть бесплатная версия с урезанным функционалом.

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

Не буду описывать все те оттенки коричневого, через которые пришлось пройти, чтобы подобрать набор полей и нод, которые будут работать максимально идентично оригинальной игре и легко расширяться, а затем это все еще заставить работать. Так что остановлюсь просто на показе того, как в целом можно будет построить диалог с неписями, наподобие конструктора.

Я создал несколько нод для обычного диалога:

  • 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. Все что необходимо знать для создания квестов - это название интеграционных нод у персонажа, куда можно встроить новый диалог. И теперь каждому конкретному квесту можно выделять свою папку!

А вот небольшая видео демонстрация на манекенах:

Да, диалоговое окно теперь будет находиться справа от NPC и содержать всю историю общения. И я ничуть не жалею о своем решении!

Пока что это просто манекены без анимаций, но в будущем, я хочу добавить возможность воспроизводить анимации из диалогов. И тогда в сочетании с описанием рассказчика, должно получится очень интересно. Но это не точно…

На сим я кончаю эту статью. Если вам она понравилась, то буду благодарен за ваши комментарии, вопросы или советы!

0
29 комментариев
Написать комментарий...
Immy

один инструмент стоит 18к рублей, другой 22к
40к чтобы сделать как-то ниже среднего
про gaea знаешь? https://quadspinner.com/
можно бесплатно создать до 1к ландшафт любой, хоть остров

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Не пробовал... но я уже не буду новый инструмент изучать)

Ответить
Развернуть ветку
Cadovvl

Я, наверное, ретроград, но мне не нравится.

Каждый инструмент избовляет тебя от части возможностей, взамен делая за тебя часть работы.
Конкретно этот выглядит так, будто он избавляет от части возможностей, взамен заставляя работать больше. Я не вижу преимущества в стрелочке с условием, вместо "if" в коде, в этом случае, в отличие, например, от Behavioral Tree или Animation Blueprint.

В моем ретроградном представлении, должен существовать "глобальный" набор квестовых переменных, а дальше все управляться скриптами. При грамотной организации кода (а не ужасе на скриншоте), должно получиться емко, коротко и удобно.

Вот тебе пример создания диалогового окна для персонажа в одной малоизвестной игре.

До третьей главы у него можно по клику на диалог "чекак?" взять квест. В процессе выполнения другого квеста получить информацию. А во всех остальных случаях ничего не значащий ответ.

Коротко, емко, удобно, вариативно, и нет никакого миллиарда стрелок.

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Бесспорно, у вашего подхода есть плюсы. Но лично я не сторонник размазывания переменных по всему проекту. Это удобно если у вас много квестов которые друг с другом связаны, но в моем случае квесты по большей части унитарны.
+ в вашем кейсе, если придется менять диалоги, то придется менять и комментарии. А если в диалоге разные текста в зависимости от репутации и рандома...

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

Так что это скорее вопрос точки зрения и стоящих задач.

Ответить
Развернуть ветку
Cadovvl
+ в вашем кейсе, если придется менять диалоги, то придется менять и комментарии

Комментарии тут - потому что я брал код не из самого проекта, а из примера для обучения. В оригинальном проекте этих комментариев нет.

А если в диалоге разные текста в зависимости от репутации и рандома

То это должно быть в этом скрипте, а не где-то еще. В качестве "диалога" указан некий обобщенный медиа ресурс, в котором локализованный текст и озвучка. В медиа файлы не надо запихивать логику.

Это удобно если у вас много квестов которые друг с другом связаны

Не только квесты, но и привязка квестов к глобальным событиям. Например, получить квест на поиск необычного растения можно только после того, как получен доступ к локации с этим растением. Или получить квест на месть только после смерти определенного NPC.

но в моем случае квесты по большей части унитарны

Это аргумент серьезный, с ним спорить тяжело. Если функционала инструмента достаточно для задумки, а порог входа кажется легче, чем "if/else" в текстовом редакторе - то выбор, безусловно, верный.
Хотя я, как истиный ретроград, считаю что для маленькой стейт машины это легко и удобно, но вот квесты с минимальной логикой так создавать будет очень проблематично. Наверное, вопрос вкуса.

Энивей, воля ваша. Выглядит так, будто вы понимаете, что вы делаете, и делаете это осознанно. Удачи!

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор
Ответить
Развернуть ветку
Cadovvl

Сразу докину, как выглядит код "сдачи" квеста:

Ответить
Развернуть ветку
A3zazel

Молодчик. Круто, что движешься вперёд и проект продвигается!

Один вопрос. Хули так мало фепесов?

Ответить
Развернуть ветку
Веа
Ответить
Развернуть ветку
A3zazel
Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Спасибо!

В игре с фепесами все ок, это запись идет в толи в 25, толи в 30 кадров. Поэтому на записи выглядит рвано. Извиняюсь за это, но моя видюха игру, редактор и запись одновременно не потянут)

Ответить
Развернуть ветку
A3zazel

Понял. Тогда от всего сердца пожелают тебе вскоре заиметь лишних денег на обновку железа,)

Ответить
Развернуть ветку
Mickey Knox

Я нифига не понял, это какие-то новые корсары или что?)

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор
Ответить
Развернуть ветку
Mickey Knox

но это же охуенно :)

Ответить
Развернуть ветку
Maks Savva

Пришел потыкать палочкой. Живи.

Ответить
Развернуть ветку
Comandante

Хорооош! Только диалоги бы как-то разделять,а то они все в куче. Сделай хоть как в мессенджерах табуляцию, что ли)или по цветом разным выделять

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Цветом можно, да. Спасибо за идею

Ответить
Развернуть ветку
Донкий ХОД

С масштабом досок проблемы. Лучше сразу привыкай делать правильно.

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

а что с ними не так?

Ответить
Развернуть ветку
Донкий ХОД

Ну посмотри как в жизни сделано. Доски толщиной с человека не делают. Посмотри фотографии пирсов и т.д. - доски в очень редких случаях могут быть широкими, если сделаны из толстых стволов, но они всё равно тонкие. Это первое.
Во-вторых, они у тебя надеты на продольные балки, как шашлык на шампур, так тоже не бывает, они должны лежать на балках, сверху.
Я понимаю, что всё это у тебя начальные наброски, но повторюсь - учись делать сразу правильно, меньше придётся переделывать, а подобные несоответствия масштабов и конструкций достаточно сильно бросаются в глаза.
Удачи!

Ответить
Развернуть ветку
KindlyWolf
нам нужно чтобы диалоговая система была гибкой, имела наглядное представление структуры диалога, возможность динамического встраивания дополнительных диалогов на основе квестов, а также легкий вызов скриптов для взаимодействия с миром. К сожалению, готового решения на рынке либо нет, либо я плохо искал…

Dialogue Plugin. Легкое создание блупринтовых условий и евентов, привязываемых к нодам. Есть на торрентах.

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Рассматривал этот вариант. Он в стоковом состоянии и в половину не так хорош для диалогов как Logic Driver Pro. Из коробки нет дополнительных полей, динамической валидации и скрытия неиспользуемых полей на основе предыдущих данных...
К тому же, это узкоспециализированный плагин, насколько я понимаю, квесты в виде графов на нем не нарисуешь. Во всяк случае такое у меня возникло впечатление после прочитанной документации.

Ответить
Развернуть ветку
KindlyWolf

Квестов там нет. Для квестов графы не очень-то и нужны. Про динамическую валидацию и дополнительные поня не понял о чем речь. Что такое поле - строчка диалога что ли? Валидация чего именно? Что такое неиспользованные поля?

У меня ощущение, что ты говоришь об условиях, типа "если у меня 5 голды, то строчка появляется, а если нет то исчезает" или "если квест в таком-то состоянии, то строчка появляется/исчезает". Если об этом, то естественно там это есть.

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Ну не согласен. Квест это та же стейт машина. Ты её стартуешь, и проходить по разным её состояниям. Представлять квест в виде состояний очень удобно как для разработки, так и для дебага.

Вот тебе пример базового функционала. Каждая диалоговая нода выбора имеет кастомный флаг "Has requirements". При активации флага, у ноды появляются дополнительные поля которые необходимо указать. Это позволяет добиться наглядности логики диалога, и не переполнять ноду лишними пустыми полями.

Ответить
Развернуть ветку
KindlyWolf

Для диалоговых нод, как я уже написал, в том плагине есть удобные "условия" для того чтобы нод отобразился игроку, и которые жрут намного меньше места, чем у тебя на скрине. Показываю пример ноды с условием. Условие тут "has gold" и параметр 100.

На третьем скрине список выпадающих условий - их тут раз два и всё, т.к. их создаешь сам - это просто uobject с функцией, которую нужно оверрайднуть. Has gold я создал сам. Логика в условиях любая и параметры экспоузишь любые. То есть легко делается например "has item" и параметр это твой итем любого типа. Можно сделать "Has stat", где статом может быть выпадающий из списка енум с твоим authority с цифровым параметром рядом. Возможности неограничены.

Помимо условий, есть точно такие же events, которые триггерятся при заходе в ноду. Тоже uobject, в котором просто оверрайдишь функцию и выполняешь любой код.

А по поводу квестов, что это стейт машина - утверждение верное для 1% квестов. Остальные - это прямая линия с парой ступенек и в крайнем случае с 1 ответвлением, и это я говорю про классические рпг с choice & consequence. Необходимость в графах - такая себе. Но можно сделать свои графы, если так прямо хочется. Я попробую скоро, когда займусь квестами у себя на проекте.

Ответить
Развернуть ветку
Dangetsu Kami-sama
Автор

Ну так вот, для того, чтобы понять что конкретно требует Response 2, мне необходимо открыть детали этой ноды. Меня такой вариант вообще не устраивает. + ключевая особенность диалогов корсаров - рандомизация ответов и зависимость текста на репутацию. Я хочу видеть все варианты сразу на графе. Если у меня нет такой возможности, то графовое представление не дает никакого преимущество перед обычным кодом, а только добавляет гемора с лишними телодвижениями. Также, если мне что-то не нужно, я вполне могу эти поля скрыть с ноды, если уж на то пошло.

это прямая линия с парой ступенек

прямая линия - тоже имеет состояния

Имхо, это больше похоже на битву мировозрений..

Ответить
Развернуть ветку
Cadovvl

ф

Ответить
Развернуть ветку
Maks Savva

Брависсимо 👏🏻

Ответить
Развернуть ветку
Читать все 29 комментариев
null