Search
Write a publication
Pull to refresh
31
0
Farley Drunk @SH42913

Разработчик C#/Unity3D

Send message

Способы организации есть, вот в этих двух статьях расписаны :)
https://habr.com/ru/articles/665276/
https://habr.com/ru/articles/742376/

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

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

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

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

О, это прям классика, да

изначально эта архитектура была ассоциирована с решением проблем производительности

Ассоциировать её с решением проблем производительности начали только после того как Unity занялись популяризацией DOTS(скорее всего подсмотрев у фростбайта). До этого все просто пользовались гибкостью.
Я работал в одной конторе, где свой самописный ECS под Unity появился задолго до Entitas(то есть вообще до ECS-хайпа) и там это было обусловленно именно гибкостью разработки и оно было реально гибко. Собсно я с тех пор и полюбил ECS всем сердцем. Жаль проект не взлетел из-за в том числе проблем с производительностью фреймворка, ибо он был полностью на рефлексии и достаточно кривоват(но крут в плане возможностей).

Все это вместе дает свою философию доступа к объектам, которая отличается от просто доступа по ссылке.

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

Если бы речь шла только про декомпозицию и отделение данных от логики, вы бы могли (и можете) организовать это на обычных компонентах unity + системах, в этом смысле она и так entity-component.

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

ультрадекомпозиция

Ультрадекомпозиция это лишь один из взглядов на ECS, совсем не обязательно делить всё до атомарного уровня(а скорее даже не стоит)

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

На моём опыте на дальней перспективе как раз классическая ООП иерархия или КОП доставляют больше жжения в жопе, чем ECS, в плане сложности добавления новых фич

Но это всего лишь инструмент, необходимо использовать его правильно.

Всё так, ECS не серебрянная пуля, а инструмент со своими плюсами(и производительность далеко не главный из них) и недостатками.

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

Для этого в контексте Unity есть Jobs + Burst, ECS тут совсем не нужен.

Жгите.

Жгу :)

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

Я бы как раз порекомендовал наоборот: вся игровая логика на ECS с вкраплениями ООП в нужных местах(деревья, сеть, сохранения и тп).

Практически все ее преимущества могут быть использованы отдельно от нее.

По отдельности преимуществ ECS можно достичь, писать код для идеальной тестируемости/модульности, заморачиваться про SRP, но зачем лезть из кожи с ООП если можно просто разделить данные и логику?

Кстати, DOTS не требует ECS, его инструменты типа jobs можно использовать отдельно.

Так и есть, поэтому и не стоит смешивая конкретную реализацию Entities из пакета DOTS с ECS архитектурой как таковой.

Я кончил

Многие пропагандируют ECS как решение по умолчанию, потому что “просто используйте ее и получите хорошую производительность за бесплатно”.

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

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

Это не для оптимальности нужно, а для разделения ответственности. Одна система занимается тем, что спаунит объекты. Другая система занимается тем, что двигает объекты. А третья тем, что обрабатывает попадания(наносить урон будет скорее всего четвертая система). Классическая S из SOLID.

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

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

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

Потому что в ECS нужно думать не объектами, а поведениями и тогда всё станет проще

Во-вторых - у вас нет базовых примитивов. Хотите делегат? Их нет, используйте компонент. Полиморфизм? Нет, это enum и несколько систем. Фильтр по циклу? Вам нужен компонент + система. Нужно дерево? Деревьев нет, используйте компоненты со ссылками на сущности.
[...]
У вас нет половины современных инструментов программирования, только императивное программирование и базовые структуры. Либо, вы можете использовать все, что захотите - тогда у вас будет мутант, который не имеет преимуществ ECS.

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

В ООП у вас есть приватные переменные и интерфейсы для сокрытия деталей

Тебе не нужно скрывать детали, когда у тебя каждая логика и так обособлена в своей системе

понятные паттерны организации кода

Ну так ECS сам по себе и есть паттерн организации кода :D
Я понимаю что хотел сказать автор, поэтому у меня есть контр-аргумент - для ECS уже тоже придуманы "понятные паттерны организации кода", как например в этой статье.

Конечно, классический код тоже можно сделать запутанным и с плохой декомпозицией, но для ECS его очень легко сделать таким

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

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

