Communitygithub.com

block-town

Crie um vídeo vertical "Nesta cidade / Neste mundo" no estilo Roblox, a partir de uma ideia até um MP4 1080x1920 finalizado: roteiro, narração, mundo e personagens construídos com código no Blender e renderizados com Three.js, além de legendas karaokê, efeitos sonoros e mixagem de voz.

O que é block-town?

Block Town é uma skill completa para assistentes de IA (como Claude Code, Cursor ou Codex) que automatiza a produção de vídeos verticais no estilo "Nesta cidade" (ou "Neste mundo"), com visual Roblox 3D. A skill orquestra todo o pipeline, desde a criação do conceito até a exportação de um MP4 1080x1920: o roteiro é escrito e dividido em cenas, a narração é gerada com Fish Audio e ElevenLabs, o mundo 3D e personagens são construídos proceduralmente no Blender, e a renderização final é feita com Three.js em headless Chrome, resultando em quadros muito mais rápidos que o renderizador nativo do Blender. O sistema inclui uma "camada de vida" que adiciona respiração, movimentos sutis e tags flutuantes aos personagens, além de legendas karaokê com no máximo três palavras, efeitos sonoros sincronizados e mixagem de áudio com loudness constante. A skill é modular, com sete portões de qualidade que garantem aprovação do usuário em cada etapa, e impõe regras rígidas contra reutilização de materiais de terceiros, chamadas de API não autorizadas e violações de direitos autorais.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/chihabMe/block-town/tree/HEAD

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

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.py verifica 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.mp4 não deve ser publicado: publique o <nome>.mp4 limpo 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 em render_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 de pictures.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ãoO que você fazMostre ao usuário
1 RegraTrê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ênciauma tabela
2 RoteiroEPISODE/script.txt (uma frase por linha) e EPISODE/SCRIPT.md: opção A e B, tabela de batidas, pontuações do críticoo roteiro
3 Vozvo.py, words.py, voice_check.py (take gratuito do Fish), level_voice.pyvo/voice.wav, seus números
4 DesignsEPISODE/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 impressoDESIGN_SHEET.jpg + as telas
5 StillsEPISODE/episode.py com todos os planos; check; stills; corrigir; contact_sheet.pyCONTACT_SHEET.jpg
6 Ganchoos primeiros ~15 s: render_threejs.sh EPISODE 0 F1, dicas sonoras, finish.pyo MP4
7 Vídeo completorender_threejs.sh EPISODE, sons, finish.py (arquivo limpo + arquivo de música); após aprovação, o take pago da vozambos 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
  • check nã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): chame focus(personagem, tag, ...) em cada plano. check e stills entã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 para EPISODE/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": 4 renderiza 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 --plain també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.
  • stills escreve duas imagens do Blender com metade do tamanho por plano (30% e 85% do percurso) em EPISODE/stills/. Use BT_LIFE=1 para 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=/path para escolher). Ele mantém seu bake em EPISODE/threejs/; delete isso e frames/ após o usuário aceitar o vídeo.
  • Após qualquer alteração em episode.py, um cenário ou uma imagem: reexecute render_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 F1 onde F1 é o quadro imediatamente antes do primeiro corte após ~15 s, depois finish.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

CaminhoO quê
blockworld/town.pya rua, o elenco, pose(), luz, câmera, build_town(style=...)
blockworld/roblox.pyo visual Roblox: rchar, plástico, climas, rule_sign, giant_clock, puddles
blockworld/rprops.pyadereç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.pyauxiliares de tempo de palavras, cartões (tags, balões), stand, walk, o runner
blockworld/life.pya 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.shbake + desenho, a maneira normal de fazer quadros finais
blockworld/vo.py, words.py, voice_check.py, level_voice.pyvoz, tempos das palavras, verificação de voz, nivelamento
blockworld/sfx_gen.py, sfx/ELEVENLABS_LIST.mdefeitos sonoros ElevenLabs: o gerador e a lista de prompts
blockworld/finish.pylegendas, voz, efeitos sonoros (incluindo loops de fundo), música, a mixagem constante, os MP4s
blockworld/cues.pylistas 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-wifio episódio completo trabalhado (visual Roblox, renderizador Three.js)
examples/ep00-roblox-look, examples/ep01-introdemonstrações curtas do visual Roblox e do visual em blocos

Habilidades Relacionadas