MAKING-OF · 27/09/2026

PERMADEATH:
cómo se hizo el video

Un film de motion graphics de 7:47 sobre el servidor hardcore de ElRichMC, hecho 100 % en código. Las 33 muertes están redibujadas a partir de sus clips, los jugadores aparecen con sus skins reales y la música se sintetiza en el navegador. Ningún dato está inventado.

el frame manda.
1920×1080 · 30 fps14.015 frames55 escenas38 jugadores−14 LUFSUS$ 285,68 equivalente API

La versión final, 7:47. Mejor en pantalla grande y con sonido.

Resumen

Un film de motion graphics de 7:47 sobre Permadeath, el servidor hardcore de ElRichMC (25/03 al 24/05/2020), hecho 100% en código: HTML, JavaScript, three.js y WebAudio, sin metraje ni modelos de video. Se exportó frame a frame a MP4 (1920×1080, 30 fps, 14.015 frames, audio AAC a −14 LUFS, 1,6 GB).

  • Estructura: apertura con el corazón hardcore y la pantalla de kick, título 3D de bloques, las reglas oficiales, presentación de los 38 jugadores con sus skins reales, crónica día por día y memorial final.
  • Crónica: 7 decretos de dificultad, 6 baneos por inactividad, 1 muerte anulada por rollback, 1 muerte revivida y 33 muertes en juego (32 jugadores y OmniRich), cada una recreada como un dibujo animado.
  • Iteraciones: la v1 duró 5:43. La v2 sumó explicaciones dibujadas a mano, cámara lenta, mejor física, decretos rediseñados y una partitura más épica.
  • Archivo final: out/PERMADEATH_v2.mp4; fuentes y pendientes en FACTS.md.

El encargo y las reglas

La regla central fue no inventar: ninguna muerte, día o causa aparece en pantalla sin una fuente contrastada. Lo que no se pudo confirmar va a FACTS.md y no se anima como hecho.

  • Pedido: investigar Permadeath (participantes, tiempos, historia, cada muerte, cada cambio) y hacer un video épico con presentación, timeline y cada muerte recreada.
  • Presentación: con las skins reales de los jugadores.
  • Muertes: recontadas en un estilo animado propio, como si se hubiera visto el clip y se lo volviera a contar en dibujo.
  • Libertad creativa: estilo, música, estructura y duración los decidía yo.
  • Freno obligatorio: solo si dos fuentes se contradecían sobre quién, cuándo o cómo, o si no se podía seguir sin inventar un dato. No hizo falta frenar: cada contradicción se resolvió con una fuente primaria.
  • "Done": skins reales en la presentación, todas las muertes confirmadas recreadas, cero datos inventados y un MP4 que se reproduce.

Investigación con subagentes

La investigación se partió en 4 subagentes en paralelo. Antes de dibujar cada muerte, extraje yo mismo los frames del clip original con ffmpeg y los miré uno por uno.

SubagenteQué trajoFuente principal
PanoramaEdiciones, 38 participantes con su nombre en juego, cambios día por día, hitos128 tuits de @PermadeathSMP recuperados del Wayback Machine, con sus imágenes oficiales
MuertesTabla cronológica con fecha UTC, causa, lugar, contexto y confianzaLas 38 tarjetas oficiales de muerte + clips de los jugadores
SkinsEl PNG real de cada jugador y su épocaNameMC (historial) + API de Mojang
Recon visualFicha cuadro a cuadro de cada clip: mensaje exacto, escenario, HUD, secuenciaCompilado de GersoonSG "TODAS LAS MU3RT3S PERMADEATH", un capítulo por muerte
  • Otras fuentes: el documental de Rubik "La Historia Completa de Permadeath" (2026), las wikis de fans y videos multi-POV.
  • Método de contraste: una herramienta propia (tools/vframes.py) arma hojas de contacto con los segundos exactos de cada clip. Con ellas verifiqué el mensaje de muerte, el escenario y lo que se ve en los últimos segundos.
  • Las muertes sin clip (Kaumaru, OutConsumer, Paracetamor) se reconstruyeron solo con sus propias palabras: su video, su directo, sus tuits y sus entrevistas en el documental.

FACTS.md y las contradicciones

FACTS.md es el contrato del video. Nada se anima como hecho si no está en al menos una fuente primaria (el clip o la tarjeta oficial) contrastada con los frames. Lo que no se pudo confirmar va a "Pendientes" y no sale en pantalla.

