Наброски нового рогалика на Godot, собираемого на базе прошлых наработок по диаблоиду. Теперь с повествованием через окружение (буквально) и black-магами.

Отличие рогалика от диаблоида

Скорее я под рогаликом имею в виду всё-таки концепцию роглайта. Где процесс более облегчён, предполагает куда менее продолжительные забеги чем в Rogue, где есть мета-прогресс и игра как раз фокусируется на том, что умирать герои будут постоянно, начиная заново. Но термин роглайт мне не особо нравится (потому как тоже широкое и мало что объясняет, вне конкретного контекста), к тому же его основные представители не особо и на Diablo то похожи. Рогалик, конечно, тоже очень широкое понятие, к тому же и сама Diablo - это тоже рогалик, хотя очень сильно облегчала концепцию и делала её динамической. Но хотя бы более менее известное и устоявшееся - то есть некоторые люди (даже с большим игровым стажем) вообще не поймут ничего, если им сказать слово "роглайт".
Что касается принципиальный отличий - в одном случае (Diablo-like) у нас персонаж разнообразно прокачивается, копит разный прогресс, хранит ценные шмотки, может их как-то усиливать (руны, зачарования). Скорее всего есть какая-то хаб-локация, лор, игровые субъекты (использую этот термин вместо корявой кальки с английского - "non-player character", которую дословно понимают как "не игровые персонажи", что в смысловом плане звучит немного дико, в то время как оригинальный смысл - это "персонажи НЕ игрока", или, условно, "неигроковские персонажи", если более кратко), лорные мини-квесты. Часто персонаж проходит разные локации/этажи за общую сессию, куда можно вернуться и где, возможно, даже сохраняются недобитые монстры/лут.
В другом случае (облегчённый рогалик/роглайт с мета прогрессом и частыми смертями) - ценности немного иные. Лор и мини-квесты не обязательны. Вместо сложной прокачки самого персонажа достаточно какой-то лёгкой, или её отсутствия, или выноса прокачки в мета-прогресс. Хотя, просто нарастить герою параметров, открывая улучшения в мета-магазине - тоже немного странный подход (хотя довольно ленивый в плане баланса, то есть проще в разработке ). Да, игрок сможет уверенно "перегриндить" более сложные уровни с таким подходом, как это обычно характерно для игр типа Final Fantasy, но у этого есть обратная сторона - со временем герой становится слишком оверпавер и это или необратимо, или просто не особо хочется сбрасывать мета-прогресс в ноль. Более балансная интересная реализация - это скорее давать игроку в мета-магазине выставить какой-то набор из ограниченных перков на каждый забег. Чтобы нельзя было включить сразу всё.
Если посмотреть в сходные динамичные игры, с рогалик-элементами, типа Returnal и Saros, то второй якобы хардкорнее в прохождении, однако позволяет пользователю мета-перегринд, что страхует разработчиков от того что игру забросят массы. А в случае с Returnal, даже после ослабления первоначального задуманного разработчиками порога хардкора - многие всё-таки не осилили игру до конца и отвалились. С другой стороны Saros потерял некоторые фишки, что были в Returnal, пойдя по тоже креативному, но и более упрощённому в чём-то пути.
Что касается лута, то в облегчённом рогалике у игрока особо нет времени на слишком уж детальное внимание к параметрам вещей и "билду". Вернее подход более поверхностный - шмотки тут более расходный материал, а в новый забег всё-равно не перенесутся. Поэтому у них по идее может быть мало параметров, отсутствие случайно генерируемых параметров, не обязательна редкость, и так далее.

Видео: https://leonardo.osnova.io/160fc5e9-7f14-5a14-9eb1-771beced7e3c/-/format/mp4/#t=0.1

Amaze, примерный процесс из более ранней версии

Концепция в текущем проекте Amaze

В прототипе диаблоида (Pandelirium) уже была реализована возможность возвращаться в пределах трёх уровней. Лут и монстры сохранялись. Некоторая сложность с этим - если делать сейвы, то не очень удобно хранить это состояние, так как реализация сильно отличается от того что было в первой Diablo, например, где все уровни чётко разлинованы по ячейкам и это как-будто отдельной огромный инвентарь игрока. В принципе и современные Diablo-like тоже от подобного ушли, потому что делать даже не то, что трудоёмко, а скорее избыточно, плюс сейчас чаще враги спавнятся заново.
В Amaze наверное можно просто это убрать и сделать забеги "одноэтажными". Или сами отдельные карты делать рассчитанными на 1-2-3 этажа. При этом можно сделать подуровни "линейными" - как в Minecraft Dungeons или DRG Survivers, то есть проходишь этаж только в одну сторону и не возвращаешься назад.
Общий предполагаемый игровой цикл прост - в начале у игрока примерно один персонаж и один уровень, куда можно отправиться. Затем можно гриндить мета-валюту на этом уровне и она сохраняется если уровень покинуть или героя убили. В локации также есть босс - за первое его убийство можно пополнять мета-ассортимент тех же доступных карт и персонажей. Также убийство босса завершает уровень и умножает собранную в момент забега мета-валюту.
Что касается заклинаний - в прототипе диаблоида идея строилась вокруг того, что все герои в основном маги, а получая разное оружие герой получает разные заклинания, в зависимости от комбинации своей основной руны и руны встроенной в оружие. При этом собирая искры можно было изучить содержащуюся в оружии руну, и использовать уже её - для новых комбинаций. В Amaze хочется сместить фокус с жонглирования разными спеллами на то, что разыне персонажи разного класса, имеют свою специализацию и основной каст визуально не меняется.
В конце концов, изобилие разных спеллов и частая их смена - это даже в диаблоидах скорее красивая дорогая добавка контента. К тому же итоговые билды - это часто про прожимание одной кнопки, то есть даже крутить циклы из нескольких кастов люди не всегда склонны. А в ранних Diablo традиционно подразумевался тоже более спокойный "однокнопочный геймплей", где ты не прокручиваешь разные заклинания, как сумасшедший. Более того, вторая часть даже в ремастере не делает процесс переключения спеллов более удобным.
То есть планируется подход скорее как близкий к тому что в League of legends (или Ravenswatch) - у персонажа один (может два) основных уникальных скилла (что придаёт ему индивидуализма) которыми он большую часть времени и колотит, а прочие скиллы более универсальные.

