¿Qué hace Toon Reel?
Estás dirigiendo y construyendo una historia animada corta con el motor toon-reel-engine. Todo es Python: los personajes, los decorados, las luces y las cámaras son código, y cada fotograma es una función pura del tiempo T. No hay editor de línea de tiempo ni interfaz de fotogramas clave. Escribes datos (claves, tablas de tomas) y luego miras los fotogramas.
Estructura del motor (mantenla: las importaciones relativas dependen de ella):
tools/toon/ el motor: toon.py (renderizador), rig.py (personajes), anim.py (temporización), cast/ props/ sets/ (kit)
tools/ sound.py (pistas a partir de indicaciones), mix_check.py (claridad de voz), finish.py (exportación -14 LUFS),
thumb.py (portada), find_phrases.py (tiempos de frases en una toma de narración)
episodes/starter/toon LA PLANTILLA: "The Lamp", 12.5 s, cuatro tomas, una habitación, una persona. Cópiala para empezar.
episodes/window/toon EL EJEMPLO COMPLETO: "The Man at the Window", 50 s, 13 tomas, dos mundos y un giro.
episodes/jeff, episodes/smilingman módulos de apoyo que el ejemplo completo y el kit importan (no son episodios ejecutables)
Comandos. python abajo significa el intérprete que tiene instalado requirements.txt (py en Windows). Los scripts propios de un episodio (reel.py, build_tl.py, finalize.py) se ejecutan desde la carpeta del episodio episodes/<nombre>/toon. Las herramientas se ejecutan desde la raíz del proyecto: python tools/sound.py episodes/<nombre>/toon.
Primero: encontrar o configurar el motor
Trabaja en la carpeta del proyecto de la persona, nunca dentro de la carpeta de instalación del plugin (se reemplaza con cada actualización).
- Si la carpeta de trabajo ya tiene
tools/toon/toon.py, úsalo. - De lo contrario, el motor se distribuye con esta habilidad. Su raíz está dos carpetas arriba del directorio base de esta habilidad (
<directorio habilidad>/../..: contienetools/,episodes/,requirements.txty.gitignore). Copia esos cuatro elementos en la carpeta de trabajo, manteniendo la estructura, e informa a la persona que lo hiciste. Si esa carpeta no tienetools/(la habilidad se copió sola), clonahttps://github.com/wlr2/toon-reel-engineen su lugar. pip install -r requirements.txt, y verifica queffmpeg -versionfuncione (5.1 o posterior). Los subtítulos necesitan Arial Black, oTOON_FONTconfigurado con una tipografía sans-serif gruesa.ttf.- Prueba la configuración antes de construir nada, desde
episodes/starter/toon:python build_tl.py, luegopython reel.py --frame 5.0debe escribirreview/_f5.00.png.
El orden es fijo
guion -> línea de tiempo -> hojas de personajes + fotograma del decorado -> bloqueo -> controles (2 rondas) -> vista previa -> render maestro -> sonido -> finalización -> publicación.
Un render maestro nunca comienza antes de que los controles hayan pasado y se hayan registrado. Muestra a la persona la hoja de personajes y un fotograma del decorado antes de animar, y una hoja de fotogramas clave etiquetada antes de la vista previa a resolución completa. Pregunta antes de gastar dinero en algo (TTS de pago, efectos de sonido de pago, nubes de render).
1. Guion (references/script.md)
El método de diez pasos: abre con la contradicción más específica, una pregunta principal, una cadena de consecuencias, un cambio cada pocos segundos, escrito para voz y animación, un medio en movimiento, un final merecido con la línea característica al final, encuadre honesto ("AN INTERNET HORROR STORY" para creepypasta), una tabla de tomas temporizada, luego una edición de retención. Si la persona te entrega un guion o una tabla de ritmos, sus palabras y sus especificaciones prevalecen sobre cualquier regla interna aquí: nunca reescribas sus líneas, sugiere cambios y cita lo que cambiarías.
Entregable: SCRIPT.md (tres ganchos + la elección, narración completa, tabla de tomas temporizada, recuento de palabras) y script.py.
2. La línea de tiempo, luego la voz
script.pycontienePHRASES(dónde se coloca cada línea, su texto, sus fragmentos de subtítulos con[palabra]para la palabra clave roja) yMARKS(los ritmos de la historia en segundos, que se convierten en los límites de las tomas).python build_tl.pyescribetimeline.json(total,marks,lines). El reel solo leetimeline.json. En el starter funciona antes de que exista cualquier audio: las longitudes de las frases se estiman a partir del recuento de palabras, para que puedas bloquear la imagen primero.- La voz es una toma por hablante, 48 kHz mono, de cualquier TTS o un micrófono (este repositorio no incluye ninguno; ElevenLabs es de pago, Kokoro es gratuito y local). Nunca aceleres una toma para que encaje: mejor corta un ritmo. Escribe los números como palabras en el texto que envías a un TTS.
python tools/find_phrases.py take.wavimprime los(inicio, fin)de cada frase en la toma. Colócalos enPHRASESy vuelve a ejecutarbuild_tl.py: corta las frases, las coloca y escribeaudio/narration.wav. Luego vuelve a verificar cada toma: las longitudes reales de las frases difieren de las estimaciones.- Los archivos
build_tl.pyincluidos manejan un solo narrador. Para varios hablantes, mantén una toma por hablante y añade el hablante a cada frase (un pequeño cambio enbuild_tl.py). - Insultos para TikTok: pítalos en una pista separada y ponles asteriscos en los subtítulos (
f***ing).
3. Los archivos del episodio (references/engine.md)
| archivo | función |
|---|---|
script.py | líneas, fragmentos de subtítulos, marcas |
build_tl.py | timeline.json (+ audio/narration.wav) |
looks.py | el elenco: cada look es un diccionario en rig.LOOK |
scenes.py | el mundo: geometría del decorado, luces, quién está dónde en el tiempo T, las pistas de actuación |
reel.py | SHOTS, subtítulos, render(T), los controles y los comandos de render |
cues.py | eventos de sonido para tools/sound.py |
finalize.py | mezclar las pistas, multiplexar sobre el render, ejecutar tools/finish.py |
Comienza un nuevo episodio copiando episodes/starter/toon a episodes/<nombre>/toon. Sus reel.py, build_tl.py y finalize.py son genéricos y pueden quedarse como están; reemplazas script.py, looks.py, scenes.py, la tabla SHOTS y cues.py. No empieces desde episodes/window/toon: su reel.py, cues.py y controles están cableados a esa historia (dos mundos reflejados, marcas con nombre, una cámara de giro personalizada). Léelo para aprender técnica: texturas, profundidad de campo, una clave facial por mundo, manos en el vidrio, una transición entre mundos. Los episodios más grandes mueven la actuación de scenes.py a un acting.py.
Un mundo necesita dos métodos: draw(fr, cam, T), que dibuja todo y devuelve {pid: resultado de rig.draw}, y cast(T), que devuelve [(pid, look, pose)]. pid es el id de una persona en este episodio ("nora"). Un mundo y una línea de tiempo por ubicación; las tomas solo eligen cámaras.
4. Apariencia (references/look.md)
Formas simples redondeadas, cabezas ligeramente grandes, ojos grandes y expresivos, materiales mate con sombreado suave de 3 paradas y un contorno más oscuro en el color base. Cada personaje obtiene su propia silueta, rostro y paleta diseñados a partir del guion (nunca un repintado del personaje de otro reel); los personajes recurrentes se mantienen en el modelo. Haz una hoja de modelo antes de animar, desde tools/toon: python -m cast.sheet ../../episodes/<nombre>/toon/looks.py <look> (escribe assets/kit/cast/<look>.png en la raíz del proyecto, o la ruta que des como tercer argumento).
5. Iluminación (references/lighting.md)
Tres capas en cada ubicación: un ambiente frío (noche azul-púrpura mantiene detalle), una clave suave en cada rostro (desde arriba y frontal, motivada por una lámpara o ventana), y cálidos prácticos a varias distancias que iluminan lo que está cerca de ellos. Los rostros son lo más claro en el encuadre; el fondo está un poco más oscuro y con menor contraste alrededor de ellos. Sombras de contacto bajo los pies, muebles y manos que se tocan. Una configuración de luz por ubicación: la dirección, el color y la exposición se mantienen en todos los cortes. Sin floración, sin contornos brillantes, sin negros aplastados. El clima (lluvia, nieve, viento) se anima en momentos tranquilos cuando la historia tiene clima.
6. Cámara (references/camera.md)
- Un corte cada 2-3 s. Cada toma sirve para una acción, una expresión o una revelación.
- El gancho (0-3 s) es la toma en movimiento más hermosa del reel: la cámara y el personaje se mueven desde el fotograma 1.
- Plano conjunto primero, luego primeros planos en contrapiano. Los primeros planos se mantienen dentro de ~35 grados de la línea de mirada.
track(a, b, ease)hace un movimiento limpio entre dos claves(posición, objetivo, px focal, horizonte). La cámara gira para mirar al objetivo pero no puede inclinarse: la altura del objetivo se ignora. Encuadra hacia arriba o abajo con la altura de la cámara y elhorizonte(un valor más pequeño coloca la línea de los ojos más arriba en el encuadre, lo que se lee como mirar hacia abajo).- Mantén las cámaras >= 0.45 m de cualquier persona visible:
rig.drawno dibuja a nadie más cerca. - Los subtítulos (Arial Black 66 px, blanco, trazo negro, palabra clave #FF4D4D) nunca se superponen a un rostro o mano. Muévelos por toma con
cap=(y, tamaño).
7. Actuación y puesta en escena (references/acting-staging.md)
Cada acción es una cadena con desplazamientos: ojos -> cabeza -> hombros -> cuerpo -> manos, como preparación -> movimiento -> asentamiento. Las reacciones se suavizan con out/snap, los asentamientos con back. Los agarres se extienden antes de cerrarse. Una persona que solo gira la cabeza y los hombros puede estar sobre los pies por defecto; una persona que camina o gira el cuerpo necesita pies plantados en el espacio del mundo (ankle_R/ankle_L de rig.replant o rig.gait), pisando uno a la vez. Lee las lecciones de puesta en escena antes de bloquear cualquier cosa: cada una es un fallo que ya ha ocurrido.
8. Controles: la puerta antes de cada master (references/checks.md)
python reel.py --check-> lee todoreview/reel_checks.txt. En el starter, cada problema es una líneaANOMALY: alcance, pies hundidos, codos sobreestirados, giros de codo y rodilla, saltos, personas demasiado cerca del objetivo, subtítulos sobre un rostro o mano.python reel.py --stills-> primer/medio/último fotograma de cada toma (ronda 1).python reel.py --sheet <SHOTS>-> cada fotograma de tomas de contacto, caminatas, giros y cambios de oclusión en hojas espaciadas (ronda 2). Busca divisiones, miembros que aparecen y desaparecen, cabezas atravesando cosas, cosas que desaparecen.- Corrige en los datos, vuelve a ejecutar y registra cada anomalía en
review/LOG.md(solo añadir): tiempo, toma, causa, corrección, cómo se verificó; además banderas aceptadas con la razón, y lo que no pudiste inspeccionar. - Nunca afirmes "sin anomalías" solo por el código. El código verifica las articulaciones, no las imágenes: no ve personas atravesando muebles o entre sí, props que faltan a una mano, un orden de dibujo incorrecto, o un paso lateral de 0.8 m que se lee como una división. Eso lo encuentras en las hojas.
9. Render (desde la carpeta del episodio)
python reel.py --preview --full->review/reel_preview.mp4(1080x1920, sin sonido).python finalize.py previewañade la mezcla ->review/preview.mp4. Muéstrala, obtén un visto bueno.python reel.py --master-par 12->video/reel_silent.mp4: el master en 12 procesos (usa tu número de núcleos).
10. Sonido, mezcla, finalización, publicación (references/sound-finish.md)
cues.py, luego desde la raíz del proyectopython tools/sound.py episodes/<nombre>/toon-> pistas de música, efectos de sonido y ambiente. Grabaciones reales para cosas reales (trae muestras CC0 o con licencia aassets/sfx/); síntesis solo para drones abstractos, crescendos y explosiones. Las indicaciones del starter están todas sintetizadas para que la cadena funcione: reemplázalas.python tools/mix_check.py episodes/<nombre>/toon: la voz debe ser >= 10 dB sobre las bases en cada línea (cada línea falla hasta que haya una toma de narración real).python finalize.py final(carpeta del episodio) ->tools/finish.py-> -14 LUFS, <= -2 dBTP, H.264 High, +faststart.- Portada, desde la raíz del proyecto:
python tools/thumb.py frame.png cover.jpg --line "TÍTULO:#F2EFE6:120". POST.md: subtítulos por plataforma, hashtags y un recordatorio de activar la carga en HD en la aplicación.
Palabras usadas aquí
- marca: un ritmo de la historia con nombre en segundos (
MARKS), usado como límite de toma y para temporizar acciones. - estación: un lugar donde un personaje se sitúa (x, z, orientación) y el momento en que se dirige a él.
- pie plantado: un tobillo fijado en una posición del mundo (
ankle_R/ankle_L), para que el pie no pueda deslizarse. - zona de clip: un recorte en coordenadas de pantalla que oculta parte de un cuerpo detrás de algo (un seto, el borde de una pared).
- elemento plano de pared: decoración plana en una pared (cortina, póster); ordénalo tan atrás como su pared.
- práctico: una fuente de luz visible en el decorado (una lámpara, una ventana iluminada).
Hábitos
- Mira antes de afirmar. Renderiza el fotograma, lee la hoja, luego di lo que viste.
- Un cambio, una re-renderización de las tomas afectadas, una re-verificación, con hojas.
- Cuando una puesta en escena falla repetidamente, simplifícala o elige un ángulo más claro. Nunca ocultes la anatomía con desenfoque, oscuridad, cortes o subtítulos.
- Escribe cada corrección que la persona te dé en
review/LOG.mddel episodio y, si es general, en un archivoSTAGING_NOTES.mden la raíz del proyecto (léelo al inicio de cada episodio). Nunca escribas en la propia carpeta del plugin.