Как стать автором
Обновить

Комментарии 12

На самом деле, разработка на этой архитектуре быстрее, потому что сотруднику требуется прилагать меньше умственных усилий и писать меньше кода
Весьма спорное утверждение, учитывая то количество лапши, которое на данный момент приходится писать.
Сама по себе архитектура никак не влияет на количество лапши, которую нужно писать. А вот конкретный фреймворк — уже влияет.
Svetlo ECS — ИМХО, рекордсмен по количеству лапши
Unity ECS — требует уже немного меньше необходимой лапши(хотя это еще хз)
Entitas — еще меньше лапши, но в обмен на кодогенерацию
Однако есть и всякие опенсорсные альтернативы, которые стараются делать максимально простой и понятный API — LeoECS и Morpeh. Вот в них количество кода будет на несколько строк больше, чем в аналогичном коде на монобехах, зато взамен они дают лучшую модульность, тестируемость и расширяемость, по сравнению с любыми вариантами на монобехах.

Пытался написать игру с использованием ECS, не осилил. Сейчас увидел статью, обрадовался, это же "Основные принципы использования ECS в разработке игр". Сейчас мне распишут что это вообще и как!


А тут одна вода. wtf

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


Дэээ, статейка ни о чем, а вот доклады хороши.
Мда.
Я как то тоже думал больше узнать про принципы и прикладные свойства, а тут странная реклама.
У нас есть опыт написания M3 игры на Entitas и они довольно специфические. Но это точно не похоже на спасение мира.
Конечно, адепты пишут, что нужно немножко сломать мышление, а потом будет красиво, легко и приятно. И в вашем проекте теперь даже есть архитектура, ха-ха.
Но:
— Теперь ваши сущности расползаются по наборам параметров и операций между ними. Чтобы собрать точное поведение сущности (например, юнита) нужно доставать куски из кучи систем и выстраивать их логику по кусочкам.
— Связи между сущностями выстраиваются специфически, данные-сигналы и данные-флажки — не самое удобное решение для многих очевидных вещей, многие паттерны очевидно не столь удобны, какк классические ООП и функциональные решения.
— Вранье, что человек думает батчами объектов (та самая аналогия, что хлеб мол не режут по кусочкам, а сразу весь батон шинкуют). Так конечно можно думать и в некоторых случаях это удобно, но любая декомпозиция сложного поведения как раз заключается в том, что ты думаешь об операциях с точки зрения одного простого и понятного объекта/агента, и думаешь всю цепочку. А не размышляешь о парралельном шаге для трех тысяч человек (хотя они конечно происходят одновременно.
— Сам по себе подход не избавляет от продумывания сущностей и дисциплины. Тебе все равно нужны понятные сущности, понятные правила, понятные способы взаимодействия. Особенно если пилит команда — нужно все равно продумывать архитектуру взаимодействия сущностей. Иначе ты ровно одинаковым способом выстрелишь себе в ногу с любой парадигмой — функциональной, компонентной, ооп или ECS. Только в отличие от старых подходов для этого еще нет устоявшихся паттернов и инструментов. Есть удобные кнопки IDE «показать вызовы функций» и «показать диаграмму связей», но нет инструмента «показать последовательность обработки данного компонента всем списком систем». А было бы крайне полезно.
— Большой плюс, он же и минус — отсутствие элементов защиты, все данные доступны, нет вариантов разбить по доменам или группам нормально (типа private перемнных). С одной стороны удобно — можно легко укусить локоть, с другой стороны, нужно потом разбираться в механиках кусания локтей.
— Гиганский плюс — явный стейт, все ключевые элементы игры выделены, можно легко сериализовать, передавать и принимать стейт, ничего не поплывет и не поломается из-за ошибки в цепочке делегатов ну и т.д.

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

При всех описываемых преимуществах, на мой взгляд, ECS остается отличным инструментом для решения далеко не всех задач игровой разработки, и разработчику стоит иметь в виду максимальное количество возможных вариантов, когда он принимает решение о выборе конкретного инструмента для решения конкретной задачи.
Я честно говоря не знаю что курил аффтар, но явно не историю.
OOP в играх не использовался с 70ых. За начало OOP в геймдеве можно считать примерно эпоху начиная с Pentium II/Windows 3.1/Windows 95. Или около того.

До этого код писался топорно в Basic/C/Pascal/даже на прямую на ASM разных пород и там уже играть в классиков тупо не позволял не сам дизайн языка, ни ограничения ресурсов.

ECS де факто является возвращению обратно к истокам с позиции логики имплементирования этой всей фаллоиммитации реальности посредством както-типо (sorta-kinda) жёсткого разделения. Да теперь оно гордо заносится под топорное разделение и может быть автоматизированно распределено средствами ECS. Только думанья головой это всё равно никто не отменял.
Вот например — ругают OOP

и не слова о ECS. Зато полно слов о оптимизации как дизайна кода так и исполнения.

Мама, я в телевизоре (с):))

