вторник, 24 декабря 2024 г.

Мои итоги 2024

моё лицо, когда я пишу эти строки

Я воздержался в своё время от итогов 2023, так как они вышли невнятными и депрессивными, но в этом году всё же решился, всё же предыдущие были три года назад. Я вступал в год без каких-то серьёзных планов и собирался импровизировать на ходу. Раскрою сразу конец поста: эта часть не меняется. Увы, планировать что-то сложное в условиях исторических событий является бессмысленным занятием. Нет, я не предлагаю продать всё (и пропить), но большие планы в условные 20 пунктов — это полная ерунда в нынешнее время.

суббота, 21 декабря 2024 г.

Короткий депрессивный пост про мотивацию

 Наткнулся на мысль, что современные управленческие идеи, пришедшие из культуры бигтеха по определению, ведут не то к депрессии, не то к шизофрении, выгоранию в общем :)

Базовая идея мотивации заключается в 100% вовлечении человека в работу, чтобы он прямо ей горел, всего себя ей отдавал. И это хорошо работает, если проект интересный и дела в нём идут замечательно, он выстреливает, растёт, а с проектом — и ценность сотрудника.

Проблемы начинаются с того момента, когда перспективы становятся неясными, что не всегда зависит от сотрудника и компании — есть конъюнктура рынка и другие внешние рамки, которые могут помешать выстрелить. И в этих условиях, когда человек никак не может изменить результат, есть два варианта: 100% гореть, что ведёт к депрессии (сколько ни копай, всё равно не выкопаешь), иначе хотя бы завести хобби. Во втором случае рано или поздно окажется, что проще работать формально и где-то забивать побольше. Очевидно, что второе для конечного индивидуума лучше — проект потом можно и новый начать, а вот расстройство от неудач ещё сто́ит пережить. Но идеи-то требуют противоположного!

В общем, такая себе проблема. Как по мне, идеального решения здесь нет.

вторник, 10 декабря 2024 г.

k-means и pixel-art

 У меня на практике давно встала нехитрая задача перевода картинки в ограниченное количество цветов, по сути — пиксель-арт на минималках. Нужно это в нескольких случаях:

  • Изображение сильно большое и тратить время пиксель-артиста — очень дорого, да и мало кто возьмётся.
  • На изображении немного чётких деталей, так что тратить на него ценное время художника не стоит.
Довольно долго я использовал ручной скриптик на питоне, который считал статистику пикселей, их цветов, пытался как-то через евклидову норму их группировать, но результаты частенько не устраивали — важные цвета терялись, а неважные иногда считались важными.
Попробовал подумать глубже в тему и пришёл к выводу, что технически это... задача кластеризации же! У нас  известно количество кластеров, под которыми подразумеваются результирующие цвета, и нам надо по ним разложить исходные.
Чтобы протестировать эту идею, я взял условный k-means из scikit (sklearn) Питона и попробовал сделать через него — т. е. пиксель по умолчанию имеет тот цвет, что и центр кластера, в который попадает. Но здесь я немного сделал пару хаков - во-первых, цвета взял в HSV, чтобы не кластеризовать условные красные, зелёные и синие цвета, а скорее исходить из оттенка, а во-вторых, добавил мультипликаторы для исходных значений, которые должны давать потенциальное улучшение результата.
Чтобы подизерить результат через евклидово расстояние ищется ближайший подходящий кластер, в который не входит текущий пиксель, оцениваются расстояния до текущего центра и второго и вычисляется вероятность того, что будет браться другой цвет. Это создаёт неплохой эффект, но не идеальный — потому что рандомный дизеринг сам по себе не очень.
В целом результатом доволен, хотя явно можно лучше. В будущем планирую попробовать другие алгоритмы кластеризации, ну и как-то стоит анализировать и само изображение для более хорошего дизеринга.

В заключение небольшой пример:

Исходное изображение

Результат (32 базовых цвета, альфа сохранена, т.к. важное)

Не идеально, но в принципе ок.




пятница, 29 ноября 2024 г.

Про ожидания, опенсурс и планирование.

 Вообще, я уже давно столкнулся с проблемой, которую трудно охарактеризовать. Она заключается в том, что, читая ченджлоги блендеров, редакторов кода и прочего возникает ощущение, что проблем в "обычном" прикладном софте не осталось - всё легко, покрыто туториалами. Бери туториал и пользуйся. И есть ощущение, что мелкие проекты часто сносно можно планировать - даже с учётом обновлений: разобрался раз, потом уже будет быстрее и проблем не будет.

