Communitygithub.com

orange9angel/dula-flat-cel

Crea cortos animados de línea plana y color plano usando modelos de imagen y scripts, desde la historia, diseños de personajes, dibujos y variantes de boca hasta un video terminado con sonido. Solo necesita Python y ffmpeg. Ideal para cortos animados, estilo cartoon de TV, animación limitada, películas dialogadas, mantener la consistencia de personajes entre tomas o corregir sincronización labial y parpadeos en los cambios de dibujo.

¿Qué es dula-flat-cel?

Esta skill permite a agentes de IA (como Claude Code, Codex, Cursor) generar cortos animados de estilo cartoon plano sin necesidad de modelos 3D ni de video. El flujo de trabajo se basa en dibujos que se mantienen durante 3-4 fotogramas, logrando la animación mediante el intercambio de dibujos y formas de boca, lo que aprovecha al máximo la consistencia de los modelos de imagen. Las herramientas incluyen scripts en Python que organizan el proyecto desde la escritura de la historia y el diseño de personajes hasta la generación de fondos, dibujos, variantes de boca, sincronización labial con audio y renderizado final en video. La skill soporta múltiples plataformas (terminal, IDE) y está diseñada para producir cortos de 20-30 segundos con personajes originales, manteniendo la coherencia visual entre tomas. Incluye pasos de control de calidad como verificación de recortes, sincronización labial y revisión manual de cada fotograma clave.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/orange9angel/dula-craft/tree/HEAD/skills/dula-flat-cel

Preguntar en tu IA favorita

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

Documentación

Animación de color plano

Un dibujo se mantiene durante 3–4 fotogramas, y el rendimiento proviene de intercambiar dibujos y formas de boca. Para diseños simples de caricatura de TV, esta es la ruta donde los modelos de imagen se mantienen más consistentes. No necesita ni 3D ni un modelo de video.

Los scripts están en la carpeta scripts/ de esta skill, con rutas relativas a este SKILL.md. A continuación, $S significa esa carpeta. Excepto por new_project.py, ejecútalos desde la carpeta de la película. Para problemas de entorno, usa dula-start.

Habla con la persona en su propio idioma.

Flujo de trabajo

python $S/new_project.py mi_pelicula && cd mi_pelicula

1. Historia y tomas

Escribe story.md, luego config/film.json (consulta la referencia de film.json). Mantén la primera película en 20–30 segundos, y una línea hablada toma aproximadamente 2–3 segundos, por lo que 15 segundos contienen 3–5 líneas. Usa solo personajes originales.

Para cada línea, piensa quién la dice, a quién y a quién muestra la cámara. Los chistes no deben depender de palabras que el público no entienda. La causa y el efecto también necesitan dibujos (entra corriendo → agarra → el objeto sale volando). No lo saltes con un corte.

2. Diseños de personajes (el paso más importante)

Coloca cada personaje en config/anchors.tsv (nombre<TAB>apariencia), luego ejecuta:

python $S/paint.py anchors config/anchors.tsv

Abre y mira cada imagen tú mismo. Algunos visores muestran un área transparente como un brillo de color sobre negro, que parece un recorte fallido. Si tienes dudas, revisa build/check_alpha.png del paso 3. Luego muestra los diseños a la persona y obtén su aprobación antes de continuar. Cada dibujo posterior sigue estos, por lo que un error aquí es el más costoso de corregir. Arregla las proporciones en palabras, como "cabeza un tercio de la altura total, cara redonda, ojos pequeños de cuenta negra, overol rojo".

3. Fondos y dibujos

Completa config/plates.tsv (nombre<TAB>descripción) y config/cels.tsv (dibujo<TAB>personaje<TAB>pose). Comienza los nombres de los dibujos con el nombre del personaje, por ejemplo heroe_correr_a.

python $S/paint.py plates config/plates.tsv
python $S/paint.py cels config/cels.tsv
python $S/prep_cels.py --bases-only    # Revisa los recortes en build/check_alpha.png antes de pintar bocas

Las imágenes tardan de 1 a 3 minutos cada una, y paint.py informa el progreso a medida que avanza. Si tu herramienta detiene comandos largos, ejecútala en segundo plano. Una re-ejecución omite las imágenes terminadas. Para rehacer una, usa --only <nombre> --force.

Para mantener la continuidad de dibujos y lugares, agrega una columna más que indique a qué seguir:

heroe_correr_a	hereo	Corriendo hacia la derecha, pie izquierdo adelante.
heroe_correr_b	hereo	Corriendo hacia la derecha, pie derecho adelante.	hereo_correr_a
prado	Un prado bajo nubes grises de lluvia.
prado_sol	La lluvia ha parado y el sol se abre paso.	prado

Reglas:

  • Dibuja un personaje por imagen. El diseño del personaje es siempre la primera referencia. Nunca uses una imagen rechazada como referencia.
  • Decide primero hacia dónde miran los personajes. Las imágenes generadas una a la vez eligen una dirección cada una, por lo que dos personas en una conversación pueden terminar fácilmente de espaldas. Especifícalo de antemano y usa flip para corregir errores.
  • Cada dibujo en un ciclo de acción sigue al anterior (la columna adicional anterior), por lo que la dirección, la escala y la forma se mantienen estables. Sin esto, un ciclo parpadea.
  • Para un cambio en la hora del día, vuelve a pintar el fondo, siguiendo la placa original. Multiplicar un color no puede ocultar un cielo azul.
  • Revisa las proporciones de un personaje en cada toma. Una descripción de pose como "cuello estirado hacia arriba" puede convertir a un cuerpo diferente.

4. Bocas y parpadeos

Cada dibujo que habla recibe ediciones locales de la misma imagen. En config/variants.tsv:

heroe_parado_m1	hereo_parado	Cambia solo la boca a medio abierta, óvalo pequeño.
heroe_parado_m2	hereo_parado	Cambia solo la boca a completamente abierta.
heroe_parado_parpadeo	hereo_parado	Cierra ambos ojos como líneas curvas simples. No cambies nada más.

Nombres: <base>_m1 es medio abierta, y <base>_m2 es completamente abierta. Con solo _m1, la boca tiene dos estados, abierta y cerrada, y eso también funciona. El dibujo base debe tener la boca cerrada. Si está dibujado con la boca abierta, haz una variante cerrada y establece los tres estados con talk en film.json.

Cada dibujo de un personaje que habla necesita sus propias bocas, incluido cada dibujo en un ciclo de caminata.

python $S/paint.py variants config/variants.tsv
python $S/prep_cels.py

prep_cels.py convierte los dibujos en color plano verdadero y bloquea cada variante a su base. Luego abre build/check_alpha.png y revisa los recortes sobre magenta. Vuelve a dibujar cualquier imagen con fondo sobrante, piezas faltantes u ojos borrados. Si advierte sobre un área grande cambiada, el modelo editó el cuerpo. Agrega una ventana x,y,w,h como columna 4 de variants.tsv.

¿Los colores se desvían? Puedes agregar config/palette.json ({"piel": [250, 220, 190]}), usando colores muestreados del diseño del personaje. Solo los colores cercanos se ajustan a él, y prep_cels.py lo aplica nuevamente después de que lo cambies.

5. Sonido

Elige una opción:

  • Genera voces con dula-voice, usando la propia clave de la persona.
  • Usa audio existente: colócalo en audio/voice/<id de línea>.wav, o establece file en la línea. mp3 y wav funcionan ambos.
  • Haz un borrador sin sonido: dale a la línea un valor seconds.

Las bocas se calculan a partir de este audio, así que define las voces antes de hacer la prueba.

Opcional: ambience, bgm, sfx y songs. Usa solo material sobre el que la persona tenga derechos. Este proyecto no genera música. Sin música con licencia, omite la banda sonora y deja que la ambientación y los efectos de sonido lleven la película.

6. Prueba

python $S/build_film.py
python $S/render.py --stills 1,3,5,8,12
python $S/render.py --range 0,20 -o output/piloto.mp4

build_film.py se detiene con un error cuando un personaje visible habla pero su boca no puede moverse, el error más fácil de pasar por alto. Mira cada fotograma fijo antes de mostrar la prueba. No esperes a que toda la película esté terminada para mostrarla a alguien.

Para colocar un personaje en el suelo: adivina ground, renderiza un fotograma fijo y ajusta. Es más rápido que calcularlo.

No dejes que las tomas permanezcan estáticas. A menos que un tiempo esté destinado a estar quieto, dale a cada toma una cosa que se mueva: un paneo en la placa, un bob o shake, un cambio de dibujo, o una superposición como lluvia. Termina la película con fade_out en la última toma.

7. Película completa y revisión final

python $S/render.py
python $S/check_mouths.py

Confirma cada uno de estos puntos antes de entregar, y di claramente si no pudiste:

  • Miraste un fotograma real de cada toma
  • check_mouths.py no informa bocas congeladas
  • Cada personaje sigue viéndose como la misma persona a través de las tomas (la cara y las proporciones importan más que el color)
  • Las personas en una conversación se miran entre sí
  • Un solo dibujo moviéndose por la pantalla tiene un bob o más dibujos, o se lee como deslizamiento
  • Escuchaste el audio. Si no puedes escuchar, di que el audio no ha sido revisado de oído

Un ejemplo completo

examples/rainy-slide en este repositorio tiene los prompts y la lista de tomas de una película terminada de 15 segundos, y docs/tutorial.md lo explica. Encuéntralos en ../../examples/rainy-slide y ../../docs/tutorial.md desde este archivo. Úsalos como modelo cuando alguien pida uno.

Ritmo

Reglas generales: las tomas duran en promedio 3–5 segundos, los personajes mantienen cada dibujo durante 3–4 fotogramas (aproximadamente 7 dibujos por segundo), con primeros planos frecuentes y expresiones exageradas. hold es el número de fotogramas por dibujo.

Problemas comunes

SíntomaCausa y solución
Los colores del cuerpo parpadean al cambiar las bocasLa variante no pasó por prep_cels.py
Una caminata o carrera late alto y bajoNo dimensiones los dibujos por separado. Un actor comparte una escala automáticamente. Agrega también align_head
Un accesorio toma el color incorrectoUna entrada de la paleta está demasiado cerca. Elimínala o baja SNAP
La boca permanece abierta durante el hablaLas bocas de dos estados usan un umbral de 0.5. Verifica si el audio está apagado
Las palabras suaves permanecen cerradasUna palabra fuerte establece la escala para su línea. Agrega un _m2, o baja mouth_open_at en la línea
La lluvia o el viento no se oyenLa ambientación es baja por defecto. Dale un level_db, como -35
Silbido constanteEl clip de ambientación es solo ruido. Reemplázalo. La ganancia está limitada, por lo que no se amplificará más
Codex dice que la imagen de referencia se perdióLa generación de imágenes debe ser su primera acción. paint.py maneja esto, así que ejecútalo de nuevo

Limitaciones

Esta ruta no es adecuada para peleas complejas, acción continua larga o pintura realista.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados