TGViewer
Channel Public Channel
Unity Architect: архитектура unity проектов

Unity Architect: архитектура unity проектов

@uniarchitect

Пишу о том, что нельзя нагуглить про архитектуру, разработку и пр.

Мой курс по архитектуре: https://course.uniarchitect.dev/y/9b8ec0c

Иногда выкладываю видео и веду стримы: youtube.com/@vangogih

По всем вопросам: @vangogih
Subscribers
5.24K
Photos
35
Videos
2
Links
99

Showing posts older than #74 · Back to latest

Older Posts 20 shown
Post #71 3.68K
КОГНИТИВНАЯ СЛОЖНОСТЬ Ч.2.

Сейчас активно перерабатываю большое кол-во материала по архитектуре.

И решил начать с основ, то откуда все берет свое начало - способы измерения сложности ПО.

В первой части, я попытался сделать выжимку статьи Yingxu Wang'а про Cognitive Complexity
Кто пропустил, крайне рекомендую

И сейчас я перечитываю эту статью и заметил очень интересный тезис, который я чувствовал, но даже не подозревал что это исследовали и даже доказали на практике.

В общем, ниже будет вопрос, ответьте на него про себя честно

Вопрос:
С чем вы испытываете большую сложность в понимании?
1️⃣ Большой класс (модуль) с несколькими вложенными циклами, делающий сложные мат вычисления, например преобразование координат
2️⃣ Маленький модуль с множеством подклассов, которые этот класс вызывает в зависимости от входных данных.
И наличие длинных цепочек взаимосвязанных операций внутри.

Договоримся что оба модуля являются реализацией одной и той же логики внутри.

Ответ:
Согласно выводам из когнитивной информатики (cognitive informatics): Людям проще дается большие циклы итераций, однако люди не очень хорошо справляются с функциональной сложностью (длинная цепочка связей, высокая абстракция объектов)

Цитата:
For instance, according to cognitive informatics (Wang, 2002b, 2003a, 2007b),
human beings may comprehend a large loop of iteration, which is the major issue of computational complexity, by looking at only the beginning and termination conditions, and one
or a few arbitrary internal loops on the basis of inductive inferences. However, humans are not
good at dealing with functional complexities such as a long chain of interrelated operations,
very abstract data objects, and their consistency maintenance.
TAXONOMY OF SOFTWARE COMPLEXITIES IN COMPUTING AND SOFTWARE ENGINEERING, p.4


Мне сложно сделать однозначные выводы из данного тезиса, кроме тех, что упомянуты или очевидны.
Можно просто принять сведению для расширения кругозора 😅

Кстати, в первую часть я не включил этот пункт, т.к. посчитал его достаточно очевидным:
🔸O(N) — вычислительная сложность (time complexity) не влияет на когнитивную сложность.
Аналогично для space complexity

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

Это лишь часть, база, от которой можно будет строить дальнейшие рассуждения и принимать решение на реальных проектах

Ставь 👍 если ты за такую движуху и контент!

#software_engineering@UniArchitect
  • 👍 55
Post #68 3.3K
KISS, SOLID, YAGNY, DRY

И почему я про них не хочу писать.

Однажды в X один чел запостил прикольный пост, который объясняет бесполезность 99% всего интернет-срачей

Вот смотрите, есть исследование, которое гласит что в космосе между Марсом и Юпитером есть чайник

Ваша задача это опровергнуть, го в комменты, я создал 👨‍💻

Вот чушь ведь, но мы не сможем опровергнуть это.

Вот так же подумал чувак и описал один простой закон, его даже в Nature цитировали, лол:
Закон асимметричности чуши — кол-во энергии, необходимое для опровержения чуши, на порядок больше, чем требуется для ее производства.


Признавайтесь, кто распознал Чайник Рассела? 😅

Я 5 раз садился писать статью про KISS, как и обещал в посте про Cognitive Complexity, но нужно просто неимоверное кол-во усилий чтобы доказать абсурдность того, что написал когда-то вояка из VMware.

Кстати есть один хороший инструмент, который используют философы:
Бритва — инструмент, помогающий отбрасывать (сбривать) маловероятные, неправдоподобные объяснения.


Есть пара бритв:
Бритва Оккама — не следует множить сущности без необходимости.
Или что может быть сделано на основе меньшего числа предположений, не следует делать исходя из большего


Моя любимая:
Бритва Хэнлона — никогда не приписывайте злому умыслу то, что вполне можно объяснить глупостью


Главное Хэнлона ненатягивать на все подряд, а то окажется что весь мир построен на глупости 😅

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

Бремя доказательства оставляю за читателями в комментах 😬

А я тем временем решил что буду делать фокус на качестве, своих собственных исследованиях, чтении статей и описание выжимок здесь.

Это способ, которым я учусь с самого начала моей карьеры и который помогает держаться планку профессионала.
Надо же как-то разрабов из универов и с опытом обгонять 😅

Буду рад, если найду научное обоснование принципам, может быть тогда о них и напишу.

А пока я разбираю работы Wang'a и думаю как весь этот годный материал скомпоновать в статьи

Ставь 👍 если ты за такую движуху и контент!

#аббревиатуры@UniArchitect
  • 👍 48
  • 💩 5
  • 🔥 2
  • 🤔 2
Post #65 3.38K
UnityEngine.Object == null

Мне не так давно написал один из разработчиков на проекте, который столкнулся с проблемой зомби объектов.

Зомби объект — жив потому что GC не может его собрать, так как в стэке есть ссылка на него, но сам объект уже Destroyed.

И дело тут не в том, что GC.Collect еще не вызвался, а в том что мы храним указатель на объект, который уже уничтожен.

Такую ситуацию очень легко получить:
🔹Берем любой класс наследник MonoBehaviour
🔹 Реализуем в нем любой интерфейс
🔹 Instantiate'им объект, сохраняем в переменную
🔹 Во вторую переменную cast'им наш объект к интерфейсу
🔹 Уничтожаем MonoBehaviour
Через Object.Destroy или Object.DestroyImmediate
🔹 Пытаемся вызвать поле или метод интерфейса

Вопросы:
🔸 Будет ли MonoBehaviour == null?
🔸 Будет ли переменная интерфейса == null?
🔸 Будет ли ошибка при вызове любого member'а интерфейса?

Подсказка

Ответы:
👍 Да
👎 Нет
❓ И да и нет.
Если вызваемый мембер не часть MonoBehavior имплементации - ошибки не будет
В остальных случаях будет MissingReferenceException


Почему так?
Потому что любой UnityEngine.Object имеет 2 runtime части:
🔹Одна на стороне unity (написанная на C++)
🔹Вторая на стороне CLR (Common Language Runtime) — класс/структура C#

Это значит:
🔸 CLRObject может смотреть уже на уничтоженный UnityObject ровно столько, сколько мы храним указатель на него
🔸 Если UnityObject уничтожен, мы все еще можем обратиться к его CLR части и взять оттуда любые данные, которые не является частью UnityObject
🔸 Момент сборки данного объекта GC может быть отложен на сколько угодно по времени

