Movement system low or high level in ecs design

Started by
15 comments, last by Dominik2000 9 years, 3 months ago

Hello,

sorry for writing so many ECS related topics, but as I'm programming, I come over more and more problems...

My architecture has an entity manager and a system manager, the entity manager manages all entities (entities are only ids), and every component has it's component pool which gives the component for the id back.

The system manager has all systems (render system, audio system,...).

Then I have an additional class scene manager, which, for example, creates the scene in the beginning of the game. The scene manager routes all work to the render system, he told the render system to create an entity with the given mesh, on the given position and so on.

And here I have my question, most of the articles say, that the movement system is a system. In my opinion, systems are low level classes, and managers (or how the will ever be named) are high level. The movement system moves my entities, that means, the movement system checks the velocity component and the position component of the entity, and moves the position of the entity by the given velocity, and told the render manager that the entity is moved. That means for me, that the movement system is not a system but a manager (it's high level, because it has nothing to do with the rendering of the entity).

Or should all systems knows the entity manager and the renderer checks all positions of the entities and moves them? But also then, the movement system is high level.

Is the ecs architecture combining high level and low level systems? This really is hard to solve for me, I know, that there is no given ECS way to go, but you have much more knowledge of this pattern I think.

Thank you!

Dominik

Advertisement


The scene manager routes all work to the render system, he told the render system to create an entity with the given mesh, on the given position and so on.

Why would the render system be responsible for creating entities? That doesn't make sense to me.


The movement system moves my entities, that means, the movement system checks the velocity component and the position component of the entity, and moves the position of the entity by the given velocity, and told the render manager that the entity is moved.

Why would the movement system tell the render manager that an entity moved? The movement system shouldn't know anything about rendering. It should just change the position of the entity based on its velocity.

I use Irrlicht as graphic engine. The render system is not responsible for creating the entity but it must show the mesh on the screen, and so the render system has to create the entity in irrlicht.

The movement system must change the position component, and the render system request the position and renders the entity.

Maybe irrlicht is the problem...

he told the render system to create an entity with the given mesh, on the given position and so on.

Wrong. The renderer doesn’t need to know about anything but the mesh, materials, and things related to rendering. You have a scene manager for a reason. Having 2 systems managing object positions etc. doesn’t make sense and violates the single-responsibility principle.

movement system is a system.

Correct, for any full-on implementation of ECS.

The movement system moves my entities, that means, the movement system checks the velocity component and the position component of the entity, and moves the position of the entity by the given velocity

Correct.

and told the render manager that the entity is moved.

Incorrect. There is no reason to communicate anything with the renderer at this time.

Is the ecs architecture combining high level and low level systems?

Yes, one of its major flaws.
However this is not related to your problem right now.


I have never used Irrlicht, but in any sane rendering system you have an object and the object has a bunch of meshes and materials and a world transform. The object is managed entirely by the scene manager (which may delegate things to physics, input, etc., but in any case it is the one pulling all the strings at the highest level) and then eventually the object’s meshes all get drawn by passing them, along with their transforms, to the renderer. The renderer doesn’t “track” anything related to the objects (positions etc.) and doesn’t even know what an object is. It knows what vertex buffers, shaders, index buffers, and matrices are, and when you want to draw something you activate/set all of these things can call MyAwesomeRenderer::DrawLikeABoss().


Maybe irrlicht is the problem...

Possibly.
It is designed to be just a rendering engine, but the problem with all “just rendering” engines is that they are hard to use unless they also provide a model format and a bit of scene management, meaning basically they aren’t sticking to the single principle to which they should and using them will force you to also use their scene-management system etc.

Since you also have your own scene manager, there will likely be a clash there.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


The movement system must change the position component, and the render system request the position and renders the entity.

There are two approaches you can consider for replicating information to your render system and a lot of it depends on how coupled you want your code.

The first approach would be to decouple your entity system and rendering system entirely. There is lots of benefits to this approach as it will allow you to easily replace your rendering engine with another but does come with it's own set of concerns. To decouple the two entirely, you would use a command queue where your ECS systems emit commands as they perform various operations. These commands are placed into the said queue and during the render system's update phase, it would parse these commands and perform the necessary rendering operations. It's important that all pertinent information be included in the command to avoid the rendering system having a need to query the ECS at all.

The second approach would be to live with the fact there will be some coupling. In this case, you would have a specialized ECS system or game loop step that runs after you have completed your logical updates and would query various entities and replicate necessary information from the ECS into the render system's scene manager. This system acts as a wrapper around calling Irrichlt's "render/update" call as it would perform the various scene updates and then render a single frame.

Both approaches have advantages and disadvantages and you can easily change between one or the other. Pick one that makes the most sense for now and move on. You can always come back later and change it and improve upon it as the need arises.

In your first approch, do you mean that in this queue, there is a move entity position to ... entry, for the scene manager of irrlicht?

The second approch would be a special irrlicht wrapper system, which do all the things with the scene manager, and the irrlicht render system only do the update?

Thank you for clarifying.

In your first approch, do you mean that in this queue, there is a move entity position to ... entry, for the scene manager of irrlicht?

Correct. Think of this as a message that contains the id of the entity, the position, and orientation. The render system takes the entity id, locates the Irrlicht scene entity by a reverse lookup table and then modifies the render scene node appropriately.

The second approch would be a special irrlicht wrapper system, which do all the things with the scene manager, and the irrlicht render system only do the update?

Correct. The wrapper system transfers all information from the entity's components into the Irrlicht scene such as position, orientation, setting appropriate mesh, material, etc. After all that has occured, this same system could just then call Irrlicht's update to send the render queue to the graphics card and swap buffers.

The first approach could be combined with an async messaging system, which I need anyway. Is this correct? This message queue is nothing else, or?

For the point of seperating the rendering from the systems I've taken the following approach:

All entites that are renderable have a RenderComponent that derives from DrawableComponent

The RenderComponent contains the model and the textures. On every frame during the Draw I call EntityManager.Draw() which calls the Draw function on every Component that is a DrawableComponent.

The Draw function of my RenderComponent calls the static ModelDrawer class and passes the position, rotation, model and textures to it for rendering


For the point of seperating the rendering from the systems I've taken the following approach:

If I understand correctly, it sounds like you've moved the dependency on the renderer from a system (a high level construct) to a component (a low level one). I don't see how that's a good thing. So if you switch to a different rendering engine, you need to replace all the DrawableComponents?

This topic is closed to new replies.

Advertisement