Игроконцепты #2

Ещё немного информации по планам/наработкам в игровом движке Godot. Варианты упрощения arpg-проектов, простой экшен на Godot 4 и радиусная тактика.

Игроконцепты #2

Превращение одного из имеющихся прототипов arpg в ещё более лайтовый рогалик. Godot 3

После первого околоиаблоида, сделанного в PlayCanvas (проект Chaosborn) у меня образовалось ещё несколько, как минимум - Сферамида, Панделирий и daMage. Spheramyd к концепции Диабло приближалась, но не сильно. Pandelirium - уже капитальный диаблоид. А daMage - опять что-то попроще и ближе к рогалику, со своими фишками вроде накапливания маны атаками и поиска на уровнях жизней-перерождений.
Наверное, я зря добавлял везде концепцию чистки нескольких связанных этажей, где уничтоженные враги не восстанавливаются (пусть и наработал в этом некоторую экспертизу, способ отсоединять слои для более простого сохранения состояний и так далее) - помимо того что это сложнее в разработке, это излишне утяжеляет игры с идеей одноразовых забегов. В лайтовом рогалике просто сам уровень для рана (забега) можно делать побольше, а если он и планируется из нескольких актов, то при нахождении перехода можно перемещать героя в следующую часть без возможности вернуться.

В da-Mage общая концепция уже сформирована и этажи там всё-таки нужны для лучшего раскрытия механики перерождений. Pandelirium - диаблоид c прокачкой (пусть она и реализована частично), вот там подобные этажи к месту. А вот если возвращаться к Сферамиде, то этажность можно было бы убрать, как ненужную. Хотя там сам размер уровня, сферы, не может быть сильно увеличен и этажи позволяли расширить это пространство. Тем не менее, для более расширенных уровней можно сделать, что герой переходя на новый этаж уже не может вернуться.

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

Spheramyd
Spheramyd

Другой момент - в Сферамиде и daMage задействуются комбинации камней для получения разных заклинаний. Разные герои начинают с отличающейся стартовой комбинацией, однако, этого мало для создания заметных различий между персонажами и геймплей за каждого из них получается не такой уникальный. И тут можно было бы ещё попробовать собрать на базе одного из этих прототипов проект с чем-то вроде забегов за героев разных классов, у которых, допустим, лишь своё конкретное несменяемое оружие в руках и базовые пара ударов/кастов - свои, фиксированные.

daMage, персонаж - тень<br />
daMage, персонаж - тень
Pandelirium, персонаж - тень<br />
Pandelirium, персонаж - тень
Pandelirium, персонаж - грибочеловек<br />
Pandelirium, персонаж - грибочеловек

Вероятно, соберу что-то подобное из копии Панделирия. Основная мысль в том, что мы отправляемся на короткие забеги героями разных классов, основные способности которых фиксированные - всё-таки, чтобы бить монстров достаточно пары скиллов, нет нужды постоянно крутить/менять эти скиллы. Хочешь другие - возьми другого героя. Таким образом слот оружия, его камни, дропающееся оружие и его изучение - убирается. Тем не менее, книжки и свитки из Панделирия можно оставить, но чтобы они не замещали текущие, а давали дополнительный активный скилл. А также добавить слоты для комбинационных камней и сами камни, просто они будут комбинироваться в пассивные спобосности, а не активные.

Заодно я подумал о том, что вместо того ,чтобы персонаж просвечивал за объектами, можно низко отрезать сами стены (к чему пришли к последним частям Диабло) - и поначалу создавать уровень именно в таком формате, а убранные куски стен добавить где-нибудь на поздних этапах разработки и в дальнейшем скрывать их в тот момент, когда они заслоняют персонажа от камеры.

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

Что-то простое с древесным рыцарем в качестве героя. Godot 4

С Godot 4 интересная ситуация - в ранних версиях он позволял использовать старые форматы моделей, но писал предупреждения о том, что они не будут использоваться в дальнейшем. Поэтому пару ранних проектов я оставил на 4.0 версии, и думал не брать версии движка выше, если использую модели в старых форматах. Тем не менее, версия 4.3 их тоже использует, но предупреждений уже не пишет. Объём минимального билда вырос по сравнению с 3, но это вроде было уже начиная с 4.0.

