Documentação
SDK Câmera
Câmera de ombro, terceira pessoa e primeira pessoa para jogos em three.js. Não conhece nenhum jogo: recebe o alvo e uma função de colisão.
const rig = CameraModosSDK.criar(THREE, { chave: 'meu-jogo-camera', nomes: { ombro: 'ombro (Q troca)' } });
rig.seletor(document.querySelector('#menu'), 'Câmera'); // seletor pronto, opcional
// a cada quadro
rig.atualiza(camera, { x, y, z, yaw, pitch, mira, agachado }, dt,
(ox, oy, oz, dx, dy, dz, max) => distanciaAteParede ?? null, // colisão (opcional)
(x, z, y) => alturaDoTeto); // teto (opcional)
if (rig.primeiraPessoa()) { rig.viewmodel(grupoDaArma, camera); /* esconda o corpo do jogador */ }
rig.ciclar(); rig.trocaLado(); rig.setModo('terceira'); rig.aoMudar(m => ...);
Convenções: yaw 0 olha para -z; pitch positivo olha para baixo; a arma tem o cano em +z. Tudo que é número (distâncias, alturas, posição do viewmodel) se ajusta em criar(THREE, { ombro: {...}, terceira: {...}, primeira: {...}, viewmodel: {...} }).
No ZombiAdA o adaptador é implementacao/jogo-web/src/91-camera.js (tecla O, seletor no menu, esconde o corpo em primeira pessoa).
SDK Modo livre (ferramenta de teste)
Arquivo: modo-livre.js. Genérico, não conhece nenhum jogo. O build.py do jogo inclui tudo de sdk/*/*.js antes do src/.
const ML = ModoLivreSDK.criar(THREE, {
chaveMarcas: 'meujogo-marcas', arquivo: 'marcas.txt', equipes: [['mapa','Mapa']],
area: (x, z) => 'nome da área', hora: () => '12:00', msg: (texto, s) => {},
pos: () => ({ x, y, z, yaw, pitch }), limites: { x: [-500, 500], y: [0.4, 260], z: [-500, 500] },
pausa: aberto => {}, // true ao abrir painel (soltar mouse, pausar), false ao fechar
});
ML.chave('id', 'Rótulo', get, set) // liga/desliga no painel (set devolve true para fechar o painel)
.acao('id', 'Rótulo', fn) // botão (fn devolve true para manter o painel aberto)
.horasDoDia([['Manhã', 0.3]], setHora)
.lugares(() => [['Grupo', [['Nome', ir]]]])
.etiquetasDe(cam => [{ x, y, z, texto, cor }])
.cenarios(lista, aplicar, checar); // checar(c) -> { critério: { ok, nota } }
ML.irPara = (x, y, z, yaw, pitch) => {};
// a cada quadro: ML.voa(dt, yaw, pitch, { frente, lado, sobe, rapido }) e ML.cameraVoo(camera, yaw, pitch) quando ML.voo;
// ML.atualiza(dt, camera, visivel). Teclas ficam no jogo: ML.abre('form' | 'lista'), ML.fecha().
ML.expoe(); // window.__cenario, __cenCheck, __cenLista, __modoLivre para Playwright
Marcas: salvas no banco do artifact (db, coleção marcas) quando houver, senão no localStorage, com copiar e baixar. Exemplo de adaptador: implementacao/jogo-web/ferramentas/92-explorar.js (ZombiAdA).
PlantasSDK
SDK genérico, sem nada de jogo específico, para plantas de casas e lotes. As posições dos móveis são gravadas (slots) e os itens são sorteados nelas com semente, então nenhuma casa repete o mesmo padrão. JS puro, sem imports: plantas.js é um IIFE que define const PlantasSDK.
Coordenadas
u corre ao longo da fachada (0..w); v vai da rua para os fundos (0..d). A sala fica na frente.- Lote:
v < 0 é o recuo frontal (jardim/garagem), v > d é o quintal, u < 0 e u > w são as laterais. - Retângulos são
[u0, v0, u1, v1]. Nos móveis, x == u e z == v (centro). Medidas em metros. - A frente do móvel é o vetor
(fu, fv). ry = atan2(fu, fv), igual ao olha(du, dv) do jogo com inw = 1. Se a rua do jogo estiver invertida, use ry = atan2(fu, inw * fv).
API
PlantasSDK.gerar(template, {w, d, semente, estilo, andar}) devolve {comodos, paredes, portas, janelas, moveis, fachada, lote, andares, faltando}. Mesmo template, medidas e semente dão o mesmo resultado.moveis[]: {id, tipo, categoria, x, z, ry, w, d, h, y, fu, fv, comodo, andar, externo, slot, sobre, modo, aabb, liga?}. y é a altura da base (itens sobre outro). externo marca itens do lote (andar -1). liga marca a escada entre andares.paredes[]: segmentos com lados (cômodo de cada lado ou 'fora'), ext, tipo (parede ou guardacorpo), andar. As portas já abrem o vão; a verga é do jogo.portas[]: {u, v, eixo, larg, a, b, abre, ext, modelo: folha|dupla|aco, folhas, zonas}.janelas[]: {u, v, eixo, larg, y0, y1, comodo, lado}.fachada: {cor:{nome,hex}, acabamento: reboco|chapisco, grades, telhado: colonial|fibrocimento|laje, sacada, portaAco}.lote: {rect, zonas, perimetro, portoes, caminhos, piscina}. Cada perimetro[] tem tipo (muro|cerca|grade), material, altura, topo (nada|caco|concertina|grade) e alturaTotal: é o que as regras de escalada usam. portoes[]: {tipo: social|garagem|carga, modelo: pedestre|basculante|correr, u, v, larg, altura, para}. caminhos[]: faixas reservadas do portão até a porta (pedestre) ou até a vaga/garagem (veículo).faltando: slots obrigatórios que não coube colocar (deve vir vazio).
PlantasSDK.slots(template, {w, d}): as posições gravadas, para revisão. Cada slot tem x, z, w, d, aabb, fu, fv, ry, âncora, cats, obrigatorio, prob, folga, frente, grupo, requer, sobre, valido e motivo (quando inválido).PlantasSDK.validar(res) devolve erros em português. listarTemplates(), catalogo, biblioteca, estilos, templates.registrarTemplate(t), registrarItem(def), registrarBiblioteca(tipo, fnOuLista).
Estilo (estilo: 'popular' | 'nobre' | 'comercial')
Muda alturas e topos dos muros, tipos de portão, paleta e materiais da fachada. O padrão vem do template. Tudo fica em PlantasSDK.estilos (dados). Popular: muro de bloco 1,8 m, portão de ferro, grades nas janelas. Nobre: muro 2,8 m com concertina ou grade. Comercial: porta de aço, sem jardim, fundos de serviço.
Regras de colocação
Nenhum móvel invade 0,9 m em frente a portas e portões; itens altos (h > 1,0) ou com janela:false nunca ficam em frente a janelas; sem sobreposição; há caminho em grade da porta (ou portão) ao centro do cômodo; frente voltada para dentro; folga na frente do móvel; piscina com aro livre de 1,2 m. Os caminhos reservados entre portão e porta ficam livres. Um slot de parede pode deslizar até 2 m ao longo da parede para escapar de porta e janela. tapete é plano e não colide.
Como adicionar
- Item:
PlantasSDK.registrarItem({tipo:'sofa4', categoria:'sofa', w:2.2, d:0.95, h:0.85, frente:'+z', janela:false, baixo:false}). O tipo é o que o jogo mapeia para a malha. - Slot: em
Biblioteca[tipoDoComodo] (ou registrarBiblioteca), com os construtores: P(id, lado, pos, [w,d], {categoria:peso}, opções) parede (lado: esq|dir|frente|fundo|qualquer), C(id, 'fundo-esq', ...) canto (aceita qualquer), Z(id, fx, fz, ...) centro (fração do cômodo, com dx, dz em metros), J(id, ...) sob janela, SB(id, paiSlot, ...) sobre outro item, DT(...) dentro. Opções: obrigatorio, prob, folga, frente (centro, porta, alvo + alvo:'slot', ou u+ u- v+ v-), grupo (alternativas: só uma é usada), requer. O cômodo pode ajustar por ajustes:{slot:{...}} (ou null para remover), sem:[ids], extras:[...], lib:'outraBiblioteca'. - Template:
registrarTemplate({id, nome, estilo, limites:{w:[a,b], d:[a,b]}, padrao:{w,d}, lote:(w,d)=>cfg|null, andares:[{nome, pe, abertos, comodos(w,d), portas(w,d), janelas(w,d)}]}). Cômodos: {id, tipo, nome, r:[u0,v0,u1,v1], partes:[...] (cômodo em L)}. Portas: {a, b:'fora'|id, lado, c, larg, abre, aco}; sem c, centraliza na parede comum. Janelas: {comodo, lado, c | n, larg, y0, y1}. lote devolve {rf, ml, mr, qf, vaga, garagem, social, carga, piscina, libs}.
Templates
casaA (4 cômodos), sobrado (2 andares, 13 cômodos), mercado (5), farmacia (5), apartamento (7, sem lote, andar opcional) e mansao (10, com piscina e jardim grande).
Como o jogo se pluga
- Concatene
plantas.js no módulo e chame const r = PlantasSDK.gerar('casaA', {w: b.w, d: b.d, semente: b.id}). - Converta
(u, v) para o mundo: X = b.x + u, Z = front + inw * v. Para a frente use ry = Math.atan2(m.fu, inw * m.fv). - Mapeie
m.tipo para a sua malha (um mapa tipo -> fábrica). Use m.w, m.d, m.h como pegada, m.y para itens sobre outros e m.categoria para o loot. - Monte paredes de
r.paredes (altura do andar em r.andares[i].pe), vergas sobre r.portas, janelas de r.janelas, e o perímetro de r.lote.perimetro com altura/topo. - Para revisar as posições gravadas use
PlantasSDK.slots(...) ou o visor-plantas.html.
Arquivos
plantas.js (SDK), teste.mjs (node teste.mjs), visor-plantas.html (visor offline; node montar-visor.mjs reembute o plantas.js), shots.mjs (capturas com Playwright).
Revisão final ZombiAdA: checklist de consistência e orçamento de desempenho
Rascunho de trabalho da revisão final (22/10/2026). O relatório consolidado sai como página quando os times terminarem. Fontes lidas: briefs de zumbis (Bestiário v12), veículos, mapa (fatia Jardim Aurora), personagens, guia de estilo do corpo, sobreviventes/destino, VFX, explosões, Arsenal (página).
PC alvo: GTX 1060 6 GB / RX 580, Ryzen 5 2600 (6 núcleos/12 threads), 16 GB RAM, 1080p médio. Host é jogador e servidor ao mesmo tempo.
1. Inconsistências encontradas (primeira passada)
Bloqueadoras (precisam de uma decisão única antes de codar)
| # | Tema | O que diverge | Proposta da revisão | Dono |
|---|
| B1 | Pilha de rede | Zumbis: Netcode for Entities / Unity Transport. Veículos e personagens: Netcode for GameObjects. Mapa: NGO ou Mirror. | Uma pilha só: Unity Transport com host autoritativo. Zumbis/multidão em Entities replicados por lote próprio (snapshot quantizado); jogador, NPC e veículo como entidades leves no mesmo transporte. Nada de Mirror. | Revisão (decisão de engine com o usuário) |
| B2 | Modelo de dano | Três modelos diferentes: Bestiário (vida 100, multiplicadores por região, integridade de membro 40%/35%), Arsenal (vida 100, corredor 80, cabeça 40, braço 45, perna 55, PEN em pontos), Guia do corpo (segmentos 40/120/90/60/45/25/80/55; "zumbi só cai com a cabeça a 0"). Pela regra do Guia, tiro no tronco nunca mata, o que contradiz "Brutamonte cai no 4º tiro de 5.56 no tronco". | Um modelo: vida total (Bestiário) decide a morte por tronco; segmentos (Guia) decidem desmembramento; penetração por pontos PEN (Arsenal) com custo por corpo e Brutamonte = 2 corpos. Arsenal é a fonte dos números das armas. | Armas + Zumbis + Personagens |
| B3 | Números das armas | 5.56: 55 (Bestiário) × 45 (Arsenal). .308: 85 × 75. 9 mm: 35 × 30 (Guia). Machado: 50 × 85. 12 ga: 9×12 × 95. | Arsenal vale para armas de fogo; o Bestiário recalcula o aceite do M2 (Brutamonte 220 cai em 5 tiros de 5.56 a 45, não 4). Armas brancas: abrir tabela única no Arsenal. | Armas |
| B4 | Velocidades e perseguição | Corredor 5,5 m/s (Bestiário e mapa) × 6,0 (Personagens). Lento 1,4 × Andador 1,2 × andante 1,4. Jogador AGI 3 corre 5,56 m/s: mais rápido que o Corredor base de 5,5, então o aceite do M1 de Personagens ("corredor alcança em <15 s") só funciona por causa do fôlego (70 pontos, 12/s = 5,8 s). | Bestiário é a fonte (Lento 1,4, Corredor 5,5 com modificadores até 6,5). Personagens reescreve o aceite do M1 contando o fôlego e o Corredor Fresco/Jovem. | Personagens |
| B5 | Tempo de infecção e reanimação | Personagens/Sobreviventes: morte em 48 h de jogo, reanima em 2–6 min. Bestiário: reanima em 2–4 min. Mapa (fatia): mordida mata e reanima em 120 s. Cena de teste v2: 30 s. | 48 h de jogo e 2–4 min. Fatia e cena de teste usam aceleração de debug, explícita no brief. | Zumbis + Mapa |
| B6 | Tempo de jogo × tempo real | Dia de jogo = 60 min reais. "Corpos 15 min", "sangue seca em 10 min", "incêndio 10 min", "partes somem em 15 min de jogo" (Guia) × "60 s" (Arsenal). 15 min de jogo = 37 s reais. | Toda duração ganha unidade: s_real para cosmético e desempenho (corpos, poças, detritos, partes), h_jogo para sistemas de mundo (infecção, fome, destino). Corpos e partes: 15 min reais. | Todos |
| B7 | Número de jogadores | Zumbis, mapa e veículos: 4. Personagens e sobreviventes: 2 a 8. | Orçamento abaixo fecha com 8 na LAN se o teto global de zumbis materializados for respeitado. Aceite de cada time mede com 4 e com 8. | Revisão |
| B8 | Banda de rede | 22–30 KB/s (teto 64), ≤64 KB/s, 256 kbps (=32 KB/s) por cliente. | Típico ≤32 KB/s, pico ≤64 KB/s por cliente (seção 3). | Todos |
Importantes
| # | Tema | Divergência | Proposta |
|---|
| I1 | LOD de simulação | Zumbis L0 <35 m, L1 35–120, L2 120–400, L3 >400 (histerese 10 m). Mapa: navmesh individual <30 m, sync 10 Hz 16 bits/eixo. NPCs 80/300 m (histerese 20 m). Veículos dormem >60 m. | Um único sistema de relevância (seção 4), com faixas por tipo de agente mas o mesmo cálculo de distância ao jogador mais próximo. |
| I2 | Taxa de replicação dos zumbis | Bestiário: 20 Hz em L0, 5 Hz em L1, delta 3–5 bytes. Mapa: 10 Hz para todos, 16 bits/eixo. | Bestiário vale; o mapa remove a própria regra. |
| I3 | Triângulos do zumbi | Bestiário: 300–800. Guia do corpo: 2.500–5.000 com LOD 100/40/15%. | LOD0 2.500 (só os ~40 mais perto), LOD1 1.000, LOD2 400, LOD3 impostor/150 (>120 m). Ver seção 2. |
| I4 | Animação | 2.000 por VAT, mas a "cascata" por junta (Animation Rigging) e o pêndulo do membro pendurado são por osso. | Cascata e pêndulo no shader VAT como atraso por junta (amostra o clipe com offset por osso) para todos; Animation Rigging só para os ≤32 em L0 mais perto. |
| I5 | Ragdolls | Bestiário 12 simultâneos, veículos pool de 24, explosões 12. | Teto global 16, pool 24 (veículos herdam o pool global). |
| I6 | Partes soltas | Guia: 40 no mapa, 15 min. Arsenal: 40 por jogador, 60 s. | 40 por jogador até 160, somem com o corpo (15 min reais) ou ao reciclar o mais antigo fora da vista. |
| I7 | Percepção e barulho | Bestiário: raios por categoria (Lento ouve 40 m). Mapa: eventos com raio (pistola 60, espingarda 90). Veículos: eventos com raio. Arsenal: "ruído" qualitativo. | Barulho é evento {posição, raio}; categoria aplica multiplicador de audição. Arsenal converte "médio/alto/extremo" em metros. |
| I8 | Porta e barricada | Mapa: porta 300 de vida, 10 por golpe a cada 1,5 s. Bestiário: pressão por corpo (1 / 1,5 / 3) e Brutamonte 3× em porta. | Golpe direto (mapa) para quem está na vaga de ataque + pressão da pilha (Bestiário) somada. |
| I9 | Nomes dos tipos | Lento / Andador / andante. 8 tipos na tabela 3.1 e 13 na rodada 4 do Bestiário. | "Lento" em todo lugar; Bestiário reescreve a 3.1 com os 13 tipos e a composição nova. |
| I10 | Nascimentos e histórias cruzadas | Sobreviventes só tem chegadas por reposição; não há nascimentos, casais, rivalidades nem efeito de uma base na outra. | Em andamento no time de Sobreviventes. Orçamento da seção 5 vale para a versão nova. |
| I11 | População total do mundo | Ninguém definiu quantos zumbis existem no Vale (32×32 km) nem o teto de materializados com jogadores espalhados. | Seção 4: população por bloco de 64 m em dados, teto global de 2.000 materializados, dividido entre jogadores. |
| I12 | Brief de zumbis | Duas seções "12" e tabelas 3.1 e 12.1 que divergem. | Renumerar e deixar só a tabela atual. |
2. Orçamento por quadro (host, 60 FPS = 16,6 ms)
CPU (o host é servidor e cliente)
| Sistema | Thread principal | Workers (Jobs/Burst) | Observação |
|---|
| Zumbis: percepção, IA, flow field, multidão, pilha | 0,6 ms | 3,0 ms | 2.000 materializados; L0 a 20 Hz, L1 a 5 Hz, espalhados por quadro |
| Física (jogadores, ≤8 veículos, ≤16 ragdolls, detritos) | 1,5 ms | — | Detritos dormem em 2 s |
| Tiros e penetração (RaycastCommand em lote) | 0,3 ms | 0,3 ms | Teto de 64 disparos por quadro |
| NPCs (até 104, LOD completo ≤20) | 0,4 ms | 0,3 ms | Utilidade reavaliada a cada 0,5 s escalonada |
| Destino e histórias (tick diário) | 0,0 ms | ≤2 ms por dia, fatiado | Fatiado em 0,1 ms por quadro, sem pico |
| Veículos | 0,5 ms | — | 8 simulados |
| Rede (snapshot, compressão, envio a 7 clientes) | 1,0 ms | 0,5 ms | 30 Hz |
| Relevância/LOD e streaming de setor | 0,5 ms | 0,5 ms | Setores de 2 km, origem flutuante |
| Animação (rigs dos próximos) | 0,8 ms | 0,5 ms | VAT para o resto não custa CPU |
| VFX (eventos, pools) | 0,8 ms | — | Conforme Oficina |
| Áudio | 0,5 ms | — | 24–32 vozes + multidão agregada |
| Mapa vivo (eventos, clima, animais) | 0,3 ms | 0,2 ms | ≤40 animais materializados |
| Jogabilidade, UI, outros | 1,5 ms | — | |
| Total principal | 8,7 ms | | Sobra ~3 ms; o render thread é separado |
| Render thread (submissão, culling) | 4,0 ms | | SRP Batcher + GPU instancing |
GPU (GTX 1060)
| Item | Típico (60 FPS) | Pior caso 2.000 zumbis (30 FPS) |
|---|
| Mundo (terreno, prédios, props, vegetação) | 5,0 ms | 6,0 ms |
| Sombras (direcional 2 cascatas + lanterna local) | 2,0 ms | 2,5 ms |
| Zumbis (VAT instanciado) | 1,5 ms | 6,0 ms |
| Jogadores, NPCs, veículos | 1,0 ms | 1,5 ms |
| VFX + decalques + fluidos (compute) | 2,5 ms | 4,0 ms |
| Pós (bloom, neblina, efeitos de tela) | 1,5 ms | 1,5 ms |
| UI | 0,3 ms | 0,3 ms |
| Total | 13,8 ms | 21,8 ms |
Geometria e chamadas
| Item | Teto |
|---|
| Triângulos na tela | ≤2,5 M típico, ≤3,5 M pior caso |
| Zumbis (2.000): 40×2.500 + 160×1.000 + 800×400 + 1.000×150 | ≈ 0,73 M |
| Batches SRP | ≤1.500 (≤400 na rua, como pede o mapa) |
| Set pass | ≤150 |
| Zumbis | ≤40 draw calls (malha × LOD × material de paleta 256²) |
| VRAM | ≤3,5 GB · RAM ≤6 GB |
3. Orçamento de rede (por cliente, 30 Hz)
| Fluxo | Conta | KB/s |
|---|
| Zumbis L0 (≤60 perto do cliente) | 60 × 20 Hz × 5 B | 6,0 |
| Zumbis L1 (≤300) | 300 × 5 Hz × 4 B | 6,0 |
| Grupos L2 (centróide) | 50 × 1 Hz × 8 B | 0,4 |
| Jogadores (7 outros) | 7 × 30 Hz × 20 B | 4,2 |
| NPCs completos (≤20) | 20 × 20 Hz × 8 B | 3,2 |
| Veículos relevantes (≤8) | 8 × 30 Hz × 24 B | 5,8 |
| Eventos (impacto 12 B, explosão 16 B, som) | ~100/s em combate | 1,2 |
| Cabeçalhos UDP/transporte | 30 × 28 B | 0,8 |
| Total | | ≈ 27,6 KB/s (meta ≤32, teto 64) |
Upload do host com 8 jogadores ≈ 190 KB/s (1,6 Mbps), sem problema em LAN. Cosmético nunca vai pela rede (semente).
4. Relevância única (mapa vivo + hordas)
| Faixa | Distância ao jogador mais próximo | Zumbis | NPCs | Veículos | Rede |
|---|
| R0 | 0–35 m | IA completa 20 Hz, hitboxes, pilha, rig dos 32 mais perto | completo (até 80 m) | simulado | 20 Hz |
| R1 | 35–120 m | flow field 5 Hz, 1 cápsula | completo/simplificado | dorme além de 60 m | 5 Hz |
| R2 | 120–400 m | grupos de 8–32, 1 Hz | simplificado (até 300 m) | dorme | centróide 1 Hz |
| R3 | >400 m | dados por bloco de 64 m, 0,2 Hz | abstrato (tick por hora de jogo) | dados | nada |
- Histerese de 10 m para zumbis e 20 m para NPCs, como nos briefs.
- Teto global de materializados (R0–R1): 2.000 zumbis. Com jogadores espalhados, o teto se divide pela área de cada um; a horda que passa do teto fica em R2 como grupo e vai sendo materializada pela borda.
- População do mundo em R3: dados por bloco (≈40 B por bloco, 250 mil blocos = 10 MB). A migração semanal de 1.000+ é um grupo R3 que só materializa perto de jogador.
- Mapa vivo (eventos, clima, animais) roda no mesmo relógio: eventos são dados em R3 e só viram entidades em R0–R1.
5. NPCs vivos e histórias
- Até 13 bases × 8 moradores = 104 NPCs, mais nascimentos (bebê é dado, não agente, até virar criança jogável fora do build).
- Tick diário de destino (pontos de virada, risco, luto, relações cruzadas, nascimentos) ≤2 ms no total, fatiado em quadros.
- LOD completo ≤20 NPCs ao mesmo tempo; o resto em simplificado (decisão a cada 2 s) ou abstrato.
- Fofoca e memória: 30 entradas × 104 NPCs, cabe em memória sem custo.
6. Próximos passos
- Acompanhar os times que ainda trabalham (Zumbis, Mapa, Armas, Veículos, Personagens, Sobreviventes, Fluidos, Cena de teste) e revisar cada entrega no navegador.
- Mandar as correções B1–B8 e I1–I12 às threads donas.
- Relatório consolidado em página.
- Marco 1: teste de estresse de 2.000 zumbis + bloco do mapa vivo medindo FPS (protótipo three.js agora; engine depois da decisão).
7. Situação em 22/10, 06h
- Relatório consolidado publicado como documento: ../jogo/revisao-final-fatia-jogavel.html
- Fatia jogável na versão 7: ../jogo/zombiada-jardim-aurora.html
- Mapa alinhou B1, B5, B7, I1, I2, I8, I9 e I11 (documento v8).
- Abertos: 9 mm (30 × 35), Corredor 5,5 × 6,0 em Personagens e a folga do aceite M1 (14 m declarados, ~11 m na conta: 6,96 × 6,46 m/s por 7,7 s).
Regras de documentação e prévias do ZombiAdA
Regra pedida pelo Anderson em 22/10/2026: pode publicar online, mas sempre existe uma cópia local atualizada na pasta do projeto.
A regra
- Toda documentação, prévia, protótipo ou página publicada online (artifact do claude.ai, Claude Doc) tem uma cópia em
docs/offline/, na pasta do time. - A cópia é atualizada no mesmo turno em que a versão online muda. Publicou uma versão nova, regrave a cópia local logo em seguida.
- A cópia abre com dois cliques, sem internet, e não perde nada: 3D, animações, interações, sons e fontes.
- three.js, addons (OrbitControls etc.), fontes e todo o código vão embutidos no próprio HTML. Nada de CDN, Google Fonts ou
<script src> externo. - Páginas com
<script type="module"> + importmap não carregam módulos externos em file://: o three.module.js vai embutido dentro do próprio módulo (o build_offline.py já faz isso). - Página com vários arquivos (ex.: Garagem) vira um HTML só.
- Claude Docs são exportados para HTML.
- Links entre páginas apontam para as cópias locais, em caminho relativo. O link para a versão online fica só no índice.
- Toda página nova entra no índice
docs/offline/index.html e no Portal das Equipes (portal/fonte/portal.html, entrada ["offline", "docs/offline/..."] em files, depois rodar python3 portal/fonte/build.py e republicar o portal). - Antes de dar por pronto: abrir a cópia com a rede bloqueada e conferir que não há erro no console nem requisição externa.
Onde fica cada coisa
| Time | Pasta local |
|---|
| Jogo | docs/offline/jogo/ |
| Mapa | docs/offline/mapa/ |
| Zumbis e personagens | docs/offline/zumbis-personagens/ |
| Sobreviventes e facções | docs/offline/sobreviventes/ |
| Armas e itens | docs/offline/armas-itens/ |
| Veículos | veiculos/garagem.html e veiculos/frota.html (mantidos pelo time de veículos) |
| Efeitos | docs/offline/efeitos/ |
| Animais | docs/offline/animais/ |
| Arte geral | docs/offline/arte/ |
Como regenerar
docs/offline/ferramentas/build_offline.py converte a página publicada numa cópia offline:
- Baixe a versão publicada de cada página para
ferramentas/raw/<nome>/index.html (o nome de cada pasta está na tabela PAGES do script). - Rode
python3 ferramentas/build_offline.py docs/offline (precisa de internet só para buscar as fontes do Google uma vez; o three.js está em ferramentas/lib/). - Teste aberto sem rede.
Nada encontrado nesta busca.