Aparecieron 11 contradicciones entre fuentes. Ninguna quedó abierta sobre quién murió, cuándo o cómo, así que no hizo falta frenar a preguntar. La regla fue siempre la misma: manda lo que se ve en pantalla (tarjeta oficial, mensaje de muerte, frames).

#Quién / quéChoqueResolución
1OmniRich, fechaWiki: 05/06/2020Capturas guardadas en el clip (2020-05-24_22.5x, hora local UTC+2): 24/05, ≈21:00 UTC
2ElRichMC, fechaProsa de la wiki 15/05, tabla 20/05Tarjeta: 20-05-2020
3EsVandal, fechaProsa 16/05, tabla 23/05Tarjeta: 23-05-2020
4Luh, causaWiki "ahogarse", documental "creeper"El clip muestra las dos cosas en cadena: explosión y luego se ahoga
5MrCarlosNoob"Caída" vs "araña de cueva"Manda el mensaje: caída mientras escapaba
6Día de las primeras muertesDocumental: "día 1"Contador del servidor: DÍA 0 (25/03)
7FrigoAdriWiki: Permadeath DemonTarjeta y mensaje: Ender Creeper
8NiaWiki "Enderman", tarjeta "Ender Ghast"Se dibuja lo visto (tótem entre endermen) y el mensaje oficial
9CrisGreen, lugarDocumental: portal al salir del NetherFootage: pasillo con canal de agua, lado Overworld
10HorasHora española vs UTCTodo en UTC + contador del servidor
11Ander, lugarAgente: "isla de champiñones"El clip: pasto, arena y río de noche

Los casos dudosos se animaron sin inventar:

  • Cecililla: el creeper nunca aparece en cámara, así que tampoco en el dibujo. La explosión llega desde fuera de cuadro.
  • Hardyluski: el Gato Supernova nunca se ve. Se dibujan el vuelo y la explosión repentina, sin el gato.
  • Golpes finales no visibles (Folagor, Mikecrack, Cibergun, Nia, EsVandal): se muestra hasta el último frame y el remate queda como destello, según el mensaje oficial.
  • Muertes que no contaron: la de MrCarlos (deshecha por rollback) se menciona sin recrearla. La primera de Kakytron (bug del script) va como boceto con sello "MUERTE ANULADA".
  • Baneos por AFK: no hubo muerte, así que van en una tarjeta de "permabaneados por inactividad".

Quedaron 10 pendientes que no salen en pantalla. Por ejemplo: la duración del Death Train en cada muerte, el "combo flecha" de Tonacho (solo es su relato), si a KillerCreeper lo mató uno o dos creepers, y qué figura era el Emperador en el clip de EsVandal.

Stack técnico

Todo el video es una página web que se renderiza sola. No hay footage, ni modelos de video, ni samples: la imagen sale de three.js y Canvas 2D, y la música se sintetiza en el navegador.

El video y la música salen del mismo guion: cada frame es función del tiempoimagen: framesmúsica: cues en JSONtimeline.js · 55 escenas en ordencada frame = función del tiempo: FILM.renderFrame(n)las mismas marcas de tiempo mueven imagen y música6 workers de Chromium headlessGPU real: WebGL2 vía ANGLEthree.js → Canvas 2D → shader de postcada worker renderiza un rango de frames6 chunks de OfflineAudioContextventanas de ~79 s sobre el mismo guioncada evento suena en la ventana dondeempieza, con su cola completaffmpeg libx264 por pipeJPEG del canvas · CRF 19 · preset slowun segmento .mp4 por workerNode suma el PCM en floatffmpeg: acompressor + alimiteruna sola mezcla, sin cortes entre chunksconcat -c copy → video_noaudio.mp418,7 min a 12,7 fps de mediaun arreglo = re-renderizar un segmentoscore.wav6 chunks en paralelo: ~14 minen un solo hilo nunca terminabamux + loudnorm (I = −14 LUFS)PERMADEATH_v2.mp4 · 7:47 · 14.015 frames · 1,6 GB
Pipeline de render: una fuente, dos ramas, un mux.