Это ведет к проблемам:
♦️ Утечки памяти по всему проекту.
UnityObject уничтожен и нам нужно удалить объект из коллекции, а мы не можем, потому что interface != null
♦️MissingReferenceException, в неожиданных местах со вкусом фрустрации и сложной отладки

4 возможных решения:
1️⃣ Проверять все экземпляры типа интерфейса методом:
bool IsNullUniversal<T>(T instance)
{
if (instance is UnityEngine.Object unityObject)
return unityObject == null;

return instance == null;
}

2️⃣ Для абстракции ВСЕХ монобехов использовать только abstract классы
3️⃣ Наследовать все интерфейсы от IEquatable<T> и использовать везде метод Equals вместо ==
4️⃣ (самый быстрый, самый дерзкий)
Через UnsafeUtility читать m_CachedPtr и m_InstanceID и через рефлексию дергать метод DoesObjectWithInstanceIDExist
Вот как это примерно может выглядеть

Почему именно так:
🔸UnityObject содержит перегрузку оператора == и != которая проверят что нативная (C++ часть) "жива"
🔻Но в CLR части == транслируется в операцию seq, которая в после IL2CPP будет выглядеть так:
((((RuntimeObject*)instance) == ((RuntimeObject*)NULL))? 1 : 0)


Или проще говоря в обычное сравнение 2ух указателей.

Такой проверки в случае реализации интерфейса в UnityObject не достаточно.
Потому мы получаем false-negative результат при сравнение на null, который потенциально ведет к утечкам памяти

Я создал Gist в котором расписал подробно TestCase'ы и решение.
Не стесняйтесь его дополнить или предложить свой вариант в комментариях 😎

#будни@UniArchitect
  • 👍 33
  • 🔥 11
  • 🤯 4
Post #63 2.78K
Комиссия Apple Store снизится до 10%

Я плотно следил за судебным разбирательством между Apple и Epic Games

Тогда линия защиты Apple строилась на том, что мол "такие комиссии" у всех
А Epic Games настаивал на том Apple пользуется исключительным правом монополиста диктовать размер комиссии

Закончилось все тем что комиссия осталась на прежнем уровне - 30%, но суд разрешил встраивать сторонние магазины

Дело было 2 года назад, но для самых любопытных ссылка на моей yandex disk с материалами дела

Толи это дело послужило прецедентом, толи Tin Sweeney узнал что европейский союз (the EU) собирается вводить новые правила и вовремя подсуетился, хз. Вопрос яйца и курицы

Но как факт (источник), пока только для EU:
🔻 iOS-приложения в App Store будут платить сниженную комиссию в размере либо 10 %, либо 17 % при совершении сделок с цифровыми товарами и услугами.
🔸 Плата за обработку платежей - приложения для iOS в App Store могут использовать обработку платежей App Store за дополнительную плату в размере 3 процентов.
Разработчики могут использовать провайдера платежных услуг в своем приложении или направлять пользователей на свой веб-сайт для обработки платежей без дополнительной платы Apple.
🔸 Будет добавлен Technical Fee
Приложения для iOS, распространяемые в App Store и/или на альтернативном рынке приложений,
will pay €0.50 for each first annual install per year over a 1 million threshold. расшифровать однозначно это пока сложно.
Но как я понял за каждую установку свыше 1кк в год, платишь 0.5$

Какое дело до этого потребителю:
🔹 Расходы, если и увеличатся, лягут на конечного пользователя, может быть цены чутка изменятся.
Но на мой взгляд инфляция больше сожрет

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

Какое дело до этого разрабам:
🔸 Да никакого, просто инфа похаливарить в чатах

Но самое крутое:
🔻Теперь официально можно принимать оплату И устанавливать игры на устройства Apple через сторонние магазины и сервисы

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

Ждем изменений со стороны Google, Valve, Sony, Nintendo и других платформ цифровой дистрибуции

В интересное время живем, крутые изменения
А вы что думаете? Пишите в комменты 🥰

@UniArchitect
Яндекс Диск Суд apple и Epic Посмотреть и скачать с Яндекс Диска
  • 🔥 8
  • 🤔 5
  • 🤯 2
Post #61 2.76K
АРХИТЕКТУРА И РЕНДЕР

Имеют ли они хоть какую-нибудь связь?

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

Хорошая архитектура позволит:
🔹Не переписывать код при изменении или добавлении требований (разве что лишь маленький кусочек)
🔹Улучшить производительность всего приложения. Причем этот пункт куда важнее, чем при написании обычных скриптов
🔹Позволит легче искать/исправлять баги

Вот конкретные кейсы, когда рендер о части рендера нужно думать заранее:
🔸Когда пишешь свой SRP (Scriptable Render Pipeline)
🔸Есть, пишется свой кастомный шейдер (аля убер-шейдер)
🔸И даже если у тебя уже готовый рендер: Built-in, URP, HDRP, но нужно написать какие-то кастомные фичи

Вот список вопросов, на которые нужно ответить на каждом проекте:
🔹Тени будут или будем fake'ать
🔹Какое способ орисовки, порядок opaque/transparent
🔹Postprocessing нужен ли
🔹Промежуточные pass'ы будут ли и где
🔹Различные пресеты настроек, крутилки художественные (причем некоторые из них должны переопределяться в сцене, а какие-то даже на участке сцены).

ШЕЙДЕРЫ

Странно, но шейдеры это тоже программа, которая просто пишется на другом языке.

Вот почему код в шейдерах и в *.cs файлах одинаков с точки зрения архитектуры:
🔸Находится так же внутри проекта, компилируется, исполняется своим runtime'ом на конечном устройстве
🔸Зашивается и исполняется на клиенте
🔸Можно выносить общую функциональность в отдельные методы.
В отдельные .hlsl файлы и подключать их как include'ы в шейдеры и в другие include'ы.

Соответственно проблемы, которые нужно решать очень похожи, термины местами просто другие:
🔹Какую функциональность куда подключить и нужно ли это вообще
🔹Как должны общаться функции для лучшей производительность и удобства
🔹Как следует подключать include'ы, в каком порядке, как разместить методы в них, по какому признаку
🔹Кого как и почему вынести под keyword'ы и как их организовать

CUSTOM RENDER FEATURE

Допустим, что-то элементарное:
🔸Игрок кликает на юнита и юнит должен получить обводку.
🔸Как сообщить материалу о том, что вот сейчас обводку надо включить а потом выключить?
🔸А цвет обводки?
🔸А если потом понадобится, чтобы обводка меняла паттерн или начинала мигать?

Под конец маленькие список потенциальных проблем, если пустить рендер часть на авось:
🔹Большое количество keyword'ов может привести к взрывному росту комбинаторной сложности.
Это значит — сотни тысяч, миллионы вариантов шейдеров, что отразится в часах компиляции проекта и на размере финального билда
🔹 NaN'ы, +-Infinity роняют проект на проде ни чуть не реже, чем баги в обычных скриптах

И при реализации фичи, эти вопросы всё равно должен кто-то решить. И вполне возможно, что этим "кто-то" окажешься именно ты)

