Component Entity Design

Started by
11 comments, last by Hodgman 5 years, 4 months ago

Lorenzo,

i understand your point, and you are probably correct that it isn’t the best use of CES. However, I am trying to push/stretch my understanding of it for any future problems I may have in my development.

 

Furthermore, you are condemning this approach without any solutions or helpful ideas on the matter. I am purely trying to understand it better and both Zakwayda and  strewya have both done just that. 

 

I dont want want to turn this into any philosophical discussion on game design. It is much simpler. I am merely trying to understand this design pattern. In reality, I would probably not use this pattern for a checkers game but what if later I decided to make the checkers do more than just jump one another. What if they had characteristics like fighting, dice rolls or options other than standard checkers. That, I am sure would help to have CES as the design pattern.

thank you though for your time.

Advertisement
On 11/28/2018 at 2:01 PM, Airtower said:

I don't have a checkers game to change from OOP to Composite Reuse design.

Composite reuse is a core part of OOP theory. Using inheritance instead of composition for the purposes of code re-use is a violation of OOP - so your inheritance-based design is a non-OOP design. That's why I suggested studying OOP -- Inheritance Based Game game entity code is often called OO, yet it breaks one of OO's core rules...?

So, there's a difference between simply using composition (a core part of all software philosophies), the composite reuse principle (a core part of OOP), and "entity + component" frameworks (a common collection of different patterns in game engines).

That last group (entity frameworks), I'd categorise into three groups:

  1. Entity base class + inheritance. Usually something like `virtual void Update` in the base class, and every type of game object inherits from this base. As above, this is abuse/violation of OOP rules.
  2. Entity is a concrete class with a collection of "components" inside it. Components are basically the same as "entities" from #1. The entity class implements the service locator pattern so that "sibling" components can communicate with each other.
  3. "ECS" - this one is basically an abuse of the relational model instead of an abuse of OOP. Entities are just ID numbers. Components are linked to an entity using those IDs. Entity fulfill the service locator pattern as in #2. Instead of adding any logic/functions to entities/components like in #1/#2, all game logic goes into "Systems" and "Components" are just plain data.

These kinds of frameworks (and variations of them -- there's no standard version!) are popular in many different game engines, so yeah, it's worth learning how to write code within these kinds of constraints... However, it's worth noting that these frameworks aren't common software engineering practice outside of game engines, and for good reason - they typically trample decades of engineering/science ? They're basically replacing existing paradigms (e.g. OOP/etc) are inventing their own ad-hoc software paradigm instead.

One of the main goals of types #2 and #3 is to allow part of the job of game programming to be done outside of the game code itself. Instead of every type of entity having to be programmed in the main language, you can build new entity types by editing scripts/configuration files that specify a list of component types to be used. This is really useful on large scale projects, but is serious over-engineering for a checkers game (unless your goal is simply education, then over-engineer away :D).

IMHO if you want to practice working within frameworks such as #2 or #3, it would be better to build a checkers game in Unity or Unreal, which both implement style #2, and Unity has also recently added support for style #3. These kinds of frameworks aren't standard patterns across all of software engineering, and their limitations and pro/con trade-offs are arbitrary. Every game engine will have a completely different style of "entity framework" (if it has one at all).

So, you could make your own entity framework with your own choice of arbitrary limitations, and then try to make checkers within that framework... but that feels a little too arbitrary :) So I'd go with practicing on an existing framework in this case.

The other practice exercise that you could do is implementing checkers within several different existing programming paradigms and design methodologies.
º Design the data layout as you would for a RDBMS with relational model, and then write procedural style code to implement the logic.
º Design the data + logic relationships with UML and then write OO code. Make sure to only use has-a relationships and no is-a to practice composition!
º Implement the game logic with a functional language like Haskell, or in an imperative language (C/C++/Java/etc) but using immutable objects (after constructing an object, never modify any of its members).

 

As for a simple design... :) A board is made up of sprites and cells. A cell is made up of a sprite and zero or 1 pieces. A piece belongs to a player and has a sprite. There's absolutely no need for inheritance here and composition is fairly natural.


struct Piece
{
  enum Color { Red, Black };
  Color color;
  bool crowned;
  Sprite* sprite; // picture of a 
};
struct Cell
{
  Piece* piece;//which game piece is in this slot
  Sprite* sprite;//background image
};
struct Board
{
  Cell cells[8][8];//bit wasteful, only 32 cells are actually valid places to put pieces in checkers...
  List<Sprite*> background;//extra images for the borders of the board, etc...
};

 

This topic is closed to new replies.

Advertisement