Если открыть почти любой движок, что юзает ECS, то можно увидеть, что почти все они — нарушают идею ECS.
Логику пишут прям в сущности, в виде функционала. Обрабатывают те или иные компоненты прям сущностях и иногда в самих компонентах. Сами сущности в движках — это god-objectы почти везде.

В одной бородатой статье писали с кодом, примером и Сишной реализацией ECS, со всеми бенчмарками и прочим.

Entity — сущность. Абстракция, которая просто есть. Она может хранить/агрегировать в себя компоненты, может иметь какие то марки и т.д. В ней НЕТ логики и быть не должно.

Component — это по сути данные. Максимум что должен иметь компонент — это функционал с работой тех самых данных, т.е. их получение и изменение (да и то, изменять содержимое компонента напрямую через методы — зло. Для этого пишется ивент-система) И возможно, компонент иметь ссылку на сущность, к которой он приписан и систему.

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

Это идеальный конь в вакууме концепт ECS.
Но в угоду практичности, многие крупные студии, даже тот же UE4 и Unity не соблюдают эту идею и зачастую, обрабатывают сущность и компоненты напрямую, чуть ли не рекурсивным перебором всех сущностей.
UE4 так вообще, это гибрид ECS, GraphTree и Actor System.
Одну из лучших ECS которую я видел, это была ECS какой то либы, для движка MonoGame. Вроде бы называлось MonoGame Extends.

Но например движок Godot — не имеет систему ECS. Там чистой воды GraphTree (дерево узлов), на подобии того, что есть в cocos2d-x, но лучше. Каждый узел — есть сущность, а каждый узел может быть сценой, под сценой и т.д, а так же ссылать или взаимодействовать с выше стоящими или ниже стоящими узлами в дереве. Очень гибкая система. И такая архитектура крайне удобна, но имеет сильную просадку в производительности, ибо каждый кадр идет по сути перебор всего дерева. Физика перебирает ВСЕ дерево и вызывает функцию _physics_process(). Отрисовка перебирает все дерево, в том числе те узлы, что не имеют рендера в себе. И т.д. Там конечно есть всякие батчинги, хитрые подсистемы для оптимизации, в которых эти узлы сами себя регистрируют и обрабатываются отдельно, но это не панацея. Ярко эта проблема всплывает в 3Д играх, с огромным количеством мелких обьектов, которые постоянно встраиваются и уничтожаются в дереве. Т.е. распоточить без танцев с бубном обработку логики — не возможно.
Но 2Д игры делать просто чудестно, удобнее чем в юнити и уже тем более чем cocos2d-x, особенно, если ты можешь заанимировать любое свойство узла (любую переменную, любого узла, любой метод, это киллер-фича их).