Пост подготовлен при поддержке и редактуре @shiko_q, спасибо😘
Специально для любимого чатика Unity CG Tech

@UniArchitect #проект_с_нуля
Telegram Unity CG Tech Unity CG, все что связано с графикой, Tech Art и Graphic Dev. Рендер, шейдеры, эффекты, текстуры, работа GPU, jobs system, burst, оптимизации и вычисления на видеокарте, etc. По базовым вопросам о unity: @unity3d_ru Флудилка: @unity_flood
  • 👍 17
  • 🤷‍♂ 4
  • 🔥 1
Post #60 2.82K
КОНФИГИ Ч.2 ВЕРСИОНИРОВАНИЕ

Структура конфигов в многом копирует (должна копировать) структуру веток проекта
Т.е. каждая ветка смотрит в свою версию конфигов - в свою google таблицу грубо говоря.

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

Вот случаи, когда "конфиги ломаются" чаще всего становятся несовместимы друг с другом:
🔹 Большая фича, которая сильно изменяет структуру конфигов
Если разраб будет менять одну версию конфигов в своей ветке, рано или поздно его версия станет несовместима с другими ветками
🔹 Конфликт веток разработки
Т.е. в версии кода/конфигов в ветках различаются и разрабатывать новые фичи параллельно с релизом не получается.
🔹 ГД работает над балансом и меняет тип данных

Проблемы с пунктами выше будут только если будет 1 версия конфигов на все ветки, а именно:
🔸 Блокировка работы всей команды до момента синхронизации конфигов и кода в ветке(-ах)
🔸 Потенциальная поломка конфигов в проде

Как решить:
🔹 Каждая версия проекта - своя версия конфигов
🔹 При слиянии веток версия конфигов меняется на актуальную

ВЕРСИОНИРОВАНИЕ

Пример:
1️⃣ Стартуем проект с нуля. Все ветки версия 100 (условно)
2️⃣ Как только происходит feature freeze и проект мержится в stable, создается копия конфигов (версия 200) с которой работает только develop.
3️⃣ Выкатка: rc и master по мере слияния смотрят в 100 версию
4️⃣ После релиза master сливается в develop. Изменения из master конфигов переносятся в develop.
5️⃣ Повторить шаги до следующего релиза

Есть нюанс на пункте 4️⃣:
Может быть ситуация когда версия 100 уже не совместима с версией 200.
Но в 99.9% версия 100 структурно является подмножеством версии 200 и нужно лишь пару полей скопировать из одной таблицы в другую.
На крайний случай master данные имеют приоритет и старая 200ая версия удаляется. Делается копия от master версии 200 и ручками восстанавливаются потерянные данные.

Плюсы:
🔸 Возможность бесшовной выкатки. Версия 100 смотрит в свои конфиги, 200 версия в свои. Это позволяет избежать downtime'а, когда версия 200 уже в сторах, но нужно время для пользователей версии 100 чтобы обновиться.
🔸 Снижение до минимума простоя из-за сломанных конфигов внутри команды

Минусы:
🔹 Больше телодвижений и другой подход к работе в команде и способе выкатки в prod.

Что можно упростить:
🔸 В маленьких командах от веток rc и stable можно отказаться и иметь всего 2 версии конфигов для develop и master
🔸 Можно создавать конфиги новой версии на шаге 4️⃣, а не на шаге 2️⃣. Тогда проблема с шагом 4️⃣ можно забыть

Как работать если фича требует поломки конфигов:
🔹 Работа над фичей ведется в отдельной ветке.
🔹 Просто копируем таблицу, локально или делаем копию прям в google sheets и ставим ссылку на локальную копию
🔹 Синхронизируем данные и структуру при слиянии ветки

И последнее, при работе с кофигами важна коммуникация. Оповещайте свою команду, когда вносите значительные изменения.
Берегите свои нервы и нервы людей с кем работаете ❤️

А как по вашему версионирование конфигов вообще нужно в проекте или это over engineering? 🤔

#проект_в_разработке@UniArchitect
  • 🤔 4
  • 🔥 3
  • 👍 2
  • 🤯 2
Post #59 3.03K
ВЫГОРАНИЕ

В 2015 я впервые познакомился с unity, в 2017 я нашел первую работу, когда учился на 3 курсе универа, в 2019 присоединился как разработчик в молодую компанию Chillgaming с которой мы делали проект Combat Quest.

Параллельно этот проект стал для меня не только первым игровым проектом в моем портфолио, но и первым проектом на котором я выгорел.

Своими словами выгорание — это дикая апатия к делу, к которому ты еще вчера горел. Это чувство полной опустошенности и желание не иметь ничего общего с делом, которому ты отдал большую часть своей жизни.
Если вы, потратив несколько лет на изучение, практику и работу чувствуете что-то подобное — вы выгорели 😵

Я выгорал дважды. И оба раза сценарий один:
🔹 Усердно работаешь, сохраняя средний уровень производительности. Иногда работаешь чуть больше, иногда чуть меньше.
🔹 В один момент нарушаешь этот баланс.
Может быть босс "дал добро" на переработки, может быть вы по "личным соображениям" (самосаботаж, fake it till you make it и пр.) начали работать больше.
🔹 Переработки становятся частью жизни.
8 часов рабочих превращаются в 9 или 16, а между выходными и рабочими днями размывается граница
И самое страшное, организм подстраивается под уровень нагрузки и прежние ужасные "задержался на работе" становятся рутиной

И вот после нескольких недель супер продуктивности, когда так много удается делать, а таски перемещаются в Done одна за одной появляется он:
🔻СТРАХ. Страх потерять в прежнем уровне продуктивности, подвести команду, проект, жену, собаку, себя самого.

Если пропустить, не осознать момент появления этого страха, то он возьмет верх над чувством усталости, измотанности и вы 100% выгорите. Вопрос 1-3 месяцев.

Последствия:
🔸 Продуктивность постепенно падает до нуля
Финальная стадия — отрицательная продуктивность: ваши задачи уходят другому разработчику.
🔸 Становится абсолютно не важно что будет дальше. Срыв сроков, выговор, увольнение? — Плевать, даже думать об этом сил нет.
🔸 Чувство отвращения к любимому делу на срок от 3 до 9 месяцев.
х2 к сроку восстановления, если нет возможности позволить себе не работать все это время.

В сухом остатке:
🔸 1 месяц продуктивности оборачиваются в до 9 месяцев отходняка.
🔸 Проекту плевать на вас и ваши переработки.
Даже если вам за это заплатили, проект, в глобальной перспективе от вашего самопожертвования только минусы. Либо нового сотрудника искать, либо вас из отпуска ждать + время на восстановление.

Как отходить:
🔹 Принять тот факт, что вы выгорели. Чем быстрее - тем лучше.
🔹 Взять отпуск. Чем дольше - тем лучше.
Если вернуться раньше срока, можно опять впасть в апатию или раш, потому что образ мысли остался тот же.
🔹 Сменить место, уехать куда-нибудь на время, в место где вы чувствуете себя хорошо, но где ничего вам не напоминает о работе.
К бабушке в деревню например 🏠
🔹Отдыхать, гулять и просто ждать.
У меня каждое из выгораний проходило только со временем.
Хакнуть систему у меня не получалось, потому что привыкал к переработкам постепенно, менял образ и ритм жизни тоже постепенно.
В одночасье отказаться от этого и жить как прежде не получится.

Я к чему это: у меня на проекте лид ушел в принудительный отпуск на месяц. Сгорел бедняга 🫡
И как человек эмпатичный, мне грустно от этого 🫠

Хочется, чтобы хоть кто-то, прочитав этот пост, решит лично для себя, что свои выходные/отпуск, он проведет не думая о работе.
Полностью переключившись, удалив с телефона slack и выйдя из всех рабочих акков на телефоне и компе.
Проиграв все время в игры или проведя время с любимыми людьми.

🎄С Новым Годом, берегите себя, отдыхайте качественно 🏕

Пост вбирает лишь мои личные ощущения, эмоции и чувства, которые я испытывал, когда выгорал.
Если вы сталкивались с этим, расскажите свою историю в комментах ❤️‍🔥

#проект_в_разработке@UniArchitect
  • 👍 47
  • 🔥 6
Post #58 3.18K
КОНФИГИ Ч.1 АРХИТЕКТУРА

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

Сделать хорошо сразу — сэкономить уйму времени на всех этапах разработки.

Конфиги решают всего одну проблему:
🔻 Создание/модификация параметров игры/приложения у пользователя без пересборки проекта

Дополнительные требования:
1️⃣ Удобство работы: понятный для непрограммистов софт, не требующий дополнительных знаний
2️⃣ Доступность: отсутствие необходимости платить и устанавливать доп. софт
3️⃣ Гибкость: может потребоваться задавать любые форматы данных в параметрах. От чисел и строк, до листов, формул и прогрессий.
4️⃣ Вариации для окружений: для каждого окружения разработки - своя вариация конфигов
5️⃣ Поддержка A/B тестов: возможность делать несколько вариаций значений одного параметра
6️⃣ Обновление в реальном времени
7️⃣ Частичная раскатка новых конфигов с возможностью отката

На проектах с которыми приходилось работать, я встречал реализации:
🔹 UI в unity, который отдает json, который статикой кладется в сервер и отдается клиентам на старте
🔹 ScriptableObject'ы в проекте
🔹 Поход клиента напрямую в google sheets, скачивание таблички и парсинг при каждом старте приложения
🔹 Использование сторонних SaaS решений

Все эти варианты имеют место быть, но каждый из них, так или иначе, не отвечает всем требованиям.

🤓 Разминка: для каждой из реализаций назовите номера требований, которые сложно будет реализовать?
Ответ:
🔹 UI в unity: не удобно (прогерам под каждое новое поле нужно делать изменения в коде), не доступно (потенциально в большой компании придется на каждого ГД по лицензии покупать). 1️⃣2️⃣
🔹 ScriptableObject'ы - вообще ни одно из требований удовлетворить не может. 1️⃣—7️⃣
🔹 Напрямую в google sheets: только 6️⃣, но у google есть лимиты на кол-во запросов в минуту + credential'ы нужно зашивать в билд, что не безопасно
🔹 SaaS решения: если хорошее решение то проблемы, скорее всего, будут только с 3️⃣4️⃣7️⃣.


В идеальном мире, я бы делал так:
🔸 Маленький проект на C# или скрипт на питоне, который умеет: ходить в google sheet, скачивать табличку, преобразовывать ее в json формат и считать хэш-сумму полученного файла
🔸 Машинка, которая слушает команды и запускает проект/скрипт. По факту любого бесплатного runner'a встроенного в любой remote git сервис
🔸 CDN (Content Delivery Network) мультирегиональный в который кладется финальный json и файлик с хэшом
🔸 Логика на клиенте, которая умеет формировать правильный адрес, чтобы забирать нужную версию конфигов.
Ну и логика сверки локального хэша конфигов и удалённого, для обновления

В Silverfox получилось сделать только так, на остальное не хватило времени и потребностей:
— Часть с созданием json'а была на сервере
— Связь с табоицей, парсинг и отдачей клиенту занимался сервер. От клиента только подключиться к правильной версии 😎

А если сервера нет:
— Парсер встроить в клиент
— Класть финальный json ручками напрямую в Firebase
— Использовать Firebase Remote Config как CDN

🎉Тадам 🎉
Сложно? На самом деле черт страшен лишь на вид:
🔸 Для связи с google sheets есть хорошо задокументированная SDK
🔸 Парсер и схема структуризации таблиц уже готова
(не использовал, но писал подобное сам, потому что легко и быстро)

А как вы на проектах работаете с конфигами? — Пишите в комментах!

Вторая часть будет про версионирование 🛞

#проект_с_нуля@UniArchitect
  • 🔥 17
  • 👍 4
  • 🤔 4
  • 🤷‍♂ 1
Post #57 3.05K
ПОСТРОЕНИЕ ДИАГРАММ

Мой первый опыт работы лидом проходил под эгидой: "Я постараюсь выпустить максимально крутой проект с точки зрения разработчика".

Пайплайн работы был такой:
1️⃣ Документация от ГД попадает на оценку разработчикам
2️⃣ Разраб оценивает фронт работ в условных единицах по системе poker planning
3️⃣ Когда задача берется в работу, набрасывается диаграмма классов, которая осматривается и approve'ится с моей стороны. Дорабатывается по требованиям.
4️⃣ Пишется код через TDD
5️⃣ Создается Pull Request и код попадает мне на ревью.
Проверяется что все принципы SOLID соблюдены и в коде нет явных ошибок.
6️⃣ PR так же прогоняется через SonarQube (статический анализатор кода), который подсказывает дополнительно где мы накосячили
7️⃣ Фича проверяется мной в редакторе
8️⃣ Вносятся правки, фича заливается в develop

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

А суть всей разработки такая:
🔸 Делать обговоренный объем работы в обозначенное время

Вот перед тем как читать, давайте разомнем голову вопросом: "Какие шаги вы бы убрали/изменили, чтобы максимально приблизится к сути?"

Ответ:
3,6 можно смело выкидывать
2 зависит от вашего PM'а
4 TDD убрать
А 7 отдать QA


Как можно догадаться, умение составлять диаграммы — не обязательный навык для разработчика.
Это приятное дополнение, которое помогает в коммуникациях:
🔸 С разработчиками на другом языке программирования
🔸 Между разработчиками в команде - через наглядное объяснение как стоит подходить к решению/реализации задачи
🔸 С DevOps инженерами.
Можно очень легко сломать копчик от кол-ва сервисов.
Потому общение диаграммами и умение быстро их накидывать, значительно ускорит работу.
Например у нас был DevOps инженер из Малайзии, где все изменения мы всегда согласовывали через схемы, чтобы убедиться что мы правильно поняли друг друга 😊

Единственное что нужно знать про диаграммы чтобы комфортно с ними работать:
🔸 Отличие имплементации, агрегации и композиции. Это добавит всем диаграммам осмысленности
🔸 Другой человек, скорее всего, так же как и вы не разбирается в тонкостях построений диаграмм
Так что забейте на все связи и правильно донесите свою мысль другому человеку 📞

