Пост - приветствие 👋
Новый год - время новых начинаний, и к наступающему новому 2023 году мы подошли с решением и готовностью создать канал, посвященный разработке игр на Unity.
Мы - это Сергей и Ирина Жильниковы.
О Сергее:
Более 15 лет в разработке от простого программиста до СТО игровых проектов (от гиперкэжа до AAA).
Кроме разработки сфера интересов Сергея включает все области математики и немного физики.
Из интереса к физике вырос патент: “Устройство для функционирования искусственного источника света”.
Об Ирине:
В прошлом Project Manager / Product Owner на проектах от корпоративного сайта до портала футбольного клуба и крупных радиостанций.
Сменила вектор и перешла из области управления командами в область их построения.
У нас накопился большой опыт, которым мы хотим поделиться и со временем обернуть знания и опыт в полноценный курс.
Как начинающему, так и опытному разработчику важно определить цель, к которой он идет.
Рассмотрим ситуацию профессионального роста на двух схожих с разработкой примерах.
Вы решили начать свой путь в олимпиадной математике.
Олимпиадная математика - определенный набор тем, подходов и задач, все есть в открытом доступе и при желании можно найти и изучить самостоятельно.
Но путь человека с ментором и самостоятельный путь - две разные истории.
При одних и тех же вводных данных и способностях человек, заручившись поддержкой ментора, проходит путь успешнее и эффективнее.
Ментор подбирает задачи под ваш уровень таким образом, чтобы сложности стимулировали к взятию новой высоты, а не ставили блок в голове “это невозможно”. Ментор комбинирует задачи с разными подходами. Отслеживает насколько аргументировано построено доказательство. Завернет ли ваше “правильное”, но не достаточно аргументированное решение, жюри или засчитает.
Если смотреть на количество знаковых олимпиад в году, то цена ошибки очевидна как никогда, если не знаешь тонкостей - жди следующего года. Если нет ментора - ты как слепой котенок идешь в темноте.
Рассмотрим более абстрактную ситуацию: вам очень нравятся автомобили, и вы хотите принять участие в их создании, но ранее никогда этим не занимались.
Уберем формальности и представим, что вас взяли в команду, сможете ли вы самостоятельно, без подсказок разобраться с тем, что вам доверили?
Если поставленная задача совсем простая, да. Но при этом вряд ли можно говорить о существенном вкладе в автомобиль.
Кроме вас в команде будут те, кто занимается фундаментальными задачами. К ним можно отнести тех, кто проектирует и реализует двигатель, АКПП, тормозную систему, рулевое управление, проводку, и т.д.
Что вам нужно сделать, чтобы быть одним из них?
Определиться с областью, за которую вы будете отвечать и далее сделать следующие шаги:
Изучить документацию;
Подготовить вопросы, которые возникли в процессе;
Найти наставника с реальным опытом;
Составить план;
Приступить к выполнению задач.
При данном подходе вас будут корректировать, направлять и фокусировать в тех местах, где высок риск ошибки. Процесс обучения и получение собственного опыта пойдет куда быстрее. При этом вы испытаете удовольствие от процесса и будете довольны результатом.
Обе рассмотренные ситуации показывают, что наличие наставника и практический опыт существенно ускоряют путь в выбранной области.
Каким бы ни был уровень подготовки человека, при должном усилии он достигнет успеха. Наша цель - дать большую базу знаний и проверенных временем подходов.
Мы поможем вам улучшить свои навыки.
Пусть наступающий год принесет новые знания и профессиональный рост 🎉
С Новым Годом!
Новый год - время новых начинаний, и к наступающему новому 2023 году мы подошли с решением и готовностью создать канал, посвященный разработке игр на Unity.
Мы - это Сергей и Ирина Жильниковы.
О Сергее:
Более 15 лет в разработке от простого программиста до СТО игровых проектов (от гиперкэжа до AAA).
Кроме разработки сфера интересов Сергея включает все области математики и немного физики.
Из интереса к физике вырос патент: “Устройство для функционирования искусственного источника света”.
Об Ирине:
В прошлом Project Manager / Product Owner на проектах от корпоративного сайта до портала футбольного клуба и крупных радиостанций.
Сменила вектор и перешла из области управления командами в область их построения.
У нас накопился большой опыт, которым мы хотим поделиться и со временем обернуть знания и опыт в полноценный курс.
Как начинающему, так и опытному разработчику важно определить цель, к которой он идет.
Рассмотрим ситуацию профессионального роста на двух схожих с разработкой примерах.
Вы решили начать свой путь в олимпиадной математике.
Олимпиадная математика - определенный набор тем, подходов и задач, все есть в открытом доступе и при желании можно найти и изучить самостоятельно.
Но путь человека с ментором и самостоятельный путь - две разные истории.
При одних и тех же вводных данных и способностях человек, заручившись поддержкой ментора, проходит путь успешнее и эффективнее.
Ментор подбирает задачи под ваш уровень таким образом, чтобы сложности стимулировали к взятию новой высоты, а не ставили блок в голове “это невозможно”. Ментор комбинирует задачи с разными подходами. Отслеживает насколько аргументировано построено доказательство. Завернет ли ваше “правильное”, но не достаточно аргументированное решение, жюри или засчитает.
Если смотреть на количество знаковых олимпиад в году, то цена ошибки очевидна как никогда, если не знаешь тонкостей - жди следующего года. Если нет ментора - ты как слепой котенок идешь в темноте.
Рассмотрим более абстрактную ситуацию: вам очень нравятся автомобили, и вы хотите принять участие в их создании, но ранее никогда этим не занимались.
Уберем формальности и представим, что вас взяли в команду, сможете ли вы самостоятельно, без подсказок разобраться с тем, что вам доверили?
Если поставленная задача совсем простая, да. Но при этом вряд ли можно говорить о существенном вкладе в автомобиль.
Кроме вас в команде будут те, кто занимается фундаментальными задачами. К ним можно отнести тех, кто проектирует и реализует двигатель, АКПП, тормозную систему, рулевое управление, проводку, и т.д.
Что вам нужно сделать, чтобы быть одним из них?
Определиться с областью, за которую вы будете отвечать и далее сделать следующие шаги:
Изучить документацию;
Подготовить вопросы, которые возникли в процессе;
Найти наставника с реальным опытом;
Составить план;
Приступить к выполнению задач.
При данном подходе вас будут корректировать, направлять и фокусировать в тех местах, где высок риск ошибки. Процесс обучения и получение собственного опыта пойдет куда быстрее. При этом вы испытаете удовольствие от процесса и будете довольны результатом.
Обе рассмотренные ситуации показывают, что наличие наставника и практический опыт существенно ускоряют путь в выбранной области.
Каким бы ни был уровень подготовки человека, при должном усилии он достигнет успеха. Наша цель - дать большую базу знаний и проверенных временем подходов.
Мы поможем вам улучшить свои навыки.
Пусть наступающий год принесет новые знания и профессиональный рост 🎉
С Новым Годом!
findpatent.ru
Устройство для функционирования искусственного источника света (два варианта)
Изобретение относится к устройству для функционирования искусственного источника света, в частности к функционированию газоразрядных ламп или ламп накаливания. Устройство для функционирования искусственного источника света содержит генератор с обмотками,…
Связность (cohesion) и зацепление (coupling).
Привет, сегодня поговорим про связность и зацепление в коде.
Полагаю, что каждый сталкивался со спагетти-кодом. Он плохо поддерживаемый и плохо структурированный.
Спагетти-код получается, когда при решении задач мы не уделяем должного внимания проектированию и сразу приступаем к написанию кода.
Проведем эксперимент.
Откроем проект А, который мы не трогали больше года. Весь год мы были заняты активной разработкой проекта Б.
Представим, что нам необходимо добавить какую-либо новую фичу в проект А.
Итак мы открываем проект А и пытаемся ответить на вопрос: "Все ли нам понятно по коду и насколько просто добавить новую фичу?".
Возможные варианты ответов:
- "Код непонятен, фичу добавить сходу не получится" - плохой сигнал;
- "Все понятно, фичу добавить просто" - хороший сигнал, вы уделили должное внимание проектированию.
Как научится проектировать хороший код, который легко поддерживать и развивать?
Первое, на что я советую обратить внимание - два неотъемлемых друг от друга понятия: связность и зацепление.
Связность - это степень того, насколько методы классов, сами классы и категории сфокусированы на выполнении своих задач.
Зацепление - это степень зависимости классов от классов других категорий. Сильное зацепление снижает читаемость и понятность кода.
Игра, которую мы разрабатываем, представляет из себя предметную область со своим набором правил. В рассматриваемой предметной области есть четко выделенные категории.
Представим, что мы разрабатываем Zombie Survival, для примера выделим следующие категории: "Игрок", "Враг", "Инвентарь", и т.д.
Каждая категория - это набор классов.
Например, категория "Игрок" должна отвечать за бизнес-логику и представление всего, что неотъемлемо связано с игроком.
Рассмотрим инвентарь.
Инвентарь поддерживает свой набор методов для работы:
- своп предметов,
- добавление предметов в стек,
- перенос предмета из одной ячейки в другую,
- выделение выбранного предмета инвентаря в UI, и т.д.
Игра развивается поэтапно, и на начальном этапе возможность пользоваться инвентарем предусмотрена только для игрока. Мы решаем реализовать бизнес-логику для работы с инвентарем в классах, которые находятся в категории "Игрок", используя часть классов из категории "Инвентарь".
Спустя какое-то время меняются бизнес-требования, и принимается решение дать возможность пользоваться инвентарем и врагам. Тогда мы добавляем часть необходимой бизнес-логики в категорию "Враг".
Таким образом получается, что за инвентарь частично отвечают классы из категории "Игрок", "Инвентарь" и "Враг". Это приводит к размыванию бизнес-логики по коду и служит примером слабой связности и сильного зацепления.
Хорошим примером будет перенос всей логики работы с инвентарем в классы категории "Инвентарь" и использование этих классов (в виде зависимостей) в классах категорий "Игрок" и "Враг". Это пример сильной связности и слабого зацепления.
Нет никакой необходимости смещать фокус работы с инвентарем в класс, который находится в категории "Игрок" и "Враг".
‼ Необходимо помнить, что сильная связность и слабое зацепление - хороший тон. Слабая связность и сильное зацепление - плохой тон.
Говоря простыми словами.
Связность - это насколько корректно сгруппированы классы по категориям и сфокусированы на задачах своей категории.
Зацепление - это насколько запутаны связи в коде.
Привет, сегодня поговорим про связность и зацепление в коде.
Полагаю, что каждый сталкивался со спагетти-кодом. Он плохо поддерживаемый и плохо структурированный.
Спагетти-код получается, когда при решении задач мы не уделяем должного внимания проектированию и сразу приступаем к написанию кода.
Проведем эксперимент.
Откроем проект А, который мы не трогали больше года. Весь год мы были заняты активной разработкой проекта Б.
Представим, что нам необходимо добавить какую-либо новую фичу в проект А.
Итак мы открываем проект А и пытаемся ответить на вопрос: "Все ли нам понятно по коду и насколько просто добавить новую фичу?".
Возможные варианты ответов:
- "Код непонятен, фичу добавить сходу не получится" - плохой сигнал;
- "Все понятно, фичу добавить просто" - хороший сигнал, вы уделили должное внимание проектированию.
Как научится проектировать хороший код, который легко поддерживать и развивать?
Первое, на что я советую обратить внимание - два неотъемлемых друг от друга понятия: связность и зацепление.
Связность - это степень того, насколько методы классов, сами классы и категории сфокусированы на выполнении своих задач.
Зацепление - это степень зависимости классов от классов других категорий. Сильное зацепление снижает читаемость и понятность кода.
Игра, которую мы разрабатываем, представляет из себя предметную область со своим набором правил. В рассматриваемой предметной области есть четко выделенные категории.
Представим, что мы разрабатываем Zombie Survival, для примера выделим следующие категории: "Игрок", "Враг", "Инвентарь", и т.д.
Каждая категория - это набор классов.
Например, категория "Игрок" должна отвечать за бизнес-логику и представление всего, что неотъемлемо связано с игроком.
Рассмотрим инвентарь.
Инвентарь поддерживает свой набор методов для работы:
- своп предметов,
- добавление предметов в стек,
- перенос предмета из одной ячейки в другую,
- выделение выбранного предмета инвентаря в UI, и т.д.
Игра развивается поэтапно, и на начальном этапе возможность пользоваться инвентарем предусмотрена только для игрока. Мы решаем реализовать бизнес-логику для работы с инвентарем в классах, которые находятся в категории "Игрок", используя часть классов из категории "Инвентарь".
Спустя какое-то время меняются бизнес-требования, и принимается решение дать возможность пользоваться инвентарем и врагам. Тогда мы добавляем часть необходимой бизнес-логики в категорию "Враг".
Таким образом получается, что за инвентарь частично отвечают классы из категории "Игрок", "Инвентарь" и "Враг". Это приводит к размыванию бизнес-логики по коду и служит примером слабой связности и сильного зацепления.
Хорошим примером будет перенос всей логики работы с инвентарем в классы категории "Инвентарь" и использование этих классов (в виде зависимостей) в классах категорий "Игрок" и "Враг". Это пример сильной связности и слабого зацепления.
Нет никакой необходимости смещать фокус работы с инвентарем в класс, который находится в категории "Игрок" и "Враг".
‼ Необходимо помнить, что сильная связность и слабое зацепление - хороший тон. Слабая связность и сильное зацепление - плохой тон.
Говоря простыми словами.
Связность - это насколько корректно сгруппированы классы по категориям и сфокусированы на задачах своей категории.
Зацепление - это насколько запутаны связи в коде.
#библиотека_программиста #геймдев
Сегодняшний пост я хочу посвятить фундаментальной литературе.
Я подготовил небольшую подборку книг, которая будет полезна как для опытных разработчиков, так и для новичков.
1. Фундаментальные алгоритмы на C++, части 1-4, Роберт Седжвик
2. Паттерны объектно-ориентированного проектирования, Ричард Хелм, Роберт Джонсон, Эрих Гамма
3. Одна из двух книг: Архитектура корпоративных программных приложений или Шаблоны корпоративных приложений, Мартин Фаулер
4. Чистая архитектура. Искусство разработки программного обеспечения, Роберт Мартин
5. Multiplayer Game Programming: Architecting Networked Games (Game Design), Josh Glazer, Sanjay Madhav.
📚 Подробнее о каждой из книг:
1. Фундаментальные алгоритмы на C++, части 1-4
Эта книга дает глубокое понимание основных структур данных, с которыми вы будете сталкиваться в своей практике.
Хотя код написан на C++, к каждому алгоритму или структуре данных приводится полное описание работы, что даст понимание и для других языков (в нашем случае C#).
Читать можно обзорно.
Подходит и для новичков, и для профессионалов.
2. Паттерны объектно-ориентированного проектирования
В книге описаны паттерны проектиования, дается детальный разбор каждого из них.
Подходит и для новичков, и для профессионалов.
3. Архитектура корпоративных программных приложений или Шаблоны корпоративных приложений
В книгах раскрываются такие понятия как: слои абстракции, домены, бизнес-логика, дается набор типовых архитектурных решений.
Можно почитать обзорно, некоторые из решений вполне применимы в геймдеве.
Подходит и для новичков, и для профессионалов.
4. Чистая архитектура. Искусство разработки программного обеспечения
Книга содержит много полезной информации, как по архитектуре, так и по основным принципам, которые применяются в разработке.
Рассматриваются базовые принципы ООП.
Книгу легко читать. Большая часть того, что написано применяется в разработке.
Подходит и для новичков, и для профессионалов.
5. Multiplayer Game Programming: Architecting Networked Games (Game Design)
Опционально для тех, кто хочет погрузиться в разработку multiplayer игры.
Книга раскрывает аспекты сетевой разработки.
Рассматриваются базовые принципы построения multiplayer игр.
Подача материала рассчитана на опытных разработчиков.
‼ Невсегда погружение в материал проходит гладко, при прочтении могут возникать сложности в понимании, и это асболютно нормально. Попробуйте сделать несколько заходов.
Приятного прочтения 🙂
Сегодняшний пост я хочу посвятить фундаментальной литературе.
Я подготовил небольшую подборку книг, которая будет полезна как для опытных разработчиков, так и для новичков.
1. Фундаментальные алгоритмы на C++, части 1-4, Роберт Седжвик
2. Паттерны объектно-ориентированного проектирования, Ричард Хелм, Роберт Джонсон, Эрих Гамма
3. Одна из двух книг: Архитектура корпоративных программных приложений или Шаблоны корпоративных приложений, Мартин Фаулер
4. Чистая архитектура. Искусство разработки программного обеспечения, Роберт Мартин
5. Multiplayer Game Programming: Architecting Networked Games (Game Design), Josh Glazer, Sanjay Madhav.
📚 Подробнее о каждой из книг:
1. Фундаментальные алгоритмы на C++, части 1-4
Эта книга дает глубокое понимание основных структур данных, с которыми вы будете сталкиваться в своей практике.
Хотя код написан на C++, к каждому алгоритму или структуре данных приводится полное описание работы, что даст понимание и для других языков (в нашем случае C#).
Читать можно обзорно.
Подходит и для новичков, и для профессионалов.
2. Паттерны объектно-ориентированного проектирования
В книге описаны паттерны проектиования, дается детальный разбор каждого из них.
Подходит и для новичков, и для профессионалов.
3. Архитектура корпоративных программных приложений или Шаблоны корпоративных приложений
В книгах раскрываются такие понятия как: слои абстракции, домены, бизнес-логика, дается набор типовых архитектурных решений.
Можно почитать обзорно, некоторые из решений вполне применимы в геймдеве.
Подходит и для новичков, и для профессионалов.
4. Чистая архитектура. Искусство разработки программного обеспечения
Книга содержит много полезной информации, как по архитектуре, так и по основным принципам, которые применяются в разработке.
Рассматриваются базовые принципы ООП.
Книгу легко читать. Большая часть того, что написано применяется в разработке.
Подходит и для новичков, и для профессионалов.
5. Multiplayer Game Programming: Architecting Networked Games (Game Design)
Опционально для тех, кто хочет погрузиться в разработку multiplayer игры.
Книга раскрывает аспекты сетевой разработки.
Рассматриваются базовые принципы построения multiplayer игр.
Подача материала рассчитана на опытных разработчиков.
‼ Невсегда погружение в материал проходит гладко, при прочтении могут возникать сложности в понимании, и это асболютно нормально. Попробуйте сделать несколько заходов.
Приятного прочтения 🙂
#паттерны_геймдев
Энтерпрайз vs Геймдев
Привет, предлагаю немного поговорить о разнице подходов для энтерпрайз и геймдев разработки.
Отличительная особенность энтерпрайз разработки - высокая стабильность (неизменность) базовых бизнес-процессов.
Например, если основная задача приложения выставлять счета, то в течение продолжительного времени данное требование остается неизменным.
Энтерпрайз характеризуют достаточно стабильные связи между системами и их компонентами.
Здесь хорошо применимы интерфейсы. Все приложение строится на реализации контрактов и связей между ними.
Такой подход обеспечивает слабое зацепление и сильную связность кода.
Для энтерпрайз характерна простота слоя представления.
Здесь хорошо подойдут большинство стандартных принципов ООП и паттернов проектирования, таких как: MVC, MVP, MVVM, и т.д, в том виде, в котором они описаны в специализированной литературе.
В геймдеве же напротив очень часто меняются бизнес-требования. От спринта к спринту гейм-дизайнер или продюсер могут менять свое видение продукта.
Частое изменения сопряжено с проверкой гипотез, анализом конкурентов и волатильностью рынка.
Приведу в качестве примера эволюцию игрового банка. Допустим, стоит задача добавления в игру первой версии банка (это первая реализация в рамках продукта и ранее ничего подобного мы не делали). Задача может звучать: “дать возможность игрокам покупать игровые предметы, выводя их списком”. Это наш первый банк и цель первой итерации - проверить монетизацию на самой простой версии.
Спустя время банк эволюционирует до разбиения игровых предметов по категориям и объединения их в паки.
Часть ранее выполненных задач могут оказаться ненужными или подвергнуться значительным доработкам.
Реализация кода через интерфейсы и связи между ними в геймдеве в большинстве случаев не позволит обеспечить сильную связанность и слабое зацепление.
Применение интерфейсов в связке с паттернами MVC, MVP, MVVM, и т.д, как правило ведет к росту количества связей между системами. Удержать проект в голове становится всё сложнее. При ротации команды сильно увеличивается технический долг.
Поэтому базовые паттерны, такие как: MVC, MVP, MVVM не подходят в чистом виде (то, как их описывают в специализированной литературе) для использования в геймдеве и требуют дополнительной адаптации.
Энтерпрайз vs Геймдев
Привет, предлагаю немного поговорить о разнице подходов для энтерпрайз и геймдев разработки.
Отличительная особенность энтерпрайз разработки - высокая стабильность (неизменность) базовых бизнес-процессов.
Например, если основная задача приложения выставлять счета, то в течение продолжительного времени данное требование остается неизменным.
Энтерпрайз характеризуют достаточно стабильные связи между системами и их компонентами.
Здесь хорошо применимы интерфейсы. Все приложение строится на реализации контрактов и связей между ними.
Такой подход обеспечивает слабое зацепление и сильную связность кода.
Для энтерпрайз характерна простота слоя представления.
Здесь хорошо подойдут большинство стандартных принципов ООП и паттернов проектирования, таких как: MVC, MVP, MVVM, и т.д, в том виде, в котором они описаны в специализированной литературе.
В геймдеве же напротив очень часто меняются бизнес-требования. От спринта к спринту гейм-дизайнер или продюсер могут менять свое видение продукта.
Частое изменения сопряжено с проверкой гипотез, анализом конкурентов и волатильностью рынка.
Приведу в качестве примера эволюцию игрового банка. Допустим, стоит задача добавления в игру первой версии банка (это первая реализация в рамках продукта и ранее ничего подобного мы не делали). Задача может звучать: “дать возможность игрокам покупать игровые предметы, выводя их списком”. Это наш первый банк и цель первой итерации - проверить монетизацию на самой простой версии.
Спустя время банк эволюционирует до разбиения игровых предметов по категориям и объединения их в паки.
Часть ранее выполненных задач могут оказаться ненужными или подвергнуться значительным доработкам.
Реализация кода через интерфейсы и связи между ними в геймдеве в большинстве случаев не позволит обеспечить сильную связанность и слабое зацепление.
Применение интерфейсов в связке с паттернами MVC, MVP, MVVM, и т.д, как правило ведет к росту количества связей между системами. Удержать проект в голове становится всё сложнее. При ротации команды сильно увеличивается технический долг.
Поэтому базовые паттерны, такие как: MVC, MVP, MVVM не подходят в чистом виде (то, как их описывают в специализированной литературе) для использования в геймдеве и требуют дополнительной адаптации.
#паттерны_геймдев #базис_геймдев #структуры_данных
Паттерны, структуры данных, векторная алгебра
Во время интервью часто спрашивают теорию: структуры данных, паттерны проектирования, векторную алгебру и проч.
Часть кандидатов воспринимают данные вопросы с удивлением: "Пишу код - зачем мне теория". Давайте рассмотрим нужны ли эти знания на практике.
Но зайдем издалека
В процессе разработки игры, мы управляем набором критериев:
- скорость разработки
- простота алгоритма
- сложность понимания кода
- скорость работы
- размер потребляемой памяти
- стоимость доработок
- устойчивость кода к изменениям
- и т.д.
Перед разработчиком стоит задача многокритериальной оптимизации. Оптимальное решение - то, к чему мы должны стремиться.
Игровой проект - набор задач, которые могут решаться оптимально или нет.
Процентное соотношение оптимально и неоптимально решенных задач влияет на обозначенные ранее критерии.
Наличие багажа знаний помогает аргументировано и быстро сделать осмысленный выбор.
Структуры данных
Каждая структура данных предназначена под определенных цели.
Знание и уместное применение влияет на:
- простоту алгоритма
- скорость работы кода (например, насколько быстро получим доступ к элементу)
- размер потреблебляемой памяти
- стоимость доработок, и т.д.
Паттерны
Знание основных паттернов проектирования влияет на:
- скорость разработки
- сложность понимания кода
- стоимость доработок
- устойчивость кода к изменениям, и т.д.
Векорная алгебра
Это базис, на котором строится разработка игр. Большая часть игрового мира (как 3D, так и 2D) базируется на понятиях вектора. Это задачи связанные с поворотами, проверкой направленности объектов (их векторов), движение объекта к определенной цели (разница векторов), и т.д.
В рамках текущей публикации ограничусь абстрактным примером, касающимся выбора структуры данных под решаемую задачу.
Допустим есть мир, куда каждый интервал времени спавнятся игровые объекты, которые необходимо хранить. Каждый игровой объект с течением времени может превращаться в другой. Описание каждого игрового объекта (экземпляр класса) находится в коллекции с контентом.
Задачу разобьем на 2 части:
- хранение заспавненных объектов
- превращение одного объекта в другой.
Для хранения заспавненных объектов можно использовать List и LinkedList. Сравним их между собой.
List - базируется на массиве, размер которого определен по умолчанию либо задан разработчиком. Размер массива не может меняться динамически. Если в List добавляется большое количество элементов, при выходе за изначально заданные размеры массива происходит перевыделение памяти под необходимый новый размер и копирование старой области данных в новую. Частое перевыделение памяти может сказаться на производительности работы приложения.
LinkedList лишен этого недостатка. При динамическом добавлении элементов не происходит переаллокация памяти.
В данном случае LinkedList будет более оптимален.
Рассмотрим реализацию превращения одного объекта в другой, сравнив List и Dictionary.
Пусть в момент превращения в контентной коллекции необходимо найти объект (по id), в который будет превращен исходный. При использовании List в худшем случае для поиска придется обойти всю коллекцию. Более эффективно создать дополнительную структуру данных или изначально хранить коллекцию в виде Dictionary, где ключом будет выступать требуемый параметр для поиска, например id. Поиск по словарю осуществляется за константное время и не зависит от размера коллекции.
Паттерны, структуры данных, векторная алгебра
Во время интервью часто спрашивают теорию: структуры данных, паттерны проектирования, векторную алгебру и проч.
Часть кандидатов воспринимают данные вопросы с удивлением: "Пишу код - зачем мне теория". Давайте рассмотрим нужны ли эти знания на практике.
Но зайдем издалека
В процессе разработки игры, мы управляем набором критериев:
- скорость разработки
- простота алгоритма
- сложность понимания кода
- скорость работы
- размер потребляемой памяти
- стоимость доработок
- устойчивость кода к изменениям
- и т.д.
Перед разработчиком стоит задача многокритериальной оптимизации. Оптимальное решение - то, к чему мы должны стремиться.
Игровой проект - набор задач, которые могут решаться оптимально или нет.
Процентное соотношение оптимально и неоптимально решенных задач влияет на обозначенные ранее критерии.
Наличие багажа знаний помогает аргументировано и быстро сделать осмысленный выбор.
Структуры данных
Каждая структура данных предназначена под определенных цели.
Знание и уместное применение влияет на:
- простоту алгоритма
- скорость работы кода (например, насколько быстро получим доступ к элементу)
- размер потреблебляемой памяти
- стоимость доработок, и т.д.
Паттерны
Знание основных паттернов проектирования влияет на:
- скорость разработки
- сложность понимания кода
- стоимость доработок
- устойчивость кода к изменениям, и т.д.
Векорная алгебра
Это базис, на котором строится разработка игр. Большая часть игрового мира (как 3D, так и 2D) базируется на понятиях вектора. Это задачи связанные с поворотами, проверкой направленности объектов (их векторов), движение объекта к определенной цели (разница векторов), и т.д.
В рамках текущей публикации ограничусь абстрактным примером, касающимся выбора структуры данных под решаемую задачу.
Допустим есть мир, куда каждый интервал времени спавнятся игровые объекты, которые необходимо хранить. Каждый игровой объект с течением времени может превращаться в другой. Описание каждого игрового объекта (экземпляр класса) находится в коллекции с контентом.
Задачу разобьем на 2 части:
- хранение заспавненных объектов
- превращение одного объекта в другой.
Для хранения заспавненных объектов можно использовать List и LinkedList. Сравним их между собой.
List - базируется на массиве, размер которого определен по умолчанию либо задан разработчиком. Размер массива не может меняться динамически. Если в List добавляется большое количество элементов, при выходе за изначально заданные размеры массива происходит перевыделение памяти под необходимый новый размер и копирование старой области данных в новую. Частое перевыделение памяти может сказаться на производительности работы приложения.
LinkedList лишен этого недостатка. При динамическом добавлении элементов не происходит переаллокация памяти.
В данном случае LinkedList будет более оптимален.
Рассмотрим реализацию превращения одного объекта в другой, сравнив List и Dictionary.
Пусть в момент превращения в контентной коллекции необходимо найти объект (по id), в который будет превращен исходный. При использовании List в худшем случае для поиска придется обойти всю коллекцию. Более эффективно создать дополнительную структуру данных или изначально хранить коллекцию в виде Dictionary, где ключом будет выступать требуемый параметр для поиска, например id. Поиск по словарю осуществляется за константное время и не зависит от размера коллекции.
#solid #solid_геймдев
Для чего нужен SOLID
Всем привет, сегодня говорим про SOLID (далее по тексту - классический SOLID).
Публикацию разобьем на 2 части: в первой упростим и выделим суть каждого принципа применительно к геймдеву, во второй рассмотрим проблемы.
SOLID - это набор из 5 принципов ООП, которые сформулировал Роберт Мартин. Аббревиатура была предложена Майклом Фэзерсом.
Определение звучит так: "SOLID - это руководства, которые также могут применяться во время работы над существующим программным обеспечением для его улучшения, например, для удаления «дурно пахнущего кода»".
Про SOLID спрашивают, его обсуждают с докладами на конференциях, его относят к правилам хорошего тона. Те, кто поопытнее пытаются применять SOLID на практике.
Но действительно ли разработчики понимают, как правильно применять SOLID принципы в геймдеве?
Практика показывает, что понимание принципов работает, как испорченный телефон.
Ведь каждый с высоты опыта и багажа по-своему интерпретирует, понимает и применяет на практике полученную информацию.
Часто в финале у большинства команд получается эдакий монстр-франкенштейн с кучей интерфейсов и их реализацией.
Код получается слабо связным и с сильной степенью зацепления.
Рассмотрим классический SOLID применительно к геймдеву.
Разберемся, что находится под капотом у принципов.
Я не буду давать классическое определение каждого из принципов, их легко найти, дам лишь свое пояснение и выделю суть.
Поехали 🚀🚀🚀
S - Single responsibility principle (SRP)
❗Суть принципа: написанный вами код (реализация) внутри каждой категории (про категории говорили тут) должен максимально соответствовать этой категории.
На примере связи Игрок - Инвентарь. Если в каком-то классе, относящемся к категории игрока, мы решили что-то сделать с ячейками инвентаря, поменять их местами (написать логику свопа в классе, который относится к категории игрока), такой подход будет нарушать SRP.
Более правильной реализацией будет работа с инвентарем в классах, относящихся к категории инвентаря.
O - Open-closed principle (OCP)
На практике этот принцип соблюсти достаточно тяжело.Так как в геймдеве часто меняются бизнес-требования.
❗Суть принципа: класс открыт для добавлений, но закрыт для изменений.
Моя рекомендация - пишите код так, чтобы его было легко менять и удобно расширять.
L - Liskov substitution principle (LSP)
❗Суть принципа: если у вас в коде есть класс A и класс B, который является наследником A, то при замене всех классов A на B в работе кода ничего не должно поменяться.
Моя рекомендация - не злоупотребляете наследованием. Иногда композиция или имплементация интерфейса сработает гораздо эффективнее.
I - Interface segregation principle (ISP)
❗Суть принципа: если и используете интерфейсы, не тащите в них то, что не нужно.
Пример подхода, нарушающего ISP: если какой-то интерфейс в реализации должен работать с игровым объектом, при этом описание игрового объекта есть в коллекции контента. Нарушением принципа будет передача в интерфейс самой коллекции контента и id того объекта, с которым хотим работать.
Чтобы обойти нарушение ISP, необходимо передавать сам интерфейс объекта, который мы предварительно получаем по id из коллекции контента.
Принцип бритвы Оккама тут может быть хорошей аналогией.
D - Dependency inversion principle (DIP)
❗Суть принципа: когда вы пишете какую-либо логику в классе и у вас есть зависимости, пишите логику не опираясь на конкретные реализации этих зависимостей. Работайте с зависимостями через абстракции.
Моя рекомендация - учитывать, что абстракции - это не только интерфейсы и абстрактные классы.
Продолжение следует…
Для чего нужен SOLID
Всем привет, сегодня говорим про SOLID (далее по тексту - классический SOLID).
Публикацию разобьем на 2 части: в первой упростим и выделим суть каждого принципа применительно к геймдеву, во второй рассмотрим проблемы.
SOLID - это набор из 5 принципов ООП, которые сформулировал Роберт Мартин. Аббревиатура была предложена Майклом Фэзерсом.
Определение звучит так: "SOLID - это руководства, которые также могут применяться во время работы над существующим программным обеспечением для его улучшения, например, для удаления «дурно пахнущего кода»".
Про SOLID спрашивают, его обсуждают с докладами на конференциях, его относят к правилам хорошего тона. Те, кто поопытнее пытаются применять SOLID на практике.
Но действительно ли разработчики понимают, как правильно применять SOLID принципы в геймдеве?
Практика показывает, что понимание принципов работает, как испорченный телефон.
Ведь каждый с высоты опыта и багажа по-своему интерпретирует, понимает и применяет на практике полученную информацию.
Часто в финале у большинства команд получается эдакий монстр-франкенштейн с кучей интерфейсов и их реализацией.
Код получается слабо связным и с сильной степенью зацепления.
Рассмотрим классический SOLID применительно к геймдеву.
Разберемся, что находится под капотом у принципов.
Я не буду давать классическое определение каждого из принципов, их легко найти, дам лишь свое пояснение и выделю суть.
Поехали 🚀🚀🚀
S - Single responsibility principle (SRP)
❗Суть принципа: написанный вами код (реализация) внутри каждой категории (про категории говорили тут) должен максимально соответствовать этой категории.
На примере связи Игрок - Инвентарь. Если в каком-то классе, относящемся к категории игрока, мы решили что-то сделать с ячейками инвентаря, поменять их местами (написать логику свопа в классе, который относится к категории игрока), такой подход будет нарушать SRP.
Более правильной реализацией будет работа с инвентарем в классах, относящихся к категории инвентаря.
O - Open-closed principle (OCP)
На практике этот принцип соблюсти достаточно тяжело.Так как в геймдеве часто меняются бизнес-требования.
❗Суть принципа: класс открыт для добавлений, но закрыт для изменений.
Моя рекомендация - пишите код так, чтобы его было легко менять и удобно расширять.
L - Liskov substitution principle (LSP)
❗Суть принципа: если у вас в коде есть класс A и класс B, который является наследником A, то при замене всех классов A на B в работе кода ничего не должно поменяться.
Моя рекомендация - не злоупотребляете наследованием. Иногда композиция или имплементация интерфейса сработает гораздо эффективнее.
I - Interface segregation principle (ISP)
❗Суть принципа: если и используете интерфейсы, не тащите в них то, что не нужно.
Пример подхода, нарушающего ISP: если какой-то интерфейс в реализации должен работать с игровым объектом, при этом описание игрового объекта есть в коллекции контента. Нарушением принципа будет передача в интерфейс самой коллекции контента и id того объекта, с которым хотим работать.
Чтобы обойти нарушение ISP, необходимо передавать сам интерфейс объекта, который мы предварительно получаем по id из коллекции контента.
Принцип бритвы Оккама тут может быть хорошей аналогией.
D - Dependency inversion principle (DIP)
❗Суть принципа: когда вы пишете какую-либо логику в классе и у вас есть зависимости, пишите логику не опираясь на конкретные реализации этих зависимостей. Работайте с зависимостями через абстракции.
Моя рекомендация - учитывать, что абстракции - это не только интерфейсы и абстрактные классы.
Продолжение следует…
Telegram
GameDev: разработка на Unity3D
Связность (cohesion) и зацепление (coupling).
Привет, сегодня поговорим про связность и зацепление в коде.
Полагаю, что каждый сталкивался со спагетти-кодом. Он плохо поддерживаемый и плохо структурированный.
Спагетти-код получается, когда…
Привет, сегодня поговорим про связность и зацепление в коде.
Полагаю, что каждый сталкивался со спагетти-кодом. Он плохо поддерживаемый и плохо структурированный.
Спагетти-код получается, когда…
#solid #solid_геймдев
Привет, друзья.
Вернемся к SOLID в разрезе геймдева.
Сегодня рассмотрим проблемы применения принципов в чистом виде и сформируем набор рекомендаций.
Итак приступим: какие из принципов и по каким причинам требуют особого внимания? Можно ли их использовать в том виде, как они были задуманы?
Вспомним, что SOLID - это:
- Прежде всего базис, на котором должны разрабатываться приложения, с поправкой на адаптацию под предметную область
- Создание хорошо сопровождаемых продуктов
- Повышение структурированности и читаемости кода
- Прозрачность бизнес-логики
- Простота и взаимозаменяемость отдельных частей продукта
- Снижение кривой сложности доработок в приложении.
В геймдев проектах можно относительно безболезненно реализовать SRP и LSP, сложности возникнут с OCP, ISP и DIP.
Рассмотрим проблемы, характерные для боевых проектов:
- SRP и LSP желателен постоянный код-ревью, при этом условии возможно безболезненное применение принципов
- OCP достаточно часто нарушается из-за переменчивости бизнес-требований, исходящих от гейм-дизайнеров, меняющих ГДД (гейм-дизайн документ). Это влечет за собой выпиливание части кода и будет сопряжено с трудностями, т.к. классы в коде уже плотно зацепились с классами из других категорий
- ISP и DIP часто интерпретируют неверно, связывая их с интерфейсами. Например: DIP - путают с Dependency Injection
- Дополнительную нагрузку при планировании и проектировании реализации DIP добавляют Dependency Injection фреймворки, наподобии Zenject, Ninject или собственные реализации. Обычно к собственной реализации приходят, если готовый фреймворк оказался сложен или избыточен.
В совокупности применение принципов без адаптации к геймдеву приводит к тому, что приложение обрастает интерфейсами и их реализациями. Задумайтесь, чем больше проект, тем неподъемнее конструкция. Каждая реализация обязана содержать public методы, что раздувает объем кодовой базы и снижает инкапсуляцию с механизмом сокрытия (тут я имею в виду private методы).
Опыт показал, что для геймдева нужен немного другой набор принципов.
✅ Сформулирую набор принципов и рекомендаций, которые я выделяю, исходя из своего опыта:
- В приложении должна быть единая точка входа в код
- Приложение должно быть разбито на слои абстракции
- Должна быть возможность пройти по всему дереву приложения из IDE
- Жизненный цикл всех объектов в приложении должен быть строго детерминирован
- Максимально, где это возможно, должна использоваться инкапсуляции с механизмом сокрытия. А именно: объекты слоя бизнес-логики должны иметь минимальное количество публичных методов, в идеале - не иметь вообще
- Использовать динамический полиморфизм. Причем, который не базируется на интерфейсах или абстрактных классах
- Минимизировать связи между объектами слоев абстракций (аналог ISP)
- Возможность легко менять и расширять код
- Использовать принцип подстановки Барбары Лисков (LSP)
- Код для работы с различными зависимостями должен быть написан декларативно (аналог DIP) и отвечать на вопрос: “что делать”. Подход обеспечит сильную связанность и слабое зацепление в сочетании с динамическим полиморфизмом.
- Простая сериализация/десериализация объектов.
Продолжение следует…
Привет, друзья.
Вернемся к SOLID в разрезе геймдева.
Сегодня рассмотрим проблемы применения принципов в чистом виде и сформируем набор рекомендаций.
Итак приступим: какие из принципов и по каким причинам требуют особого внимания? Можно ли их использовать в том виде, как они были задуманы?
Вспомним, что SOLID - это:
- Прежде всего базис, на котором должны разрабатываться приложения, с поправкой на адаптацию под предметную область
- Создание хорошо сопровождаемых продуктов
- Повышение структурированности и читаемости кода
- Прозрачность бизнес-логики
- Простота и взаимозаменяемость отдельных частей продукта
- Снижение кривой сложности доработок в приложении.
В геймдев проектах можно относительно безболезненно реализовать SRP и LSP, сложности возникнут с OCP, ISP и DIP.
Рассмотрим проблемы, характерные для боевых проектов:
- SRP и LSP желателен постоянный код-ревью, при этом условии возможно безболезненное применение принципов
- OCP достаточно часто нарушается из-за переменчивости бизнес-требований, исходящих от гейм-дизайнеров, меняющих ГДД (гейм-дизайн документ). Это влечет за собой выпиливание части кода и будет сопряжено с трудностями, т.к. классы в коде уже плотно зацепились с классами из других категорий
- ISP и DIP часто интерпретируют неверно, связывая их с интерфейсами. Например: DIP - путают с Dependency Injection
- Дополнительную нагрузку при планировании и проектировании реализации DIP добавляют Dependency Injection фреймворки, наподобии Zenject, Ninject или собственные реализации. Обычно к собственной реализации приходят, если готовый фреймворк оказался сложен или избыточен.
В совокупности применение принципов без адаптации к геймдеву приводит к тому, что приложение обрастает интерфейсами и их реализациями. Задумайтесь, чем больше проект, тем неподъемнее конструкция. Каждая реализация обязана содержать public методы, что раздувает объем кодовой базы и снижает инкапсуляцию с механизмом сокрытия (тут я имею в виду private методы).
Опыт показал, что для геймдева нужен немного другой набор принципов.
✅ Сформулирую набор принципов и рекомендаций, которые я выделяю, исходя из своего опыта:
- В приложении должна быть единая точка входа в код
- Приложение должно быть разбито на слои абстракции
- Должна быть возможность пройти по всему дереву приложения из IDE
- Жизненный цикл всех объектов в приложении должен быть строго детерминирован
- Максимально, где это возможно, должна использоваться инкапсуляции с механизмом сокрытия. А именно: объекты слоя бизнес-логики должны иметь минимальное количество публичных методов, в идеале - не иметь вообще
- Использовать динамический полиморфизм. Причем, который не базируется на интерфейсах или абстрактных классах
- Минимизировать связи между объектами слоев абстракций (аналог ISP)
- Возможность легко менять и расширять код
- Использовать принцип подстановки Барбары Лисков (LSP)
- Код для работы с различными зависимостями должен быть написан декларативно (аналог DIP) и отвечать на вопрос: “что делать”. Подход обеспечит сильную связанность и слабое зацепление в сочетании с динамическим полиморфизмом.
- Простая сериализация/десериализация объектов.
Продолжение следует…
Какими механизмами вы обеспечиваете полиморфизм в своих проектах?
Final Results
62%
Интерфейсы
70%
Виртуальные методы
22%
Другие конструкции языка
0%
Нет опыта
Доброе утро, друзья!
Подведем итоги опроса "Какими механизмами вы обеспечиваете полиморфизм?".
Первым делом хочу поблагодарить всех, кто принял участие и дал обратную связь 👍
Проголосовало чуть меньше 50% участников, это хороший результат.
Вижу, что вы знакомы с понятием полиморфизма 👍
Итак, на момент подведения итогов большинство из участников, принявших участие, выбрали виртуальные методы ~ 70% из 100%, далее следуют интерфейсы ~60% из 100% и другие конструкции языка лишь ~ 20% из 100%.
Что касается меня, для решения задач слоя бизнес-логики приложения я отдаю предпочтение "другим конструкциям языка". А именно реактивным объектам (из библиотеки UniRx).
Кроме этого к другим конструкциям языка относятся делегаты, шина сообщений и т.д.
Если речь идет про библиотеки, которые не завязаны на бизнес-логику приложения, то для обеспечения полиморфизма подойдут как виртуальные методы, так и интерфейсы.
Почему для решения задач слоя бизнес-логики я стараюсь избегать использования интерфейсов и виртуальных методов. Обеспечение полиморфизма такими способом, как правило, влечет за собой организацию связей в коде проекта через публичные методы. Наличие большого количества интерфейсов ведет к разрастанию кодовой базы, так как для каждого интерфейса нужна как минимум 1 реализация.
В итоге мы придем к коду, который мало устойчив к изменениям, в котором сложно ориентироваться.
При изменении состава команды у новых участников возникнут сложности с использованием публичного API приложения (которое уже было спроектировано).
Будет усиливаться зацепление кода.
Если есть желание поговорить подробнее про использование других конструкций языка, оставьте комментарий ⬇
Подведем итоги опроса "Какими механизмами вы обеспечиваете полиморфизм?".
Первым делом хочу поблагодарить всех, кто принял участие и дал обратную связь 👍
Проголосовало чуть меньше 50% участников, это хороший результат.
Вижу, что вы знакомы с понятием полиморфизма 👍
Итак, на момент подведения итогов большинство из участников, принявших участие, выбрали виртуальные методы ~ 70% из 100%, далее следуют интерфейсы ~60% из 100% и другие конструкции языка лишь ~ 20% из 100%.
Что касается меня, для решения задач слоя бизнес-логики приложения я отдаю предпочтение "другим конструкциям языка". А именно реактивным объектам (из библиотеки UniRx).
Кроме этого к другим конструкциям языка относятся делегаты, шина сообщений и т.д.
Если речь идет про библиотеки, которые не завязаны на бизнес-логику приложения, то для обеспечения полиморфизма подойдут как виртуальные методы, так и интерфейсы.
Почему для решения задач слоя бизнес-логики я стараюсь избегать использования интерфейсов и виртуальных методов. Обеспечение полиморфизма такими способом, как правило, влечет за собой организацию связей в коде проекта через публичные методы. Наличие большого количества интерфейсов ведет к разрастанию кодовой базы, так как для каждого интерфейса нужна как минимум 1 реализация.
В итоге мы придем к коду, который мало устойчив к изменениям, в котором сложно ориентироваться.
При изменении состава команды у новых участников возникнут сложности с использованием публичного API приложения (которое уже было спроектировано).
Будет усиливаться зацепление кода.
Если есть желание поговорить подробнее про использование других конструкций языка, оставьте комментарий ⬇
Привет, друзья 🙂
Ниже анонс тем для ближайших публикаций 👇
Все они вместе с затронутыми ранее темами являются важными составляющими разработки игр.
UPD: для удобства навигации заголовок рассмотренных тем дополнен ссылкой на публикацию
1 Деление игры на слои абстракции
Поговорим про:
- представление (view, отвечает на вопрос: "как")
- слой бизнес-логики (presentation model, отвечает на вопрос: "что делать")
- построение дерева приложения (иерархия или граф entity)
- контентный слой (набор контента, с которым стартует игра)
- слой сервисов (например, рекламный сервис, сервис аналитики) не влияющий на бизнес-логику игры
- слой состояний игровых объектов (state)
2 С чего должен начинаться Unity проект
Поговорим про нюансы на уровне Unity: количечтво точек входа, последовательность старта объектов
3 MonoBehaviour
Обсудим его роль в проекте
4 Организация префабов
Поговорим про правильную организацию и роль слоя view в ней
5 Жизненный цикл объектов
Обсудим, кто за него должен отвечать
6 Изолированность классов
Поговорим о том, как ее обеспечить
7 Dependency Injection
Обсудим, как применять. Затронем DI фреймворки. Разберем, как правильно внедрять зависимости
8 Абстракции
Как не использовать интерфейсы, при этом писать абстрактный код. Полиморфизм
9 Связи
Разберем, как выстроить связи между классами со слабым зацеплением в коде. Рассмотрим применение реактивных объектов из библиотеки UniRx
10 Контент
Как должен выглядеть контент, используемый игровыми объектами
11 Состояние объектов в игре
Поговорим про то, как и где хранить состояние объектов в игре, также состояние мира/игрока
12 Плагины
Обсудим, как использовать сторонние плагины, чтобы они вписывались в общую архитектуру проекта
13 Сериализация и десериализация
Как правильно сериализовать и десериализовать объекты внутри игры.
Ниже анонс тем для ближайших публикаций 👇
Все они вместе с затронутыми ранее темами являются важными составляющими разработки игр.
UPD: для удобства навигации заголовок рассмотренных тем дополнен ссылкой на публикацию
1 Деление игры на слои абстракции
Поговорим про:
- представление (view, отвечает на вопрос: "как")
- слой бизнес-логики (presentation model, отвечает на вопрос: "что делать")
- построение дерева приложения (иерархия или граф entity)
- контентный слой (набор контента, с которым стартует игра)
- слой сервисов (например, рекламный сервис, сервис аналитики) не влияющий на бизнес-логику игры
- слой состояний игровых объектов (state)
2 С чего должен начинаться Unity проект
Поговорим про нюансы на уровне Unity: количечтво точек входа, последовательность старта объектов
3 MonoBehaviour
Обсудим его роль в проекте
4 Организация префабов
Поговорим про правильную организацию и роль слоя view в ней
5 Жизненный цикл объектов
Обсудим, кто за него должен отвечать
6 Изолированность классов
Поговорим о том, как ее обеспечить
7 Dependency Injection
Обсудим, как применять. Затронем DI фреймворки. Разберем, как правильно внедрять зависимости
8 Абстракции
Как не использовать интерфейсы, при этом писать абстрактный код. Полиморфизм
9 Связи
Разберем, как выстроить связи между классами со слабым зацеплением в коде. Рассмотрим применение реактивных объектов из библиотеки UniRx
10 Контент
Как должен выглядеть контент, используемый игровыми объектами
11 Состояние объектов в игре
Поговорим про то, как и где хранить состояние объектов в игре, также состояние мира/игрока
12 Плагины
Обсудим, как использовать сторонние плагины, чтобы они вписывались в общую архитектуру проекта
13 Сериализация и десериализация
Как правильно сериализовать и десериализовать объекты внутри игры.