Generando mazmorras en The Binding of Isaac



Binding of Isaac y su remake Binding Of Isaac: Rebirth son algunos de mis juegos favoritos. Pertenecen al género roguelite de disparos de doble palo y son muy similares a Enter the Gungeon .



Las mazmorras generadas por estos juegos son especialmente famosas. He visto innumerables tutoriales en Internet sobre cómo crear una generación al estilo Isaac, pero me preguntaba cómo se implementó en el original. Para mi sorpresa, la mayoría de los tutoriales describen el proceso de forma incorrecta. En este artículo hablaré sobre cómo funciona la generación y mostraré un ejemplo en una demostración de Javascript.



Aunque tuve que descompilar y actualizar mi polvoriento conocimiento de Flash (una vez escribí mi propio descompilador de Actionscript), también tuve mucha suerte: el desarrollador IsaacFlorian Himsl y uno de los desarrolladores principales de Rebirth, Simon Parser , respondieron felizmente a mis preguntas. De hecho, Florian incluso recientemente grabó un video que describe el algoritmo. En su canal también podrás conocer los detalles del desarrollo de su nuevo juego Squid Invaders.



Dada la presencia de su historia, mi artículo puede considerarse redundante, pero si quieres detalles sangrientos, sigue leyendo.



Algoritmo basico



Los desarrolladores de Isaac se inspiraron en gran medida en los juegos 2D de la serie Zelda y generaron mapas similares a sus mazmorras.





Se trata de un conjunto de habitaciones cuadradas conectadas por bordes entre sí. Algunas habitaciones son especiales: siempre hay una tienda , una sala del tesoro y un jefe en cada piso ; Además, se seleccionan al azar varias otras habitaciones especiales. Excepto por la habitación secreta , no hay bucles en la mazmorra.



El juego en sí consiste en un pasaje lineal de dichos niveles, normalmente hay dos de ellos por "capítulo". En el proceso de aprobación, los mapas se vuelven un poco más grandes y el contenido de las habitaciones cambia, pero el algoritmo para crear su estructura, de hecho, sigue siendo el mismo cada vez.



La primera versión de Isaac se desarrolló en menos de 3 meses, por lo que Himslu tuvo que usar su tiempo de manera increíblemente eficiente. El diseño fundamental del juego es elegante y simple. Primero, se genera un plano de planta (nivel). Luego, algunas habitaciones se seleccionan como especiales. Luego, el interior de cada habitación se selecciona de la piscina correspondiente.



Planta baja



Isaac se genera en una cuadrícula de 9x8. Por conveniencia, las celdas se indican con números: los unos indican la posición X, decenas, la posición Y. Esto significa que puede moverse hacia arriba, abajo, izquierda y derecha, simplemente agregando +10, -10, +1 y -1. Las celdas con una posición X de 0 no se utilizan (siempre están vacías), lo que significa que la mayor parte del código no necesita preocuparse por los límites del mapa. Es decir, la celda superior izquierda del mapa es 01 y la parte inferior derecha 79.



El plano de planta solo define qué celdas contendrán habitaciones; el contenido de la habitación se selecciona más adelante.



Primero, la fórmula random(2) + 5 + level * 2.6determina el número de habitaciones. Aquellos. los niveles comienzan en 7 u 8 habitaciones y aumentan en 2 o 3 habitaciones cada vez.



Luego, el juego coloca la sala de inicio (celda 35) en la cola. Luego, cíclicamente pasa por alto la cola. Para cada celda de la cola, recorre las 4 direcciones principales y hace lo siguiente:



  • Determina la celda adyacente agregando + 10 / -10 / + 1 / -1 a la celda actual.
  • Si la celda adyacente ya está ocupada, el juego no hace nada.
  • Si la celda vecina tiene más de un vecino lleno, el juego no hace nada.
  • Si ya hay suficientes habitaciones en el nivel, el juego no hace nada.
  • El juego no hace nada con un 50% de probabilidad.
  • De lo contrario, el juego marca la celda adyacente como que contiene la habitación y la agrega a la cola.


