Описание архитектуры
Я создаю (проектирую) систему сущностей и столкнулся со многими проблемами. Я стараюсь максимально эффективно ориентировать их на данные и эффективность. Мои компоненты - это структуры POD (точнее, массив байтов), размещенные в однородных пулах. У каждого пула есть ComponentDescriptor - он просто содержит имя компонента, типы полей и имена полей.
Entity - это просто указатель на массив компонентов (где адрес действует как идентификатор объекта). EntityPrototype содержит имя сущности и массив имен компонентов. Наконец, подсистема (система или процессор), которая работает с пулами компонентов.
Актуальная проблема
Проблема заключается в том, что некоторые компоненты зависят от других (Model, Sprite, PhysicalBody, Animation зависит от компонента Transform), что создает много проблем при их обработке.
For example, lets define some entities using [S]prite, [P]hysicalBody and [H]ealth:
Tank: Transform, Sprite, PhysicalBody
BgTree: Transform, Sprite
House: Transform, Sprite, Health
and create 4 Tanks, 5 BgTrees and 2 Houses and my pools will look like:
TTTTTTTTTTT // Transform pool
SSSSSSSSSSS // Sprite pool
PPPP // PhysicalBody pool
HH // Health component
Нет способа обработать их, используя индексы. Я провожу 3 дня, работая над этим, и у меня все еще нет никаких идей. В предыдущих проектах TransformComponent был привязан к сущности, но это не было хорошей идеей. Можете ли вы дать мне несколько советов, как их обрабатывать? Или, может быть, я должен изменить общий дизайн? Возможно, мне следует создать пулы энтитов (пулы компонентных пулов) - но я думаю, что это будет кошмар для кешей процессоров.
Спасибо
Ответы:
Отказ от ответственности: Чисто уходя от моих знаний класса систем.
Я изначально думал, почему бы просто не использовать хеш-функцию для идентификатора объекта для вашего индекса?
Таким образом, вы получите
Или как бы то ни было, сущности оказались размещенными. Вы можете иметь пулы для всех компонентов и для сущностей и использовать пул сущностей в качестве «главного», так что коллизии проверяются по массиву сущностей. Но, конечно, вы сталкиваетесь с проблемой утилизации компонентов и объектов.
Если ваш игровой дизайн это позволяет, вы можете заранее планировать, куда идет каждый тип сущности, чтобы получить максимально эффективную упаковку. Скажем, сущности 0-20 зарезервированы для резервуаров, сущности 21-30 для домов и 31-60 для деревьев BG. Возможно, вы не сможете эффективно порождать бесконечные недобрые слова, и это своего рода побеждает динамизм компонентных систем, но это решит проблему. Я не вижу способа съесть твой торт и съесть его тоже.
Я думал о том, как, возможно, ускорить процесс рендеринга, когда у вас есть файл
RenderingComponent
, содержащий все данные, которые нужны системе рендеринга, чтобы она могла просто проходить через массив этих вещей, но тогда есть издержки на копирование данных. Кроме того, каждый раз, когда вы разыменовываете указатель, вы думаете о том, находится ли он в кэше или нет.Если вы хотите очень быструю игру, я бы сказал, распланируйте ваше распределение. Если вам нужна гибкая игровая архитектура, разверните хеш-таблицы и строковые идентификаторы. В любое время, когда вам нужна гибкость, вам нужно создать абстракцию, и, следовательно, это потребует дополнительных затрат.
TL; DR;
Основываясь на том, что вы описали, я бы создал более высокий уровень
RenderComponent
с указателямиSprite
иTransform
компонентами и дал бы ему необходимые ссылки при инициализации объекта.(Прошу прощения за любой предполагаемый бред, я тоже думал об этом в своей системе, так что это была возможность продумать это)
источник
void update(u32 n, PhysicalBodyComponents* bodys, Transform* transforms)
Я хочу работать со многими входами и разделить эту функцию на несколько ядер. Можно с хешмапами?bodys
иtransforms
массив выстроятся в линию. Это просто то, что вы не можете обойти без добавления слоя абстракции или планирования своего размещения. Я чувствую, что у меня нет опыта, чтобы говорить о масштабировании до нескольких ядер. Может быть, найти вопрос о потоке и масштабировании или написать свой.