Conceptualmente, ¿cómo se hace un motor de reglas / restricciones (no gráficos / física) para un juego?

16

Quiero hacer un juego simple similar a los libros de elige tu propia aventura. Al jugador se le presenta un texto narrativo y puede elegir su acción de una lista de posibilidades. Esto, a su vez, conduce a un nuevo texto narrativo, hasta el infinito. El único inconveniente es que, dependiendo de algunas decisiones anteriores, la lista de posibilidades puede diferir.

A primera vista, esto suena como una carga de declaraciones if-else, lo que implica que un motor de reglas estaría en su lugar. Pero, también me parece una máquina de estados finitos.

Estoy a punto de escribir esto en Java o quizás en Groovy. Actualmente estoy más interesado en los problemas conceptuales, es decir, ¿cómo se debe hacer esto a un nivel amplio (de todos modos, ¿cómo implementan las personas los juegos de ajedrez o de cartas?), Pero algunos consejos sobre una biblioteca específica también son bienvenidos.

Obviamente, el "motor del juego" del título no se refiere a la detección de colisiones u otra física / mecánica de gráficos, sino a la lógica que decide qué opciones le ha dado un jugador a la situación y su estado actual.

kaqqao
fuente
1
¿Es esta pregunta más adecuada para gamedev ?
Uwe Plonus
2
@Uwe Plonus lo consideró, pero no lo creo. Mi pregunta es puramente conceptual y no tiene nada que ver con las bibliotecas gráficas, 3D y otros temas que dominan gamedev. Ahora que lo pienso, esta pregunta tiene poco que ver con los juegos per se ... pero no estoy seguro de cómo titularla mejor.
kaqqao
El ajedrez y los juegos de cartas son muy diferentes de las aventuras.
Deer Hunter
1
Su pregunta parece abarcar también el desarrollo de sistemas expertos. Donde el rango de preguntas de seguimiento y posibles diagnósticos se limita con cada respuesta seleccionada. ¿Tal vez eso es lo que debe buscar para encontrar algo más de "entrada"?
Marjan Venema

Respuestas:

7

Según lo que has dicho en los comentarios, así es como lo manejaría:

Implemente la historia como una máquina de estados finitos, con un giro. Cada estado es una página de la historia, y cada transición es un enlace de una página a otra. Pero cada transición también tiene condiciones . Las Condiciones pueden ser nulas, en cuyo caso la Transición siempre aparece como una opción disponible, pero si no, deben evaluarse cuando aparece la página, y si la evaluación regresa False, la Transición no aparece.

Hay dos formas básicas de implementar las Condiciones. El primero es configurar un motor de script completo dentro del juego, y luego se ve la Condición return player.inventory.contains(GUN). Inicialmente, esto es más complicado de configurar, pero permite secuencias de comandos más avanzadas.

El segundo es codificar las posibles condiciones en algún tipo de objeto. Podría tener un RequiredItemcampo, y si ese campo tiene un valor, verifique si se cumple la condición. Este sistema es más sencillo de configurar. Limita mucho más lo que puede hacer que las secuencias de comandos, pero si no necesita la flexibilidad que proporcionaría un motor de secuencias de comandos, probablemente sea mucho más fácil de usar.

Mason Wheeler
fuente
1
De hecho, utilizamos algo como esto en nuestra aplicación web completamente no relacionada con el juego. El usuario tiene varios Estados, y cualquier número de Eventos puede activarse en código, muchos de los cuales están preestablecidos para la transición de usuarios de un Estado a otro. Creo que para los casos descritos de la pregunta, tener algún tipo de lenguaje de scripting rudimentario (o uno completo como Python / Lua) para definir condiciones / disparadores también sería útil.
Katana314
Me gusta mucho este enfoque. ¡Gracias! Lo investigaremos más a fondo. ¿Alguna posibilidad de que conozcas una biblioteca útil?
kaqqao
@veggen: No, lo siento. No es un desarrollador de Java.
Mason Wheeler
@MasonWheeler: ¿Qué opinas de Lázaro ?
Robert Harvey
1
Dado que esta pregunta llegó a la lista de preguntas populares hoy, informaré que implementé esto exactamente como dije en el comentario anterior. Hice un buen DSL e implementé la lógica FSM yo mismo, ya que es muy, muy simple. No podría estar más satisfecho con la solución. @MasonWheeler Gracias de nuevo por un gran consejo!
kaqqao
5

