Sign up ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am trying to design a typical (data-oriented) ECS. The issue I am struggling with is that my rendering system have to rely on two different sets of entities to actually do rendering.

My current idea is to have (usually one, but possibly more) entities representing cameras (e.g. sets of components describing views and viewports). Then, I can have CameraSystem that iterates through all CameraComponents and renders everything they 'see' to appropriate viewports.

However, this requires CameraSystem to query for two non-intersecting sets of components: cameras and renderables.

My current approach allows systems to select all nodes having a particular combination of components. However, it is not possible in my design to select entities that have either CameraComponent or RenderableComponent. This is not the first time when optional component dependencies (using unions of component sets insetead of their intersections) seem useful to me, although I have never seen such an approach.

I could gather rendering data in RenderableSystem and then pass (e.g. through event or message) it to CameraSystem for actual rendering, but since two systems are so dependent, there seems to be little sense in separating them.

So, is allowing systems to have optional dependencies on components the most convenient and flexible solution in this case, or is there a better way?

share|improve this question

First, you should not have a strict 1-1 mapping of Components to Systems. It's unclear to me from your question if that's the case already. You may very well have singular systems that use or interact with numerous components. Rendering, physics, AI, etc. are all Systems (they perform a cohesive set of updates and logic) but interact with many Components.

A System needs to be able to store a list of entities that match some particular Signature. e.g., if physics requires BodyComponent and TransformComponent, then the PhysicsSystem needs a list of all entities that have both of those two components.

Solution 1

A System also likely needs multiple such lists, as you're finding. RenderSystem needs to know about all Renderable+Transform pairs, as well as all Camera+Transform pairs, and that's only for a very simple rendering engine (once you get particles, post-processing, terrain, foliage, skinned meshes, etc. it gets more complex).

Solution 2

The other alternative that I'm rather fond of is to stop trying to use the ECS pattern. If you split all your engines (physics, graphics, AI, audio, etc.) up into separate libraries (which is probably already the case for physics since most people use off-the-shelf libraries there) then you'll note that you need each to exist independently of your ECS framework.

For instance, when you load an entity up and see that it has a PhysicsComponent you call into your physics library's CreateBody() function with all the data from the entity; that will usually return some kind of pointer or id. Store that into the PhysicsComponent. Most of the rest of the data you loaded off disk can possibly even just be thrown away since it'll all be copied into the physics library's internal data structures. Really all you're left with is some glue so when game logic needs to add a force to a game object it can find the appropriate pointer to the physics library's body object.

Your Components end up mostly just being glue that holds your convenient data-driven game objects together with the external handles/objects managed by your engine libraries. You're more likely to find that you don't need Systems at all anymore and possibly (for simpler games) don't even need Components, either.

Depending on your choice of libraries or how you decide to implement Components, this may still even end up looking a lot like an ECS. For instance, instead of storing a PhysicsComponent that holds a pointer to a rigid body object, your library may allow you to attach a unique ID to a body when it's created and then query for bodies by ID; that would allow you to attach the EntityId to the corresponding physics body and then write a ComponentMapper facade that queries your third-party physics library instead of a custom component data structure. I question the utility of such a design myself, but it's certainly something you could do.

share|improve this answer
    
It's probably not useful to post another answer saying to not use ECS for this, so I'll add my thoughts as a comment. If you imagine a scene graph for dealing with rendering, sound, etc., it's very easy to hook it up with an ECS; simply have a component that refers to or owns a node in the graph. The scene graph is the meat and bones of the world, while the ECS is the brain. – Boreal 4 hours ago

I think you are over-using the component model. While what you are saying could be accomplished and would work, the general way of doing this is making the camera a global thing.

Sometimes it is just much easier to make an exception than to try force everything into a rigid view of "everything must be a component". So I recommend making the camera not a component but rather a property of the RenderSystem. There you could even have a list of cameras, and the RenderSystem would have much more control to optimize the way things get rendered.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.