Почему так? На мой взгляд есть пара объективных причин:
🔸 Диаграммы не содержат логики
🔸 Очень сложно отразить адекватно все связи с реальным классом так, чтобы это было удобно воспринимать
🔸 Диаграммы устаревают так же быстро, как код, а для поддержки их в актуальном состоянии времени нужно чуть ли не меньше, чем само написание кода

#проект_в_разработке@UniArchitect
  • 👍 9
  • 😁 1
Post #56 3K
NETWORKING

Декабрь прошлого года прошел в диком раше.
В Silverfox Games мы готовили большое обновление, в котором планировали добавить: новый UI, daily задания, новых героев и 3 новых режима 🤯

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

С чего все начиналось:
SILVERFOX GAMES НАЧАЛО

Тогда, под конец года, мне в LinkedIn написал сообщение Андрей — CEO Datasakura с предложением созвониться и познакомиться.
Цель была очень простая — расширение списка контактов, для общения в будущем.

В тот момент я находился в диком мыле и был полностью погружен релизом. На столько, что хотфикс в прод я выливал в 7 часов вечера 31 Декабря 🫠

Релиз прошел успешно, правда метрики оказались не очень.
В Феврале, когда стало понятно что с такими показателями инвесторов на seed раунд нам не найти, я начал вспоминать какие знакомые есть и какие гештальты не закрыты.
И вспомнил о сообщении Андрея и опции встретиться лично на Кипре.

Мы с женой как раз перебрались из Турции (потому что мы там были 59 дней) на Кипр.
Там мы планировали задержаться на 2 месяца (именно столько у нас оставалось легальных дней по болгарской визе из-за правила 90 в 180).
Этого времени оказалось достаточно чтобы запланировать встречу.

И вот встреча состоялась только спустя 3 месяца после первого сообщения. А еще через 4 месяца я стал частью компании Datasakura.

Как дела обстояли дальше:
ЖИЗНЬ ПОСЛЕ SILVERFOX

Сама же встреча получилась не навязчивой: не много про работу, про игровую индустрию, опыт и жизнь на Кипре.

Сейчас на дворе Декабрь 2023.
И смотря на то, на сколько маленькая встреча оказала большое влияние на меня, я решил попробовать провести нетворкинг в рамках моего блога.
Вдруг контакты окажутся полезными в будущем году, кто знает 😬

🔻Мое предложение:
— Вот ссылка на мой Calendly (дайте знать в комментах, если есть проблема со ссылкой)
UPD: Остался последний свободный слот!
UPD2: Свободных слотов не осталось!
— В нем я выделил 6 слотов по 45 минут
— Резервируйте удобный вам слот
— В назначенное время созваниваемся и просто общаемся.
Никакой agend'ы, только чистое общение обо всем 😊

Игровая индустрия достаточно тесная, кто знает во что обернется наше знакомство в будущем, так что не стесняйтесь и смело бронируйте 😎
Ограничение только по временным слотам, все остальное не важно, предрассудки и предубеждения смело отбрасывайте и резервируйте слот!

До встречи 📞

#моя_история@UniArchitect
  • 🔥 9
Post #55 2.67K
Unity Architect: архитектура unity проектов ИНИЦИАЛИЗАЦИЯ Точка входа Для правильной инициализации нужно одно: ❕Честная загрузка приложения без фейковых ожиданий и шкал. Это меняет архитектуру объектов, так как загрузка должна быть асинхронной и последовательной. Звучит не сложно, но часто проект…
С ПОЛЕЙ РАЗРАБОТКИ: КРИВАЯ ИНИЦИАЛИЗАЦИЯ

На проекте, где сейчас работаю, все описанные в посте рекомендации нарушены.
И сейчас проект столкнулся с большими проблемами техническими:

1️⃣ Добавилась авторизация на сервере и время загрузки значительно увеличилось.
Отследить почему почти невозможно, потому что процесс инициализации раскидан по 100+ классам.
В итоге почему-то было принято решение бороться с ветряными мельницами и уменьшать кол-во запросов к серверу. Меньше запросов - быстрее загрузка, очевидно же 😵‍💫

2️⃣ Интегрирую FirebaseMessaging и получаю краш.
Нативная SDK кидает исключение как раз в момент, когда компоненты движка еще не проинициализированы.
Видя исключения на старте — ядро андроида просто убивает activity.
В результате ни нормальных логов, ни понимания что конкретно произошло.
А причина отсутствия логов - инициализация под аттрибутом RuntimeInitializeOnLoadMethod 🤕

А вот ниже причина, почему об инициализации нужно думать заранее:
void IInitializable.Initialize()
{
if (config.ConfigLoaded)
InitializeInternal();
else
config.OnConfigLoaded += OnConfigLoaded;

if (playerDataLoader.IsLoaded)
InitializeInternal();
else
playerDataLoader.PlayerDataLoaded += OnPlayerDataLoaded;
}


Честно, каждый раз, когда я пишу такие конструкции просто 🤣 в голос от боли скорее
И вот такое нужно в каждый класс копировать...

Просто представьте как тяжело будет:
— Вызвать логику между загрузкой конфигов и загрузкой профиля игрока 😱
— Перезагрузить игру, если не удалось авторизоваться 😵
— Изменить порядок вызова событий
Это ведь каждую копипасту нужно будет найти и поправить.

Вот так и рождаются ситуации, когда в одном месте "чинишь", а в другом ломается.
Страшно ребят.. мы ведь женам и детям дома нужны.
Берегите себя и инициализацию в своем проекте, амэн 😇

#будни@UniArchitect
  • 😁 7
  • 🤪 4
  • 🔥 2
  • 😨 2
Post #54 2.68K
DevGAMM Lisbon 2023: ИТОГИ

Как я уже писал, для меня это был первый раз, когда я отправился на конференцию от компании.
Моей задачей было — общаться с людьми из разных уголков ЕС и обмениваться контактами, чтобы попробовать найти возможности для сотрудничества

🔻Удалось пообщаться с ребятами из компаний:
🔸 tinyBuild games - у компании огромное количество разных игр под все платформы
В сторис, я рассказывал и показывал игру SpiderHeck прикольный 2D action 👍

🔸 miniclip games — эти ребята не так давно купили SYBO (создатели Subway Surfs).
Они же, по совместительству, создали самый популярный симулятор бильярда 8Pool (>1ккк установок только на android)
Забавно, но я пару лет назад в одной белоруской компании работал над клоном этой игры 😅

🔸 infinity games - делают очень классные медитативные мобилки. Я обожаю подобного рода жвачку для мозгов после работы
Особенно рекомендую поиграть в Maze и Laser Quest — любовь с первого взгляда 😍

🔸 fortis games — это либо темная лошадка мобильной игровой индустрии, либо огромный распил ковидных инвестиций
У компании 0 выпущенных проектов (пока что), ей 2 года, и уже ~300 сотрудников и 6 проектов в разработке 🤯

