Skip to content

feat(v2.1): times, mapas novos e o arnês que passou a medi-los — 200 commits - #399

Open
rubenmarcus wants to merge 220 commits into
mainfrom
feat/times-e-mapas-completo
Open

feat(v2.1): times, mapas novos e o arnês que passou a medi-los — 200 commits#399
rubenmarcus wants to merge 220 commits into
mainfrom
feat/times-e-mapas-completo

Conversation

@rubenmarcus

Copy link
Copy Markdown
Member

Junta na main o trabalho da v2.1 que estava vivendo em nove worktrees (v21/a-lajesv21/h-vida1) e na v2.1.0-teste. As nove já foram absorvidas aqui — estão 0 commits à frente, limpas e sem stash, então não há PR delas para abrir.

200 commits · 1688 arquivos · +132.531 / −31.866

O que entra

Mapas — 5 mapas novos e 12 revisados:

novo linhas
map_lajes.js + map_lajes_authored.js 1356 + 1263
map_corrego.js 1258
map_mansao.js 951
map_escadao.js 813
map_campomorro.js 713

Mais map_sky.js (céu por mapa) e retoques em brasília, ferro velho, havan, piscina, quebrada, penitenciária, atacadão, obras, parque, posto, UPA e velho oeste.

Ambiência e vida de cenaambientlife.js com 9 espécies (rato, pomba, cachorro, gato, galinha, vaca, tatu, barata, papagaio), som ambiente por mapa, fauna reagindo a tiro. Cobertura medida: ambience-registry-check AR1–AR6 verdes nos 17 mapas.

Elenco e facções — pixação (21 commits), models, personagens míticos, vozes, thumbnails, brasões.

Arnês94 réguas novas em tools/eval/, entre elas as de contrato de mapa (campo-contract, corrego-contract, escadao-contract, lajes-*), as de material e textura (texel-*, char-pbr, char-plastico), as de água e vento (mansao-water, corrego-water, wind, softparticles) e o mapa-novo-gate.

Superou dois PRs abertos

Fechei o #376 (fauna nos 12 mapas) e o #369 (arnês/grafite, BUG-60) porque esta branch já carrega as duas coisas em versão igual ou melhor — ambientlife.js de 561 linhas contra 410, 9 espécies contra 1, e o define:vars genérico do serve.mjs no lugar do replace literal do __SUPPORT. Conferi item a item antes de fechar; o diagnóstico está escrito nos dois PRs.

Estado honesto dos portões

npm run check:fast87/96. As 9 vermelhas, todas anteriores a este PR e não regressões dele:

eval:shaderbudget · eval:mapid · eval:redesign · docs:check · arch:check · eval:camera-grip · eval:char-thumbnail · eval:asset-integrity · eval:devport

Duas delas são armadilha conhecida de commit (arch:check e docs:check cobram bloco gerado); eval:devport reprova quando já há dev server de pé. As dívidas de invariante seguem catalogadas em tools/eval/KNOWN-RED.json (VM*, CHR*, BOT8, CTF1, GRAF1).

O pre-push local barra este push por causa do merge 7eca0656 (19/08), que não tem o trailer Agent: e já está em três branches — corrigir exigiria reescrever história compartilhada.

Como revisar isto

200 commits não se revisam em ordem. Sugestão: pelos contratos. Cada frente de mapa tem régua própria em tools/eval/ com cláusulas nomeadas e mutantes; SCRIPTS.md descreve cada uma, o defeito que a comprou e o que ela mede. Ler a régua diz mais sobre a frente do que ler o mapa.

ruben-cytonic and others added 30 commits August 8, 2026 06:15
…atch