La línea de tiempo alimenta dos ramas que corren por separado y se juntan recién en el mux final.

  • Determinismo: nada depende de un reloj real, todo lo que se mueve depende del número de frame. Por eso 6 workers pueden renderizar rangos distintos y el resultado pega sin costuras. También permite re-renderizar un solo segmento para arreglar una escena.
  • Motor: Chromium 152 headless controlado con puppeteer-core, con la GPU AMD real.
  • Capas por frame: escena 3D (three.js) → composición 2D (textos, notas, HUD) → shader de post (grano, aberración cromática, viñeta, destello, temblor, glitch, letterbox y transiciones de quemado, tinta y corte).
  • Captura: canvas.toDataURL en JPEG, por pipe directo a ffmpeg. No se guardan frames sueltos en disco.
  • Audio: el mismo FILM.cuesJSON() que usa la imagen le dice a la música dónde caen los impactos, los decretos y las cámaras lentas.
  • Archivos clave: film/src/main.js (arranque y API FILM), film/src/timeline.js (las 55 escenas), film/render.mjs (video) y film/render_audio.mjs (audio).

Dirección de arte

El video habla con dos lenguajes visuales. Lo "oficial" (presentación, título, decretos, tuits) es Minecraft limpio: vóxeles en 3D y tipografía del juego. Las muertes, en cambio, son un relato dibujado: tinta y aguada sobre papel, como alguien que vio el clip y lo vuelve a contar a mano.

El shader "ink & wash" (film/src/gl.js, renderInk) convierte cualquier escena 3D en dibujo:

  • Filtro Kuwahara: aplana las texturas de bloque en manchas de aguada sin perder los bordes.
  • Líneas de tinta: salen de la profundidad (Sobel) y de un laplaciano. Tiemblan ("boil") a 8 fps, como una animación dibujada cuadro a cuadro.
  • Trama de sombreado en las zonas oscuras, fibra de papel, manchas y bordes de página quemados.
  • Tinta roja: es el único color saturado y se reserva para la lava y el fuego.

El modo "boceto a lápiz" se usa para las muertes sin clip (Kaumaru, OutConsumer, Paracetamor y la primera de Kakytron). Se ve distinto a propósito, para que quede claro que es una reconstrucción a partir de lo que ellos mismos contaron.

Las notas a mano son la firma de la segunda pasada:

  • Texto en Caveat que se escribe letra por letra.
  • Flechas, círculos y subrayados que se trazan en vivo y siguen al objeto en 3D (se proyecta su posición en cada frame).

La cámara lenta re-mapea el tiempo de la escena: la imagen pierde color (35 % monocromo), entran franjas de cine y la música baja a latidos.

Los decretos (cambios de dificultad) son motion graphics con tipografía de Minecraft:

  • Un cuentakilómetros que gira hasta el día nuevo y un titular que se escribe con glitch.
  • Tooltips del juego con códigos de color (dorado y rojo tachado).
  • Un pedestal 3D con el mob de cada cambio, sobre un fondo de texturas del juego en mosaico.

Tipografías: Monocraft (Minecraft), Cinzel (épica), Fraktur, VT323 (terminal), Oswald, Caveat (mano) y Permanent Marker.

Momentos épicos fuera de las muertes: el título "PERMA / DEATH" hecho de bloques que sube desde la lava entre rayos, y el anillo con los 38 jugadores y sus skins reales.

Skins reales

Cada jugador aparece con la skin que llevaba cuando murió, no con la de hoy. La prueba es su tarjeta oficial de muerte: @PermadeathSMP la tuiteó dentro del día y muestra la cara 8×8 del jugador en escala de grises.

Cómo se verificó:

  1. Nombre de juego → UUID con la API de Mojang.
  2. Historial de texturas de la cuenta en NameMC. NameMC bloquea curl con Cloudflare, así que los PNG se bajaron desde una sesión de navegador real.
  3. Se comparó la cara de cada textura con la de la tarjeta, píxel por píxel en luminancia. Coincidencia = diferencia máxima menor a 1 nivel sobre 255.
ResultadoJugadoresCómo aparece en el video
Cara idéntica a la tarjeta33 de 38Skin completa
Muy parecida, no idénticaFrigoAdri, CibergunLa textura más parecida
Solo existe la skin actualShadoune666Rotulado "skin actual (la de 2020 no se conserva)"
Cuenta sin confirmarPerxitaa, BarbeQSolo la cara 8×8 extraída de su tarjeta, cuerpo en sombra

Trampas encontradas:

  • Hay cuentas que hoy tienen el mismo nombre pero no son los jugadores de 2020 (por ejemplo Luh, IbaiLlanos, alexelcapo). Por eso se fue siempre por UUID y tarjeta, nunca por nombre.
  • Varios jugadores usan la misma cabeza en muchas skins (Mikecrack, ElRichMC, CrisGreen, KillerCreeper55, Rubik). La tarjeta prueba la cara, no el cuerpo, así que se eligió la textura más cercana a la fecha de la muerte.
  • Algunas tarjetas no coinciden con la primera textura que registró NameMC: el jugador había vuelto a una skin vieja, y NameMC registra cada textura una sola vez.

