Bob Nystrom (not the hockey player) wrote the book "Game Programming Patterns". His web site is http://stuffwithstuff.com/. His talk at Roguelike celbration was about programming patterns: why the popular ECS pattern may not be appropriate for roguelikes, and patterns he thinks are useful.
Entity-Component-System makes the game's "entities" (players, NPCs, obstacles, bullets, etc.) just a bag of specialized components or aspects. There may be a component for position and velocity, one for appearance, another for AI, etc. (Not all entities need have all components.) Each component is managed by an associated system that is responsible for manipulating and acting on that components' state.
This architecture attempts to solve the problem of complexity by making components as orthogonal as possible, and separating out the state from how it is manipulated. This avoids "everything in one big class" or even worse problems if you try to use inheritance for the different aspects.
A game loop that looks like this:
will be slow because of bad caching behavior. A better approach is to have each component in its own list, so that the systems can iterate over just the relevant components. (I believe, though I don't think Bob made this clear, that this works best if the components are allocated from the same memory pages instead of intermixed with other component allocation.)
But this is overkill for a roguelike game that typically has little physics, little display logic, and tons of AI. Cramming everything into one aspect is the sort of complexity that designers use ECS to avoid, so we haven't made any pr/ogress! So what are architectures that do grapple with the complexity in a roguelike: lots of actions and lots of content
(1) Split out capabilities, not domains or aspects, into classes. These form the components in an item. Bob's example was that an object could be used both offensively and defensively would have an offensive capability and a defensive capability filled in. Code that tries to invoke specific capabilities deal with these capability objects, not the entire entity. This uses composition, not inheritance:
class Object {
public:
Attack attack;
Defense defense;
Use use;
};
(2) The "type-object pattern". Use a class for the type of a monster, to store common attributes of all monsters of that type. (Got it?) So you can think of having a "template" for every monster type (i.e., "kobold") that contains shared state, while the object representing a specific monster ("kobold 43") refers to that template by name or pointer.
This sort of reinvents the object-oriented system one level up, but that's OK because it's data driven (not necessarily fixed at compile time) and can have the properties the game needs from inheritance, not whatever the programming language decided was right.
(3) "command" pattern: objects that represent actions. Each such object can be thought of as a "first-class turn", something that an actor in the game does on its turn. This pulls complicated actions out of the player/monster/actor class and into a smaller, managable unit. Player and monster AIs can share the same action objects, instead of implementing "move one square" twice for PCs and NPCs.
Adding a new action becomes a more separable operation from the "state" of the game, allowing the designer to create lots of actions feasibly without interleaving their code. Also, he showed a game loop which naturally handles different actors moving at different rates--- they are asked for their next action when their "energy" (or virtual clock) indicates it's time for them to move.
I upvoted your post.
Keep steeming for a better tomorrow.
@Acknowledgement - God Bless
Posted using https://Steeming.com condenser site.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit