Как сделать State в ECS архитектуре?

Рейтинг: 2Ответов: 1Опубликовано: 18.01.2023

Хочу реализовать классическую для ECS задачу, как в RPG игре Dungeon Siege: юнит стоит, бежит, атакует, взаимодействует с сундуком/рычагом, валяется мертвым и т.д.

В классическом ООП это просто паттерн state, но как он выглядит в ECS архитектуре? Я не понимаю как может существовать контракт current state в виде компонентов на сущности (энтити), что он всегда один, что их не два или не ноль. Вариант что, CurrentStateType это поле в UnitModel и все системы обрабатывающие каждый стейт, чекает его, видится рабочим, но это как клиенты долбящие запросами сервер http чата, криповая кринжуха какая-то. А как это делать по людски?

Ответы

▲ 2Принят

Вопрос несколько туманен в том, какое именно Состояние имеется ввиду. Это состояние Машины Состояний или это флаг чего-либо (на каждый чих по флагу - ведь тоже подход). Также непонятен сценарий использования, это обработка состояний при апдейтах внутренних процессов или часть Управления от игрока (почти одно и то же) или Презентации в интерфейс.

*Данный ответ про Машину Состояний и внутренние апдейты.


По-хорошему, при любом раскладе, если состояние всегда одно и однозначно, то и SPOT у него должен быть один (Single Point Of Truth), чтобы не было по как-то причинам рассинхрона, что одни компоненту думают, что юнит бежит, а другие - что он уже умер.

Единое состояние надо где-то хранить или вычислять. Т.е. Предоставлять "наружу" геттер. Это может быть как свойство юнита, так и отдельный компонент. По сути, State ничем не отличается от, например, положения юнита в мире - точно такое же нерушимо-однозначное свойство.

Если сделаете компонентом, то можете в него положить какие-то доп.свойства нужные для расчета Машины Состояний (и, соответственно, сделать итератор который будет все состояния апдейтить). Например, длительность текущего состояния, чтобы автоматом переводить умирающего в мертвого, или мертвого в разложившегося.

И на всякий случай, взять значение атрибута по прямой ссылке (или даже через 2-3) совершенно не то же самое, что делать и ждать HTTP запрос, порядков так на 5-7 (доли нс против десятков мс). Не занимайтесь преждевременной оптимизацией =)