Видео: https://leonardo.osnova.io/75e0e02e-6257-5fc6-a634-5da1fa26999b/-/format/mp4/#t=0.1

Вот и босс первого уровня.

Экипировка

Для диаблоида я делал такой вариант хранения данных, что вещь хранит в себе массив параметров. Словари тогда не хотелось использовать, потому что вещи имеют случайные генерируемые свойства. Однако, такой способ не совсем оптимален и переделывая старую архитектуру под рогалик я решил использовать комбинированный вариант - в массиве теперь хранится ID основы предмета и базовые параметры, которые собраны отдельно в общей дате экипировки и фиксированы. Часть изменяемых данных остаётся - редкость, свойства, прогресс изучения, возможные заряды.
Можно было сделать вещи более простыми, фиксированными, но всё-таки в систему заложена редкость, опознание редкого через ловлю искр остающихся от врагов, заряды. Вряд ли стоит это совсем убирать.

Передвижение

Так как и традиционное мышекликание одной кнопкой меня не устраивало (было хорошо для Diablо 1, так как игра непродолжительная, в последующих частях и "подражателях"" - уже боль) и WASD тоже не является такой уж панацеей - в процессе тестов диаблоида я пришл к концепту "зажал кнопку и персонаж бежит в ту сторону за мышью", как наиболее удобному и основному. Например ту же кнопку "S. То есть персонаж не начинает на автомате неочевидно оббегать препятствия, не надо часто-часто кликать, когда кликаешь-стреляешь нон-таргет заклинанием - он точно остановится, а не будет ломиться куда-то. Такое частично есть в диаблоидах, но там всё ещё надо кликать в таргет, чтобы персонаж не подумал что просто надо бежать. Это напрягает. К тому же там динамика повышенная, всякие рывки и под чисто такой способ не особо заточено происходящее.
Пара альтернативных режимов - WASD и концепт что по нажатию персонаж переходит в режимы "автобег" или "стоять", но тут скорее на любителя, работают упрощённо и не знаю буду ли вводить их полноценно.

Мини-карта

В диаблоидах исторически закрепился некоторый перебор с ролью мини-карты. То есть она бывает сильно подробная сама по себе, часто открыта прямо поверх экрана, что засоряет картинку, при этом несколько нивелирует роль прочей графики - то есть игроку достаточно бежать по этой схеме, по сути и не смотря на окружение. По идее диаблоид вообще можно было делать таким, что схематичная графика мини-карты и была бы основной графикой (лишь немного "улучшенной", и чтобы на ней отображался лут, персонаж, монстры), но редко что-то такое попадается - либо слишком цветастый пиксельарт, либо простые линии, но и геймплей совсем плоский, либо другая крайность - всё сделано в ASCII (миллионы "клонов" Rogue).
В Amaze мини-карта сделана элементарным способом, через строки фона, которые периодически обновляются, формируясь из матрицы значений, где хранятся данные о том, какие клетки уже были посещены во время забега. Собственно, в рогалике можно было её и не делать, но почему нет.
Ну а строка обозначающая персонажа наложена поверх, и, когда надо поменять место - встаёт в координаты нужной строки фона. Это одна ось, а вторая ось - превращается в количество пробелов, которое надо поставить в строке персонажа перед белой звёздочкой.
Похожим образом делал мини-карту в самом первом прототипе Diablo-подобного геймплея на вёб-движке PlayCanvas (Chaosborn).

Чтобы способ нормально и точно работал - шрифт, естественно, должен быть моноширинным. То есть место занимаемое символом не меняется в зависимости от того какой именно символ.

Чтобы способ нормально и точно работал - шрифт, естественно, должен быть моноширинным. То есть место занимаемое символом не меняется в зависимости от того какой именно символ.

Кстати, перерасчёт мини-карты делается в моменты когда персонаж двигается. Можно было бы не оптимизировать, но для ещё большего уменьшения нагрузки заведён таймер (раз уж в Godot они имеются, и можно не делать самописный таймер в коде). Причём, работающий просто как кулдаун, без сигнала timeout(). То есть, пока таймер откручивается перерасчётов не происходит, а если не крутится, то считается новая позиция и таймер запускается снова.

#gamedev #godot #диабло #рогалик #arpg #прототип #devlog