El modelo 3D (film/src/skin3d.js) arma el jugador directo desde el PNG:

  • Las UV de Minecraft, con la capa de ropa encima.
  • Detección de brazos finos (modelo "slim").
  • Soporte de skins viejas de 64×32, con los miembros espejados.
  • La regla de Minecraft para esas skins viejas: si la capa del sombrero es opaca entera, se ignora. Sin esa regla, el sombrero tapaba la cara de esos jugadores.

El registro completo (UUID, fuente y evidencia de cada archivo) está en assets/skins/SKINS.md.

Recreación de las muertes

Las 33 muertes confirmadas (32 jugadores y OmniRich) tienen cada una su viñeta dibujada, de 7 a 10,7 segundos. A eso se suma la primera muerte de Kakytron, que fue anulada y aparece como boceto con sello. Los 6 baneos por AFK no se recrean porque no hubo muerte: aparecen como tarjeta de "permabaneado".

Cada muerte es un módulo (film/src/deaths/dNN_jugador.js) con la misma forma:

  • Datos: número, jugador, día, fecha, momento del impacto y duración.
  • chat: los mensajes del chat, textuales del clip (el mensaje vanilla y la frase de muerte personalizada).
  • slow: los tramos en cámara lenta.
  • build(): arma el mundo en vóxeles, los mobs y al jugador con su skin. Devuelve:
    • cues (sonidos), hearts (la vida en el HUD) y notes (las explicaciones dibujadas).
    • overlay (HUD 2D: hotbar, tooltips, citas).
    • update(t), que ubica cámara, jugador y mobs para cada instante.

El ciclo de cada muerte:

  1. La ficha visual del clip (research/parts/), cuadro a cuadro.
  2. Un agente, o yo, escribe el módulo siguiendo film/AGENT_GUIDE.md.
  3. tools/preview.sh renderiza frames sueltos y tools/vframes.py arma la hoja del clip real para compararlos lado a lado.
  4. Se corrige y se vuelve a comparar.

Ejemplos de cómo el clip manda sobre el dibujo:

MuerteLo que muestra el clipCómo quedó dibujado
#3 CecilillaEl creeper nunca entra en cuadroLa explosión llega desde fuera de cuadro, con un rótulo que lo dice
#13 TonachoPantano al amanecer, slime gigante, tótem, dos slimes y un creeperEl mismo encuadre. No hay esqueletos: el "combo flecha" es solo su relato
#32 ElRichMCEn el frame de 20:15 la élitra está en su inventarioInventario replicado casilla por casilla, con la nota "¡la élitra estaba aquí!"
#37 KillerCreeper55Salón de hielo y cofres, medalla en la mano, tooltip "Shield" 0,2 s antes de morirEl mismo salón y la misma hotbar. El escudo sube tarde y una nota lo marca

Piezas compartidas (film/src/deaths/common.js):

  • groundAt: pega jugadores y mobs al suelo real del mundo. Antes, algunos flotaban o se hundían.
  • creeperFuse y walkCreeper: el creeper camina, parpadea en blanco y se hincha antes de explotar.
  • totemPop: el tótem salta en 2D encima de la imagen, con su textura real de 16×16 y giro, como en el juego.
  • hop: el salto con aplastamiento de los slimes.

Después de cada impacto la viñeta sigue 1 segundo más (1,6 en las anuladas) para que se alcance a leer el mensaje de muerte.

Música y sonido

Toda la banda sonora está sintetizada en el navegador, sin un solo sample. Se genera a partir de la lista de escenas y de los cues del propio video, así que cada golpe cae en su frame exacto.

El sintetizador (film/src/audio/synth.js) tiene 25 voces hechas con osciladores, ruido y envolventes. Entre ellas: bombo, braam de cine, coro con formantes de vocales, campanas, piano, trémolo de cuerdas, redoble de timbales, rugido, platillo, truenos, lluvia y latido.

La base (film/src/audio/score.js) está en re menor a 120 BPM, con un acorde cada 2 segundos:

  • Pad, bajo sub, un ostinato de cuerdas pulsadas y batería. Cada 4 compases entra un redoble de taikos.
  • La intensidad sube con cada decreto: el ostinato pasa de corcheas a semicorcheas y los filtros se abren.
  • Desde el día 30 entran tambores de guerra. Desde el día 40 la progresión cambia a una más oscura, con semitonos (re → mi♭ → re → do♯).