четверг, 28 ноября 2024 г.

Прикладное программирование в 2024 на C++... На TURBO C++!

    Неожиданно набрёл на забавное - книгу "Прикладное программирование на C/C++"

    По названию, кажется, что вот оно - предлагается изучить работу со звуком, изображением и сетями на C++. Ну думается, бомба, сейчас нам покажут что юзать для норм обработки звука, сборки серверов, в общем надо брать.

    А нет, ни разу. Оказалось что это переиздание какой-то очень древней книги, где предлагается кодить на TURBO C++ (MS-DOS, ееее) и верх работы с вышеуказанным - это работа с WinAPI.

    В общем, если надо современный C++ с серьёзной работой с сетью, изображениями и прочим, не рекомендую. Но, если вдруг решите поностальгировать, как там жилось в прошлом, как надо было кодить году максимум в 2005 - однозначно, 10 из 10, одни скриншоты с Windows 98 чего стоят. Ну и на букинистический экспонат это точно годится.

Blender Transparent Film + Bloom

    Недавно перешёл на более новый (4.2) Blender, потому что в старом почему-то нормально не работала анимация. Обнаружил неприятное.

воскресенье, 27 октября 2024 г.

Давайте уже в январе

Я что-то давно ничего не постил и тому было много причин. 

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

Увы, до этого я взял некоторую подработку, и она отняла больше времени чем хотелось, и потребовала ещё потом тщательного рассмотрения. Я, возможно, некоторые моменты по этому распишу позднее, т.к. исследование вышло за рамки обычного ковыряния в коде, а пришлось потрогать всякие стрёмные моменты.

Ещё на меня свалилось маленькое чёрное пушистое счастье, которое сейчас беззаботно дрыхнет где-то за гладильной доской. Собственно, за ней ещё стоит позаботиться, и, частично, это моя забота, хотя Даша и старается.

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

Посты, тем не менее, будут, но, скорее всего, по другим темам. 


среда, 28 августа 2024 г.

Про артбук Cyarin

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

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

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

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

В общем, мне трудновато ругать этот артбук, но и трудно его порекомендовать. Такое себе. 

вторник, 20 августа 2024 г.

Доклад про оптимизацию на современные CPU

 Рекомендую: один из немногих докладов по плюсам, которые стоит смотреть в этом году.




понедельник, 12 августа 2024 г.

SD outpainting limits

Недавно попытался повозиться с сабжем и наткнулся на ограничение в 256 пикселей, и что-то удивился чего так мало. В итоге, в процессе гуглежа набрёл на https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/9532 . У себя в итоге через греп удалось увеличить, но как оказалось ограничение не столько техническое, сколько тюнинг - модель теряет условное "внимание" на больших значениях и уже дальше результаты перестают быть консистентными. Но сохранил себе, как напоминание на всякий пожарный.

Надо конечно посмотреть другие модели и статьи, конечно.

среда, 24 июля 2024 г.

Нет, это не красивый C++. Придумайте честное название!

 Предупреждение: внизу будет зашкаливающе душный пост. Заходить в костюме химзащиты!


Книга, которую все мы (плюсовики) заслужили

(Что мы получили - обложка взята с OZON)


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

воскресенье, 21 июля 2024 г.

Актуалочка про недавний сбой

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

Немного про Giga IDE

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

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

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

Такие дела.

P.S.  А ещё хачю поддержку C++. Греф, когда?

суббота, 20 июля 2024 г.

Простой анимированный генератор появления лавы на поверхности в 2D на Питоне

Вот такого приблизительно и хотелось

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

суббота, 29 июня 2024 г.

"Игровая разработка, когда у тебя много денег и ресурсов"

 

Обложка книги

   Я всё ещё продолжаю разгребать завалы литературы, и мне попалась на глаза "Игровая разработка без боли и кранчей" Ричарда Лемаршана. И, как по мне, это довольно хорошая книга, несмотря на забавное название. Почему я нахожу его немного смешным? Ну, в разработку игр без кранчей, я с трудом, но могу поверить. Но без боли? Ха, и ещё три раза ха. Тут на некоторые движки взглянуть без боли нельзя, а если начать смотреть в их кишки, то единственная реакция на это может быть только изображение ниже. 
