Saltar al contenido
Tórculo1.0 · borrador de trabajo

Texto normativo · Borrador de trabajo

Tórculo: un estándar para películas escritas como pliegos, versión 1.0

Manda el inglés si las dos versiones discrepan. Las palabras clave del BCP 14 (DEBE, PUEDE…) van marcadas.

  • Estado: Borrador de trabajo, 2026-10-15. Lo bastante estable para implementarlo; los cambios pasan por el proceso de RFC (spec/rfcs/). La batería de conformidad de conformance/ forma parte de esta especificación.
  • Editor: José Luis Saorín Ferrer.
  • Esta versión: spec/SPEC.md en https://github.com/joseluissaorin/torculo (privado hasta que pasen la especificación, la batería de conformidad y las implementaciones de referencia).
  • Traducción: traducción española fiel de SPEC.md; si discrepan, manda el inglés.
  • Licencia: esta especificación se publica bajo CC BY 4.0. El código del repositorio es MIT OR Apache-2.0. Quienes contribuyen se comprometen a no hacer valer patentes contra las implementaciones.

Resumen

Tórculo es un estándar abierto para hacer películas, vídeos explicativos, cortos de animación e ilustraciones en movimiento a partir de un texto que se lee como la película. Ese texto es un pliego, un fichero .mesa escrito en la lengua de Tórculo: un guion orientado a líneas, en español, con vocabularios cerrados, en el que el autor dice qué pasa y cómo («la piedra rueda hasta el borde, pesada») y el motor deriva todos los números (posiciones, curvas, duraciones, colores, sonoridad). El estándar tiene siete partes: la lengua de pliegos, el proyecto portable (.mesapack) con su sidecar de voz, las piezas (dibujos, marionetas, personajes y collage), el canon de la casa (paleta y azar determinista, con vectores de prueba en tres lenguajes), las láminas (dibujos a mano revelados por un atlas de tiempo), las materias (la convención de pasadas WGSL para papel, acuarela, risografía y transiciones) y las tomas (la salida grabada del motor, un fork de ManimGX, con su API pública). Todas las partes son deterministas: las mismas entradas dan la misma película.

Estado de este documento

Esta es la primera versión pública del estándar. Su parte de la lengua absorbe y reorganiza SPEC-MESA-2.md de manim-saorín (el documento de trabajo de la implementación de referencia, época 2 de la lengua); las demás partes formalizan documentos que ya existían (pluma/LAMINA.md, materias/README.md, FORK.md, SPEC-PIEZAS.md). Cuando este texto y un caso de conformidad discrepan, la discrepancia es un fallo que se resuelve por el proceso de RFC; mientras no se resuelva, las implementaciones siguen el caso de conformidad. Las desviaciones conocidas de la implementación de referencia respecto de este texto se enumeran en el apéndice D y figuran como casos pendientes en la batería.

Índice

Prefacio

Un tórculo es la prensa del grabador. La plancha se trabaja una vez y se estampa tantas veces como haga falta. En este estándar la plancha es un pliego, un dibujo o una materia, y las estampas son un vídeo, una página web, una app o un juego. La mesa es la mesa de trabajo donde se dispone el pliego (la hoja que pasa por la prensa): por eso los pliegos conservan la extensión .mesa.

La lengua nació dentro de manim-saorín, una biblioteca de collage en movimiento sobre Manim, para vídeo-ensayos con aspecto de cuaderno: papel, tinta que hierve, recortes con cinta, tambores de risografía. Su primera época (SPEC-MESA.md) creció como un registro de cambios; la segunda (SPEC-MESA-2.md, 2026-08) la hizo formal; el cortometraje Radiointermisión (2026-10) le enseñó carteles, cámaras, sonido y una imagen que escucha. En paralelo, Scholaris dio a la casa su pluma de dibujo a mano y su papel crema, y un fork de ManimGX (un motor en Rust y wgpu con la API de Python de Manim) se convirtió en el motor común: una película escrita en un pliego que tardaba unas tres horas y tres cuartos en renderizarse con Cairo se renderiza en él en menos de ocho minutos. Tórculo es el nombre de ese conjunto: la lengua, los formatos que la rodean y el motor con que se imprimen.

La lengua es española por diseño. Sus palabras clave son palabras españolas que se leen como español (la piedra rueda hasta el borde · pesado), las tildes distinguen palabras donde el español lo necesita (él es un personaje, el un artículo), y las derivaciones del motor codifican un oficio (los principios de animación de Lasseter, el montaje de continuidad, la imprenta) en lugar de parámetros. Esta especificación está escrita en inglés para que cualquiera pueda implementarla; cada palabra clave se cita tal como se escribe en un pliego.

1. Convenciones y terminología

Las palabras clave DEBE (MUST), NO DEBE (MUST NOT), OBLIGATORIO (REQUIRED), DEBERÁ (SHALL), NO DEBERÁ (SHALL NOT), DEBERÍA (SHOULD), NO DEBERÍA (SHOULD NOT), RECOMENDADO (RECOMMENDED), PUEDE (MAY) y OPCIONAL (OPTIONAL) se interpretan como se describe en BCP 14 (RFC 2119 y RFC 8174) cuando, y solo cuando, aparecen en mayúsculas. En esta traducción cada una sustituye a la palabra inglesa indicada entre paréntesis, con su mismo alcance; sus formas de plural (DEBEN, PUEDEN, DEBERÍAN…) tienen el mismo valor.

1.1 Términos

TérminoSignificado
pliegoUn fichero .mesa: un guion en la lengua de Tórculo.
servilletaUn pliego sin ninguna cabecera de capítulo (==): prosa llana (§5.12).
capítulo (chapter)Una unidad de página y de render, abierta por ==. Los capítulos PUEDEN renderizarse en paralelo.
escena (scene)Una unidad de mundo dentro de un capítulo, abierta por --; el mundo persiste entre sus planos.
clip o beatUna unidad de tiempo (un plano), abierta por *.
línea (line)Una unidad de acción dentro de un clip.
pieza (piece)Todo lo que se pone en la mesa: una cartulina, una etiqueta, un dibujo, una marioneta, una fotografía, un letrero.
bestiario (bestiary)El catálogo de piezas con nombre del proyecto (PYTHON, PIEZAS).
compiladorUn programa que analiza un pliego, lo comprueba (§12) y produce su IR (§10).
intérpreteUn programa que convierte un IR en fotogramas y sonido. La referencia tiene dos: ce (Manim Community Edition, Cairo) y gx (el motor de Tórculo).
IRLa representación intermedia (guion rico), en JSON (§10).
sidecar<pliego>.tiempos.json: las duraciones de la voz y los tiempos de cada palabra, y dónde están sus grabaciones (§14.3).
toma (take)Una grabación de una ejecución del motor como un flujo de mensajes (.take, §19).
láminaUn dibujo a mano con un atlas de tiempo, listo para que cualquier motor lo revele (§17).
materiaUna pasada de cómputo sobre un plano (papel, acuarela, risografía…), en la convención de §18.
canonLa única fuente de verdad de la casa: paleta, azar, números del oficio, pesos del foley (§16).
época (epoch)La versión de la lengua en que está escrito un pliego (§22).

1.2 Notación

Las producciones de la gramática usan el EBNF del apéndice B (spec/gramatica/mesa.ebnf): los nombres en mayúsculas son no terminales, "literal" es texto literal, [ ] opcional, { } cero o más, | alternativa, TEXT el resto de la línea, NL un fin de línea, QUOTE un texto entre comillas latinas. Un no terminal en mayúsculas que la gramática no define es un vocabulario cerrado (§6, apéndice A); esa correspondencia es exhaustiva.

En este documento las palabras clave se escriben con sus tildes, como se leen; la comparación se hace sobre la forma normalizada (§4.5).

1.3 JSON canónico

Siempre que esta especificación calcula el hash de un JSON o lo compara, usa el esquema de canonicalización JSON de la RFC 8785 (JCS): claves de objeto ordenadas por unidades de código UTF-16, sin espacios en blanco, números en la forma más corta que se conserva en ida y vuelta en notación ECMAScript (1.0 es 1, 1e-7 es 1e-7), cadenas en UTF-8 crudo que solo escapan ", \ y de U+0000 a U+001F. La implementación de referencia es conformance/tools/jcs.py.

2. Arquitectura y conformidad

2.1 Las siete partes

ParteObjeto normativoVersión en Tórculo 1.0
1. Lengua de pliegosel fichero .mesa, su compilación y su interpretaciónépoca 2
2. Proyecto portableel paquete .mesapack y el sidecar de vozmesapack 1
3. Piezasel contrato de pieza (niveles, ficha, partes, marionetas, personajes)1
4. Canonpaleta, azar, números del oficio y del foleycanon 1
5. Láminasel formato .lamina1
6. Materiasla convención de pasadas WGSL1
7. Tomas y APIel flujo .take del fork y las interfaces públicas del motor0x8000_0002

Cada parte puede implementarse por separado. Un producto declara su conformidad con una parte y, cuando la parte define clases o perfiles, con esas clases y perfiles.

2.2 Clases de producto

ClasePartePasa los tipos de caso de la batería
Compilador1vocabulario, lee, ir (proyección normativa, §10.6), cierre, espejo
Intérprete, por perfil1huella y banda para los pliegos de sus perfiles (§8)
Empaquetador2mesapack_referencia; sus paquetes pasan mesapack
Lector de paquetes2mesapack
Proveedor de piezas3las comprobaciones de piezas de §15.6
Implementación del canon4canon_azar y canon_paleta para su lenguaje
Productor de láminas5lamina (salida idéntica byte a byte)
Lector de láminas5revela cada lámina de la batería como dice §17.5
Anfitrión de pasadas6ejecuta toda materia conforme; materia para el comprobador
Escritor / lector de tomas7toma

2.3 La conformidad en general

Un producto conforme:

  1. DEBE aceptar todo lo que esta especificación declara válido para su clase, y rechazar lo que declara inválido, con los códigos de diagnóstico del apéndice C donde haya un código definido;
  2. NO DEBE extender un vocabulario cerrado en silencio (§6.1);
  3. DEBE ser determinista en el sentido de §7.4 y §16.3;
  4. DEBE pasar todos los casos no pendientes de su clase en la batería de conformidad de la misma versión (conformance/manifest.json);
  5. DEBERÍA comunicar sus resultados en el formato de informe de conformance/README.md.

A un compilador no se le exige renderizar: comprobar un pliego y producir su IR son operaciones conformes sin ningún motor gráfico.


Parte 1. La lengua de pliegos

3. Principios

Estos principios son normativos: deciden toda cuestión que este texto no zanja, y una RFC que rompa alguno DEBE decirlo y explicar por qué.

  1. La constitución anti-parámetro. El pliego dice cuentas humanas y maneras; el motor pone los números. Un pliego no tiene easing, fotogramas clave, tiradores de Bézier, funciones de ritmo, colores hexadecimales, sombras por pieza ni duraciones sueltas en el dialecto pobre (§3.1). Ninguna capacidad nueva entra en la lengua si obliga a los pliegos a decir números que antes se derivaban.
  2. Vocabularios cerrados. La constitución solo se sostiene porque todo vocabulario es cerrado, y los vocabularios cerrados solo son tolerables porque el motor deriva. Una palabra fuera de su lista es un error, nunca una extensión silenciosa.
  3. Cierre. Escribir lo que el motor decidió no cambia la película (§11.1).
  4. La identidad es la semilla. Todo lo aleatorio se siembra a partir de la identidad de lo que afecta, calculada a partir del contenido, nunca de la posición, el proceso, el reloj ni el sistema de archivos (§7.4).
  5. Lo que no cabe en la hoja no se lee. Un texto que no puede leerse en el tiempo que está en pantalla es un defecto (§12, la revisión de Lasseter).
  6. La lejanía manda. La velocidad, el color y la profundidad de cada capa se derivan de su distancia (lejanía) y de nada más, con una excepción declarada (§7.7).
  7. Los tres asientos. Una capacidad que no está en la gramática, el compilador y el intérprete no existe. Una directiva que conociera el vocabulario pero no el analizador se imprimiría en pantalla como narración, que es el peor fallo del sistema; por eso todo no terminal tiene su tabla (§6) y todo evento declara si está vivo o reservado (§6.3).
  8. La ley de autoridad. La documentación se enumera desde el analizador, no desde la memoria. Los vocabularios del apéndice A se extraen del analizador de referencia (spec/vocabularios/extrae.py) y la batería comprueba que coinciden (vocabulario).

3.1 Los dos dialectos

DialectoQuién lo escribeNúmeros
pobre (plain)una personaninguno
revelado (revealed)mesa escribe, los transpiladores, el modo réplicasí, cada decisión marcada (máquina)

La proporción pobre de un pliego es la fracción de sus líneas de dramaturgia sin cifras. Un pliego de autor DEBERÍA mantenerla en el 85 % o más; un compilador DEBE calcularla y DEBERÍA avisar por debajo del 85 % (W112). Quedan fuera de la cuenta, cada cosa por su razón: los bloques de sección (calibran un oficio, y ahí los números son legítimos), el cuerpo de un ver: (los datos que dibuja una visualización), los títulos de capítulo, los comentarios y la línea de formato. Los nombres de cues de sonido y de efectos (por ejemplo 1M1) son nombres, no cifras, y NO DEBERÍAN contar (véase el apéndice D).

4. Estructura léxica

4.1 Codificación y líneas

Un pliego es UTF-8 sin marca de orden de bytes. Los compiladores DEBEN normalizarlo a NFC antes del análisis. Las líneas terminan en LF o CRLF. El análisis es por líneas: cada línea se clasifica por su prefijo, y el prefijo siempre gana. Solo los bloques de sección (§5.3) y dentro: (§5.10) abarcan varias líneas. Las líneas en blanco separan clips. La sangría inicial no es significativa salvo dentro de los bloques de sección y de dentro:.

4.2 Comentarios, digresiones y encargos

FormaSignificadoEn el IR
// textcomentario técnicono
( text ) en una línea propiadigresión del autorsí, digresiones
~ deriva: textun encargo al motorsí, derivas

4.3 El separador de campos

El punto medio · (U+00B7), con espacios opcionales alrededor, es el único separador de campos dentro de una línea.

4.4 Las comillas

El texto que va a pantalla, y los nombres que se refieren a texto, se escriben entre comillas latinas «…» (U+00AB, U+00BB). Las comillas rectas no son equivalentes y NO DEBEN aceptarse en su lugar. Una línea que consiste solo en un texto entrecomillado es un grito (shout); un clip tiene como mucho uno (E030).

4.5 Identificadores y normalización

Un identificador es una secuencia de letras (incluidas las letras con tilde y la ñ), dígitos y _. Las claves de sección PUEDEN contener espacios.

Las palabras clave y las palabras de los vocabularios se comparan tras esta normalización:

  1. minúsculas;
  2. las series de espacios se reducen a uno;
  3. _ equivale a un espacio (toca_la_truca es toca la truca);
  4. se eliminan los diacríticos combinantes (NFD, se descartan de U+0300 a U+036F): la forma canónica no lleva tildes, y se aceptan las dos formas (ilustración es ilustracion).

Excepción: las palabras reservadas (§6.4) se comparan tal como se escriben, sin normalizar, porque en español la tilde diacrítica distingue palabras: el es un artículo reservado y él es un nombre de personaje válido; igual tu/tú, si/sí, mas/más.

Los identificadores de piezas y dibujos (id, nombres del bestiario) DEBERÍAN ser ASCII: son semillas (§16.3), y una tilde cambia la semilla.

4.6 Números

NUMBER es un entero o un decimal con punto, con signo opcional. Donde la lengua acepta coma decimal, lo dice (2,39:1).

4.7 La marca (máquina)

Un (máquina) al final declara que esa decisión la tomó el motor, no una persona. Afecta a los campos de procedencia del IR (autor_cabecera, origen) y a nada más; en particular, no afecta al hash maestro (§7.4).

4.8 La raya

La raya — (U+2014) separa una cabeza de su cuerpo en MOTIVO, PERSONAJE, ver: y juntos:. Los compiladores DEBEN aceptarla con o sin espacios a cualquiera de sus lados. El estilo canónico, el que usan este documento y la batería, la pega al cuerpo, como hace la puntuación española con una raya de apertura: MOTIVO «error» —empieza como enemigo, ver: votos —sí: 7 · no: 4, juntos: a · b · c —en fila. En el diálogo, la raya que abre un parlamento forma parte del texto (él: —¿Falta mucho?).

5. Gramática

La gramática completa es el apéndice B. Esta sección expone la estructura y las reglas que las producciones por sí solas no expresan.

5.1 El documento

PLIEGO   = PREAMBLE { CHAPTER } [ END ] ;
CHAPTER  = CHAPTER-HEAD { UNIT-LINE | SECTION | COMMENT } { SCENE | CLIP } ;
SCENE    = SCENE-HEAD { UNIT-LINE | SECTION | COMMENT } { CLIP } ;
CLIP     = CLIP-HEAD { CLIP-LINE } ;

El mismo conjunto de líneas de unidad es válido en el preámbulo, en un capítulo y en una escena; las secciones son válidas en los tres niveles. Dentro de un clip, las líneas se clasifican por su prefijo, el prefijo siempre gana, y se conserva su orden.

5.2 El preámbulo

MESA [v N] TITLE abre un pliego y PUEDE declarar la época (MESA v2 «El puerto»). Un pliego que declara una época más nueva que la del compilador DEBE rechazarse (E001).

formato declara propiedades: una relación de aspecto (16:9, 4:3, 2,39:1), sala crema o sala pizarra, tirada borrador o tirada definitiva, página desnuda (sin folio ni sello, solo papel) y en dos (todo lo dibujado, animado a dos fotogramas).

REPARTO NAME: drum[, voice][, voice colour][, side][, alias: A · B] declara a un hablante. El reparto es normativo para el diálogo: un hablante que no está declarado en REPARTO o en PERSONAJE no es un hablante (§5.5). El color de voz es con radio o seca (si no, E016); el lado es a la izquierda, a la derecha o al centro.

El preámbulo lleva también los recursos del proyecto: PYTHON (o PIEZAS, parte 3) para el bestiario, EFECTOS y BANDA para las carpetas de sonido, MEZCLA para la mezcla, PARTITURA, SOPORTE, LETRA, ARCHIVO, FANTASMA, RELOJES y SONIDO. Las rutas son relativas a la carpeta del pliego; en un proyecto portable DEBEN serlo (§14).

En la época 2, la línea de preámbulo MUSICA path (modo canción: la canción manda en el montaje) y la línea de unidad MÚSICA cue (una cue de BANDA) comparten palabra clave. Un compilador DEBE tratar MÚSICA seguida de un nombre que existe en BANDA como una cue, y cualquier otra línea MÚSICA del preámbulo como una canción, con tilde o sin ella (RFC 0004; apéndice D).

5.3 Las secciones y la ley del espejo

SECTION = "#" NOMBRE-SECCION [ IDENT ] NL { SECTION-LINE } "#FIN" | NOMBRE-SECCION PATH ;

Un bloque de sección escrito dentro del pliego es idéntico en gramática al fichero importado en su lugar. Invariante (§11.2):

effective(p) == effective(parte(p)) == effective(funde(parte(p)))

Las claves de varias palabras llevan dos puntos (por defecto: tijera) para que sobrevivan a la ida y vuelta. La precedencia, única y sin excepciones, es por herencia parcial (una línea sobrescribe una línea):

imported  <  inline in the preamble  <  chapter block  <  scene block

(Es decir: lo importado, menos que lo escrito en el preámbulo, menos que el bloque de capítulo, menos que el bloque de escena.)

TALLER y MANO son normativas (apéndice A: FAMILIA_TALLER, CLAVE_MANO); la sección BESTIARIO equivale a la línea PYTHON del preámbulo, y la sección REPARTO, a las líneas REPARTO del preámbulo; MONTAJE y CASCADA están reservadas (§6.3).

5.4 Capítulos y escenas

== TITLE · attributes ==== abre un capítulo. Atributos: tensión (una TENSION), nº, tambor, gigante, plano fijo (una PLANTILLA, no una talla), tramo a → b, nocturno, diurno.