Lo que suena en cada momento clave:

MomentoQué suena
Arranca una muerteWhoosh y trémolo de cuerdas. Un redoble de timbales crece hasta el impacto
El impactoSilencio total de la base 1,6 s. Suena solo el golpe según la causa (explosión, vacío, ahogo, flecha o golpe), con braam, coro y platillo
"¡Permadeath!"Rugido sintetizado, campana y coro
Cámara lentaSe corta la base. Quedan latidos cada 0,55 s, un barrido grave y un sub
DecretoRiser, boom, platillo, braam, coro y campana. Cada regla nueva trae un golpe de metales que sube (re, fa, sol, la, do)
MemorialPiano solo sobre un pad, con coro al final

El truco que más rindió fue el silencio antes del golpe. La base se apaga justo en el impacto y en las cámaras lentas. Eso hace que cada muerte pegue más fuerte que si sumara capas.

La mezcla final:

  1. Los 6 chunks se suman en float.
  2. ffmpeg aplica acompressor y alimiter.
  3. En el mux, loudnorm a −14 LUFS, el nivel de YouTube.

La suma cruda llegaba a un pico de 2,25 (más del doble del máximo). Sin el limitador, cada explosión habría saturado.

Render y exportación

El MP4 sale en tres comandos: video, audio y mux. Cada rama se reparte en 6 procesos paralelos. En una sola PC, el video tardó 18,7 minutos y el audio 13,75.

node render.mjs --workers 6      # → out/video_noaudio.mp4
node render_audio.mjs 6          # → out/score.wav
ffmpeg -i out/video_noaudio.mp4 -i out/score.wav -map 0:v -map 1:a -c:v copy \
  -af loudnorm=I=-14:TP=-1.0:LRA=11 -c:a aac -b:a 256k -ar 48000 \
  -shortest -movflags +faststart out/PERMADEATH_v2.mp4

Video (film/render.mjs):

  • Abre 6 páginas de Chromium headless, con la GPU habilitada y sin throttling de pestañas en segundo plano.
  • Cada página recibe un rango de frames. Por cada frame llama a FILM.renderFrame(n), saca el canvas en JPEG (calidad 0,96) y lo manda por pipe a su ffmpeg.
  • ffmpeg codifica en H.264: preset slow, CRF 19, yuv420p, 30 fps.
  • Al final, concat -c copy une los 6 segmentos sin volver a codificar.

Audio (film/render_audio.mjs): 6 ventanas de ~79 s en paralelo. Node junta el PCM y ffmpeg comprime y limita.

Arreglos sin re-renderizar todo: para corregir una escena se renderiza solo su rango (--from/--to), se reemplaza ese segmento y se vuelve a concatenar. Así se arregló la muerte de ElRichMC en v2: se reemplazó solo el segmento 4.

Problemas que aparecieron y cómo se resolvieron:

ProblemaCausaSolución
El audio en un solo hilo no terminaba nuncaCasi 8 minutos de partitura en un solo OfflineAudioContextPartirlo en 6 ventanas por tiempo de inicio y sumarlas
Abrir 6 páginas daba timeoutCada página construía las 55 escenas al cargarConstruir cada viñeta recién al usarla, abrir las páginas de a una y subir el timeout a 900 s
Colores que no coincidían con la paleta en el shader de tintaMezcla de espacios de color lineal y sRGBCorregir con pow(1/2,2) y pasar los colores crudos
Las previews de los agentes se pisabanTodas escribían en la misma carpeta temporalUna carpeta temporal por llamada

Verificación del MP4 final:

  • Se decodificó completo con ffmpeg sin errores.
  • Tiene 14.015 frames.
  • No hay saltos en las uniones de segmentos.
  • La sonoridad medida es −14 LUFS.

Segunda pasada con 5 subagentes

La v1 (5:43) gustó, y la segunda pasada fue de pulido. Se atendió una lista de pedidos concretos del feedback y se repartieron 27 muertes entre 5 subagentes. Yo me quedé con los sistemas compartidos y las 7 muertes que requerían fuentes nuevas.

Lo que pediste y dónde quedó:

  • Física y composición: groundAt para que nadie flote, y cámaras reencuadradas escena por escena.
  • Arañas paradas sobre sus patas, creepers que se acercan, parpadean y explotan, slimes con cara.
  • Tótem con su textura real y su giro, en 2D sobre la imagen.
  • Tiempo para leer: 1 s más después de cada muerte.
  • Explicaciones dibujadas en todas las muertes, trazadas en vivo, y cámara lenta en los momentos clave.
  • Decretos con motion graphics y tipografía de Minecraft, y música más épica en muertes y decretos.