Si una celda no agrega una habitación a ninguna de las celdas adyacentes, entonces es un callejón sin salida y se puede agregar a la lista de habitaciones de destino para su uso posterior.



En caso de que los mapas requieran más de 16 habitaciones, la sala inicial se vuelve a poner en cola periódicamente para estimular el crecimiento.



Dado que el algoritmo descrito anteriormente comienza con una sola habitación y se expande hacia afuera muchas veces, es esencialmente una primera exploración amplia. La restricción que no permite agregar una habitación si ya hay dos vecinos divide las habitaciones en pasillos separados que nunca se unen en bucles.



A continuación, se comprueba la coherencia del plano de planta. Debe contener el número requerido de habitaciones, y la sala del jefe no debe estar ubicada al lado de la sala de inicio. De lo contrario, la generación comienza de nuevo.



Habitaciones especiales



Las salas de jefe se colocan leyendo el último elemento de la lista de salas finales. Debido a que la generación se realiza como un crecimiento hacia el exterior, esta siempre será una de las salas ubicadas a mayor distancia de la sala de inicio.



Entonces se indica la posición de la habitación secreta. Estas habitaciones se agregan al plano de planta; son una de las pocas excepciones a la regla que prohíbe colocar habitaciones junto a varias existentes. De hecho, el algoritmo, por el contrario, prefiere colocarlos así. El generador busca aleatoriamente una celda vacía junto a al menos tres habitaciones y no cerca de ninguna de las habitaciones finales. Si no lo encuentra después de 300 intentos, debilita ligeramente el criterio de búsqueda y después de 600 intentos lo debilita aún más. Este procedimiento garantiza que la habitación secreta siempre se coloque en el nivel, pero generalmente se aprietan cerca de las intersecciones, lo que significa que siempre hay muchas habitaciones cerca de ellas.



Casi todas las demás habitaciones especiales están ubicadas en habitaciones finales aleatorias. Algunas habitaciones están garantizadas, otras tienen una pequeña posibilidad o criterio. Por ejemplo, las salas de sacrificio aparecen una de siete veces; si el jugador tiene plena salud, entonces ocurren aproximadamente una de cada tres veces.



Habitaciones regulares



Las habitaciones adyacentes siempre tienen una puerta (o pared rompible) exactamente en el centro, y cada habitación está diseñada para ser accesible desde las cuatro direcciones. Por lo tanto, no se requieren consideraciones especiales al elegir las habitaciones; cualquier combinación servirá.



Las habitaciones se seleccionan al azar de la piscina. La información sobre las habitaciones contiene tanto estructuras (pozos, fuego, piedras, etc.) como monstruos. Ambos están sujetos a variaciones aleatorias, como la aparición de monstruos campeones y chimeneas rojas.



Para las habitaciones normales, hay tres grupos: fácil, medio y difícil. La primera etapa del capítulo elige entre salas simples y medianas, y la segunda entre medianas y difíciles. El primer capítulo (Sótano) contiene 174 habitaciones ordinarias en piscinas. Los "capítulos alternativos" como el sótano, que reemplaza al sótano al azar, tienen un conjunto de habitaciones ligeramente diferente.



Maldición del laberinto



Una de las características adicionales más interesantes del código son los mapas de doble tamaño. Se crean de forma aleatoria y solo para algunos modos de desafío. Además de la obvia duplicación del número de salas especiales y dos salas de jefe adyacentes, también tienen muchos pequeños detalles:



  • 80% más habitaciones normales (máximo 45)
  • Para salas especiales, solo se utilizan las 6 salas del extremo
  • Los niveles seleccionan habitaciones de grupos de habitaciones simples, medianas y complejas.
  • Las habitaciones normales adicionales se agregan aleatoriamente al plano de planta con una lógica de ubicación similar a las habitaciones secretas.


Manifestación



Creé un ejemplo simplificado de un generador en Javascript para que puedas experimentar con él. El código completo se puede encontrar aquí y un ejemplo de trabajo se puede encontrar en el artículo original .





