Files
portifolio-evandrodevbr/specs/2026-11-10-jogo-zumbis-etapa-2-refino.md
T
evandro 67b32fcab3
CI / audit (push) Successful in 10m48s
CI / verify (push) Successful in 19m2s
CI / deploy (push) Successful in 2m14s
CI / e2e (push) Failing after 36m15s
feat(jogo): expediente dos mortos, jogo de zumbis em primeira pessoa
Etapa 1 inteira (logica com 100% de cobertura, cena 3D, toque, sons, bancada de desempenho, e2e) e a base da etapa 2 (mapa novo no Tiled, texturas, imagens dos itens, sons conferidos, golpe recortado e medido). Pagina /jogo fora do menu e do sitemap ate a medicao no celular.
2026-11-10 19:37:10 -03:00

23 KiB
Raw Blame History

Jogo de zumbis do portfólio: etapa 2, refino (mapa, itens, golpe sincronizado)

Autor: Evandro · Data: 2026-11-10 · Porte: grande · Status: em execução

Aprovação: o pedido foi "faça uma spec completa para esses passos e execute de maneira autônoma". Vale como ok antecipado; mudança de escopo ou de CA continua indo para o Registro e para o relato final.

1. Objetivo

Refinar o jogo de /jogo com ferramentas abertas controladas por linha de comando: um mapa maior feito num editor de mapas, zumbis que começam devagar e largam itens com imagem própria, golpe do zumbi que só tira vida no instante em que a mão bate (com som no mesmo instante), ataque um pouco mais rápido e sons de tiro conferidos.

2. Escopo

  • Dentro: escolha e prova das ferramentas (mapa, modelo, som); mapa novo do escritório gerado por script, editável no Tiled e convertido para a grade da lógica e para o GLB da cena; 4 itens que caem dos zumbis (munição, kit médico, café, bateria) com imagens geradas pela assinatura do ChatGPT; ritmo crescente das hordas; golpe em três fases ligado ao clipe atacar; ciclo de ataque 25% mais rápido; sons de tiro, de dano, de item e de golpe no ar; zumbi novo a partir do MPFB2 se a prova passar (T2).
  • Fora (não fazer): botão na entrada do site (continua esperando a medição no S26 Ultra); segundo mapa; inventário com escolha de item; armas novas; multiplayer; música; dependência nova no package.json; servidor MCP do Blender (ver seção 5); instalar programa com sudo ou com login; mudar a interface fora do HUD dos itens.

