Communitygithub.com

block-town

Crea un video vertical de estilo historia 'En este pueblo / En este mundo' en una ciudad 3D estilo Roblox, desde una idea hasta un MP4 1080x1920 completo: regla, guion, voz narradora característica, mundo y personajes construidos desde código en Blender y renderizados con Three.js, planos, la capa de vida, pantallas de teléfono y utilería, subtítulos tipo karaoke, efectos de sonido ElevenLabs o librería, mezcla de voz estable y archivo de música. Úsalo cuando el usuario diga 'haz un video de en este pueblo' o 'en este mundo', una historia Roblox, ciudad de bloques, el kit de ciudad, o /block-town; o pida escribir ese guion, hacer su voz, animarlo, añadir un personaje, utilería, pantalla de teléfono o punto de referencia a la ciudad, renderizarlo, o terminar subtítulos y sonido.

¿Qué es block-town?

El skill 'block-town' es un kit completo para producir videos verticales (1080x1920) con estilo narrativo 'En este pueblo / En este mundo', similares a las historias virales populares en plataformas como TikTok. Está diseñado para agentes de IA como Claude Code, Cursor o Codex, proporcionando un flujo de trabajo de 7 pasos que va desde una idea inicial hasta un video finalizado con voz, efectos de sonido, música y subtítulos tipo karaoke. El skill construye el mundo y los personajes mediante código Python ejecutado en Blender (usando un estilo Roblox o bloques clásicos) y luego renderiza los fotogramas finales con Three.js en un navegador headless, logrando velocidades de renderizado mucho más rápidas que Blender solo (un video de 66 segundos toma ~10-12 minutos frente a ~3 horas). Incluye gestión de voz mediante Fish Audio (con opción de versión de pago), efectos de sonido de ElevenLabs o librerías libres, y una capa de 'vida' que añade animaciones sutiles (respiración, miradas, rebotes, etc.) para que nada se vea estático. El skill impone reglas estrictas para evitar problemas de copyright (no reutilizar contenido de terceros), manejar costos de APIs de paga (preguntando siempre al usuario primero), y mantener una alta calidad visual: cada pantalla de teléfono se ve real, los tags y burbujas no se cortan ni solapan, y el volumen de la voz se nivela con precisión. El flujo de 7 puertas (regla, guion, voz, diseños, fotogramas, hook y video completo) permite revisar y aprobar cada etapa antes de continuar.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Block town

Esta carpeta contiene el kit completo: la ciudad, el reparto, cómo se mueven, el renderizador, la voz, los sonidos, la configuración de música y los pasos desde una idea hasta un video vertical terminado. La carpeta del skill es el directorio que contiene este archivo; se le llama SKILL en adelante. Los episodios viven fuera de ella (el usuario nombra la carpeta), llamada EPISODE en adelante. Usa rutas absolutas.

Lee antes de construir: docs/ROBLOX_LOOK.md (el mundo, el reparto, la utilería, cómo se hacen los planos), docs/RENDER.md (el renderizador Three.js, la capa de vida, etiquetas, pantallas de teléfono y utilería impresa), docs/SCRIPT.md (cómo se escribe la historia), docs/VOICE.md (voz y música), docs/SOUND.md (efectos de sonido, ElevenLabs, la mezcla de voz estable). docs/PROMPTS.md tiene un prompt para cada etapa. docs/GUIDE.md es el manual original del aspecto de bloques: el mapa, pose(), los movimientos y las reglas de cámara siguen vigentes.

Cómo se hace un video (desde ep05)

Blender construye y posa todo desde el código Python del episodio; Three.js dibuja los fotogramas finales. El renderizador propio de Blender solo se usa para hojas de diseño y fotogramas fijos de planos.

episode.py ──(Blender: construye la ciudad, posa cada fotograma, capa de vida)──> horneado: scene.glb + anim.bin + materials.json
           ──(Three.js en Chrome headless)──> EPISODE/frames/f_####.jpg  (~0.1-0.15 s por fotograma)
           ──(finish.py: subtítulos, voz nivelada, efectos de sonido, música)──> EPISODE/<nombre>.mp4 y <nombre>_music.mp4

Un episodio de 66 segundos toma aproximadamente 10-12 minutos desde los fotogramas hasta los MP4 terminados (con Blender EEVEE tomaba unas 3 horas).

