Estoy trabajando en un juego con una arquitectura basada en componentes. Un Entityposee un conjunto de Componentinstancias, cada una de las cuales tiene un conjunto de Slotinstancias para almacenar, enviar y recibir valores. Funciones de fábrica tales como Playerproducir entidades con los componentes necesarios y las conexiones de ranura.
Estoy tratando de determinar el mejor nivel de granularidad para los componentes. Por ejemplo, en este momento Position, Velocityy Accelerationtodos son componentes separados, conectados en serie. Velocityy Accelerationpodría reescribirse fácilmente en un Deltacomponente uniforme , o Position, Velocityy Accelerationpodría combinarse junto con componentes como Frictiony Gravityen un Physicscomponente monolítico .
¿Debe un componente tener la menor responsabilidad posible (a costa de mucha interconectividad) o los componentes relacionados deben combinarse en monolíticos (a costa de la flexibilidad)? Me estoy inclinando hacia la primera, pero podría usar una segunda opinión.
fuente

Respuestas:
Hay una línea entre la granularidad completa, que no genera desperdicio de código o un estado similar a un blob (razón por la cual se favorecen las arquitecturas de componentes) y la usabilidad.
Obviamente, las cosas pueden tener un
Position, pero no son necesariamente dinámicas (entonces, ¿por qué tenerVelocityyAcceleration?). Sin embargo, algo con unVelocityva a ser un objeto en movimiento, por lo que tiene sentido también haberAccelerationagrupado.¿Vas a tener un caso donde v y una va a ser necesaria, pero no desea una simulación física para ellos? Del mismo modo, ¿habrá algún punto
Gravitysi no son objetos de física?tl; dr Agrupe lo que tiene sentido.
fuente
EntitytienePositionalgunos componentes que hacen quePositionparticipen en la física, entoncesEntityes de facto físico. Creo que lo que puedo hacer es agregar algunos componentes para la agrupación lógica y mantener todos los componentes fundamentales en una sola responsabilidad. Por lo que añadir, por ejemplo, unaMovablea unaEntitytendría el mismo efecto que la adición de unaPosition,VelocityyAcceleration.Para evitar la microgestión de todas y cada una de las variables que sugeriría al comenzar con fuerza, elija divisiones en torno a la responsabilidad y refactorice cuando la situación se presente de forma lógica. Puede comenzar los primeros diseños en papel. En algún momento, estas divisiones groseras de responsabilidad se convertirán en los componentes básicos de sus entidades.
Entonces, para un ejemplo apresurado, tienes Game. El juego se divide en Medio Ambiente + Estado. El entorno se divide en StaticWorld + MovingStuff. El estado se divide en AIControlled + PlayerControlled. La idea general de Daño se divide en TakesDamage + GivesDamage.
Y así.
Muy parecido al consejo común de "¡Crea juegos, no motores!" para los nuevos practicantes recomiendo "¡Crear juegos, no sistemas de componentes elaborados!" porque solo con experiencia personal con un juego en ejecución sabrás si se requiere un complejo sistema de componentes en futuros trabajos.
fuente
Mi conjetura sería combinar componentes que tendrán mucha interacción. En su caso, mantendría la posición en un solo componente y mantendría la velocidad y la aceleración juntas en un componente de física.
Pero depende mucho de las características de su juego (a menos que esté creando un marco sin un juego específico en mente).
fuente
Me doy cuenta de que esta es una vieja pregunta, pero tal vez alguien encuentre útil esta respuesta.
Creo que eso
Systemslo ayudará mejor a comprender cómo construir Componentes. Los sistemas existen en arquitecturas donde los componentes no contienen su propia lógica, aparte de simples getter / setters y funciones auxiliares. Los sistemas operan en entidades que satisfacen los requisitos de los componentes. Esta es la razón por la cual es mejor separar los datos de los componentes tanto como tenga sentido que esos datos se procesen sin los otros datos.Por ejemplo, puede tener una
MovementSystemque actualice sus Entidades enPositionfunción de susVelocity. Esto podría ser para entidades simples en el juego. Pero, para el Jugador y los Enemigos, es posible que desee un movimiento queAccelerationse proceseAcceleratedMovementSystem. Pero para Obstáculos puede que quierasFriction. El terreno también puede tener fricción, pero no tendrá un componente de velocidad. ¿Pero que pasaGravity? Simplemente agréguelo Player, Enemy y Obstacle, y cree unGravitySystempara procesarlo.La conclusión es que cuanto más desacoplado su
Componentsson, más extensible laEntitieshabrá cuando se utilizaSystems.Editar: hizo la última declaración más clara.
Editar: Ok, he estado trabajando en mi propio sistema y llegué a esta conclusión. Un ejemplo para dividir la posición y la velocidad es que manipular la velocidad hace que la posición cambie con un sistema de movimiento. Como resultado, un 'InputMovementSystem' no necesita una posición para hacer que el jugador se mueva de la entrada del usuario porque el sistema de movimiento recogerá los cambios en la velocidad para aplicar a la posición. De acuerdo, todavía funcionaría bien unirlos, pero ese es un ejemplo de por qué no es necesario que lo sean.
Hace poco leí una publicación de blog que decía algo como esto:
fuente