¿Cómo conectar una máquina de estados finitos a una arquitectura basada en componentes? [cerrado]

23

Las máquinas de estado parecen causar dependencias dañinas en arquitecturas basadas en componentes.

¿Cómo, específicamente, se maneja la comunicación entre una máquina de estado y los componentes que llevan a cabo un comportamiento relacionado con el estado?

Donde estoy

  • Soy nuevo en arquitecturas basadas en componentes.
  • Estoy haciendo un juego de lucha, aunque no creo que eso deba importar. Imagino que mi máquina de estado se usa para alternar estados como "agacharse", "apresurarse", "bloquear", etc.
  • He descubierto que esta técnica de administración de estado es el sistema más natural para una arquitectura basada en componentes, pero está en conflicto con las técnicas sobre las que he leído: Sistema dinámico de componentes de objetos de juego para caracteres de comportamiento mutable. Sugiere que todos los componentes se activen / desactiven ellos mismos al verificar continuamente una condición para la activación.
  • Creo que acciones como "correr" o "caminar" tienen sentido como estados, lo que está en desacuerdo con la respuesta aceptada aquí: /gamedev//a/7934
  • He encontrado esto útil, pero ambiguo: ¿Cómo implementar el comportamiento en una arquitectura de juego basada en componentes? Sugiere tener un componente separado que no contenga más que una máquina de estado. Pero, esto requiere algún tipo de acoplamiento entre el componente de la máquina de estado y casi todos los demás componentes. No entiendo cómo se debe manejar este acoplamiento. Estas son algunas conjeturas:

    A. Los componentes dependen de la máquina de estado: los
    componentes reciben referencia a los componentes de la máquina de estado getState(), que devuelve una constante de enumeración. Los componentes se actualizan regularmente y verifican esto según sea necesario.

    B. La máquina de estados depende de los componentes: el componente de la
    máquina de estados recibe referencias a todos los componentes que está monitoreando. getState()Consulta sus métodos para ver dónde están.

    C. Alguna abstracción entre ellos ¿
    Usa un centro de eventos? Patrón de comando?

    D. Se
    utilizan objetos de estado separados que hacen referencia a los componentes . Se crean objetos de estado separados, que activan / desactivan un conjunto de componentes. La máquina de estado cambia entre objetos de estado.

  • Estoy mirando los componentes como implementaciones de aspectos . Hacen todo lo que se necesita internamente para que ese aspecto suceda. Parece que los componentes deberían funcionar solos, sin depender de otros componentes. Sé que algunas dependencias son necesarias, pero las máquinas de estado parecen querer controlar todos mis componentes.

Cachorro
fuente

Respuestas:

7

La descripción general es bastante ligera, pero mira estas diapositivas de una presentación que hice para New Game Conf el año pasado:

https://docs.google.com/presentation/d/110MxOqut_y7KOW1pNwIdcccisIA3ooJwVR-xm-ecuc4/view

(ver imágenes pertinentes a continuación)

La esencia de la técnica es combinar el patrón de la lista de acciones (explicado, algo mal, en las diapositivas) con máquinas de estado de comportamiento que actúan sobre una entidad de juego basada en componentes.

En esencia, es lo mismo que crear un sistema de composición especial solo para el comportamiento de IA, orientado hacia los tipos de integración entre comportamientos que necesita para sistemas de IA más simples.

Mi parte favorita de ese juego en particular era cómo podíamos crear tipos de enemigos completamente nuevos simplemente seleccionando de una lista de comportamientos preescritos, ponerlos en la lista de acciones para el objeto del juego (que reside en un Componente Cerebral) en el orden deseado. prioridad, y todo simplemente funcionó. Con una lista de acciones que permite acciones de Bloqueo / No Bloqueo, esto puede hacer cosas realmente geniales a pesar de lo simple que es implementarlo.

Incluso comportamientos como "aturdir" donde realmente solo una StunBehaviorAction se coloca en la parte superior de la lista de acciones; si el comportamiento de aturdimiento se activa (después de observar que el EarsComponent del objeto del juego escuchó un impresionante ataque de ondas de choque), establece su estado interno en Aturdido, le dice al AnimationComponent que reproduzca la animación de aturdimiento y establece su estado de acción en Bloqueo, y su temporizador en un tiempo de espera de aturdimiento extraído del EnemyParametersComponent del objeto del juego. Dado que estaba Bloqueando y en la parte superior de la lista de acciones, ninguno de los otros BehaviorAction en la lista de acciones obtendría su método de actualización, por lo que esencialmente se desactivarían. Cuando expiró el tiempo de espera, StunBehaviorAction volvió a establecer su estado en Inactivo y su estado de acción a Sin bloqueo.

Los otros comportamientos que implementamos se implementaron casi todos con una sola máquina de estado interna. Los únicos dos que no tenían máquinas de estado, de hecho, eran PatrolPathBehaviorAction (empujaría una serie de PathAction's a la lista de acciones si estaba inactivo, lo que a su vez empujaba MoveAction's) y GuardHomeBehaviorAction (siempre en la parte inferior del lista de acciones, y siempre empujaría una PathAction de vuelta a la ubicación de inicio del enemigo). Cualquier otro comportamiento era una máquina de estados.

