Explicador animado (motion graphics 3D por código)
Tudo é código: cada parte do vídeo é um mundo 3D (escena/partes/<parte>.js) que é função pura do tempo,
motor.js decide qual é exibida e desenha as legendas karaokê, e render.mjs pede ao Chrome sem janela cada quadro.
Nada é editado manualmente: se algo der errado, corrige-se o código e renderiza-se novamente.
Onde fica tudo: HOME3D = $EXPLICADORES_3D ou, se não existir, ~/.explicadores-3d (criado pelo instalador). Lá
ficam biblioteca/ (modelos 3D, vendor/ com three.js, fontes) e uma cópia desta skill. SKILL_DIR = a pasta
deste SKILL.md.
| Arquivo | Para quê |
|---|---|
nuevo.py <pasta> | Cria o projeto com o template (motor, estilo, lib2d, three.js, fonte Fredoka, scripts de voz/tempos/áudio, uma parte de exemplo, CONTRATO.md em branco e DECISÕES.md) |
render.mjs | --folha, --probe a,b,c, --range a,b, --metade, --sub N, --rapido, --sem-gpu |
entregar.py <projeto> <NOME> --ronda N [--escritorio] | Vídeo + áudio, versão de celular < 29 MB, folhas de revisão a cada 0,5 s e dados.txt (duração, LUFS, pico) |
revisar_folha.py <projeto> [--trecho a,b | --ronda N | --quadros …] | Revisão automática em ~5 s e sem tokens: texto duplo em fusões, halos, gêmeos (parecem olhos), brancos queimados, manchas, fora de zona, saltos de brilho |
ENCARGO_CONSTRUTOR.md | Template do encargo curto de construtor (uma parte por agente) |
ENCARGO_REVISORES.md | Revisores A (retenção), B (dados), D (imagem) sobre a folha e o vídeo |
Requisitos: Node 18+, npm install playwright-core no projeto, Chrome (ou CHROME_PATH, ou
npx playwright install chromium), Python 3.10+ com numpy e faster-whisper, e ffmpeg.
Regras da casa
- Zero dados inventados: cada número com sua fonte no CONTRATO antes de construir.
- Sem mascotes nem objetos com olhos, e sem formas que pareçam olhos (ver "Erros típicos").
- Estilo padrão: um objeto limpo sobre fundo escuro com halo quente, câmera macro sempre em movimento suave, palavra-chave em dourado, legendas karaokê de toda a narração, loop no primeiro quadro.
- Ritmo: 3,0-3,2 palavras/s, uma mudança de enquadramento a cada ~3 s, nada parado por mais de 5 s, gancho antes de 4,5 s.
- Duração: 15-30 s se for solto; mais de 60 s apenas se for parte de uma série com nome e número.
O fluxo
python SKILL_DIR/nuevo.py <tema>-AAAA-MM(cria a pasta no diretório atual). Abra e teste se aparece:npx http-server escena -p 8080(oupython -m http.serverdentro deescena/) e acesselocalhost:8080.- Roteiro com a skill
guion: pesquisa com fontes, MAPA, Rodada 0 (A ≥ 9, C ≥ 9, máx. 2 rodadas) e pareROTEIRO PRONTO. Não continue sem o OK do usuário. - Narração (gasta créditos ou tempo de CPU, por isso vai depois do OK):
- ElevenLabs:
export ELEVENLABS_API_KEY=...(o usuário define; nunca escreva num arquivo) epython scripts/voz_eleven.py [--voz <id>]→voz/tomas_eleven/. Plano gratuito = sem uso comercial e com crédito. - Grátis e local:
pip install kokoro soundfile(+espeak-ngdo sistema) epython scripts/voz_local.py [--voz em_alex]→voz/tomas_local/. python scripts/verificar_voz.py(Whisper large-v3, uma vez e em segundo plano) marca palavras mal ditas.python scripts/tempos.py --tomas tomas_eleven(outomas_local) →voz/voz_completa.wav,escena/beats.js(segundo de cada palavra-chave, conformevoz/chaves.json) eescena/palavras.js(karaokê).
- ElevenLabs:
- CONTRATO completo (
escena/CONTRATO.md): partes com seus trechosB.*, o que se vê em cada chave, letreiros exatos, dados com fonte, zona segura, ritmo. É a única coisa que os construtores leem: o que não estiver lá eles adivinham. Altere emmotor.jsoPLAN(ordem das partes e transições) eCHAVE(palavras douradas do karaokê). - Modelos 3D: antes de modelar, busque na biblioteca (skill
biblioteca,HOME3D/biblioteca/CATALOGO.md) e copie o que servir paraescena/modelos/. O que faltar é feito por um único agente (modelo compartilhado, esforçomedium, limite 150 k) e avisa commodelos/PRONTO_<objeto>.txt. - Construtores, com
ENCARGO_CONSTRUTOR.md:- uma parte por agente (uma cena de ≤ 15 s), em segundo plano, máximo 3 ao mesmo tempo;
- encargo curto: apenas seu trecho, seus modelos com a API em uma linha e as regras; o construtor não lê o motor nem o CONTRATO completo;
- com o bloco "Erros típicos" e o "Limite do construtor" colados exatamente como estão;
- um construtor fresco por rodada de correções, nunca continuar conversando com um que já passou de 40 turnos;
- nunca deixá-los "esperando" outro agente: primeiro o modelo compartilhado, depois as partes.
- Folha antes do render:
node render.mjs --folha(um quadro por beat: o roteiro visual) epython SKILL_DIR/revisar_folha.py .. VERMELHO = corrigir com um agente frescolowantes de continuar. Depois revisores A, B e D sobre a folha (ENCARGO_REVISORES.md, Rodada 1), com a saída derevisar_folha.pycolada no encargo de D. python scripts/audio.py→audio/mistura.wava -14 LUFS (música e efeitos sintetizados; editeEFEITOSeMUDANCASno início do arquivo).- Render para iterar:
node render.mjs --rapido --sub 1. Depoispython SKILL_DIR/entregar.py . NOME --ronda 1epython SKILL_DIR/revisar_folha.py . --ronda 1antes de enviar para A e D (1 rodada sobre vídeo). - Render final, uma única vez:
node render.mjs --sub 6. Nunca dois renders ao mesmo tempo. python SKILL_DIR/entregar.py . NOME --ronda N --escritorioe entregue a versão de celular.- Contribuir para a biblioteca (ativado por padrão): siga "Contribuir modelos novos" da skill
biblioteca(novos.py→ preparar →Devo subir para a biblioteca? (S/n)). Se o usuário já disse que não neste projeto, não pergunte.
Esforço e modelo por função
Ver a tabela completa por harness em AGENTS.md do repositório. Resumo (nomes do Claude Code; em outros harness use o
equivalente "rápido/médio/profundo"):
| Função | Modelo | Esforço |
|---|---|---|
| Sessão que coordena o vídeo | o que você usa | medium |
| Pesquisador de dados e revisor B | médio (Sonnet) | high |
| Modelo 3D compartilhado | médio | medium, limite 150 k |
| Construtores de cenas | médio | medium, limite 40 turnos / 120 k |
| Revisores A, C, D | médio | medium (modelos pequenos tipo Haiku contradizem regras: não) |
| Correções pequenas de uma cena | médio | low |
max | nunca | demora muito e pensa demais |
Orçamento de tokens e sessões
O custo é turnos × tamanho da conversa, não o que se escreve. Regras:
- Uma sessão fresca por vídeo. Revezamento aos 150 k de contexto: deixe
AVANCE.md(o que ficou, o que vem, decisões) e continue em uma sessão nova que o leia. - Avisos apenas nos marcos:
ROTEIRO PRONTO,VÍDEO RÁPIDO PRONTO,TERMINADOou quando estiver bloqueado. O resto é anotado emTEMPOS.mdsem avisar. - Nada de capturas nem imagens na sessão principal: as vê um subagente que responde em texto.
- Revisores com orçamento: Rodada 0 sobre o MAPA máx. 2 rodadas; Rodada 1 sobre a folha 1; sobre o vídeo 1 rodada apenas com A e D. Segunda rodada apenas da área que ficou abaixo de 8,5.
Limite do construtor (vai colado, exatamente como está, ao final de cada encargo; para o modelo compartilhado, 150 k):
Orçamento: máximo 40 turnos e 120 k tokens de contexto. Quando atingir qualquer um dos dois, escreva
AVANCE.mdna sua pasta de trabalho (o que ficou, o que falta, o que testou e falhou) e termine com um resumo de 5 linhas; outro agente continuará a partir daí. Não leia o motor, o CONTRATO completo nem partes alheias: o que precisa está neste encargo. Nunca leia um arquivo completo de mais de 300 linhas: use intervalos ou grep. As capturas, apenas comnode render.mjs --probe <seg> --metadee máximo 1 a cada 5 turnos. Antes de pedir uma captura, executerevisar_folha.py(não gasta tokens). Não espere ninguém: se faltar algo, anote emAVANCE.mde termine.
Erros típicos (vão colados, exatamente como estão, em cada encargo de construtor; (auto) = é capturado por revisar_folha.py):
- Texto duplo nas fusões (auto): retire a placa antiga completamente antes de a nova entrar (saída < 0,15 s) ou use corte seco; nunca dois letreiros ao mesmo tempo na mesma zona.
- Halos e auras (auto): orbe, disco ou foco com brilho suave ao redor parece olho ou sol. Emissivo plano, sem sprite radial; se algo brilha, que seja alongado e sem anel.
- Gêmeos (auto): duas janelas, focos ou orbes do mesmo tamanho e brilho juntos parecem olhos. Tamanhos diferentes, em alturas diferentes, ou apenas um.
- Brancos queimados (auto, aviso): nada em branco puro com bloom; cor da paleta, fosco.
- Manchas e pontos soltos (auto, aviso): partículas soltas, sombras atrás de placas, bordas que ficam.
- Fora de zona (auto): nada em y < 215 nem abaixo de y = 1450 (karaokê); nada atravessa uma placa.
- Saltos de brilho (auto com
--ronda): luz média 60-90, sem saltos > 25 entre tomadas.- Duplicados: mesmo texto em letreiro e karaokê ao mesmo tempo; apenas um letreiro por ideia.
- Rostos e mãos: pessoas de costas ou 3/4 traseiras; a mão entra de lado ou pelo dorso.
- Letreiros pequenos: tudo >= 42 px (placas >= 52 px).
Render: onde o tempo é gasto (medido em um laptop de 4 núcleos com GPU integrada)
| Passo | Por quadro |
|---|---|
| Extrair o quadro do Chrome (JPEG, GPU via ANGLE) | ~0,07 s |
x264 slow CRF 16 (entrega) | +0,11 s |
--rapido (Quick Sync no Windows/Intel; x264 veryfast nos outros; CODEC_RAPIDO para escolher) | +0,02-0,05 s |
Desfoque --sub 6 | +0,09 s |
Sem GPU (--sem-gpu) é ~40 % mais lento. Nada de transmission em materiais e cada parte < 80 ms por quadro.
Lições que custam uma volta se esquecidas
update(t)é função pura de t: o render pede quadros soltos e com subquadros. Nada deMath.random(useE.azar(semente)) nem estado entre quadros. Proteja t < 0.- Movimentos de câmera de ≥ 0,6 s com inOutCubic: com
--sub 6os chutes saem como fantasmas. - Se um teste sair com pedaços de outro quadro, outro processo estava renderizando ao mesmo tempo: repita-o.
- O 404 de "Failed to load resource" ao final do render é normal; os erros de verdade são
pageerror. - Com
scene.environment, three r186 usascene.environmentIntensity, nãoenvMapIntensitydo material. - Partículas da biblioteca (three.quarks) são deterministas por tempo: não mova o grupo, use sua
pos. - Painel de ajustes com o mouse:
?ajustes=1na URL (verbiblioteca/base/LEEME.md); o render nunca o carrega. - Material real (fotos, metragem de arquivo): Wikimedia Commons e Internet Archive têm domínio público e CC BY; anote os créditos na descrição.