Post image

Entity-component-system: Переламывая себя

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

Сейчас, разбираясь с Cocos2d-x я пришел к тому, что привычная модель Model Controller View для данного движка и для игр в общем, плохо подходи. MVC или наследование в лоб делаю из игрового приложения неповоротливого монстра, развивать которого сущие муки с хентаем и тентаклями. Даже классические паттерны описанные бандой четырех слабо помогают, а порой запутывают код в неописуемые спагетти.

Порывшись в этих ваших интернатах я наткнулся на один интересный ресурс который описывает, новую для меня, парадигму разработки игровых приложений: Entite Component System. Ash framework как раз об этом таинственном зверьке, к тому же написан на ActionScript, что облегчает понимание для такого Flash барана как я.

Суть ECS - убираем ООП к чертям и начинаем работать через данные. Чуть более детальное описание: У нас есть Сущности, которые содержат в себе Компоненты, которые в свою очередь обрабатываются Системами. Сущности не более чем коллекция компонентов, порой это просто ID для доступа к определенной коллекции, они ничего не умеют делать. Компоненты это данные которые создают сущность, к примеру компонент движения содержит позицию сущности и её ускорения, компонент визуализации содержит в себе то что будет рисоваться на экране, они так же ничего не умеют делать. В свою очередь Системы, независимо друг от друга, обрабатываю компоненты в основном цикле программы.

“На пальцах” выглядит это так: Есть сущность Bot у которого есть два компонента Position и Render. struct Position {// Компонент содержит данные о позиции сущности int x; int y;
};

struct Render {// Компонент содержит данные о визуализации сущности Sprite sprite;//То что надо нарисовать на экране };

Есть система для визуализации, метод update у которой обновляется в основном цикле программы:

class RenderSystem { /** Метод который вызывается каждый фрейм **/ void update(vector<Entity> entities) { for(int i = 0; i < entities.size(); ++i) { Entity entity = entities[i];//Обрабатываем каждую Сущность entity.sprite.x = entity.position.x;//Перемещаем спрайт сущности по х entity.sprite.y = entity.position.y;//Перемещаем спрайт сущности по у } } }

В сущность Bot можно добавить безграничное количество компонентов расширив его без наследования. Захотелось чтобы бот стрелял, добавили Компонент Gun, захотелось чтобы бот летал добавил Компонент Fly, захотелось чтобы борщ готовил, добавил компонент Borzch и т.д. Конечно под каждый компонент надо будет добавить свою систему. И забыть о такой полезном понятии из ООП как инкапсуляция.

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

Более подробно и понятно о Entite Component System можно узнать почитав статьи разработчика Ash framework, и перечитав очень интересные материалы из официально вики. Статья от Wargaming о Создание World of Tanks Blitz. Еще одна статья от популяризатора ECS и разработчика Dungeon Siege Скота Билас. Так же узнать много об оптимизации памяти для игровых приложений.

Пока я занимаюсь переламывание себя под новое мышление и уход от традиционного подхода. Как не печально но данный процесс для меня оказался довольно сложным, еще не во всем разобрался и общая картинка размыта. К тому же приходится все время бить себя по рукам, не бросаться переписывать свой проект loonyquack.com. Что-то подобное со мной уже происходило, давным давно, когда только познакомился с паттернами проектирования: по старому писать уже не хочется, а по новому еще не могу.

Если кто нибудь из читателей уже применял Entite Component System в своих проектах буду очень рад прочитать его мнения и советы в комментария.