Diapositiva 10 Diapositiva 25 Diapositiva 26

Sean Middleditch
fuente
¿Cuál es la diferencia fundamental entre "Comportamientos" y "Acciones"?
Cachorro
1
@Pup: desde la perspectiva del código, tal como lo construí, un comportamiento es una acción. Desde un punto conceptual, las acciones suelen ser transitorias, existen solo hasta que están "completas", mientras que los comportamientos son para siempre y nunca se eliminan de la lista. He visto a otro equipo construir un sistema similar pero con dos listas, una para Acciones y otra para Comportamientos, que funciona bastante bien. Sin embargo, me gusta tener la capacidad de una Acción para bloquear ciertos comportamientos, usando las máscaras de bits y la agrupación (carriles, creo que los llamé en las diapositivas). Lamento que el gráfico de la diapositiva del medio sea tan malo. :)
Sean Middleditch
3

En una empresa anterior para la que trabajaba, teníamos un sistema basado en componentes con IA basada en el estado. Teníamos un componente de IA que controlaba todo el comportamiento de ese objeto / unidad. Cuando la IA estaba activa, como deambular, atacar, etc., recibiría una actualización de cada cuadro para hacer cualquier lógica que fuera necesaria. Cuando la IA estaba inactiva o no se movía, el componente se desactivaba y no se actualizaba cada cuadro. El componente, aunque está desactivado, aún podría recibir mensajes basados ​​en eventos, por lo que recibiría un mensaje para algo así como un jugador que ingresa a su radio de aggro, y podría responder a eso reactivando el componente AI para que pueda realizar actualizaciones basadas en marcos.

El componente AI tiene subcomponentes, que podría crear y destruir sobre la marcha, según el tipo de acciones que estaba realizando. Por ejemplo, si estaba deambulando, podría crear un subcomponente errante y actualizar cada cuadro mientras deambula, y luego, si se agroe mientras deambula, cerraría ese subcomponente y abriría un subcomponente de ataque. El componente AI debe ser independiente de todos los demás componentes de un objeto. Por ejemplo, teníamos un componente de entrada, que simplemente buscaría valores de movimiento en una unidad. La consulta que hizo fue algo a lo que responderían tanto los objetos humanos como los de IA. Esto permitió que el componente de IA simplemente estableciera valores de movimiento en sí mismo durante cosas como deambular, que el componente de entrada podría detectar, al igual que un componente controlable por humanos establecería valores que el componente de entrada podría detectar.

Nic Foster
fuente
Entonces, ¿los subcomponentes de IA realmente están haciendo el trabajo? ¿Existían como componentes de la entidad, al mismo nivel que el componente de IA?
Cachorro
Los subcomponentes en nuestro motor eran parte de la clase de componentes base. Por lo tanto Component, cualquiera , derivado de BaseComponent, podría tener cualquier número de SubComponents. El Update()método en BaseComponentverificaría la lista de subcomponentes y recurriría Update()a ellos. Subcomponentseran completamente opcionales, por lo que BaseComponentpodría no tener ninguno. Además, los mensajes que se enviaron a un componente también se enrutaron a los subcomponentes.
Nic Foster
1

No está claro qué quiere decir con componentes, ya que sus términos son muy vagos sin ejemplos concretos. A menudo, las entidades del juego se crean utilizando la composición en lugar de la herencia. Por lo tanto, podría convertirlos en algo que pueda sufrir daños al agregar un componente de salud a la entidad o podría animarlos agregando un componente animado. También se podría poner la IA en dicho componente. Habrá una lógica de toma de decisiones en su componente AI y si le preocupa acoplar eso a gran parte del otro código en el sistema, podría recopilar la información en una pizarra a la que solo se permite el acceso a la lógica AI. También está el problema de las dependencias en la salida del sistema AI. Básicamente, su IA está controlando una entidad y ese control necesita una interfaz. Un concepto útil es el de un controlador o gamepad. Tu IA puede completar una estructura similar a la que llenaría un gamepad de jugador (aunque podría tener algunos "botones" adicionales para habilidades específicas). Ahora esta estructura podría pasarse a su componente animado que lo interpretaría y seleccionaría las animaciones apropiadas para reproducir. Diferentes subcomponentes de inteligencia artificial podrían incluso estar escribiendo en diferentes campos de la estructura o en los mismos campos con diferentes prioridades. Apuntar y caminar, por ejemplo. Diferentes subcomponentes de inteligencia artificial podrían incluso estar escribiendo en diferentes campos de la estructura o en los mismos campos con diferentes prioridades. Apuntar y caminar, por ejemplo. Diferentes subcomponentes de inteligencia artificial podrían incluso estar escribiendo en diferentes campos de la estructura o en los mismos campos con diferentes prioridades. Apuntar y caminar, por ejemplo.

Jesse Cluff
fuente