Specs dos 4 conteúdos propostos (Time Mítico + 3 mapas), workflow de crash-fix,
skill sync, ferramenta spec.mjs, e dispatch de erro JS (migration 020).
Base para construir times e mapas.
Spec plans/12-ESCADAO.md. Mapa de verticalidade pura:
- 3 lances × 12 degraus (espelho 0,17 · piso 0,29 · Blondel 0,63 — NBR 9077)
- 3 patamares intermediários com barricadas e caveirão no central
- 2 becos laterais com escada própria (CTF2: mínimo 2 rotas separadas)
- groundHeightAt multinível (base y=0 → topo y=6,12)
- spawns E na base (bar/mercadinho) · B no mirante (caixa d'água)
- 4 bandeiras CTF alternando lados (alturaTriângulo 6,77 m ≥ 4,5 m)
- 14 armas no chão (pickup-check: 63 pickups, 0 fora do piso)
Adiciona fy_escadao ao registry de mapas com ctfMode: true.
Mirror SEO do novo mapa Escadão (Morro) em src/data/jogo.ts.
Spec plans/11-CAMPO-DO-MORRO.md. Mapa de convergência:
- Campo central de várzea (~40×25m) com traves, alambrado e arquibancada
- Galpão de baile funk no norte (spawn B): paredão de som, portão de aço, DJ
- 4 becos convergindo do galpão ao campo (≥6m de separação entre cada)
- Assimetria deliberada: campo exposto × galpão protegido
- 3 saídas do galpão (portão central + vãos dos becos NW/NE) para CTF2
- CTF2: mínimo 2 rotas separadas em todos os pares
- 16 armas no chão + armário do game.js
Adiciona fy_campomorro ao registry de mapas e ao mirror do site.
Spec plans/10-LAJES.md. Mapa de camadas verticais:
- Fileira norte: 3 prédios (lajes a y=3,5; central mais alto a y=5,0)
- Beco central: corredor largo conectando todos os becos
- Fileira sul: 3 prédios + beco sul (spawn B)
- 4 escadas conectando as camadas (NW, NE, SW, SE)
- groundHeightAt multinível: laje sobre prédios, beco entre eles
- 'blocked' y-aware: sólidos só bloqueiam no nível do chão
- CTF2: mínimo 3 rotas separadas (corredores laterais + becos + lajes)
- Caixas d'água, muretas, varais, antenas nas lajes
Spec plans/09-TIME-MITICO.md. Nova facção M (roxo #9d4edd):
Zumbi dos Palmares · Maria Bonita · Saci-Pererê · Lampião · Lobisomem ·
Bandeirante · Macunaíma · Cuca · Curupira

Mudanças em 11 arquivos:
- characters.js: 9 personagens (team M, tribe mitico) + TEAM_RIM + CHAR_WEAPON + faixa peito
- game.js: _teamColor/_teamInk/_teamName/_teamTag + BRASAO_FILE + GLOVE
- brasoes.js: COR_TIME + BRASAO (M: #9d4edd)
- main.js: 3 loops de facção + onclick + FACTION_NAME (fix P→E) + preview
- fparms.js: GLOVE (também adiciona F que faltava)
- index.astro: cartão btn-team-m no HTML
- style.css: .team-m com gradiente roxo
- jogo.ts: FACCOES + 9 PERSONAGENS
- about.astro, characters.astro, faccoes/[id].astro: EN maps + PLACA

FAC1 (faccao-paleta-check): PASSA — 6 facções com paletas coerentes.
# Conflicts:
#	public/js/maps.js
#	src/data/jogo.ts
# Conflicts:
#	public/js/maps.js
#	src/data/jogo.ts
…assets 3D

CAMPO DO MORRO redesenhado como rosa dos ventos:
- Grid 5×5 com padrão em estrela (H= casa, .= corredor, F= campo central)
- 4 corredores cardeais (N, S, E, W) + 4 diagonais (zig-zag)
- 8 direções de ataque convergindo no campo central
- Traves, container, banco no campo; galpão de baile como cover no canto NW
- MAP1 0 | CTF1 9,43m | CTF2 mínimo 3 rotas | MAP2B folga 3,8m

Texturas fotorrealistas (OpenRouter / gpt-5-image):
- favela_wall.webp — parede de tijolo aparente com reboco caindo
- asphalt_br.webp — asfalto brasileiro gasto
- dirt_field.webp — campo de várzea (terra batida)
- concrete_br.webp — concreto crackudo
- azulejo.webp — azulejo colorido (Selarón genérico)
- sky_rj.webp — skybox do Rio de Janeiro (favela no morro, golden hour)
- Texturas carregadas no browser com fallback canvas em node

Arte da facção Mítico:
- brasoes/m.png — escudo circular roxo com Saci e fogo do Curupira
- faccoes/mitico.webp — card de seleção

Models 3D (Tripo API):
- props/favela_house — barraco de favela
- props/caixa_dagua — caixa d'água preta
- props/trave_futebol — trave de gol
MANSAO JOÁ (fy_mansao):
- cs_mansion brasileiro: jardim Burle Marx + interior jogável + piscina infinita
- Hall de pé-direito duplo, sala, cozinha gourmet, home theater, mezanino com escada
- Garagem aberta com carros esportivos, heliponto
- SPAwn A no portão (jardim) · B no terraço (piscina)
- MAP1 0 | CTF1 9,53m | CTF2 mínimo 2 rotas
- Texturas: mármore, jardim, deck de ipê, skybox oceano (Joá)

CÓREGO (fy_corrego):
- Favela de SP sobre córrego a céu aberto
- 3 pontes de madeira (chokepoints), jacaré no córrego, capivara na margem
- Palafitas com telhado de zinco, antenas parabólicas, caixas d'água
- Trechos alagados nas pontas
- Texturas: zinco, madeira, água poluída, skybox SP

SPECS criadas: Sítio Atibaia, Sertão, Ver-o-Peso, Balneário Camboriú
?arena=1 ativa o modo Arena:
- Quem morre troca pro time do assassino (aplicado no respawn)
- Sem rounds, sem timer — partida corre até um time ficar com ≤ 1
- Arena win check após cada kill (_checkArenaWin)
- timeLeft = Infinity no arena (round nunca acaba por timer)
- HUD mostra 'VOCÊ SOBREVIVEU' ou 'VOCÊ FOI CONVERTIDO' no fim
Todos os 9 personagens Míticos com models GLB PBR (~1MB cada):
- zumbi, mariabonita, saci, lampiao, lobisomem, bandeirante,
  macunaima, cuca, curupira
- Gerados no mint.gg (text-to-3D), formato GLB com materiais PBR
- Registrados em GLB_CHARS (glbchars.js)
- Agora aparecem como models 3D reais no jogo (não caixas procedural)
…-3D)

Lampiao, Lobisomem, Saci, Bandeirante, Macunaima, Cuca agora gerados a
partir de imagem de referência (OpenRouter → Mint image-to-3D), não
texto only. Detalhes muito mais fiéis ao design de cada personagem.
TIRADOS: Zumbi dos Palmares, Macunaíma
COLOCADOS: Boto Cor de Rosa, Mula-sem-cabeça
RESTAURADOS v1 (preferidos pelo dono): Saci, Bandeirante

Elenco final do Time Mítico (9):
Maria Bonita · Saci · Lampião · Lobisomem · Bandeirante ·
Boto Cor de Rosa · Mula-sem-cabeça · Cuca · Curupira
3 models regerados no Meshy (text-to-3D + texture_image_url do usuario):
- Boto: 4.2MB (golfinho rosa, ref do usuario)
- Lampiao: 18MB (rosto historico, ref do usuario)
- Lobisomem: 18MB (lobo-guara, ref do usuario)
- Boto adicionado ao GLB_CHARS

Pendente: Mula-sem-cabeça (sem ref ainda), otimizacao de tamanho
Mula-sem-cabeca TIRADA → Zumbi dos Palmares VOLTA (6 refs do usuario)

4 models regerados no Meshy com texture_image_url das REFS DO USUARIO:
- Zumbi: 7.4MB (guerreiro quilombola)
- Lampiao: 12MB (cangaceiro historico, 4 refs)
- Lobisomem: 12MB (lobo-guara, 3 refs)
- Cuca: 10MB (bruxa jacare do Lobato, 4 refs)

Elenco final do Time Mitico (9):
Maria Bonita · Saci · Lampiao · Lobisomem · Bandeirante ·
Boto Cor de Rosa · Zumbi dos Palmares · Cuca · Curupira
Boto: restaurado do Mint (816KB, humano com terno branco)
Map previews: fy_escadao, fy_campomorro, fy_lajes, fy_corrego, fy_mansao
glowing-gator-witch.glb → cuca.glb (1.0MB)
pink-river-shapeshifter.glb → boto.glb (816KB)
…+ cover mitico

- game.js: QP.get→QS.get (QP nao existia no game.js, causava crash)
- map_corrego.js: adicionado col() que faltava
- map_campomorro.js: T.dirt→(T&&T.dirt) defensivo + T.muraisHom fallback
- Cover do Time Mítico: 4 personagens com armas (estilo dos outros times)
- Todos os 5 mapas novos bootam OK no harness
Snapshot da árvore de trabalho para o merge dos 260 commits que a main tem
a mais que esta branch. NÃO é entrega — é ponto de retorno.

Conteúdo:
- tools/eval/  (74) arnês e réguas novas
- public/img/  (42) arte, brasões, texturas
- public/models/ (39) GLBs dos 9 personagens Míticos
- public/js/   (23) os 5 mapas novos + edições
- .claude/skills/faction-pipeline/, content/, plans/19-*

Também entra a correção do gl-shots.mjs achada hoje: o arnês de captura
conhecia só 5 dos 10 mapas, então escadao/campomorro/lajes/corrego/mansao
NUNCA foram fotografados por régua nenhuma. É a raiz de eles terem entrado
chapados — o que não é fotografado não é criticado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
26 conflitos resolvidos. Regra geral aplicada: preservar os DOIS lados —
a main traz conserto, a branch traz conteúdo (5 mapas + 9 Míticos).

Decisões em que um lado venceu, com motivo:
- package.json/version.js -> alpha.79 (main). Regredir a versão faz o ?v= do
  import map servir módulo velho de cache: é a causa raiz do BUG-39.
- workflows -> main (superset estrito; nada da branch perdido).
- blocos <!-- BEGIN:GERADO --> -> regenerados por `npm run docs`, não
  resolvidos à mão. ARCH.md e package-lock idem.
- graffiti_layout.js mesclado POR MAPA: main nos 5 antigos (devolve 29 murais
  que a branch tinha zerado), branch nos 5 novos. 10 mapas, 3777 peças.
- game.js/_kill: mantida sfx.characterVoice (superset de sfx.voice); as duas
  juntas tocariam voz dobrada a cada abate.

Também entra o conserto do tools/eval/serve.mjs achado durante o merge:
writeHead(200) vinha ANTES de await renderIndex(), então falha no render
virava ERR_HTTP_HEADERS_SENT em handler async e matava o processo. Isso
truncou a bateria de captura de 12/08 e os 5 mapas novos saíram
ERR_CONNECTION_REFUSED — que no log parece defeito do jogo.

Verificado: syntax 40 arquivos OK · docs:check verde · arch:check verde ·
zero marcador de conflito · index serve 200 com ?v=2.0.0-alpha.79.

PENDENTE (decisão do dono): KNOWN-BUGS.md tem 5 IDs colididos (BUG-42..46),
cada lado numerou por conta. As 10 entradas foram preservadas, nenhuma
renumerada — renumerar quebra referência de evidência.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
…onagem

Três defeitos de ENGINE achados por críticos adversariais em 12/08. Nenhum
deles precisava de asset novo — o dono estava prestes a gastar crédito de
text-to-3D em problema de código.

weapons.js — o "fuzil de madeira gigante" do print
  `zlen` normalizava a arma SÓ pelo eixo Z, supondo que `cfg.rot` já pusera o
  cano em +Z. O `rot:[-90,0,0]` do mosquete leva Z→Y, então o normalizador
  media a SEÇÃO TRANSVERSAL: 7,856 m contra `len: 1.45` declarado (5,42×).
  Conserto: `rot` → [0,0,0] e `zlen` → max(dx,dy,dz).
  Medido depois: 0,205 / 0,261 / 1,450. Nas outras 26 armas o delta é
  0.00e+0 — zero absoluto, não "dentro da tolerância", porque nelas o maior
  eixo já era Z.
  Régua: tools/eval/weapon-scale-check.mjs (vermelha antes citando 7,856).

glbchars.js — "uns parecem anões, outros gigantes"
  A normalização usava `Box3.setFromObject`, que engloba chapéu, boné, bico e
  antena. A altura saía certa (1,72 m) e a ANATOMIA não: o punk andava 21 cm
  mais baixo que o elenco para o moicano caber no orçamento.
  E a hitbox de cabeça era `BoxGeometry(0.26,0.30,0.26)` FIXA para os 61 —
  cobertura de 0,32 a 1,00, espalhamento 3,09×. Isso é balanceamento, não
  estética: cabeça grande não registrava headshot.
  Conserto: escala por marco anatômico (head_end) e caixa por (head_end−neck).
  estatura 0,222 m → 0,000 m · hitbox 3,09× → 1,06× · 37 chars abaixo de 0,75
  de cobertura → 0.
  Régua: tools/eval/char-escala-check.mjs, 3 mutantes.

serve.mjs — o instrumento que acusava o jogo
  `renderIndex()` substituía atributo POR ATRIBUTO e só conhecia dois. O merge
  trouxe o conserto do BUG-39 da main (`?v=` amarrado ao pkg.version) e com ele
  `src={`/js/main.js?v=${V}`}`, que passou a vazar como texto literal: 404 no
  main.js, `window.__game` inexistente, boot parado em "CARREGANDO ARENA…".
  Em captura headless isso vira `waitForFunction: Timeout 900000ms` e o log
  acusa o MAPA — quase reportamos "os 5 mapas novos não bootam" quando NENHUM
  mapa bootava. Agora a substituição é genérica, com o limite declarado no
  código (expressão de escopo de runtime continua vazando de propósito).

DÍVIDA DECLARADA, não escondida: a amplitude da altura do OLHO não fecha por
normalização — `olhoPct` é invariante de escala (gotinha 62,5%, dollynho 94,2%
da própria estatura), então 0,545 m é o piso matemático. Fechar isso é decisão
de ARTE (crânio menor nos mascotes), não de código. A régua avisa sem reprovar.

PENDENTE: as duas réguas novas não estão em portão nenhum (falta wire no
package.json), e o encaixe do mosquete na mão em 3ª pessoa não foi conferido
em pixel — o eixo do cano mudou e `gripZ: 0.68` ficou intocado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
#200

A `main` LOCAL estava 8 commits atrás de `origin/main`, e foi por isso que o
merge anterior não trouxe o rename. Estes 8 têm: ids de mapa sem nome de
Counter-Strike (#200), custo de cena virou portão + cor de facção com origem
única (#198), módulos podados no deploy (#199), varying budget do WebGL1
(#194) e o BUG-51.

40 conflitos. Regra: preservar os DOIS lados; conserto da main tem precedência
sobre estilo da branch.

DECISÕES QUE PRECISAM SER LIDAS:

1. Cor de facção — os dois lados consertaram O MESMO bug (a bandeira apagada de
   07/08) em módulos diferentes: main criou `paleta.js` (5 facções), branch criou
   `factions.js` (10, com brasão/tag/nome). Ficou `factions.js` como origem, e
   NÃO é preferência: os hexes das 5 compartilhadas são byte-idênticos nos dois,
   então nenhum pixel se move — mas lendo de `paleta.js` os Míticos ('M') sairiam
   `undefined`, que é o defeito de 07/08 de volta na facção que esta branch traz.
   Preservado da main: `bracadeiraDaFaccao()`, o `|| 0xffffff` deliberado, o
   ESPELHO vindo de `paleta.js`, e os comentários que explicam o bug.

2. `index.astro` ficou com a main INTEIRA. A lista de 37 módulos à mão da branch
   morreu: `moduleCacheManifest()` varre public/js e acha 45, os 5 mapas novos
   inclusive. A branch não definia `JS_REV`, que a linha comum já consumia — o
   lado dela estava quebrado de qualquer jeito.

3. `serve.mjs` — os dois lados consertaram o mesmo defeito por caminhos
   diferentes e as DUAS metades ficaram: o `JS_REV` da main (BUG-39) e a
   substituição genérica da branch. Só a da main devolve a fragilidade; só a da
   branch DERRUBA O BOOT, porque o guarda dela rejeitava `${JS_REV}`. Agora as
   variáveis são tabela. Provado isolado, 4/4 casos.

4. `gl-shots.mjs` deixou de ter lista literal de mapas: LÊ o registro. Era uma
   lista fixa em 5 enquanto o jogo foi a 10 — a raiz de os 5 mapas novos nunca
   terem sido fotografados por régua nenhuma.

5. Os .json de évidência ficaram de UM lado inteiro, marcados para regerar. O
   `map_check.json` parecia caso perfeito de mesclar por chave (chaves disjuntas)
   e NÃO era: a branch acrescentou o critério `map6` e as linhas da main não têm
   o campo. Mesclar anunciaria um critério que metade das linhas nunca mediu.

REVERTIDO POR MIM, e vale registrar por quê: eu havia renomeado os 5 mapas novos
(`fy_escadao` -> `escadao` etc.) junto do rename da main. Está desfeito. `LOOKS`
é indexada pelo id do REGISTRO; `AERIAL` e `GRAFITE`, pelo LITERAL que o builder
passa — e `map_corrego.js`/`map_lajes.js` ainda leem `GRAFITE?.fy_corrego` no
literal. Renomear só no registro faz `LOOKS` perder os 5 CALADO, caindo no
DEFAULT_LOOK da Brasília, sem erro no console. Fica como dívida anotada no
próprio `maps.js`: é mudança própria, com régua que case registro × LOOKS ×
AERIAL × GRAFITE.

Verificado (o merge anterior foi declarado pronto sem isto, e estava errado):
  syntax 41 arquivos OK · docs:check verde · arch:check verde · 0 marcadores
  registro × LOOKS × AERIAL × GRAFITE = os mesmos 10 ids
  check:fast 58 passos / check:deploy 17 — zero passo órfão
  BOOT REAL: `quebrada` chega em countdown, `fy_corrego` chega em LIVE, com
  main.js resolvendo `?v=2.0.0-alpha.83-b8ec20ba67d3` (V + JS_REV juntos)

PENDENTE: `paleta.js` cobre 5 facções e o elenco tem 10 — M/T/N/R/O (17
personagens) caem no NEUTRO cinza. Não quebra (o fallback é deliberado), mas
`faccao-paleta-check` F1 reprova com razão. As cores já existem em `factions.js`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
O padrão do dia: o instrumento acusava o jogo. Três vezes, e cada vez a
mentira parecia defeito de código ou de asset.

RÉGUAS NOVAS
  texel-check + custo/mutantes/tetos  densidade de texel nos 10 mapas
  char-pbr-check      (eval:charpbr)  metal/rough EFETIVOS nos 62
  char-plastico       (eval:charplastico) rugosidade no pixel via ?charprobe
  sky-seam-check + sky_seam.py        costura de wrap dos 8 céus
  escadao-rota-check                  conectividade de lance + oclusão de spawn
  relevo-check                        amplitude/declive/silhueta no motor
  corrego-superficie-check            % de material sem map, m² sem textura
  mapa-novo-gate      (eval:mapanovo) ortogonalidade + altura + superfície
  foto-vs-render + .py                14 descritores, foto real × render
  gl-poses + gl-poses.json            captura com pose declarada por mapa

INSTRUMENTOS QUE MENTIAM, consertados
  map-check MAP1 era o ÚNICO critério SEM cláusula de reprovação: imprimia
  `dentro 5, pior 1.384` e saía 0.
  mapa-id-check varria `.claude/worktrees/`, que está no .gitignore: 12
  ocorrências de uma branch abandonada deixavam o portão vermelho.
  select-inflate ganhou diagnóstico por osso e 4 ablações — foram elas que
  REFUTARAM a hipótese de que o balão era código.
  char-shade estava MORTO (spawns.P não existe na loja_h, recortes vazios,
  TypeError de mediana vazia).
  charlineup.html nunca chamava setCharacterRendererCapabilities: toda
  medição de personagem feita ali media o caminho WebGL1.

O QUE AS RÉGUAS PROVARAM, e economizou crédito do dono
  "62 personagens com PBR quebrado" -> 1. Fator ausente com canal azul zerado
  é inofensivo: medir a TEXTURA, nunca a declaração.
  "53 em KTX2, imedíveis" -> não existe KTX2 no elenco, é WebP.
  "é cromo" -> characters.js:370 descarta o metalness do GLB; era dielétrico
  liso, outro mecanismo.
  "o balão é o IK" -> desligar IK+curl move 0,0% na cuca e piora o mandrake
  em 21%. É asset, e são 6 personagens, não 62.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
O dono viu uma emenda vertical no fy_quebrada partindo a tela: metade quente,
metade cinza-azulada. Medido no frame 1500x1000: coluna x=812, ΔL* 7,70,
Δmatiz 77,5°.

NÃO era compressão e NÃO era o código. Estava no ASSET, na costura u=1→u=0:

  sky_quebrada    ΔL* 17,38 → 0,52     horizonte 33,05 → 1,10
  sky_joa        ΔL* -15,35 → -0,96    horizonte -42,30 → -2,10   (o da Mansão)
  sky_ferrovelho  ΔL*  6,47 → 0,49     horizonte 13,35 → 0,09
  sky_havan       Δb*  -8,16 → -0,60   horizonte -3,75 → 0,19

A prova de que map_sky.js está certo: sky_rj.webp passa pelo MESMO caminho com
ΔL* 0,13. A costura do sky_joa era 19,7x a maior aresta interna da imagem.

Rampa multiplicativa em luz linear e antissimétrica, sigma=3/k=6: a cor média
não deriva mais que 0,12 L* nos quatro. sigma=0 fechava melhor (0,26) mas
injetava estria ACIMA do ruído nativo — trocaria emenda por listra.

O resize do PIL grampeia a borda e REABRIA a costura (0,89 → 0,97);
reamostragem circular de 16 colunas resolveu (0,52).

Três subiram para 2048x1024. Custo total: +0,37 MB.
LIMITE DECLARADO: resolução não cria detalhe. O céu segue sub-amostrado 2,8x
contra os 16,2 px/grau da tela — some parte do borrão, não todo.

Régua: tools/eval/sky-seam-check.mjs, 2 mutantes. O segundo (`rampa-estreita`)
existe para impedir que um conserto futuro troque costura por BANDA com a
régua verde.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
…no jogou e viu

ESCADÃO — "3 escadas, 2 não levam pra lugar nenhum, e dá pra ver o andar do
respawn de cima". Estava certo, e era pior:
  lances úteis          2/7 → 7/7
  pontos altos que leem o spawn   203/1044 (19%) → 0/1050
  MAP2 exposição do spawn E       9,6% → 0,2%
A régua DESCOBRE os lances varrendo groundHeightAt em vez de ler world.stairs,
que declara 5 quando existem 7 — as escadas de beco, justamente as que o dono
contou, estavam fora da declaração.
DOIS ACHADOS ALÉM DO RELATO: a bandeira de CTF do Patamar 1 estava numa ILHA
INALCANÇÁVEL (fresta de 0,62 m contra 0,84 m do corpo), e as rotas de waypoint
dos becos atravessavam dois muros — os bots NUNCA tiveram aquela rota.
Causa do respawn exposto, medida: o parapeito do mirante tem 1,20 m e o olho
está a 1,62 m. Você olha por cima da sua própria mureta.
Consertado por GEOMETRIA, spawn intocado (lição do BUG-32).

CAMPO DO MORRO — "também sem topografia". O relevo NÃO existia: groundHeightAt
devolvia TRÊS valores em 93,6% do mapa. Uma malha de 17 mil triângulos
desenhando um plano com uma depressão de 8 cm.
  amplitude   1,08 → 4,10 m       plano 97,2% → 15,4%
  topo        8,33 → 20,17 m      subida contínua a pé 6,23 m
  botsim      stuck% 3,011 → 2,433 (-19%), latFlips de combate -25,6%
O latFlips bruto subiu 15,7% e a causa foi atribuída por A/B ao relevo (o bot
contorna curva de nível). Não recuei: stuck% é o número que a casa usa.

MANSÃO — corpoDentroDeSolido 5 → 0, pior penetração 1,384 m → 0, custo ZERO no
botsim (idêntico até a 3ª casa). Causa: três famílias de vegetação nasceram sem
`nonSolidSurface` que outras seis do MESMO arquivo já tinham, mais um pote de
cerâmica rígido sem colisor.
DOIS PALPITES REFUTADOS COM MEDIÇÃO: "move os 5 pontos" (varredura densa acha
87 células, não 5 — os 5 eram a fase da grade de 1 m) e "marca tudo
nonSolidSurface" (o pote tem 0 colisores e _collide empurra 0,0000 m).

DÍVIDA ANOTADA no maps.js: os 5 mapas novos seguem com prefixo `fy_` do
Counter-Strike que o PR #200 veio tirar. Renomear só no registro faz LOOKS
perder os 5 CALADO (AERIAL e GRAFITE são indexadas pelo literal do builder).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Ruben Marcus <8454267+rubenmarcus@users.noreply.github.com>
…,5) preso 0,9 m

O colisor do vão ia de x -4 a 4; mourões (±4,15) e motor (4,62) ficavam
fora, com collide:false — corpo andava dentro da geometria visível. Colisor
próprio no idiom do col() do portão; CTF2 e rotas intactos (map-check verde).

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
…JS_REV

Perdida no merge interno do PR (0293c32); a varredura genérica de attrs
resolve o template, mas o contrato SB7 ancora o mecanismo do BUG-39 nele —
o comentário do próprio arquivo manda mantê-la ("ISSO FICA"). Mutações
cache-* confirmadas mordendo.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
…dator entra como devDep

O dev script puro (astro dev) obedecia ao lock plantado pelo dev-port-check
e saía 0 sem segunda URL — o launcher com --ignore-lock/foreground existia
(eb1491b) e foi perdido no merge interno do PR. gltf-validator faltava nas
devDeps apesar do eval:gltf-validator-check existir.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
…exit

Saíam por fora do padrão da casa (push na lista ou flag no exit) — agora
mutacaoCega viaja no process.exit(), como o MC1 exige; exit-cego morde.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
#407

A main recomprimiu armas/personagens em d4cc21e (#407) DEPOIS que o PR
mediu os recibos — geometria bit-idêntica (hash de POSITION conferido:
m4 42f127b7f69e4ac4, camera-roxa 1b40659628a8f3d3), bytes diferentes.
Regenerados via build-camera-grip-source + blender-camera-grip-evidence
(Blender 5.2.0 LTS fbe6228777e7): walk/crouch melhoram (<=6 mm), idle
passa a ser medido — camera-roxa dá 35,4 mm no apoio (decisão de teto
pendente do dono, ver PR). finalSha256 da camera-roxa repinado com nota
de procedência; thumbnail do lenda-lanhouse capturado (360x463, M4
canônica do CHAR_WEAPON).

Commit-grande: 41 arquivos de evidência binária (PNG/GLB/JSON) — um recibo
por personagem não é divisível sem quebrar a árvore em estado em que o
gate lê recibo novo contra GLB velho.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
npm run docs + arch + grafite (5 mapas novos) + audio; map_check.json
vem do map-check do conserto do mansão; evidence maps/lajes é saída do
runner.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
…do dono)

UIR22/26/30 ancoravam o menu 4-itens com submenu ▸ MATA-MATA, ENVIE SEU
FEEDBACK com tick e legenda da prévia; o PR redesenhara em mode-cards e a
régua ficou vermelha. Dono escolheu a main (25/08): nav portada, wrap de
prévia com legenda restaurado, data-acts preservados (switch do main.js
intacto). Teto de apoio do idle da camera-roxa: 40 mm com procedência
(medição 35,4 mm, rig de mãos largas, recibo pós-#407).

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
…ene de travessão

CINE7 pinava os mode-cards que a decisão do dono tirou; a home passa a ser
guardada por UIR22/26/30 (menu) e os landmarks aqui são a vitrine
home-title-block/home-season. Mutante composicao-antiga continua mordendo.

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
Rodado pelo autofix: só arquivo gerado, conferido pela lista de permissão.

Signed-off-by: csbrasil-bot <csbrasil-bot@users.noreply.github.com>
@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: regenerei os blocos derivados e empurrei o commit. O PR não precisa de mais nada disso.

@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: regenerei os blocos derivados e empurrei o commit. O PR não precisa de mais nada disso.

@estraga-codigo estraga-codigo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Palhaço Mal

Palhaço Mal · revisor da casa · 🤡

mapa da mudança

  • assets (583): m.png, n.png, o.png, r.png
  • arnês (226): audit-character-voices-stt.mjs, blender-add-cultural-gear.py, blender-add-tv-badge.py, blender-alpha62-runtime-fixes.py
  • outros (80): openai.yaml, .gitignore, opencode.json, voice-lines.json
  • docs (57): SKILL.md, SKILL.md, SKILL.md, AGENTS.md
  • jogo (26): ambientlife.js, audio.js, bloom.js, brasoes.js
  • mapas (19): map_atacadao.js, map_brasilia.js, map_campomorro.js, map_corrego.js
  • site (9): jogo.ts, about.astro, characters.astro, como-jogar.astro

Tip

Risco BAIXO · nota 10/10 ▓▓▓▓▓▓▓▓▓▓

pente fino passado: nenhum achado que eu defenda em voz alta

Revisão de bot — fio não resolvido TRAVA o merge (a main exige conversa resolvida). Resolve ou refuta.

impacto cruzado

graph RL
  main_js["main.js"] --> audio_js["audio.js"]
  game_js["game.js"] --> bloom_js["bloom.js"]
  main_js["main.js"] --> bloom_js["bloom.js"]
  main_js["main.js"] --> bloom_js["bloom.js"]
  game_js["game.js"] --> brasoes_js["brasoes.js"]
  game_js["game.js"] --> characters_js["characters.js"]
  glbchars_js["glbchars.js"] --> characters_js["characters.js"]
  loading3d_js["loading3d.js"] --> characters_js["characters.js"]
  game_js["game.js"] --> fparms_js["fparms.js"]
  main_js["main.js"] --> fparms_js["fparms.js"]
Loading

(grafo local de public/js, uma rodada atrás do head do PR.)

todo bug confessa no diff, eu só faço o interrogatório 🤡

…ivadas com as ferramentas do branch

No clone limpo da Vercel, pixo-lajes-01.png (versionado, sem prefixo or-)
satisfazia a contagem >0 e o pack nunca baixava: 196 decalques faltando,
assert:assets derrubava o deploy. A marca .decals-pack-v2 só existe depois
de um download bom. Docs: o autofix do CI as regenerou com package.json da
BASE (124 scripts) numa árvore com 186 — branch voltou a ser consistente
consigo mesmo (o gate do autofix para PR da mesma casa vem em PR separada).

Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
Agent: OpenCode
@estraga-codigo

Copy link
Copy Markdown
Collaborator

Esbirro

Esbirro · plantão da produção · 🕵️

check vermelho parado neste PR

Caution

Não sei classificar este vermelho. Segue o que o CI cuspiu — palpite de bot sobre bug alheio só atrapalha.

o quê valor
head 41176ec00f5a
checks vermelhos 7
classe outra
hora do plantão 2026-08-25T01:57:23.852Z

Vermelho:

classify (https://github.com/corosolto/client/actions/runs/32798295206/job/97654017106)
portao (https://github.com/corosolto/client/actions/runs/32798047001/job/97653277565)
build (https://github.com/corosolto/client/actions/runs/32798046986/job/97653277593)
build (https://github.com/corosolto/client/actions/runs/32798047100/job/97653277852)
smoke (https://github.com/corosolto/client/actions/runs/32798046923/job/97653277135)
dco (https://github.com/corosolto/client/actions/runs/32798046986/job/97653277453)
Vercel (https://vercel.com/rubenmarcus-projects/csbrasil/D2ED2ZuTMKC1v7aQx3SCDRz11Yhz)

Rabo do log:

2026-08-25T01:38:45.8108459Z   GH_TOKEN: ***
2026-08-25T01:38:45.8108672Z   PR_NUMBER: 399
2026-08-25T01:38:45.8108886Z   DESIRED_BASE_BRANCH: staging
2026-08-25T01:38:45.8109200Z   pythonLocation: /opt/hostedtoolcache/Python/3.13.15/x64
2026-08-25T01:38:45.8109652Z   PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.13.15/x64/lib/pkgconfig
2026-08-25T01:38:45.8110089Z   Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.13.15/x64
2026-08-25T01:38:45.8110472Z   Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.13.15/x64
2026-08-25T01:38:45.8110860Z   Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.13.15/x64
2026-08-25T01:38:45.8111246Z   LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.13.15/x64/lib
2026-08-25T01:38:45.8111573Z ##[endgroup]
2026-08-25T01:38:45.8547185Z Traceback (most recent call last):
2026-08-25T01:38:45.8668201Z   File "/home/runner/work/client/client/scripts/ci/pr_classify.py", line 87, in <module>
2026-08-25T01:38:45.8669221Z     raise SystemExit(main())
2026-08-25T01:38:45.8669667Z                      ~~~~^^
2026-08-25T01:38:45.8670413Z   File "/home/runner/work/client/client/scripts/ci/pr_classify.py", line 39, in main
2026-08-25T01:38:45.8671284Z     files = [f["path"] for f in payload.get("files", [])]
2026-08-25T01:38:45.8671881Z                                 ~~~~~~~~~~~^^^^^^^^^^^^^
2026-08-25T01:38:45.8672436Z TypeError: 'NoneType' object is not iterable
2026-08-25T01:38:45.8729087Z ##[error]Process completed with exit code 1.


nada fora do normal no meu turno 🕵️

Agent: csbrasil-bot (autofix)

Signed-off-by: csbrasil-bot <csbrasil-bot@users.noreply.github.com>
Rodado pelo autofix: só arquivo gerado, conferido pela lista de permissão.

Agent: csbrasil-bot (autofix)

Signed-off-by: csbrasil-bot <csbrasil-bot@users.noreply.github.com>
@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: regenerei os blocos derivados e empurrei o commit. O PR não precisa de mais nada disso.

@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: regenerei os blocos derivados e empurrei o commit. O PR não precisa de mais nada disso.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 preview no ar → https://csbrasil-5brp2vo49-rubenmarcus-projects.vercel.app

@estraga-codigo estraga-codigo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Palhaço Mal

Palhaço Mal · revisor da casa · 🤡

mapa da mudança

  • assets (583): m.png, n.png, o.png, r.png
  • arnês (225): audit-character-voices-stt.mjs, blender-add-cultural-gear.py, blender-add-tv-badge.py, blender-alpha62-runtime-fixes.py
  • outros (81): openai.yaml, .gitignore, opencode.json, voice-lines.json
  • docs (57): SKILL.md, SKILL.md, SKILL.md, AGENTS.md
  • jogo (26): ambientlife.js, audio.js, bloom.js, brasoes.js
  • mapas (19): map_atacadao.js, map_brasilia.js, map_campomorro.js, map_corrego.js
  • site (9): jogo.ts, about.astro, characters.astro, como-jogar.astro

Tip

Risco BAIXO · nota 10/10 ▓▓▓▓▓▓▓▓▓▓

nada aqui que quebre amanhã. amanhã é outro diff

Revisão de bot — fio não resolvido TRAVA o merge (a main exige conversa resolvida). Resolve ou refuta.

impacto cruzado

graph RL
  main_js["main.js"] --> audio_js["audio.js"]
  game_js["game.js"] --> bloom_js["bloom.js"]
  main_js["main.js"] --> bloom_js["bloom.js"]
  main_js["main.js"] --> bloom_js["bloom.js"]
  game_js["game.js"] --> brasoes_js["brasoes.js"]
  game_js["game.js"] --> characters_js["characters.js"]
  glbchars_js["glbchars.js"] --> characters_js["characters.js"]
  loading3d_js["loading3d.js"] --> characters_js["characters.js"]
  game_js["game.js"] --> fparms_js["fparms.js"]
  main_js["main.js"] --> fparms_js["fparms.js"]
Loading

(grafo local de public/js, uma rodada atrás do head do PR.)

todo bug confessa no diff, eu só faço o interrogatório 🤡

@estraga-codigo

Copy link
Copy Markdown
Collaborator

Esbirro

Esbirro · plantão da produção · 🕵️

check vermelho parado neste PR

Caution

Não sei classificar este vermelho. Segue o que o CI cuspiu — palpite de bot sobre bug alheio só atrapalha.

o quê valor
head daa9249d1952
checks vermelhos 4
classe outra
hora do plantão 2026-08-26T03:36:27.130Z

Vermelho:

portao (https://github.com/corosolto/client/actions/runs/32926287190/job/98049755099)
build (https://github.com/corosolto/client/actions/runs/32926287209/job/98049755210)
dco (https://github.com/corosolto/client/actions/runs/32926287209/job/98049755091)
Vercel (https://vercel.com/rubenmarcus-projects/csbrasil/KHLunCzoqNMSiStEioY6CrkDKbdS)

Rabo do log:

2026-08-26T03:26:55.4842181Z   sertanejo     revolver38      0.188   0.461   1.035      3.4   3.11       11.3
2026-08-26T03:26:55.4842652Z   punk          ak         ik   0.211   0.389   1.014     3.12   3.55       10.6
2026-08-26T03:26:55.4843135Z   doidinho-bairro p90        ik   0.215   0.495   1.008     1.92   3.92       10.6
2026-08-26T03:26:55.4843642Z   pagodeiro     pistol           0.19   0.399    1.12     1.93   2.98       10.4
2026-08-26T03:26:55.4844150Z   lenda-lanhouse m4         ik   0.211   0.414   0.993     4.14   3.49         10
2026-08-26T03:26:55.4844613Z   et            awp             0.152   0.404   0.956     3.78   2.71        9.7
2026-08-26T03:26:55.4845262Z   funkraiz      shotgun    ik   0.198   0.488   0.976     1.75   3.62        8.6
2026-08-26T03:26:55.4845762Z   caminhoneiro  md97       ik   0.285   0.497   0.907     1.22    6.5        8.4
2026-08-26T03:26:55.4846236Z   raul          deagle          0.191   0.443   0.963      4.2   3.16        7.8
2026-08-26T03:26:55.4846699Z   designer-ux   m4         ik   0.178   0.378   0.769     3.68    2.6        7.3
2026-08-26T03:26:55.4847320Z   motoca-cachorro-loko m4         ik   0.294   0.623   0.978     2.26   6.88          7
2026-08-26T03:26:55.4847884Z   bandeirante   mosin      ik   0.185   0.393   0.869     3.21   2.78        3.7
2026-08-26T03:26:55.4848361Z   microfonildo  m4         ik       0       0       0        0      0          0
2026-08-26T03:26:55.4848622Z
2026-08-26T03:26:55.4848738Z REPROVADOS: 22/62
2026-08-26T03:26:55.4849023Z -> tools/eval/select_inflate.json
2026-08-26T03:26:55.4849210Z
2026-08-26T03:26:55.4850987Z PORTÃO VERMELHO — 22 reprovados, acima do teto declarado de 12.
2026-08-26T03:26:55.5026442Z ##[error]Process completed with exit code 1.


de plantão: vi, registrei, hora no relógio 🕵️

@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: a base andou e o conflito encostou em arquivo de código — não é meu para resolver. Os arquivos em conflito estão no log do run; rode git merge origin/main e decida.

1 similar comment
@csbrasil-BOT

Copy link
Copy Markdown
Collaborator

🤖 autofix: a base andou e o conflito encostou em arquivo de código — não é meu para resolver. Os arquivos em conflito estão no log do run; rode git merge origin/main e decida.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Assignees

Couldn't load assignees.