- Rust 95.5%
- Shell 4.5%
|
Some checks failed
ci/woodpecker/push/pipelines/1 Pipeline was successful
ci/woodpecker/push/pipelines/2 Pipeline was successful
CI / Test Suite (push) Has been cancelled
CI / Test Suite-1 (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Clippy-1 (push) Has been cancelled
CI / Rustfmt (push) Has been cancelled
CI / Rustfmt-1 (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Build-1 (push) Has been cancelled
`.githooks/pre-commit` executa aqui o que o Woodpecker executa no servidor: lint do proprio pipeline, `cargo fmt --check`, clippy com `-D warnings`, build e testes. Ele e gerado a partir do `.woodpecker/pipelines.yml` deste repositorio, entao os dois nao podem divergir -- mudou o piso de cobertura no pipeline, regera-se o hook. As etapas caras (cobertura, auditoria, mutacao, a perna MSRV) ficam atras de `PRE_COMMIT_COMPLETO=1`. Pedi-las a cada commit e pedir que o hook seja desligado; elas sao para antes do push. O lint do pipeline entrou por experiencia recente: um `: ` sem aspas num `echo` fazia o YAML virar mapa e o Woodpecker recusava o arquivo inteiro, sem que ninguem percebesse que o CI nunca rodava. Ativacao, uma vez por clone: `git config core.hooksPath .githooks`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PhdPjHUuVhXaitwT4mG53t |
||
|---|---|---|
| .cargo | ||
| .githooks | ||
| .github/workflows | ||
| .woodpecker | ||
| assets/sounds | ||
| src | ||
| tests | ||
| .gitignore | ||
| .mutants-teto | ||
| AUDIO_SETUP.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
Rogue - Dungeon Crawler em ASCII
Um clone didático do clássico jogo Rogue, implementado em Rust com macroquad.
🎮 Sobre o Jogo
Rogue é um dungeon crawler roguelike clássico onde você explora dungeons geradas proceduralmente, enfrenta monstros, coleta tesouros e procura o lendário Amuleto de Yendor.
Características
- ✨ Geração Procedural: Cada dungeon é única, gerada com algoritmo de salas e corredores
- 🎯 3 Níveis: Dificuldade crescente com monstros mais fortes
- ⚔️ Sistema de Combate: Combate baseado em turnos com ataque e defesa
- 🗝️ Portas Secretas: Descubra passagens ocultas
- 🚪 Portas de Teleporte: Todas as portas (+) são portais que teleportam você para outras áreas!
- 💣 Armadilhas: Cuidado onde pisa!
- 💰 Tesouros: Ouro, poções, armas e armaduras
- 📈 Sistema de Progressão: Ganhe XP e suba de nível
- 📊 Estatísticas: Rastreamento completo de monstros mortos, tesouros coletados e equipamentos
- 🏆 Tela de Vitória: Veja suas estatísticas e créditos ao vencer o jogo
- 🎬 Créditos Animados: Créditos finais em estilo cinematográfico
- 🎨 Arte ASCII: Visual clássico roguelike
- 🔊 Suporte a Áudio: Sistema preparado para efeitos sonoros (veja AUDIO_SETUP.md)
🎯 Objetivo
Desça pelos 3 níveis da dungeon e encontre o Amuleto de Yendor (") para vencer!
Ao pegar o Amuleto, você verá:
-
📊 Tela de Estatísticas: Suas conquistas da jornada
- Monstros mortos
- Tesouros coletados
- Equipamentos encontrados
- Ouro acumulado
- Nível final alcançado
- Dano causado e recebido
-
🎬 Créditos Cinematográficos: Pressione ESPAÇO para ver os créditos descendo como em filmes!
🕹️ Controles
- W/A/S/D ou Setas: Mover
- H: Mostrar legenda do jogo
- ESPAÇO: Avançar para créditos (na tela de vitória)
- R: Reiniciar jogo
- Q/ESC: Sair do jogo
🗺️ Símbolos do Mapa
Terreno
#- Parede.- Chão+- Porta>- Escadas (próximo nível)^- Armadilha (quando revelada)
Entidades
@- Você (o herói)r- Rato (fraco)g- Goblin (médio)o- Orc (forte)T- Troll (muito forte)D- Dragão (boss)
Itens
$- Ouro!- Poção de cura)- Arma (aumenta ataque)]- Armadura (aumenta defesa)"- Amuleto de Yendor (objetivo!)
🏗️ Arquitetura do Código
O projeto está organizado de forma modular e didática:
Módulos
map.rs - Geração de Dungeons
- Algoritmo: Salas e corredores (rooms and corridors)
- Processo:
- Gera salas aleatórias sem sobreposição
- Conecta salas com corredores em L
- Adiciona portas, armadilhas e portas secretas
Conceitos-chave:
- Room: Estrutura retangular com posição e dimensões
- Tile: Enum representando tipos de terreno
- Map::generate(): Método principal de geração procedural
entities.rs - Jogador, Monstros e Itens
- Player: HP, ataque, defesa, XP, level
- Monster: Diferentes tipos com stats balanceados
- Item: Tesouros e equipamentos
Conceitos-chave:
- Position: Sistema de coordenadas
- MonsterType::for_level(): Spawna monstros apropriados
- Item::apply(): Aplica efeitos ao jogador
game.rs - Lógica Principal
- Gerenciamento de estado: Playing, Victory, Defeat
- Sistema de turnos: Jogador move → Monstros agem
- Combate: Damage = Ataque - Defesa (mínimo 1)
- Interações: Portas, armadilhas, itens, escadas
Conceitos-chave:
- Game::move_player(): Processa movimento e interações
- Game::monster_turn(): IA dos monstros
- Game::generate_level(): Cria novo nível
render.rs - Renderização ASCII
- Macroquad: Biblioteca para desenhar texto como gráficos
- Sistema de cores: Diferentes cores para diferentes elementos
- UI: Stats do jogador, mensagens, controles
Conceitos-chave:
- Renderer::draw_char(): Desenha caractere ASCII na grid
- Colors: Paleta de cores para elementos
- window_config(): Configuração da janela
main.rs - Loop Principal
- Game Loop: Input → Update → Render
- Async: Usa macroquad::main macro
- Input Handling: Processa teclas WASD/Arrow
🧪 Testes
Quatro camadas, cada uma respondendo a uma pergunta diferente.
cargo test # todas: 102 testes
cargo test --lib # unidade — as regras, uma a uma
cargo test --test integration_tests # integração — partidas inteiras
cargo test --test spider # propriedade — varre o espaço de entradas
cargo test --test mutantes # travas nascidas do cargo-mutants
Unidade (src/*.rs)
Vivem ao lado do código que testam, dentro de #[cfg(test)] mod tests.
Cobrem cada regra isolada: intersecção de salas, dano e cura, level up,
o Cow do cache de mensagens, o Deref do HitPoints, o pool de
objetos com Arc<Mutex<_>>.
Integração (tests/integration_tests.rs)
Montam um Game de verdade e jogam. Uma partida de 500 comandos que
cobra estado coerente do começo ao fim; descer os três níveis até o
fundo; matar um monstro e receber o XP; pisar na armadilha e conferir
que ela não dispara duas vezes; pegar o Amuleto e vencer.
Propriedade (tests/spider/)
Em vez de fixar casos, varrem o espaço de entradas com proptest e
cobram invariantes. Isso importa especialmente aqui porque a dungeon é
gerada por sorteio: um teste de exemplo só consegue olhar o mapa que
ele mesmo montou. As propriedades valem para qualquer mapa que o gerador
produza — toda dungeon é jogável, nenhuma sala vaza para fora, toda
porta leva a uma casa caminhável, perseguir sempre alcança o alvo.
Mutação (tests/mutantes/ + cargo mutants)
Cobertura diz que a linha executou. Mutação diz se alguém conferiu o resultado. A ferramenta injeta um defeito de cada vez e roda a suíte; se ela continua verde, aquele defeito é invisível.
cargo mutants # tem de ficar dentro do teto em .mutants-teto
Foi assim que se descobriu que, mesmo com 93% de cobertura, dava para
trocar o nome de todo monstro por "xyzzy" ou achatar os atributos de
todos em (1, 1, 1, 1) sem quebrar nada — as asserções perguntavam se
os valores eram positivos, não se eram os certos.
O teto de sobreviventes fica em .mutants-teto, versionado, e só pode
cair: quem abrir um buraco novo quebra o build.
🚀 Como Executar
Pré-requisitos
- Rust 1.70+ (https://rustup.rs/)
Compilar e Executar
# Clone o repositório
git clone <repo-url>
cd rogue
# Executar em modo debug
cargo run
# Executar em modo release (mais rápido)
cargo run --release
📚 Aprendendo com o Código
Este projeto é didático e demonstra:
1. Geração Procedural
- Como criar dungeons aleatórias mas jogáveis
- Algoritmo de salas e corredores
- Validação de conectividade
2. Game Design
- Sistema de combate balanceado
- Curva de dificuldade (3 níveis)
- Feedback ao jogador (mensagens coloridas)
3. Padrões Rust
- Ownership e borrowing
- Enums para tipos de entidades
- Pattern matching
- Testes unitários
4. Arquitetura de Jogos
- Separação de responsabilidades (MVC-like)
- Game loop assíncrono
- Sistema de entidades
5. Macroquad
- Renderização de texto
- Input handling
- Window configuration
🎓 Conceitos de Roguelike
Geração Procedural
Cada partida é única! O mapa é gerado aleatoriamente usando:
- Criação de salas sem sobreposição
- Corredores conectando salas adjacentes
- Distribuição aleatória de itens e monstros
Permadeath
Quando você morre, recomeça do zero. Sem saves!
Sistema de Turnos
O jogo espera sua ação. Pense antes de agir!
Exploração
Descubra portas secretas explorando as paredes.
🔊 Adicionar Efeitos Sonoros (Opcional)
O jogo está preparado para suportar efeitos sonoros! Para adicionar áudio:
- Siga as instruções no arquivo
AUDIO_SETUP.md - Baixe sons gratuitos de licença CC0 dos sites recomendados
- Coloque os arquivos na pasta
assets/sounds/ - Descomente o código no arquivo
src/audio.rs - Descomente a dependência
quad-sndnoCargo.toml
Sons suportados:
- 🗡️ Ataque a monstros
- 💀 Morte de monstros
- 💰 Coletar itens/tesouros
- 🚪 Teleporte por portas
- ❤️ Receber dano
- 🏆 Vitória
🔧 Melhorias Futuras
Ideias para expandir o jogo:
- Field of View (FOV) - Fog of war
- Inventário completo
- Mais tipos de itens (scrolls, wands)
- Mais monstros e comportamentos de IA
- Salas especiais (tesouros, boss rooms)
- Sistema de fome
- Identificação de itens
- Salvar/carregar jogo
- Sistema de estatísticas do jogador
- Tela de vitória com estatísticas
- Créditos animados
- Sistema de portas de teleporte
- Estrutura para efeitos sonoros
📖 Recursos de Aprendizado
- Roguebasin - Wiki sobre desenvolvimento roguelike
- Macroquad Docs - Documentação do macroquad
- The Rust Book - Aprender Rust
📝 Licença
GPL-3.0-or-later — veja LICENSE. Projeto educacional, livre para uso, estudo e modificação.
🤝 Contribuindo
Sinta-se livre para fazer fork, modificar e aprender com o código!
Divirta-se explorando as dungeons! 🗡️🛡️
Verificações antes do commit
O .githooks/pre-commit roda aqui o que o Woodpecker roda no servidor. Ele
é gerado a partir do .woodpecker/pipelines.yml deste repositório, então os
comandos não podem divergir do CI. Ative uma vez por clone -- o hook é
versionado, a configuração que aponta para ele não é:
git config core.hooksPath .githooks
A cada git commit: lint do pipeline, cargo fmt --check, clippy com
-D warnings, build e testes. Antes de um push, o nível completo, que
acrescenta cobertura, auditoria de dependências, teste de mutação e a perna MSRV 1.90:
PRE_COMMIT_COMPLETO=1 git commit ...
Para pular de propósito, git commit --no-verify. Um hook que não se pode
pular é um hook que todo mundo desativa; o CI continua sendo a rede que
não se pula.