Avalanche
Puzzle · Unity · C#
- Meu papel Programação e design de mecânicas
- Equipe 3 pessoas
- Contexto Projeto acadêmico
- Engine Unity
- Código GitHub
Jogar agora
Clique no jogo para ativar o teclado. Setas para mover e girar, Espaço para queda rápida, C para guardar a peça, Esc para pausar. O botão de tela cheia fica no canto do jogo.
Não carregou? Abra direto no itch.io.
O jogo
Avalanche é o Tetris reconstruído do zero e depois quebrado de propósito. Sobre as regras normais correm três sistemas que disputam o tabuleiro com o jogador.
Os blocos de aço aparecem no meio das peças e não podem ser eliminados: uma linha não se completa enquanto houver aço nela. Eles entopem colunas e vão subindo.
Os blocos de runa são a resposta. Ao pousar, disparam um feixe pela coluna inteira e convertem todo o aço que encontram. Quanto mais aço estiver preso no tabuleiro, maior a chance de uma runa aparecer — a dificuldade e o alívio crescem juntos.
E a avalanche, que dá nome ao jogo: de tempos em tempos, uma fileira inteira despenca sobre o tabuleiro. Um contador na tela avisa quando vai acontecer, mas nunca o que vem junto — se o tabuleiro estiver travado demais, a avalanche inteira vem feita de runas.
A tecla C guarda a peça atual para usar depois. Guardar uma runa e escolher a hora de gastá-la acabou sendo a decisão mais interessante do jogo, e não estava no plano: apareceu sozinha quando duas mecânicas independentes se encontraram.
O que foi meu
Tudo menos a arte. Programação, máquina de estados das animações, sistema de pontuação, tela de loading e o desenho das mecânicas.
A equipe fez as artes dos blocos, o plano de fundo e as animações.
Reconstruir o Tetris sem olhar a resposta
Eu podia ter procurado como o Tetris é implementado. Preferi jogar bastante e deduzir as regras a partir do que via na tela.
Isso me custou caro em alguns pontos, e a rotação das peças foi o mais caro de todos: encostado na parede, girar simplesmente não funcionava. Depois descobri que o problema tem nome e solução conhecida — o sistema oficial usa wall kicks, testando alguns deslocamentos quando a rotação esbarraria numa parede, e aceitando o primeiro que couber.
Hoje o jogo tem wall kicks. Fazer do zero foi mais lento, mas me obrigou a entender por que cada regra existe, em vez de copiar um comportamento pronto e não saber o que ele resolve.
A mecânica que fazia o oposto do que devia
O bloco de aço nasceu para atrapalhar: indestrutível até uma runa convertê-lo de volta.
Só que a função que decidia se uma linha estava completa verificava uma coisa só — se todas as dez casas estavam ocupadas. Nunca perguntava o que ocupava cada casa. Então a linha com aço se completava normalmente, sumia, e o bloco de aço continuava ali. Na prática, aquela coluna passava a precisar de uma peça a menos. O obstáculo tinha virado presente.
A correção é uma linha: a verificação passa a devolver "não está cheia" assim que encontra aço.
E aí apareceu o segundo bug, mais interessante. Quando a runa converte o aço, o componente que marca o bloco como metálico é removido — mas na Unity, remover um componente não acontece na hora: fica agendado para o fim do quadro. No mesmo quadro em que a runa limpava a coluna, a linha ainda se considerava bloqueada por um aço que, para todos os efeitos, já não existia.
A solução foi desligar o componente antes de mandar removê-lo, e fazer a verificação perguntar se ele está ligado em vez de perguntar se ele existe. Desligar é imediato; remover é agendado. É uma distinção que eu não fazia antes desse bug, e que passei a enxergar em todo lugar depois dele.