¿Qué hace novel-script?
Escribe guiones para series cortas generadas por IA. Premisa fundamental: el guion se ocupa de la narrativa, el storyboard de la filmación — «¿es emocionante?» y «¿cómo se graba?» son ritmos de iteración diferentes. Los diálogos se reescriben una y otra vez, y si los atas a planos, cada cambio obliga a reordenar las tomas. Por eso esta capa solo contiene episodios, escenas y flujo de ritmos: sin números de plano. Los planos, los prompts de primer fotograma y los lotes de generación son trabajo de la siguiente habilidad de storyboard.
Pero hay una línea roja: los diálogos deben ser datos estructurados, no prosa. Cada línea de diálogo es una entrada independiente (hablante + texto + tono), y la acción es un ritmo independiente. Esta es la base de todas las comprobaciones deterministas:
| Entregable | Resuelve |
|---|---|
| Presupuesto de duración por episodio | Un episodio de tres minutos son tres minutos: los diálogos se convierten según la velocidad de habla, las acciones se estiman por ritmo. Si se escribe de más o de menos, se detecta al instante, no se deja para la generación |
| Flujo de ritmos (acción ⇄ diálogo) | Los diálogos se conectan directamente con TTS para generación línea por línea; los ritmos de acción son lo que debe ocurrir en pantalla. Mezclarlos en prosa no alimenta la tubería |
| Al menos un ritmo de acción por escena | Una escena solo con diálogo es un radiodrama: la IA no tiene nada que dibujar al generar |
| Gancho de apertura + suspenso final | La línea de vida de una serie corta, cada episodio debe tenerlo por escrito; el gancho no es una etiqueta, es el primer ritmo — hookBeat reclama la posición concreta, debe caer dentro de los primeros 3 ritmos del episodio completo (apertura en frío) |
| Reclamación de puntos culminantes | Si el resumen dice que este episodio tiene un gran clímax, el guion debe tener una escena que lo reclame — evita que se pierda al reescribir |
| Conciliación con upstream | Escenas/iluminación/atrezzo contra art.json, personajes contra outline.json; si se escribe un estado de iluminación no registrado en arte, se reporta al instante |
{baseDir} = directorio donde se encuentra este archivo. El script {baseDir}/scripts/novel-script.mjs no tiene dependencias, se ejecuta directamente con node.
Límites (lo que no hace): sin números de plano, sin prompts de generación de imágenes, sin generar imágenes, sin música — no toca nada del storyboard. No modifica la estructura del esquema (cortar o fusionar líneas es trabajo de novel-outline); no define personajes ni escenarios (trabajo de novel-characters / novel-art).
Step 0 — Definir entrada y alcance
outline.json es el upstream directo del guion (resúmenes por episodio, puntos culminantes, duración por episodio). El flujo estándar comienza desde ahí. Si no existe, pregunta al usuario si debe ejecutar novel-outline; si el usuario insiste en escribir directamente, pide el número de episodios y la duración en minutos por episodio, construye un esqueleto manualmente, y la puerta de conciliación indicará que se omite.
¿Cuántos episodios por vez?: Por defecto, un lote ≤ 3 episodios. El guion es la capa que se modifica con más frecuencia en toda la tubería; lote pequeño, decisión rápida, luego se escribe el siguiente. Si el usuario pide la serie completa, se produce en lotes, cada uno pasando la validación.
Opcionalmente (se proporcionan solo para conciliación/mostrar nombres):
--outline: conciliación de referencias a personajes + verificación de reclamación de puntos culminantes + el informe muestra nombres reales en C01--art: conciliación de escenarios/estados de iluminación/atrezzo + el informe muestra nombres de escenario en S01
Step 1 — Esqueleto seed
node {baseDir}/scripts/novel-script.mjs seed <outline.json> --eps 1-3 > <workdir>/script.json
Transferencia determinista: duración objetivo (minutos del episodio × 60), gancho, suspenso, reclamación del punto culminante del episodio, escenarios y personajes candidatos (en seedNote). No dejes que el modelo vuelva a pensar estos datos. scenes se deja vacío; eso es trabajo de la escritura.
Step 2 — Escribir episodio por episodio
Cada episodio es una tarea, se pueden paralelizar. Cada tarea recibe:
{baseDir}/references/script-pass.mdy{baseDir}/references/schema.md(léelos, síguelos)- El esqueleto seed del episodio + el resumen/puntos culminantes/esquema de personajes de ese episodio en el esquema
- Las fichas de escenario (anclas, estados de iluminación de art.json) e información de personajes (personalidad, forma de hablar — mejor si hay cast.json)
- El suspenso final del episodio anterior (la apertura de este episodio debe conectar)
Los requisitos principales están en script-pass.md, los cuatro más importantes: los ritmos de acción solo describen acciones comunes (cargar una carga en un barco, agarrar un poste, etc. — acciones que la IA ha visto millones de veces; acciones delicadas como estirar un poste para bloquear o un parpadeo de pestañas fallan en generación); el presupuesto de duración es lo primero (un episodio de tres minutos tiene unos 50 ritmos; después de escribir, ejecuta validate para ver los segundos); los diálogos deben ser coloquiales, una línea completa de una sola vez, que cada quien hable como es (si hay cast.json, usa la personalidad y forma de hablar del personaje); el primer ritmo de cada episodio debe ser una apertura en frío que concretice el gancho (hookBeat lo reclama, la puerta verifica la posición), el último ritmo debe ser un suspenso.
Después de escribir, elimina seedNote.
Step 3 — Validación ⛔ No se puede saltar
node {baseDir}/scripts/novel-script.mjs validate <script.json> \
--outline <outline.json> --art <art.json>
Las 10 puertas de calidad son todas código: duración por episodio dentro del ±15% del objetivo (diálogos convertidos a 4.5 caracteres/segundo, acciones a 2.5 segundos/ritmo, params ajustable), cada línea de diálogo ≤ 35 caracteres, el hablante está entre los personajes de la escena o marcado como VO, gancho y suspenso por escrito en cada episodio, el gancho concreto se cumple dentro de los primeros 3 ritmos del episodio completo (hookBeat lo reclama, params.hookWindow ajustable), al menos un ritmo de acción por escena, la acción narrativa no mezcla comillas de diálogo, reclamación de puntos culminantes, conciliación de personajes, conciliación de escenarios/iluminación/atrezzo.
Si hay infracciones, corrígelas una por una, vuelve a ejecutar, hasta que pase. Si escribes de más, primero quita ritmos de acción, luego comprime diálogos; si escribes de menos, añade trama sin relleno — añade conflicto, no cortesías. Si necesitas un estado de iluminación no registrado en arte, ve a art.json a agregarlo y luego vuelve, no eludas la puerta.
Step 4 — Salida e informe
cd <directorio de salida>
node {baseDir}/scripts/novel-script.mjs render <nombre-serie>-script.json --md \
--outline <outline.json> --art <art.json> > <nombre-serie>-script.md
node {baseDir}/scripts/novel-script.mjs render <nombre-serie>-script.json --html \
--outline <outline.json> --art <art.json> --cast <cast.json> > script-report.html
# Interfaz en inglés: añade --lang en (por defecto chino, o sigue el campo lang de script.json)
El informe incluye: KPI (incluido porcentaje de diálogo), panel de duración (barras por episodio dentro de la banda objetivo, fuera de rango en rojo), guion por episodio (dos episodios por fila, información de escena con más de 300px se desvanece cortando, haz clic para expandir), tabla de escenas, libreto (dos por fila, agrupados por personaje, lista de seis líneas de alto con desplazamiento, copia del grupo completo; con --cast cada grupo de personaje tiene un botón de sugerencia de tono de voz — diálogo y tono en una página, listo para TTS), panel de puertas de calidad, exportación JSON (descarga el script.json original).
El informe dice en una frase: cuántos episodios/escenas/líneas de diálogo, duración estimada total vs objetivo, qué episodios están cerca del margen de tolerancia, ruta del informe; las puertas no superadas se indican claramente.
Salida final:
<directorio de salida>/
├── <nombre-serie>-script.json
├── <nombre-serie>-script.md
└── script-report.html ← Se abre con doble clic
Relevo de las cuatro habilidades
novel-outline → outline.json (qué: estructura y episodios)
novel-characters → cast.json (quién: activos de personajes)
novel-art → art.json (dónde + lo que llevan: activos artísticos)
novel-script → script.json (trama: escenas, ritmos, diálogos)
seed consume outline.json; los parámetros --outline --art de validate/render se encargan de la conciliación y mostrar nombres. Los cuatro JSON tienen sus propios informes con botón de exportación; después de modificar, se pueden volver a pasar por sus respectivos render/validate. El siguiente nivel es el storyboard: números de plano, duración por plano, prompt de primer fotograma, lotes de generación en ese lado.
Límites
- El informe incluye interfaz en chino/inglés (
--lang, por defecto chino, o sigue el campolangde script.json); el idioma de los diálogos va con la serie - La duración es estimación, no cronómetro — el margen ±15% está previsto para ello;
params.charsPerSecondse puede ajustar según la velocidad de doblaje VOes la marca unificada de voz en off; quién habla en su mente se escribe endelivery; en el libreto, VO forma un grupo separado- No hay límite de escenas por episodio — cambiar de escenario en IA no cuesta dinero; el número de cambios solo entra en la estadística de KPI, no hay puerta
Autoprueba
node {baseDir}/scripts/selftest.mjs
154 afirmaciones, sin invocar modelos, sin gastar crédito. Cada una de las 10 puertas de calidad tiene un caso de prueba de ruptura. Después de modificar el script, ejecuta esto primero.
Ejemplos incluidos
{baseDir}/examples/渡口-script.json: guion completo de 6 episodios de «渡口 (El Ferry)» (9 escenas, 123 líneas de diálogo; cada episodio abre en frío con el gancho, dentro de 120 segundos ±15%). Contra los ejemplos de novel-outline y novel-art, todas las puertas de calidad pasan. Sirve como referencia de calidad y como fixture de autoprueba.