Hi,
Since the game engine I'm working on is largely useless compared to the more "professional" engines out there, I'm taking the opportunity to experiment with the architecture for it. The design I'm working on is a slightly different take on the Entity Component System, based off ideas I've had from working with both Unity and UE4. Anyway, here goes:
The root type of object in a scene is a GameObject, which has the following features:
Transform - Describing the position/rotation/scale/parent of the GameObject. In a pure ECS design this would be a component unto itself, but there's very few cases where you don't want one, and I'd rather have the guarantee that it exists.
Behavior Components - This is a linear array of components that are responsible for manipulating the GameObject that owns them. This is where the bulk of game logic will be attached, including networking and physics behavior. Basically anything that fits under the concept of "Manipulation" should go here.
Display Components - Unlike Behavior Components, this is a tree rather than an array. Anything that fits under that concept of "Description" should go here - meshes, particle emitters, sound emitters, and more. Each display component has a transform of its own, to describe a physical offset from its parent (the base case of which is the GameObject itself).
Behavior components would mainly be manipulating the state of the GameObject and its display components each frame, while the display components would pretty much just sit around to be enumerated by their respective subsystems (ie, the particle system could poll for the transform of every particle emitter in the scene).
One large advantage to this system is that what would have been constructed as a parent/child hierarchy of objects in Unity can now be boiled down into one GameObject with several display components.
This only exists on paper right now, and I'm still not entirely satisfied with the design. One problem with the ECS pattern as a whole is that it doesn't provide many guarantees about objects (knowing at compile time which features exist on any given GameObject). I suppose I could allow the 'GameObject' class to be extended, promoting components to actual fields when it's really integral to the behavior of the class (i.e some class must have a StaticMeshComponent or something, which gets manipulated in a special way) but that could get messy. One thing I do like about this design is it makes a clear distinction between "behavior" and "data"; and a shallow inheritance hierarchy like this not only allows the engine to be more data-driven, but makes reasoning about memory usage and runtime behavior much easier.
Has anyone worked on a design similar to this one, and if so: what were issues/benefits of the design in practice? Am I over thinking this? Bottom line is this: I'd like to have the guarantees of a more object-oriented approach, with the flexibility of an ECS. I'm a little stumped on how to do that, but I wouldn't be writing my own engine if I weren't willing to get stumped sometimes.
Thanks!