Який належний рівень деталізації для архітектури на основі компонентів?


26

Я працюю над грою з компонентною архітектурою. У Entityвласності набір Componentпримірників, кожен з яких має набір Slotпримірників, з якими зберігати, надсилати та отримувати значення. Заводські функції, такі як Playerвиробляти об'єкти з необхідними компонентами та з'єднаннями слотів.

Я намагаюся визначити найкращий рівень деталізації деталей. Наприклад, зараз Position, Velocityі Accelerationвсі окремі компоненти з'єднані послідовно. Velocityі їх Accelerationможна легко переписати на рівномірний Deltaкомпонент, або Position, Velocityі їх Accelerationможна поєднувати поряд з такими компонентами, як Frictionі Gravityв монолітний Physicsкомпонент.

Якщо компонент повинен мати найменшу відповідальність (ціною безлічі взаємозв’язків) чи повинні поєднуватися пов'язані компоненти в монолітні (ціною гнучкості)? Я схиляюся до колишнього, але міг би використати другу думку.


Схожий питання: gamedev.stackexchange.com/questions/4914 / ...
Den

Чи збираєтесь ви використовувати власний двигун фізики чи інтегрувати існуючий?
День

@Den: Я пишу код фізики , але це не двигун жодним чином. Просто щоденна 2D кінематика.
Джон Перді

Відповіді:


14

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

Очевидно, що речі можуть бути такими Position, але вони не обов'язково динамічні (так навіщо так Velocityі Acceleration?). Однак щось із a Velocityбуде рухомим об’єктом, тому має сенс також Accelerationзгрупуватися.

У вас буде випадок, коли v і a будуть потрібні, але ви не хочете, щоб фізичне моделювання для них? Аналогічно, чи буде сенс, Gravityякщо вони не є об'єктами фізики?

tl; dr. Група, що має сенс.


1
Звучить справедливо. У моїй системі дуже мало централізації: якщо в А Entityє Positionдеякі компоненти, які Positionберуть участь у фізиці, то Entityце фактично є фізичним. Я думаю, що я можу зробити - це лише додати деякі компоненти для логічного групування, а всі основні компоненти - єдину відповідальність. Тому додавання, скажімо, Movableдо Entityматиме той же ефект , як і додавання Position, Velocityі Acceleration.
Джон Перді

6

Щоб уникнути мікроменеджменту кожної змінної, я б запропонував, починаючи важко, вибирайте розділення на відповідальність та рефактор, коли ситуація представляється логічно. Перші конструкції можна починати на папері. В якийсь момент ці грубі розподіли відповідальності стануть складовими елементами ваших організацій.

Отже, для прискореного прикладу у вас є Game. Гра розбивається на навколишнє середовище + стан. Навколишнє середовище розбивається на StaticWorld + MovingStuff. Держава розбивається на AIContROL + PlayerContROL. Загальна ідея пошкодження розбивається на TakesDamage + GivesDamage.

І так далі.

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


Я не новий розробник. Якщо у мене є компоненти, що базуються на концепціях, а не на поведінці (тобто «зверху вниз» та «знизу вгору»), чи не буде моя архітектура більш крихкою та досконалішою? Я можу реалізувати будь-яку поведінку, яку хочу з невеликих компонентів, але я не завжди можу отримати бажану поведінку від попередньо поєднаних. Не кажучи вже про те, що я не можу передбачити все, чого я хочу досягти, навіть у контексті однієї гри.
Джон Перді

Недолік «знизу вгору» полягає в тому, що комунікація між компонентами стає проблемою, і люди, як правило, починають занадто мікромірно в масштабах того, що вони моделюють. Я в основному намагався відійти від супер-мікро "xyz - це компонент", "ротація - це компонент", "rgb - компонент" рівня для когось недосвідченого.
Патрік Хьюз

Досить справедливо. Я просто хотів переконатися, що я тебе правильно зрозумів. Зі слотною системою, що у мене є, комунікація компонентів є простою та ефективною, тому я дійсно не бачу недоліків до шкали "супер-мікро". Я не маю наміру переробляти це на самостійний двигун, але якщо це зробити, я завжди можу ввести такі абстракції, як групи компонентів, про які я згадую у своєму коментарі до відповіді комуністичної качки.
Джон Перді

4

Думаю, було б поєднувати компоненти, які матимуть багато взаємодії. У вашому випадку я б утримував позицію в одному компоненті, а швидкість і прискорення зберігалися разом у складі фізики.

Але це дуже залежить від того, які є ваші особливості гри (якщо ви не будуєте рамки, не маючи на увазі конкретної гри).


2
Проблема поєднання компонентів з великою кількістю взаємодії полягає в тому, що іноді інша частина не потрібна.
Качка комуніста

4

Я усвідомлюю, що це старе питання, але, можливо, хтось знайде цю відповідь корисною.

Я вважаю, що Systemsце допоможе вам краще зрозуміти, як конструювати компоненти. Системи існують в архітектурах, де компоненти не містять власної логіки, окрім простих функцій getter / setters та helper. Системи працюють на об'єктах, які відповідають вимогам Компонента. Ось чому найкраще відокремлювати компоненти компонентів настільки, наскільки має сенс обробляти ці дані без інших даних.

Наприклад, у вас може з’явитися MovementSystemоновлення, яке оновлює його Суб’єкти Positionна основі їх Velocity. Це може бути для простих осіб у грі. Але для гравця та ворогів ви можете захотіти рух, Accelerationякий обробляється AcceleratedMovementSystem. Але для Перешкод ви можете захотіти Friction. Terrain також може мати тертя, але це не буде мати складову швидкості. А як же Gravity? Просто додайте до нього програвач Player, Enemy та перешкода та створіть його GravitySystemдля обробки.

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

Редагувати: остання заява стала яснішою.

Редагувати: Гаразд, я працював над власною Системою і прийшов до цього. Прикладом поділу позиції та швидкості є те, що маніпулювання швидкістю призводить до зміни позиції за допомогою MovementSystem. Як результат, "InputMovementSystem" не потрібна позиція, щоб змусити програвач перейти від вводу користувача, оскільки MovementSystem підбере зміни швидкості, які застосовуються до позиції. Зрозуміло, все одно буде чудово скласти їх, але це приклад того, чому цього не потрібно.


Нещодавно я прочитав допис у блозі, де сказано щось подібне:

"Якщо у вас є дані, які можна згрупувати з двома різними компонентами, найкраще створити третій компонент з цими даними."

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.