3. Critérios de aceite

  • CA1 (ferramentas): 3d/FERRAMENTAS.md lista cada programa usado, versão, licença lida no arquivo de licença dele e o comando exato; bash 3d/mapa.sh refaz o mapa inteiro sem abrir janela e, rodado duas vezes, não muda nenhum arquivo → bash 3d/mapa.sh && git status --short lib/jogo/mapas public/jogo/mapa.glb sem diferença na segunda vez.
  • CA2 (mapa): escritório com pelo menos 40 × 28 células, 6 ambientes com nome, 6 nascedouros e 2 caminhos entre quaisquer dois ambientes; toda célula de chão é alcançável do início; todo nascedouro fica a 8 m ou mais do início; nenhuma passagem tem menos de 2 células de largura; a grade da lógica e o GLB da cena saem do mesmo 3d/mapa/escritorio.tmx → pnpm test -- lib/jogo/mapas e capturas da cena.
  • CA3 (ritmo): hordas de 8, 14 e 20 zumbis (antes do multiplicador); um zumbi nasce a cada 90, 50 e 30 passos; a velocidade deles é 0,8×, 1× e 1,15× → pnpm test -- lib/jogo/hordas.
  • CA4 (itens, lógica): zumbi morto larga item com chance de 30%, sorteado por peso (munição 45, kit 25, café 15, bateria 15; kit com peso dobrado se a vida está abaixo de 40; bateria só com drone vivo); munição dá 30 balas, kit dá 25 de vida, café dá 1,3× de velocidade por 8 s, bateria dobra a cadência dos drones por 10 s; item some em 20 s; no máximo 10 no chão; recolhe a 0,9 m; mesma semente, mesmos itens → pnpm test -- lib/jogo/itens.
  • CA5 (itens, tela): cada item no chão mostra a imagem gerada dele; ao recolher, o HUD mostra o nome e o tempo que resta do efeito e toca o som item; todos os itens juntos custam até 2 chamadas de desenho; o atlas das imagens tem até 512 px de lado e 120 KB → pnpm test -- app/jogo/itens3d app/jogo/Hud e e2e.
  • CA6 (golpe sincronizado): o golpe tem preparo, impacto e volta; a vida só cai no passo do impacto, e só se o jogador ainda está a até 1,4 m; fora disso sai golpeNoAr, sem dano; começado, o golpe vai até o fim. Na tela, o tempo do clipe atacar vem do tempo da lógica: em cada golpe, o clipe está a no máximo 34 ms do instante de impacto medido no Blender, e o som e o clarão vermelho saem no mesmo quadro → pnpm test -- lib/jogo/zumbis app/jogo/efeitos e e2e com GPU lendo window.__jogo.golpes.
  • CA7 (ataque mais rápido): o ciclo do ataque cai de 60 para 48 passos (de 1 para 1,25 golpe por segundo) → pnpm test -- lib/jogo/valores.
  • CA8 (sons): tiro de pistola, rajada, dano no jogador, item e golpe no ar em MP3 mono, com menos de 10 ms de silêncio no começo e pico até −1 dBFS; licença CC0 lida na página oficial do pacote e não contradita por arquivo dentro dele, sem login; o som do tiro sai no mesmo quadro do evento tiro → pnpm test -- lib/jogo/creditos lib/jogo/orcamento app/jogo/efeitos.
  • CA9 (zumbi novo, condicional): se T2 passar, o zumbi vem do MPFB2 com camisa, calça comprida e sapato de pacotes CC0, até 12 mil triângulos e 1,5 MB, com os mesmos 6 clipes, e entra no jogo só se o render lado a lado for melhor que o atual; se T2 não passar, fica o atual e o motivo vai para o Registro → renders em 3d/out/jogo/ e pnpm test -- lib/jogo/orcamento.
  • CA10 (desempenho e peso): com o mapa novo, 16 zumbis à vista, itens e drones: p95 do quadro ≤ 16,7 ms em 1440 × 900 e ≤ 33 ms com CPU 4× mais lenta; até 120 chamadas de desenho; mapa.glb ≤ 1,5 MB; public/jogo ≤ 6 MB; depois do descarte sobram 0 geometrias e 0 texturas → e2e da bancada e pnpm test -- lib/jogo/orcamento.
  • CA11 (qualidade): pnpm test:jogo com 100% nas quatro colunas e nenhuma função acima de 10 decisões; o piloto vence nas 3 dificuldades no mapa novo; Biome, typecheck, pnpm test, build e e2e verdes; os CAs da etapa 1 continuam valendo.
  • CA12 (conteúdo e licença): todo arquivo novo de public/jogo/ está em CREDITOS.json (CC0-1.0 ou propria); nenhum texto cita cliente.

4. Contexto verificado

  • Golpe hoje: lib/jogo/zumbis.ts:113-120 tira vida quando tempo % 60 === 20, sem relação com o clipe; o clipe atacar do GLB dura 2,667 s; ao sair do alcance o zumbi troca de estado na hora (zumbis.ts:156).
  • Itens hoje: só a caixa de munição (MUNICAO em lib/jogo/valores.ts:60-67, 25% de chance, 30 balas, tipo Caixa em tipos.ts:76).
  • Hordas hoje: 12, 16 e 20 (valores.ts:79-88); nascimento a cada 20 passos (zumbis.ts:16).
  • Mapa hoje: grade de 28 colunas escrita à mão em valores.ts:108-126, lida por lerMapa (lib/jogo/mapa.ts:38), caracteres # M . J N.
  • Sons hoje: 10 MP3 em public/jogo/sons/, escolhidos sem ninguém ouvir; um pacote de tiros (Tabasco) foi recusado porque o zip traz CC-BY.
  • Na máquina: Blender 5.2.2, ffmpeg, ImageMagick e flatpak; não há Tiled, Godot, LDtk, TrenchBroom nem sox.
  • Pesquisa (em ~/tmp/jogo/pesquisa-ferramentas.md, com as fontes): Tiled exporta sem janela com tiled --export-map json entrada.tmx saida.json e baixa sem login pelas releases do GitHub; MPFB2 é extensão de Blender (código GPLv3, saída sem restrição), com pacotes CC0 de pele, camisa, calça e sapato, e cria humano por Python (HumanService.create_human); a documentação cita um esqueleto "mixamo". Não confirmado: Tiled sem servidor gráfico nesta máquina, MPFB2 no Blender 5.2, triângulos do humano, nomes dos ossos.