Reparto:

SubagenteMuertesEsfuerzo
Overworld y cuevasAlvaro, TheGamerMaldito, Ibai, Reven, Ander, Tonacho, RanguGamermedio
Nether y End AAKAWonder, FrigoAdri, Gona, EsVandalmedio
End BMikecrack, Cibergun, Alkapone, Niamedio
Lote DCecililla, Felipez, Rubik, Zeling, Folagor, MrCarlosmedio-alto
Lote EBrii, Kakytron, CrisGreen, KillerCreeper55, Luh, OmniRichmedio-alto
YoKaumaru, OutConsumer, Paracetamor, Hardy, ElRichMC, Shadoune y la primera de Kakytron—

Los agentes arrancaron en esfuerzo medio. Cuando pediste medio-alto según la complejidad, los lotes D y E salieron así. Ninguno usó el máximo.

Lo que hizo que 5 agentes pudieran trabajar a la vez sin romperse entre sí:

  • film/AGENT_GUIDE.md con reglas duras: datos solo de research/parts y FACTS.md, cada uno edita solo sus archivos, todos pegados al suelo con groundAt. También documenta la API de notas y de cámara lenta.
  • Sistemas compartidos en manos de uno solo: notas, cámara lenta, tótem 2D, mobs y el motor de viñetas los toqué solo yo. Los agentes los usaron sin modificarlos.
  • Previews aisladas: preview.sh usa una carpeta temporal por llamada.

Lo que igual falló:

  • Un error de sintaxis de un agente rompió por un rato las previews de todos, porque todas cargan el mismo timeline.
  • El compañero sin identificar de Ander salía con la skin de OmniRich. Se cambió por una silueta genérica.
  • En la muerte de ElRichMC, las notas se superponían. Se corrigieron los tiempos y se re-renderizó solo ese segmento.

El resultado es la v2: 7:47, con todas las muertes revisadas contra sus frames.

Aprendizajes

Lo más valioso no fue técnico: fue decidir que el frame manda y dejar por escrito qué no se sabe. Todo lo demás se apoya en eso.

Investigación

  • El clip le gana a la wiki. Las 11 contradicciones se resolvieron mirando un frame o una tarjeta. La wiki incluso se contradice sola: la prosa dice una fecha y la tabla otra.
  • Las tarjetas oficiales de muerte fueron la mejor fuente. En una sola imagen traen fecha y hora UTC, causa y la cara del skin.
  • "No se sabe" también es un dato. Cada caso dudoso tiene su convención visual: boceto a lápiz, explosión desde fuera de cuadro o sello de "anulada". Así el video cierra sin inventar nada.
  • Las palabras del propio jugador desbloquean casos sin clip. Paracetamor (el gateway) y el búnker de Kakytron salieron de sus entrevistas en el documental.

Código y producción

  • Determinismo desde el día uno. Que cada frame dependa solo del tiempo es lo que permitió 6 workers, parches de un solo segmento y previews idénticas al render final.
  • Un motor compartido y módulos chicos. Una muerte es un archivo de 122 líneas de media encima del motor de viñetas. Eso escaló a 33 escenas y a 5 agentes.
  • El ciclo de corrección más rápido: frames sueltos del render al lado de la hoja de frames del clip real. No hace falta renderizar el video para ver si una escena está bien.
  • Construir las escenas solo cuando se usan. Construirlas todas al cargar trababa el arranque del render.

Agentes

  • Reglas escritas y dueños de archivo claros valen más que prompts largos. Con AGENT_GUIDE.md y un archivo por agente no hubo conflictos de edición.
  • Los sistemas compartidos no se delegan. Cuando todos dependen del mismo motor, un error de uno frena a todos.
  • Esfuerzo medio alcanza para arreglos puntuales. Medio-alto sirve para lotes que suman notas y cámara lenta.

Audio

  • Audio largo = ventanas por tiempo de inicio con cola completa, y después sumar. La mezcla es exacta y se paraleliza.
  • El silencio pega más que otra capa. Cortar la base justo en el impacto le dio a cada muerte más peso que cualquier braam.

Creativo

  • Dos lenguajes visuales separan hecho de relato. Lo oficial va en Minecraft limpio. La muerte es un recuerdo dibujado.
  • Las notas a mano convierten el espectáculo en explicación. Pero tienen que anclarse al objeto 3D; si no, flotan desconectadas de la acción.