Renacimiento





Binding of Isaac: Rebirth es una nueva versión del Binding of Isaac original, creado por Nicalis , que en ese momento era famoso por sus versiones VVVVV y Cave Story . El juego fue portado a C ++ y todos los sonidos y gráficos fueron rehechos. A lo largo de los años, el juego ha recibido muchos DLC, agregando nuevos elementos y enemigos a la ya impresionante lista del original.



Si bien Rebirth tiene un montón de innovaciones interesantes, la principal contribución a la generación de niveles fue la adición de salas irregulares más grandes.





Con un conjunto completo de DLC (en el momento de escribir este artículo, esto es Afterbirth +), el juego tiene 11 salas grandes: 2 × 2, 2 × 1, en forma de L y pasillos estrechos en diferentes opciones de rotación.





Habitación típica en forma de L, tres veces el tamaño de una habitación normal. Fue implementado por Simon Parser mediante una cuidadosa modificación del código fuente de Himsla.



En lugar de recorrer todas las direcciones, el algoritmo omite todas las salidas de la habitación. En una habitación de 2x2, puede haber hasta ocho de ellos.



Cuando se trata de insertar una habitación, intenta insertar aleatoriamente una habitación grande. Los controles de vecinos se siguen aplicando, pero solo en la primera celda junto a la puerta; sin embargo, el algoritmo comprueba si hay suficiente espacio para el resto de la habitación. Esto significa que las habitaciones grandes pueden crear bucles de nivel. Por lo general, se generan dos habitaciones grandes una al lado de la otra y se complementan con un par de puertas que las conectan.



Si no hay suficiente espacio para una habitación, el algoritmo intenta insertar otro candidato. Si las habitaciones grandes se insertan correctamente, existe un 95% de posibilidades de que se eliminen del grupo.



Se necesita aún más código para manejar las grandes salas de jefes. Recuerda que las salas de jefe siempre están ubicadas lo más lejos posible de la sala de inicio. Si se desea una habitación más grande, el generador reemplaza la habitación individual prevista. Dado que las salas de los jefes siempre son callejones sin salida, cuando se reemplazan, el algoritmo verifica si están adyacentes a algunas salas adicionales. A veces, el reemplazo sigue siendo imposible, por lo que todos los puntos finales se verifican a la distancia máxima desde la sala de inicio y, si no encajan, el algoritmo se da por vencido.



Para las habitaciones secretas, las habitaciones contiguas en el plano de planta se consideran para la ubicación y las habitaciones se seleccionan solo cuando el algoritmo determina que no se necesitan puertas.





En Isaac, los abismos suelen ser imposibles de cruzar



Salida



Isaac Level Generator no es el más complejo que he visto, pero a pesar de una cantidad tan pequeña de código, funciona increíblemente bien. Probablemente por eso intentan recrearlo con tanta frecuencia. Su sencillez permite cambios y ampliaciones, como podemos ver en el ejemplo de Rebirth. Un resultado increible.



También puede notar que este juego continúa la tendencia de generar planos de planta por separado de los detalles de la habitación. En mis artículos sobre Diablo 1 [ traducción a Habré] y Enter the Gungeon [ traducción a Habré], dije por qué este enfoque puede ser muy poderoso.



Al descompilar el código, no encontré ningún detalle particularmente interesante. Lo más interesante que puedo decir es que la ubicación de la sala del tesoro se almacena en una variable llamada "boner", probablemente la abreviatura de Bonus Room. También hay sutilezas en el código con respecto a los efectos secundarios menores de varios elementos, pero dejaré este tema a los analizadores .



Luego puedes ver la serie de videos de Himsla sobre los aspectos internos del juego, o incluso jugar a Isaac y ver todos los niveles en vivo. Escuché que el nuevo DLC de Arrepentimiento saldrá este año. También recomiendo jugar a otros juegos del diseñador jefe Edmund McMillen (especialmente Super Meat Boy).



All Articles