5. Desenho

  • Ferramentas escolhidas. Mapa: Tiled (aberto, tem CLI, e o arquivo .tmx abre no editor para ajuste à mão). Modelos e cenário 3D: Blender por script, como na etapa 1. Humano: MPFB2 dentro do Blender. Imagens: geração de imagem do ChatGPT (logo-gpt). Som: ffmpeg. Descartados: Godot (é motor, o jogo roda em three.js), TrenchBroom e LDtk (sem CLI confirmada), Material Maker (CLI não confirmada; as texturas saem da geração de imagem), servidor MCP do Blender (exige o Blender aberto com janela; o script por CLI refaz tudo sozinho e fica no repositório).
  • Instalação. Programas baixados ficam em 3d/ferramentas/ (fora do git), sem sudo e sem login. O MPFB2 usa uma pasta de usuário do Blender separada (BLENDER_USER_RESOURCES), para não mexer no Blender do Evandro.
  • Cadeia do mapa. 3d/mapa.py gerar (com semente, só sob --gerar) escreveu a primeira versão de 3d/mapa/escritorio.tmx, que passa a ser a fonte → Tiled exporta 3d/mapa/escritorio.json e uma imagem de conferência → 3d/mapa.py converte para lib/jogo/mapas/escritorio.ts (a grade em texto que lerMapa já entende) → blender -b -P 3d/mapa_3d.py monta public/jogo/mapa.glb (paredes, piso, forro, móveis, luminárias) a partir do mesmo JSON. 3d/mapa.sh roda tudo. Editou o .tmx no Tiled, rodou o script, o jogo muda.
  • Golpe. 3d/jogo.py recorta o clipe atacar para um golpe só, mede o quadro em que a mão vai mais à frente e grava lib/jogo/golpe.json (duracao e impacto, em segundos). A lógica usa ciclo de 48 passos e passoDoGolpe = round(impacto / duracao × 48). A tela não deixa a animação correr solta: a cada quadro põe o tempo do clipe em (tempo do zumbi % 48) / 48 × duracao. Sincronia por construção, e conferida por medida (CA6).
  • Itens. lib/jogo/itens.ts substitui a caixa: sorteio, queda, validade, coleta e efeitos, tudo pela semente. Na tela, um atlas 2 × 2 com as 4 imagens e um só desenho instanciado, mais um anel de luz no chão.
  • Ritmo. HORDAS ganha nascerACada e velocidade por horda; a tabela de dificuldade continua multiplicando por cima.
  • Contrato. Os tipos e valores novos entram em lib/jogo/tipos.ts e valores.ts antes das tarefas de lógica (T6), para elas rodarem em paralelo sem disputar esses dois arquivos.

6. Restrições, riscos, suposições

  • Restrições: as da etapa 1 (sem dependência nova no projeto, nenhum byte do jogo na home, só CC0 sem login, textos sem cliente). Commit na branch feat/jogo-zumbis e push dela como prévia já estão autorizados; nada vai para a main.
  • R1: o Tiled pode não rodar sem servidor gráfico aqui. Saída: QT_QPA_PLATFORM=offscreen, depois flatpak --user; se nada funcionar, o .tmx continua sendo a fonte e a conversão é feita pelo nosso script (registrar).
  • R2: o MPFB2 pode não rodar no Blender 5.2, passar de 12 mil triângulos ou não aceitar os clipes do zumbi atual. T2 mede antes; se falhar, fica o zumbi atual (CA9).
  • R3: mapa maior e itens custam quadro. CA10 mede de novo, com CPU 4× mais lenta.
  • R4: ninguém ouve os sons aqui. A conferência é por duração, pico e forma de onda; o ouvido do Evandro decide depois.
  • R5: golpe que vai até o fim e erra deixa o jogo mais fácil de esquivar; o ciclo 25% mais rápido compensa. Valores continuam iniciais (S5 da etapa 1).
  • Suposições: S1 "começar devagar" é o ritmo do CA3; S2 "itens" são os 4 do CA4; S3 "software para mapas com CLI" é atendido pelo Tiled mais o Blender; S4 a etapa 1 fecha (consertos do parecer, e2e, commit e prévia) antes de a lógica nova entrar.

