Animaciones voxel
Crea escenas que parecen un juego de construcción por bloques, sin usar nada de uno: cada textura se genera en código en tiempo de ejecución y el personaje es un diseño original. El resultado es una página HTML autónoma (interactiva, compartible) y, cuando se solicita, un vídeo fotograma exacto renderizado desde esa misma página.
Archivos de esta habilidad
assets/voxel-kit.js: el kit (texturas, materiales, bucle de la aplicación, cámara orbital, cielo con día/noche, terreno isla, plataforma de estudio, rig del personaje, partículas, aparición, explosión, antorchas, ayudantes de ruta, grabador, modo captura). Léelo antes de escribir una escena: la referencia de la API más abajo es un resumen, el archivo es la verdad.assets/template.html: página de inicio con el marcador del kit, isla, personaje y una pequeña línea de tiempo.examples/house-builder.html: un constructor coloca una casa bloque a bloque, celebra, explota, bucle.examples/melting-crystal.html: ejemplo de física (fusión de Lindemann de una red de hielo de 6×6×6, con un termómetro voxel, charco y recongelación). Copia su estructura para explicaciones científicas.scripts/inline_kit.py: reemplaza<!-- VOXEL_KIT -->en una página con el kit, dando un solo archivo.scripts/render.py: renderizado fotograma exacto a fotogramas PNG y.mov/.mp4/.webm.
Si solo está disponible este SKILL.md (falta la carpeta), obtén la habilidad completa desde https://github.com/normix93/voxel-animations antes de construir.
Flujo de trabajo
- Define la idea en una línea: qué se construye, transforma o explica, y cómo termina el bucle (reinicio, explosión, congelación, cámara alejándose). Decide el destino: página interactiva, vídeo para editar (fondo transparente o no), corto vertical (1080×1920).
- Storyboard como línea de tiempo: 3–6 momentos con duraciones, p.ej.
0–2 s lugar vacío → 2–40 s construir → 40–44 s celebrar → 44–49 s explotar → bucle. Cada momento es unmodeen una máquina de estadosapp.onUpdate(ver el ejemplo de la casa). - Parte de
assets/template.html, mantén el marcador del kit, escribe la sección SCENE. Reutiliza piezas del kit en lugar de reescribirlas. Mantén todo en una página. - Construye la página:
python3 scripts/inline_kit.py scene.src.html scene.html. - Compruébala: ábrela (o renderiza unos fotogramas con
render.pya una carpeta y míralos). Busca: bloques flotando o superpuestos, personaje atravesando paredes, cámara atravesando árboles, primeros segundos vacíos, parpadeo en bloques transparentes. - Entrega: publica la página como un artefacto cuando el entorno lo soporte y también entrega el archivo .html; renderiza el vídeo si se pide (ver Exportar).
Reglas de estilo
- Original solo. Nunca uses texturas, sonidos, logotipos, criaturas, personajes o nombres de un juego existente. No llames al resultado "Minecraft" de ninguna forma: di voxel, bloque, mundo de bloques. Las texturas procesales y el constructor con casco del kit son seguros de usar y modificar.
- Nitidez pixelada: texturas 16×16 con
NearestFilter(el kit lo hace). Luz dura, sombras claras, pocos colores por material, poco ruido. - El movimiento tiene peso: los bloques aparecen con rebase (
app.pop), los escombros usan gravedad (≈20–22 bloques/s²) y rebotes amortiguados, el personaje camina a ~5 bloques/s y gira suavemente. Evita interpolaciones lineales para cualquier cosa física. - Legible de un vistazo: un tema principal en el centro, cámara orbitando lentamente
(
autoSpeed0.05–0.1), fondo tranquilo (cielo o colorstudio). - Texto: la página puede tener un título y una línea de estado. Para vídeo, renderiza con
?clean(sin interfaz). Si se necesitan etiquetas en el vídeo, usa palabras muy cortas; las explicaciones pertenecen a la narración o a la página, no a los fotogramas.
API del kit (resumen)
const app = VK.createApp({
title, subtitle, hint, // texto de la interfaz (oculto con ?clean o tecla H)
sky: 'day' | 'night' | 'studio', // studio = color plano (studioColor), sin niebla
cycle: false, dayLength: 48, tod: .27, // hora del día 0..1 (.25 amanecer lateral, .75 noche)
camera: { radius, phi, theta, target: [x,y,z], auto: true, autoSpeed: .07 },
speed: 1, seed: 7, fileName: 'my-scene', shadowSize: 28,
});
app.M.grass | dirt | stone | sand | planks | roof | log | leaves | glass | water | ice | snow | cobble | brick | lava
VK.solid(0xff8800, { glow, opacity, noise, border }) // material de bloque de color
VK.block(app, 'planks' | material, x, y, z, { pop: true }) // malla única (moviéndose/apareciendo)
VK.instanced(app.scene, material, [[x,y,z], ...]) // bloques estáticos, una sola llamada de dibujo
const world = VK.island(app, { seed, radius: 18, flatRadius: 7.5, trees: 10, water: -1, snowLine })
// → world.groundTopAt(x, z), world.hAt(ix, iz)
VK.platform(app, { size: 16, top: .5, mat: 'stone', topMat: 'cobble' }) // suelo de estudio
const hero = VK.character(app, { ground: world.groundTopAt, position: [x,0,z], yaw, colors: { shirt:[r,g,b], hat: 0xf5c518 | null, ... } })
hero.goTo([[x,z], ...]) · hero.arrived · hero.face(x, z, dt) · hero.jump(v)
hero.pose = 'idle' | 'reach' (set hero.reach 0..1) | 'cheer' | 'panic' | 'wave'
hero.lookTarget = {x,y,z} | null
VK.standOutside(x, z, { halfX, halfZ, cx, cz }) // dónde pararse para trabajar en un bloque de una caja
VK.routeAround(from, to, { halfX, halfZ, cx, cz }) // puntos de ruta que rodean esa caja
VK.explode(app, meshes, { center, power, ground, onDone })
VK.torch(app, x, y, z) // la luz se vuelve más fuerte de noche
app.puff(position, material, n, power) · app.pop(mesh) · app.clearParticles()
app.onUpdate((dt, time) => { ... }) // dt ya escalado por speed; determinista en modo captura
app.rand() // aleatorio con semilla: úsalo en lugar de Math.random
app.status(html) · app.button({ label, key, toggle, on, onClick }) · app.standardButtons({ cycle })
app.start()
Reglas que mantienen las escenas correctas:
- Usa
app.rand()(con semilla), nuncaMath.random(), para que los renders sean repetibles. - Pon todo el movimiento en
app.onUpdateusandodt; nunca usessetTimeout/setIntervalpara animación (el modo captura se rompería). - Los bloques son 1×1×1 y centrados en coordenadas enteras; una columna de altura
htiene su superficie superior enh + 0.5. Un personaje se para engroundTopAt(x, z). - Escenario estático →
VK.instanced; cualquier cosa que se mueva, aparezca o explote →VK.block. - Recuentos grandes: mantén las mallas en movimiento por debajo de ~1500; más allá, anima un InstancedMesh.
Recetas
- Secuencia de construcción: haz un plan ordenado
[{type,x,y,z}](capa por capa, caminando por el perímetro; filas en serpentina para tejados). Para cada elemento: ruta astandOutside, establecepose='reach', genera en ~45% del alcance, siguiente. Verexamples/house-builder.html. - Explica física con bloques: mapea la cantidad a algo visible. Temperatura →
amplitud de vibración ∝ √T (equipartición); presión → colisiones de bloques; niveles de energía →
pisos de una torre; un campo → flechas de bloques; entropía → una pared ordenada que se reordena;
gravedad → pilas que se derrumban cuando no están soportadas. Muestra la variable de control con un
indicador voxel (el termómetro en
melting-crystal.html) en lugar de números en pantalla. - Transformaciones: cambia
mesh.material(agua ↔ hielo, piedra → lava), aplana conscale.y, desliza con una interpolación suavizada entre dos posiciones. - Átomos / moléculas: cubos
VK.solid(color)para partículas,glow: truepara electrones o fotones, cubos pequeños (mesh.scale.setScalar(.3)) para estelas. - Finales que hacen bucle: explota (
VK.explode) → reinicia, o congela + cámara lenta, o cae la noche (app.sky.cycle = true) con antorchas.
Exportar
Parámetros de URL (funcionan en cualquier página construida con el kit):
?clean ocultar interfaz · ?alpha fondo transparente (sin cielo, sin niebla) · ?seed=3 ·
?speed=2 · ?night · ?capture&fps=30 modo fotograma exacto usado por el renderizador.
Teclas: H ocultar interfaz · Space pausa · V grabación rápida WebM en tiempo real (funciona cuando
la página se abre desde un archivo local; las vistas previas alojadas pueden bloquear la descarga).
Vídeo fotograma exacto (preferido para edición):
pip install playwright && python3 -m playwright install chromium # una vez, también se necesita ffmpeg
python3 scripts/render.py scene.html --seconds 12 --fps 30 --out scene.mov # ProRes 422 HQ
python3 scripts/render.py scene.html --seconds 12 --alpha --out overlay.mov # ProRes 4444 con alfa
python3 scripts/render.py scene.html --size 1080x1920 --warmup 3 --out short.mp4 # H.264 vertical
python3 scripts/render.py scene.html --seconds 5 --out frames/ # solo fotogramas PNG
--warmup omite segundos de escena antes de grabar; --params "seed=3&night" añade parámetros
URL; --headed usa un navegador visible (GPU real, más rápido en la mayoría de portátiles). Con
--alpha la cámara sigue orbitando; establece camera: { auto: false } para una superposición estática.
Antes de entregar
- La página se abre sin errores de consola; el primer fotograma ya muestra el tema principal.
- El bucle funciona al menos dos veces (el reinicio limpia mallas, luces y partículas).
- El personaje nunca atraviesa paredes; nada flota a menos que sea intencionado.
- Para vídeo: renderizado con
?clean, tamaño/fps correctos, alfa comprobado si se solicitó. - Sin nombres, texturas ni personajes de juegos de terceros en ninguna parte (código, título, nombres de archivo).