2

I'm currently learning about "Entity Component System". After reading many tutorials and forum threads I still wonder where rendering logic has to go. I am not talking about actual OpenGL/DirectX-Rendering code that, for example, takes a sprite and renders it. What I mean is the logic that decides which sprite to render.

A visible entity requires three aspects:

  1. Evaluating the AI (changing position, state, ...)
  2. Evaluating the rendering state. For example which sprite cycle to use when the entity is walking, climbing, getting hit, ...
  3. Actually rendering the sprite

Most tutorials propose to use something like an AISystem (1.) for logic and a RenderSystem (3.) to show a sprite (cycle) that is defined in a RenderComponent. What they do not say is where the RenderComponent is updated. It is my understanding that just putting (2.) into (1.), thus mixing character logic with rendering logic, would be bad design.

The straight-forward solution would be to add a specific render logic system for each enemy. So for example for a Gumba, I could add a GumbaLogicSystem, a GumbaRenderLogicSystem and for actual rendering, a generic SpriteRenderSystem that all sprite based entities use. However, this means creating two components* and two systems for every entity type, which does not seem to be a good solution.

Is there a good solution that separates character logic and rendering logic while keeping the number of systems small?

Thank you

(* = in a simple approach, a system processes an entity depending on its component. In order to have the GumbaRenderLogicSystem work on the entity, it needs a GumbaRenderingLogicComponent in order to be recognized by this system. The same is true for the character logic.)

Edit1: I am aware that ECS is an abstract pattern. My question aims at best practices on how to keep the number of systems small. My example is motivated from game programming but not restricted to this area. Let me explain with a more abstract example:

Imagine I had some entity that is visible. In a hierarchy based architecture I would have something like:

  • SomeModel (inherits from AbstractModel)
  • SomeController (inherits from AbstractController)
  • SomeRenderer (inherits from PixelRenderer which in turn inherits from AbstractRenderer).

In ECS I would need a whole bunch of new classes:

  • SomeModelSpecificDataComponent (i.e. data that is specific to this semantic entity)
  • SomeModelSystem (that does the logic)
  • SomeModelSpecificRenderComponent (i.e. rendering data that is specific to this semantic entity)
  • SomeModelSpecificRendererLogicSystem (system that decides how to render)
  • PixelRendererSystem

Is there any way I can reduce the number of new system that need to be introduced? One solution might be to add "agents" or "behavior objects": a general RenderingComponent is attached an instance of some "RenderingAgent" class that has a single method "Update" which is called in the RenderSystem. So technically the component does not contain logic itself. I fear this might be overengineered, though.

4

1 回答 1

0

经过一段时间的思考和多次讨论后,我意识到,我的思维方式可能是错误的。我所描述的实际上适用于普通 ECS 方法。

防止系统和组件爆炸的唯一方法是对游戏元素进行适当的抽象,以便可以描述渲染的各种需求,而不是进行编程。

我的意思是,例如,精灵引擎必须允许足够的抽象,您只能通过存储在由渲染系统评估的渲染组件中的描述来表达各种动画和状态。您还需要做的是正确地将您的解决方案拆分为可重复使用的部分。

通过这种方式,ECS 比其他模式更迫使您真正考虑一个好的架构。

于 2016-02-11T15:59:18.913 回答