7. Microtasks

T1 · provar o Tiled por linha de comando · sênior [P]

  • Serve: CA1 · Depende de: nenhuma · Arquivos: criar 3d/FERRAMENTAS.md, 3d/mapa/prova.tmx, 3d/mapa/prova.json
  • Fazer: baixar o Tiled para 3d/ferramentas/, exportar um mapa de prova para JSON e para imagem sem abrir janela, anotar versão, licença lida e comando.
  • Pronto quando: prova.json saiu do Tiled por CLI; FERRAMENTAS.md tem a linha do Tiled com a licença citada.
  • feito

T2 · provar o MPFB2 por linha de comando · sênior [P]

  • Serve: CA9 · Depende de: nenhuma · Arquivos: criar 3d/humano.py; acrescentar em 3d/FERRAMENTAS.md
  • Fazer: instalar a extensão em pasta de usuário separada, criar um humano com camisa, calça comprida e sapato de pacotes CC0, pôr esqueleto compatível com os clipes do zumbi atual, renderizar frente e perto. Parar e relatar se não der (R2).
  • Pronto quando: blender -b -P 3d/humano.py termina com OK humano e informa triângulos e ossos; renders em 3d/out/jogo/humano-*.png; veredito escrito.
  • feito

T3 · recortar e medir o golpe · sênior [P]

  • Serve: CA6 · Depende de: nenhuma · Arquivos: modificar 3d/jogo.py, public/jogo/zumbi.glb; criar lib/jogo/golpe.json
  • Fazer: deixar o clipe atacar com um golpe só (preparo, impacto, volta), medir o instante do impacto e gravar duracao e impacto.
  • Pronto quando: blender -b -P 3d/jogo.py termina com OK zumbi; golpe.json existe; 3d/out/jogo/golpe.png mostra 5 quadros do golpe com o do impacto marcado.
  • feito

