Table of contents
- Decisões (ADR)
- ADR-001 — Bevy como engine · aceita
- ADR-002 — Câmera em primeira pessoa (FPS) · aceita (2026-10-11)
- ADR-003 — Sem engine de física no MVP · aceita (revisada para 3D)
- ADR-004 — Armas, inimigos e rounds data-driven · aceita
- ADR-005 — Placeholder primeiro, arte depois · aceita
- ADR-006 — Wiki = teoria; Issues/Projeto = trabalho · aceita
- ADR-007 — Inimigos: forças hostis (soldados) que atiram · aceita (2026-10-11)
- ADR-008 — CI no runner com tag debian · aceita
- ADR-009 — Núcleo reutilizável de jogo de tiro (shooter_core) · aceita (2026-10-11)
- ADR-010 — Assets de teste: pacotes CC0 prontos (.glb) · proposta
- ADR-011 — Inventário de duas armas + faca dedicada; pulo e agachar · aceita (2026-10-11)
- ADR-012 — Primeiro inimigo: zumbi corpo a corpo; fuzileiro hostil adiado · aceita (2026-10-12)
- ADR-013 — Navegação por campo de fluxo · aceita (2026-10-12)
- ADR-014 — Esc abre opções/pausa como camada · aceita (2026-10-12)
- ADR-015 — Tiros como projéteis (substitui o hitscan) · aceita (2026-10-12)
Decisões (ADR)
Formato: Contexto → Decisão → Consequências. Status: aceita, proposta ou substituída.
ADR-001 — Bevy como engine · aceita
Contexto: jogo 3D em Rust, simples e fluido, com ECS. Decisão: Bevy 0.20 (última estável em 2026-10). Consequências: API muda entre versões — fixar versão e validar no spike #8; plugins por domínio.
ADR-002 — Câmera em primeira pessoa (FPS) · aceita (2026-10-11)
Contexto: o dono do projeto confirmou FPS. Havíamos proposto top-down. Decisão: câmera em primeira pessoa, cursor travado, mira no centro da tela, arma visível (viewmodel). Substitui: a proposta top-down inicial. Consequências: tiro é raio 3D (com cabeça/corpo); precisa de viewmodels, indicador de dano direcional e áudio posicional; legibilidade depende de HUD e traçantes.
ADR-003 — Sem engine de física no MVP · aceita (revisada para 3D)
Decisão: colisão cápsula/cilindro-vs-AABB própria no plano XZ (arena plana, sem gravidade ativa), raio 3D contra AABBs (slab) e contra volumes simples dos inimigos (cápsula do corpo + esfera da cabeça). Grid espacial para separação. Reavaliar (avian3d) se entrarem pulo, escadas, rampas, objetos físicos ou projéteis balísticos. Consequências: barato e determinístico; exige testes unitários da matemática de raios.
ADR-004 — Armas, inimigos e rounds data-driven · aceita
Decisão: WeaponDef/EnemyDef/RoundCurve + módulo de tunables; migrar para RON se o ciclo de ajuste ficar lento.
Consequências: nova arma/inimigo = uma entrada de dados; é a base do reuso (ADR-009).
ADR-005 — Placeholder primeiro, arte depois · aceita
Decisão: gameplay usa primitivas até o modelo existir; modelos reais entram como .glb. Para teste, usar pacotes CC0 (ADR-010).
Consequências: arte nunca bloqueia o M1.
ADR-006 — Wiki = teoria; Issues/Projeto = trabalho · aceita
Consequências: mudou regra → atualizar wiki no mesmo ciclo.
ADR-007 — Inimigos: forças hostis (soldados) que atiram · aceita (2026-10-11)
Contexto: tema militar; o jogador precisa de cobertura contra tiros. Decisão: o inimigo base é um fuzileiro hostil com tiro hitscan impreciso e telegrafado; cobertura bloqueia tiros. Corpo a corpo vira tipo futuro (rusher). Consequências: IA precisa de linha de visada (raio contra o mapa); HUD de dano direcional; balanceamento muda (teto de vivos 16).
ADR-008 — CI no runner com tag debian · aceita
Consequências: dependências de sistema do Bevy no runner (X11/ALSA/udev/xkbcommon).
ADR-009 — Núcleo reutilizável de jogo de tiro (shooter_core) · aceita (2026-10-11)
Contexto: a ideia principal é um modelo de jogo de tiro 3D que possa ser reaproveitado em outros jogos de tiro. Decisão: workspace Cargo com:
crates/shooter_core— biblioteca sem conteúdo de jogo: controlador FPS, armas e disparo, dano/vida, raio/colisão, IA de atirador, máquina de rounds, loja, blocos de HUD. Configurada por dados e por umShooterCorePlugin.crates/survivors— o jogo: tunables, mapa, modelos, sons, regras específicas. Regras: o core nunca depende do jogo; conteúdo entra por recursos/dados e componentes de extensão; semconstde balanceamento dentro do core. Consequências: custo inicial de separar camadas; reuso por dependência git (ou registry do Gitea) em novos jogos; versionar o core (SemVer). Guia de reuso é entregável do M3 (#38).
ADR-010 — Assets de teste: pacotes CC0 prontos (.glb) · proposta
Decisão: para validar o pipeline sem esperar arte própria, usar pacotes gratuitos CC0 (Kenney: Blaster Kit, Survival Kit). Não exige Blender: já são modelos 3D; o ajuste de escala fica nos dados (ModelDef.scale).
Consequências: registrar licença/origem no MANIFEST; substituir por arte própria depois sem mudar código.
ADR-011 — Inventário de duas armas + faca dedicada; pulo e agachar · aceita (2026-10-11)
Contexto: pedido do dono após o primeiro teste jogável.
Decisão: o jogador carrega até 2 armas (teclas 1/2/scroll) e a faca fora dos slots, ativa enquanto V está pressionado (apertar V dá o golpe). Interagir passa a ser F. Entram pulo (~1 m) e agachar.
Substitui: os 4 slots fixos e o "sem pulo/agachar" do GDD v0.2.
Consequências: pegar uma 3ª arma troca a atual (escolha de loadout passa a importar); agachado, a caixa de 1,2 m vira cobertura total; o pulo não deve alcançar o topo das caixas. Colisão ganha eixo vertical (apoio no topo de caixas), ainda sem engine de física (ADR-003 mantida).
ADR-012 — Primeiro inimigo: zumbi corpo a corpo; fuzileiro hostil adiado · aceita (2026-10-12)
Contexto: o dono pediu começar pelos zumbis. A ADR-007 previa fuzileiros que atiram. Decisão: o inimigo do protótipo é o zumbi (persegue e ataca de perto). O fuzileiro hostil vira tipo futuro. Consequências: a cobertura passa a servir para quebrar rota e ganhar tempo (não para bloquear tiros inimigos, por enquanto); o teto de vivos volta a 24; vida do zumbi cresce de forma linear (60 + 20 por round) porque, sem melhorias de arma, a curva exponencial tornaria os rounds altos impossíveis até o 50.
ADR-013 — Navegação por campo de fluxo · aceita (2026-10-12)
Contexto: muitos perseguidores, um único alvo, obstáculos em forma de caixa. Perseguição em linha reta prende os inimigos atrás de contêineres. Decisão: grade de 0,5 m do mapa (caixas infladas pelo raio do zumbi) + distâncias até a célula do jogador (Dijkstra, sem cortar quinas), recalculadas só quando o jogador muda de célula. Perto e com linha de visada, o zumbi vai direto; vizinhos se repelem para cercar. Consequências: custo independe do número de inimigos; mapa novo = só o SVG. Não trata alturas diferentes (jogador em cima de caixa) — rever se o pulo permitir subir.
ADR-014 — Esc abre opções/pausa como camada · aceita (2026-10-12)
Decisão: Overlay::Options é uma camada independente da tela (menu ou partida). Na partida: congela o tempo do jogo, bloqueia a entrada do jogo (InputGate), solta o cursor e oferece voltar, menu principal ou sair.
Consequências: nada no mundo é destruído ao pausar; sistemas que precisam rodar em pausa usam Time<Real>.
ADR-015 — Tiros como projéteis (substitui o hitscan) · aceita (2026-10-12)
Contexto: pedido do dono na v0.1.2-dev. Até aqui todo tiro era um raio instantâneo (ADR-003).
Decisão: cada disparo cria uma entidade Projectile (no shooter_core) que voa em linha reta, com velocidade constante definida por arma (WeaponDef.projectile_speed), sem gravidade. A cada frame o trecho percorrido é varrido contra as caixas do cenário, o cilindro (corpo) e a esfera (cabeça) dos alvos — as mesmas funções de raio, limitadas ao tamanho do passo, então o projétil não atravessa alvos finos. A faca continua acertando na hora.
Visual: o jogo pendura um rastro luminoso no projétil; ele sai da ponta da arma e converge para a linha da mira em 8 m (o cálculo parte do centro da câmera, para o tiro ir onde a mira aponta).
Consequências: o acerto depende de onde o alvo está quando o projétil chega (antecipação em alvos laterais); o marcador de acerto e o dinheiro chegam com um pequeno atraso proporcional à distância; continua sem engine de física. Queda do projétil e penetração ficam para depois, se o jogo pedir.