-- TITLE [· HORA] -- abre una escena. Líneas de unidad del núcleo:

  • EJE de A a B: la regla de los 180 grados. De ella se derivan el lado de cada quien, la dirección de las miradas y por dónde vuelve a entrar quien salió por un lado.
  • LUZ direction · hardness [· rasante]: una por escena; gobierna todas las sombras. Ninguna pieza declara su propia sombra.
  • MUNDO movement [N] · direction: el reloj del mundo (§7.7).
  • FONDO key · distance y DELANTE key [· distance] [· cada N]: fondo multiplano y proscenio; la velocidad, el color y la profundidad se derivan de la lejanía.
  • ESCENARIO, TABLAS (el teatro de papel como decorado fijo; la hora tiñe, no oscurece; quien tiene pies se apoya en el suelo), ARCHIVO, REPITE «scene» (los mismos clips con las mismas identidades: el mismo vídeo).

Las líneas de unidad del preámbulo se aplican a todo el pliego; en un capítulo o una escena, a ese capítulo o esa escena. La escena prevalece sobre el capítulo y el capítulo sobre el preámbulo.

5.5 Clips

CLIP-HEAD = "*" [ BEAT-ID ] ( FUNCION | SHOT ) [ "·" AFECTO ] [ "(máquina)" ] ;
SHOT      = { TALLA | ALTURA | FRENTE | MODO } [ "de" [ ARTICLE ] IDENT ] ;

Dos lenguajes, los dos legítimos: una función dramatúrgica (* prueba · seco), de la que se deriva la plantilla de composición (§6.5), o un plano (* corto contrapicado de tercero · nervioso), que declara una talla. Son dos ejes (§6.5). El artículo del sujeto se descarta (general de la carretera tiene por sujeto carretera). Un id de beat opcional (* r01_02 primer de LOCUTOR · …) da al clip un identificador estable, el que usa el sidecar.

Líneas de contenido: di: TEXT es la narración y la partitura del beat: su locución da la duración del beat. SPEAKER: TEXT es diálogo; el hablante DEBE estar declarado y NO DEBE ser una palabra reservada (E021); las directivas se resuelven primero, de modo que un hablante con nombre de directiva no puede capturarla. SPEAKER / SPEAKER: … es una frase partida entre dos voces. letrero (register): TEXT es un letrero (REGISTRO_LETRERO; desconocido: E014; reservado: W111). terminal:, canta: y la prosa llana completan las líneas de contenido.

5.6 Piezas y colocación

pon: TYPE «text» · attributes pone una pieza de un TIPO-PIEZA; foto:, recorte: y prensada: ponen material de archivo; ver: KEY —body, una visualización del catálogo CLAVE_VIS, cuyo cuerpo son datos; pica:; python: NAME args, una pieza del bestiario (parte 3); arriba:, pie:, nota:; marca: GESTURE «text» (GESTO_MARCA).

La ley del cuerpo: casi nada va en coordenadas. La colocación es relacional: en los pies de primero:, bajo «X» a 0.42:, junto a, delante de, detrás de, juntos: a · b · c —disposition, en el mundo:, en el documento:, y los prefijos de los perfiles (en MATERIA:, de «A» a «B»:, a la izquierda:, una lejanía, en silueta:). Los prefijos se encadenan, y se encadenan con al decir «…»:. El tamaño de un dibujo va tras un · (grande, enorme, gigante, a sangre).

clip: path [de mm:ss a mm:ss] pone vídeo real, un recorte vivo cuyo sonido entra en la mezcla en su tiempo exacto. Un clip dura lo que dice que dura: un beat NO DEBE cerrarse mientras uno de sus clips sigue corriendo; en su lugar, el beat crece (W123 dice cuánto). > espera al clip da al clip el turno entero: primero suena la narración, luego una respiración, luego el clip, y la banda de subtítulos se retira mientras corre. La realidad no se revela: un clip de vídeo real nunca pasa por el cuarto oscuro (ni trama, ni duotono, ni troquel de tijera).

5.7 Movimiento

MOVEMENT = [ PLACEMENT ] [ ARTICLE ] SUBJECT VERB [ DESTINATION ]
           { "·" ( [ "por" ] TRAYECTO | MANERA | GRANULADO | REGISTRO-MOV | RASTRO ) } [ WINDOW ] ;

Un movimiento se reconoce por su verbo (VERBO_MOV, VERBO_RELACIONAL), nunca por sus sufijos. Si no, la piedra rueda hasta el borde, sin sufijo, caería en la prosa y se imprimiría como narración (§3, principio 7). Tras un · en una línea de movimiento solo son válidos un trayecto, una manera, un granulado, un registro, un rastro o una ventana; cualquier otra cosa es un error (E012). Los verbos relacionales crean una ligadura viva que muere con su objetivo; un ciclo de ligaduras, una cadena de más de tres eslabones o un anidamiento de más de tres niveles son un error (E032).

La ley del movimiento: la curva nunca se declara; se deriva de la materia, la mano, el afecto y la manera (§7.6).

Verbos de la vida. Un personaje o una marioneta también se gira, se sienta y mira, con palabras llanas: X se gira, X se da la vuelta, X se vuelve hacia la cámara, X se pone de frente | de perfil, X se vuelve de espaldas; X se sienta | se levanta | se inclina | se yergue | se asoma a la barandilla | se apoya en la barandilla; X asiente | niega | se encoge de hombros | se rasca la cabeza; X se acerca (camina hacia la cámara y crece sobre sus pies), X se aleja; X mira a «Y» (cabeza y ojos hacia otra pieza hasta el beat siguiente); X se queda quieto (solo respira). Todos se pueden anclar (al decir «gol»: X se asoma a la barandilla). Sin comillas, A mira a B es a la vez la mirada que actúa la pieza y la mirada del cine (§5.8, W103); un compilador DEBE conservar los dos sentidos.

5.8 Cámara, cine y viaje

la truca ORDER [IDENT] [en SIZE] mueve la truca (ORDEN_TRUCA); A mira a B (también a alguien fuera de cuadro); A sale|entra por la SIDE; sonido: adelanta|retiene|dentro|fuera (cortes en J y en L); fuera de campo: TEXT; el foco en X, el foco pasa a X, todo en foco (el foco es densidad de tinta, nitidez del borde y sombra, nunca desenfoque); X está STATE (un estado para la continuidad). El viaje: X viaja, X se apea, el mundo MOVEMENT, por la ventanilla: … desfilan.

5.9 Eventos

EVENT = ">" EVENT-NAME [ ARG ] { "·" ">" EVENT-NAME [ ARG ] } ;

Los nombres de evento son un vocabulario cerrado con estado (§6.3). Un evento escrito en un clip actúa en su lugar dentro del orden del autor y puede anclarse a la voz (al decir «GOL»: > temblor). Una transición escrita en un clip dice cómo entra el clip; funde a negro y funde a blanco dicen cómo sale. Cuatro eventos se copian además a un campo del clip porque otra pasada los lee (EVENTO_A_CAMPO): salta y cruza el eje (las escapatorias de los avisos de continuidad), congela y continúa.

5.10 Anidamiento y concurrencia

dentro: abre subclips (como mucho tres niveles); mientras: abre una pista paralela; al decir «w»: LINE ancla una línea al momento en que la voz dice w; LINE hasta decir «w» la estira hasta entonces. Las anclas se escriben como se escriben, no como suenan; un compilador con el sidecar empareja las cifras con su lectura (1154 y «mil ciento cincuenta y cuatro») y las transcripciones aproximadas por distancia de edición, y avisa de las anclas que nunca casan (W120) o que casan con la voz pero no con el texto (W122).

5.11 El final

== FIN === cierra la película; las líneas que lo siguen son su colofón; > silencio N, su silencio final (sin él, el compilador aplica 3 segundos y avisa, W113).

5.12 La servilleta

Un pliego sin ningún == es prosa: cada frase es un clip y el dramaturgo (reglas fijas, sin aprendizaje automático) decide el resto. Es la puerta de entrada y DEBE funcionar siempre: todo compilador y todo intérprete del perfil núcleo DEBE aceptar una servilleta, incluida una con un preámbulo que declara su sonido (BANDA, MÚSICA, AMBIENTE).

6. Vocabularios cerrados

6.1 La ley

Si una palabra no está en su lista, es un error, no una extensión silenciosa. Todo no terminal de la gramática que la gramática no define es un vocabulario cerrado que figura en el apéndice A, con la estructura del analizador de referencia de la que se extrae y el perfil al que pertenece. El apéndice A se genera (spec/vocabularios/vocabularios.json); un compilador DEBE aceptar exactamente esas palabras para la época que implementa, comparadas tras la normalización (§4.5), y DEBE rechazar cualquier otra palabra en una posición cerrada con el código de esa posición (apéndice C).

Los vocabularios de una época están congelados: una versión posterior de un compilador NO DEBE rechazar una palabra que la época declaró, incluidas las reservadas (§6.3). Las palabras nuevas solo entran mediante una RFC y están disponibles para los pliegos que declaran la época que las introdujo.

Un compilador acepta la lengua entera. Los perfiles (§8) dicen lo que un intérprete realiza; nunca restringen lo que acepta un compilador. Un compilador NO DEBE rechazar una palabra de ningún perfil porque un intérprete concreto no la realice.

6.2 Panorama

El apéndice A enumera 98 vocabularios (1015 palabras en total en esta versión). Los más usados:

VocabularioPalabrasNotas
AFECTO8contenido, eufórico, exhausto, juguetón, nervioso, seco, sereno, solemne
FUNCION11apertura, cartel, contrapunto, digresión, eco, giro, ilustración, prueba, remate, respiro, tesis
TENSION4sube, mantiene, cae, rompe
ARCO6espiral, letanía, pregunta→respuesta, ruina, tesis→antítesis→síntesis, viaje y vuelta
TALLA7, con ordengeneral, conjunto, medio, americano, corto, primer, detalle
ALTURA, FRENTE, MODO5, 5, 3los demás ejes de un plano
PLANTILLA8documento, primerísimo, general, mapa, contraplano, orla, nocturno, cartel
VERBO_MOV24baja, cae, camina, corre, cruza, entra, esquiva, flota, gira…
VERBO_RELACIONAL11agarra, alcanza, arrastra, cuelga, empuja, esquiva, huye, orbita, se apoya, sigue, suelta
TRAYECTO, MANERA, GRANULADO16, 15, 4trayectos, maneras y granulados de un movimiento
EVENTO163eventos de todos los perfiles, cada uno con su estado (§6.3)
LEJANIA8, con ordenal pie, al paso, cerca, a media distancia, lejos, al fondo, en el horizonte, en el cielo
CLAVE_VIS68el catálogo de ver:
TAMBOR7ámbar, bermellón, naranja, rosa, ultramar, verde, violeta
PALABRA_RESERVADA76§6.4

Los vocabularios con orden (TALLA, LEJANIA, DISTANCIA, CADENCIA, INTENSIDAD, SOPORTE) llevan significado en su orden: la distancia entre dos tallas es su número de escalones, y una intensidad es un nivel de 0 a 10.

6.3 Estado: vivo y reservado

Todo evento, y todo nombre de sección, declara un estado:

  • vivo (alive): el compilador o el intérprete lo consume;
  • reservado (reserved): la lengua lo acepta y el intérprete todavía no hace nada. Es vocabulario congelado: escribirlo hoy no rompe mañana. Un compilador DEBE aceptarlo y DEBERÍA avisar (W110).

En esta versión todos los eventos están vivos. Están reservadas las secciones MONTAJE y CASCADA y los registros de letrero máquina, dymo y tira (REGISTRO_LETRERO_RESERVADO).

6.4 Palabras reservadas

PALABRA_RESERVADA enumera las palabras que abren una línea en el analizador, más artículos y preposiciones. NO DEBEN ser el nombre de un hablante ni un identificador (E021), y se comparan sin normalizar (§4.5): él no es el.

6.5 Plantillas y tallas son dos ejes

Una talla (TALLA) dice cuánto del encuadre ocupa el sujeto. Una plantilla (PLANTILLA) dice dónde caen las piezas en la hoja. Comparten una palabra, general, y primerísimo no es primer. Consecuencias:

  1. PLANO_DE hace corresponder funciones con plantillas, no con tallas:

    FunciónPlantilla
    aperturaorla
    remate, giroprimerísimo
    respirogeneral
    ilustración, contrapuntocontraplano
    digresiónmapa
    tesis, prueba, ecodocumento
    cartelcartel
  2. El aviso de salto de talla (W102) solo se evalúa entre dos planos consecutivos que declaran talla los dos.

  3. plano fijo toma una plantilla.

6.6 Tipos de pieza y sustratos

TIPO-PIEZA (lo que acepta pon:: cartulina, dymo, mano, python, rescate, sello, texto, tira, y apunte) es un papel dramatúrgico; SUSTRATO (14: papel, tira, cartulina, postit, vegetal, acetato, foto, periódico, pijama, milimetrado, kraft, dymo, ficha, polaroid) es una propiedad física (color de base, opacidad, sombra, foley al posarse). Todo tipo se resuelve en un sustrato (rescate, texto y mano en papel, sello en cartulina, y los homónimos en sí mismos); a los sustratos que no son tipos se llega desde el taller (materia NAME) o desde el bestiario, no desde pon:.

7. Semántica

7.1 Unidades y estratos

PLIEGO
 └─ CHAPTER      unit of page and of rendering (rendered in parallel)
     └─ SCENE    unit of world (the world persists between shots)
         └─ CLIP unit of time: a beat, a shot
             └─ LINE  unit of action

(El capítulo es la unidad de página y de render, y se renderiza en paralelo; la escena, la unidad de mundo, que persiste entre planos; el clip, la unidad de tiempo: un beat, un plano; la línea, la unidad de acción.)

Como los capítulos PUEDEN renderizarse en procesos separados, la continuidad entre ellos son datos serializados (estado_entrada, §10.4), nunca objetos vivos.

EstratoViveEspacioBanda de zLo compone el resolutor
FONDOpor secuenciaespacio de mesade −60 a −30no
MUNDOhasta el mutis o el telónsuelo, marcas, ligadurasde −20 a 0no (relacional)
DOCUMENTOpor frasezonas y slots, con reservade 1 a 100sí
PROSCENIOmientras cruzaespacio de mesade 101 a 200no
ANOTACIÓNcon su objetivoel objetivo9000 en adelanteno

El proscenio (lo que está entre la cámara y la escena) va por encima del documento, porque si no cualquier cartulina se dibujaría sobre él y la oclusión no ocluiría, y por debajo de la anotación, porque un subtítulo no está en la habitación: está sobre la película. La pertenencia se infiere del tipo de pieza y se corrige con una palabra (en el mundo:, en el documento:).

7.2 Las cinco leyes

  1. La constitución anti-parámetro (§3).
  2. El cierre (§11.1).
  3. La identidad es la semilla (§7.4).
  4. Lo que no cabe en la hoja no se lee.
  5. La lejanía manda sobre la velocidad, el color y la profundidad de cada estrato (§7.7).

7.3 Precedencia

Toda decisión del motor tiene una dimensión y una lista ordenada de autoridades; gana la primera autoridad que tiene un valor. Todo decisor devuelve un valor y su razón, o nada; la razón es obligatoria por firma. Las autoridades son un vocabulario cerrado (AUTORIDAD, 34 palabras).

DimensiónOrden de autoridad (gana la de la izquierda)
sitiomano, ligadura, cuerpo, slot, compositor, semilla
zestrato, proscenio, llegada
tamañodeclarado, mano, identidad, papel, legibilidad
tiempopartitura, ventana, tope, gesto
fondoorden de la mano, escena, capítulo, carácter
velocidad de estratolejanía, orden del mundo
color de estratolejanía, archivo, paleta
curvamanera, materia, mano, afecto
sombraluz (la dice la escena, nunca la pieza)
nombreexacto, alias, texto exacto, texto difuso

Dos candidatos que empatan en el mismo nivel de la dimensión name (nombre) son una ambigüedad y un error (E020). La presencia de un campo en el IR es la señal de autoridad (§10.5): una herramienta de explicación (mesa por-que) lee exactamente eso, de modo que su explicación no puede apartarse del render.

7.4 Identidad, semilla y determinismo

La identidad es la ruta declarada (id portada/fabula) o la ruta derivada (chapter/scene/text, es decir, capítulo/escena/texto). Se calcula a partir del contenido, nunca de la posición; un índice #n solo desempata piezas literalmente idénticas, y localmente.

Semilla:

seed(piece) = H(identity) ⊕ H(take)

donde H es la función de semilla del canon (FNV-1a de 32 bits sobre UTF-8, §16.3) y take es el número de interpretación (--toma N). La identidad gobierna lo que debe verse siempre igual; la toma gobierna la materia: --toma 3 da otra interpretación de la misma película (mismos planos, misma duración, distinta materia).

Semillas prohibidas: ninguna semilla puede depender del orden de render o de creación, de las direcciones de los objetos, del proceso, del reloj ni del sistema de archivos.

El hash maestro se calcula sobre el pliego desnudado y canonicalizado: espacios normalizados, comentarios y digresiones fuera, secciones resueltas, marcas (máquina) retiradas. Volver a escribir un pliego (escribe) no cambia su semilla.

El contrato de determinismo. Dos ejecuciones producen la misma película cuando coinciden estas cinco entradas: (1) el pliego canonicalizado, (2) el número de toma, (3) la versión del motor, (4) el bestiario y las secciones importadas, (5) el sidecar de voz. El sidecar forma parte del contrato, no es un metadato: su hash y su metodo por beat son entradas. Una huella dorada (§13.4) es válida para un juego de esas cinco entradas en una máquina y una GPU; entre GPU distintas la huella se compara con tolerancia. Un pliego que se use como referencia dorada DEBE declarar tirada definitiva y fijar su toma.

7.5 El tiempo

Un beat, un reloj. Todo beat tiene una duración antes de renderizarse: la de la voz (di: y el diálogo, a través del sidecar, §14.3), la de > dura N, la de sus clips (un beat no se cierra mientras corre un clip, §5.6) o una sintética (el tiempo de lectura de su texto, §16.4). No hay régimen libre.

La partitura (al decir «w»:) es la primera autoridad del tiempo. Toda acción tiene una ventana; mientras: abre una pista paralela; hasta decir estira; el tope impide que una acción se coma el turno de la siguiente. Dos acciones sobre el mismo sujeto en la misma ventana son un error (E031). El movimiento persiste a través de un corte salvo con > congela.

7.6 El movimiento y el oficio

La curva de todo movimiento se deriva; el pliego nunca la declara. Los principios de Lasseter (1987) son el comportamiento por defecto de todo verbo de movimiento, con los números del canon (oficio, §16.4):

PrincipioQué hace el intérpreteQuién lo modula
entrada y salida lentasla curva derivada se suaviza en los dos extremos; nunca es linealla manera (de golpe conserva la brusquedad)
anticipaciónretrocede por su trayecto antes de salir, en proporción a la velocidadcon anticipación la fuerza; de golpe la quita
arcossin trayecto, decide el verbo (salta en arco, vuela en curva, cae cayendo); si no, un arco suave hacia arriba; nada sale de la hoja por el caminoun trayecto escrito prevalece; recto es recto
estirar y encogerse estira a lo largo de la marcha conservando su área; se aplasta al aterrizarla velocidad y la materia (lo rígido cede la mitad)
acción continuadase pasa y se asienta; se inclina contra la marchala masa, el rebote y el cimbreo
acción superpuestalas partes de un grupo salen escalonadas, como muelles amortiguados; nunca hay más de simultaneos_maximos moviéndose a la vez
tiempola duración sale de la distancia y la manera, nunca por debajo de fotogramas_minimosla manera
pausa vivalo que se ha movido respira (una deriva mínima sembrada): nunca un fotograma congelado> deja posar la alarga
exageracióntodo factor × exageracionel canon

A dos fotogramas: en dos anima lo dibujado a la mitad de la cadencia, con poses sostenidas; es un sufijo de un movimiento o una propiedad del pliego entero. El vídeo real, el hervor y los actualizadores siguen a un fotograma.