Números y archivos

El video final dura 7:47, pesa 1,57 GB y salió de unas 8.500 líneas de código propio.

DatoValor
Duración7:47 (467,17 s)
Imagen1920×1080, 30 fps, 14.015 frames, H.264 a ~26,8 Mb/s
SonidoAAC 256 kb/s, 48 kHz, −14 LUFS
Escenas55
Muertes recreadas33 (32 jugadores y OmniRich), más la primera de Kakytron (anulada)
Baneos por AFK6, en 4 tarjetas
Decretos7 (días 10, 20, 25, 30, 40, 50 y 60)
Jugadores con skin38, más OmniRich
Contradicciones resueltas11
Tuits oficiales recuperados128
Subagentes9: 4 de investigación y 5 de segunda pasada
Código propio~8.500 líneas (sin contar three.js)
Tiempo de render18,7 min de video y 13,75 min de audio

Dónde está cada cosa (dentro de la carpeta del proyecto):

RutaQué es
out/PERMADEATH_v2.mp4El video final
FACTS.mdHechos, fuentes, contradicciones y pendientes
film/README.mdCómo previsualizar y renderizar
film/AGENT_GUIDE.mdReglas para los subagentes
film/src/timeline.jsEl orden de las 55 escenas
film/src/vignette.jsEl motor de las viñetas de muerte
film/src/deaths/Una muerte por archivo
film/src/scenes/Intro, título, jugadores, decretos, tarjetas y memorial
film/src/audio/Sintetizador y partitura
assets/skins/SKINS.mdOrigen y evidencia de cada skin
research/Notas, frames y evidencia

Quedan dos exportaciones viejas en out/: PERMADEATH.mp4 (v1, 1,22 GB) y permadeath_v1.mp4 (4,92 GB). No las borré.

Posibles mejoras

Lo que más sumaría ahora es cerrar pendientes con más clips multi-POV. Después vienen las versiones para distribuir. Nada de esto hace falta para que el video actual sea correcto.

Datos que se podrían confirmar

  • Clips de otros jugadores del mismo momento: podrían mostrar el primer golpe de Folagor, Cibergun y Alkapone, si a KillerCreeper55 lo mató uno o dos creepers, y la duración del Death Train en cada muerte.
  • La skin de 2020 de Shadoune666: buscarla en miniaturas y videos viejos suyos.
  • Las cuentas de Perxitaa y BarbeQ: buscar su nombre en la lista de jugadores (tab) de algún clip, para usar su skin completa en vez de solo la cara.

Distribución

  • Capítulos de YouTube automáticos: el timeline ya sabe dónde empieza cada escena (tools/info.mjs).
  • Subtítulos en inglés: las notas y citas son datos con tiempos, así que se puede generar un .srt directo desde el código.
  • Un corte vertical para Shorts o TikTok con 3 o 4 muertes. El motor ya permite renderizar cualquier rango, pero habría que recomponer los encuadres a 9:16.
  • Una versión liviana para compartir: el master a ~26,8 Mb/s es ideal para subir, pero pesado para mandar por chat.

Técnica

  • Render más rápido: hoy va a 12,7 fps de media. No medí si el límite es la GPU, la codificación JPEG o el x264 en preset slow. Medirlo diría si conviene sumar workers en otra máquina (la idea del VPS) o solo bajar el preset.
  • Un chequeo automático de escenas: que falle si alguien flota, si una nota se sale de cuadro o si dos notas se pisan. Hoy eso se revisa a ojo en las previews.

Costo, tokens y tiempo

Todo el proyecto usó 718,11 M tokens en 2.647 llamadas a la API: la sesión principal más 18 subagentes. Al precio de lista de Claude Opus 5.5, eso equivale a US$ 285,68. Pasaron 4 h 44 min de reloj, de las 20:38 a las 01:23 (hora de Argentina).

US$ 285,68equivalente API
718,11 Mtokens en total
4 h 44 minde reloj
10 h 54 minsumando los 18 subagentes

Tokens y costo por tipo

El 49 % del costo son lecturas de caché: cada llamada relee el contexto acumulado. A $0,20 por millón son baratas, pero fueron 699,15 M.

TipoTokensPrecio Opus 5.5 (por millón)Costo
Entrada sin caché5.298US$ 4US$ 0,02
Escritura de caché (5 min)13.860.360US$ 5US$ 69,30
Escritura de caché (1 h)2.107.479US$ 8US$ 16,86
Lectura de caché699.153.467US$ 0,20US$ 139,83
Salida2.983.084US$ 20US$ 59,66
Total718.109.688US$ 285,68

