Blog de Metlivi

Cómo mantener testeables las historias ramificadas de videojuegos

A medida que una historia ramificada crece, testea las decisiones y los cambios de estado que hacen que las rutas se comporten de forma distinta, en lugar de tratar cada recorrido posible como un script independiente de principio a fin. Modela la narrativa como un grafo, define las condiciones y los resultados de cada decisión, y construye una suite compacta que cubra las transiciones críticas, los puntos de convergencia y los fallos. Luego, utiliza un muestreo de rutas basado en el riesgo y playtests con personas para detectar problemas que las verificaciones estructuradas no pueden evaluar. Esto ofrece a los diseñadores narrativos y a los equipos de control de calidad una forma reproducible de encontrar defectos sin pretender una cobertura exhaustiva de rutas.

27 de septiembre de 20267 min de lecturaLectura, arte y culturaPor Metlivi Editorial Team
Sección 1

Empieza con un grafo que registre el comportamiento

Representa cada pasaje o escena jugable como un nodo y cada elección como una arista dirigida. Añade anotaciones a las aristas con sus condiciones y efectos: por ejemplo, `has_key = true` habilita “Abrir la verja”, lo que establece `gate_open = true`. Marca explícitamente los finales, los bucles y los puntos de convergencia (rejoin points). Un punto de convergencia es donde se vuelven a unir rutas distintas; es un lugar muy útil para comprobar que la historia puede continuar a partir de múltiples historiales sin arrastrar un estado no deseado.

El grafo debe reflejar lo que el juego evalúa realmente, no solo la estructura de la prosa. Registra qué variables lee una elección, cuáles escribe y qué nodos posteriores dependen de ellas. Incluye valores predeterminados, reglas de reinicio y cualquier efecto de un solo uso. Si se activa un flag en una rama y nunca se limpia, puede que sea intencionado; documentarlo hace que la consecuencia sea visible para su revisión y prueba.