Из indie проектов понравилась студия, которая делает 2D приключение в оригинальном сетинге, где все персонажи - акулы
Игра называется Townseek, зацените и не забудьте поддержать ребят, добавив игру в wishlist 👍

🔻Доклады
Для меня стало открытием, что гонять по встречами и ходить на доклады это вещи взаимоисключающие друг друга. Маховика времени нет и попасть на некоторые доклады просто не получилось.

Так же докладов технических не было. Как и привычных треков (направлений) докладов по типу: аналитика, техника, бизнес, арт и т.п.
Потому понять какие именно доклады будут прикольные какие нет было сложно и приходилось ориентироваться на имена и компании спикеров.

🔸На открытии конференции выступал Warren Spector.
Этот дядька продюсировал DeusEx, Thief и еще часть известных игр.
Он рассказывал о своей работе в индустрии и делился "мудростями". Иначе это и не назвать, потому что дядечке 68 лет и игры он делает с 90х.

Вот мудрость, которая нашла во мне отклик:
— Здоровье
— Семья
— Работа
Именно контроль и сохранение этих приоритетов по жизни - самое главное.

Я с ним согласен, т.к. за свою недолгую карьеру я уже дважды выгорал.
Сейчас же, после переезда в Испанию, приоритеты явно изменились и я как никто согласен с этой мудростью 🫡

🔸Я фанат проектов компании Supermassive games, которые делают отличные хоррор игры с возможностью игры в кампании друзей.
Просто зацените Until down, Man of Medan и другие игры серии dark anthology

И вот выступала оттуда продюсер, которая ... рассказывала про Flow.
И вот то ли она мою статью про постфикс Flow читала, то ли про процессы рассказывала, то ли про взаимодействие отделов...
И в конце показала картинку из paint. Которую она за 3 часа до доклада сделала и сказала: "Вот так вы можете сделать свое Flow, помните, это очень важно" 🫠

Если вам было тяжело понять о чем я сейчас написал, поздравляю, вы только что испытали те же чувства, что и я после доклада 😬

🔸Был так же прикольный доклад от CEO tinyBuild.
Он рассказывал как создать игру на 1000 часов.

Там была мысль:
Вместо того чтобы создавать 1000 условных уровней, каждый из которых проходится за час, лучше делать различные механики. И вот комбинации механик позволят пользователям самим генерить контент и сохранять вовлеченность.
Примеры: Rust, Minecraft, DayZ, Unturned, Gardenscapes

Вроде очевидно, я наверняка читал об этом в книге A Book of Lenses (на русском "Геймдизайн"), но уже просто забыл 😅

🔻Итоги:
На конференции подобного формата нужно ехать чтобы network'ать и знакомиться с людьми, это было для меня открытием.

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

Напишите пожалуйста в комментах, как вам формат сторис и информации про конференцию?
Писать в будущем, если еще поеду куда? 😎

#DevGAMM_Lisbon_23@UniArchitect
  • 🔥 15
  • 👍 1
  • 🤔 1
Post #53 2.98K
DevGAMM Lisbon

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

Когда я только начинал свою карьеру, я думал что работодатели максимально заинтересованы в росте своих сотрудников и часто отправляют их на конференции, чтобы те могли конвертировать знания в value для компании.

По факту — нет. Меня на всех предыдущих местах работы, всегда отправляли писать обоснование ценности для компании. Дикость крч 😐

Но в этот раз вышло иначе. Мотивация отправить меня на конференцию шла сверху, а именно от CEO Datasakura.
Тут, конечно же, все звезды сошлись как для компании, которая имеет интерес продвигать свои услуги, так и для меня т.к. я всегда мечтал совмещать путешествия и работу.

🔻 В итоге с 15 по 18 я буду в Лиссабоне на игровой конференции DevGAMM.

Для тех кто поедет на конференцию, буду рад встретиться офлайн, пишите в личку или букайте встречу через PINE в любой свободный слот 👍

⚠️ Для тех кто не сможет лично присутствовать на конференции:

У меня есть минимально оборудование (IPhone и стабилизатор), чтобы сделать истории в Telegram в которых я постараюсь рассказывать обо всем интересном что будет на конференции.

Потому взаимовыгодное предложение:
🔸 От меня — качественный контент без воды о том как, где, в какой атмосфере проходит конференция + короткое summary докладов
🔸 От вас — только Boost'ы в Telegram, чтобы я мог публиковать сторис.
Не стесняйтесь boost'ануть по максимуму, ведь это отличная возможность конвертировать не самую популярную фичу телеги во что-то полезное 😬

#DevGAMM_Lisbon_23@UniArchitect
  • 🔥 27
Post #52 4.17K
ЖИЗНЬ ПОСЛЕ SILVERFOX

SILVERFOX GAMES НАЧАЛО
КРАТКИЙ КАРЬЕРНЫЙ ПУТЬ

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

После переговоров с партнером, мы пришли к решению на некоторое время, от года, приостановить развитие компании и сосредоточиться на стабилизации личного состояния

На тот момент я и он за год сменили больше 5 стран, в которых мы жили по 2-3 месяца, при этом управляя компанией. Мы очень сильно от этого устали и хотелось взять паузу 😵‍💫

Мы сошлись на том, что мы на какое-то время устраиваемся на работу, стабилизируем ситуации в наших семьях, стабилизируем финансовое положение и после этого пытаемся восстанавливать деятельность компании

Дальше начался долгий и изнурительный поиск работы. С Апреля по Июль я активно искал работу. За все это время отправил более 200 откликов на вакансии в Европе, Америке и СНГ.
Искал и откликался в основном на Linkedin, но так же использовал Indeed, Glassdoor и сайты компаний

И вот несколько выводов из этого поиска:
🔸Если вы уехали и у вас нет финансовой подушки на полгода, но вы хотите сменить место работы, знайте, сейчас не самое лучшее время для этого.
Игры — развлечение. В кризис, люди отказываются от лишних трат, это снижает выручку компаний, а те в свою очередь сокращают штат или сокращают набор новых сотрудников.
🔸Поиск работы вне СНГ занимает от 3 месяцев
Да, не так как в СНГ и я к этому факту оказался совсем не готов
🔸По факту мало европейских компаний готовы работать в удаленном формате
Чаще всего это гибридный формат, что в свою очередь значит что нужно будет переезжать в страну, оформлять там ВНЖ, искать квартиру и все это за свой счет
🔸Все кто хотел перевезти людей, уже это сделали. Вероятность что перевезут вас, очень низкая.
Примерно 30% отказов было связано с тем, что компания не готова ждать или помогать с переездом 🤷‍♂️
🔸Сейчас рынок работодателя. Он устанавливает цены и может позволить себе выбирать лучших.
Кол-во откликов на одну вакансию на LinkedIn на Senior'а в Европе >200. Представьте что из этих всех людей вам нужно выделиться и занять это место 🤯

Это было долго, изнурительно и очень стрессово. И результатом стало устройство с компанию Datasakura.
Помогаю компании Zeptolab улучшать проект Overcrowded

Компания работает в удаленном формате уже более 5 лет и все процессы максимально подстроены под удаленщиков.
Что, как я упомянул выше, довольно сложно найти