После многочасовой отладочной сессии

     Но опять же, книга написана с точки зрения геймдизайнера, причём довольно крупных студий - Naughty Dog язык не повернётся назвать маленькой. Так что речь в книге идёт с позиции этой профессии, а также её роли в процессе разработки.
     Сразу же напишу о том, что в книге не понравилось, так как понравившегося всё же больше. Я сильно не люблю маркетинговый стиль написания книг, когда возникает ощущение, что человек продаёт свою важность и пытается её доказать нам. Как по мне, сам факт покупки книги уже достаточен и особо пиариться и пиарить профессию в тексте нет смысла. Но, к счастью, к середине книги это ощущение исчезает. 
     Ещё часть советов выглядят как "делайте хорошо, а плохо не делайте", т.е. довольно очевидны любому, кто хоть раз открывал литературу по управлению проектами. Ну да ладно, всё же для новичков такое будет полезно.
    Это всё мелочи, но что мне понравилось - замечательное описание документов, оформляемых геймдизом - макродизайна и микродизайна. Отличные советы по оформлению плейтестов - пожалуй, к ним хочется вернуться. Ещё огромный интерес у меня вызвала связь порядка разработки игры с порядком следования элементов сюжета. Она здесь, оказывается, довольно неочевидна, но этому приведено внятное и хорошее обоснование. Я, например, полагал, что начать надо с условного первого уровня игры и так вперёд, а, оказывается, - нет, и даже не с последнего.
   Из управления проектами страшно понравилась идея диаграммы "сгорания задач". В принципе, автопостроение такой диаграммы - классная тема, и, как по мне, полезная вещь. Она в книге не совсем такая, как в вики, и выглядит более удобной.
   Но я не удержусь здесь от небольшой критики - вообще процессы, описанные в книге, выглядят немного тяжеловесными и будут хороши, когда на их поддержание есть ресурсы. Это заставляет задуматься о том, что же можно из всего процесса исключить при управлении маленькой командой? Есть ощущение, что после размышлений в итоге можно прийти к выводу, описанному в одном из ранних докладов о разработке ПО: "Какие планы? Какие диаграммы? Садимся работать и ***шим!"
    Но книгу однозначно рекомендую. Это неплохое чтение, и я, пожалуй, в своей библиотеке оставлю.

четверг, 27 июня 2024 г.

Ghostware: годный шутер 2024 года

главное меню игры

    Пока все судорожно пытаются осилить DLC к сами-знаете-какому сосалику, я решил написать про игру, которая мне страшно зашла и немного удовлетворила ностальгию по шутанам юности. Я имею в виду недавно окончательно вышедшую GHOSTWARE: Arena of the Dead. Узнал я о ней от главного ютубера по бумер-шутерам, как мне кажется - от Civvie11. Собственно, я посмотрел и сразу добавил её в вишлист и, собственно, потом так и купил.

воскресенье, 26 мая 2024 г.

devlog hrtp-demake: Optick и небольшое профилирование.

 


Вот как-то так Optick у меня и выглядел на одной из итераций профилирования

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

вторник, 21 мая 2024 г.

Emperor: Battle For Dune - игра, которая могла стать классикой

 



Сегодня я хочу немного рассказать об игре моего отрочества, в которую успел поиграть после RA2, будучи в поисках чего-то "такого же, но другого". И, как я помню, я относительно быстро её "пробежал", но как-то не стал её потом сильно ковырять: возиться со скирмишами и прочим, как это было с другими RTS. Недавно решил вернуться и подумать:  а что в ней было же не так? Сразу вспомнился графон, который был довольно постный, но видосы на ютуб показывали, что можно выставить и сносное качество, и всё было не так уж плохо. В итоге сел разбираться.

среда, 24 апреля 2024 г.

libPNG 1.6.43 vs stb_image 2.14 на загрузке PNG

    Я  как-то в своё время решил заюзать stb_image для загрузки картинок в движке, ибо он был быстрый, а ещё - легко встраивался в приложение, без страшной возни с зависимостями, условными autoconf и прочим. И в какой-то момент немного поправили в pro.graphon: вот, дескать, libpng быстрее. Беглый поиск привёл меня к тесту, и сомнения стали смущать: а что, если, правда, быстрее? Не пора ли съехать? Забегая вперёд, я хочу отметить сноску в этом посте, где автор пишет, что на малых PNG, у него stb иногда и выигрывал по перфу. И это почти мой случай - у меня нагрузка состоит из POT текстур от 512px до 2048px.