Creo que la respuesta está en el título: necesitas un motor de reglas. Si planea escribir su aplicación con Java, por supuesto, puede escribir la suya como sugirió Gilbert Le Blanc, O tal vez quiera echar un vistazo a Drools , un motor de reglas.

¿Qué opciones tiene un jugador para dar la situación y su estado actual?

De hecho, con Drools, o cualquier otro motor de reglas, puede definir una situación parametrizada que genere una lista de posibles acciones. Puede codificar reglas simples que suc tiene:

  • El jugador está en la página X:

    • opción 1: título: "ir a la izquierda", acción: "página45"
    • opción 2: título: "ir a la derecha", acción: "página56"
    • SI el jugador tiene el Bastón de bolas de fuego ENTONCES opción 3: título "lanzar bola de fuego", acción: "página32"
    • SI el jugador tiene una Habilidad de Percepción de 10 ENTONCES opción 4: título "revisar escritos en la pared", acción: "página67"

Lo interesante de Drools es que puedes codificar todas tus reglas en un archivo de Excel, y luego, al comienzo del juego, hacer que Drools lea ese archivo. Después de eso, todo está en la memoria, solo necesita preocuparse por su interfaz de usuario.

Aquí hay algunos recursos para ayudarlo a comenzar con Drools:

Jalayn
fuente
En general, busque el algoritmo Rete implementado en cualquier motor de reglas de su agrado.
Deer Hunter
Sí, Drools fue una de las cosas con las que comencé. Tengo que investigar un poco más para ver si puedo evaluar solo un paquete de reglas a la vez, ya que eso es bastante importante en mi caso. ¡Gracias!
kaqqao
@veggen encantado de ayudar!
Jalayn
2

Conceptualmente, tu juego es sencillo. En psudeocode, se vería así:

while not at end of adventure story
    display text
    get response

Ahora, encadenar todo el texto para que fluya de una acción a la siguiente es la parte difícil. Podrías usar una base de datos relacional. Podrías usar un árbol.

Es un poco difícil ser más específico sin saber qué lenguaje de computadora quieres usar. Como mencionó Java, me inclinaría más hacia una estructura de árbol.

Cree una clase de respuesta que contenga una respuesta y un enlace a una clase de texto.

Cree una clase de texto que contenga el texto de aventura y una Lista de respuestas como instancias de la clase de respuesta.

Editado para responder el comentario:

No calculas nada basado en este modelo. Usando su ejemplo, el árbol se vería así, donde T es el texto y A es una opción de acción:

T You stumble on a dead police officer
    A Take the gun
    T You hear footsteps
      A Run away
      A Hide and see who comes
    A Don't touch anything
    T You hear footsteps
      A Run away

Sí, hay cierta duplicación de texto, pero al seguir la cadena, las acciones futuras pueden tener en cuenta las decisiones pasadas. Es un gran árbol de decisiones.

Gilbert Le Blanc
fuente
Mi problema es calcular las posibles respuestas. Las decisiones pasadas influyen en las opciones actuales. Entonces, si un jugador presentado con "tropiezas con un oficial de policía muerto" elige "robar su pistola" en lugar de "no tocar nada", luego tiene la opción de "disparar al perseguidor" además de "huir como loco ", que habría sido la única opción si no hubieran adquirido previamente un arma.
kaqqao
@veggen: Vea la respuesta actualizada.
Gilbert Le Blanc