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

26

Я работаю над игрой с компонентной архитектурой. Объект Entityвладеет набором Componentэкземпляров, каждый из которых имеет набор Slotэкземпляров, с помощью которых можно хранить, отправлять и получать значения. Заводские функции, такие как Playerсоздание объектов с необходимыми компонентами и соединениями слотов.

Я пытаюсь определить лучший уровень детализации для компонентов. Например, прямо сейчас Position, Velocityи Accelerationвсе это отдельные компоненты, соединенные последовательно. Velocityи Accelerationможет быть легко переписан в единый Deltaкомпонент, или Position, Velocityи Accelerationможет быть объединен вместе с такими компонентами, как Frictionи Gravityв монолитный Physicsкомпонент.

Должен ли компонент иметь наименьшую возможную ответственность (за счет большого количества соединений) или же связанные компоненты должны быть объединены в монолитные (за счет гибкости)? Я склоняюсь к первому, но я мог бы использовать второе мнение.

Джон Перди
источник
Аналогичный вопрос: gamedev.stackexchange.com/questions/4914/…
Ден
Собираетесь ли вы использовать свой физический движок или интегрировать существующий?
День
@Den: я пишу некоторый физический код , но это ни в коем случае не движок . Просто мирская 2D кинематика.
Джон Пурди,

Ответы:

14

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

Очевидно, что вещи могут иметь Position, но они не обязательно являются динамическими (так зачем иметь Velocityи Acceleration?). Однако что-то с a Velocityбудет движущимся объектом, поэтому имеет смысл также Accelerationсгруппироваться.

У вас будет случай, когда понадобятся v и a , но вы не хотите имитацию физики для них? Точно так же, будет ли смысл, Gravityесли они не являются физическими объектами?

TL; Dr Group, что имеет смысл.

Коммунистическая утка
источник
1
Звучит справедливо. Моя система имеет очень мало централизацию: если Entityимеет Positionи некоторые компоненты , которые делают , что Positionучаствуют в физике, то Entityесть де - факто физически. Я думаю, что я могу сделать, просто добавить некоторые компоненты для логической группировки и сохранить все основные компоненты под одной ответственностью. Поэтому добавление, скажем, Movableк Entityбудет иметь тот же эффект , как и добавление Position, Velocityи Acceleration.
Джон Пурди
6

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

Так что для поспешного примера у вас есть игра. Игра разбивается на Environment + State. Среда разделяется на StaticWorld + MovingStuff. Состояние распадается на AIControlled + PlayerControlled. Общая идея Повреждения распадается на TakesDamage + GivesDamage.

И так далее.

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

Патрик Хьюз
источник
Я не новый разработчик. Если у меня есть компоненты, основанные на концепциях, а не на поведении (то есть, сверху вниз и снизу вверх), не будет ли моя архитектура более хрупкой и более сложной? Я могу реализовать любое поведение, которое я захочу, из небольших компонентов, но я не всегда могу получить желаемое поведение из предкомбинированных. Не говоря уже о том, что я не могу предсказать все, чего я хочу достичь, даже в контексте одной игры.
Джон Пурди,
Недостаток снизу вверх заключается в том, что связь между компонентами становится проблемой, и люди, как правило, начинают слишком микро в масштабе того, что они моделируют. Я в основном пытался держаться подальше от супер-микро «xyz is component» «вращение является компонентом» «rgb is component» уровень для кого-то неопытного.
Патрик Хьюз
Справедливо. Я просто хотел убедиться, что правильно тебя понял. С имеющейся у меня системой слотов взаимодействие компонентов простое и эффективное, поэтому я не вижу никаких недостатков в масштабе «супер-микро». Я не собираюсь превращать это в автономный движок, но если я это сделаю, я всегда могу представить абстракции, такие как группы компонентов, которые я упоминаю в своем комментарии к ответу Коммунистической утки.
Джон Перди
4

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

Но это во многом зависит от особенностей вашей игры (если вы не строите фреймворк без особой игры).

XGouchet
источник
2
Проблема с объединением компонентов с большим количеством взаимодействия состоит в том, что иногда другая часть не нужна.
Коммунистическая утка
4

Я понимаю, что это старый вопрос, но, возможно, кто-то найдет этот ответ полезным.

Я считаю, что Systemsэто поможет вам лучше понять, как создавать компоненты. Системы существуют в архитектурах, где компоненты не содержат своей собственной логики, кроме простых методов получения / установки и вспомогательных функций. Системы работают на Объектах, которые удовлетворяют требованиям Компонента. Вот почему лучше отделить данные компонента настолько, насколько это целесообразно, чтобы эти данные обрабатывались без других данных.

Например, у вас может быть объект, MovementSystemкоторый обновляет свои сущности на Positionоснове их Velocity. Это может быть для простых объектов в игре. Но для Игрока и Врагов вам может понадобиться движение, Accelerationкоторое обрабатывается в AcceleratedMovementSystem. Но для препятствий вы могли бы хотеть Friction. Местность также может иметь трение, но это не будет иметь составляющую скорости. Но как насчет Gravity? Просто добавьте его Player, Enemy и Obstacle, и создайте его GravitySystemдля обработки.

Суть заключается в том, что чем больше развязаны ваш Components, тем более расширяемыйEntities будет при использовании Systems.

Изменить: сделать последнее заявление яснее.

Изменить: Хорошо, я работал над своей собственной системой и пришел к этой реализации. Примером разделения Положения и Скорости является то, что манипулирование Скоростью вызывает изменение Положения с помощью MovementSystem. В результате для InputMovementSystem не требуется Position, чтобы заставить игрока перейти от пользовательского ввода, потому что MovementSystem подберет изменения в Velocity для применения к Position. Конечно, было бы неплохо собрать их вместе, но это пример того, почему этого не должно быть.


Недавно я прочитал сообщение в блоге, в котором говорится что-то вроде этого

«Если у вас есть данные, которые можно сгруппировать с двумя различными компонентами, лучше всего создать третий компонент с этими данными».

Дэн Х.
источник