Частично согласен, об этом сказал выше. С другой стороны весов больших проектов у нас жёсткая ригидность ООП иерархии, когда вносить изменения в неё становится очень больно(или практически невозможно), в то время как в ECS ты просто добавляешь новый компонент и новую систему(можно к ней Unit-тест написать сразу) зачастую не трогая старый код.

Шутеры? - Симуляция сотни игроков и тысяч пуль для ECS это даже не разминка, с этим легко справится обычный код, вы можете даже не получить преимущества.

А если завтра прилетит геймдиз, который захочет чтобы "камера убивала"? В ООП иерархии это может оказаться неподдерживаемым и придётся много костылить, а в ECS накинул компонент, добавил нужную систему(если вообще нужно) и всё готово.

И мы даже не говорим про пиксельные инди рогалики и 3-в-ряд.

Знаю разработчиков, которые очень довольны тем, что выбрали ECS для разработки 3-в-ряд как раз по причине гибкости :)

Важно отметить, что обычное ООП тоже не прямо уж медленное.

Так никто этого и не утверждает вроде бы. Я даже больше скажу: невозможно сделать игру на ECS совсем без использования ООП(ну ладно-ладно, можно, но это такой гемор, особенно на Unity), поэтому нормальной практикой считается комбинирования ECS с ООП там, где оно нужно.

В то же время, ECS по сути сама занимается управлением памятью, и не факт, что во всех сценариях она делает это эффективнее.

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

Резюмируя: в вашей игре, вероятно, тормозит не игровая логика, соответственно и оптимизировать нужно не ее.

С этим утверждением я солидарен

Нушож, время обеда, можно и прочитать...

Сейчас будет куча цитат и моих контр-аргументов.
TLDR: автор путает DOD и ECS, смешивает ECS как архитектурный паттерн и реализацию ECS фреймворков, ну и вцелом не совсем понимает что представляет собой ECS архитектура.

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

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

производительность доступа к памяти

Этим занимается DOD, а не ECS

Теперь за выделением памяти следит ECS, она располагает все компоненты в чанки - массивы с заранее выделенной памятью и одним типов компонентов.

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

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

Нету в ECS этого из коробки. В паре ECS фреймворков это есть, но лишь в паре.

но создаст большие сложности с обслуживанием кода

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

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

Вот это правильный довод. Залог хорошей оптимизации - это профилирование и устранение узких мест. ECS тут совсем непричём, игровая логика занимает относительно небольшую часть CPU загрузки и если она тормозит, то скорее всего тормозит конкретный алгоритм.

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

является специализированной высокопроизводительной архитектурой

Да нет же, не является ECS "специализированной высокопроизводительной архитектурой". "Специализированным высокопроизводительным" может быть фреймворк, например, таким можно считать DOTS от Unity, который крутится вокруг ECS, но сам подход нельзя называть так, ибо разделение данных и логики само по себе НИКАК не говорит про производительность. И в этом моя главная претензия ко всем нелюбителям(и половине любителей) ECS и именно это сподвигло меня написать статью, на которую вы ссылаетесь в самом начале. ECS это в первую очередь удобство разработки благодаря отделению данных от логики, производительность вторична и оооочень сильно зависит от фреймворка. В то же время какой-нибудь DOD(Data-Oriented-Design, реализация ECS вполне может соответствовать DOD) уже - да, разговаривает про производительность.

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

Helldivers не даст соврать

Чот флешбеки с "CYBERSTAN CAN'T KEEP HER DOWN" вернулись...

Вышла очень хорошая статья про полезные практики в ECS, крайне рекомендую к ознакомлению - https://habr.com/ru/articles/742376/

Отличная статья! Огромное спасибо!

Задумка прикольная :)

Ещё можно Soulseek попробовать: древняя p2p сеть по обмену музыкой, где чего только нету

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

Скорее всего именно в этом все дело

Статью можно дополнить только через привлечение модераторов, поэтому просто отпишу здесь:

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

Я именно так и пришёл в IT, правда, к моему сожалению, не всегда делаю игры

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

Information

Rating
10,168-th
Location
Пермь, Пермский край, Россия
Registered
Activity

Specialization

Game Developer
Middle