@ agnasg

agnasg


La máquina de estados finitos que no existió

23-01-2023 5:36 PM

Este artefacto es un patrón en game programming, con el que se controla, entre otras cosas, el flujo de ejecución del juego en términos de las fases o etapas (llamados estados) que lo componen, y sus transiciones entre una y otra. La definición académica es:

“Una máquina de estados finitos es una estructura que permite definir comportamientos complejos. Facilita definir comportamientos complejos y encapsularlos en mini interacciones únicas que llamaremos estados. Cada estado debe describir una acción muy simple.”

Por ejemplo, en khpx (hasta ahora) he necesitado 3 niveles de control de flujo: el estado del juego (presentando la introducción, jugando, en el menú principal, dentro de un dungeon, etc). En los distintos estados de un dungeon (introducción, jugando, fase 1, fase2, game over, etc), y dentro de uno de estos estados, presentando un sprite, moviendo alrededor el sprite, haciendo fade in (lo cual puede requerir 2-3 etapas, etc).

La máquina de estados finitos (MEF) controla qué cosas puede y no puede hacer el jugador en cada etapa o fase del juego, y cuándo se deben activar cada tipo de eventos por fase del juego. Controla las distintas señales de los distintos componentes del juego que permiten cambiar de fase, activar un evento, cancelar otro, etc..

La máquina de estados finitos (MEF) es, en definitiva, un subsistema del juego, que permite programar en forma simple todo esto. Esa es la teoría. En juegos anteriores (antes de khpx) he implementado esto totalmente integrado al resto, en C o C++. A veces es buena idea que esta MEF tenga una interfase con un lenguaje scripting como python o LUA, lo cual va a facilitar el prototyping y configuración de estados, señales y eventos. En definitiva es un importante y crucial componente dentro del game loop.

Pero khpx no usa nada de eso.

Cuando comencé a programar el primer dungeon (“Mindworm”), lo hice completamente en C++, pensando que una vez completado podía reimplementarlo con el MEF y metascript (mi propio lenguaje interpretado tipo javascript pero no tan tarado, tan poderoso como python pero no tan, bueno eso, y más fácil que usar que Lua, porque si hay algo que no genera el resultado que espero, lo programo para que lo haga). Es decir, mi lenguaje de prototyping es, sí eso es correcto, es C++. Quedó tan bien, tan elegante y eficiente que ni en un millón de años lo voy a tocar para convertirlo en un indescifrable MEF y python y lua y no se qué cuernos. Así que en khpx, no hay máquinas de estados finitos, o, visto de otra forma, cada sección del juego que lo requiere tiene su propia MEF.

No es una arbitrariedad de mi parte, es la filosofía de diseño de khpx, tiene y debe ser absolutamente simple. Por otro lado, está programado en C++ sin clases + la standard template library. Las implementaciones de los MEF usualmente consisten en una clase con médodos que permiten registrar los estados, las transiciones, los eventos, las señales etc.. La máquina de estados finita del dungeon Mindworm es un vector de estados, y cada estado es basicamente una estructura con apuntadores a tres funciones: inicialización, actualización y rendering. La primera se ejecuta una vez, al comenzar un estado, las dos siguientes en cada game loop. El cambio de estado se ejecuta simplemente incrementando el índice en el vector de estados. Eso es todo. Debuguear aquello es tan simple como revisar las funciones, no hay nada más que revisar. De hecho, luego de 40 horas de trabajo, 575 líneas de código, y 32 estados diferentes, acumulé 0 bugs debido MEF (pseudo MEF). Claro que hubo bugs, pero fueron sprites desapareciendo y cosas por el estilo (so->sy debe ser incrementado con so->vy, no con so->sy. Por algo prefiero los nombres largos. Menos confusiones).

La MEF, el lenguaje de scripting, el engine de sprites, el editor de recursos del juego y el manejo del menú principal son cinco cosas que ya he implementado al menos 3 veces desde 0. Todo lo he hecho de diversas formas, siempre diferentes, casi sin reutilizar nada. Espero que con khpx sea la definitiva de y ahora en adelante pueda usar estos componentes en el futuro.