𝐑𝐨𝐨𝐭𝐓𝐨𝐨𝐥 𝐁𝐥𝐨𝐠
194 subscribers
570 photos
48 videos
5 files
60 links
ニャン
Download Telegram
𝐑𝐨𝐨𝐭𝐓𝐨𝐨𝐥 𝐁𝐥𝐨𝐠
Неожиданный дроп, месяц работы и встречайте - A Cold Love Story Remaster (V1.1) Да-да, хоть кто-то спустя 10 лет взялся за игру Лиама Викерса (Серьезно, он выпустил ее в 2015-м) Чем можем порадовать? - Подчистка от лишних файлов - залог оптимизации (Вес…
A Cold Love Story

Делюсь с вами роликом товарища по SSTWL про криппипасту/новеллу Лиама Викерса - A Cold Love Story
(Делюсь ночью, потому что так атмосфернее)

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

Ссылочка: тык
(Ролик с трудом делался аж 3 месяца, поддержите его как никак)
🔥3❤1
🎶Солнце мое, взгляни на меня🎶
🎶Моя ладонь превратилась в кулак🎶

Что ж.... Что ж.... Прошли недели, улетели месяцы, 1 год разработки и вот она - Портал Солвер Альфа

Безусловно, это не конец. Это далеко не конец

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

Но все равно, было весело проводить время вместе. Конечно кого-то перегнула внутренняя гордыня, кто-то не поделил любовный треугольник а кто-то еще просто не подрос лол

Даже если мы больше не увидимся - то помните, что было весело провести время с вами

А еще было приятно встретить вас на релизе Альфы! Я честно и не думал что вам так все понравится. Да, были баги, хотя фичи тоже были - кататься на лазерном релее это сильно)

Очень высоко оценили саундтреки, меню, оптимизацию (вау) и кастомизацию Солвера

Собственно еще раз благодарю команду, ее бывших участников и вообще всех тех, кого когда-либо встречал. Без вас бы этот день не случился!
❤‍🔥3❤1🔥1🎉1
This media is not supported in your browser
VIEW IN TELEGRAM
Опыт штука прикольная, жаль только приходит со временем


Удивительно, но сегодня начнем с Portal De Solverio

Точнее - БЕКЕНД 💀
Иронично, что в Альфе есть оптимизация, но дьявол скрыт в деталях...
Примерно чтобы вы понимали спектр моей работы сейчас - мне нужно как хирург аккуратно работать с существующей кодовой базой Альфы, перестраивать ее, переписывать, дак еще выпускать патчи

А причина?
- Во-первых... код написан сомнительно, а за год разработки я не один раз наступал на грабли, так еще сроки - нужно было усердно все заматывать изолентой, чтобы это хотя бы запустилось хвхвхвхв)
- Та и во-вторых редактор карт, да! К нему мы стремимся! От чего нужно очень сильно изменить структуру текущего бекенда Альфы. Думаете только мне одному стремно?

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

- UCLASS(MinimalAPI) - удобнейшая штучка для оптимизации. Говоря простым языком - в компиляцию пойдет не весь класс, а только то, что используется. То есть если будут какие-то функции, которые "просто оставлены", но никто с ними не работают - то они не пойдут в финальный билд. Уменьшает время компиляции!

- UInterface - Интерфейсы... Да

В свое время я допустил большую ошибку, когда мне нужно было обновлять лазерные компоненты по-очереди (просто потому что так надо), я накатал небольшую подсистему ULaserSubsystem от UTickableWorldSubsystem (Подсистема, живущая в текущем мире и имеющая тик), и в ней я хранил ссылки на акторы лазерных элементов и там же обновлял их состояние в нужном порядке (TX -> RX -> Cube -> Relay).

Сами понимаете, хранить ссылки на каждый класс это... не круто как-то? Так еще у меня был САМЫЙ НЕЛЮБИМЫЙ КЛАСС в Портал Солвере - LaserClass.cpp, это была тупо затычка, которая всегда багалась и вылетала из-за ТУПЕЙШЕЙ рефлексии Анрила. То компонент удалялся, то неправильно регистрировал все, то вообще... да... Нет слов одни рыданья (Интересно как Альфа еще жива хвхвхв)

Поэтому сейчас начал жествую перепись кода и теперь все строится на абстрактных интерфейсах - на деле это жесть какая удобная штука!

Хотя возникает вопрос - как хранить интерфейсы в массиве? Сделать TArray<AActor*> и каждый тик делать каст на нужный интерфейс? Ха, размечтались...

- TScriptInterface<T> - Контейнер интерфейсов. Обычно интерфейсы являются самостоятельными классами и трудно как-то "взять их", но тут Эпики на удивление постарались и сделали нам TScriptInterface - контейнер, что хранит ссылку на интерфейс, прикрепленный к определенному обьекту. И как бы сложите это и выше сказанное и у вас получится красивенький TArray<TScriptInterface<T>> - именно так и реализовано сейчас. А так как это массив, то его можно спокойно перебрать и делать то, что хотите (вот на примере моего интерфейса ILaserInterface):

for (const TScriptInterface<ILaserInterface>& Laser : LaserArray) // Перебираем каждый элемент массива
if (Laser && IsValid(Laser.GetObject())) // Если сам интерфейс и его родитель существуют (проверяйте, ибо частенько спасает от вылетов в финальной сборке)
Laser->TickLaser(DeltaTime); // То выполняем функцию через интерфейс (В моем случае тик лазера)