El movimiento secundario (arrastre, rebote, cimbreo) es una propiedad de la materia y nunca se declara en el pliego. Apoyo: una pieza soltada cae hasta su apoyo; solo flota si su materia lo permite (si no, E033).

7.7 La lejanía manda, y su única excepción

De la lejanía (LEJANIA), y de nada más, se derivan la velocidad, el color y la z de una capa. La excepción, declarada: MUNDO acelera a N y MUNDO frena a N son una orden explícita de la mano al reloj del mundo; la dimensión velocidad de estrato tiene una segunda autoridad, orden del mundo, por debajo de la lejanía. La ley sigue valiendo entre capas (una capa no puede ir despacio y estar delante); la orden cambia el reloj común, que las multiplica a todas por igual. MUNDO para fija el reloj a cero.

7.8 La materia

Nada es un relleno plano. Toda pieza pertenece a un registro (REGISTRO_MATERIA): recorte (contorno de tijera, grano, sombra dura, canto), pintado (gouache o rotulador: pasadas con ductus y un borde desbordado), fotográfico (revelado y troquelado), tinta (una línea dibujada a mano, que hierve). El hervor: tres poses del mismo camino, misma geometría, distinto temblor, periodos sembrados por la identidad; las poses DEBEN ser isomorfas. El hervor cambia la forma, nunca el sitio.

7.9 Cámara, continuidad, luz y foco

Del eje se derivan el lado de cada quien, su vista y su lado de entrada. El volteo solo se aplica a las piezas declaradas espejables. Las tres leyes de cámara: el desplazamiento es un dato, no una caja envolvente; el corte no viaja; una escena con mundo propio es un lugar nuevo. Cuando la mano declara toca la truca: sí, la truca hereda su pulso (anticipación, un temblor de periodo primo, sobrepaso, y pierde al sujeto medio segundo).

Una luz por escena, y todas las sombras la obedecen; la hora la tiñe. Está prohibido ajustar la sombra de una sola pieza. El foco no es desenfoque: lo que está fuera de foco es más pálido, con un borde más blando y algo más grande. El texto nunca se desenfoca, salvo que se rompa una regla con permiso (§8.5).

7.10 Avisos de continuidad

Ninguno es fatal: romperlos es legítimo, pero hay que decirlo. AVISO_CONTINUIDAD:

AvisoCuándoLo silencia
W101 salto de ejese cruza la línea sin un plano neutro> cruza el eje, > rompe el eje porque «…»
W102 salto de tallala misma talla y el mismo ángulo sobre el mismo sujeto, o más de dos escalones, entre planos que declaran talla los dos> salta
W103 raccord de miradaen un contraplano los dos miran al mismo lado
W104 direcciónsale por un lado y entra por el mismo
W105 estadouna pieza cambia sin una acción que lo explique

8. Perfiles

Un perfil es un conjunto de capacidades que un intérprete realiza. Todo intérprete DEBE aceptar todo IR válido; ante una capacidad ajena a sus perfiles DEBE comportarse como si la línea no estuviera, NO DEBE fallar y DEBERÍA avisar al autor una vez por capacidad. Un intérprete declara los perfiles que realiza; los casos huella y banda de la batería se agrupan por perfil.

PerfilAlcance (gramática en el apéndice B)Referencia
núcleo (core)§5 y §7: la mesa, el collage, las piezas, el movimiento con el oficio, el cine y la continuidad, el viaje, el teatro de papel, el mapa, y las líneas de aspecto de §8.1ce (en parte: no el aspecto) y gx
sonido (sound)§8.2: voz, efectos, la partitura del sonido, cues de música, ambientes, salas, paneo y mástergx
cartel (poster)§8.3: todo plano es un cartelgx
oído (hearing)§8.4: la imagen que escucha, luz, soporte, intensidadgx
cámara (camera)§8.5: la cámara como objeto, profundidad, tiempo por capas, el cuadro como objeto, romper con permisogx

La RFC 0002 propone separar las líneas de aspecto en un perfil propio.

8.1 Aspecto (parte del perfil núcleo)

Líneas de unidad (preámbulo, capítulo o escena; prevalece la escena) y eventos, todo vocabulario cerrado y sin números; los números son cosa del intérprete:

  • MATERIA papel PAPEL | acuarela | risografía A y B [y C] · registration · screen | pincel | tejido [drum] | tinta | ninguna [sobre papel PAPEL]: de qué está hecho el cuadro, una pasada sobre el fotograma terminado en la convención de la parte 6. Las mismas palabras como prefijo dan la materia de una pieza (en acuarela: python: gamba). Una fotografía no tiene capas: su materia se hornea una vez sobre la imagen original, no sobre su trama. Eventos: > se moja, > se seca, > se lava, > florece [drum] [en «X»], > se teje, > la tinta lo cubre todo [drum].
  • BOBINA truca | sin grano | noticiario: la película (el noticiario a 18 fotogramas por segundo, sepia, rayas, parpadeo y vaivén).
  • FORMATO 4:3 | 16:9 | 2,39:1 [· de televisión] [· bandas de papel] y > formato X: bandas de tinta con bordes rasgados; el cambio se anima. En un pliego que cambia de formato, todo formato es un visor con esquinas redondeadas y papel alrededor, y la pasada del visor va la última.
  • ESPEJO [side], PANTALLA PARTIDA [· con un espejo en medio] [· que se miran] [· desigual] [· inclinada], SIMULTÁNEO en rejilla | en abanico | en abanico que gira, con sus eventos (> se rompe el espejo, > se parte la pantalla, > un solo plano…).
  • Transiciones (TRANSICION): transiciones de dos planos en las que el plano entrante está vivo y el saliente es una lámina fija de su último fotograma; corta, corta en la acción, sintoniza, a la vez, se sostiene, retención larga.
  • RÍO TIPOGRÁFICO [· en fila | en libertad | a pantalla completa | no]: la voz escrita palabra a palabra en el instante en que se dice; las mayúsculas y > revienta «…» crecen, estampan y desbordan. La frase partida (A / B: —…) y el letrero volador (de «A» a «B»: pon: …).
  • MONTAJE se acelera · al ritmo de las palabras · al pulso · cada vez más cerca · la cámara no para · mezcla «A» · «B»: cortes dentro del beat.
  • Rastros de movimiento (con estela, con líneas de fuerza, en cronofotografía), metamorfosis (X se funde en Y, X hierve con Y, el pelo pasa de X a Y), > se rasga el papel y asoma «SCENE», > asoma «SCENE» en el hueco, REPITE «SCENE», personajes con ficha (parte 3) y HERVOR dibujado | suave | no.

La cadena de cada instante es: materia, lo que asoma, espejo y pantalla partida, simultaneidad, cámara, formato, noticiario, transición, sintonía y el baño (papel y película). Una pasada solo cambia cuando algo cambia; sus animaciones son funciones del tiempo de la escena.

8.2 Sonido

El perfil sonido abarca la voz y la banda entera. Todo ejemplo, pieza de galería y pliego de conformidad de este estándar lleva música y diseño sonoro.

Preámbulo: EFECTOS folder (efectos y ambientes, por nombre de fichero), BANDA folder (cues de música), MEZCLA para la web | para cine · con stems | sin stems, y en REPARTO la voz, su color (con radio: la banda del altavoz, un toque de saturación y el soplido de la emisora; o seca) y su lado. Líneas de unidad: MÚSICA cue | ninguna, AMBIENTE a · b (capas), ESPACIO estadio | patio | estudio | radio | seco (la sala de los efectos), CAMA, JINGLE. Líneas de clip: sonido: effect [side] (anclable: al decir «X»: sonido: pitido). Eventos: > entra la música «cue», > la música se corta, > la música se apaga, > silencio de verdad, > las voces se juntan en el centro, > cada voz a su lado, > la voz se vuelve radio.

Un intérprete del perfil sonido DEBE:

  1. resolver los nombres sin distinguir mayúsculas y con la normalización de §4.5: sonido: y AMBIENTE en EFECTOS y después en BANDA; MÚSICA en BANDA. (Un nombre que no está en ninguna es un error que da el compilador: E040, E041, E042; un intérprete NO DEBE rodar ese pliego como si el sonido fuera silencio.)
  2. mezclar en estéreo a través de cuatro buses: voces, música, efectos y ambientes;
  3. mantener sonando una cue de música mientras escenas consecutivas nombran la misma cue (no vuelve a empezar), encadenar con un fundido cruzado al cambiar de cue, dejar que una cue más corta que su tramo termine por sí sola y fundir al final de su tramo una más larga;
  4. repetir en bucle los ambientes con un fundido cruzado en cada vuelta, mientras duren;
  5. bajar la música bajo la voz más que los ambientes: la voz siempre se entiende;
  6. con > silencio de verdad, cortar la música, los ambientes y lo que estuviera sonando hasta el siguiente beat, sin tono de sala; un efecto que empieza en ese mismo instante suena entero;
  7. colocar cada voz en su lado, moverlas con los eventos de paneo y aplicar la sala de ESPACIO a los efectos (la voz ya lleva su color en la toma);
  8. masterizar a −14 LUFS integrados para la web y −24 LUFS para cine, con picos verdaderos por debajo de −1 dBTP (un limitador con sobremuestreo de al menos cuatro veces) y, con stems, escribir los cuatro buses con la ganancia del máster y sin el limitador;
  9. no llamar nunca a un servicio de pago mientras renderiza: las voces llegan grabadas en el sidecar (§14.3).

La referencia escribe el máster como WAV de 24 bits junto al vídeo (<out>.master.wav), los stems en <out>.stems/ y un informe en <out>.banda.json con la sonoridad medida, el pico verdadero, las cues y los recuentos; los casos banda de la batería leen ese informe.

8.3 Cartel: todo plano es un cartel

PALETA A, B y C (campo, figura, acento, más el papel; COLOR_CARTEL) y CARTEL composition · … (COMPOSICION) componen la página como un cartel; dentro de un clip se aplican a ese plano. Los letreros son piezas: LETRA «WORD» · en TYPE · arrangement · place · size · de COLOUR, «X» es un PAPEL-SIGNO [a «SCENE»], una letra que es una figura o se convierte en una, [las letras de] «X» VERB (cada letra con su montura y el oficio), la raya corta «X», «X» forma FORM, ESCALA A como B, BOSQUE de …, en silueta:. El borde puede cortar las piezas (CORTE) y estas pueden crecer gigante. La salvaguarda: un corte nunca quita lo esencial de una pieza (la cara y la boca de quien habla, la mano que actúa, el objeto que importa: las partes esenciales de la parte 3); el texto que debe leerse se lee; · sin leer da permiso. El texto se teje: TEJE, SINTONIZA, se interrumpe en, sigue, FRASES, y los eventos con estado del tejido. PARTITURA path deja que la tipografía del texto fuente proponga lo que un clip no dice (cursivas, rayas, mayúsculas); lo que el clip declara prevalece.

8.4 Oído: la imagen que escucha

El intérprete oye el audio real (la voz de cada beat, ambientes, música, efectos) como curvas a 100 muestras por segundo: intensidad (absoluta y relativa), tono (en octavas), ataque, centroide espectral y 32 bandas logarítmicas. Pistas (PISTA): la voz, la música, la cama, los efectos, la radio, o un sonido con nombre. Líneas: la cámara respira con PISTA, el río mide la voz, la luz sube con PISTA, el dial es la línea de tiempo, X es el espectrograma de PISTA. Luz: LUZ de «piece» · desde abajo · drum (una sola fuente dura, sujeta a su pieza), LUZ de los focos · en contraluz, LUZ plana, COLOR monocromo [drum] | pleno, > estalla el color. Soporte (la degradación como dramaturgia): SOPORTE limpio | usado | gastado | sucio | roto, > el soporte empeora | se deshace | se limpia; el soporte dura toda la película. La intensidad como parámetro de dirección: INTENSIDAD WORD | de WORD a WORD [· extraña] [· con PISTA], con once palabras de nula (0) a rota (10), que gobiernan a la vez el temblor, la inclinación, el fuera de registro, el grano y el ritmo de MONTAJE al pulso.

8.5 Cámara: la cámara como objeto

Líneas de unidad: CÁMARA lens · weight · hand · depth, HORIZONTE recto | se inclina | gira, CADENCIA target cadence · … (cada capa dibuja a su propia cadencia), GOLPES con impacto | con borrón, PISTA ÓPTICA [side]; los prefijos de lejanía (lejos: python: fachada) ponen una pieza a esa distancia de una cámara de perspectiva real, y el paralaje nunca se declara: sale de la perspectiva cuando la cámara se mueve. El cielo está en el infinito. Los eventos (EVENTO_CAMARA) incluyen panorámicas con masa, travelín, grúa, objetivos con la focal y la distancia separadas, el plano de vértigo, una curva de tensión continua para la cámara en mano, el horizonte que se inclina, la snorricam, la órbita, el tiempo bala, atravesar piezas, el plano secuencia, los cortes en el eje, el cuadro como objeto (bandas de papel, perforaciones, un cuadro descarrilado) y X mira a cámara.

Romper con permiso. Un plano puede romper una regla a sabiendas, con su razón: > rompe el eje porque «…», > se sale del cuadro porque «…», > sin leer porque «…», > demasiado rápido porque «…», > todo a la vez porque «…», > sin respiro porque «…», y los encuadres incómodos con nombre (ENCUADRE_INCOMODO). Una regla rota sin su razón es un error (E060); un compilador lo explica y la revisión de Lasseter lo enumera aparte.

9. Extensión por capas

La lengua no se extiende nunca en silencio. Crece por capas, de dentro afuera:

  1. La lengua: vocabulario cerrado, que solo cambia por RFC y en una época nueva (§22).
  2. Las secciones #TALLER y #MANO: calibran el oficio de un proyecto o de una escena (papel, tinta, cantos, anclas, sombra, materias con masa y arrastre, el baño, la retícula; el pulso de la mano, su precisión, su grano, su entrada y su salida, su cansancio, y si toca la truca). Aquí los números son legítimos; la ley del espejo (§5.3) se cumple.
  3. El bestiario (PYTHON, PIEZAS): piezas con nombre con sus parámetros, partes, poses, acciones y ciclos (parte 3), llamadas desde el pliego por su nombre (python: radio, LOCUTOR señala). Un bestiario añade piezas, nunca gramática; sus acciones son el vocabulario cerrado de esa pieza.
  4. El intérprete: pasadas en la convención de la parte 6, materias, foley. Un intérprete PUEDE añadir pasadas y apariencias bajo palabras existentes; NO DEBE añadir palabras.

La capa de la casa. Un pliego que solo dice (un REPARTO y líneas di:) ya es una película: en una unidad en la que ningún beat pone nada propio, un intérprete DEBERÍA poner en el papel la frase de cada beat con la pieza que piden la función y el afecto (una pregunta a mano, un grito en nota de rescate, una cita recortada de un periódico, lo demás a máquina). La capa se apaga sola, unidad a unidad, en cuanto un beat enseña algo propio; página vacía en la línea de propiedades la apaga en todo el pliego. Es lo que permite a una persona o a un modelo pequeño escribir un primer pliego sin ningún dibujo.

~ deriva: text registra un encargo al motor en el IR sin cambiar la película. Lo que un pliego no puede decir: easing, fotogramas clave, funciones de ritmo ni duraciones sueltas en el dialecto pobre; colores en hexadecimal o RGB; sombra, velocidad de estrato o z por pieza; piezas sin nombre; dos sitios para la misma decisión.

10. La representación intermedia

10.1 Qué es

compile(pliego) devuelve (script, report, extra): el IR (guion rico), una lista de frases legibles sobre la dirección, y las decisiones por beat (función, afecto, plantilla, tensión, autor), los motivos, el reparto y el arco. El IR es JSON, se regenera siempre y nunca se versiona dentro de los proyectos; es el contrato del que comen un intérprete y un narrador (mesa cuenta). Si el narrador no sabe contar una capacidad nueva, la capacidad está mal integrada.

Los nombres de campo son identificadores españoles sin tildes. Los intérpretes DEBEN ignorar los campos desconocidos (compatibilidad hacia delante, §22).

10.2 Nivel de guion

Obligatorios (un compilador conforme los emite siempre):

CampoTipoSignificado
escenacadenanombre de la escena que se renderiza
capituloenteroíndice de página (empieza en 0)
salacadenacrema o pizarra
beatsarraylos clips compilados (§10.3)
tallerobjetoel taller efectivo, con toda la precedencia aplicada
manoobjetola mano efectiva
unidadesarraylos capítulos (§10.4); OBLIGATORIO cuando el pliego tiene capítulos

Opcionales (ausentes o null cuando el pliego no los declara): registro (el afecto dominante), subtitulos, gigantes, personajes, reparto, claves_cap, tambor_cap, tramos_cap, archivo, archivo_cap, archivo_tintas, fantasma, python_ruta, python_rutas, replica, efectos, banda, mezcla, bano, en_dos, pagina, aspectos y colofon ({lineas, tirada, semilla, toma, pobre}: contado, no declarado).

El nivel de guion lleva además marionetas (las marionetas de foto declaradas con MARIONETA: nombre, foto, mira, canto), y el aspecto de cada unidad y de cada beat lleva partitura_modo (si la voz se compone como partitura tipográfica, §8.3; null cuando el pliego no dice nada). Los dos son parte del IR de referencia; ninguno entra en la proyección normativa.

10.3 Nivel de beat

Obligatorios: id (el ordinal del clip, b07, o su id de beat declarado), cap (índice del capítulo), plano (la plantilla resuelta), afecto (el afecto resuelto), acciones (§10.5) e identidad (la ruta estable de §7.4, fuente de las semillas; véase el apéndice D).

Opcionales, y lo que distingue a las parejas: di (la locución del beat), dura (duración declarada cuando no hay voz), sec, corte (hay un corte antes de este beat, lo haya decidido quien sea) y corte_mano (lo pidió la mano), plano_mano (la plantilla se declaró, no se derivó), limpia, queda, canta, nocturno, congela, luz (la luz efectiva, ya resuelta con la hora), escena, escena_titulo, abre_escena, lugar_nuevo, linea (la línea de origen), aspecto (el aspecto efectivo de §8.1 a §8.5, un objeto por beat), transicion, montaje, rio, voces, frase_partida, revienta, rotos (reglas rotas con permiso) y el resto de los campos de los perfiles. El patrón X / X_mano es sistemático: X es el valor y X_mano dice si lo puso una persona.

10.4 Nivel de unidad

Cada elemento de unidades: n, titulo, beats (ids), escenas (títulos) y estado_entrada (OBLIGATORIO): {velocidad_mundo, sentido, hora}, el estado con que se abre el capítulo. Existe porque el movimiento persiste a través de los cortes y los capítulos se renderizan en procesos distintos: la única manera de que el capítulo 3 sepa a qué velocidad iba el mundo es que el compilador lo escriba, recorriendo todo lo anterior, de forma determinista.

10.5 Nivel de acción

verbo es OBLIGATORIO. La presencia de un campo es la señal de autoridad: en (sitio declarado por la mano: autoridad mano), liga (ligadura), cuerpo (cuerpo), al_decir (partitura), run (gesto), y los trayecto, manera y granulado del movimiento; spec y sobre llevan el cuerpo de un ver: y el objetivo de una marca. Los verbos que emite el compilador de referencia figuran en su IR; un intérprete DEBE ignorar un verbo que no conoce y DEBERÍA avisar al autor.

10.6 Forma canónica y proyección normativa

La forma canónica de un IR es su serialización JCS (§1.3); su resumen es el SHA-256 de esa serialización, en hexadecimal en minúsculas (no confundir con la huella de una película, §13.4).

La proyección normativa de un IR conserva solo los campos obligatorios de §10.2 a §10.5 (niveles de guion, beat, unidad y acción). Dos compiladores conformes DEBEN producir IR con proyecciones normativas iguales para todo pliego de la batería. A la implementación de referencia se le exige además su IR completo, congelado en conformance/expected/ir/: todo cambio es o una regresión o el objeto de una RFC.

11. Invariantes

11.1 Cierre

canon(compile(p)) == canon(compile(escribe(p)))