Древесного рыцаря я моделил уже в новом формате gltf, вернее делал по схеме - моделинг в классическом Blender, после чего модель переносится в новый Blender, анимируется и сохраняется в glb. Как оказалось, что в движке PlayCanvas, что в Godot 4 из glb можно вынуть сразу весь набор разных треков анимации (то есть обращаться к ним, запуская то один, то другой), правда для этого нужно разобраться, как в Blender хранить несколько треков анимации для одной и той же арматуры в одной сцене (там не особо сложно, а заодно желательно ещё научиться правильно именовать треки в Blender, чтобы внутри движка было проще с обращением к ним).

Blender. Внизу перечисленны сохранённые анимационные треки для текущего скелета с моделькой. Кстати, на один скелет можно привязать и несколько независимых мешей сразу, экспортировать всё это разом, а в движке уже включать/отключать отдельные части.<br />
Blender. Внизу перечисленны сохранённые анимационные треки для текущего скелета с моделькой. Кстати, на один скелет можно привязать и несколько независимых мешей сразу, экспортировать всё это разом, а в движке уже включать/отключать отдельные части.

Ранее, в формате collada, я закидывал одну анимацию вместе с моделькой, но можно было добавлять другие анимации к этой модельке, если загружать их отдельно, сохранять их анимационный трек, цеплять его к первой модели и затем удалять ненуную более модель с дополнительной анимацией. В этом способе тоже есть некие плюсы, так как можно добавить анимаций потом, не ломая уже настроенные связи. Через glb придётся заранее собрать в нём внутри Blender все нужные анимации, а если менять - то записывать весь файл заново и импортировать его в движок, проводя некоторые манипуляции для того, чтобы встроить новую модель в созданную структуру на место старой (что тоже не так сложно).

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

Тестовая сцена, настройки графики понижены.
Здесь уже графика накручена - включены каскады SDFGI, объемный туман и прочее.

Радиусная тактика, продолжение проработки. Godot 3

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

Радиусная тактика<br />
Радиусная тактика

Психологически игроку комфортнее получить хоть какой-то эффект от действия, чем ничего. Промах - это ничего, однако действие всё-таки совершилось и гештальт закрылся. Существенно хуже для игрока, когда уже совершенное им действие на самом деле не произошло вобще - именно этот момент хорошо иллюстрирует игра MTG (карточная Magic: the Gathering), где синий цвет своей отменой заклинаний оказывает куда большее психологическое давление на игрока, чем прочие эффекты, в том числе синий же возврат в руку. Убить существо, изгнать, вернуть, обезвредить, уничтожить стол, сыграть что-то своё в ответ на твоё заклинание - это всё воспринимается игроками более нормально, субъективно это происходит "честно", цена уплачена, цели выбранны, эффекты сработали. Отмена - не только вынимает бутерброд изо рта, но и не даёт даже сомкнуть челюсти. Никаких ожидаемых последствий не только не наступает, но и прилетает наказание - как если бы тебя ударили током и забрали некую вещь просто за мысль что-то сделать, но ты этого ещё даже не делал.

MTG
MTG

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

В своё время, разрабатывая тактическую боёвку настольно-ролевого Монстробоя, я хотел ускорить сражения, поэтому в рамках этой установки на ускорение устранил броски на попадание вобще, зашив их в сами броски урона от атак и приёмов. Во-первых, не нужно тратить время на лишний бросок попадания. Во-вторых, если почти каждое действие будет наносить урон, пусть и немного, то и схватка закончится быстрее. Заодно убрал затягивание убеганием - после совершения действия персонаж там уже не может двигаться (хотя некоторые специфические действия не отменяют движение, а вариативности в боёвке и так хватает за счёт системы экшенпоинтов). Что упрощает и читаемость хода событий за игровым столом - тут снова можно вспомнить MTG, где нередко возникают вопросы "я поставил землю в этот ход или нет".