Por agente

Son 19 filas: la sesión principal y los 18 subagentes. La investigación fue lo más caro después de la sesión principal: 13 agentes leyendo frames, tuits y wikis en paralelo. Todos corrieron en Opus 5.5 a velocidad estándar.

AgenteQué hizoLlamadasEntrada + cachéSalidaCosto
Sesión principal (yo)Orquestación, motor, escenas, render, doc472226,36 M712.887US$ 75,97
Investigación · panoramaEdiciones, reglas, cambios, tuits11928,57 M102.176US$ 12,76
Investigación · muertesLanzó 4 sub-agentes7215,21 M113.415US$ 13,71
↳ muertes · grupoSub-agente12331,33 M87.697US$ 10,04
↳ muertes · grupoSub-agente10319,74 M94.612US$ 7,49
↳ muertes · grupoSub-agente14739,55 M113.657US$ 12,33
↳ muertes · grupoSub-agente21456,78 M106.753US$ 15,60
Investigación · skinsNameMC, Mojang, tarjetas18335,37 M165.384US$ 16,76
Investigación · recon visualLanzó 5 sub-agentes8815,28 M94.874US$ 9,07
↳ recon visual · lote ASub-agente11929,76 M129.639US$ 12,18
↳ recon visual · lote BSub-agente15737,26 M138.725US$ 16,85
↳ recon visual · lote CSub-agente10321,66 M100.666US$ 10,44
↳ recon visual · lote DSub-agente13429,39 M136.540US$ 14,63
↳ recon visual · lote ESub-agente10720,97 M104.278US$ 10,56
2.ª pasada · Overworld y cuevas7 muertes · esfuerzo medio12630,86 M186.105US$ 13,77
2.ª pasada · Nether y End A4 muertes · esfuerzo medio8214,26 M123.592US$ 6,69
2.ª pasada · End B4 muertes · esfuerzo medio9820,38 M176.750US$ 9,31
2.ª pasada · lote D6 muertes · esfuerzo medio-alto11824,72 M147.228US$ 9,41
2.ª pasada · lote E6 muertes · esfuerzo medio-alto8217,66 M148.106US$ 8,11

Tiempo

Hora (AR)Hito
20:38Pedido inicial
20:39 – 22:19Investigación: 4 agentes y 9 sub-agentes en paralelo, mientras yo armaba el motor
22:11 – 22:44Primeros renders: audio, video y la v1 (5:43)
23:07Tu feedback de la v1
23:13 – 23:59Segunda pasada con 5 subagentes
23:59 – 00:25Render de la v2, parche del segmento 4 y mux final
00:35 – 01:23Doc, costos, esta página, el repo de GitHub y el video en YouTube
  • Tiempo con actividad: 3 h 38 min. Cuento como pausa todo hueco de más de 10 minutos sin ninguna acción de ningún agente; hubo 3, que suman 1 h 06 min.
  • Tiempo de máquina en renders: 58 minutos de video (v1, v1b, v2 y el parche) y 27 de audio. Buena parte corrió en paralelo con otro trabajo.
  • Trabajo en paralelo: sumando la duración de cada subagente salen 10 h 54 min. Eso es más del doble del tiempo de reloj.

Qué no entra en la cuenta

  • La compactación de contexto (1 vez, sobre ~968.000 tokens) no queda registrada en el transcript. Suma entre ~US$ 0,50 y ~US$ 4, según cuánto estuviera en caché.
  • Las 94 búsquedas web cuestan US$ 10 cada 1.000 (US$ 0,94), más los tokens de esas búsquedas, que tampoco se registran.
  • Las 34 lecturas de páginas web las resume un modelo chico aparte, y su uso tampoco se registra.
  • Es un equivalente: suma el uso registrado a precio de lista de la API. Si la sesión corrió con una suscripción, el cobro real es otro.
  • Foto al momento de generar esta página: lo que pase después (incluido publicarla) no está sumado.

Fuente: los transcripts de Claude Code (sesión y subagentes). Cada respuesta se cuenta una sola vez por su id de mensaje. Precios de platform.claude.com/docs/en/about-claude/pricing: Opus 5.5 cobra US$ 4 la entrada, US$ 5 y 8 las escrituras de caché de 5 min y 1 h, US$ 0,20 las lecturas de caché y US$ 20 la salida; el contexto de 1M va a tarifa estándar. Script: costs/usage.py.