
Binding of Isaac e seu remake Binding Of Isaac: Rebirth são alguns dos meus jogos favoritos. Eles pertencem ao gênero roguelite twin stick shooter e são muito semelhantes ao Enter the Gungeon .
As masmorras geradas por esses jogos são especialmente famosas. Já vi inúmeros tutoriais na Internet sobre como criar a geração ao estilo Isaac, mas me perguntei como isso foi implementado no original. Para minha surpresa, a maioria dos tutoriais descreve o processo incorretamente. Neste artigo, falarei sobre como funciona a geração e mostrarei um exemplo disso em uma demonstração de Javascript.
Embora eu tivesse que descompilar e atualizar meu conhecimento empoeirado de Flash (uma vez eu escrevi meu próprio descompilador Actionscript), eu também tive muita sorte: o desenvolvedor IsaacFlorian Himsl e um dos principais desenvolvedores do Rebirth, Simon Parser , responderam alegremente às minhas perguntas. Na verdade, Florian até recentemente gravou um vídeo descrevendo o algoritmo. Em seu canal, você também pode conhecer os detalhes do desenvolvimento de seu novo jogo Squid Invaders.
Dada a presença de sua história, meu artigo pode ser considerado redundante, mas se você quiser detalhes sangrentos, continue lendo.
Algoritmo básico
Os desenvolvedores de Isaac foram fortemente inspirados pelos jogos 2D da série Zelda e geraram mapas semelhantes às masmorras.

É um conjunto de salas quadradas conectadas por bordas entre si. Algumas salas são especiais - há sempre uma loja




O jogo em si consiste em uma passagem linear de tais níveis, normalmente existem dois deles por "capítulo". No processo de passagem, os mapas tornam-se um pouco maiores e o conteúdo das salas muda, mas o algoritmo para criar sua estrutura, na verdade, permanece o mesmo todas as vezes.
A primeira versão de Isaac foi desenvolvida em menos de 3 meses, então Himslu teve que usar seu tempo de forma incrivelmente eficiente. O design fundamental do jogo é elegante e simples. Primeiro, uma planta baixa (nível) é gerada. Em seguida, alguns quartos são selecionados como especiais. Em seguida, o interior de cada quarto é selecionado da piscina correspondente.
Planta
Isaac é gerado em uma grade 9x8. Por conveniência, as células são denotadas por números - uns indicam a posição X, dezenas - a posição Y. Isso significa que você pode mover para cima, para baixo, para a esquerda e para a direita, simplesmente adicionando +10, -10, +1 e -1. As células com uma posição X igual a 0 não são usadas (sempre vazias), o que significa que a maior parte do código não precisa se preocupar com os limites do mapa. Ou seja, a célula superior esquerda no mapa é 01 e a inferior direita é 79.
A planta baixa apenas define quais células conterão quartos - o conteúdo do quarto é selecionado posteriormente.
Primeiro, a fórmula
random(2) + 5 + level * 2.6
determina o número de quartos. Essa. os níveis começam em 7 ou 8 quartos e aumentam em 2 ou 3 quartos a cada vez.
O jogo então coloca a sala inicial (célula 35) na fila. Em seguida, ele percorre a fila. Para cada célula na fila, ele percorre as 4 direções principais e faz o seguinte:
- Determina a célula adjacente adicionando + 10 / -10 / + 1 / -1 à célula atual.
- Se a célula adjacente já estiver ocupada, o jogo não fará nada.
- Se a própria célula vizinha tiver mais de um vizinho preenchido, o jogo não fará nada.
- Se já houver salas suficientes no nível, o jogo não fará nada.
- O jogo não faz nada com 50% de probabilidade.
- Caso contrário, o jogo marca a célula adjacente como contendo a sala e a adiciona à fila.
Se uma célula não adicionar uma sala a nenhuma das células adjacentes, ela será um beco sem saída e poderá ser adicionada à lista de salas de destino para uso posterior.
No caso de os mapas exigirem mais de 16 salas, a sala inicial é periodicamente enfileirada novamente para estimular o crescimento.
Uma vez que o algoritmo descrito acima começa com uma única sala e se expande para fora muitas vezes, é, na verdade, uma primeira exploração em amplitude. A restrição que não permite que um quarto seja adicionado se já houver dois vizinhos divide os quartos em corredores separados que nunca se juntam em loop.
A planta baixa é então verificada quanto à consistência. Ele deve conter o número necessário de salas, e a sala do chefe não deve estar localizada próxima à sala inicial. Caso contrário, a geração recomeça.
Salas especiais
Salas de chefe são colocadas lendo o último item da lista de salas finais. Pelo fato de a geração ser realizada como um crescimento externo, ela sempre será uma das salas localizadas mais afastadas da sala inicial.
Em seguida, a posição da sala secreta é indicada. Esses quartos são adicionados à planta baixa; eles são uma das poucas exceções à regra que proíbe a colocação de quartos próximos a vários já existentes. Na verdade, o algoritmo, ao contrário, prefere colocá-los assim. O gerador procura aleatoriamente por uma célula vazia próxima a pelo menos três salas e não perto de nenhuma das salas finais. Se ele não o encontrar após 300 tentativas, enfraquece ligeiramente o critério de pesquisa e, após 600 tentativas, enfraquece ainda mais. Esse procedimento garante que a sala secreta seja sempre colocada no nível, mas geralmente eles ficam espremidos perto de cruzamentos, o que significa que sempre há muitos quartos perto deles.
Quase todas as outras salas especiais estão localizadas em salas finais aleatórias. Alguns quartos são garantidos, outros têm uma pequena chance ou critério. Por exemplo, salas de sacrifício aparecem uma de sete vezes; se o jogador tiver saúde total, eles ocorrem cerca de uma em cada três vezes.
Salas normais
Os cômodos adjacentes sempre têm uma porta (ou parede quebrável) exatamente no centro, e cada cômodo foi projetado para ser acessível das quatro direções. Portanto, nenhuma consideração especial é necessária ao escolher os quartos - qualquer combinação servirá.
Os quartos são selecionados aleatoriamente da piscina. As informações sobre as salas contêm estruturas (fossas, fogo, pedras, etc.) e monstros. Ambos estão sujeitos a variações aleatórias, como o aparecimento de monstros campeões e lareiras vermelhas.
Para quartos regulares, há três piscinas: fácil, média e difícil. A primeira fase do capítulo escolhe entre as salas simples e médias e a segunda entre as médias e difíceis. O primeiro capítulo (Porão) contém 174 quartos comuns em piscinas. "Capítulos alternativos", como Cellar, que substitui aleatoriamente o Basement, têm um conjunto de quartos ligeiramente diferente.
Maldição do labirinto
Um dos recursos adicionais mais interessantes do código são os mapas de tamanho duplo. Eles são criados aleatoriamente e apenas para alguns modos de desafio. Além da óbvia duplicação do número de salas especiais e duas salas de chefe adjacentes, eles também têm muitos pequenos detalhes:
- 80% mais quartos normais (máximo de 45)
- Apenas as 6 salas da extremidade oposta são usadas para salas especiais
- Os níveis selecionam quartos em pools de quartos simples, médios e complexos.
- Salas normais adicionais são adicionadas aleatoriamente à planta baixa com lógica de colocação semelhante às salas secretas.
Demo
Criei um exemplo simplificado de um gerador em Javascript para que você possa experimentá-lo. O código completo pode ser encontrado aqui , e um exemplo prático pode ser encontrado no artigo original .