donde escribe materializa en el pliego todas las decisiones del motor (dialecto revelado, §3.1) y canon(ir) elimina la procedencia y la posición, y nada más: los campos origen, autor_cabecera, _importado, linea y colofon. Todo lo que decide un fotograma DEBE coincidir; quién lo decidió, y en qué línea, no tiene por qué.

11.2 El espejo

Para las secciones de §5.3, effective(p) == effective(parte(p)) == effective(funde(parte(p))), donde parte lleva cada bloque a su propio fichero y lo importa, funde incorpora en línea cada importación, y effective es el taller y la mano tras la precedencia, comparados línea a línea tras la normalización.

11.3 Compatibilidad

Un pliego que compiló una vez compila siempre (§22).

12. Diagnósticos

Un compilador comprueba un pliego (mesa lee en la referencia) e informa de errores y avisos, cada uno con un código estable (apéndice C, spec/diagnosticos.json) y un mensaje libre, que DEBERÍA enseñar: decir qué se esperaba y ofrecer las palabras válidas más cercanas. Un pliego con algún error es inválido; la orden de comprobación de un compilador DEBE terminar con un estado distinto de cero para un pliego inválido y DEBERÍA terminar con cero en caso contrario. La batería compara conjuntos de códigos, nunca mensajes ni orden.

Los errores cubren las palabras fuera de un vocabulario cerrado (de E010 a E019), los nombres (de E020 a E022), la estructura (de E030 a E033), los recursos de sonido (de E040 a E042), el bestiario (E050, E051), las reglas rotas sin razón (E060) y las líneas mal formadas (E090). Los avisos cubren la continuidad (de W101 a W105), las palabras reservadas en uso (W110, W111), la salud del pliego (de W112 a W118), lo que necesita el sidecar de voz (de W120 a W123) y la revisión de Lasseter (W130).

Los avisos que necesitan el sidecar solo se emiten cuando existe <pliego>.tiempos.json: el ancla muerta, las dos voces (un clip que suena dentro de un beat narrado sin > espera al clip), el ancla ilegible y el beat que crece.

La revisión de Lasseter se mide sobre la línea de tiempo real de un render (o de un render en seco que interpola los mismos fotogramas sin rasterizar), nunca sobre el pliego: movimiento de menos de fotogramas_minimos fotogramas a 24 fps, más de simultaneos_maximos piezas que siguen en escena moviéndose en el mismo fotograma, falta de pausa_fin_beat al final de un beat, texto en pantalla durante menos de words / palabras_por_minuto · 60 + asiento_lectura segundos (palabras entre palabras por minuto, por 60, más el asiento de lectura), beats gemelos, movimiento lineal, movimiento rápido sin anticipación. Cada aviso lleva su beat, su línea, su instante, una sugerencia y una gravedad.

Los diagnósticos que necesitan el bestiario se calculan leyendo el bestiario sin ejecutarlo (en la referencia, con el ast de Python): un nombre de python: que no existe (E050), una pose que no se declaró (E051), una pose escrita sin normalizar, un grupo que compone una pieza no creada en ese beat.

12.1 Diagnósticos que enseñan

El criterio de usabilidad de la lengua es que una persona, o un modelo de lenguaje mucho más pequeño que el que la diseñó, escriba un pliego limpio en pocos intentos sin leer código. Los diagnósticos son la herramienta principal para ello, así que un compilador conforme:

  • DEBE dar la línea de todo diagnóstico que la tenga;
  • DEBERÍA dar, tras el mensaje, el porqué (la regla que se aplica), el arreglo (con «¿quisiste decir…?» construido por distancia de escritura, prefijo y una tabla de sinónimos: lento → despacio, de frente → frontal) y un ejemplo de la línea correcta;
  • DEBERÍA ofrecer una explicación de cualquier palabra o línea (en la referencia, mesa explica «X»: qué es, dónde va y un ejemplo; para una línea entera, lo que entiende el parser) y una chuleta de una página de la lengua (mesa chuleta);
  • DEBERÍA listar las piezas que ve un pliego, con su tipo, su descripción y las acciones que declara cada una, y la línea exacta para pedirlas (mesa bestiario pliego.mesa).

12.2 Ningún fallo silencioso

Lo que parece una orden y no lo es es un error, nunca prosa. Una línea que el intérprete escribiría en el papel sin querer (un diálogo de quien no está en el REPARTO, una línea de escena escrita dentro de un clip, una orden o un verbo que no existen) es E023; una línea de prosa que se escribirá a máquina a propósito es el aviso W125. Un compilador DEBE informar además, leyendo el pliego y el bestiario sin ejecutar nada:

CódigoLo que, si no, fallaría en silencio
E018un modificador desconocido tras · en foto:, recorte: o clip:, o un campo desconocido de MARIONETA
E024NOMBRE acción para una pieza que no está en el REPARTO (con la pieza como alias) ni es una MARIONETA: la acción no le llegaría nunca
E025al decir «X» cuando la voz escrita de ese beat no dice X (sin el sidecar; con él, W120)
E052un dibujo mal invocado: argumentos tras ·, paréntesis como en un lenguaje de programación, o argumentos que la firma de la pieza no admite
E053el bestiario declarado con PYTHON o PIEZAS no existe junto al pliego
E054una acción que la pieza no declara entre sus acciones, poses o ciclos (§15.2)
W124una página vacía: un beat abre cuadro nuevo (una talla declarada, un capítulo o una escena nuevos) y no pone nada mientras suena la voz; no se emite en un respiro, que vacía la página a propósito

El color de una entrada del REPARTO es vocabulario cerrado (los tambores del canon y las tintas de la paleta del cartel); otra palabra es un error (E019).

13. Herramientas y huellas

13.1 La orden (informativo)

La referencia trae una orden, mesa (python -m manim_saorin.formato.cli). Sus subórdenes no son normativas, pero los adaptadores de conformidad las usan: lee (comprobar), ir (volcar el IR), cuenta (contar el pliego en prosa), escribe (revelar), indice (censo de nombres y ambigüedades), por-que (cada decisión con su autoridad y su línea), mueve, taller, parte, funde, graba (sintetizar la voz y escribir el sidecar), animatica, toca (renderizar; --motor gx sobre el motor de Tórculo), suena (la banda sin renderizar), lasseter, intensidad, dura, empaqueta, desempaqueta, comprueba (parte 2), pieza y bestiario (parte 3), y las herramientas que enseñan de §12.1: explica, chuleta y nuevo (mesa nuevo "Título" [--desde texto.md] escribe un proyecto con una plantilla comentada capa a capa, un bestiario mínimo y sus carpetas, o un primer pliego sacado de un texto).

13.2 Lo que un compilador DEBE ofrecer

Un compilador conforme DEBE ofrecer, por cualquier interfaz: la comprobación de un pliego con los códigos del apéndice C, el volcado de su IR como JSON, y la revelación de un pliego (escribe) y la partición y fusión de sus secciones (parte, funde), de modo que pueda probarse §11.

13.3 Lo que un intérprete DEBE ofrecer

Un intérprete conforme DEBE renderizar un pliego con su sidecar a un vídeo con sonido, y DEBERÍA ofrecer una ejecución en seco que produzca la línea de tiempo que lee la revisión de Lasseter.

13.4 La huella de una película

La huella (fingerprint) de un vídeo es una secuencia de miniaturas en gris de 96 × 54 píxeles, una por segundo, escaladas promediando por área (ffmpeg -vf fps=1,scale=96:54:flags=area -pix_fmt gray), guardadas en base64 en JSON con el MD5 de cada miniatura cuantizada a 4 bits. Dos huellas casan cuando tienen el mismo número de muestras (±1) y la diferencia absoluta media por píxel de cada pareja de muestras es como mucho 10 (sobre una escala de 0 a 255). En la misma máquina y con el mismo motor, la referencia casa con diferencia 0. Las métricas mienten: una huella dice dónde están las cosas, no si viven; no se cambia ninguna huella dorada sin mirar antes una tira de la película.


Parte 2. El proyecto portable

14. El proyecto portable

14.1 Qué es un proyecto

Un proyecto es el pliego, su bestiario y su sonido (la voz con su sidecar, los efectos, la música) más todo lo que el pliego lee (la PARTITURA, las secciones importadas, los clips de vídeo real, las fotografías, el cerrojo de las láminas elegidas). Un empaquetador DEBE descubrir esos ficheros leyendo el pliego y el bestiario, y NO DEBE ejecutar código del proyecto para hacerlo (la referencia lee el bestiario con el ast de Python).

Un proyecto es portable cuando toda ruta que usa es relativa a la carpeta del pliego y queda dentro de ella, y todo fichero que necesita está dentro de ella o figura en el manifiesto como dependencia de la instalación.

14.2 El paquete

Un .mesapack es un archivo ZIP (PKWARE APPNOTE; se admite ZIP64). El audio, el vídeo y las imágenes DEBERÍAN guardarse sin recomprimir (método 0). Contiene el árbol del proyecto, con el pliego en la raíz, y un fichero MANIFIESTO.json en la raíz:

MiembroTipoObligatorioSignificado
formatocadenasí"mesapack 1"; un lector DEBE rechazar otra versión mayor (P003)
pliegocadenasíla ruta del pliego dentro del paquete; DEBE terminar en .mesa y existir (P008)
titulocadenanoel título del pliego
creadocadenanoISO 8601
porcadenanola herramienta que lo empaquetó
versionesobjetosílengua (la época, OBLIGATORIO), motor (nombre, versión, commit, rama), torculo (commits del estándar y del motor), o null donde se desconozca
vocesobjetonoel reparto con voz, color y lado, y cuántas tomas de cada método hay (§14.3)
fuentesobjetonopor fuente tipográfica: dónde está (motor, sistema, usuario) y, para las fuentes del usuario, su ruta en el paquete (_fuentes/…)
externosarraynolo que el bestiario lee de la instalación y no viaja: {ruta, por, donde}
no_portablearraynolo que no pudo hacerse portable: {donde, ruta, arreglo}
archivo_fotosarraynolas fotografías de archivo que van en _archivo/
archivosobjetosípor ruta: {sha256, bytes, por}; por dice por qué está el fichero en el paquete

Un lector:

  1. DEBE rechazar las entradas con una ruta absoluta, un segmento .., una barra invertida o una letra de unidad (P004), y NO DEBE escribir fuera de la carpeta de destino;
  2. DEBE verificar el SHA-256 y el tamaño de cada fichero declarado (P005) y DEBERÍA rechazar los ficheros no declarados (P006);
  3. DEBE comprobar que las grabaciones del sidecar son rutas relativas dentro del paquete (P007);
  4. DEBERÍA, tras desempaquetar, comprobar el proyecto como lo haría un empaquetador y avisar cuando las versiones de la lengua, del motor o del estándar difieran de las del manifiesto.

El validador de referencia es conformance/tools/mesapack.py; el empaquetador de referencia es mesa empaqueta (con desempaqueta y comprueba).

14.3 El sidecar de voz

<pliego without extension>.tiempos.json (el nombre del pliego sin extensión) está junto al pliego. Es la quinta entrada del contrato de determinismo (§7.4).

{
  "beats": {
    "b01": {"dur": 2.57, "pause": 0.4, "hash": "cf79cc76fda2", "metodo": "silabas",
            "palabras": [{"w": "Un", "t": 0.05, "d": 0.214}, {"w": "tórculo", "t": 0.264, "d": 0.482}]}
  },
  "wavs": {"b01": "audio/voz/b01.wav"}
}
  • beats hace corresponder un id de beat con su locución: dur (segundos), pause (segundos tras ella), hash (del texto que se dijo, de modo que un texto cambiado invalida la toma), metodo (cómo se obtuvieron los tiempos: whisper, silabas, elevenlabs, declarado, cancion, hueco u otro nombre) y palabras, cada palabra w con su inicio t y su duración d en segundos desde el comienzo del beat. Un beat PUEDE llevar t_abs (un tiempo absoluto, para las canciones).
  • wavs hace corresponder un id de beat con su grabación: una ruta, una lista de rutas (tomas encadenadas, como en una frase partida entre dos hablantes) o una lista de objetos {ruta, desde} (tomas que suenan a la vez, cada una desde su instante).
  • Las rutas DEBERÍAN ser relativas a la carpeta del sidecar (la del pliego) y, en un paquete, DEBEN serlo. Los lectores DEBEN aceptar rutas relativas y absolutas, y resolver las relativas respecto de la carpeta del sidecar. Un sidecar cuyas rutas absolutas apuntan a una ubicación antigua de un proyecto que se ha movido PUEDE reanclarse cuando el mismo fichero (mismo sufijo de ruta y mismo tamaño) existe en la ubicación nueva.
  • Un pliego cuyas voces se grabaron fuera del motor (por ejemplo, en un servicio de casting) las lleva en el sidecar; el render NO DEBE llamar a un servicio de voz.

14.4 Diagnósticos

P001 no es un ZIP, P002 no hay un MANIFIESTO.json legible, P003 formato desconocido, P004 ruta peligrosa, P005 fichero que falta o hash incorrecto, P006 fichero no declarado, P007 una grabación del sidecar fuera del paquete o absoluta, P008 falta el pliego, P009 falta un miembro obligatorio.


Parte 3. Piezas

15. Piezas

Esta parte normaliza lo que entra en un pliego por PYTHON/PIEZAS, python:, MARIONETA, foto: y clip:. Sigue SPEC-PIEZAS.md v1 de manim-saorín (rama piezas, 2026-10-15); la vinculación con Python que allí se describe es la vinculación de referencia, y otro motor PUEDE ofrecer el mismo contrato en otro lenguaje.

15.1 Niveles

NivelQué esEl pliego puede además
0, dibujoun dibujo a pluma, una fotografía, un recorteponerlo, moverlo, filmarlo, cortarlo por el borde
1, partesmás partes con nombre y con pivoteel pelo pasa de A a B; proteger lo esencial al cortar
2, marionetamás articulación (madres y pivotes), poses, acciones y ciclosX saluda, X corre hasta…; la boca sigue a la voz si hay mandíbula
3, personajemás cinco vistas, expresiones, visemas, manos, ciclos de andar y correr, mundos de colorX de espaldas; la vista sigue al plano; al decir «…»: X se asombra

Cada nivel es un superconjunto del anterior.

15.2 El contrato de una pieza

Una pieza es un constructor (en la vinculación de referencia, una función de Python que devuelve un mobject de ManimGX) con:

  • sus propios argumentos, por posición o por nombre (lo que el pliego escribe tras python: name), y los extras con valores por defecto: alto (altura en unidades de escena; la pantalla mide 8 de alto), hervor (0, 1 o 2 fija una pose de hervor; sin él, la mesa lo hace hervir), mundo (§15.5), espejo, id;
  • su ficha (§15.3);
  • su hervor: tres poses con la misma estructura y otro pulso;
  • su apoyo: la altura donde descansa (sus pies), de modo que se sostiene por los pies, no por el centro.

Desde el nivel 1, una pieza expone partes (de nombre a subobjeto) y un pivote por parte. Desde el nivel 2: la firma de ficha vista, pose, expresion, boca, mano_i, mano_d, hervor; POSES (nombres), ACCIONES (de acción a una lista de poses, que se ejecutan a dos fotogramas) y CICLOS (de ciclo a una lista de poses que se repite; corre y anda los ponen en marcha los verbos de movimiento); un pivote y una madre para cada parte articulada; una parte llamada mandibula se abre con los visemas. Las acciones de una marioneta son su vocabulario cerrado: X saluda es válido si saluda está entre sus acciones o sus poses; si no, el intérprete avisa con la lista que tiene.

Un personaje de nivel 3 tiene vistas (frente, tres cuartos, perfil, tres cuartos de espalda, espalda), expresiones, bocas (reposo, a, e, i, o, u, m, f, l, gol), manos (abierta, puño, señalando, aplaudiendo, pinza, o con un objeto en la mano), poses comunes y los ciclos corre (8 dibujos), anda (8) y habla (6), y partes anidadas con pivotes (tronco, cuello, cabeza con sus rasgos, pelo, bufanda, brazos, antebrazos, manos, muslos, piernas, pies).

15.3 La ficha

ClaveQuéObligatoria
niveldibujo, partes, marioneta o personajesí
nombreASCII sin espacios: es la semilla y lo que escribe el pliegosí
titulocon tildes, para las hojasno
descripcionlo que se ve, para quien no puede verlo; la usan la capa de sentido y el listado del bestiariosí, de 20 caracteres o más
altoaltura natural en la escenarecomendada
miraderecha, izquierda o frente: para el espejo y el ejerecomendada
tintaslos colores que usarecomendada
registrodibujo, foto, recorte, clip, tipografia, materia o escaneono
parteslas partes que tienedesde el nivel 1
esencialesde esencial a partedesde el nivel 1

15.4 Partes esenciales

Lo que la lengua protege al cortar por el borde (§8.3): cara, boca, cabeza, mano (la que actúa) y objeto (lo que importa). Un personaje declara las cuatro primeras; una marioneta, al menos cabeza u objeto; un dibujo, objeto. Ninguna parte esencial puede salirse del contorno de su pieza. Sin declaraciones, el centro de la pieza es lo esencial.

15.5 Mundos de color

mundo=: natural, tinta, sepia, noche, hielo, silueta o silueta:#RRGGBB, riso:DRUM+DRUM (dos tambores del canon), y los mundos que registre un proyecto. Un mundo recolorea todas las tintas de un dibujo y lleva los grises de una fotografía a sus dos tintas.

15.6 En el pliego, y las comprobaciones

PIEZAS path (un módulo, un fichero declarativo de un personaje, una marioneta o un recorte, o una carpeta entera) amplía PYTHON. MARIONETA name · de la foto path [· mira a la izquierda | derecha] [· canto …] declara una marioneta de foto. python: name [args] pone cualquier pieza; los argumentos con nombre fijan la pose y la vista iniciales de una ficha. WHO action ejecuta una acción que la pieza declara. Collage en movimiento: foto: path · sin fondo · canto de tijera | de troquel | rasgado | limpio · sombra pegada | levantada | sin sombra · con cinta | celo | chincheta, y clip: path de a a b · sin fondo (una película recortada, a dos fotogramas por defecto).

Un proveedor de piezas DEBE ofrecer una comprobación que llame a cada pieza como lo hará el intérprete y verifique: que dibuja; que hierve (tres poses, misma estructura, distinto pulso); que tiene sus partes y sus esenciales, ninguno fuera del contorno; que toda parte articulada tiene un pivote dentro de la pieza; que toda acción y todo ciclo usan poses que existen; y, para un personaje, las cinco vistas, los visemas y los ciclos. La referencia es mesa pieza comprueba.

15.7 Marionetas de foto

Una marioneta de foto es una pieza de nivel 2 hecha de una fotografía sin código: MARIONETA nombre · de la foto ruta … en el preámbulo o una ficha nombre.marioneta.toml. El proveedor encuentra las articulaciones y la cara de la persona, corta la foto una vez con el canto declarado y la parte por las articulaciones (cabeza, tronco, brazos, antebrazos, muslos, piernas; las piernas solo si se ven enteras), cada parte con su pivote y solapada con su madre; lo que queda bajo el labio es la mandibula, que se abre con la voz. Sin persona ni cara, la foto es una sola pieza que tiembla. Toda marioneta de foto sabe, además de lo que declare su ficha: saluda, celebra, señala, baila, se inclina, duda, grita, aplaude, en jarras, y los ciclos anda y corre. Una acción cuyas partes no tiene la foto (un brazo que no se encontró) DEBERÍA avisarla la comprobación de la pieza.

Una ficha de personaje con palabras (nombre.personaje.toml) declara un personaje de nivel 3 con palabras cerradas en vez de código: cuerpo (altura, complexión, edad), cabeza (cráneo, nariz, gafas, ojos), pelo (estilo, color), ropa (arriba, abajo, calzado y sus colores), el objeto que sostiene y sus poses propias ([poses.recuerda] brazo_i = "a la boca"). Las palabras son vocabulario cerrado del proveedor; una palabra desconocida es un error de la comprobación de la pieza.

15.8 El collage en movimiento