Естественно, совсем убирать промахи из системы я не стал, но игрок может подобрать оружие, которое вобще не промахивается, успешное попадание еще не означает что будет нанесён урон (может защиты снизят его до 0), а способностей, которые срабатывают с шансом, не стал делать слишком много. К тому же способности с шансом срабатывания - это не то же самое, что промазать обычной атакой. Игрок обычно видит шансы приёма и соглашается/не соглашается получить какой-то редкий эффект, принимая возможность провала. А от стандартной атаки он не ждёт, что та попадает с шансом, пусть даже игра шанс этот прописывает - это простой инструмент, часто с не таким великим уроном, и он должен работать просто. Вот с этим ожиданием я и работал - например, делая низкоуровневые жезлы и посохи мажущими в половине случаев (ведь маг должен понимать, что забить кого-то посохом - идея вряд ли удачная и не для того он записывался в маги), или добавляя возможность промаха в топоры (но и подкрутив им урон при хорошем попадании). А вот мечи и кортики, даже первоуровневые, попадают в любом случае, за тем исключением что у кортиков поначалу есть шанс нанести нулевой урон при попадании, но они попадают при этом (и к этому 0 урона может добавиться бонусный урон или какие-то наносимые атакой статусы/эффекты).

Игроконцепты #2

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

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

В радиусной тактике я захотел делать не очередную адаптацию урезанной системы из настолки, а всё-таки попробовать концепцию смены профессии и комбинации способностей классов, на манер того что было в FFT (консольная Final Fantasy Tactics). Ну и ещё какие-то вещи, которые больше зайдут под компьютерную реализацию или попроще в менеджменте/управлении. Допустим, вместо экшен-поинтов просто 1 движение и 1 действие на ход. Настольная тактика тоже не останется в стороне - оттуда есть что позаимствовать, например, концепцию оружия с 4 позициями атаки (что уже реализовано - герои и монстры при нормальной атаке словно "бросают" четырёхгранный кубик со своими определёнными исходами) и то, что нулевой урон всё-таки тянет за собой прочие возможные бонусы к повреждениям и шанс наложить эффекты.

Final Fantasy Tactics<br />
Final Fantasy Tactics

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

Собственно, окно настройка гамбитов из Final Fantasy 12, где разработчики вынесли часть игровой логики, превратив её в игромеханику (часто нечто подобное происходит и в прочих играх). Первая директива: если у союзника меньше 30 % здоровья - лечить его.<br />
Собственно, окно настройка гамбитов из Final Fantasy 12, где разработчики вынесли часть игровой логики, превратив её в игромеханику (часто нечто подобное происходит и в прочих играх). Первая директива: если у союзника меньше 30 % здоровья - лечить его.

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

Теперь сделано несколько монстров с немного разным поведением. В персональных способностях добавлено лечение. При выделении героя/монстра пишется имя и хитпоинты.

Например, как это работает сейчас - получая ход скелет пытается с места применить стартовый гамбит (атаку), если она получилась, то происходит пост-передвижение и там есть директива с условием (здоровье скелета меньше 50%). Если условие срабатывает, то скелет идёт к цели с малым количеством хитпоинтов. Если нет, то директива пропускается и скелет идёт к ближайшей цели. Если же стартовый гамбит не случился (атака сразу с места невозможна), то скелет бежит к ближайшей цели и во время этого могут сработать финальные гамбиты - атака (если цель оказалась близко), затем бросок головы (у этой директивы есть условие - здоровье скелета должно быть менее 25/%. дальность этой атаки выше, но сам скелет при этом умирает).

Когда скелет "при смерти", то он не будет самоубийственно бросать череп, если рядом окажется цель для ближней атаки. Таким образом, при помощи разных директив с условиями и их порядка срабатывания - настраиваем особенности поведения монстров. Например, зомблину можно поставить поведение, что если удалось провести атаку с места, то дальше он уже никуда не пойдёт - то есть заложить ему чуть более туповатое, неповоротливое поведение. Что касается скелета - можно перенести бросок головы в стартовый гамбит, тогда если "полумёртвый" скелет не нашёл целей ни для ближней атаки ни для броска - он побежит дальше, ища уже цель для ближней атаки, которой скорее всего не обнаружит. Можно перенести бросок в финальный триггер - тогда, скелет сначала постарается сткунуть кого-то с места, потом побежит искать кого стукнуть ближней атакой и только в конце, если всё было безуспешно, посмотрит напоследок - в кого можно бросить голову.

55
11
1 комментарий

ты наверное для статьи сделал больше чем для игры