В компании до сих пор ищут Senior Unity Developer, но с последнего поста так же добавилось еще 2 вакансии на C++ и Java Senior Developer

Так что если вы, ваш друг, знакомый, сейчас в поиске, знает Английский, находится вне России и Белорусии, не стесняйтесь закинуть CV 😅

#моя_история@UniArchitect
  • 👍 10
  • 🤗 1
Post #50 3.92K
DEFINE'Ы ПРОЕКТА

В большинстве случаев, делай как удобно и норм.
Но со временем у меня сформировалось 3 подхода к добавление и использованию define’ов в проекте:

1️⃣Восходящий — define’ы и их кол-во определяется фичами, которые используются в проекте. Как бы идем снизу, от фичей.
Начинаются с ENABLE или DISABLE и отключают какой-то функционал, например:
DISABLE_CHEATS, DISABLE_LOGS, ENABLE_SERVER_CONFIGS и т.д.

2️⃣Нисходящий — define’ы и их кол-во определяется потребностями проекта.
Начинаются с имени компании SILVERFOX, ROGAIKOPbITA и отключают/включают целую группу функций, которые должны быть доступны на том или ином окружение.

3️⃣Комбинированный — когда включение одного define’а, включает/отключает несколько фичей. Требует конфигурации глобальных предиктив (те что действуют на весь проект).
К сожалению поддерживается только для проектов, где *.csproj файлы задаются пользователем. В unity эти файлы генерирует только IDE, самому unity они не нужны, т.к. файлы ищутся по всему проекту и отдаются на сборку через csc.exe.

Например вот так в своей студии я организовывал define’ы:
🔹SILVERFOX_RC — отключены читы, отключен fake iap магазин, отключены валидации данных, отключены все логи ниже warning, включена консоль с логами
🔹SILVERFOX_PROD — отключены все фичи отладки и разработки
🔹В случае если ни одна из предиктив не указана, проект собирается со всеми включенными отладками, читами, логами. В общем работает по максимуму на разработчика и поиск проблемы

Плюсы:
🔸Кол-во define’ов полностью синхронизировано с кол-вом веток и их назначением
Про структуру веток, я уже писал тут
🔸Есть четкое понимание когда какой define нужно использовать
🔸Нет проблемы с двойным отрицанием по типу !DISABLE_CHEATS

Минусы:
Как по мне их нет, но если вы нашли, 👨‍💻 в комментарии

На последок не очевидный момент, который заставляет фрустрировать:
♦️Предиктива DEBUG указывает на то, в каком режиме был скомпилирован ваш проект. По умолчанию все c# проекты идут с двумя конфигурациями: DEBUG и RELEASE.
Вот только в unity весь код компилируется только в DEBUG режиме и никак не связан с Development build’ом. Для этого есть отдельный define DEVELOPMENT_BUILD . Это значит, что код под DEBUG всегда будет попадать в финальную сборку.

UPD: про DEBUG я оказался не прав, спасибо @realwar_fx за замечание в комментариях.
Заблуждение сформировалось из-за некачественных проверок мной, а так же из-за отсутствующей документации от unity насчет этого момента. Мое упущение, извиняюсь

Что касается DEBUG:
— Всегда работает в редакторе не зависимо от DEVELOPMENT_BUILD.
Сам DEVELOPMENT_BUILD всегда отключен в редакторе.
— DEBUG включается в билд, только если включен Development Build в настройках
— Debug, Release, Master конфигурации c++ на предиктиву DEBUG никак не влияют
— Release дефайна нет ни в одном из случаев, даже при переключении редактора из debug в release режимы


#проект_с_нуля@UniArchitect
Telegram Unity Architect: архитектура unity проектов СТРУКТУРА ВЕТОК ПРОЕКТА У структуры веток всего 1 требование — деление процесса разработки на понятные стадии. Из опыта создания нескольких проектов с нуля я выделил такую структуру веток: 🔹 develop — разработка. - В этой ветке происходит контролируемый…
  • 👍 9
  • 😎 2
Post #49 3.9K
ИНИЦИАЛИЗАЦИЯ

Точка входа

Для правильной инициализации нужно одно:
❕Честная загрузка приложения без фейковых ожиданий и шкал.
Это меняет архитектуру объектов, так как загрузка должна быть асинхронной и последовательной.

Звучит не сложно, но часто проект сталкивается с проблемами из-за невнимания к этому:
🔹 Инициализация происходит слишком рано
У меня раньше было искажение что инициализация должна происходить до того как загрузится сцена. Такое решение может привести к неочевидным проблемам.

Например: я с Unity IAP ловил такой баг, что черный экран после сплэша висит больше 5 секунд. Как я тогда понял это связано с тем, что жирная логика инициализации под атрибутом RuntimeInitializeOnLoadMethod. Помню на проде долго фрустрировал откуда такая ошибка, потому что тот же logcat ничего путного не показывал 🤔

🔹 Инициализация детерминирована
Когда RRR и инициализация разделяются, но вызовы методов не упорядочены
Или упорядочены не прозрачно, с завязкой на порядок регистрации или BindExecutionOrder

🔹 Логика инициализации выполняется раньше решения графа
Частая ошибка - писать весь код инициализации в Start или Awake, смешивая загрузку и инициализацию ресурсов.
Так можно столкнуться с ситуацией, когда ресурс А зависит от ресурса Б, который еще не готов.

Чтобы этих проблем не было, нужно:
🔸 Разделить фазу RRR и инициализации
🔸 Выделить конcтруктор и метод Init(-ialize)
🔸 Сделать сервис загрузки
🔸 Реализовать все Initialize методы
🔸 Запустить инициализацию, когда все компоненты движка 100% загружены

Тут лежит пример как это может быть 👨‍💻 на практике.
Это реальное тестовое задание, которое я делал пару месяцев назад меня с ним взяли в компанию, где я сейчас работаю

Так же пример точки инициализации с одного из реальных проектов. Для понимания как это выглядит в продакшене 😵‍💫

#проект_с_нуля@UniArchitect
  • 👍 15
Post #48 4.03K
Unity Empty Project Template (UEPT)

Под постом про точку входа собралось больше 50 👍, это просто ошеломительный результат 🤯

После пары выходных плотной работы я подготовил шаблон, с которого вы можете начать создание своего нового проекта 😎

В разделе Installation вы сможете найти инструкции по настройке.
Пока там 10 пунктов, все из которых нужно делать ручками.
Использовать unitypackage не получилось т.к. он игнорирует пустые папки при импорте 😵‍💫

Я хочу написать автоматизацию пунктов 4-9. Окно-помощник, в котором можно будет:
— Переименовать все папки
— Удалить лишние папки
— Переименовать все asmdef и asmref файлы
— Удалить все примеры
— Сгенерировать Scope, Flow файлы для Zenject
Благодаря ему можно будет за пару кликов настроить проект!

Давайте наберем 25 ⭐️ GitHub и тогда еще за пару недель я 👨‍💻 окно-помощник

Как вам шаблон? 👨‍💻 в комменты