Fotos, recortes, vídeo real, letra, pluma y materias comparten un mismo plano.

  • foto: ruta [· modificadores] pega una foto; con · sin fondo la figura se recorta (el proveedor quita el fondo), y el canto (canto de tijera | de troquel | rasgado | limpio), la sombra (sombra pegada | levantada | sin sombra) y la sujeción (con cinta | con celo | con chincheta) se declaran con palabras. recorte: es una foto ya sin fondo. La materia de una pieza sigue valiendo (en risografía rosa: foto: …).
  • clip: ruta [de a a b] · sin fondo es una película recortada: cada fotograma se recorta y se vuelve a cortar a tijera, así que el canto hierve solo; va en dos (12 dibujos por segundo) salvo que se diga en uno / a 24 o en cuatro, y es un actor sin marco ni celo.
  • clip de fondo: ruta [de a a b] llena el cuadro a la cadencia del cine. Un clip de fondo dura su tramo: cuando acaba, se va al abrir el beat siguiente aunque el plano siga; nunca se queda congelado encima de lo que viene.
  • CADENCIA (§8.5) fija la cadencia de cada capa (las figuras en dos · el fondo en uno), de modo que la mezcla de cadencias del collage (el vídeo real a 24, los recortes en dos, la pluma hirviendo a 8) sale sola.
  • Los decorados de la casa. FONDO y DELANTE montan piezas del bestiario como decorado de una escena; un intérprete del perfil núcleo DEBE ofrecer además, sin ningún bestiario, los decorados de la casa: cielo, sierra, agua, arcada, celosia, ciudad, farola, lluvia, arboleda, cuarto, luna. Una pieza del bestiario con el mismo nombre lo sustituye. Un decorado que no es ni lo uno ni lo otro es un error.

Quién actúa. Una acción se pide con un nombre del REPARTO cuyo alias es el nombre de la pieza, también para una pieza que no habla (REPARTO TIJERAS: minio, alias: tijeras, y luego al decir «corta»: TIJERAS corta); un alias igual a su propio nombre del REPARTO no es una ambigüedad. La pieza tiene que estar en la mesa en ese beat o antes.


Parte 4. El canon

16. El canon

16.1 Fuente y ficheros generados

canon/canon.toml es la única fuente de verdad. Todas las demás formas las genera canon/genera.py: Python (canon.py), TypeScript (canon.ts), Rust (canon.rs), WGSL (canon.wgsl) y CSS (canon.css). Los ficheros generados NO DEBEN editarse a mano; genera.py --check falla si alguno está desfasado. El fichero declara version = 1.

16.2 Paleta

Los colores son sRGB, escritos #RRGGBB. En WGSL y Rust son esos mismos valores sRGB como flotantes, component / 255 redondeados a seis decimales (sin pasarlos a luz lineal); en CSS, propiedades personalizadas --group-name (grupo y nombre).

GrupoColores
papel (papel)base #F5F0E8, hundido #EDE6D6, hoja #FAF7F0, filete #D4C4B0, filete_hondo #C4AE96, noche #1A0F0A
tinta (tinta)base #2C1810, segunda #5C3D2E, apagada #7A5F4E, lapiz #9A8E80, negro #1A120D, sobre_noche #FAF7F0
escritorio (escritorio)rojo #C1453B (minio), azul #2B4C7E (azurita), amarillo #E8A838, oro #D6A03A
tambores (tambores de risografía)ultramar #2B3BC7, bermellon #D93325, naranja #E8501A, ambar #F2C744, verde #00A95C, rosa #FF48B0, violeta #765BA7, humo #1A1A1A

Los tambores son para el contenido, nunca para el cromo de la interfaz. El vocabulario TAMBOR del pliego nombra siete (todos menos humo); la materia de risografía (TAMBOR_RISO) acepta también humo, tinta y azurita. La obra nueva DEBE usar este papel y esta tinta; los cremas antiguos #F2EEE4 y #F6F0E2 son legado.

16.3 Azar

Todo el azar de Tórculo es determinista y se deriva de tres funciones, que toda implementación DEBE calcular bit a bit:

semilla(text):   FNV-1a, 32 bits, over the UTF-8 bytes of text
                 h = 0x811C9DC5; for each byte b: h = (h XOR b) * 0x01000193 mod 2^32
serie(s):        Mulberry32 seeded with s; each call:
                 a = (a + 0x6D2B79F5) mod 2^32; t = a
                 t = (t XOR (t >> 15)) * (t OR 1)               mod 2^32
                 t = t XOR ((t + ((t XOR (t >> 7)) * (t OR 61))) mod 2^32)
                 return (t XOR (t >> 14)) / 2^32                  in [0, 1)
hash32(n):       x = (n * 0x9E3779B9 mod 2^32) XOR 0x85EBCA6B
                 x = x XOR (x >> 13); x = x * 0xC2B2AE35 mod 2^32; x = x XOR (x >> 16)
                 return (x AND 0xFFFFFF) / 2^24                   in [0, 1)

serie devuelve dobles que son múltiplos exactos de 2^−32; hash32 devuelve valores que son exactos en un flotante de 32 bits. Nada puede usar el reloj del sistema, Math.random ni un generador sin semilla. Las semillas se calculan sobre UTF-8; un antiguo auxiliar de Scholaris en TypeScript sembraba sobre unidades de código UTF-16, lo que solo coincide en ASCII: esa es una de las razones por las que los identificadores DEBERÍAN ser ASCII.

Los vectores de prueba son normativos: conformance/canon/vectores.json da, para un conjunto de textos (vacío, ASCII, con tildes, ñ, CJK y un carácter fuera del BMP), la semilla, los ocho primeros valores de la serie como enteros antes de la división, y el hash32 de la semilla y de cinco enteros fijos. Una implementación del canon en cualquier lenguaje DEBE reproducirlos.

16.4 Oficio y foley

oficio (el oficio, Lasseter en números; ningún pliego los escribe, el motor los aplica): palabras_por_minuto = 220 y asiento_lectura = 1.0 s (tiempo de lectura de un texto), fotogramas_minimos = 8 (a 24 fps, nada se mueve durante menos), simultaneos_maximos = 3, pausa_fin_beat = 0.6 s, anticipacion = 0.2 (fracción de la acción), exageracion = 1.25, hervor_fps = 8, hervor_poses = 3, dibujo_en = 2 (lo dibujado, a dos fotogramas). Un canon de una versión posterior PUEDE añadir claves; las implementaciones DEBEN ignorar las claves que no conocen.

foley: el peso relativo de cada evento de foley (el oído no oye una tecla como un sello): rotulador 0.55, tecla 0.75, hilo 0.8, papel-deslizar 1.0, papel-posar 1.0, carton-posar 1.1, celo 1.15, despegar 1.15, tijera 1.3, chincheta 1.25, sello 1.35, punzon 1.2, papel-rasgar 1.3, pagina 1.4, campanilla 1.1, pincel 0.6, lavado 0.7.


Parte 5. Láminas

17. Láminas

Una lámina es un dibujo a mano listo para que cualquier motor (web, app, juego, vídeo) lo haga aparecer bajo la pluma sin volver a calcular la mano: la imagen se rasteriza una vez y, a su lado, un atlas de tiempo dice en qué instante llega la pluma a cada píxel.

17.1 Dos envoltorios, el mismo contenido

  • Directorio name.lamina/ con los ficheros de §17.2.

  • Empaquetada, un único fichero name.lamina:

    BytesContenido
    de 0 a 7la firma LAMINA\0\x01 (4C 41 4D 49 4E 41 00 01)
    de 8 a 11n, la longitud del índice, u32 little-endian
    de 12 a 12+nel índice, JSON en UTF-8: {"archivos": [{"ruta", "inicio", "largo"}, …]}
    desde 12+nlos ficheros uno tras otro; inicio cuenta desde aquí

Las rutas del índice son las rutas del directorio. Un lector distingue los dos casos por la firma.

17.2 Ficheros

manifiesto.json                 what there is and how it is composed (always first)
geometria.json                  the vector geometry of every pose (optional)
vista.png                       the finished drawing on paper, pose 0 (preview)
capas/<layer>-<pose>.png        colour atlas of a layer in a pose
capas/<layer>-<pose>-tiempo.png time atlas of that layer in that pose

(manifiesto.json: lo que hay y cómo se compone, siempre el primero; geometria.json: la geometría vectorial de cada pose, opcional; vista.png: el dibujo terminado sobre papel, pose 0, como vista previa; capas/<layer>-<pose>.png: el atlas de color de una capa en una pose; capas/<layer>-<pose>-tiempo.png: el atlas de tiempo de esa capa en esa pose.)

Todas las imágenes de una lámina tienen el mismo tamaño: tamano.ancho × tamano.alto píxeles, la caja del dibujo por su escala (2 por defecto).

Atlas de color: PNG RGBA de 8 bits con alfa premultiplicado (el PNG declara alfa directo; un lector DEBE cargarlo sin tocar los valores: en WebGL, createImageBitmap(blob, {premultiplyAlpha: 'none', colorSpaceConversion: 'none'}) y UNPACK_PREMULTIPLY_ALPHA_WEBGL = false). Sin papel: lo que no tiene tinta es transparente.

Atlas de tiempo: PNG RGB de 8 bits. En cada píxel, R·256 + G es el instante normalizado a 16 bits, t = (R·256 + G) / 65535, con 0 el comienzo y 1 la duracion de la lámina; B vale 255 donde la capa tiene tinta y 0 en el resto (y entonces R y G no significan nada). DEBE muestrearse sin filtrado (vecino más próximo o texelFetch). Donde se cruzan dos piezas de la misma capa, gana el instante más temprano.

PiezaInstante de un píxel
tinta y color (pluma)el del punto más cercano de su línea central; a lo largo de la línea, inicio + duracion · B⁻¹(arc/length), con B la Bézier cúbica (0.55, 0.1, 0.45, 0.95)
lápizlo mismo, lineal: inicio + duracion · arc/length
planoun pincel en diagonal: inicio + 0.7 s · f, con f la posición a lo largo de la diagonal de su caja
notaescrita de izquierda a derecha, línea tras línea, en 0.9 s

17.3 Capas

En este orden, solo las que tienen algo: lapiz (normal), planos (multiplicar), tinta (normal), color (multiplicar, con el desplazamiento de fuera de registro), encima (multiplicar, con el desplazamiento), notas (normal; no hierve: todas sus poses apuntan a la misma imagen).

17.4 Hervor

hervor.variantes poses (3 por defecto). La pose 0 es el dibujo de siempre; las demás tienen la misma geometría y el mismo ritmo y solo cambian el temblor. En reproducción, pose = floor(seconds_at_rest · fps + offset) mod variantes (los segundos en reposo por los fps, más el desfase), con fps = 8 y el desfase escrito en el manifiesto (hash32(semilla(id)) · variantes). Mientras la pluma dibuja, se muestra la pose 0; el hervor empieza cuando el dibujo está entero (al_reposar: true).

17.5 El revelado

Para cada capa, de abajo arriba, con progress de 0 a 1:

float t = (R * 255.0 * 256.0 + G * 255.0) / 65535.0;
float reveal = B > 0.5 ? clamp((progress * 1.03 - t) * 60.0, 0.0, 1.0) : 1.0;
vec4 c = color * reveal;                        // premultiplied
dst = blend == "multiplicar" ? dst * (1.0 - c.a) + dst * c.rgb
                             : c.rgb + dst * (1.0 - c.a);

dst empieza siendo el papel. El adelanto de 1.03 garantiza que con progress = 1 todo está dibujado; la pendiente 60 da un frente de tinta de 1/60 de la duración. Los dos números están en el manifiesto (revelado).

17.6 El manifiesto

manifiesto.json tiene: formato ("lamina"), version (1), id (el id y la semilla del dibujo, en ASCII), titulo y descripcion (para los lectores de pantalla, en la lengua de la lámina), lengua, tamano (ancho, alto, escala, caja), duracion, papel, alfa ("premultiplicada"), revelado (formula, adelanto 1.03, pendiente 60), hervor (variantes, fps, desfase, semilla, al_reposar), capas (por capa: nombre, mezcla, desplazamiento, hierve, y las rutas de color y tiempo por pose), trazos (el orden de la mano: indice, capa, elemento, pasada, modo (lineal, pluma, pincel, escritura), inicio, duracion, t0, t1), trayectoria (dos herramientas, lapiz y pluma, cada una una lista de [ms, x, y, down] en unidades de dibujo, con milisegundos que nunca decrecen), geometria (ruta o null), vista y canon (version, semilla, serie).

geometria.json da, por pose y por trazo en el orden de la mano: tipo (cinta, linea, relleno, nota), su capa y sus índices, cómo se pinta, inicio, duracion, modo, la línea central temblada puntos, el arco acumulado, la anchura ancho por punto, la llegada llegada por punto, el contorno y, para las notas, su texto, posición, tamaño, rotación y ancla. Los números se redondean a milésimas.

17.7 Garantías

  • Determinismo. La misma lámina sale idéntica byte a byte en Rust nativo, en Python y en WebAssembly: el azar es el del canon y nada lee el reloj. La batería da el SHA-256 de tres láminas empaquetadas (casos lamina); un productor DEBE reproducirlos.
  • Fidelidad. La pose 0 es el mismo dibujo que el SVG del motor de dibujo a mano (diferencia media inferior a medio nivel de gris, por el antialiasing).
  • Ids en ASCII (§4.5).

17.8 Memoria

Cada capa en cada pose son dos texturas de width × height × 4 bytes (ancho por alto por 4). Los lectores DEBERÍAN permitir a los productores bajar la escala o las variantes en los dibujos grandes.

17.9 Diagnósticos

L001 firma incorrecta, L002 índice incorrecto, L003 falta un fichero de la lista, L004 manifiesto incorrecto o incompleto, L005 una imagen de tamaño equivocado, L006 un PNG de tipo equivocado, L007 un atlas de tiempo cuyo canal azul no es 0 ni 255, L008 capas desordenadas o con la mezcla o el número de poses equivocados, L009 trazos, L010 trayectoria, L011 parámetros de hervor o de revelado. El validador de referencia es conformance/tools/lamina.py.


Parte 6. Materias

18. Materias: la convención de pasadas

18.1 Qué es una materia

Una materia convierte un plano limpio en papel, acuarela, pintura, risografía, punto de tejido o una transición. Es una o varias pasadas de cómputo WGSL en una convención común, de modo que cualquier anfitrión (la cadena de posproceso del motor, una biblioteca, una herramienta) la ejecuta tal cual. La biblioteca de referencia es materias/ (Rust + WGSL) y el m.Pass del motor (§19.6).

18.2 Grupo 0: la convención

Toda pasada de una materia de plano enlaza exactamente:

EnlaceNombreTipo
@group(0) @binding(0)entradatexture_2d<f32>: la entrada, en luz lineal, premultiplicada, en flotantes de media precisión
@group(0) @binding(1)muestreosampler: bilineal, sujeto a los bordes
@group(0) @binding(2)planovar<uniform> Plano
@group(0) @binding(3)salidatexture_storage_2d<rgba16float, write>: la salida, en la misma forma
struct Plano {
    resolucion: vec2f,     // offset 0
    fotograma: u32,        // 8
    tiempo: f32,           // 12: scene time in seconds, never the system clock
    semilla: u32,          // 16
    paso: u32,             // 20: free for the materia (simulation step, pass number)
    _hueco0: u32,          // 24
    _hueco1: u32,          // 28
    params: array<vec4f, 4>, // 32: sixteen parameters
}                          // 96 bytes

(tiempo es el tiempo de la escena en segundos, nunca el reloj del sistema; paso queda libre para la materia, como paso de simulación o número de pasada; params son dieciséis parámetros; la estructura ocupa 96 bytes.)

Una materia DEBERÍA obtener el grupo 0 con #import plano en lugar de declararlo.

18.3 Grupos 1 y 2

Lo que es propio de una materia va en @group(1): las texturas que lee o escribe, los búferes. En el motor, el @group(1) de una pasada contiene solo sus imágenes (una plancha, el plano saliente de una transición), una textura muestreada por enlace desde el 0, en el orden dado. El estado persistente va en @group(2): en el enlace 0, el estado tal como está (una textura); en el enlace 1, el siguiente (una textura de almacenamiento rgba16float); antes de la pasada, su punto de entrada de paso se ejecuta un número fijo de veces por fotograma, cada una del estado al siguiente, intercambiándolos. Una materia NO DEBE enlazar otros grupos, y NO DEBE repetir un enlace.

18.4 Determinismo

El único tiempo que ve una pasada es el de la escena (plano.tiempo, plano.fotograma). Las materias con estado (la acuarela) avanzan en pasos fijos de 60 Hz: dos ejecuciones dan los mismos píxeles. Un fotograma sostenido también avanza; retroceder en el tiempo vuelve a empezar el estado desde cero. Una materia NO DEBE leer el reloj del sistema.

18.5 Módulos y cadenas

#import name pega un módulo una vez (un preprocesador de la biblioteca). Módulos compartidos: canon (paleta y hash32, generados a partir del canon), comun (sRGB y lineal, PCG, ruido de valor, fbm, ruido de gradiente entrelazado, sobre), plano (la convención), campos_papel (los once campos del papel y color_papel), espectral (transmitancia en 16 bandas y reconstrucción espectral).

Una cadena de materias se escribe materia(key=value, …) > materia > …; los valores son números, nombres que la materia entiende (tipo=khadi, tambor1=rosa) o colores #RRGGBB. Los puntos de entrada son puntos de entrada de cómputo con @workgroup_size; una pasada que escribe salida DEBERÍA tomar @builtin(global_invocation_id) y tratar un píxel por invocación.

18.6 Diagnósticos

M001 ni importa plano ni declara el grupo 0 de la convención, M002 el grupo 0 no es exactamente el de la convención, M003 Plano no es la estructura de la convención, M004 un punto de entrada que no es de cómputo o al que le falta @workgroup_size, M005 recursos propios fuera de los grupos 1 y 2, o un enlace repetido, M006 lee un reloj. El comprobador de referencia es conformance/tools/materias.py; la compilación y los fotogramas de referencia los prueban las pruebas propias de la biblioteca (cargo test --release en materias/).


Parte 7. Tomas y la API pública

19. Tomas y la API pública

19.1 El motor

El motor de referencia es un fork de ManimGX (Rust y wgpu, con la API de Python de Manim Community Edition), rama seams. Todo lo que el fork añade está desactivado por defecto: si no se usa nada de ello, el motor dibuja exactamente como el original (upstream), píxel a píxel en el corpus de referencia. Las tomas propias del fork tienen versiones propias (§19.3), que los lectores del original rechazan.

19.2 El flujo de la toma

Una toma registra una ejecución del motor como las llamadas del motor: formas, pinceles e imágenes subidas bajo sus claves, y luego fotogramas (una vista y sus registros, mostrados durante cierto número de fotogramas). Es un único flujo de mensajes, en little-endian:

message  = length:u32  opcode:u8  fields…        (length counts the opcode and the fields)
bytes    = length:u32  data…

(La longitud cuenta el código de operación y los campos.)

El primer mensaje DEBE ser START; una toma completa termina con END. Los lectores DEBEN rechazar una toma cuyo primer mensaje no sea START, cuya versión no conozcan, que contenga un código de operación desconocido, un mensaje más largo que lo que queda, un segundo START o cualquier cosa después de END.

CódigoMensajeCampos
14STARTversión u32, anchura u32, altura u32, cadencia f64
1PATHclave u64, centroide y área f32 × 6, claves de array (puntos, subtrayectos)
2POINTSclave u64, clave de array
3MESHclave u64, contorno u32, bloque u32, claves de array
4ROWSclave u64, clave de array (las filas de un pincel)
5TEXTUREclave u64, anchura u32, altura u32, clave de array (RGBA8)
6GROWclave u64, cerrado u8, clave de array
8FRAMErepetición u32, vista (bytes), clave de registros u64, número de cámaras u32 y, por cámara: clave u64, anchura u32, altura u32, vista (bytes), clave de registros u64
9NOTEbytes: JSON en UTF-8 (las jugadas, las secciones y los rótulos)
10SOUNDbytes: un fichero de audio que el reproductor reproduce junto a los fotogramas
11ARRAYclave u64, clave base u64 (0: ninguna), tipo u8, codificación u8, bytes (zstd)
12ENDfallida u8
13ENVIRONMENTid u32, anchura u32, altura u32, clave de array
15POSTbytes: la descripción de la cadena de posproceso (solo en 0x8000_0002, justo después de START)
16MATERIALid u32, bytes: código fuente WGSL (en 0x8000_0002; código 15 en 0x8000_0001)

