Animations voxel
Créez des scènes qui ressemblent à un jeu de construction en blocs, sans rien utiliser de tel : chaque texture est générée dans le code à l'exécution et le personnage est un design original. Le résultat est une page HTML autonome (interactive, partageable) et, sur demande, une vidéo image par image rendue à partir de cette même page.
Fichiers de ce skill
assets/voxel-kit.js: la boîte à outils (textures, matériaux, boucle d'application, caméra orbitale, ciel jour/nuit, terrain en île, plateforme de studio, squelette du personnage, particules, apparition, explosion, torches, helpers de routage, enregistreur, mode capture). Lisez-le avant d'écrire une scène : la référence API ci-dessous est un résumé, le fichier est la vérité.assets/template.html: page de départ avec le marqueur de la boîte à outils, l'île, le personnage et une minuscule timeline.examples/house-builder.html: un constructeur place une maison bloc par bloc, applaudissements, explosion, puis boucle.examples/melting-crystal.html: exemple de physique (fusion de Lindemann d'un réseau de glace 6×6×6, avec un thermomètre voxel, une flaque et une re-congélation). Copiez sa structure pour des explications scientifiques.scripts/inline_kit.py: remplace<!-- VOXEL_KIT -->dans une page par la boîte à outils, produisant un seul fichier.scripts/render.py: rendu image par image en PNG et.mov/.mp4/.webm.
Si seul ce SKILL.md est disponible (le dossier manque), récupérez le skill complet sur https://github.com/normix93/voxel-animations avant de construire.
Flux de travail
- Fixez l'idée en une ligne : ce qui est construit, transformé ou expliqué, et comment la boucle se termine (réinitialisation, explosion, gel, sortie caméra). Décidez le support : page interactive, vidéo pour montage (fond transparent ou non), court métrage vertical (1080×1920).
- Storyboard en timeline : 3 à 6 temps avec durées, par ex.
0–2 s site vide → 2–40 s construction → 40–44 s applaudissements → 44–49 s explosion → boucle. Chaque temps est unmodedans une machine d'étatapp.onUpdate(voir l'exemple house). - Partez de
assets/template.html, gardez le marqueur de la boîte à outils, écrivez la section SCÈNE. Réutilisez les morceaux de la boîte au lieu de les réécrire. Gardez tout dans une seule page. - Construisez la page :
python3 scripts/inline_kit.py scene.src.html scene.html. - Vérifiez-la : ouvrez-la (ou rendez quelques images avec
render.pydans un dossier et regardez-les). Cherchez : des blocs qui flottent ou se chevauchent, le personnage qui traverse les murs, la caméra qui s'encastre dans les arbres, les premières secondes vides, des scintillements sur les blocs transparents. - Livrez : publiez la page comme artefact si l'environnement le permet et transmettez également le fichier .html ; rendez la vidéo si demandé (voir Export).
Règles de style
- Original uniquement. N'utilisez jamais de textures, sons, logos, mobs, personnages ou noms provenant d'un jeu existant. N'appelez pas le résultat "Minecraft" ou assimilé : dites voxel, bloc, monde de blocs. Les textures procédurales et le constructeur au casque du kit peuvent être utilisés et modifiés en toute sécurité.
- Pixel-crisp : textures 16×16 avec
NearestFilter(le kit le fait). Lumière dure, ombres nettes, peu de couleurs par matériau, faible bruit. - Le mouvement a du poids : les blocs apparaissent avec dépassement (
app.pop), les débris utilisent la gravité (≈20–22 blocs/s²) et des rebonds amortis, le personnage marche à ~5 blocs/s et tourne en douceur. Évitez les interpolations linéaires pour tout ce qui est physique. - Lisible d'un coup d'œil : un sujet principal au centre, la caméra orbite lentement (
autoSpeed0.05–0.1), fond calme (ciel ou couleurstudio). - Texte : la page peut avoir un titre et une ligne de statut. Pour la vidéo, rendez avec
?clean(pas d'interface). Si des étiquettes sont nécessaires dans la vidéo, utilisez des mots très courts ; les explications appartiennent à la narration ou à la page, pas aux images.
API du kit (résumé)
const app = VK.createApp({
title, subtitle, hint, // Texte de l'interface (caché par ?clean ou touche H)
sky: 'day' | 'night' | 'studio', // studio = couleur unie (studioColor), pas de brouillard
cycle: false, dayLength: 48, tod: .27, // heure du jour 0..1 (.25 lever du soleil côté, .75 nuit)
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 }) // matériau de bloc coloré pixel
VK.block(app, 'planks' | material, x, y, z, { pop: true }) // maillage unique (mobile/apparaissant)
VK.instanced(app.scene, material, [[x,y,z], ...]) // blocs statiques, un appel de dessin
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' }) // sol de studio
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 }) // où se tenir pour travailler sur un bloc d'une boîte
VK.routeAround(from, to, { halfX, halfZ, cx, cz }) // waypoints qui contournent cette boîte
VK.explode(app, meshes, { center, power, ground, onDone })
VK.torch(app, x, y, z) // la lumière devient plus forte la nuit
app.puff(position, material, n, power) · app.pop(mesh) · app.clearParticles()
app.onUpdate((dt, time) => { ... }) // dt déjà mis à l'échelle par speed ; déterministe en mode capture
app.rand() // aléatoire à graine : utilisez-le au lieu de Math.random
app.status(html) · app.button({ label, key, toggle, on, onClick }) · app.standardButtons({ cycle })
app.start()
Règles qui gardent les scènes correctes :
- Utilisez
app.rand()(à graine), jamaisMath.random(), pour que les rendus soient reproductibles. - Mettez tout le mouvement dans
app.onUpdateen utilisantdt; n'utilisez jamaissetTimeout/setIntervalpour l'animation (le mode capture serait cassé). - Les blocs font 1×1×1 et sont centrés sur des coordonnées entières ; une colonne de hauteur
ha sa surface supérieure àh + 0.5. Un personnage se tient àgroundTopAt(x, z). - Décors statiques →
VK.instanced; tout ce qui bouge, apparaît ou explose →VK.block. - Grands nombres : gardez les maillages mobiles sous ~1500 ; au-delà, animez un InstancedMesh.
Recettes
- Séquence de construction : faites un plan ordonné
[{type,x,y,z}](couche par couche, en longeant le périmètre ; rangées en serpentin pour les toits). Pour chaque élément : routez versstandOutside, mettezpose='reach', spawn à ~45% de la portée, suivant. Voirexamples/house-builder.html. - Expliquez la physique avec des blocs : associez la quantité à quelque chose de visible. Température → amplitude de gigue ∝ √T (équipartition) ; pression → collisions de blocs ; niveaux d'énergie → étages d'une tour ; champ → flèches de blocs ; entropie → mur ordonné remélangé ; gravité → piles qui s'effondrent sans support. Montrez la variable de contrôle avec un indicateur voxel (le thermomètre dans
melting-crystal.html) au lieu de chiffres à l'écran. - Transformations : changez
mesh.material(eau ↔ glace, pierre → lave), aplatissez avecscale.y, glissez avec une interpolation adoucie entre deux positions. - Atomes / molécules : cubes de
VK.solid(couleur)pour les particules,glow: truepour électrons ou photons, petits cubes (mesh.scale.setScalar(.3)) pour les traînées. - Finitions qui bouclent : explosez (
VK.explode) → réinitialisez, ou gelez + caméra lente, ou nuit qui tombe (app.sky.cycle = true) avec des torches.
Export
Paramètres d'URL (fonctionnent sur toute page construite avec le kit) :
?clean cache l'interface · ?alpha fond transparent (pas de ciel, pas de brouillard) · ?seed=3 ·
?speed=2 · ?night · ?capture&fps=30 mode image par image utilisé par le moteur de rendu.
Touches : H cache l'interface · Space pause · V enregistrement WebM rapide en temps réel (fonctionne quand la page est ouverte depuis un fichier local ; les prévisualisations hébergées peuvent bloquer le téléchargement).
Vidéo image par image (préférée pour le montage) :
pip install playwright && python3 -m playwright install chromium # une fois, ffmpeg aussi nécessaire
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 avec alpha
python3 scripts/render.py scene.html --size 1080x1920 --warmup 3 --out short.mp4 # vertical H.264
python3 scripts/render.py scene.html --seconds 5 --out frames/ # images PNG seulement
--warmup saute les secondes de scène avant l'enregistrement ; --params "seed=3&night" ajoute des paramètres d'URL ; --headed utilise un navigateur visible (vrai GPU, plus rapide sur la plupart des portables). Avec --alpha la caméra orbite toujours ; mettez camera: { auto: false } pour un calque statique.
Avant la livraison
- La page s'ouvre sans erreur de console ; la première image montre déjà le sujet.
- La boucle fonctionne au moins deux fois (la réinitialisation efface les maillages, lumières et particules).
- Le personnage ne traverse jamais les murs ; rien ne flotte sauf intentionnel.
- Pour la vidéo : rendue avec
?clean, bonne taille/fps, alpha vérifié si demandé. - Aucun nom, texture ou personnage de jeu tiers (code, titre, noms de fichiers).