I have been experimenting with the Entity-Component-System paradigm in game developement (specifically by using the excellent crate specs
). Point in question, I am working on turn-based games, e.g. a roguelike.
After some effort I managed to get the whole thing running, but then I started wondering. The more I read about it, the more it looks to me like ECS was thought to be used on real-time games, where systems run continously and in parallel. Adapting it to my turn-based game produced some weird quirk: systems have to run one at a time, and are mostly exclusive!
E.G. I have a system making an entity step in some direction and changing its position accordingly, which only runs when the entity currently playing actually perform a step; otherwise, the step system remains silent.
While this seems to suggest ECS is not suited to my use-case, the Entity-Component part actually worked great: it gave my entities a great deal of flexibility, yielding the benefits ECS promises in this sense compared to OOP.
So I am wondering whether I should change my approach. I could, for example, define a single Entity
type containing all possible components behind an Option
, and then store those in a huge Vec
. To make an explicit example of what I mean:
// an example component
struct Life {
pub max_hp: u8,
pub current_hp: u8,
}
// another example component
struct Movement {
speed: u8,
}
// a generic entity, owning its components
struct Entity {
id: usize,
life: Option<Life>,
movement: Option<Movement>,
}
// the main game type
struct Game {
// storing all the components
world: Vec<Entity>,
}
impl Game {
// main method to interact with the game:
// an entity performs some action
pub fn play_action(&mut self, entity_id: usize, action: Action) {
// apply action to game following the game's rules
}
}
Pros and cons of this approach: I expect it to be unoptimized, but, after all, speed is not my main concern. On the other side, it is much more explicit and easy than a full-fledged ECS like that provided by specs
.
So, am I grossly misunderstanding ECS? Should I stick to it, pursue my example, or something different altoghether?