Renascimento

Binding of Isaac: Rebirth é um remake do Binding of Isaac original, criado por Nicalis , que na época era famoso por seus portos VVVVV e Cave Story . O jogo foi portado para C ++ e todos os sons e gráficos foram refeitos. Ao longo dos anos, o jogo recebeu muitos DLCs, adicionando novos itens e inimigos à já impressionante lista do original.
Embora Rebirth tenha um monte de inovações interessantes, a principal contribuição para a geração de níveis foi a adição de salas maiores e irregulares.

Com um conjunto completo de DLCs (no momento da redação deste artigo, este é Afterbirth +), o jogo tem 11 grandes salas: 2 × 2, 2 × 1, em forma de L e corredores estreitos em diferentes opções de rotação.

Sala típica em forma de L, três vezes o tamanho de uma sala normal. Ele foi implementado por Simon Parser através da modificação cuidadosa do código-fonte do Himsla.
Em vez de percorrer todas as direções, o algoritmo ignora todas as saídas da sala. Em uma sala 2x2, pode haver até oito deles.
Quando se trata de inserir uma sala, ele tenta inserir aleatoriamente uma sala grande. As verificações de vizinho ainda são aplicadas, mas apenas para a primeira cela próxima a ela fora da porta; no entanto, o algoritmo verifica se há espaço suficiente para o resto da sala. Isso significa que salas grandes podem criar loops de nível. Normalmente, duas grandes salas são geradas uma ao lado da outra e são complementadas por um par de portas que as conectam.
Se não houver espaço suficiente para uma sala, o algoritmo tenta inserir outro candidato. Se salas grandes forem inseridas com sucesso, há 95% de chance de serem removidas da piscina.
Ainda mais código é necessário para lidar com as grandes salas do chefe. Lembre-se de que as salas dos chefes estão sempre localizadas o mais longe possível da sala inicial. Se uma sala maior for desejada, o gerador substitui a sala individual desejada. Como as salas dos chefes são sempre becos sem saída, ao substituí-las, o algoritmo verifica se elas são adjacentes a algumas salas adicionais. Às vezes, a substituição ainda é impossível, então todos os pontos finais são verificados na distância máxima da sala inicial e, se eles não se encaixarem, o algoritmo desiste.
Para salas secretas, salas adjacentes na planta baixa são consideradas para posicionamento e salas são selecionadas apenas quando o algoritmo determina que as portas não são necessárias.

Em Isaac, os abismos geralmente são impossíveis de atravessar
Resultado
O Isaac Level Generator não é o mais complexo que já vi, mas apesar da pequena quantidade de código, ele funciona incrivelmente bem. É provavelmente por isso que tentam recriá-lo com tanta frequência. Sua simplicidade permite mudanças e extensões, como podemos ver no exemplo do Rebirth. Um resultado incrível.
Você também pode notar que este jogo continua a tendência de gerar plantas separadas dos detalhes dos quartos. Em meus artigos sobre Diablo 1 [ tradução para Habré] e Enter the Gungeon [ tradução para Habré], eu disse por que essa abordagem pode ser muito poderosa.
Ao descompilar o código, não encontrei nenhum detalhe particularmente interessante. A coisa mais interessante que posso dizer é que a localização da sala do tesouro é armazenada em uma variável chamada "boner" - provavelmente abreviação de Bonus Room. Também há sutilezas no código em relação aos efeitos colaterais menores de vários itens, mas deixarei esse tópico para os analisadores .
Depois, você pode assistir à série de vídeos de Himsla na parte interna do jogo, ou até mesmo jogar Isaac e ver todos os níveis ao vivo. Ouvi dizer que o novo DLC do Arrependimento será lançado este ano. Eu também recomendo jogar outros jogos do designer-chefe Edmund McMillen (especialmente Super Meat Boy).