понедельник, 22 апреля 2024 г.

hrtp-demake: релиз демки и босса второго акта.

 



    Наконец могу спокойно релизнуть демку проекта, так как второй босс-файт готов. Впрочем эта часть блога переезжает, и теперь новые новости по проекту будут на https://hrtp-demake.site/ . Сюда только буду кросспостить и делать комментарии не для основного блога проекта. Собственно, скачать билд демки можно по ссылке

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

    Если я вернуть к нему, то, скорее всего  в первую очередь займусь профилированием и вознёй с Optick, т.к. в ряде конфигураций есть явно проблемы с перфом. Ну и третий акт само собой.


четверг, 18 апреля 2024 г.

Про A Thousand Suns

 

(тысяча солнц жи!)

    Вчера по наводке из другого блога, посмотрел текущие вышедшие серии этого соперника "Любви, смерти и роботов" и, в итоге, напомнил этим почему не смотрю 99,5% современного кино.

среда, 17 апреля 2024 г.

О Blood Midnight Blossom

(картинка, сгенерированная условным https://www.craiyon.com/ по запросу)

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

    Недавно натолкнулся на просто невероятное описание визуальной новеллы. Вдумайтесь: "Главная героиня – обычная девушка по имени АННИГИЛЯЦИЯ, которая живёт в маленьком городке А. Она получает по наследству огромный долг своего отца и в отчаянии ищет выход. На улице она встречает незнакомку в плаще, назвавшуюся КАТАРСИС, которая предлагает ДЕМОНСКУЮ подработку на неделю." . Честно говоря, надо отдать должное автору - тут на фоне остальных ВН волей-неволей такое привлекает внимание. Я успел смачно посмеяться над сиим эпичным синопсисом, и вроде бы даже собирался пройти мимо... Но любопытство погубило кошку, и, я всё же не удержался и купил это в стиме.
    Я скажу честно - у меня неоднозначное отношение к русским VN. Да, я успел в юности навернуть пару-тройку японских новелл, но условное "Бесконечное Лето" для меня - просто ужасная графомания начиная с самого начала. Но, в целом я ничего против не имею, хоть у большинства довольно примитивное и скучное описание, не вызывающее интереса.
    ... И игра мне понравилась. Неплохой сеттинг, не самая тривиальная история (даже несколько поворотов сюжета завезли!). Для новеллы по цене за две шаурмы - вообще кайф. Я провёл пару вечеров, выбил большую часть концовок, за минусом тролльной хорошей. 
    Пожалуй, в игре есть два недостатка - крайне короткий сценарий, всё же хотелось бы больше деталей о персонажах, их предыстории и прочем. Оно, конечно, видно, что есть заимствования элементов сеттинга из других (новелл?? аниме?? манги??), но блин, хочется побольше деталей о прошлом героев, их жизни и прочем.
    Второй, более серьёзный - это рисовка. Я хз, где там нейросети, но, как по мне, строго НЕ ХВАТАЕТ иной раз фонов, особенно для всяких экшонистых моментов и динамики. Герои, к несчастью, сильно по рисовке напоминают витюберов и просто просят сделать дизайн персонажей получше.
    Но купить и порофлить можно, надеюсь, у автора появится БЮДЖЕТ, и я в будущем увижу более крутые новеллы от него.

воскресенье, 31 марта 2024 г.

Очередной девлог-апдейт по разработке hrtp-demake

 

(взято отсюда: https://vk.com/wall-143107500_73606)
    Я уже давно не писал ничего на эту тему в первую очередь, потому что был сильно занят на основной работе. Но прогресс по задаче есть: в принципе, все пункты из поста сделаны. Игра на довольно мощной машине грузится не 13с, а 3-5, а то и меньше, памяти отъедает в пике не более 400 Мб, в принципе жить можно. Тесты прошли на основном компе тоже хорошо, особых проблем нет.

    Казалось бы - вперёд, выкладывай и кайфуй. Но, увы, пока сильно радоваться не приходится из-за некоторых технических проблем. Производительность на слабых машинах оставляет желать лучшего, но это не фатально - есть ощущение, что если собрать, наконец, полноценный релизный билд со всеми жёсткими оптимизациями и протестировать его, можно в принципе забить. Это не значит, что профилировать не придётся, но я, скорее всего, отложу такое на будущее. Хочется всё же идти вперёд, а то разглядывать текущий контент, откровенно говоря, задолбало и демотивирует. Ещё последний тест на Windows XP показал странные графические артефакты - возможно, у старья, конечно, отваливается древняя встроенная видеокарта, возможно просто что-то с мипами. Игра при этом работает хорошо, геймплей это не блокирует. Но, скорее всего, и это отложу на потом, хоть мне их и хочется отладить побыстрее и такие проблемы самого раздражают. Юмор ситуации заключается в том, что именно релизный билд с оптимизацией на древнем слабеньком компе с допотопной виндой показывает скорость получше, чем на сравнительно свежем без. В общем - поле для исследования есть, найти бы на это время, как и на планируемую интеграцию Optick для профилирования.

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

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

  Ну и хоть на паре локальных машин посмотреть, насколько всё в релизной сборке работоспособно. Должно быть хорошо - на Windows XP, по сути, она и тестировалась, но неясно являются ли проблемы выше чисто местным колоритом или это что-то иное.

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


вторник, 20 февраля 2024 г.

Про "Архитектуру видеоигровых миров. Уровень пройден!"

     Закончил недавно читать "Архитектуру видеоигровых миров. Уровень пройден!" и теперь могу описать своё мнение об этой книге.

    В целом, в первую очередь - это не гайд и не учебник по левелдизайну. Да, кое-какие советы книга даёт, но они в целом, вряд ли чем-то помогут в сложных случаях.
    Однако, как набор эссе — книга однозначно топ. Мне довольно сильно понравилась идея рассмотреть внутриигровые миры с позиции современного градостроительства и логики архитектуры. Вышло интересно, некоторые моменты действительно вызывают комментарий вида "да как же я сам не догадался?". Однако иногда авторы фиксировались на некоторых странных моментах. Например, условному Найт-Сити из CP2077 досталось по полной - его и так рассматривали, и так. И в некоторых местах пришли к парадоксальному, на мой взгляд, выводу, что как город он не работает. С другой стороны - ну не работает, и ладно. Город как бы сам по себе в стиле ретрофутуризма выполнен, а там далеко не всегда всё было логично и в книгах. Ещё не понравился длительный анализ Control - я в неё не играл, но футажи её архитектуры довольно скучны, как по мне, разбирать там особо нечего.
    Отдельно забавным выглядит раздел 3, где в качестве элементов рассмотрены санузел, дверь, лестницы и монументальное искусство. Да-да, именно в таком порядке. Несмотря на крайнюю забавность, подглава про санузлы написана довольно хорошо, в принципе, читать хочется. Но порядок, честно говоря странный всё равно. Про монументальное искусство стоит сказать отдельно - рассматривать некоторые оставшиеся артефакты, серьёзно изменяющие мир игры, и создающие точки интереса, как монументы (в качестве примера - затонувшая машина из диско элизиума) - по-своему  оригинальная мысль.
    Отдельно зашла типографика - очень хорошо сделано, цветные иллюстрации, и у меня, кроме пары опечаток, нет замечаний.
    Думаю, читать стоит.

суббота, 20 января 2024 г.

Работа с Blueprint-перечислениями (UUserDefinedEnum) из кода на С++ Unreal Engine 5.2+

    Недавно прилетела нетривиальная задача – хотелось дёргать и работать со значениями перечисления, созданного в редакторе UE для блюпринтов.  Навскидку удалось отказаться от этого, просто переведя это само перечисление на плюсы, но осадок остался.  Сел разбираться.

    В документации ясно, что все перечисления из БП имеют тип UUserDefinedEnum, но если прописать UUserDefinedEnum* аргументом в открытом для блюпринтов коде C++, то окажется, что это ассет со всем блюпринтовым Enum   и метод будет принимать на входе сам тип, а не то, что нужно.  Конечно, такое удобно для определённых целей, но всё же, хочется принимать значения.

    Чтобы протестировать то, как же изнутри выглядят такие переменные, я попробовал создать в БП свойство блюпринтового перечисления, найти его через рефлексию и достать оттуда класс.  И оказалось… Там, по сути, обычный FByteProperty.

    Получить его  можно через код вида:

// this – это объект блюпринтового класса, где такое
// свойство есть (в примере это TestEnum) 
UClass* Me = this->GetClass();
if (FProperty* Prop = Me->FindPropertyByName(TEXT("TestEnum")))
{
	if (Prop->GetClass()->GetName() == TEXT("ByteProperty"))
	{
		const FByteProperty* ByteProp = static_cast<FByteProperty*>(Prop);
		uint8 Value = 0;
		ByteProp->GetValue_InContainer(this, &Value);
		// Какой-нибудь вывод значения
		// GEditor->AddOnScreenDebugMessage(
		//     0, 500, FColor::Red, FString::FormatAsNumber(Value)
		// );
	}
}

    Более-менее разбирающийся читатель сейчас уже лезет за вилами и топором – как же так,  мы тут Cast не используем. А вот почему – вот  FProperty,  а вот FByteProperty . Классы связаны, но эта "склейка" иерархий классов возникает где-то на TProperty из-за  чего, судя по всему, компилятор путается и  Cast не работает. Замечу, что это какой-то косяк пятой версии, а, возможно, и самой студии, в четвёртой всё было норм.  Ну или шаблонная магия всё поломала. Опять же, отладчик показывает именно такое. Value, понятное дело, будет содержать числовое значение перечисления.

    Кстати, установка свойства работает аналогично:

const uint8 Value = 1;
ByteProp->SetValue_InContainer(this, Value);

    Чтобы получить более-менее внятное текстовое значение перечисления нужно что-то вида:


// Дорогая операция, лучше закешировать, например передать перечисление аргументом
// PATH_TO_BLUEPRINT_ENUM –  путь к перечислению, можно достать
// через Copy Reference в Content Browser
const UObject* Obj = StaticLoadObject(
	UUserDefinedEnum::StaticClass(), 
	this, 
	TEXT("PATH_TO_BLUEPRINT_ENUM")
); 
if (Obj)
{
	if (const UUserDefinedEnum* UDE = Cast<UUserDefinedEnum>(Obj))
	{
		// Проверка значения на валидность
		if (Value >= 0 && Value < UDE->GetMaxEnumValue())
		{
			// тут будет что-то типа 
			// <имя перечисленияя>::NewEnumerator0
			const FName Name = UDE->GetNameByValue(Value); 
			// а тут реальное, отображаемое в редакторе, 
			// имя значения перечисления
			const FText DisplayName = UDE->GetDisplayNameTextByValue(Value); 
			GEditor->AddOnScreenDebugMessage(
				0, 500, FColor::Red, Name.ToString() + DisplayName.ToString()
			);
		}
		else
		{
			LogRuntimeWarning(FText::FromString(TEXT("Invalid enum value passed")));
		}
	}
}


  Стоит отметить, что при таких условиях нет никакого нормального сильно типобезопасного способа передать в плюсовый код значение перечисления БП или вернуть его. Но опять же, при таких условиях можно тупо передавать целые числа, используя  ToInteger, а возвращать их через преобразование инта применяя Utilities/Enum/Byte To <имя перечисления>, обернув для проверки корректности вызов в блюпринтовую функцию.

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

пятница, 19 января 2024 г.

UMaterial, UMaterialInstanceDynamic, UMaterialInstanceConstant и UpdateStaticPermutation в UE5.2+

    Недавно столкнулся со странностями в архитектуре UE 5.2+. В данном случае – с устройством материалов в движке. Материал, как уже известно, в анриле может быт много чем, но меня интересовала первичное его назначение – когда он работает как эдакий шейдер+ с биндингами переменных. Основной проблемой было то, что материалы странно вели себя при рендеринге из коммандлета, который запускался из консоли – в одну из веток поступали какие-то некорректные данные и, увы, это пока не удалось отладить. Частично из-за того, что нет простой прямой связи между объектами рендеринга и материалами. А ещё RenderDoc упорно не хотел показывать никаких вызовов графического API, хотя рендеринг явно происходил. В итоге принял решение сбросить определённый флажок, который имел вид Static Parameter Switch в наследуемом инстансе материала  и должен был решить проблему за счёт убирания глючащей ветки.

    И вот здесь позволю себе отступления, что вообще во время исполнения EG рекомендуют использовать UMaterialInstanceDynamic, который по идее позволяет избежать лишней компиляции материалов и вообще весь шустрый. В принципе, почему бы и нет? Все нужные методы у него есть, хорошо же? Я говорю, само собой, об условном UpdateStaticPermutation, аж в трёх вариантах, который по идее должен давать возможность переопределять статические параметры.

    А вот нет, ни разу. Перегрузка может не триггерить  повторную компиляцию материала. Беглый поиск по редактору и движку, показал, что там чаще используется вот эта перегрузка. Но самое смешное – это если дёрнуть метод на UMaterialInstanceDynamic, то оно счастливо упадёт с ассертом о том, что лишь UMaterialInstanceConstant можно менять такие флаги. В документации ограничения нет, отсюда и пост.

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

    Справедливости ради создать UMaterialInstanceConstant в рантайме, вполне можно есть вот такой пример. Однако здесь его кидают в ассет, а это не обязательно всё же делать. Зато, кроме переопределения статических параметров, было нужно ещё и копирование настроек из определённого «предыдущего» материала.

    В итоге получилось что-то такое. Это  далеко не оптимальный код, есть ощущение, что если покопаться ещё, то можно ещё отрезать ненужные действия.


UMaterialInstanceConstantFactoryNew* MaterialFactory = 
	NewObject<UMaterialInstanceConstantFactoryNew>();
// Это совсем базовый материал, а вот Material – это инстанс, который хочется копировать. 
// Замечу, что BaseMaterial должен по идее быть UMaterial
UMaterialInterface* BaseMaterial = Material->GetBaseMaterial();
MaterialFactory->InitialParent = BaseMaterial;
const FName MatName = FName(TEXT("REPLACE_WITH_OWN_MAT_NAME"));
// В данном случае нам не интересен пакет, т.к. мы не планируем из этого делать ассет
UMaterialInstanceConstant* Instance = CastChecked<UMaterialInstanceConstant>(
	MaterialFactory->FactoryCreateNew(
    	UMaterialInstanceConstant::StaticClass(), 
        this, 
        MatName, 
        RF_Standalone | RF_Public, 
        nullptr, 
        GWarn
   )
);

// Это обычно делают перед обновлением свойств в редакторе, не стал менять
Instance->PreEditChange(nullptr); 

// Копирование исходных параметров. Замечу, что если родителем Material является 
// другой инстанс, то его тоже стоит скопировать 
Instance->CopyMaterialUniformParametersEditorOnly(Material, true);

// Далее меняем Static Parameter Switch
FStaticParameterSet Set;
// Важно использовать именно эту перегрузку, другая не возвращает базовые свитчи
Instance->GetStaticParameterValues(Set); 
for (auto& Switch : Set.StaticSwitchParameters)
{
     if (Switch.ParameterInfo.Name.ToString() == TEXT("SWITCH_NAME"))
	{
		Switch.Value = <новое значение>;
		Switch.bOverride = true;
	}
}
Instance->UpdateStaticPermutation(Set, Instance->BasePropertyOverrides, true);

// Тут документация недоговаривает, эта принудительная компиляция прекрасно работает 
// и вне FMaterialUpdateContext. 
// Возможно, в будущем всё изменится, но пока это так.
Instance->InitStaticPermutation();  

    Дополнительно можно подёргать всякие сбросы кешей, чтобы сработало, но, по идее, это не обязательно:


Instance->RecacheUniformExpressions(true);
// UPD: 02.03.2024 Вот это вообще на 5.3.2+ начало крашить при рендеринге - причины непонятны, увы
// Впрочем код выше работает и без этого.
Instance->RecacheAllMaterialUniformExpressions(true);
FPropertyChangedEvent Evt(nullptr, EPropertyChangeType::ValueSet);
Instance->PostEditChangeProperty(Evt);
Instance->PostEditChange();

    Как-то так. Это опять же, способ, который я отыскал сам ковырянием в движке и редакторе, но если у кого-то есть более простой и красивый вариант – я буду рад узнать о нём.

четверг, 18 января 2024 г.

Про «Деконструкцию виртуальных миров» Кадикова

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