@UniArchitect
GitHub GitHub - vangogih/unity-empty-project-template: Low-cognitive complexity Unity project template Low-cognitive complexity Unity project template. Contribute to vangogih/unity-empty-project-template development by creating an account on GitHub.
  • 👍 45
  • 🤯 2
Post #47 4.07K
КОГНИТИВНАЯ СЛОЖНОСТЬ

В 2009 было опубликована статья.
В ней взяли все типы сложности ПО (см. Table 1, стр. 5), расписали критерии их измерения, написали несколько программ, получили данные и сравнили их по значимости.

Для понимания выводов нужно пояснить:
🔸 Символьная сложность (symbolic complexity, definition. 7, стр. 7) — кол-во строк кода
🔸 Операционная сложность (operational complexity) — сумма весов сложности базовых операций (if, switch, for, while, do-while, function call и т.д. Table. 3, стр. 14)
🔸 Архитектурная сложность (architectural complexity, definition 22, стр. 16) — сумма весов всех аргументов, возвращаемых значений и локальных переменных
🔸 Когнитивная сложность одного объекта (unit of cognitive complexity, definition 24, стр. 17) — произведение операционной и архитектурной сложности объекта
Если совсем просто: все операции объекта, помноженные на все его переменные
🔸 Когнитивная сложность ПО (cognitive complexity) — сумма когнитивных сложностей всех объектов системы
🔸 Сложность связей проекта (relational complexity, definition 25, стр. 20) — произведение кол-ва объектов проекта и кол-ва связей объекта с самым большим кол-вом связей
Т.е. как будто все объекты системы одинаково сложны

Вот несколько сухих выводов оттуда:
1️⃣ Минимальная когнитивная сложность — символьная сложность. Когда архитектурная и операционная сложность = 1.
Т.е. проект без циклов, ветвлений, объектов, вызовов методов и т.д.
2️⃣ Максимальная когнитивная сложность — все объекты одинаково сложны
3️⃣ Когнитивная сложность находится между минимальным и максимальным значениями (corollary 4, стр. 21)
4️⃣ Зависимость между минимальной и максимальной сложностью — квадратичная
Т.е. условные 10 строк кода могут создать максимальную сложность в 100. Если каждая из строк будет вынесена в отдельный класс, в отдельный метод с одним аргументом и одним возвращаемым значением

Душно, да? Давайте своими словами:
🔹 Выделение логики в отдельный метод не всегда равно упрощение
Т.е. если метод с 2мя for'ами разбить на 2 метода по 1 for в каждом, то сложность объекта увеличится в 2 раза 🤷‍♂️
🔹 Сделать объект проще = уменьшить его архитектурную и операционную сложность
Т.е. выделить аргументы в 1 объект, избавиться от возвращаемого значения, уменьшить кол-во локальных переменных и уменьшить кол-во операций
🔹 Уменьшение архитектурной сложности ведет к увеличению сложности связей
Т.е. суммарная когнитивная сложность проекта остается такой же
🔹 Когнитивная сложность проекта всегда растет

#software_engineering@UniArchitect
  • 👍 20
Post #46 3.33K
ТОЧКА ВХОДА

Точка входа — LUCA проекта, место откуда все начинается.

А ее первостепенная и единственная задача — прозрачная инициализация проекта/сцены

Критерии прозрачности:
🔹Можно легко найти в проекте/сцене
Объект всегда находится вверху иерархии сцены
На сцене объект всегда называется "EntryPoint"
🔹Сквозное единое именование
Постфикс Scope — для RRR фазы
Постфикс Flow — для фазы инициализации
Пример: BattleScope, BattleFlow, MetaScope, MetaFlow
🔹Единый дизайн классов
Каждый Scope наследуется от класса, предоставляющий функционал IoC контейнера LifetimeScope, MonoInstaller
Каждый Flow начинается с метода Start, в котором происходит вся инициализация

Т.е. мы сначала создаем объекты, inject'им их в Flow, ждем вызова Start и согласно нашему порядку инициализируем.

Из интересного:
🔸Поскольку решение графа и инициализация разделены, то начало работы класса может быть отложено на сколько угодно по времени.
🔸Инициализация в Start освобождает от необходимости помнить что такое ExecutionOrder
Так же защищает от рисков обратиться к внешней зависимости (плагину), которая еще не проинициализирована.
🔸Можно легко включать, отключать части игры, занося блоки инициализации под define
🔸Правило "1 точка входа = 1 сцена" избавляет от racing condition при инициализации
🔸Для инициализации монобехов пишется отдельный метод Init
Start и Awake не реализуются из-за racing condition
Иногда удобно прописать вызов Init в Start, чтобы запустить объект на другой сцене, вне основной системы
🔸Легко сделать примитивный перезапуск игры. Достаточно ещё раз вызвать метод Start

Пост по миграциями собрал больше 15 👍 и я уже начал пилить свою легковесную версию. Следите за обновлениями 😊

Так же думаю сделать базовый шаблон проекта в unity в котором реализую все описанные в #проект_с_нуля рекомендации.
Давайте 30 👍 под этим постом, я за пару недель 👨‍💻 свою версию, которую вы сможете первой импортировать в пустой проект 😎

#проект_с_нуля@UniArchitect
  • 👍 71
Post #45 2.8K
С ПОЛЕЙ РАЗРАБОТКИ: РАБОТА С VPS

Вводные:
Часто при разработке нужно подключиться к удаленному серверу (VPS), чтобы поднять упавший прод, VPN'чик свой развернуть или боевую базу удалить 😵‍💫

Но сегодня я подключался к тачке, к которой доступ был только через QEMU в браузере.

Задача:
Подключиться через ssh к машине

Нюанс:
▫️Буффер-обмена между моей локальной машиной и VPS не работает.
Т.е. вы не можете через ctrl+c ctrl+v передать любые данные.
▫️Для удобной работы нужно прописать в authorized_keys свой публичный ключ
Но вот беда, RSA 2048/4086 ключ, очень длинный. ~400 и ~700 символов, на секундочку 🤯

Возможные варианты решения:
1️⃣ Вбить ручками
2️⃣ Положить ключ в файл с публичным доступом и через curl скачать его.
Например: github gist или на свой веб-сервер.
Проблема очевидна, шарим ключ в паблик и может быть засвечен какими-нибудь nmap ботами.
3️⃣ Настроить синхронизацию буффера-обмена
Проблема: нужно ребутить тачку и не факт что это вообще заработает.

Мое решение:
Использовал не RSA, а ed25519 ключ (он короче RSA в ~8 раз) и вбил его ручками 🤷‍♂️
Проблема: если у вас только RSA, то лучше воспользоваться 2ым решением. Так же не всеми программами он поддерживается (привет postgres)

Дополнение ко 2️⃣ решению:
Можно сделать secret github gist, сгенерировать временный access token и одним curl запросом выкачать его. Подробнее тут
Минусы: весь запрос придется вбивать ручками, но это все равно быстрее и эффективнее чем идти по 2 или 3 пути.

Есть другие варианты? 👨‍💻 в комменты

#будни@UniArchitect
  • 👍 4
  • 😁 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →