The more I use fat struct for my entity system, the more I love it. Just saying each flag corresponds to a feature reducing a lot of invariants for most gameplay code. But something that I still kink of figuring out is how to make a system whose job is to manage and change these flags.
Most of these flags are just set-up-and-run types that get initialized when you first create an entity (e.g ControlledByPlayer, GameOverWhenDied, AttackWhenCollide, etc). These kinds of flags can also get changed by other data transformations at runtime and are usually responsible for simple, single, independent behaviors. For example, when the player gets hit he can't attack other entities so we disable his AttackWhenCollide flag for a while. Or we can set the GameOverWhenDied flag for entities that would resolve to a game over when died like the player, NPCs in escorted mission, final boss, etc.
But great games are formed by interesting interactions between combinations of features. Oh, when the player moves to this spring it springs the player toward this direction passes these turret's sensors which make them shoot some other enemies which make those explode and burn the wooden bridge that the player landed on. We can think of this example as a series of data transformations that happen to all the entities which get started when the player touches the spring. Specifically, each interaction sets up some flags and changes some values of some entities.
The main problem that I'm currently facing is how to make complicated behaviors that work across multiple entities and consist of multiple smaller behaviors each with a different set of invariants. This has been a really tough challenge since I started working on my enemy's AIs.
The first idea that I had is to have some kind of EntityBrain and delegate all the decision-making to it (like in handmade hero). The brain would run every frame to check for a set of conditions, manage the flags and states correctly, and later execute the behaviors based on some enums. Each entity has an EntityStateEnum and an EntityMoveTypeEnum. These will get changed by the brain and at the end of the frame, the entity has a switch statement to handle movement. This quickly falls apart because there were a lot of repeatable patterns. A lot of brains started to have the same conditions to check but different enough so I couldn't use goto. The movement also started to get samey, a lot of entities move closely like each other but with different orders or operations. I also should say that these brains are pretty specific about an entity "kind" (e.g PLAYER_BRAIN, SNAKE_BRAIN, ZOMBIE_BRAIN, etc) so maybe this is why it failed.
The second idea that I'm currently trying is to make is having a big MoveData struct that contains all of the necessary data. It has a bunch of flags saying how and when should you move it. But then you get into interesting questions like I want the player to move and jump so should I have a single MoveData struct that can both move and jump at the same time or I should have 2 MoveData structs, one for each. How many instances should an entity hold? Does MoveData have something like a pointer to the next MoveData or should every entity just hold an array of these, loop through, and execute the first one that met its condition.
I'm very curious to see your solution to this problem!