Las subidas se retienen hasta que un fotograma las muestra; los arrays se envían una vez bajo una clave de su tipo y su contenido (un resumen opaco de 64 bits: los lectores DEBEN tratar las claves como opacas) y se codifican respecto del array al que sustituyen: ALONE (0), FIRST (diferencia respecto de la base), SECOND (diferencia respecto de la predicción lineal), TAIL (la base es su comienzo), carril a carril y comprimidos con zstd, con un fotograma clave cada 32 versiones. Los registros de un FRAME ocupan 424 bytes cada uno (ocho claves de 8 bytes, banderas, dos matrices de 3 × 4, pinturas, parámetros, trazo discontinuo, material, el id de la materia u32, la mezcla u32, un id de usuario u64 y dieciséis flotantes de usuario). El número de fotogramas de una toma es la suma de las repeticiones de los mensajes FRAME.

19.3 Versiones

VersiónRegistrosCódigos 15 y 16Lectores
0x8000_0001424 B15 = MATERIALDEBE leerse
0x8000_0002424 B15 = POST, 16 = MATERIALla escribe el motor de Tórculo 1.0

El rango de 0x8000_0000 en adelante es del fork; las versiones del original están por debajo. Un escritor de tomas de este estándar DEBE escribir 0x8000_0002. Una disposición o un código de operación nuevos toman la versión siguiente.

19.4 Diagnósticos

T001 el primer mensaje no es START, T002 versión desconocida, T003 un mensaje más largo que la toma, T004 código de operación desconocido, T005 START repetido o datos después de END, T006 POST no va justo después de START, T007 un NOTE o un MATERIAL que no es UTF-8 válido (JSON, en el caso de NOTE). El lector de referencia es conformance/tools/toma.py.

19.5 Determinismo del motor

Los sombreadores ven el tiempo de la escena (o el índice del fotograma), nunca el reloj. La misma escena, renderizada dos veces en la misma máquina y la misma GPU con el mismo motor, da los mismos bytes; entre GPU distintas no se garantiza, y por eso las huellas se comparan con tolerancia (§13.4). Las semillas de las materias, del fuera de registro y del hervor salen de la semilla del canon aplicada al nombre de una pieza (set_material(…, pieza="c1_09/rosa")), nunca de un contador.

19.6 La API pública

Estabilidad. Las interfaces de esta sección son públicas en Tórculo 1.0: solo cambian mediante una RFC. Todo lo demás del fork es interno.

Python (import manimgx as m; la API de Manim CE, véase la guía propia del motor):

InterfazQué
m.config.post = [m.Papel(), m.Bobina("truca")]la cadena de posproceso: pasadas sobre cada fotograma terminado; el grano vive en las pausas
m.Pass(shader, entry=None, reach=…, moves=…, params=(), paths=(), pictures=…, estado=None, pasos=…)cualquier pasada en la convención de la parte 6, con las imágenes en @group(1) y el estado persistente en @group(2)
m.Papel(plate=None, …), m.Bobina(reel="truca", lut_in=None, lut=None, papel=canon paper, …)el baño de imprenta y la película de la casa
m.config.compositing = "linear"componer en luz lineal (flotantes de media precisión); por defecto, sRGB
mobject.set_material(name, …, pieza=None), m.register_material(name, wgsl, params)materias por objeto (papel, acuarela, riso, y las registradas que definen fn materia(m: Materia) -> vec4<f32>)
`mobject.set_blend("normal""multiplicar")`
`mobject.set_clip("mascara""dentro"
m.Trazo(points, widths, tiempos=None, grano=None), m.Trazo.de_pluma(stroke)el trazo de pluma de anchura variable, que Create dibuja al ritmo de la mano
m.Hervor(drawing, poses=3, fps=8, desfase=True, gpu=False)la línea que vive en reposo
`m.sidecar(pliegotiempos.json

Línea de órdenes: manimgx render scene.py [--codec h264 | hevc | prores | prores4444] [--take] [-r WxH] [--fps N] [--sound-events]. HEVC Main10 y ProRes usan VideoToolbox (macOS); ProRes 4444 lleva alfa, sin premultiplicar. Los binarios que incluyen x264 (--codec h264) son GPL; las compilaciones solo con VideoToolbox no lo son (DECISIONES.md). Los errores estrictos son lo predeterminado: el LaTeX mal formado y los avisos de Typst fallan en la línea de la escena; --no-strict los convierte en avisos.

Rust: el crate manimgx-render (Replay::read(&bytes), replay.render(i) a RGBA, Gpu::from_device(…) para dibujar en el dispositivo de otra aplicación).

Web: <manimgx-film src="Scene.take" autoplay> reproduce una toma con WebGPU, sin Python; necesita mezcla en float32 y depth32float-stencil8 (Chrome y Edge 113 y posteriores, Safari 26).


20. Consideraciones de seguridad

  • Compilar NO DEBE ejecutar código del proyecto. Un compilador comprueba y compila un pliego y lee su bestiario sin ejecutarlo (§12). Un empaquetador descubre los ficheros de la misma manera (§14.1).
  • Renderizar ejecuta el bestiario. Un pliego con PYTHON o PIEZAS ejecuta ese código cuando se renderiza: un intérprete DEBE tratar un pliego así como un programa, y un visor de proyectos que no son de confianza NO DEBE renderizarlos fuera de un entorno aislado. Una servilleta o un pliego sin bestiario no ejecuta nada más que el motor.
  • Los paquetes pueden llevar rutas peligrosas (§14.2): los lectores DEBEN rechazarlas antes de escribir nada, verificar los hashes y acotar el tamaño total sin comprimir.
  • Las tomas llevan código fuente de sombreadores (MATERIAL, POST) que se ejecuta en la GPU. WebGPU y wgpu lo validan, pero una toma hostil aún puede agotar recursos: los reproductores DEBERÍAN acotar el número de materiales, el tamaño de los arrays y de las texturas, y el tamaño descomprimido de cada ARRAY, y DEBEN rechazar una toma que incumpla §19.2.
  • Las láminas están acotadas por su manifiesto; un lector DEBERÍA rechazar una lámina cuyos tamaños de imagen o número de capas superen su presupuesto de memoria (§17.8).
  • Sin red durante el render. Las voces, la música y los efectos vienen del proyecto; un intérprete NO DEBE llamar a un servicio de pago o remoto mientras renderiza.

21. Consideraciones de privacidad

  • Las grabaciones de voz son datos personales de quien habla. Un paquete las lleva; su manifiesto dice cuántas tomas de cada método tiene, nunca quién las grabó, salvo que lo declare el reparto.
  • Las rutas absolutas revelan nombres de usuario y estructuras de carpetas (/Users/name/Library/Caches/…). Los sidecars DEBERÍAN usar rutas relativas, y los paquetes DEBEN usarlas (§14.3).
  • El manifiesto registra los commits y las versiones de las herramientas, no la máquina.

22. Versiones y compatibilidad

  • La constitución de la compatibilidad: un pliego que compiló una vez compila siempre. La época se declara en el preámbulo (MESA v2); un compilador DEBE compilar todo pliego de toda época que declare soportar, y DEBERÍA leer la época 1 (SPEC-MESA.md) como legado. El vocabulario de una época está congelado, palabras reservadas incluidas.
  • Una época nueva PUEDE añadir palabras y líneas; NO DEBE cambiar el significado de un pliego válido de una época anterior. Retirar una palabra solo es posible declarándola legado en una época nueva, y los compiladores siguen aceptándola en los pliegos que declaran la antigua.
  • El IR no se versiona (§10.1): los intérpretes DEBEN ignorar los campos y los verbos desconocidos.
  • Las versiones mayores de mesapack son incompatibles entre sí (mesapack 2 sería otro formato); las menores (mesapack 1.1) solo añaden miembros que los lectores pueden ignorar.
  • La versión 1 de las láminas se escribe en la firma y en el manifiesto; una disposición nueva toma la versión 2.
  • Las versiones de las tomas figuran en §19.3.
  • La version del canon cambia cuando cambia cualquier valor; los ficheros generados la llevan.
  • La especificación se numera MAYOR.MENOR con publicaciones editoriales (spec-v1.0.0); su número y los de las bibliotecas son independientes (governance/VERSIONING.md).

23. Tipos de medio e identificación de ficheros

Propuestos, no registrados:

ExtensiónTipo de medioIdentificación
.mesatext/vnd.torculo.mesa; charset=utf-8texto UTF-8 cuya primera línea que no es comentario empieza por MESA (o prosa: una servilleta)
.mesapackapplication/vnd.torculo.mesapack+zipun ZIP con MANIFIESTO.json cuyo formato empieza por mesapack
.laminaapplication/vnd.torculo.laminala firma LAMINA\0\x01 (un directorio .lamina/ tiene manifiesto.json)
.takeapplication/vnd.torculo.takeprimer mensaje START (código 14) con una versión desde 0x8000_0001
.tiempos.jsonapplication/jsonjunto a un pliego con la misma raíz de nombre

24. Internacionalización

La lengua de Tórculo es el español: las palabras clave, los vocabularios y los diagnósticos son palabras españolas, y las tildes son significativas donde el español las hace significativas (§4.5, palabras reservadas). El texto en pantalla es lo que escriba el autor, en cualquier escritura, normalizado a NFC. Los compiladores DEBERÍAN escribir sus mensajes en español y PUEDEN ofrecer traducciones; los códigos no dependen de la lengua. Un juego de palabras clave localizado (por ejemplo, palabras clave inglesas que lleven al mismo IR) sería un dialecto nuevo y necesita una RFC; el IR, que es el contrato, no cambiaría.


Apéndice A. Vocabularios cerrados

Generado a partir de spec/vocabularios/vocabularios.json, que se extrae del analizador de referencia. Cada vocabulario da su perfil, la estructura de la que procede y sus palabras en forma canónica (sin tildes, §4.5); un compilador las acepta con tildes o sin ellas.

Perfil: núcleo

ACCION_FICHA (15 palabras; Fuente: formato.aspecto.ACCIONES)

anda · aplaude · baila · cae · celebra · corre · gesticula · gira el dial · grita · habla · recoge · salta · se levanta · senala · señala

AFECTO (8 palabras; Fuente: formato.vocabulario.AFECTOS)

contenido · euforico · exhausto · jugueton · nervioso · seco · sereno · solemne

ALTURA (5 palabras; Fuente: formato.continuidad.ALTURAS)

cenital · contrapicado · nadir · normal · picado

ANCLA (5 palabras; Fuente: formato.vocabulario.ANCLAS)

bordado · celo · chincheta · esquineras · washi

ARCO (6 palabras; Fuente: formato.vocabulario.ARCOS)

espiral · letania · pregunta→respuesta · ruina · tesis→antitesis→sintesis · viaje y vuelta

AUTORIDAD (34 palabras; Fuente: formato.precedencia.AUTORIDADES)

afecto · alias · archivo · capitulo · caracter · compositor · cuerpo · declarado · escena · estrato · exacto · gesto · identidad · legibilidad · lejania · ligadura · llegada · luz · manera · mano · mano_taller · materia · orden_mano · orden_mundo · paleta · papel · partitura · proscenio · semilla · slot · texto_difuso · texto_exacto · tope · ventana

AVISO_CONTINUIDAD (5 palabras; Fuente: formato.continuidad.AVISOS)

RACCORD DE DIRECCIÓN · RACCORD DE ESTADO · RACCORD DE MIRADA · SALTO DE EJE · SALTO DE TALLA

BOBINA (3 palabras; Fuente: formato.aspecto.BOBINAS)

noticiario · sin grano · truca

CLAVE_MANO (7 palabras; Fuente: formato.taller.MANO_BASE)

cansa · entra · granulado · precision · pulso · sale · toca la truca

CLAVE_VIS (68 palabras; Fuente: visualizaciones.CATALOGO)

alfiler · ancla · arbol · balanza · barras · brujula · bucle · cadena · caja · cancelacion · ciclo · comparacion · constelacion · convergencia · cuadrante · cuenta · curva · dado · diana · dispersion · distribucion · domino · ecuacion · ejes · embudo · engranaje · escalera · espectro · espiral · flecha de proceso · fraccion · globo · grieta · huella · interruptor · isla · jerarquia · laberinto · linea temporal · lista tachada · lupa · mapa · medidor · moneda · monton · multitud · onda · orbita · papeleta · pendulo · pila · ping pong · porcentaje · proceso · puente · recorrido · red · reloj · resta · semaforo · suma · telarana · teorema · termometro · titere · venn · versus · votos

DESREGISTRO (2 palabras; Fuente: formato.aspecto.DESREGISTROS)

desregistrada · en registro

DIMENSION (10 palabras; Fuente: formato.precedencia.DIMENSIONES)

color_estrato · curva · fondo · nombre · sitio · sombra · tamaño · tiempo · velocidad_estrato · z

DIRECCION_LUZ (5 palabras; Fuente: formato.vocabulario.DIRECCIONES_LUZ)

cenital · de atras · de frente · de la derecha · de la izquierda

DISPOSICION (8 palabras; Fuente: formato.vocabulario.DISPOSICIONES)

amontonados · como flores · en abanico · en columna · en corro · en fila · en fila holgados · en rejilla

DUREZA (2 palabras; Fuente: formato.vocabulario.DUREZAS)

blanda · dura

ESPEJO_LADO (2 palabras; Fuente: formato.aspecto.ESPEJO_LADOS)

de la derecha · de la izquierda

EVENTO (163 palabras; Fuente: formato.vocabulario.EVENTOS)

a la vez · aire al reves · amanece · anochece · arranca de golpe · asoma · barre · barrido · barrido a la derecha · barrido a la izquierda · barrido hacia abajo · barrido hacia arriba · barrido temporal · cada voz a su lado · camara lenta · camara lenta a saltos · capitulo · chasquido · congela · congela la imagen · continua · corta · corta en la accion · cortado por la barbilla · cortado por la frente · cortinilla de tijera · cruza el eje · cuadro vacio · deja posar · demasiado cerca de · demasiado rapido · desenfoque de pasada · destellan los focos · dura · el clip se agranda y se va · el color se apaga · el cuadro gira · el cuadro se endereza · el fotograma se descarrila · el horizonte se endereza · el horizonte se inclina · el montaje se acelera · el que habla fuera de campo · el rio mide · el soporte empeora · el soporte se deshace · el soporte se limpia · empapela · encadena · entra de golpe · entra la musica · espectrograma de · espera al clip · estalla el color · florece · formato · fotograma de impacto · fotograma en blanco · funde a blanco · funde a negro · funde desde blanco · funde desde negro · gigante · gran angular · iris · la camara atraviesa · la camara baja · la camara deja de respirar · la camara entra en · la camara gira alrededor de · la camara mira desde dentro de · la camara no para · la camara respira con · la camara sale de · la camara se acerca a · la camara se aleja · la camara sube · la camara va a · la camara va montada en · la camara va pegada a · la camara vuelve · la costura se mueve hacia · la intensidad cae a · la intensidad salta a · la intensidad sube a · la linea se endereza · la linea se inclina · la linea se mueve · la linea se rompe · la luz sube con · la mancha deja · la mano tapa · la musica se apaga · la musica se corta · la pista se desborda · la pista vuelve · la tela se desenreda · la tela se enreda · la tension cae · la tension rompe · la tension se mantiene · la tension sube · la tinta lo cubre todo · la voz se vuelve radio · las bandas bajan · las bandas suben · las voces se juntan en el centro · lente normal · mezcla los registros · mirando fuera de campo · montaje al pulso · montaje al ritmo de las palabras · ojo de pez · pasa pagina · pasa por delante · plano holandes · plano secuencia por · queda · rampa de velocidad · respira · retencion larga · revienta · rio tipografico · rompe el eje · salta · salto axial a · se desteje · se junta la pantalla · se lava · se moja · se para en seco · se parte la pantalla · se quema · se rasga el papel · se rasga la banda · se rompe el espejo · se sale del cuadro · se seca · se sostiene · se teje · se van las perforaciones · se ven las perforaciones · seco · silencio · silencio de verdad · simultaneo en abanico · simultaneo en abanico que gira · simultaneo en rejilla · sin leer · sin respiro · sintoniza · teleobjetivo · temblor · tiempo bala sobre · todo a la vez · todo se para menos · triple salto axial a · un solo plano · velocidad normal · vertigo · vertigo al reves · vuelve el espejo · zoom de golpe

Reservados: ninguno.

EVENTO_A_CAMPO (8 palabras; Fuente: formato.vocabulario.EVENTO_A_CAMPO)

Correspondencia: congela → congela_mano · continua → continua · cortado por la barbilla → salta · cortado por la frente → salta · cruza el eje → cruza_eje · demasiado cerca de → salta · rompe el eje → cruza_eje · salta → salta

EXPRESION (9 palabras; Fuente: formato.aspecto.EXPRESIONES)

duda · se asombra · se asusta · se calma · se enfada · se entristece · se pone serio · se rie · sonrie

FAMILIA_TALLER (10 palabras; Fuente: formato.taller.TALLER_BASE)

ancla · bano · canto · fantasma · materia · papel · reticula · sombra · tinta · vida

FORMATO (6 palabras; Fuente: formato.aspecto.FORMATOS)

16:9 · 1:1 · 2,39:1 · 4:3 · 4:5 · 9:16

FORMATO_MODO (2 palabras; Fuente: formato.aspecto.FORMATO_MODOS)

bandas de papel · de television

FRENTE (5 palabras; Fuente: formato.continuidad.FRENTES)

escorzo · espalda · frontal · perfil · tres cuartos

FUNCION (11 palabras; Fuente: formato.vocabulario.FUNCIONES)

apertura · cartel · contrapunto · digresion · eco · giro · ilustracion · prueba · remate · respiro · tesis

GESTO_MARCA (4 palabras; Fuente: formato.vocabulario.GESTO_MARCA)

rodea · senala · subraya · tacha

GRANULADO (4 palabras; Fuente: movimiento.GRANULADOS)

a doses · a pulso · a treses · a unos

HERVOR (3 palabras; Fuente: formato.aspecto.HERVORES)

dibujado · no · suave

HORA (5 palabras; Fuente: formato.vocabulario.HORAS)

amanece · atardece · diurna · mediodia · nocturna

LADO (4 palabras; Fuente: formato.vocabulario.LADOS)

abajo · arriba · derecha · izquierda

LEJANIA (8 palabras, con orden; Fuente: viaje.LEJANIAS)

al pie · al paso · cerca · a media distancia · lejos · al fondo · en el horizonte · en el cielo

LINEA_UNIDAD_ASPECTO (20 palabras; Fuente: formato.aspecto.UNIDAD)

AMBIENTE · BANDA · BOBINA · CAMA · EFECTOS · ESPACIO · ESPEJO · FORMATO · HERVOR · JINGLE · MATERIA · MEZCLA · MONTAJE · MÚSICA · PANTALLA PARTIDA · REPITE · RIO TIPOGRAFICO · RÍO TIPOGRÁFICO · SIMULTANEO · SIMULTÁNEO

MANERA (15 palabras; Fuente: movimiento.MANERAS)

a la deriva · a regañadientes · a tirones · con anticipación · con cuidado · de golpe · de un tirón · despacio · en volandas · ligero · pesado · resuelto · rozando · sin ganas · titubeante

MATERIA (7 palabras; Fuente: formato.aspecto.MATERIAS)

acuarela · ninguna · papel · pincel · risografia · tejido · tinta

MODO (3 palabras; Fuente: formato.continuidad.MODOS)

cartel · documento · mundo

MONTAJE (6 palabras; Fuente: formato.aspecto.MONTAJES)

al pulso · al ritmo de las palabras · cada vez mas cerca · la camara no para · mezcla · se acelera

MOVIMIENTO_MUNDO (4 palabras; Fuente: formato.vocabulario.MOVIMIENTO_MUNDO)

acelera · avanza · frena · para

NOMBRE_SECCION (6 palabras; Fuente: formato.taller.SECCIONES)

BESTIARIO · CASCADA · MANO · MONTAJE · REPARTO · TALLER

ORDEN_TRUCA (9 palabras; Fuente: formato.vocabulario.ORDEN_TRUCA)

baja · busca a · encuadra a · se acerca · se acerca a · se queda · sigue a · sube · viaja con

PALABRA_RESERVADA (76 palabras; Fuente: formato.vocabulario.PALABRAS_RESERVADAS)

a · al · alias · ancla · archivo · arco · arriba · bajo · bestiario · camino · canta · cascada · clip · con · contenido · de · del · delante · dentro · deriva · detras · di · eco · eje · el · en · escenario · fantasma · foco · fondo · formato · foto · fuera · hilo · junto · juntos · la · las · letra · letrero · los · luz · mano · marca · mesa · mientras · montaje · motivo · mundo · musica · nota · o · para · personaje · pica · pie · pon · por · prensada · python · que · recorte · relojes · reparto · revelado · se · sobre · sonido · su · sus · taller · terminal · un · una · ver · y

PAPEL (11 palabras; Fuente: formato.aspecto.PAPELES)

cuaderno · escolar · grano fino · khadi · kraft · lienzo · satinado · tintado · torchon · verjurado · washi

PARTE_CUERPO (7 palabras; Fuente: formato.vocabulario.PARTES_CUERPO)

el hombro · el pecho · el regazo · la cabeza · la espalda · las manos · los pies

PLANO_DE (11 palabras; Fuente: formato.vocabulario.PLANO_DE)

Correspondencia: apertura → orla · cartel → cartel · contrapunto → contraplano · digresion → mapa · eco → documento · giro → primerisimo · ilustracion → contraplano · prueba → documento · remate → primerisimo · respiro → general · tesis → documento

PLANTILLA (8 palabras; Fuente: formato.vocabulario.PLANTILLAS)

cartel · contraplano · documento · general · mapa · nocturno · orla · primerisimo

RASTRO (4 palabras; Fuente: formato.aspecto.RASTROS)

con borron · con estela · con lineas de fuerza · en cronofotografia

REGISTRO_LETRERO (6 palabras; Fuente: formato.vocabulario.REGISTROS_LETRERO)

cartulina · cita · cita maquina · cita moderna · mano · rescate

REGISTRO_LETRERO_RESERVADO (3 palabras; Fuente: formato.vocabulario.REGISTROS_LETRERO_RESERVADOS)

dymo · maquina · tira

REGISTRO_MATERIA (4 palabras; Fuente: materia.REGISTROS)

fotografico · pintado · recorte · tinta

REGISTRO_MOV (1 palabras; Fuente: movimiento.REGISTROS)

en dos

RIO_MODO (3 palabras; Fuente: formato.aspecto.RIO_MODOS)

a pantalla completa · en fila · en libertad

SENTIDO (2 palabras; Fuente: formato.vocabulario.SENTIDOS)

de espaldas · de frente

SIMULTANEO (3 palabras; Fuente: formato.aspecto.SIMULTANEOS)

en abanico · en abanico que gira · en rejilla

SUSTRATO (14 palabras; Fuente: pieza.SUSTRATOS)

acetato · cartulina · dymo · ficha · foto · kraft · milimetrado · papel · periodico · pijama · polaroid · postit · tira · vegetal

TALLA (7 palabras, con orden; Fuente: formato.continuidad.TALLAS)

general · conjunto · medio · americano · corto · primer · detalle

TAMBOR (7 palabras; Fuente: formato.vocabulario.TAMBORES_V)

ambar · bermellon · naranja · rosa · ultramar · verde · violeta

TAMBOR_RISO (10 palabras; Fuente: formato.aspecto.TAMBORES_RISO)

ambar · azurita · bermellon · humo · naranja · rosa · tinta · ultramar · verde · violeta

TENSION (4 palabras; Fuente: formato.vocabulario.TENSIONES)

cae · mantiene · rompe · sube

TRAMA (3 palabras; Fuente: formato.aspecto.TRAMAS)

de grano · de lineas · de puntos

TRANSICION (16 palabras; Fuente: formato.vocabulario.TRANSICIONES)

chasquido · corta · corta en la accion · cortinilla de tijera · desenfoque de pasada · encadena · entra de golpe · funde a blanco · funde a negro · funde desde blanco · funde desde negro · iris · la mano tapa · pasa pagina · se quema · sintoniza

TRAYECTO (16 palabras; Fuente: movimiento.TRAYECTOS)

a saltos · cayendo · en arco · en curva · en espiral · en zigzag · flotando · fuera de campo · girando · por el borde · por el camino · por el suelo · rebotando · recto · resbalando · rodando

VENTANA (2 palabras; Fuente: movimiento.VENTANAS)

hasta decir · mientras

VERBO_MOV (24 palabras; Fuente: movimiento.VERBOS)

baja · cae · camina · corre · cruza · entra · esquiva · flota · gira · rebota · resbala · rueda · sale · salta · se apea · se encaja · se levanta · se sienta · sube · tiembla · tropieza · va · viaja · vuela

VERBO_RELACIONAL (11 palabras; Fuente: movimiento.VERBOS_RELACIONALES)

agarra · alcanza · arrastra · cuelga · empuja · esquiva · huye · orbita · se apoya · sigue · suelta

VISTA (5 palabras; Fuente: formato.aspecto.VISTAS)

de espaldas · de frente · de perfil · de tres cuartos · de tres cuartos de espaldas

Perfil: sonido

ESPACIO (5 palabras; Fuente: formato.aspecto.ESPACIOS_SALA)

estadio · estudio · patio · radio · seco

MEZCLA (4 palabras; Fuente: formato.aspecto.MEZCLAS)

con stems · para cine · para la web · sin stems

VOZ (6 palabras; Fuente: formato.sonido.VOCES)

cita · cita_f · cita_f2 · cita_f3 · cita_m2 · narrador

Perfil: cartel

BOSQUE (5 palabras; Fuente: formato.cartel.BOSQUES)

brazos · brazos y punos · manos · manos abiertas · punos

COLOR_CARTEL (16 palabras; Fuente: formato.cartel.COLORES)

amarillo · arena · azul · blanco · celeste · crema · lila · minio · morado · naranja · negro · rojo · rosa · tinta · ultramar · verde

COMPOSICION (15 palabras; Fuente: formato.cartel.COMPOSICIONES)

campo a sangre · campo en bandas · campo partido en diagonal · centro vacio · columna a sangre a la derecha · columna a sangre a la izquierda · diagonal de abajo a la izquierda arriba a la derecha · diagonal de arriba a la izquierda abajo a la derecha · disco detras · en silueta · enorme · figura delante de la letra · la letra corta a la figura · la letra delante de la figura · tercios

CORTE (12 palabras; Fuente: formato.cartel.CORTES)

cortada por abajo · cortada por arriba · cortada por el borde · cortada por la derecha · cortada por la frente · cortada por la izquierda · cortado por abajo · cortado por arriba · cortado por el borde · cortado por la derecha · cortado por la frente · cortado por la izquierda

DISPOSICION_SIGNO (6 palabras; Fuente: formato.cartel.DISPOSICIONES)

a sangre · en abanico · en columna · en escalera · girada · rota por el borde

EVENTO_CARTEL (5 palabras; Fuente: formato.cartel.EVENTOS)

la costura se mueve hacia · la mancha deja · la tela se desenreda · la tela se enreda · se desteje

FORMA_PALABRA (5 palabras; Fuente: formato.cartel.FORMAS)

el patio · un marco · un muro · una columna · una porteria

LINEA_UNIDAD_CARTEL (3 palabras; Fuente: formato.cartel.UNIDAD)

CARTEL · PALETA · PARTITURA

PAPEL_SIGNO (9 palabras; Fuente: formato.cartel.ROLES)

barandilla · cielo · cuchilla · mascara · muro · persiana · porteria · suelo · ventana

SITIO_SIGNO (5 palabras; Fuente: formato.cartel.SITIOS)

a la derecha · a la izquierda · abajo · arriba · en el centro

TIPO_LETRA (6 palabras; Fuente: formato.cartel.TIPOS)

anton · la serifa de pretexto · league gothic · letra de mano · maquina de escribir · serifa

VERBO_SIGNO (14 palabras; Fuente: formato.cartel.VERBOS_SIGNO)

cae · caen · se abre · se abren · se apila · se apilan · se estampa · se estampan · se rompe · se rompen · se separa · se separan · se va · se van

Perfil: oído

DIRECCION_FUENTE (4 palabras; Fuente: formato.oye.DIRECCIONES_LUZ)

desde abajo · desde arriba · desde la derecha · desde la izquierda

EVENTO_OYE (14 palabras; Fuente: formato.oye.EVENTOS_OYE)

destellan los focos · el color se apaga · el rio mide · el soporte empeora · el soporte se deshace · el soporte se limpia · espectrograma de · estalla el color · la camara deja de respirar · la camara respira con · la intensidad cae a · la intensidad salta a · la intensidad sube a · la luz sube con

INTENSIDAD (11 palabras, con orden; Fuente: formato.oye.INTENSIDADES)

nula · quieta · serena · templada · viva · agitada · tensa · encendida · desatada · furiosa · rota

PISTA (5 palabras; Fuente: formato.oye.PISTAS)

la cama · la musica · la radio · la voz · los efectos

SOPORTE (5 palabras, con orden; Fuente: formato.oye.SOPORTES)

limpio · usado · gastado · sucio · roto

Perfil: cámara

BANDA_CUADRO (4 palabras; Fuente: formato.camara.BANDAS)

de abajo · de arriba · de la derecha · de la izquierda

BLANCO_CADENCIA (6 palabras; Fuente: formato.camara.BLANCOS_CADENCIA)

el fondo · la camara · la letra · las figuras · lo de delante · todo

CADENCIA (4 palabras, con orden; Fuente: formato.camara.CADENCIAS)

en uno · en dos · en tres · en cuatro

DISTANCIA (9 palabras, con orden; Fuente: formato.camara.DISTANCIAS)

delante · al pie · cerca · al paso · a media distancia · lejos · al fondo · en el horizonte · en el cielo

ENCUADRE_INCOMODO (7 palabras; Fuente: formato.camara.INCOMODOS)

aire al reves · cortado por la barbilla · cortado por la frente · cuadro vacio · demasiado cerca de · el que habla fuera de campo · mirando fuera de campo

EVENTO_CAMARA (47 palabras; Fuente: formato.camara.EVENTOS_CAMARA)

barrido temporal · camara lenta a saltos · el cuadro gira · el cuadro se endereza · el fotograma se descarrila · el horizonte se endereza · el horizonte se inclina · fotograma de impacto · gran angular · la camara atraviesa · la camara baja · la camara entra en · la camara gira alrededor de · la camara mira desde dentro de · la camara sale de · la camara se acerca a · la camara se aleja · la camara sube · la camara va a · la camara va montada en · la linea se endereza · la linea se inclina · la linea se mueve · la linea se rompe · la pista se desborda · la pista vuelve · la tension cae · la tension rompe · la tension se mantiene · la tension sube · las bandas bajan · las bandas suben · lente normal · ojo de pez · pasa por delante · plano secuencia por · rampa de velocidad · salto axial a · se rasga la banda · se van las perforaciones · se ven las perforaciones · teleobjetivo · tiempo bala sobre · todo se para menos · triple salto axial a · vertigo · vertigo al reves

GOLPE (2 palabras; Fuente: formato.camara.GOLPES)

con borron · con impacto

HORIZONTE (3 palabras; Fuente: formato.camara.HORIZONTES)

gira · recto · se inclina

LENTE (4 palabras; Fuente: formato.camara.LENTES)

gran angular · normal · ojo de pez · teleobjetivo

LINEA_UNIDAD_CAMARA (7 palabras; Fuente: formato.camara.UNIDAD)

CADENCIA · CAMARA · CÁMARA · GOLPES · HORIZONTE · PISTA OPTICA · PISTA ÓPTICA

MANO_CAMARA (2 palabras; Fuente: formato.camara.MANOS)

al hombro · en tripode

PESO_CAMARA (3 palabras; Fuente: formato.camara.PESOS)

con masa · ligera · pesada

PISTA_LADO (2 palabras; Fuente: formato.camara.PISTA_LADOS)

a la derecha · a la izquierda

PROFUNDIDAD (2 palabras; Fuente: formato.camara.PROFUNDIDADES)

poca profundidad · profundidad total

ROTURA (6 palabras; Fuente: formato.camara.ROTURAS)

demasiado rapido · rompe el eje · se sale del cuadro · sin leer · sin respiro · todo a la vez

Apéndice B. Gramática

La gramática completa es spec/gramatica/mesa.ebnf, normativa, que se reproduce aquí.

(* Tórculo 1.0, part 1: the grammar of the pliego language (.mesa), epoch 2.

   Normative. Notation (SPEC §1.4):
     NAME            nonterminal; every nonterminal in capitals that is not defined
                     here is a closed vocabulary of Appendix A (spec/vocabularios/
                     vocabularios.json), and that correspondence is exhaustive.
     "literal"       literal text, compared after normalization (SPEC §4.5),
                     except reserved words, which are compared as written.
     A | B           alternative          [ A ]   optional       { A }  zero or more
     TEXT            any characters up to the end of the line
     NL              end of line
     IDENT           identifier (SPEC §4.5)
     NUMBER          integer or decimal with a point, optional sign
     QUOTE           "«" TEXT-WITHOUT-» "»"      (U+00AB … U+00BB; straight quotes are not equivalent)
     ·               the field separator, U+00B7 MIDDLE DOT, with optional spaces around it

   Analysis is line oriented: each line is classified by its prefix and the
   prefix always wins (SPEC §5.1). Only section blocks and "dentro:" span lines.
   Blank lines separate clips. *)

PLIEGO          = PREAMBLE { CHAPTER } [ END ] ;
PREAMBLE        = { PREAMBLE-LINE | UNIT-LINE | SECTION | COMMENT } ;

(* ---------- preamble ---------- *)
PREAMBLE-LINE   = "MESA" [ "v" NUMBER ] TITLE
                | "formato" PROPERTY { "·" PROPERTY }
                | "ARCO" ARCO
                | "MOTIVO" QUOTE [ "—" TEXT ]
                | "ECO" IDENT ( "→" | "->" ) IDENT
                | "REPARTO" SPEAKER ":" TAMBOR [ "," VOZ ] [ "," VOICE-COLOUR ] [ "," SIDE ] [ "," "alias:" ALIAS { "·" ALIAS } ]
                | "PERSONAJE" IDENT "—" TEXT
                | "LETRA" PATH
                | "PYTHON" PATH
                | "ARCHIVO" KEY { "·" KEY }
                | "FANTASMA" ( "foto" | "texto" | "numeral" ) NUMBER
                | "RELOJES" IDENT NUMBER { IDENT NUMBER }
                | "SONIDO" TEXT
                | "EFECTOS" PATH                       (* sound profile: folder of effects and ambiences *)
                | "BANDA" PATH                         (* sound profile: folder of music cues *)
                | "MEZCLA" MEZCLA { "·" MEZCLA }       (* sound profile: "para la web" | "para cine"; "con stems" | "sin stems" *)
                | "PARTITURA" PATH                     (* cartel profile *)
                | "SOPORTE" SOPORTE                    (* oído profile *)
                | "el dial es la línea de tiempo"      (* oído profile *)
                | "baño" BOBINA ;
PROPERTY        = ASPECT-RATIO | "sala" ( "crema" | "pizarra" ) | "tirada" ( "borrador" | "definitiva" )
                | "página desnuda" | "en dos" ;
ASPECT-RATIO    = FORMATO ;
VOICE-COLOUR    = "con radio" | "seca" ;
SIDE            = "a la izquierda" | "a la derecha" | "al centro" ;

(* ---------- sections: the mirror law (SPEC §5.3) ---------- *)
SECTION         = BLOCK | IMPORT ;
BLOCK           = "#" NOMBRE-SECCION [ IDENT ] NL { SECTION-LINE } "#FIN" ;
IMPORT          = NOMBRE-SECCION PATH ;
SECTION-LINE    = FAMILY [ VALUE ] { "·" FIELD } ;
FIELD           = KEY ( " " | ": " ) VALUE ;       (* keys of several words take a colon *)
FAMILY          = FAMILIA-TALLER | CLAVE-MANO ;

(* ---------- chapter and scene ---------- *)
CHAPTER         = CHAPTER-HEAD { UNIT-LINE | SECTION | COMMENT } { SCENE | CLIP } ;
CHAPTER-HEAD    = "==" TITLE { "·" CHAPTER-ATTR } { "=" } ;
CHAPTER-ATTR    = "tensión" TENSION | "nº" NUMBER | "tambor" TAMBOR | "gigante" WORD
                | "plano fijo" PLANTILLA | "tramo" NUMBER ( "→" | "->" | "a" ) NUMBER
                | "nocturno" | "diurno" ;
SCENE           = SCENE-HEAD { UNIT-LINE | SECTION | COMMENT } { CLIP } ;
SCENE-HEAD      = "--" TITLE [ "·" HORA ] "--" ;

(* Unit lines are valid in the preamble (whole pliego), a chapter or a scene;
   the scene prevails over the chapter, the chapter over the preamble. Several
   are also valid inside a clip, for that shot only (SPEC §5.6). *)
UNIT-LINE       = CORE-UNIT-LINE | ASPECT-UNIT-LINE | SOUND-UNIT-LINE
                | CARTEL-UNIT-LINE | OIDO-UNIT-LINE | CAMERA-UNIT-LINE ;
CORE-UNIT-LINE  = "EJE" "de" IDENT "a" IDENT
                | "LUZ" DIRECCION-LUZ { "·" ( DUREZA | "rasante" ) }
                | "MUNDO" MOVIMIENTO-MUNDO [ NUMBER ] [ "·" SENTIDO ]
                | "FONDO" KEY { ARG } "·" LEJANIA [ "·" NUMBER ]
                | "DELANTE" KEY { ARG } [ "·" LEJANIA ] [ "·" "cada" NUMBER ]
                | "ESCENARIO" TEXT
                | "TABLAS" { "·" ( HORA | "suelo" NUMBER | "a sangre" | "ancho" NUMBER | "alto" NUMBER ) }
                | "ARCHIVO" KEY { "·" KEY }
                | "REPITE" QUOTE ;
ASPECT-UNIT-LINE= "MATERIA" MATERIA-SPEC
                | "BOBINA" BOBINA
                | "FORMATO" FORMATO { "·" FORMATO-MODO }
                | "ESPEJO" [ ESPEJO-LADO ]
                | "PANTALLA PARTIDA" { "·" ( "con un espejo en medio" | "que se miran" | "desigual" | "inclinada" ) }
                | "RÍO TIPOGRÁFICO" [ "·" ( RIO-MODO | "no" ) ]
                | "SIMULTÁNEO" SIMULTANEO
                | "MONTAJE" MONTAJE-SPEC { "·" MONTAJE-SPEC }
                | "HERVOR" HERVOR ;
MATERIA-SPEC    = "papel" PAPEL
                | "acuarela" [ ON-PAPER ]
                | "risografía" TAMBOR-RISO "y" TAMBOR-RISO [ "y" TAMBOR-RISO ]
                     { "·" ( DESREGISTRO | "trama" TRAMA ) } [ ON-PAPER ]
                | "pincel" [ ON-PAPER ] | "tejido" [ TAMBOR-RISO ] | "tinta" [ ON-PAPER ] | "ninguna" ;
ON-PAPER        = "sobre papel" PAPEL ;
MONTAJE-SPEC    = MONTAJE | "mezcla" QUOTE { "·" QUOTE } ;
SOUND-UNIT-LINE = "MÚSICA" ( CUE | "ninguna" )
                | "AMBIENTE" EFFECT-NAME { "·" EFFECT-NAME }
                | "ESPACIO" ESPACIO
                | "CAMA" EFFECT-NAME | "JINGLE" EFFECT-NAME ;
CARTEL-UNIT-LINE= "PALETA" COLOR-CARTEL "," COLOR-CARTEL "y" COLOR-CARTEL
                | "CARTEL" COMPOSICION { "·" COMPOSICION } ;
OIDO-UNIT-LINE  = "INTENSIDAD" ( INTENSIDAD | "de" INTENSIDAD "a" INTENSIDAD ) { "·" ( "extraña" | "con" PISTA ) }
                | "SOPORTE" SOPORTE
                | "COLOR" ( "monocromo" [ TAMBOR-RISO ] | "pleno" )
                | "LUZ" ( "de" ( QUOTE | "los focos" ) { "·" ( DIRECCION-FUENTE | TAMBOR-RISO | "en contraluz" ) }
                        | "plana" [ "·" "de estudio" ] )
                | "la cámara respira con" PISTA | "el río mide la voz" | "la luz sube con" PISTA ;
CAMERA-UNIT-LINE= ( "CÁMARA" | "CAMARA" ) CAMERA-SPEC { "·" CAMERA-SPEC }
                | "HORIZONTE" HORIZONTE
                | "CADENCIA" BLANCO-CADENCIA CADENCIA { "·" BLANCO-CADENCIA CADENCIA }
                | "GOLPES" GOLPE { "·" GOLPE }
                | "PISTA ÓPTICA" [ PISTA-LADO ] ;
CAMERA-SPEC     = LENTE | PESO-CAMARA | MANO-CAMARA | PROFUNDIDAD ;

(* ---------- clip ---------- *)
CLIP            = CLIP-HEAD { CLIP-LINE } ;
CLIP-HEAD       = "*" [ BEAT-ID ] ( FUNCION | SHOT ) [ "·" AFECTO ] [ "(máquina)" ] ;
BEAT-ID         = IDENT ;                         (* optional, stable id for the sidecar (e.g. r01_02) *)
SHOT            = { TALLA | ALTURA | FRENTE | MODO } [ "de" [ ARTICLE ] IDENT ] ;

CLIP-LINE       = CONTENT | PIECE | REAL-VIDEO | PLACEMENT | SCENE-VERB | MAP | MOVEMENT | CAMERA
                | JOURNEY | SOUND | EVENT | NESTING | UNIT-LINE | SIGN | WEAVE | CHARACTER | COMMENT ;

CONTENT         = "di" [ "(" VOZ ")" ] ":" TEXT
                | SPEAKER-LIST ":" TEXT                (* the speaker MUST be declared (REPARTO, PERSONAJE) *)
                | "letrero" [ "(" REGISTRO-LETRERO ")" ] ":" TEXT { "/" TEXT }
                | "terminal:" TEXT | "canta:" TEXT | "contenido (máquina):" TEXT
                | QUOTE                              (* a shout: at most one per clip *)
                | TEXT ;                             (* prose: the beat's content *)
SPEAKER-LIST    = SPEAKER { "/" SPEAKER } ;        (* "VECINO / LOCUTOR": the split sentence *)

PIECE           = "pon:" TIPO-PIEZA QUOTE { "·" PIECE-ATTR }
                | ( "foto" | "recorte" | "prensada" ) ":" KEY
                | "ver:" CLAVE-VIS [ "—" BODY ]
                | "pica:" KEY [ "en" NUMBER ]
                | "python:" NAME { ARG | NAME "=" VALUE } { "·" PIECE-SIZE | "·" CORTE | "·" "sin leer" }
                | ( "arriba" | "pie" | "nota" ) ":" TEXT
                | "marca:" GESTO-MARCA QUOTE ;
PIECE-ATTR      = NUMBER | "id" PATH | TAMBOR ;
PIECE-SIZE      = "grande" | "enorme" | "gigante" | "a sangre" ;

REAL-VIDEO      = "clip" [ " de fondo" | " mudo" ] ":" PATH [ "de" TIME "a" TIME ] ;
TIME            = [ DIGITS ":" ] DIGITS [ "." DIGITS ] ;

PLACEMENT       = "en" NUMBER NUMBER ":" CLIP-LINE
                | "en" PARTE-CUERPO "de" IDENT [ NUMBER NUMBER ] ":" CLIP-LINE
                | RELATION OBJECT [ "a" NUMBER ] ":" CLIP-LINE
                | RELATION "cada uno:" IDENT TEXT
                | "juntos:" LIST "—" DISPOSICION
                | ( "en el mundo" | "en el documento" ) ":" CLIP-LINE
                | "en" MATERIA-SPEC ":" CLIP-LINE          (* the material of one piece *)
                | "de" QUOTE "a" QUOTE ":" CLIP-LINE       (* the sign that flies *)
                | ( "a la izquierda" | "a la derecha" ) ":" CLIP-LINE
                | DISTANCIA ":" CLIP-LINE                  (* camera profile: depth *)
                | "en silueta:" CLIP-LINE ;                (* cartel profile *)
RELATION        = "bajo" | "sobre" | "junto a" | "delante de" | "detrás de" ;

SCENE-VERB      = IDENT "con vista" VISTA
                | IDENT "se encaja en" HOLE | "en sus huecos:" LIST
                | "recoge" IDENT | "clava" IDENT "en" IDENT
                | ( "recorta" | "dobla" | "tapa" | "traslada" ) QUOTE TEXT
                | "retira:" ( "el escenario" | "las tablas" | "el teatro" )
                | "la truca" ( "se acerca a" IDENT | "vuelve" | "se aleja" ) ;

MAP             = "mapa:" MAP-ORDER ;
MAP-ORDER       = "territorio" QUOTE { "·" ( "con" LIST | "grande" | "en" PLACE ) }
                | "línea desde" QUOTE [ "hacia" QUOTE ]
                | "la línea de" QUOTE ( "llega a otro igual" | "se hunde" | "vuelve" )
                | "conecta" QUOTE { "·" QUOTE } | "el círculo se abre" | "mira a" QUOTE
                | "en fila abajo" | "en columna izquierda" | "se va" ;

(* Movement is recognized BY THE VERB (VERBO-MOV, VERBO-RELACIONAL), never by its suffixes. *)
MOVEMENT        = [ PLACEMENT-PREFIX ] [ ARTICLE ] SUBJECT ( VERBO-MOV | VERBO-RELACIONAL ) [ DESTINATION ]
                     { "·" ( [ "por" ] TRAYECTO | MANERA | GRANULADO | REGISTRO-MOV | RASTRO ) } [ VENTANA-SPEC ]
                | SUBJECT "se funde en" SUBJECT | SUBJECT "hierve con" SUBJECT
                | "el pelo pasa de" SUBJECT "a" SUBJECT
                | SUBJECT "se sale del cuadro" [ "por la" LADO ] ;
DESTINATION     = ( "hasta" | "a" | "hacia" ) OBJECT | "fuera de campo" [ "por la" LADO ] ;
VENTANA-SPEC    = "hasta decir" QUOTE | "mientras" ;

CAMERA          = "la truca" ORDEN-TRUCA [ IDENT ] [ "en" TALLA ]
                | IDENT "mira a" IDENT | IDENT "mira a cámara"
                | [ ARTICLE ] IDENT ( "sale" | "entra" ) "por la" LADO
                | "sonido:" CRUCE-SONIDO [ NUMBER ]
                | "fuera de campo" [ "por la" LADO ] ":" TEXT
                | [ "el" ] "foco" ( "en" | "pasa a" ) IDENT [ "y en" IDENT ] | "todo en foco"
                | IDENT "está" TEXT ;                   (* a state, for continuity *)

JOURNEY         = IDENT "viaja" | IDENT "se apea"
                | "el mundo" MOVIMIENTO-MUNDO [ NUMBER ]
                | "por la ventanilla:" LIST "desfilan"
                | "por" WINDOW-OF "de" IDENT "se ve el mundo" ;

SOUND           = "sonido:" EFFECT-NAME [ SIDE ] ;      (* an effect, at its place; anchorable with "al decir" *)

CHARACTER       = SUBJECT ( ACCION-FICHA | EXPRESION | "de espaldas" | "de perfil" | "de frente"
                          | "de tres cuartos" | "de tres cuartos de espaldas" ) ;

SIGN            = "LETRA" QUOTE { "·" ( "en" TIPO-LETRA | DISPOSICION-SIGNO | SITIO-SIGNO | PIECE-SIZE
                                      | "de" COLOR-CARTEL | "sin leer" ) }
                | QUOTE "es" ( "un" | "una" ) PAPEL-SIGNO [ ( "a" | "de" ) QUOTE ]
                | [ "la" | "el" ] LETTER "de" QUOTE ( "es" | "se convierte en" ) IDENT
                | IDENT "se convierte en" [ "la" | "el" ] LETTER "de" QUOTE
                | [ "las letras de" ] QUOTE VERBO-SIGNO
                | "la raya corta" QUOTE
                | QUOTE "forma" FORMA-PALABRA
                | QUOTE "tapa a" IDENT | IDENT "tapa" QUOTE
                | "el ojo completa" QUOTE
                | "ESCALA" IDENT "como" IDENT
                | "BOSQUE de" BOSQUE ;
WEAVE           = ( "TEJE" | "SINTONIZA" ) QUOTE { "·" ( "en" TIPO-LETRA | "con la aguja del dial" | PIECE-SIZE | DISPOSICION-SIGNO ) }
                | QUOTE "se interrumpe en" QUOTE | QUOTE "sigue"
                | "los hilos de" IDENT "y" IDENT "se entretejen"
                | "FRASES" QUOTE { "·" QUOTE } ;

(* Events: a closed vocabulary with state (alive | reserved). The union of
   EVENTO, EVENTO-CARTEL, EVENTO-OYE and EVENTO-CAMARA, some with an argument. *)
EVENT           = ">" EVENT-NAME [ ARG ] { "·" ">" EVENT-NAME [ ARG ] } ;
EVENT-NAME      = EVENTO | EVENTO-CARTEL | EVENTO-OYE | EVENTO-CAMARA | ROTURA-WITH-REASON | ENCUADRE-INCOMODO ;
ROTURA-WITH-REASON = ROTURA "porque" QUOTE ;      (* breaking a rule with permission: the reason is required *)

NESTING         = "dentro:" NL { CLIP-LINE }          (* sub-clips; at most three levels *)
                | "mientras:" CLIP-LINE
                | "al decir" QUOTE ":" CLIP-LINE
                | CLIP-LINE "hasta decir" QUOTE ;

(* ---------- end ---------- *)
END             = "==" "FIN" { "=" } { TEXT } [ NL ">" "silencio" NUMBER ] ;

(* ---------- comments ---------- *)
COMMENT         = "//" TEXT                  (* technical comment: not in the IR *)
                | "(" TEXT ")"               (* author's digression: in the IR, `digresiones` *)
                | "~" "deriva:" TEXT ;       (* a commission to the engine: in the IR, `derivas` *)

(* ---------- terminals ---------- *)
ARTICLE         = "el" | "la" | "los" | "las" ;
TITLE           = QUOTE | TEXT ;
SPEAKER         = IDENT ;          (* not a reserved word; compared as written *)
CUE             = WORD ;           (* a file of BANDA, by name, case-insensitive *)
EFFECT-NAME     = WORD { WORD } ;  (* a file of EFECTOS (or BANDA), by name *)
PATH            = TEXT ;           (* relative to the pliego's folder in a portable project *)
LIST            = IDENT { "·" IDENT } ;

Apéndice C. Códigos de diagnóstico

Códigos de la lengua de pliegos (spec/diagnosticos.json):

CódigoGravedadQué significa
E001errorel pliego declara una época mayor que la del compilador
E010errorafecto fuera del vocabulario cerrado
E011errorfunción o plano desconocidos en la cabecera de un clip
E012errorpalabra suelta en una línea de movimiento (no es trayecto, manera, granulado, registro ni ventana)
E013errorevento > fuera del vocabulario cerrado
E014errorregistro de letrero desconocido
E015errorESPACIO (sala) desconocido
E016errorcolor de voz desconocido en el REPARTO
E017errorarco desconocido
E018errormodificador de collage o campo de MARIONETA desconocido (detrás de · en foto:, recorte:, clip: o MARIONETA)
E019errorotra palabra fuera de un vocabulario cerrado
E020errornombre ambiguo: dos candidatos empatan en el mismo nivel de la dimensión nombre
E021errorpalabra reservada usada como nombre de hablante o identificador
E022errorreferencia a algo que no existe (pieza, clip, id de ECO, personaje)
E023errorlínea que parece una orden y no lo es: se escribiría en pantalla sin querer (diálogo de quien no está en el REPARTO, línea de escena dentro de un clip, orden o verbo inexistentes)
E024erroruna pieza actúa (NOMBRE acción) sin estar en el REPARTO ni ser una MARIONETA
E025errorancla muerta en el texto: al decir «X» y la voz escrita de ese beat no dice X
E030errordos gritos en un clip
E031errordos acciones sobre el mismo sujeto en la misma ventana, o una duración declarada dos veces
E032errorciclo de ligaduras, cadena de más de tres eslabones o anidamiento excesivo
E033errorpieza sin apoyo cuando su materia no flota
E040errorMÚSICA que no está en BANDA (o BANDA sin declarar)
E041errorefecto sonido: que no está en EFECTOS ni en BANDA
E042errorAMBIENTE que no está en EFECTOS
E050errorpython: nombra algo que no está en el bestiario
E051errorpose que el bestiario no declara
E052errordibujo mal invocado: argumentos detrás de ·, paréntesis, o argumentos que la firma de la pieza no admite
E053errorel bestiario declarado (PYTHON o PIEZAS) no existe junto al pliego
E054erroracción que la pieza no declara (ni entre sus ACCIONES, ni sus POSES, ni sus CICLOS)
E060errorrotura de una regla sin su porque
E090errorlínea mal formada (el parser no puede seguir)
W101avisoSALTO DE EJE
W102avisoSALTO DE TALLA
W103avisoRACCORD DE MIRADA
W104avisoRACCORD DE DIRECCIÓN
W105avisoRACCORD DE ESTADO
W110avisoevento reservado: la lengua lo acepta y el intérprete aún no lo realiza
W111avisoregistro de letrero reservado
W112avisoporcentaje pobre por debajo del 85 %
W113avisosin silencio final declarado
W114avisodemasiados clips sin respiro
W115avisoescena con dos o más personajes y sin EJE
W116avisoclip vacío
W117avisorelojes no coprimos
W118avisoacción dudosa sobre una pieza (entra dos veces, actúa sobre algo ausente)
W120avisoancla muerta: al decir «X» y la voz nunca dice X
W121avisodos voces: clip con sonido dentro de un beat narrado sin > espera al clip
W122avisoancla ilegible: casa con la voz pero no con su di:
W123avisoel beat se alarga: el clip dura más que la voz
W124avisopágina vacía: el beat abre cuadro nuevo y no pone nada mientras suena la voz
W125avisotexto en pantalla: una línea de prosa que se escribirá a máquina en el papel
W130avisorevisión Lasseter (sobre la cronología real)
W199avisootro aviso

Códigos de las demás partes: de P001 a P009 (proyecto portable, §14.4), de L001 a L011 (láminas, §17.9), de M001 a M006 (materias, §18.6), de T001 a T007 (tomas, §19.4).

Apéndice D. Desviaciones conocidas de la implementación de referencia

Encontradas al construir la batería de conformidad (2026-10-15) frente a manim-saorín 1.0.0b1. Cada una es un caso pendiente en la batería; deja de estar pendiente cuando la referencia lo pasa.

CasoQué hace la referenciaQué dice esta especificación
lee-errores-reservadaacepta REPARTO nota: … y luego trata nota: como una directiva (avisa «clip vacío»)un hablante con nombre de palabra reservada es E021 (§5.5, §6.4)
lee-estampasavisa «clip vacío» (W116) en un clip cuyo único contenido es un letrero (LETRA)un letrero es una pieza (§8.3); el clip no está vacío
lee-errores-letra-preambuloacepta en el preámbulo una línea LETRA (una línea de clip) sin error y la descarta en silencio: el signo no llega a la IRlas tres sedes (§3): una línea fuera de su sitio es un error (E090), nunca una línea que desaparece
cierre-servilletamesa escribe reescribe el preámbulo de una servilleta y pierde BANDA, EFECTOS, MEZCLA, MÚSICA y AMBIENTEel cierre (§11.1): el pliego revelado suena igual
espejo-tallerun .mano importado lee toca la truca: sí como no; un precisión alta escrito en línea se queda como clave sin normalizar junto a precision alta; parte pierde el nombre de la secciónla ley del espejo (§11.2)
(todos los casos ir)no emite identidad en cada beatidentidad es un campo obligatorio del beat (§10.3); la proyección normativa lo incluirá cuando la referencia lo emita
(preámbulo)MUSICA 1M1 sin tilde en el preámbulo se toma como ruta de canción y la cue se pierde en silencioMÚSICA y MUSICA son la misma palabra (§4.5); un nombre que está en BANDA es una cue (§5.2, RFC 0004)
(proporción pobre)cuenta como cifras nombres de cue como 1M1los nombres no son cifras (§3.1)
(comprobación)mesa lee no informa de las ambigüedades de nombre; mesa indice sí, con estado de salida 0la comprobación de un compilador informa de E020 y falla (§12); el adaptador une las dos órdenes
(códigos)mensajes sin códigoslos códigos del apéndice C (RFC 0003); el adaptador los deriva de los mensajes

Apéndice E. Referencias

  • BCP 14: RFC 2119 y RFC 8174, palabras clave.
  • RFC 8785, JSON Canonicalization Scheme (JCS).
  • RFC 6838, especificaciones y procedimientos de registro de tipos de medio.
  • ISO/IEC 14977, EBNF.
  • PKWARE, .ZIP File Format Specification (APPNOTE).
  • W3C, WebGPU y WGSL.
  • EBU R 128 e ITU-R BS.1770, sonoridad y pico verdadero.
  • J. Lasseter, Principles of Traditional Animation Applied to 3D Computer Animation, SIGGRAPH 1987.
  • Real Academia Española, Diccionario panhispánico de dudas, «raya».
  • SPEC-MESA-2.md, SPEC-PIEZAS.md (manim-saorín); pluma/LAMINA.md, materias/README.md, FORK.md (este repositorio); ManimGX (Academa, MIT).

Apéndice F. Perfiles en desarrollo (informativo)

Tres ramas de la implementación de referencia construyen perfiles nuevos en el momento de este borrador. Lo que sigue es informativo: deja constancia de las líneas que introducen para que otras implementaciones no usen las mismas palabras para otra cosa. Cada uno pasa a normativo cuando su rama se fusiona y la batería tiene casos para él.

  • metraje (metraje real), fusionado en la implementación de referencia el 15-10-2026 (su documento de trabajo es SPEC-METRAJE.md); las palabras nuevas de FORMATO ya están en el apéndice A, y el aspecto del IR lleva formato.reencuadre. Preámbulo: METRAJE, REVELADO, RECORTA, LIMPIA, ESTABILIZA. Clip: plano ≈ «…» y recurso ≈ «…» (un plano encontrado por sentido en una biblioteca indexada), toma: «…», plano: fichero de A a B, y los prefijos de seguimiento sobre la mano de X: y sobre «objeto»: (la pluma sigue a lo filmado). REPARTO admite la voz filmada. FORMATO gana 9:16, 1:1 y 4:5, con reencuadre tras ·: sigue a quien habla | sigue al sujeto | sigue a NOMBRE | centrado. Herramientas: ingesta, busca, monta (montaje por palabras), exporta, importa, planilla. La transcripción es local y palabra a palabra.
  • géneros (géneros y producción). Preámbulo: GÉNERO X [· campo …], que solo pone valores por defecto donde el pliego no dice nada. Clip: ecuación:, fuente:, dato:, rótulo:, cita:, y ver: curva | barras | puntos desde datos.csv. Lienzos vertical y cuadrado nativos. Herramientas: nuevo --género, serie, variantes, traduce, subtitulos, audiodescribe, accesible, revisa, notas, trailer, canal, deriva.
  • 3D (volumen). El escenario en volumen a partir de las palabras del pliego, la misma cámara física en el 3D ligero del motor y en Blender orquestado por capas, el intercambio por glTF y USD, y las imágenes y clips generados, declarados y congelados.