А юнити и cocos2d-x — это вообще самые яркие представите антипатерна god-object. У кокоса гибрид графа и ecs, но ecs реализована очень убого там. Каждый узел есть сущность, узел может иметь дочерние и родительские узлы. Но у каждого узла могут быть компоненты. И все это работает исключительно в одном потоке. Сами компоненты не имеют внятного API для обработки системы, они просто обрабатываются в лоб, когда вызывается update у узла, потом update у всех его компонентов, потом update у следующих узлов в дереве. Про баги движка и кривую работу того FastTileMap я даже говорить не хочу 5 лет они делали чанковый батчинг тайловых карт и адекватно не могли срастить рендер с камерой, приходилось вьюпорт двигать, а не камеру.
Дорогой товарищ, вы наступили на достаточно частое заблуждение. Вы путаете два совершенно разных(хоть и близких) архитектурных подхода: Entity-Component-System(ECS, о котором эта статья) и Entity-Component(EC). Они хоть концептуально и близки, но совершенно разные на практике.
Почти все перечисленные вами варианты, в особенности Unity и UE4, по умолчанию предлагают именно EC-подход. Там есть условный GameObject/Actor(сущность) и есть его свойства(компоненты). Сама по себе сущность — абстракция, которая просто есть, а компоненты одновременно содержат и данные, и логику, которая обрабатывает эти самые данные. Собсно это допущение и порождает в итоге god-objects, тк так проще писать и проще думать. Когда у компонента напрямую вызывается Update() — это явный признак того, что перед нами именно EC.
Ключевая же особенность ECS — строгое отделение данных от их процессинга + линейный(конвейерный) способ обработки данных. Все иные ситуации, где перечисленных свойств не наблюдается, уже не являются ECS. Update(), в случае ECS, вызывается ИСКЛЮЧИТЕЛЬНО у систем, а внутри систем уже и происходит вся логическая магия. Системы, в свою очередь, не являются какими-либо хранителями состояния и, в идеале, не должны хранить каких-либо данных(но это допускается).
Unity в рамках DOTS предлагает разработчикам перейти с EC-подхода на чистый ECS, но и без DOTS для Unity(и C# в частности) уже предостаточно ECS-фреймворков, с которыми очень комфортно работать. Для C++ ECS-фреймворков тоже предостаточно, стоит только пройтись по гитхабу. Однако плюсовые фреймворки стоят немного в стороне от UE4, но уже появляются люди и проекты, которые хотят это исправить.
Движков, которые написаны изначально под использование ECS-подхода, можно пересчитать по пальцам, доступных общественности — на пальцах одной руки. Но они, к сожалению, пока только развиваются и еще далеки от идеала.
Надеюсь мне удалось развеять ваше заблуждение и вы таки попробуете ECS-подход на своих проектах. В него сложно влиться по началу, но стоит только вкусить этот божественный плод — больше не слезешь :)
Ну я в этом плане подтянул матчасть.
Но все же тот же UE4 юзает акторных, асинхронный подход. Т.е. в правильной релизации, там все строится на ивентах и асинхронных вызовах. В tick почти никогда не пишут нормальные люди.

Unity содержет в себе полноценную ECS. Ибо Тот же Render, физика и т.п. компонеты обрабатывается в отдельной системе. А там по факту гибрит ECS + SceneGraph. Скрипт — это вообще отдельный компонент-сценарий. Сценарий — тоже компонет. Сделать полноценную ECS в юнити не сложно. В лоб, просто логику обрабатывать где то в отдельном Entity. Это и распоточить можно или сразу батчингом обрабатывать сразу логику всех компонентов за один вызов.

Всякие LeoECS и его производные — это как по мне, откровенный костыль, так сказать ECS внутри ECS.

Возьми любой крупный проект на Unity. Они в итоге в начале пишут в Update все свое дерьмо, а потом переписывают всю логику в подсистеме, а потом на нее фигачат Burst аддон и т.д. Ибо рекурсивный обход всего SceneGraph уж дороговато выходит для 100500 обьектов)

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

Если брать NodeGraph паттерн. То тут наверное нынешний фаворит у меня, это Godot Engine. Там нету компонентов. Там все есть узел. Узел есть сцена, сцена есть узел. Узел есть сущность, узел есть компонент. Узлы общаются по принципу сигналы-слоты как в Qt.

Но если взять Cocos2d-x, то там недо копоненты, недо SceneGraph, не до узловая система)
Вообще это ужастный движок, лучше уже на Acid писать с нуля)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий