Construcción de Papercut
Construye cada episodio usando la biblioteca en lugar de escribir un proyecto Remotion desde cero. Lee $MOTION_LIB/core/README.md una vez.
Verificación previa
- Instalación: Estándar o Completa. Necesita la biblioteca, node 20+, npm, ffmpeg, herramientas Python (numpy, Pillow, soundfile) y Chrome/Chromium para el renderizado de audio. Verifica con los comandos en
motion-explainer; si falta algo, ejecuta./install.sh --doctory pasa amotion-setup. - Biblioteca:
$MOTION_LIB, o la líneaMOTION_LIB=en~/.config/motion-explainer/config.env, o pregunta una vez. Sin biblioteca, construye desde los bocetos en$MOTION_LIB/style/$MOTION_STYLE/remotion/RECIPES.md. - Carga primero la habilidad de mejores prácticas de Remotion solo para el motor remotion (
remotion-best-practices, desde el plugin de Remotion, onpx skills add remotion-dev/skills -g -y -a <tu id de harness>;install.sh --mode standardlo hace) y sigue su enrutamiento para marcas, subtítulos y el Studio. Parakyfram, carga la habilidadkyframen su lugar. - Necesita
video/STORYBOARD.mdynarration/script.jsonde las etapas anteriores. - Prueba de humo de todo el toolchain:
$MOTION_LIB/core/tools/selftest.shconstruyeexamples/hello-reel/en una carpeta temporal y renderiza un fotograma.
1. Preparación y verificación del motor
El proyecto del episodio ya debería estar preparado desde la fase de ingesta / motion-strategy. Verifica video/episode.json para el engine registrado:
-
Si aún no está preparado, pregunta al usuario (
remotion,fframesokyfram) y ejecuta:$MOTION_LIB/new_episode.sh <directorio-serie> NN-slug CompId [nombre-salida] --engine remotion|fframes|kyfram -
Comandos de previsualización desde
video/:- fframes:
cargo run --release -- preview(o instala CLI:cargo install --locked cargo-fframes) - kyfram: renderiza una vez, luego
kyfram view out/cache/kyfram/build/<Scene>.lgv(el script compilado: preludios + encabezado generado + tu escena) - remotion:
npx remotion studio(onpm run dev)
- fframes:
-
fframes: el proyecto del episodio es un crate de Rust (
media/,src/main.rs). Renderiza concargo run --release -- rendero$MOTION_LIB/core/tools/render.sh. -
kyfram: el proyecto del episodio son scripts
.lgv(scenes/,media/fonts/,src/plan.json). Renderiza con$MOTION_LIB/core/tools/render.sh(almacena en caché por escena y concatena). Invoca primero la habilidadkyfram. -
remotion: Proyecto React (
src/,package.json). Renderiza connpx remotion render <CompId> out/<salida>.mp4orender.sh.
2. Plan: episode.json, voz, temporización
Desde el storyboard, llena video/episode.json:
scenes:[["S01Hook", "l1_hook", 0], ["S02Name", "l2_name", "called"], ...](id de escena, id de línea de narración, primera palabra como índice o la palabra exacta).banners:{"S01Hook": "CONCLUSIÓN EN MAYÚSCULAS"}.hook: vermotion-hook.cuts: la columna de corte de la tabla Cámara/Corte.bed,whipScene,cutSfx,gaps(pulso extra después de una línea, en segundos).
Luego ejecuta motion-voice a través de su paso de temporización (termina con build_vo.py y timing_md.py). Luego, desde video/:
python3 $MOTION_LIB/core/tools/stubs.py # genera stubs de escenas multiarchivo según el motor
build_vo.py marca cualquier escena de menos de 1.2 s; combínala con una vecina. timing_md.py escribe la sección de Temporización de STORYBOARD.md (fotogramas absolutos y claves de palabra), para que los agentes nunca abran plan.json.
3. Assets
Sigue $MOTION_LIB/style/$MOTION_STYLE/docs/asset-prompts.md: una herramienta de imágenes (que genere PNGs transparentes) para fondos y accesorios estáticos complejos, código para personajes, todo texto, etiquetas, indicadores, botones e interfaz de usuario. Sin texto dentro de imágenes generadas. Sin herramienta de imágenes, construye cada accesorio en código con el filtro de papel; el estilo resiste. Fondos: usa el conjunto <Backdrop> de la biblioteca (style/$MOTION_STYLE/remotion/public/bg/backdrops/_sheet.jpg); genera uno nuevo solo cuando un episodio necesite un lugar que la biblioteca no tenga. La captura de pantalla de prueba: node $MOTION_LIB/core/tools/capture.mjs <url> public/proof/x.png, mostrada con el RealShot del kit.
4. Escenas (Arquitectura estricta de múltiples archivos)
NUNCA pongas todas las escenas en un solo archivo. Cada escena debe vivir en su propio archivo aislado para permitir trabajo paralelo de agentes, pruebas independientes y diff de git limpios.
Revisa engine desde video/episode.json:
Para Remotion (engine: "remotion")
- Estructura de archivos:
src/scenes/<Scene>.tsx(ej.S01Hook.tsx,S02Name.tsx) — exactamente un archivo por escena.src/scenes/<Scene>.parts.tsx(opcional) — para subcomponentes privados de esa escena únicamente.src/scenes/index.ts— array de registroSCENESadministrado automáticamente porstubs.py. Nunca escribas cuerpos de escena aquí.
- Construye tú mismo
S01Hookprimero ensrc/scenes/S01Hook.tsx, desde el bloque HOOK. Es la escena de referencia que los agentes deben igualar (constantes de clave, la cámara,interpolateajustado). - Entrega el resto a agentes de escena en paralelo, agrupados por escena (2-3 escenas cada uno). La instrucción es
style/$MOTION_STYLE/remotion/AGENT_BRIEF.md. - Propiedad del archivo: un agente escribe solo
src/scenes/<Scene>.tsx, un opcional<Scene>.parts.tsxytools/cue_sheet.d/<Scene>.json. Nunca edites otras escenas oindex.ts. - Los agentes leen
style/$MOTION_STYLE/remotion/CATALOG.mdy$MOTION_LIB/core/audio/CATALOG.md.
Para fframes (engine: "fframes")
- Estructura de archivos:
src/scenes/<scene_snake>.rs(ej.s01_hook.rs,s02_name.rs) — exactamente un archivo por escena, definiendo su struct eimpl Scene for <Scene>.src/scenes/mod.rs— registra automáticamente todos los módulos de escena mediantestubs.py(pub mod s01_hook; pub use s01_hook::*;).src/main.rs/lib.rs— solo monta las escenas medianteVideo::define_scenes(). Nunca escribas código de dibujo de escena dentro demain.rs.
- Construye
s01_hook.rsprimero como escena de referencia. - Entrega las escenas restantes a agentes en paralelo (cada agente es dueño solo de
src/scenes/<scene_snake>.rs). - Lee
style/$MOTION_STYLE/fframes/src/para obtener las estructuras de cámara, escenario y accesorios disponibles en lugar de componentes TSX.
Para kyfram (engine: "kyfram")
- Estructura de archivos:
scenes/<Scene>.lgv(ej.S01Hook.lgv) — exactamente un script por escena, solo formas.- El renderizador antepone
$MOTION_LIB/core/kyfram/lgv/core.lgv,style/$MOTION_STYLE/kyfram/PRELUDE.lgvy un encabezado generado (SCENE_ID,BANNER,DUR,FPSR,CAPS, y la llamadascene()), por lo que una escena nunca llama ascene(), nunca codifica su duración o claves de subtítulo, y nunca redeclara un helper.
- Invoca la habilidad
kyfram. ConstruyeS01Hook.lgvtú mismo primero como escena de referencia, y verifícala conbash $MOTION_LIB/core/tools/render.shmásbash $MOTION_LIB/core/tools/qa.sh hook 0-<N> 6 0.3 6. - Entrega las escenas restantes a agentes en paralelo (cada agente es dueño solo de
scenes/<Scene>.lgv), con la habilidadkyframnombrada en la instrucción. - Los agentes leen
style/$MOTION_STYLE/kyfram/PRELUDE.lgvpara tokens y muebles (drawRoom,drawHero,drawBanner,drawCaptions), yout/cache/kyfram/build/<Scene>.lgvdespués de un render para el script compilado exacto. - El cableado de SFX y cama sigue el flujo de remotion a continuación;
render.sh --voicemultiplexapublic/vo/voiceover.waven el mp4 una vez que ese archivo exista.
Reglas de construcción: 1080x1920, 30 fps, escenas encadenadas en la serie de transiciones del kit. Capas globales: VO y música <Audio>, el banner con cinta <Boil>, <WordTagCaptions>, <GrainOverlay>. Cada accesorio está envuelto en <Paper>, las entradas usan <PopIn>, cada escena se ejecuta dentro de su cámara de storyboard. Sin animaciones CSS. Mantén el 20% inferior despejado. Las escenas vecinas nunca comparten un fondo. El héroe predeterminado es una criatura naranja cuadrada (token C.hero #D67354, sombra C.heroLo #A9553B, alias you); los accesorios y las píldoras de nombre distinguen al elenco.
5. Sonido
Selecciona SFX por nombre desde $MOTION_LIB/core/audio/sfx/*.js y la cama por preset desde $MOTION_LIB/core/audio/beds/*.json. Para kyfram, invoca primero la habilidad kyfram y escribe filas de SFX por escena en tools/cue_sheet.d/<Scene>.json; posee el mismo pipeline de sonido compartido que fframes y Remotion. Desde video/:
python3 $MOTION_LIB/core/tools/cues.py && node $MOTION_LIB/core/audio/render.mjs
cues.py fusiona las filas de los agentes en tools/cues.json e imprime una nota si los sonidos aéreos superan uno cada 2.5 s. render.mjs escribe public/audio/music.wav y fx.wav.
6. Renderizado
Previsualización: cargo run --release -- preview (fframes), npx remotion studio (remotion) o kyfram view out/cache/kyfram/build/<Scene>.lgv (kyfram). Renderiza solo cuando se solicite, siempre a través del envoltorio: selecciona el motor desde episode.json:
$MOTION_LIB/core/tools/render.sh # -> out/<salida>.mp4
Banderas: --workers N (predet. 3), --conc N, --force, --keep. Cada escena se almacena en caché, por lo que después de una corrección solo se vuelve a renderizar la escena modificada; un cambio en el kit, el plan, la voz o los subtítulos vuelve a renderizar todo. La primera ejecución descarga el Chrome sin cabeza de Remotion, y out/cache ocupa varios GB de ProRes.
Para corregir o reconstruir una escena: edita src/scenes/<Scene>.tsx, verifica con motion-qa, luego ejecuta render.sh nuevamente.
7. Cosecha (después del episodio)
python3 $MOTION_LIB/core/tools/harvest.py . # desde video/; informe de solo lectura
python3 $MOTION_LIB/core/tools/catalog.py # regenera ambos catálogos
Promueve correcciones del kit, componentes reutilizables, nuevos SFX y ritmos recurrentes como describe library/HARVEST.md, y agrega una entrada a library/CHANGELOG.md.
- Cuando un movimiento parezca rígido o turbio, revisa
$MOTION_LIB/style/$MOTION_STYLE/docs/motion-principles.mdpara el principio correspondiente y su helper del kit.
Transferencia
Lo siguiente es motion-qa, que lee fotogramas del proyecto y STORYBOARD.md. Ejecútalo por escena mientras construyes y una vez en todo el reel antes del renderizado final. Después de la publicación, motion-strategy ejecuta la autopsia.