Nunca

  • Sin elementos del catálogo de Roblox, modelos descargados, ni imágenes, historias o audio de otros creadores. Todo en la imagen se construye con código o se dibuja con blockworld/pictures.py. Los videos virales pueden estudiarse para aprender la técnica, nunca reutilizarse.
  • Sin llamadas a APIs de pago sin el consentimiento del usuario. Fish Audio (voz) y ElevenLabs (efectos de sonido) cuestan dinero: di cuánto costará una ejecución primero. sfx_gen.py verifica los créditos restantes y se detiene antes de la reserva; nunca aumentes la reserva ni repitas generaciones para 'reintentar' sin preguntar. Pregunta antes de descargar cualquier cosa.
  • Sin música ni clips de voz de referencia en este kit. La música solo proviene de un archivo que el usuario proporcione, y solo en la copia _music.mp4. Si ese archivo se extrajo del video de otro creador, di claramente que el _music.mp4 no debe publicarse: publica el <nombre>.mp4 limpio y agrega la canción en el selector de sonidos de TikTok.
  • No cambies los ocho personajes recurrentes (colores, cabello, ropa): blockworld/town.py.
  • No cambies un episodio que ya está en progreso a otro aspecto visual.
  • Sin gráficos abstractos sin explicación. Un rayo, una línea o un brillo entre dos figuras pequeñas no le dice nada al espectador (ep05: el rayo 'regalando todas las barras' se leyó como 'una línea azul'). Muestra la cosa en sí misma: barras volando de una etiqueta, un contador bajando, una pantalla de teléfono que lo dice.

El aspecto

Los episodios nuevos usan el aspecto Roblox: build_town(..., style="roblox"). Cabezas redondas con caras anime, cabello en capas, ropa impresa, plástico brillante, estados de ánimo sol / niebla / lluvia, subtítulos karaoke de 3 palabras. El aspecto bloque anterior (cabezas cúbicas, colores planos) sigue ahí para episodios que empezaron con él: build_town(...) sin style da el aspecto bloque, así que siempre escribe style="roblox" en un episodio nuevo.

Barra de calidad (lo que el usuario rechazó o pidió)

  • Nada es estático nunca. Renderiza con la capa de vida (BT_LIFE=1, el valor predeterminado en render_threejs.sh): respiración, miradas, cambios de peso, un rebote en cada corte, bamboleo de cámara y acercamientos, árboles meciéndose, nubes a la deriva, etiquetas flotantes, ruedas de carga girando, anillos Wi-Fi pulsantes, barras de señal rebotando. Un plano donde solo la cámara se mueve lentamente es un plano débil: dale su propia acción.
  • Las etiquetas y burbujas nunca se tapan ni se cortan. La capa de vida las dibuja sobre todo, las eleva por encima del cabello y las mantiene dentro del área segura de TikTok (x 5-85 %, y por encima de los subtítulos). Verifica que dos etiquetas no se superpongan entre sí (aún no es automático).
  • Cada pantalla parece un teléfono real: big_phone(screen=...) con una imagen de pictures.py (barra de estado, 'Sin servicio', diseño de aplicaciones, una mano sosteniéndolo), nunca una caja blanca con texto 3D. Los teléfonos sostenidos con la mano muestran una pantalla de bloqueo.
  • La utilería se lee al tamaño de un teléfono: un mapa de papel es un mapa real dibujado (paper_map()), un letrero está completamente en el encuadre (aleja la cámara: un letrero de 10 unidades necesita ~25 unidades de distancia en 9:16).
  • La voz nunca baja. finish.json {"voice": "vo/voice_level.wav", "loudness": "static"}: la narración se nivela oración por oración y la mezcla recibe una ganancia fija, así que los efectos fuertes no pueden hacer que la voz baje. Medida: la sonoridad a corto plazo debe mantenerse dentro de ±1 dB de -14 LUFS durante todo el video.
  • Sin efectos apilados o agresivos. Un sonido por momento; nada más largo que el momento; no dos sonidos de 'error' en menos de medio segundo.

Haz un episodio: siete puertas

Detente después de cada puerta, muestra el resultado y espera al usuario. Cuando haya una elección creativa real, ofrece dos o tres opciones y di cuál recomiendas.

PuertaQué hacesMuéstrale al usuario
1 ReglaTres reglas (de la idea del usuario o de las pruebas de docs/SCRIPT.md), cada una con un estado de ánimo y una idea de punto de referenciauna tabla
2 GuionEPISODE/script.txt (una oración por línea) y EPISODE/SCRIPT.md: opciones A y B, tabla de ritmos, puntuaciones del críticoel guion
3 Vozvo.py, words.py, voice_check.py (toma gratuita de Fish), level_voice.pyvo/voice.wav, sus números
4 DiseñosEPISODE/design/episode.py: un fotograma fijo de cada nuevo punto de referencia, utilería, disfraz y personaje; EPISODE/pictures.json y pictures.py para cada pantalla de teléfono y utilería impresaDESIGN_SHEET.jpg + las pantallas
5 Fotogramas fijosEPISODE/episode.py con cada plano; check; fotogramas fijos; arreglar; contact_sheet.pyCONTACT_SHEET.jpg
6 Hooklos primeros ~15 s: render_threejs.sh EPISODE 0 F1, señales de sonido, finish.pyel MP4
7 Video completorender_threejs.sh EPISODE, sonidos, finish.py (archivo limpio + archivo de música); con aprobación, la toma de voz de pagoambos MP4

Los detalles de las puertas están en docs/PROMPTS.md (el prompt 1 ejecuta todo). Copia examples/ep05-wifi para empezar: es un episodio terminado hecho de esta manera, con su hoja de diseño, 42 planos, imágenes de teléfono, señales y configuración.

Una toma final de pago es una nueva grabación: ejecuta words.py y level_voice.py de nuevo, luego check, y re-renderiza (los planos siguen los tiempos de las palabras). Así que aprueba el ritmo de la toma gratuita en la puerta 3, pero haz la toma de pago antes de la puerta 6 si el usuario quiere publicar.

Comandos

# voz (puerta 3)
python3 SKILL/blockworld/vo.py EPISODE                 # una toma en la voz 'Roblox' de Fish (vo_config.json)
python3 SKILL/blockworld/vo.py EPISODE --post-only     # rehacer ajuste / presencia / tempo en la toma guardada, sin nueva llamada
python3 SKILL/blockworld/words.py EPISODE              # tiempos de palabras -> vo/times.json
python3 -I SKILL/blockworld/voice_check.py EPISODE     # ritmo, pausas, brillo contra los rangos virales
python3 -I SKILL/blockworld/level_voice.py EPISODE     # cada oración a un nivel -> vo/voice_level.wav

# imágenes para utilería (puerta 4)
python3 -I SKILL/blockworld/pictures.py EPISODE        # EPISODE/pictures.json -> EPISODE/pictures/*.png

# planos (puertas 4-5): Blender, siempre a través de run.py con --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 [plano ...]
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   # un fotograma fijo numerado por plano -> CONTACT_SHEET.jpg

# fotogramas finales (puertas 6-7): Three.js
bash SKILL/blockworld/render_threejs.sh EPISODE              # todos los fotogramas -> EPISODE/frames/ (~10 min para 66 s)
bash SKILL/blockworld/render_threejs.sh EPISODE F0 F1        # solo F0..F1 (el hook, un plano rehecho)

# efectos de sonido (puertas 6-7): ver docs/SOUND.md
python3 -I SKILL/blockworld/sfx_gen.py --credits             # créditos restantes de ElevenLabs
python3 -I SKILL/blockworld/sfx_gen.py el-tag-pop ep07-...   # generar sonidos nombrados desde sfx/ELEVENLABS_LIST.md
python3 -I SKILL/blockworld/cues.py EPISODE cues_spec.json   # señales por palabra ('decir': 'se congeló') -> EPISODE/cues.json

# finalización (puertas 6-7)
python3 -I SKILL/blockworld/finish.py EPISODE                # subtítulos + voz + efectos (+ música) -> los MP4
  • check no renderiza nada: ejecuta cada plano, imprime la tabla de planos y advierte sobre planos de más de 2.5 s.
  • Verificaciones automáticas de fotogramas fijos (blockworld/stillcheck.py, desde ep08): llama a focus(personaje, etiqueta, ...) en cada plano. check y stills luego informan caras bloqueadas (por un poste, una persona, una etiqueta o el propio brazo del personaje), caras debajo de la banda de subtítulos, etiquetas fuera del área segura (x 5-85 %, entre la barra superior de TikTok y los subtítulos), etiquetas que se tapan entre sí, y cualquier cosa a menos de 1 unidad del lente. Los resultados van a EPISODE/still_check.txt. Arregla cada línea antes de mostrar los fotogramas fijos, y luego aún míralos: no juzga el encuadre ni si la imagen cuenta la línea.
  • 60 fps con desenfoque de movimiento (opcional): finish.json "render_fps": 240, "blur": 4 renderiza 240 fotogramas por segundo y promedia cada 4 en un fotograma de 60 fps. Aproximadamente 1.6 min de renderizado por segundo de video.
  • Giro de color (opcional): finish.json "grade": {"word": 24, "ramp": 0.5, "saturation": 0.6, "brightness": -0.05, "cool": 0.1, "vignette": true} atenúa la imagen más fría, más oscura y más plana desde esa palabra del guion (el giro de la historia). Los subtítulos no se gradúan. finish.py EPISODE --plain también escribe <nombre>_plain.mp4 (30 fps, sin desenfoque, sin grado) para una comparación lado a lado.
  • ep08 (episodes/ep08-price-tags-10s) es la prueba de 10 segundos de esto, con planos de ~1 s.
  • stills escribe dos imágenes de Blender a medio tamaño por plano (al 30 % y 85 % de su duración) en EPISODE/stills/. Usa BT_LIFE=1 para que las etiquetas se coloquen como las coloca el render final. Mira cada fotograma fijo antes de mostrar alguno.
  • render_threejs.sh se ejecuta en segundo plano si tus comandos expiran (aproximadamente 10 minutos para 66 s). Instala los dos paquetes npm en el primer uso (blockworld/threejs/) y necesita Chrome o Chromium (CHROME=/ruta para elegir). Guarda su horneado en EPISODE/threejs/; bórralo y frames/ después de que el usuario acepte el video.
  • Después de cualquier cambio en episode.py, una pieza de escenario o una imagen: vuelve a ejecutar render_threejs.sh (el horneado lee el código; no se almacena nada en caché entre ejecuciones).
  • render_all.sh (fotogramas de Blender EEVEE) se conserva solo para comparaciones: aproximadamente 3-6 s por fotograma.
  • El hook: render_threejs.sh EPISODE 0 F1 donde F1 es el fotograma justo antes del primer corte después de ~15 s, luego finish.py (usa los fotogramas que existen), y renombra el MP4 para que el video completo no lo sobrescriba.
  • Mira fotogramas en todo el video (al menos uno por plano) y mide la sonoridad antes de darlo por terminado. Si no puedes escuchar, dilo claramente y enumera qué revisaste en su lugar.

Qué va dónde

RutaQué
blockworld/town.pyla calle, el reparto, pose(), luz, cámara, build_town(style=...)
blockworld/roblox.pyel aspecto Roblox: rchar, plástico, estados de ánimo, rule_sign, giant_clock, puddles
blockworld/rprops.pyutilería lista: etiquetas de barra de señal y fichas de barra voladoras, teléfonos con pantallas reales y una mano, imágenes iluminadas e impresas, mapa de papel doblado, póster, fajín, sombrero de copa, autobús, puerta, viga, paloma, torre Wi-Fi
blockworld/pictures.py, blockworld/pictures/dibuja pantallas de teléfono, pantallas de bloqueo y mapas desde pictures.json; las imágenes predeterminadas del kit
blockworld/anim.pyayudantes de temporización de palabras, tarjetas (etiquetas, burbujas), stand, walk, el corredor
blockworld/life.pyla capa de vida (BT_LIFE=1): movimiento inactivo, cámara, balanceo de escena, ruedas giratorias, colocación de etiquetas
blockworld/threejs/el renderizador: bake.py (lado Blender), scene.html + capture.mjs (lado Three.js)
blockworld/render_threejs.shhornear + dibujar, la forma normal de hacer fotogramas finales
blockworld/vo.py, words.py, voice_check.py, level_voice.pyvoz, tiempos de palabras, verificación de voz, nivelación
blockworld/sfx_gen.py, sfx/ELEVENLABS_LIST.mdefectos de sonido ElevenLabs: el generador y la lista de prompts
blockworld/finish.pysubtítulos, voz, efectos de sonido (también bucles de fondo), música, la mezcla estable, los MP4
blockworld/cues.pylistas de señales por palabra -> cues.json
sfx/efectos de sonido: el conjunto Pixabay (sfx/CREDITS.md); los sonidos de ElevenLabs llegan aquí como el-*.mp3 / epNN-*.mp3 una vez generados (ninguno todavía hasta ep05)
examples/ep05-wifiel episodio completo desarrollado (aspecto Roblox, renderizador Three.js)
examples/ep00-roblox-look, examples/ep01-introdemos cortos del aspecto Roblox y el aspecto bloque

Skills relacionados