In this article there's also a "System"
No wonder why its called Entity Component System EDIT: Ninja'd by sean
The "pure" ECS approach has 3 parts:
- Entities, which are an ID (integer, long, UUID, whatever you prefer).
- Components, which are data, and only data (no behavior, no methods, no logic).
- Systems, which are the logic and manipulate components and entities.
For setting up these, you need a way to track what components each entity has (many ways to do this) and a way for the systems to specify what kind of entities they can process, that means, a way to specify what components a system needs in an entity for processing it (again, many ways to do this), for example, a PhysicsSystem won't process an entity if it doesn't has a "RigidBody" component.
That's the general idea, you put components in an entity, and let the systems resolve what entities they process, run all the systems in the game loop.
Ideally the systems aren't very coupled, ie, only few of them need to be run in a specific order, and ideally, when a system processes an entity, it doesn't has side effects that go beyond the components of said entity. This allows for running decoupled systems in parallel and for running the entity processing itself of each system in parallel too.
I said "ideally" because coming up with such decoupling can be a challenge in itself (just like designing class hierarchies).
This is the most "pure" approach I'd say. Of course you can go off tangent by having Entities being more than pure unique IDs, components having some logic, and using inheritance here and there when it merits it. As with everything, nothing is set in stone and no one says doing ONLY components and ONLY systems and ONLY entities will fix all of your problems.
EDIT: On the "data oriented" part. The idea is that components are stored contiguously in memory, so that when a system iterates over entities, it can fetch contiguous components from an array and make the best use of CPU cache. How you do this part depends on your game.
For example, if you put every kind of component in their own array, and use the Entity ID to index into said arrays, your data essentially becomes a struct of arrays.
If a system that processes most of the entities in the game uses 5 or more different types of components at the same time, it might be more worthwhile placing those 5 components into an array of structures instead, so the 5 components are near each other in memory and can be prefetched by the CPU more efficiently.
This part depends a lot on how your game is set up (remember we're making a game after all), you might want some components grouped in memory rather than isolated by type, and some others might be better isolated by type rather than grouped.
That is something you'd only know when you have all the components and systems set up, and can profile everything. You can't make these kind of decisions as you go (or maybe you can if you really, really know what you're doing). Ideally, the layout in memory should be abstracted in such a way that you can do these sort of changes (grouping some components, isolating others) without having to refactor everything. As always, YMMV.