Block town
Esta pasta contém o kit completo: a cidade, o elenco, como eles se movem, o renderizador, a voz, os sons, as
configurações de música e os passos para ir de uma ideia a um vídeo vertical finalizado. A pasta da skill é o diretório que contém este
arquivo; é chamada de SKILL abaixo. Os episódios ficam fora dela (o usuário nomeia a pasta), chamada de EPISODE abaixo. Use
caminhos absolutos.
Leia antes de construir: docs/ROBLOX_LOOK.md (o mundo, o elenco, os adereços, como os planos são feitos),
docs/RENDER.md (o renderizador Three.js, a camada de vida, tags, telas de celular e adereços impressos),
docs/SCRIPT.md (como a história é escrita), docs/VOICE.md (voz e música), docs/SOUND.md (efeitos sonoros,
ElevenLabs, a mixagem de voz constante). docs/PROMPTS.md tem um prompt para cada etapa. docs/GUIDE.md é o manual
original do visual em blocos: o mapa, pose(), os movimentos e as regras de câmera ainda se aplicam.
Como um vídeo é feito (desde ep05)
O Blender constrói e posiciona tudo a partir do código Python do episódio; Three.js desenha os quadros finais. O renderizador próprio do Blender é usado apenas para folhas de design e stills de cena.
episode.py ──(Blender: constrói a cidade, posiciona cada quadro, camada de vida)──> bake: scene.glb + anim.bin + materials.json
──(Three.js em Chrome headless)──> EPISODE/frames/f_####.jpg (~0,1-0,15 s por quadro)
──(finish.py: legendas, voz nivelada, efeitos sonoros, música)──> EPISODE/<nome>.mp4 e <nome>_music.mp4
Um episódio de 66 segundos leva cerca de 10-12 minutos para ir dos quadros aos MP4s finalizados (o EEVEE do Blender levava cerca de 3 horas).
Nunca
- Sem itens do catálogo Roblox, modelos baixados, filmagens, histórias ou áudios de outros criadores. Tudo na
imagem é construído em código ou desenhado por
blockworld/pictures.py. Vídeos virais podem ser estudados pela técnica, nunca reutilizados. - Sem chamadas de API pagas sem o consentimento do usuário. Fish Audio (voz) e ElevenLabs (efeitos sonoros) custam dinheiro: diga quanto
uma execução vai custar primeiro.
sfx_gen.pyverifica os créditos restantes e para antes da reserva; nunca aumente a reserva ou repita gerações para "tentar de novo" sem perguntar. Peça permissão antes de baixar qualquer coisa. - Sem música e sem clipes de voz de referência neste kit. Música apenas de um arquivo fornecido pelo usuário, e apenas na
cópia
_music.mp4. Se esse arquivo foi extraído do vídeo de outro criador, diga claramente que o_music.mp4não deve ser publicado: publique o<nome>.mp4limpo e adicione a música no seletor de sons do TikTok. - Não altere os oito personagens recorrentes (cores, cabelo, roupas):
blockworld/town.py. - Não mude um episódio já em andamento para outro visual.
- Sem gráficos abstratos inexplicados. Um feixe, uma linha ou um brilho entre duas pequenas figuras não diz nada ao espectador (o feixe "dando todas as barras" do ep05 parecia "uma linha azul"). Mostre a coisa em si: barras voando para fora de uma tag, um contador diminuindo, uma tela de celular que diz o que é.
O visual
Novos episódios usam o visual Roblox: build_town(..., style="roblox"). Cabeças redondas com rostos de anime,
cabelo em camadas, roupas impressas, plástico brilhante, climas de sol / neblina / chuva, legendas karaokê de 3 palavras. O visual em blocos mais antigo
(cabeças cúbicas, cores sólidas) ainda existe para episódios que começaram com ele: build_town(...) sem style dá o visual em blocos,
portanto sempre escreva style="roblox" em um novo episódio.
Padrão de qualidade (o que o usuário rejeitou ou solicitou)
- Nada é estático. Renderize com a camada de vida (
BT_LIFE=1, o padrão emrender_threejs.sh): respiração, olhares, mudanças de peso, um salto a cada corte, tremor de câmera e zoom-ins, árvores balançando, nuvens à deriva, tags flutuantes, spinners de carregamento girando, anéis de Wi-Fi pulsando, barras de sinal quicando. Um plano onde apenas a câmera se move é um plano fraco: dê a ele sua própria ação. - Tags e balões nunca são cobertos e nunca são cortados. A camada de vida os desenha acima de tudo, os levanta acima do cabelo e os mantém dentro da área segura do TikTok (x 5-85 %, y acima das legendas). Verifique se duas tags não se sobrepõem (ainda não automático).
- Toda tela parece um celular de verdade:
big_phone(screen=...)com uma imagem depictures.py(barra de status, "Sem Sinal", layout de aplicativo, uma mão segurando-o), nunca uma caixa branca com texto 3D. Celulares segurados mostram uma tela de bloqueio. - Adereços legíveis no tamanho de um celular: um mapa de papel é um mapa desenhado de verdade (
paper_map()), uma placa está completamente no quadro (afaste a câmera: uma placa de 10 studs precisa de ~25 studs de distância em 9:16). - A voz nunca diminui.
finish.json{"voice": "vo/voice_level.wav", "loudness": "static"}: a narração é nivelada frase por frase e a mixagem recebe um ganho fixo, para que efeitos altos não façam a voz cair. Medida: a loudness de curto prazo deve ficar dentro de ±1 dB de -14 LUFS durante todo o vídeo. - Sem efeitos empilhados ou agressivos. Um som por momento; nada mais longo que o momento; nenhum dois sons de "erro" dentro de meio segundo.
Faça um episódio: sete portões
Pare após cada portão, mostre o resultado e aguarde o usuário. Onde houver uma escolha criativa real, ofereça duas ou três opções e diga qual você recomenda.
| Portão | O que você faz | Mostre ao usuário |
|---|---|---|
| 1 Regra | Três regras (a partir da ideia do usuário ou dos testes de docs/SCRIPT.md), cada uma com um clima e uma ideia de ponto de referência | uma tabela |
| 2 Roteiro | EPISODE/script.txt (uma frase por linha) e EPISODE/SCRIPT.md: opção A e B, tabela de batidas, pontuações do crítico | o roteiro |
| 3 Voz | vo.py, words.py, voice_check.py (take gratuito do Fish), level_voice.py | vo/voice.wav, seus números |
| 4 Designs | EPISODE/design/episode.py: um still de cada novo ponto de referência, adereço, figurino e personagem; EPISODE/pictures.json e pictures.py para cada tela de celular e adereço impresso | DESIGN_SHEET.jpg + as telas |
| 5 Stills | EPISODE/episode.py com todos os planos; check; stills; corrigir; contact_sheet.py | CONTACT_SHEET.jpg |
| 6 Gancho | os primeiros ~15 s: render_threejs.sh EPISODE 0 F1, dicas sonoras, finish.py | o MP4 |
| 7 Vídeo completo | render_threejs.sh EPISODE, sons, finish.py (arquivo limpo + arquivo de música); após aprovação, o take pago da voz | ambos os MP4s |
Os detalhes de cada portão estão em docs/PROMPTS.md (o prompt 1 executa tudo). Copie examples/ep05-wifi para começar: é um
episódio finalizado feito dessa forma, com sua folha de design, 42 planos, imagens de celular, dicas e configurações.
Um take pago final é uma nova gravação: execute words.py e level_voice.py novamente, depois check, e re-renderize (os planos
seguem os tempos das palavras). Portanto, aproveite o tempo do take gratuito no portão 3, mas faça o take pago antes do portão 6 se o usuário
quiser publicar.
Comandos
# voz (portão 3)
python3 SKILL/blockworld/vo.py EPISODE # um take na voz "Roblox" do Fish (vo_config.json)
python3 SKILL/blockworld/vo.py EPISODE --post-only # refazer ajuste / presença / tempo no take salvo, sem nova chamada
python3 SKILL/blockworld/words.py EPISODE # tempos das palavras -> vo/times.json
python3 -I SKILL/blockworld/voice_check.py EPISODE # ritmo, pausas, brilho em relação às faixas virais
python3 -I SKILL/blockworld/level_voice.py EPISODE # cada frase em um nível -> vo/voice_level.wav
# imagens para adereços (portão 4)
python3 -I SKILL/blockworld/pictures.py EPISODE # EPISODE/pictures.json -> EPISODE/pictures/*.png
# planos (portões 4-5): Blender, sempre através de run.py com --factory-startup
blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE check
BT_LIFE=1 blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE stills [shot ...]
blender -b --factory-startup --python-exit-code 1 -P SKILL/blockworld/run.py -- EPISODE frame 12.5
python3 -I SKILL/blockworld/contact_sheet.py EPISODE # um still numerado por plano -> CONTACT_SHEET.jpg
# quadros finais (portões 6-7): Three.js
bash SKILL/blockworld/render_threejs.sh EPISODE # todos os quadros -> EPISODE/frames/ (~10 min para 66 s)
bash SKILL/blockworld/render_threejs.sh EPISODE F0 F1 # apenas F0..F1 (o gancho, um plano refeito)
# efeitos sonoros (portões 6-7): veja docs/SOUND.md
python3 -I SKILL/blockworld/sfx_gen.py --credits # créditos restantes do ElevenLabs
python3 -I SKILL/blockworld/sfx_gen.py el-tag-pop ep07-... # gerar sons nomeados de sfx/ELEVENLABS_LIST.md
python3 -I SKILL/blockworld/cues.py EPISODE cues_spec.json # dicas por palavra ("diga": "congelou") -> EPISODE/cues.json
# finalização (portões 6-7)
python3 -I SKILL/blockworld/finish.py EPISODE # legendas + voz + efeitos (+ música) -> os MP4s
checknão renderiza nada: ele executa cada plano, imprime a tabela de planos e avisa sobre planos com mais de 2,5 s.- Verificações automáticas de still (
blockworld/stillcheck.py, desde ep08): chamefocus(personagem, tag, ...)em cada plano.checkestillsentão relatam rostos bloqueados (por um poste, uma pessoa, uma tag ou o próprio braço do personagem), rostos abaixo da faixa de legendas, tags fora da área segura (x 5-85 %, entre a barra superior do TikTok e as legendas), tags se cobrindo e qualquer coisa dentro de 1 stud da lente. Os resultados vão paraEPISODE/still_check.txt. Corrija cada linha antes de mostrar os stills e depois ainda os examine: ele não avalia o enquadramento nem se a imagem conta a frase. - 60 fps com desfoque de movimento (opcional):
finish.json"render_fps": 240, "blur": 4renderiza 240 quadros por segundo e calcula a média de cada 4 em um quadro de 60 fps. Cerca de 1,6 min de renderização por segundo de vídeo. - Virada de cor (opcional):
finish.json"grade": {"word": 24, "ramp": 0.5, "saturation": 0.6, "brightness": -0.05, "cool": 0.1, "vignette": true}torna a imagem mais fria, escura e plana a partir daquela palavra do roteiro (a virada da história). As legendas não são graduadas.finish.py EPISODE --plaintambém escreve<name>_plain.mp4(30 fps, sem desfoque, sem gradação) para uma comparação lado a lado. - ep08 (
episodes/ep08-price-tags-10s) é o teste de 10 segundos disso, com planos de ~1 s. stillsescreve duas imagens do Blender com metade do tamanho por plano (30% e 85% do percurso) emEPISODE/stills/. UseBT_LIFE=1para que as tags sejam colocadas da mesma forma que a renderização final as coloca. Olhe para cada still antes de mostrar qualquer um.render_threejs.shé executado em segundo plano se seus comandos expirarem (cerca de 10 minutos para 66 s). Ele instala os dois pacotes npm no primeiro uso (blockworld/threejs/) e precisa do Chrome ou Chromium (CHROME=/pathpara escolher). Ele mantém seu bake emEPISODE/threejs/; delete isso eframes/após o usuário aceitar o vídeo.- Após qualquer alteração em
episode.py, um cenário ou uma imagem: reexecuterender_threejs.sh(o bake lê o código; nada é armazenado em cache entre as execuções). render_all.sh(quadros do Blender EEVEE) é mantido apenas para comparações: cerca de 3-6 s por quadro.- O gancho:
render_threejs.sh EPISODE 0 F1ondeF1é o quadro imediatamente antes do primeiro corte após ~15 s, depoisfinish.py(ele usa os quadros que existem) e renomeie o MP4 para que o vídeo completo não o sobrescreva. - Assista aos quadros em todo o vídeo (pelo menos um por plano) e meça a loudness antes de considerá-lo finalizado. Se você não puder ouvir, diga isso claramente e liste o que verificou no lugar.
O que vai onde
| Caminho | O quê |
|---|---|
blockworld/town.py | a rua, o elenco, pose(), luz, câmera, build_town(style=...) |
blockworld/roblox.py | o visual Roblox: rchar, plástico, climas, rule_sign, giant_clock, puddles |
blockworld/rprops.py | adereços prontos: tags de barras de sinal e tokens de barras voadoras, celulares com telas reais e uma mão, imagens iluminadas e impressas, mapa de papel dobrado, cartaz, faixa, cartola, ônibus, porta, feixe, pombo, torre de Wi-Fi |
blockworld/pictures.py, blockworld/pictures/ | desenha telas de celular, telas de bloqueio e mapas a partir de pictures.json; as imagens padrão do kit |
blockworld/anim.py | auxiliares de tempo de palavras, cartões (tags, balões), stand, walk, o runner |
blockworld/life.py | a camada de vida (BT_LIFE=1): movimento ocioso, câmera, balanço de cena, spinners, posicionamento de tags |
blockworld/threejs/ | o renderizador: bake.py (lado Blender), scene.html + capture.mjs (lado Three.js) |
blockworld/render_threejs.sh | bake + desenho, a maneira normal de fazer quadros finais |
blockworld/vo.py, words.py, voice_check.py, level_voice.py | voz, tempos das palavras, verificação de voz, nivelamento |
blockworld/sfx_gen.py, sfx/ELEVENLABS_LIST.md | efeitos sonoros ElevenLabs: o gerador e a lista de prompts |
blockworld/finish.py | legendas, voz, efeitos sonoros (incluindo loops de fundo), música, a mixagem constante, os MP4s |
blockworld/cues.py | listas de dicas por palavra -> cues.json |
sfx/ | efeitos sonoros: o conjunto Pixabay (sfx/CREDITS.md); sons ElevenLabs vão para cá como el-*.mp3 / epNN-*.mp3 após gerados (nenhum ainda até ep05) |
examples/ep05-wifi | o episódio completo trabalhado (visual Roblox, renderizador Three.js) |
examples/ep00-roblox-look, examples/ep01-intro | demonstrações curtas do visual Roblox e do visual em blocos |