Досі системи компонентів сутності, якими я користувався, працювали здебільшого як артеміди Java:
- Всі дані в компонентах
- Незалежні системи без громадянства (принаймні, настільки, наскільки вони не потребують введення при ініціалізації) ітерацію над кожною сутністю, що містить лише ті компоненти, які конкретна система зацікавлена
- Усі системи обробляють свої сутності одним галочкою, тоді все починається заново.
Зараз я намагаюся застосувати це до гри по черзі вперше, з тоннами подій та відповідей, які повинні відбуватися в наборі в порівнянні з іншими, перш ніж гра може продовжуватися. Приклад:
Гравець A отримує шкоду від меча. У відповідь на це броня A забиває і знижує отриману шкоду. Швидкість руху A також знижується внаслідок ослаблення.
- Отримані збитки - це те, що заповнює всю взаємодію
- Броня повинна бути обчислена і нанесена на пошкодження, що надходять, до того, як шкода буде нанесена гравцеві
- Зменшення швидкості руху не може бути застосоване до пристрою, поки пошкодження фактично не буде нанесено, оскільки це залежить від остаточного розміру пошкодження.
Події також можуть викликати інші події. Зменшення пошкодження меча за допомогою броні може призвести до розбиття меча (це має відбутися до завершення зменшення шкоди), що, в свою чергу, може спричинити додаткові події у відповідь на нього, по суті рекурсивну оцінку подій.
Загалом це, здається, призводить до кількох проблем:
- Багато витрачених циклів обробки: Більшість систем (окрім речей, які завжди працюють, як-от рендерінг) просто не мають нічого гідного робити, коли це не їхня черга працювати, і витрачати більшу частину часу на очікування гри дійсна робота-стан. Це засмічує кожну таку систему з чеками, які постійно збільшуються в розмірі, чим більше станів додається в гру.
- Щоб дізнатись, чи може система обробляти об'єкти, які є в грі, їм потрібен певний спосіб контролювати інші незв'язані стану сутності / системи (система, відповідальна за нанесення шкоди, повинна знати, застосована чи ні броня). Це або заплутує системи з численними обов'язками, або створює потребу в додаткових системах, не маючи інших цілей, окрім сканування колекції сутностей після кожного циклу обробки та спілкування з набором слухачів, кажучи їм, коли добре щось робити.
Вищевказані два пункти передбачають, що системи працюють на одному і тому ж наборі сутностей, які в кінцевому підсумку змінюють стан, використовуючи прапорці в своїх компонентах.
Іншим способом вирішити це було б додавання / видалення компонентів (або створення абсолютно нових об'єктів) у результаті роботи однієї системи для просування стану ігор. Це означає, що всякий раз, коли система насправді має відповідну сутність, вона знає, що її дозволено обробляти.
Це, однак, робить системи відповідальними за запуск наступних систем, ускладнюючи міркування про поведінку програм, оскільки помилки не з’являться в результаті єдиної системної взаємодії. Додавання нових систем також стає складніше, оскільки їх неможливо реалізувати, не знаючи, як саме вони впливають на інші системи (і попередні системи, можливо, доведеться модифікувати, щоб викликати стани, в яких нова система зацікавлена), начебто перемагаючи мету створення окремих систем з одним завданням.
Це щось, з чим мені доведеться жити? Кожен приклад ECS, який я бачив, був у режимі реального часу, і це дуже просто зрозуміти, як працює ця цикл з однією ітерацією за гру в таких випадках. І мені це все ще потрібно для візуалізації, воно просто здається непридатним для систем, які призупиняють більшість аспектів себе кожного разу, коли щось відбувається.
Чи є якась схема дизайну для переміщення ігрового стану вперед, яка підходить для цього, або я повинен просто перемістити всю логіку з циклу і замість цього запустити її лише за потреби?