Привет всем спонсорам!
Апрельская работа у меня вышла очень продуктивной. Я усиленно работал над проектом и смог реализовать много технических деталей, и о самых интересных я сейчас расскажу.
[Grim Wild]
Новая отрисовка
Это настолько большая тема, что я выделил её в отдельный пост: https://boosty.to/teedeezet/posts/263ca61d-d1b8-4595-a27e-a8e41652d78c
Если же говорить про то, что я сделал именно в апреле, то:
1. Static Sprites v1, которые я сделал в ноябре 2023, оказались "пробой пера" и полным провалом. Игра постоянно вылетала, а спрайты имели слишком много ограничений. Главное, что версия 1 мне дала - это понимание того, что мои идеи достижимы. В апреле я почти с нуля (но уже будучи в теме) сделал v2.
Версия 2 позволяет удалять из атласа ненужные спрайты, так что его полезная нагрузка повышается. Ещё теперь можно поворачивать текстуры, чтобы уместить их в свободное пространство более эффективно.
В версии 2 спрайтам можно назначать любой шейдер, а не только Master Material. Да, объединения Draw Calls из-за этого не будет. Но это не так критично: подавляющее большинство объектов всё-таки останутся на стандартном материале.
2. Новые типы ассетов:
• Sprite Data: для спрайтов. Поддерживаются разные направления (восток/запад, юг, север) и сокеты, которые могут добавляться и изменяться модами
• Icon: для иконок на интерфейсе
• Animation Data (в работе): для "анимаций 2.0", как я назвал их в карте развития. Про её фишки, правда, лучше рассказать когда-нибудь потом
3. Начало разработки механик на основе Static Sprites. Например, отложенное обновление трансформации, свою собственную визуальную стыковку и анимации 2.0. Это всё друг за друга цепляется, поэтому приходится работать над всем сразу.
Думаю, перспективы новой системы отрисовки достаточно позитивные. Самое долгое (этап изучения, пробы пера и попыток избавиться от вылетов) теперь позади, и всё, что мне осталось сделать, займёт уже не так много сил и времени.
ObjectData: шаблоны и под-объекты
Небольшой офф-топ.
Один из ключевых факторов отсутствия у меня выгорания - это занятие несколькими делами одновременно. Такой подход помогает моему мозгу всегда быть в тонусе и не перегружаться определённой задачей.
Обычно я одновременно занимаюсь тремя делами с разным приоритетом. Например, вот схема работы в апреле:
• Высокий приоритет: Static Sprites + новая отрисовка
• Средний приоритет: шаблоны ObjectData
• Низкий приоритет: обновление стиля UI и перенос логики виджетов из Blueprints в C++
Я, "жонглируя" этими задачами, не успеваю от них устать настолько, чтобы они мне надоели.
Так вот, второе дело апреля - это шаблоны и под-объекты для ObjectData.
Под-объект - это термин из UE (Sub-Object), означающий, что сущность является частью какого-то более крупного объекта, а не самостоятельной единицей.
Ещё я ввел термин супер-объект (Super-Object). Это уже аналогия из C++ с его "Super::". Он означает как раз тот самый "более крупный объект", то есть владельца под-объекта.
Как вы знаете, любая сущность в игре (логический компонент, часть тела, событие, технология, поселение, задание...) - это отдельный WorldObject. И эти WorldObject'ы обычно цепляются друг за друга, чтобы сформировать какую-то логику.
Возьмём, например, обычного человека. У него есть тело. У тела - голова. У головы - глаза, рот и причёска. И всё это - разные WorldObject'ы, которые мы определяем на уровне ассета. То есть любой Human в игре имеет всё это по умолчанию.
Серые элементы: определяются внутри ассета Жёлтые: выбираются при генерации
Оранжевые: добавляются людям индивидуально
Раньше мы в ObjectData могли хранить только "пустого" человека. А сейчас - какое угодно количество рекурсивных под-объектов, которые создаются из своих шаблонов во время его спавна.
Ещё одна важная деталь. Каждый под-объект - это отдельный ассет с переписанными данными. Например, возьмём картофелину. Она имеет компоненты Съедобное и Физическое тело. Эти компоненты имеют свой собственный код и взаимодействие с игроком (например, съедобные параметры должны показываться игроку на UI и иметь описание и переводы на разные языки).
Съедобное (красный цвет) = класс компонента. Там написан весь код.
Съедобное (серый цвет) = экземпляр компонента. Мы можем добавлять их в ассеты (в нашем случае, в Картошку) и устанавливать значения переменных.
Думаю, понять весь замысел механики по краткому тексту понять сложно. Ничего страшного! Я посвящу этой теме десятую серию видео (если планы не поменяются).
Сохранение данных игровых объектов на диск идёт относительно их шаблона. Если у какой-то картофелины будет 50/50 ХП, то этот параметр просто не сохранится, ведь он идентичен параметру шаблона. А вот картофелина, у которой 49/50 здоровья, свои изменённые данные уже сохранит.
Это называется Delta Serialization и используется для уменьшения размера сохранения на диске. Правда, в Unreal Engine по умолчанию оно происходит относительно Class Default Object (то есть относительно красной плашки из примера), так что мне пришлось подкрутить это под свои нужды.
Шаблоны: полная совместимость с модами
Когда какой-то ассет загружается в память, он вызывает событие OnAssetLoaded(), к которому могут привязаться любые моды, чтобы изменить в нём какие-то данные.
Пример: в базовой игре у нас есть пистолет, который требует для стрельбы обычные патроны. Мод на продвинутую боёвку изменяет это. Когда пистолет загружается в память, тип патрона меняется на "9mm".
Пример 2: Мод добавляет слот одежды "перчатка" для человеческой руки. Вот, что произойдёт, когда с этим модом мы загрузим ассет человека:
У человека рекурсивно загружаются все вложенные ассеты. То есть голова, тело, причёска и как раз руки.
Во время загрузки ассета руки происходит это:
1) Загружаем данные с диска
2) Вызываем OnAssetLoaded()
3) Мод на перчатки перехватывает событие и модифицирует ассет, добавляя туда слот "перчатка"
После этого рука полностью готова к использованию, так что она (с внедрёнными модами изменениями) вставляется в Человека. Теперь и он имеет в руках слоты перчаток.
Наследование ассетов
Представьте себе ассеты, которые не просто существуют сами по себе, а опираются на другие ассеты и просто изменяют или дополняют их данные.
Например, есть растение "рис". А есть генно-модифицированное игроком растение "ГМ-рис", которое имеет все данные обычного риса и просто модифицирует параметр скорости роста и урожайности.
В данном случае ГМ-рис опирается на обычный рис и наследует все его параметры (кроме скорости роста и урожайности. Они как раз у ГМ-риса переопределены)
Я назвал такую механику Наследованием Ассетов (Asset Inheritance), и она будет очень полезна для модов и неосознанной генерации контента.
Например, какой-то мод создаёт новый вид животного: Супер-бобёр. Он идентичен обычному бобру, но имеет другой спрайт и количество здоровья.
Мододелу не надо создавать новый ассет, чтобы скопировать туда все бобровые данные. Достаточно лишь унаследовать его от классического бобра и изменить всё, что требуется.
Минусы такого подхода:
• Наследованные ассеты загружают в оперативную память свои зависимости. В случае супер-бобра, в ОЗУ загрузится и обычный бобёр тоже.
Плюсы такого подхода:
• Нет копирования одинаковых данных на диске
• Совместимость модов между собой. Примеры:
На данной схеме мы возвращаемся к моду супер-бобров. Но что, если игрок в свою сборку также включит мод "Бобры строят плотины", который добавляет бобрам новый вид деятельности? Унаследованный ассет супер-бобра тоже получит эту активность, хотя эти два мода совершенно никак не связаны друг с другом.
А вот пример, где есть мод на эльфов и мод на перчатки. С помощью наследования эльфа от человека у нас по той же самой логике получается автоматическая совместимость. Эльфы смогут носить перчатки!
Эльфы могут отличаться от человека, например, своими именами, оттенками кожи и навыками. Это всё можно сделать через дополнение "человека"
Пользовательский интерфейс
Я постепенно перевожу интерфейс игры на новый дизайн, который был ещё давно анонсирован.
В связи с этим я переделал свои старые стилизованные виджеты, которые в 2021 году были сделаны для Envision Framework.
Например, я отказался от использования Gameplay Tags, которые нахваливал во второй серии. Они оказались больше проблемными, чем удобными. Поддержку модов с ними внедрять очень сложно, и игра даже может из-за этого вылететь.
Окно Gameplay Tags (картинка из интернета)
Весь функционал интерфейса я переношу из Blueprints в C++. Это нужно для улучшения производительности.
[Публичная деятельность]
Сценарий для седьмой серии находится в работе. Там пока что написано слишком много информации, и объем текста придётся сокращать, выбрасывая самые слабые куски.
Совершенно неожиданно был написан черновик для восьмой серии. Это тот самый пост про отрисовку, который вчера вышел на Бусти. Конечно, он будет переработан для синхронизации с видеорядом. Но наполнение и порядок расположения тем меня уже устраивают.
Итоги месяца: апрель 2024
Торнадо, которое я планирую использовать для вступления седьмой серии. Сделано в Grim Wild.
[Планы на май]
Продолжить работу над всеми текущими делами, потому что ни одно из них не было выполнено на все 100%. Речь и про систему отрисовки, и про шаблоны ObjectData, и про интерфейс.
Сценарий седьмой серии надо будет обязательно закончить. Хотелось бы его заодно озвучить.
Для Envision Video Editor планов нет. Вышел Unreal Engine 5.4, и туда добавили "свой Фотошоп" и "свой After Effects". Теперь UE - это полноценный инструмент для создания моушен-графики. Прежде, чем строить планы на EVE, мне бы хотелось посмотреть, как я могу использовать новые фичи UE на практике. Но не в мае.
[Grim Wild'у 3 года]
1 мая 2021 года я начал делать "GrimWorld", который за всё это время пару раз менял направление и степень серьёзности.
Хотелось бы поскорее закончить техническую часть и перейти к контенту, чтобы увидеть результаты своих многолетних трудов в действии. Думаю, в течение 2024 года это обязательно случится.
Спасибо за внимание!