Esta estructura también ayuda a localizar puntos de decisión que son fáciles de pasar por alto en un guión extenso. Un artículo de 2024 de Alexey Tikhonov estudia la detección de puntos de decisión de personajes en narrativas ramificadas y propone un conjunto de datos basado en grafos de juegos de Elige tu propia aventura. Su tarea se centra en identificar puntos de decisión narrativos, no en validar un método de control de calidad; puede servir de referencia sobre cómo los equipos inventarían las opciones, pero no demuestra que el enfoque de pruebas aquí expuesto sea efectivo. [Tikhonov, “Branching Narratives: Character Decision Points Detection”](https://aclanthology.org/2024.games-1.8/)

Sección 2

Testea las transiciones de estado, no solo las visitas a escenas

Una prueba que solo confirma que apareció un nodo puede pasar por alto una elección defectuosa. Para cada elección importante, verifica tres cosas: si la opción está disponible bajo la condición prevista, si seleccionarla aplica el cambio de estado esperado y si el siguiente nodo y el resultado visible coinciden con ese estado. Estas comprobaciones tratan la historia como un sistema de transición de estados: dado un estado inicial y una acción, se verifica el estado resultante y el destino.

Por ejemplo, una prueba para la elección “Mostrar el mapa” podría asegurar que el mapa se muestra, que `trust` se mantiene sin cambios y que la ruta llega a la escena compartida del observatorio. Una prueba emparejada comienza con `has_map = false` y asegura que esta opción no está disponible o sigue la alternativa especificada. El comportamiento exacto esperado depende de la especificación narrativa; lo fundamental es asertarlo explícitamente en lugar de deducir que es correcto a partir del título de un pasaje.

En los puntos de convergencia, testea más allá de la simple llegada. Compara el estado que cada ruta debe conservar, cambiar o descartar. Un guardia al que se convenció en una rama podría seguir siendo un aliado tras la reunión, mientras que un disfraz temporal debería caducar. Haz que esas reglas formen parte del estado posterior a la convergencia esperado. Si las rutas deben converger por completo, aserta el estado compartido; si deben conservar diferencias significativas, aserta también esas diferencias.

Sección 3

Usa un ejemplo ficticio para visibilizar la cobertura

Supongamos que un misterio breve incluye una decisión en el archivo. El jugador puede pedir ayuda, entrar a hurtadillas o usar una llave prestada; cada ruta llega al mismo pasillo, y luego una elección posterior determina si el jugador se lleva una carta sellada. La siguiente matriz ficticia rastrea un conjunto compacto de obligaciones de prueba. “Cubierto” significa que se ha planificado una prueba para la obligación específica, no que se haya probado toda la ruta o cada combinación posible.

**A:** `trust = high`; pedir ayuda al archivero. Aparece la opción de ayuda; `trust` se mantiene alto; la ruta llega al pasillo. Disponibilidad de elección y transición

**B:** `trust = low`; pedir ayuda. La opción de ayuda está oculta o se rechaza, según lo especificado. Condición negativa

**C:** `has_key = true`; abrir la puerta lateral. La puerta se abre; la ruta llega al pasillo; la llave se consume solo si se ha especificado. Efecto de estado y convergencia

**D:** `has_key = false`; intentar abrir la puerta lateral. La puerta no se puede abrir; no se activa ningún flag de éxito. Aserción negativa

**E:** Desde el pasillo, coger la carta sellada. `has_letter = true`; la escena posterior de pruebas ofrece la línea de diálogo específica de la carta. Resultado derivado

**F:** Desde el pasillo, dejar la carta. `has_letter = false`; la línea de diálogo específica de la carta no aparece. Contraste de resultados y aserción negativa

Esta matriz es una ayuda para la toma de decisiones, no un porcentaje de cobertura ni una suite mínima universal. Hace visibles las omisiones: aquí, el filtro de baja confianza y el resultado de “carta ausente” merecen sus propias comprobaciones porque una visita por el camino feliz (happy path) no las verificaría. Cada fila debe apuntar al nodo o transición relevante en el grafo para que cualquier condición modificada pueda rastrearse hasta las pruebas afectadas.

Sección 4

Prioriza la cobertura de ramas cuando las combinaciones aumenten

Si una historia tiene muchos flags independientes, el número de combinaciones posibles puede dispararse con rapidez. No respondas a esto listando cada ruta teórica como una partida completa obligatoria. Primero identifica las aristas de alto riesgo: elecciones que condicionan finales, consumen objetos, establecen hechos persistentes de una relación o fusionan historiales. Testea directamente esas transiciones y sus resultados derivados importantes.

Luego, muestrea combinaciones de forma deliberada. Incluye condiciones límite (el valor mínimo que modifica una elección), ambos lados de cada condición crítica, combinaciones representativas de flags que puedan interactuar entre sí y rutas que alcancen un punto de convergencia a través de historiales diferentes. Prioriza los cambios recientes y los caminos con prerrequisitos complejos. Cuando dos variables puedan interactuar, añade una prueba para ese par en lugar de asumir que verificaciones individuales por separado demuestran que la combinación funciona.

Registra la unidad de cobertura y sus límites. Un equipo puede monitorizar si se ejercitó cada arista de elección crítica, si cada condición se comprobó tanto en verdadero como en falso cuando correspondía y si al menos una prueba diseñada alcanzó cada desencadenante de final. Esos son informes útiles sobre lo que se ha muestreado; ninguno demuestra que se hayan explorado todos los historiales posibles, combinaciones de estados o problemas de redacción.

La investigación sobre playtesting en videojuegos puede aportar una idea relacionada pero acotada. El artículo de arXiv de 2021 de Gordillo y colaboradores describe agentes de aprendizaje por refuerzo recompensados por realizar acciones novedosas para explorar la cobertura de estados en un escenario complejo en 3D. Ese trabajo se centra en la exploración en un entorno de juego 3D, no en elecciones narrativas ramificadas ni en el método específico de pruebas de transición descrito aquí. Respalda considerar la exploración automatizada como un posible complemento, pero ni ese estudio ni el de Tikhonov validan este método exacto de pruebas narrativas. [Gordillo et al., “Improving Playtesting Coverage via Curiosity Driven Reinforcement Learning Agents”](https://arxiv.org/abs/2103.13798)

Sección 5

Añade aserciones negativas y playtests con personas

Las aserciones positivas confirman que la opción o el resultado esperado existen. Las aserciones negativas confirman que no ocurre algo prohibido: una opción bloqueada no aparece, una pista ya consumida no se concede por segunda vez, una carta ausente no activa su línea de diálogo correspondiente o un intento fallido no activa un flag de éxito. Las comprobaciones negativas resultan especialmente útiles en torno a nodos compartidos, donde el estado residual de otra ruta puede filtrarse a la escena actual.

Las comprobaciones automatizadas pueden verificar la lógica de rutas y los cambios de estado exactos, pero no juzgan con fiabilidad si una transición se siente coherente, si una línea de texto contradice lo que el jugador recuerda o si una elección es comprensible en su contexto. Por tanto, los playtests humanos deben utilizar rutas seleccionadas con un propósito concreto: pedir a los testers que sigan una rama menos común, que lleguen a una convergencia con un historial particular o que intenten alcanzar un final sin una llave necesaria. Observa tanto el estado resultante como la interpretación que hace el jugador.

Mantén las notas del playtest vinculadas a los identificadores de nodos y elecciones, además del estado inicial y los pasos seguidos. Esto hace que cualquier problema reportado sea reproducible y ayuda a distinguir una duda de redacción de un fallo de lógica. Tras una corrección, vuelve a ejecutar las pruebas de transición afectadas y al menos una ruta representativa a través de la convergencia o el resultado modificado.

Sección 6

Un ciclo de prueba práctico para una historia en evolución

Con cada actualización de la historia, exporta o revisa el grafo, identifica los nodos, condiciones, efectos y puntos de convergencia que hayan cambiado, y luego actualiza la matriz de cobertura. Ejecuta primero pruebas focalizadas de transición de estado; continúa con muestras de rutas seleccionadas y playtests con personas para las secciones de alto impacto o modificadas recientemente. Cuando aparezca un fallo, registra el estado inicial y la secuencia de elecciones para que el equipo pueda reproducirlo, corregir la regla o el pasaje correspondiente y conservar el caso como una prueba de regresión.

El objetivo es contar con un registro comprobable de qué se ha verificado y por qué. Un grafo hace que la estructura sea inspeccionable, las pruebas de transición hacen explícita la lógica, el muestreo de ramas orienta el esfuerzo hacia variaciones significativas, las aserciones negativas detectan estados residuales no deseados y los playtests humanos evalúan la interpretación. En conjunto, proporcionan una cobertura útil a medida que las rutas se multiplican, manteniendo al mismo tiempo un límite claro sobre lo que queda sin probar.

Lecturas relacionadas

Sigue explorando este tema