En un motor de sistema de componente de entidad, ¿cómo trato con grupos de entidades dependientes?

48

Después de repasar algunos patrones de diseño del juego, me decidí por Entity-Component-System (ES System) para mi motor de juego. He leído artículos (principalmente T = Machine ) y reviso algunos códigos fuente y creo que tengo suficiente para comenzar.

Solo hay una idea básica con la que estoy luchando. ¿Cómo trato con grupos de entidades que dependen unas de otras?

Dejame usar un ejemplo:

Suponga que estoy haciendo un tirador aéreo estándar (piense en Jamestown ) y quiero construir una "entidad de jefe" con múltiples partes distintas pero conectadas. El desglose podría verse así:

  • Cuerpo del barco: movimiento, renderizado
  • Cañón: posición (bloqueado en relación con el cuerpo del barco), seguimiento \ disparar al héroe, recibir daño hasta deshabilitar
  • Núcleo: posición (bloqueada en relación con el cuerpo de la nave), seguimiento \ disparar al héroe, recibir daño hasta deshabilitar, deshabilitar (er ... destruir) todas las demás entidades en el grupo de la nave

Mi objetivo sería algo que sería identificado (y manipulado) como un elemento distinto del juego sin tener que reescribir el subsistema desde cero cada vez que quiera construir un nuevo Elemento agregado.

¿Cómo implemento este tipo de diseño en ES System?

  1. ¿Implemento algún tipo de relación de entidad padre-hijo (las entidades pueden tener hijos)? Esto parece contradecir la metodología de que las entidades son solo contenedores vacíos y lo hace sentir más POO.
  2. ¿Los implemento como entidades separadas, con algún tipo de componente de conexión (BossComponent) y sistema relacionado (BossSubSystem)? No puedo evitar pensar que esto será difícil de implementar, ya que la forma en que los componentes se comunican parece ser una gran trampa para los osos.
  3. ¿Los implemento como una sola entidad, con una colección de componentes (ShipComponent, CannonComponents, CoreComponent)? Este parece desviarse de la intención del Sistema ES (los componentes aquí se parecen demasiado a entidades pesadas), pero sé esto, así que pensé que lo pondría ahí.
  4. ¿Los implemento como algo más que he mencionado?

Sé que esto se puede implementar muy fácilmente en OOP, pero mi elección de ES sobre OOP es una con la que me quedaré. Si necesito romper con la teoría pura de ES para implementar este diseño, lo haré (no es que no haya tenido que comprometer el diseño puro antes), pero preferiría hacerlo por razones de rendimiento en lugar de comenzar con un mal diseño.

Para obtener un crédito adicional, piense en el mismo diseño, pero cada una de las "entidades de jefe" estaba realmente conectada a una "entidad de BigBoss" más grande hecha de un cuerpo principal, núcleo principal y 3 "Entidades de jefe". Esto me permitiría ver una solución para al menos 3 dimensiones (abuelo-padre-hijo) ... que debería ser más que suficiente para mí.

John Daniels
fuente
2
Se trata simplemente de diferentes componentes de malla unidos a una entidad, malla de barco y cañón conectada a la entidad del jefe, no genere demasiado. Por cierto, un sistema de componentes de la entidad ES OOP
Maik Semder
2
Sí, lo peor de esos artículos de T-Machine es la idea errónea de que de alguna manera esto no está orientado a objetos. La mayoría de los sistemas de componentes para entidades están completamente orientados a objetos, solo que no están basados ​​en la herencia.
Kylotan
3
Creo que hacen hincapié en la naturaleza no OOP porque "pensar en la OOP clásica" te meterá en muchos problemas. Hasta ahora he ayudado a algunas personas a comenzar con los sistemas de entidades y ese es el mayor obstáculo. Intentar poner código en los componentes, tratar de tener componentes que se subclasifiquen entre sí, etc. es un gran problema al principio, pero es agradable ver que se enciende la luz cuando la idea finalmente se capta por completo.
PSpeed
@MaikSemder Limpié mis comentarios y los moví a chatear
MichaelHouse
1
Solo para que entienda @MaikSemder, en el sistema ES al que hace referencia, una entidad puede tener múltiples componentes del mismo tipo y el subsistema responsable de esos componentes tendría que lidiar con ese hecho. Entonces, ¿una Entidad puede tener múltiples componentes de Render y los datos y subsistemas de esos componentes determinarían cómo representarlos cada uno correctamente? Eso llevaría a menos entidades, potencialmente menos componentes pero una lógica de subsistema un poco más profunda, ¿correcto?
John Daniels

Respuestas:

42

Si estuviera en esta situación, crearía cada parte del jefe como una entidad separada. Estos "sub-entidades" incluirían algún tipo de AttachmentPointo ParentEntitycomponente. Este componente incluiría una referencia a la entidad matriz y un desplazamiento de la posición de los padres. Al actualizar la posición, verifican la posición principal y aplican el desplazamiento para generar su propia posición. Además, podría realizar comprobaciones para garantizar que la entidad principal aún exista. Además, puede tener un SubEntitycomponente que rastrea la existencia de subentidades para la entidad principal. Esto le permite hacer cosas como hacer que el núcleo del jefe sea vulnerable cuando se destruyen los brazos con escudos.

Actualmente uso un TargetEntitycomponente en mi juego, que se usa para el seguimiento de torretas y cuando los duendes van a recoger un recurso. Puede verificar la posición de la entidad objetivo y cambiar su comportamiento en consecuencia. Las entidades que no tienen posición nunca se agregan como objetivo, por lo que no hay preocupaciones allí. Sin embargo, cuando llegue a ser más profundo, como verificar la salud, el escudo, las reservas de energía o lo que sea de la entidad principal o secundaria, deberá asegurarse de que la entidad principal o secundaria realmente tenga el componente relacionado.

Al hacer que cada parte sea su propia entidad, se mantiene la flexibilidad del marco de la entidad / componente al permitirle agregar componentes adicionales y diferentes a cada parte del jefe. Por ejemplo, una parte del jefe podría tener un componente de arma y un componente de salud, mientras que otra tendría un componente de escudo y un componente de salud.

Encontré otra discusión sobre este tema aquí . En el cual los usuarios están discutiendo agregar múltiples componentes del mismo tipo a una entidad (lo cual me parece una mala idea). Parece una conversación útil, aunque no he leído toda la discusión.

MichaelHouse
fuente
Mucha buena información aquí. Explicaste bien la solución, dame un ejemplo y probablemente respondas 1 o 2 preguntas más por las que habría tenido que volver para más tarde. La discusión vinculada también parece intrigante, especialmente cuando empiezo a realizar una implementación más difícil. Gracias @ Byte56!
John Daniels
No hay problema John! Por supuesto, hay muchas formas diferentes de implementar un sistema EC. El sistema que tenía en mente para esta respuesta es el que describí en esta respuesta . ¡Buena suerte con tu juego!
MichaelHouse
Su enfoque es el más flexible y es bueno usarlo en un motor de juego generalista.
Coyote
7

Sin conocer demasiados detalles sobre sus sistemas existentes, la forma en que modelaría esto (y hasta cierto punto en mi propio sistema de entidades) es tener un componente como AttachedTo (parentEntity). A cualquiera de los niños se les puede asignar el componente AttachedTo (jefe).

El sistema de renderizado (o lo que sea) toma entidades con componentes: Position, AttachedTo, etc. y forma las jerarquías adecuadas.

PSpeed
fuente
Esta parece ser la respuesta consensuada. La próxima vez daré más detalles de implementación para que las personas puedan masticar. Gracias @PSpeed!
John Daniels
4

Si desea tener una entidad representada solo por una ID, la contención de entidades se puede hacer a través de un componente especial. Podría llamarlo CompositeComponent, y este contiene una lista de ID de entidades secundarias e interfaces para agregar / eliminar elementos secundarios de esa lista.

Obviamente, cualquier componente que dependa de la posición, etc. deberá trabajar con este para colocar la entidad correctamente. Cómo implementar esto dependerá un poco de cómo implemente el posicionamiento actualmente.

Por cierto, no existe una "teoría de ES pura": hacer entidades a partir de componentes es un enfoque popular, pero el método preciso de ninguna manera está estandarizado todavía.

Kylotan
fuente
Sí, debería aprender a no usar la palabra "puro" en ninguna discusión de diseño ... no existe tal cosa. ConpositeComponent route parece el consenso aquí. Gracias @Kylotan!
John Daniels