T4 · imagens dos itens · logo-gpt, depois impl [P]

  • Serve: CA5, CA12 · Depende de: nenhuma · Arquivos: criar 3d/itens/*.png, public/jogo/itens.webp; modificar public/jogo/CREDITOS.json
  • Fazer: gerar munição, kit médico, café e bateria no mesmo estilo, fundo removível; montar o atlas 2 × 2 com transparência.
  • Pronto quando: atlas com 512 px e até 120 KB; as 4 imagens conferidas a olho; crédito propria.
  • feito

T5 · sons novos e tiros conferidos · sênior [P]

  • Serve: CA8, CA12 · Depende de: nenhuma · Arquivos: public/jogo/sons/*.mp3, public/jogo/CREDITOS.json
  • Fazer: conferir (e trocar se preciso) pistola e automatica; acrescentar dano, item e golpe-no-ar; licença lida dentro de cada pacote.
  • Pronto quando: pnpm test -- lib/jogo/creditos lib/jogo/orcamento verde; tabela com duração, pico e silêncio inicial de cada som.
  • feito

CP1 · após T1–T5 · direto

  • Ver os renders do humano e do golpe e as imagens dos itens; decidir CA9; registrar.
  • feito

T6 · contrato da lógica nova · direto

  • Serve: CA3, CA4, CA6, CA7 · Depende de: T3 e fim da etapa 1 · Arquivos: modificar lib/jogo/tipos.ts, lib/jogo/valores.ts
  • Fazer: tipos Item, TipoItem, eventos golpeNoAr, itemCaiu, itemPego; valores ITENS, HORDAS.nascerACada, HORDAS.velocidade, ATAQUE_DO_ZUMBI com ciclo de 48 e alcanceDoGolpe.
  • Pronto quando: tsc compila com os tipos novos; pnpm test -- lib/jogo/valores verde.
  • feito

T7 · golpe em três fases · sênior [P]

  • Serve: CA6, CA7 · Depende de: T6 · Arquivos: modificar lib/jogo/zumbis.ts, lib/jogo/zumbis.test.ts
  • Fazer: preparo, impacto e volta; dano só no impacto e dentro do alcance; golpeNoAr; golpe começado vai até o fim.
  • Pronto quando: pnpm test -- lib/jogo/zumbis verde com 100% do arquivo.
  • feito

T8 · itens na lógica · sênior [P]

  • Serve: CA4 · Depende de: T6 · Arquivos: criar lib/jogo/itens.ts, lib/jogo/itens.test.ts; modificar lib/jogo/partida.ts
  • Fazer: sorteio, queda, validade, coleta, efeitos de café e bateria; tirar a caixa antiga.
  • Pronto quando: pnpm test -- lib/jogo/itens lib/jogo/partida verde com 100%.
  • feito

T9 · ritmo das hordas · impl [P]

  • Serve: CA3 · Depende de: T6 · Arquivos: modificar lib/jogo/hordas.ts, lib/jogo/hordas.test.ts
  • Fazer: tamanho, intervalo de nascimento e velocidade por horda.
  • Pronto quando: pnpm test -- lib/jogo/hordas verde com 100%.
  • feito

T10 · gerar o mapa no Tiled · sênior [P]

  • Serve: CA1, CA2 · Depende de: T1 · Arquivos: criar 3d/mapa.py, 3d/mapa.sh, 3d/mapa/escritorio.tmx, lib/jogo/mapas/escritorio.ts, lib/jogo/mapas/escritorio.test.ts
  • Fazer: gerador com semente, exportação pelo Tiled, conversão para a grade; testes do CA2.
  • Pronto quando: bash 3d/mapa.sh duas vezes sem diferença; pnpm test -- lib/jogo/mapas verde; imagem do mapa conferida.
  • feito

T11 · texturas do cenário · logo-gpt [P]

  • Serve: CA2, CA12 · Depende de: nenhuma · Arquivos: criar 3d/texturas/cenario-*.jpg
  • Fazer: parede, carpete, forro, madeira de mesa e 4 cartazes de escritório, todas repetíveis sem emenda (menos os cartazes).
  • Pronto quando: 8 imagens conferidas a olho; nenhuma com marca, logotipo ou nome de empresa.
  • feito

T12 · montar o mapa em 3D · sênior

  • Serve: CA2, CA10 · Depende de: T10, T11 · Arquivos: criar 3d/mapa_3d.py, public/jogo/mapa.glb; modificar public/jogo/CREDITOS.json
  • Fazer: paredes, piso, forro, móveis e luminárias a partir do JSON do Tiled, com poucas malhas e poucas texturas.
  • Pronto quando: mapa.glb ≤ 1,5 MB; 3 renders em 3d/out/jogo/mapa-*.png; pnpm test -- lib/jogo/orcamento verde.
  • feito

CP2 · após T7–T12 · direto

  • pnpm test:jogo com 100%; piloto vence nas 3 dificuldades no mapa novo; ver os renders do mapa.
  • feito

T13 · cena com o mapa novo · sênior

  • Serve: CA2, CA10 · Depende de: T12 · Arquivos: modificar app/jogo/ambiente.ts, app/jogo/ambiente.test.ts, app/jogo/cena.ts
  • Fazer: carregar mapa.glb no lugar das caixas geradas; luzes nos pontos marcados; descarte completo.
  • Pronto quando: capturas da cena conferidas; window.__jogo.sobras 0 e 0; até 120 chamadas de desenho.
  • feito

T14 · golpe na tela · sênior

  • Serve: CA6, CA8 · Depende de: T7, T13 · Arquivos: modificar app/jogo/atores.ts, app/jogo/efeitos.ts, app/jogo/cena.ts
  • Fazer: tempo do clipe vindo da lógica; som e clarão no quadro do evento; publicar window.__jogo.golpes.
  • Pronto quando: pnpm test -- app/jogo verde; no navegador com GPU, todo golpe com desvio até 34 ms.
  • feito

T15 · itens na tela · sênior

  • Serve: CA5 · Depende de: T8, T4, T14 · Arquivos: criar app/jogo/itens3d.ts, app/jogo/itens3d.test.ts; modificar app/jogo/Hud.tsx
  • Fazer: itens instanciados com o atlas, anel no chão, piscar no fim da validade; HUD com nome e tempo do efeito.
  • Pronto quando: pnpm test -- app/jogo/itens3d app/jogo/Hud verde; captura com item no chão e efeito no HUD conferida.
  • feito

T16 · zumbi novo no jogo · sênior (só se o CP1 aprovar)

  • Serve: CA9 · Depende de: T2, T3 · Arquivos: modificar 3d/jogo.py, public/jogo/zumbi.glb, public/jogo/roupa-*.jpg
  • Fazer: trocar a base pelo humano do MPFB2, com as 3 roupas, o sangue e os 6 clipes.
  • Pronto quando: render lado a lado conferido; pnpm test -- lib/jogo/orcamento verde; bancada sem perda.
  • feito

T17 · testes de ponta a ponta do refino · sênior

  • Serve: CA5, CA6, CA10, CA11 · Depende de: T13–T15 · Arquivos: modificar e2e/jogo.spec.ts, e2e/jogo-bancada.spec.ts, lib/jogo/piloto.ts
  • Fazer: casos de item, de golpe sincronizado e de desempenho no mapa novo; piloto ajustado se precisar.
  • Pronto quando: e2e verde com GPU; piloto vence nas 3 dificuldades.
  • feito

CP3 · fechamento · direto

  • Rodar a verificação de cada CA; parecer do fable-critico sobre a sincronia e o descarte; impeccable critique e audit; commit e push da prévia; preencher CA → resultado.
  • feito

8. Registro

2026-11-10 — spec escrita a partir do pedido do Evandro e da pesquisa de ferramentas. A etapa 1 ainda fecha em paralelo (consertos do parecer crítico, polimento visual e e2e); as tarefas de lógica desta etapa só entram depois dela (S4). 2026-11-10 — T1 feita: Tiled 1.12.2. O AppImage só traz o plugin gráfico xcb e a máquina não tem xvfb-run, então o caminho sem janela é o Flatpak de usuário: env -u DISPLAY -u WAYLAND_DISPLAY flatpak run --env=QT_QPA_PLATFORM=offscreen --command=tiled org.mapeditor.Tiled --export-map json entrada.tmx saida.json (e --command=tmxrasterizer para imagem). Mapa de prova exportado para JSON (48 células, 1 ponto) e para PNG. Efeito colateral: o Flatpak ficou em ~/.local/share/flatpak (não em 3d/ferramentas/), instalou o KDE Platform 6.10 e atualizou o runtime GL.nvidia do Flatpak. R1 resolvido. 2026-11-10 — T4 (imagens): 4 imagens dos itens geradas e conferidas a olho (caixa de balas com pente, estojo vermelho com cruz, copo de café, bateria com 4 luzes verdes), fundo preto liso. A bateria e o pente são quase pretos: o atlas remove o fundo por preenchimento a partir dos cantos, não por limiar. Falta montar o atlas. 2026-11-10 — T11 feita: parede, carpete em placas, forro e madeira saíram repetíveis; os 4 cartazes saíram com o texto certo ("METAS DO MÊS", "BACKUP: TODA SEXTA", "NÃO DESLIGUE O SERVIDOR", "SENHA NÃO SE EMPRESTA"), sem marca nem nome. 2026-11-10 — T5: nenhum pacote de tiro CC0 do OpenGameArt traz arquivo de licença dentro (nem os tiros que já estavam em uso). Regra ajustada (muda o texto do CA8): vale a licença escrita na página oficial do pacote, desde que nada dentro do arquivo a contradiga; pacote com arquivo dizendo outra licença continua recusado. O crédito guarda a página e a data da leitura. 2026-11-10 — T5 feita: automatica trocada por um tiro de PPSh da Free Firearm Sound Library cortado em 180 ms (a antiga tinha cauda de 69 ms e corpo fraco); pistola mantida, com o pico corrigido (+0,17 → −1,07 dBFS); caixa com pico corrigido; golpe tinha 22 ms de ruído antes da pancada e agora começa em 0,5 ms; novos dano (gemido curto), item (arpejo) e golpe-no-ar (vush). Os 13 arquivos medidos: pico entre −1,83 e −1,07 dBFS, silêncio inicial até 0,2 ms. Ninguém ouviu: escolha por espectrograma e forma de onda (R4). 2026-11-10 — T10 feita: mapa de 44 × 32 células, 11 ambientes (os 7 pedidos mais banheiros, hall dos elevadores, escada e área de serviço), 7 nascedouros, 22 portas, salão de 18 × 10 com 4 ilhas de mesas e corredor em anel. bash 3d/mapa.sh duas vezes com o mesmo sha256sum; 7 testes do mapa verdes; pnpm test:jogo 100% com 273 testes. Planta conferida a olho: parece um escritório. Desvio da seção 5: o mapa.sh rodava o gerador e apagaria edição feita à mão no Tiled; decisão: o .tmx é a fonte e o gerador só roda com --gerar. Não conferido: abrir o .tmx no Tiled com janela. 2026-11-10 — T2 feita: MPFB 2.0.18 roda sem janela no Blender 5.2.2, instalado só em 3d/ferramentas/blender-user. Humano com camisa polo, calça de lã e botina: 41.364 triângulos brutos, 11.634 depois de tirar as faces sob a roupa e reduzir; esqueleto mixamo com 52 ossos de mesmo nome dos do zumbi (faltam só 13 pontas que não deformam); os 6 clipes passaram. Recusados por licença: calça cargo e uma pele, cujos arquivos dizem AGPL apesar de o pacote se dizer CC0. Pendências medidas: GLB de 13,7 MB por causa das texturas (limite 1,5 MB); pele fura a camisa no ombro com o braço erguido; morrer ainda anda 1,2 m; não testado no three.js. R2 resolvido. 2026-11-10 — CP1, decisão do CA9: aprovada a troca da base do zumbi. No render lado a lado o humano do MPFB2 tem proporção e rosto de gente e roupa de escritório; o zumbi atual tem tronco inchado, mangas soltas do corpo e barriga de fora. T16 entra, com estas condições: pele morta, sangue e olhos turvos; ombro sem furo; GLB ≤ 1,5 MB e ≤ 12 mil triângulos; morrer sem andar; conferido no three.js. A aparência final continua sendo decisão do Evandro (R1 da etapa 1). 2026-11-10 — T4 feita: public/jogo/itens.webp com 512 × 512 e 32 KB, refeito por bash 3d/itens.sh; conferido sobre vermelho e sobre cinza: os 4 objetos inteiros (pente e bateria sem buraco), sem halo; o vapor do café sumiu, como previsto. Crédito propria e caso novo no teste de orçamento (17 testes verdes). 2026-11-10 — T3 feita: atacar recortado para um golpe só (quadros 8 a 50 do original, com os 5 últimos voltando à pose do primeiro): duração 1,400 s, impacto em 0,833 s, mão direita, alcance 0,790 m à frente do quadril; lib/jogo/golpe.json gravado. Com o ciclo de 48 passos, passoDoGolpe = 29 (0,483 s depois do começo do golpe) e a tela toca o clipe 1,75× mais rápido. zumbi.glb: 11.950 triângulos, 1.455.084 B. Render 3d/out/jogo/golpe.png conferido: preparo, mão estendida no impacto, volta. Desvio: o exportador começava os clipes em 1/30 s; o atacar passou a começar em 0 s. Não conferido: o golpe em movimento no navegador (T14). 2026-11-10 — CP1 fechado: humano, golpe e imagens dos itens vistos; CA9 aprovado (acima). 2026-11-10 — HUD em celular deitado (pendência da etapa 1, feita aqui): feed no canto de cima à direita com até 3 linhas, acima dos botões; cartão "Resolvido" no terço de cima, fora da mira; o feed fica transparente enquanto o cartão aparece. Capturas 3d/out/jogo/hud-915*.png e hud-640*.png conferidas. Área segura só testada com valor 0.