(Скоро будет второй пост, ибо есть что рассказать)
❤‍🔥3❤1🎉1🤩1🫡1
Сначала программисты говорят, что у них нет депрессии, а потом смотришь на их компилятор...

59 ФАЙЛОВ НА КОМПИЛЯЦИЮ НА МОЕМ БЕДНОМ i5
❤3🕊1
Успешно отсортировано и закомпилино 74 файлов

Теперь проект отсортирован не только в Контент Браузере, а еще в папке Source (с кодом)

(Не обращайте внимание на 4 файла, классы компилились "пачками", всего их 74)

Могу выделить основные разделы:
- Elements - Классы всех элементов головоломок
- Interfaces - Интерфейсы
- Settings - 2 класса для настроек игры (да, в нашей архитектуре GConfig не раскинут по всему бекенду, а красиво собран в 1 классе)
- Subsystems - Разного рода подсистемы (Discord, GameJolt, Лазеры и тд.)
- UI - Все классы для UI менюшек
- UMG - Классы кастомных UI элементов (А вы думали мы вручную в блюпринтах для каждой кнопочки делаем подсветку текста? Ага)


Так что... проблемы компиляции - это проблемы Анрила
❤2🔥1💘1
This media is not supported in your browser
VIEW IN TELEGRAM
Второй пост!
Тут я решил оставить вам самую вишенку на торте:

- Blueprints -> C++ - Из блюпринтов в С++? Именно: это и есть одна из задач переписи бекенда - избавиться от блюпринтов и перейти на чистый спавн С++ классов в мире (Если кто не в курсе - в меню "Spawn Actor" можно заспавнить как блюпринт, так и чисто С++ класс)

Почему? Когда вы создаете блюпринт, то Анрил вокруг вашего С++ класса создает свою обертку, хотя даже нет... виртуальную среду вокруг С++ класса. Благодаря ей вы можете редактировать этот блюпринт и тд. Но будем честны - если в уровне будет 200+ блюпринтов, то игра банально будет лагучей (И это правда, по ошибке молодости скажу - в Портал Солвер Демо десятки блюпринтов, даже статичных обьектов, вызывало большущие лаги). Но есть небольшая хитрость - то, что вы "делаете мышкой" можно сделать кодом!

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

- ConstructorHelpers::FObjectFinder<T> - Функция, что загружает ассет по определенному пути в конструкторе класса (Можно сказать на моменте его спавна в мире). Прикольная штука, но у меня она перестала работать с половинной ассетов ¯\_(ツ)_/¯ (Sound Cue и Ниагары-Системы)

Чтобы быстро скопировать нужный путь: ПКМ по ассету -> Copy Object Path. И да - НЕ используйте его в любой другой функции, кроме конструктора класса!

А как сделать чтобы обьект мог иметь 2 статик меша по выбору? Тут тоже есть решение

- StaticLoadObject - то же самое, что ConstructorHelpers::FObjectFinder<T>, но является низкоуровневым (и гибким) собратом, не ломает проект если его вызывать не в конструкторе класса, работает со всеми ассетами (как минимум трудностей я не встретил) и вообще он плюс вайб активити (Использование показано на фотке 1)

И теперь вспоминая тот гайд про OnConstruction можем применить эти знания для переключения между статик мешами! (И вот вам домашнее задание хвхвхвх)

Да.... 8 тысяч символов в 2 поста... теперь я буду здесь рассказывать про прогресс и опыт, ибо вы меня очень сильно порадовали на релизе Альфы и поэтому я уже не могу просто опустить руки и пойти отдыхать :)
❤3🔥1🤔1
Наконец-то сделал то, что давно хотел сделать - использовать интерфейсы

Да, я знаю, использовать IsA(T::StaticClass())) это довольно таки плоховато... Хотя знаете, когда только пишешь код, думаешь "Ай ладно, 1 раз сделаю и ничего"

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

Про себя я могу сказать... Если только в UI - спустя +-7 месяцев на С++ я научился создавать реально масштабируемые структуры, от чего добавление нового UI не вызывает головной боли


На 2-й фотке создаем новый интерфейс IHighlightableObjectInterface

На 3-й это результат того, как сильно упростился код. А куда подевалась вся логика? Она ушла на 4-ю фотку. Теперь каждый класс сам решает при каких условиях ему можно подсвечиваться

(От чего мне больше не надо лесть в Солвер Ган, чтобы что-то там добавить)
🔥2❤‍🔥1
Почему.... зачем....
🕊3🤔1🤨1
Лаааадно, такого у меня еще не было со времен переписи UI...

Что могу сказать:
- Теперь все кубы являются самостоятельными акторами и не унаследуются от базового класса кубиков
- Добавлены новые интерфейсы: IIndicatorCubeInterface и IGrabbableInterface
- Также охрененно проделана работа в области раздатчика кубов - теперь раздатчик спавнит не блюпринт куба, а сам куб (вот о чем я вам говорил ранее)
- Ну а также под конец завез нам ABaseCubeElement, который хранит лишь параметр какого типа кубов он относится (обычный, лазерный и тд.). И перед стартом игры он заменяется на соответствующий куб с полной логикой (Сделано для редактора карт)

Зачем? У меня как-то была идея сделать 2 куба в 1: Лазерный + Обычный и переключатель между типами. Но у них сильно отличается логика и их смешивание может полностью убить масштабируемость кода, читабельность и в первую очередь оптимизацию - зачем вам в обычном кубике логика для лазерного? Во-во..

А так я жесть устал, всем спокойной ночи! (Или доброе утро)
❤2🔥1🤩1