Voxel-Animationen
Erstelle Szenen, die wie ein Blockbau-Spiel aussehen, ohne etwas davon zu verwenden: Jede Textur wird zur Laufzeit im Code generiert, und der Charakter ist ein Originaldesign. Die Ausgabe ist eine einzige, eigenständige HTML-Seite (interaktiv, teilbar) und, wenn gewünscht, ein bildgenaues Video, das von derselben Seite gerendert wird.
Dateien in diesem Skill
assets/voxel-kit.js: das Kit (Texturen, Materialien, App-Loop, Orbit-Kamera, Himmel mit Tag/Nacht, Inselgelände, Studio-Plattform, Charakter-Rig, Partikel, Einblenden, Explodieren, Fackeln, Routing-Hilfen, Rekorder, Aufnahmemodus). Lies es, bevor du eine Szene schreibst: Die API-Referenz unten ist eine Zusammenfassung, die Datei ist die Wahrheit.assets/template.html: Startseite mit dem Kit-Marker, Insel, Charakter und einer winzigen Zeitleiste.examples/house-builder.html: Ein Bauarbeiter platziert ein Haus Block für Block, jubelt, es explodiert, Schleife.examples/melting-crystal.html: Physik-Beispiel (Lindemann-Schmelzen eines 6×6×6-Eisgitters, mit einem Voxel-Thermometer, Pfütze und Wiedergefrieren). Kopiere seine Struktur für Wissenschaftserklärer.scripts/inline_kit.py: Ersetzt<!-- VOXEL_KIT -->in einer Seite durch das Kit, ergibt eine Datei.scripts/render.py: Bildgenaues Rendern zu PNG-Frames und.mov/.mp4/.webm.
Wenn nur diese SKILL.md verfügbar ist (der Ordner fehlt), hole dir das vollständige Skill von https://github.com/normix93/voxel-animations, bevor du baust.
Arbeitsablauf
- Die Idee in einem Satz festlegen: Was wird gebaut, umgewandelt oder erklärt, und wie endet die Schleife (zurücksetzen, explodieren, einfrieren, Kamera ausfliegen). Entscheide das Ziel: interaktive Seite, Video für die Bearbeitung (transparenter Hintergrund oder nicht), vertikaler Short (1080×1920).
- Storyboard als Zeitleiste: 3–6 Takte mit Dauern, z. B.
0–2 s leere Baustelle → 2–40 s bauen → 40–44 s jubeln → 44–49 s explodieren → Schleife. Jeder Takt ist einmodein einemapp.onUpdate-Zustandsautomaten (siehe Haus-Beispiel). - Starte von
assets/template.html, behalte den Kit-Marker, schreibe den SCENE-Abschnitt. Verwende Kit-Teile wieder, anstatt sie neu zu schreiben. Halte alles in einer Seite. - Erstelle die Seite:
python3 scripts/inline_kit.py scene.src.html scene.html. - Überprüfe sie: Öffne sie (oder rendere ein paar Frames mit
render.pyin einen Ordner und sieh sie dir an). Achte auf: schwebende oder überlappende Blöcke, Charakter, der durch Wände geht, Kamera, die in Bäume eintaucht, leere erste Sekunden, Flimmern bei transparenten Blöcken. - Ausliefern: Veröffentliche die Seite als Artefakt, wenn die Umgebung dies unterstützt, und übergib zusätzlich die .html-Datei; rendere das Video, wenn gewünscht (siehe Export).
Stilregeln
- Nur Originale. Verwende niemals Texturen, Sounds, Logos, Mobs, Charaktere oder Namen aus einem bestehenden Spiel. Nenne die Ausgabe nicht "Minecraft" oder ähnlich: sage Voxel, blockartig, Blockwelt. Die prozeduralen Texturen und der Bauarbeiter mit Helm im Kit sind sicher zu verwenden und zu modifizieren.
- Pixel-scharf: 16×16-Texturen mit
NearestFilter(das Kit erledigt das). Hartes Licht, klare Schatten, wenige Farben pro Material, wenig Rauschen. - Bewegung hat Gewicht: Blöcke erscheinen mit Überschwinger (
app.pop), Trümmer nutzen Schwerkraft (≈20–22 Blöcke/s²) und gedämpfte Sprünge, der Charakter läuft mit ~5 Blöcken/s und dreht sich geschmeidig. Vermeide lineare Tweens für alles Physische. - Auf einen Blick lesbar: ein Hauptmotiv in der Mitte, Kamera langsam orbitierend
(
autoSpeed0.05–0.1), ruhiger Hintergrund (Himmel oderstudio-Farbe). - Text: Die Seite kann einen Titel und eine Statuszeile haben. Für Video mit
?cleanrendern (keine UI). Wenn im Video Beschriftungen nötig sind, verwende sehr kurze Wörter; Erklärungen gehören in den Kommentar oder die Seite, nicht auf die Frames.
Kit-API (Zusammenfassung)
const app = VK.createApp({
title, subtitle, hint, // UI-Text (versteckt mit ?clean oder Taste H)
sky: 'day' | 'night' | 'studio', // studio = flache Farbe (studioColor), kein Nebel
cycle: false, dayLength: 48, tod: .27, // Tageszeit 0..1 (.25 Sonnenaufgangsseite, .75 Nacht)
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 }) // farbiger Pixel-Block-Material
VK.block(app, 'planks' | material, x, y, z, { pop: true }) // einzelnes Mesh (bewegend/einblendend)
VK.instanced(app.scene, material, [[x,y,z], ...]) // statische Blöcke, ein Zeichenaufruf
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' }) // Studioboden
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' (setze hero.reach 0..1) | 'cheer' | 'panic' | 'wave'
hero.lookTarget = {x,y,z} | null
VK.standOutside(x, z, { halfX, halfZ, cx, cz }) // wo stehen, um an einem Block einer Kiste zu arbeiten
VK.routeAround(from, to, { halfX, halfZ, cx, cz }) // Wegpunkte, die um diese Kiste herumgehen
VK.explode(app, meshes, { center, power, ground, onDone })
VK.torch(app, x, y, z) // Licht wird nachts stärker
app.puff(position, material, n, power) · app.pop(mesh) · app.clearParticles()
app.onUpdate((dt, time) => { ... }) // dt bereits skaliert mit speed; deterministisch im Aufnahmemodus
app.rand() // gesäter Zufall: verwende ihn statt Math.random
app.status(html) · app.button({ label, key, toggle, on, onClick }) · app.standardButtons({ cycle })
app.start()
Regeln, die Szenen korrekt halten:
- Verwende
app.rand()(gesät), niemalsMath.random(), damit Renderings wiederholbar sind. - Setze alle Bewegungen in
app.onUpdatemitdt; verwende niemalssetTimeout/setIntervalfür Animationen (der Aufnahmemodus würde kaputtgehen). - Blöcke sind 1×1×1 und auf ganzzahligen Koordinaten zentriert; eine Säule der Höhe
hhat ihre obere Oberfläche beih + 0.5. Ein Charakter steht beigroundTopAt(x, z). - Statische Landschaft →
VK.instanced; alles, was sich bewegt, einblendet oder explodiert →VK.block. - Große Anzahlen: Halte bewegliche Meshes unter ~1500; darüber hinaus animiere ein InstancedMesh.
Rezepte
- Bausequenz: Erstelle einen geordneten Plan
[{type,x,y,z}](Schicht für Schicht, entlang des Umfangs gehend; Serpentinenreihen für Dächer). Für jedes Element: Routen zustandOutside, setzepose='reach', spawnen bei ~45% der Reichweite, weiter. Sieheexamples/house-builder.html. - Physik mit Blöcken erklären: Bilde die Größe auf etwas Sichtbares ab. Temperatur →
Zitteramplitude ∝ √T (Äquipartition); Druck → Blockkollisionen; Energieniveaus → Stockwerke eines Turms;
ein Feld → Pfeile aus Blöcken; Entropie → eine geordnete Wand, die neu gemischt wird;
Schwerkraft → Stapel, die umkippen, wenn sie nicht gestützt werden. Zeige die Kontrollvariable mit einer Voxel-Anzeige
(das Thermometer in
melting-crystal.html) anstatt Zahlen auf dem Bildschirm. - Transformationen: Ändere
mesh.material(Wasser ↔ Eis, Stein → Lava), flachdrücken mitscale.y, gleiten mit einer abgemilderten LERP zwischen zwei Positionen. - Atome / Moleküle:
VK.solid(farbe)-Würfel für Partikel,glow: truefür Elektronen oder Photonen, kleine Würfel (mesh.scale.setScalar(.3)) für Spuren. - Enden, die schleifen: explodieren (
VK.explode) → zurücksetzen, oder einfrieren + langsame Kamera, oder Nacht einbrechen lassen (app.sky.cycle = true) mit Fackeln.
Export
URL-Parameter (funktionieren auf jeder mit dem Kit erstellten Seite):
?clean UI verstecken · ?alpha transparenter Hintergrund (kein Himmel, kein Nebel) · ?seed=3 ·
?speed=2 · ?night · ?capture&fps=30 bildgenauer Modus, der vom Renderer verwendet wird.
Tasten: H UI verstecken · Space Pause · V schnelle Echtzeit-WebM-Aufnahme (funktioniert, wenn die
Seite von einer lokalen Datei geöffnet wird; gehostete Vorschauen können den Download blockieren).
Bildgenaues Video (bevorzugt für die Bearbeitung):
pip install playwright && python3 -m playwright install chromium # einmal, ffmpeg wird auch benötigt
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 mit Alpha
python3 scripts/render.py scene.html --size 1080x1920 --warmup 3 --out short.mp4 # vertikal H.264
python3 scripts/render.py scene.html --seconds 5 --out frames/ # nur PNG-Frames
--warmup überspringt Szenensekunden vor der Aufnahme; --params "seed=3&night" fügt URL-Parameter
hinzu; --headed verwendet einen sichtbaren Browser (echte GPU, auf den meisten Laptops schneller). Mit
--alpha orbitiert die Kamera weiter; setze camera: { auto: false } für ein statisches Overlay.
Vor der Auslieferung
- Seite öffnet sich ohne Konsolenfehler; erstes Frame zeigt bereits das Motiv.
- Schleife funktioniert mindestens zweimal (Reset löscht Meshes, Lichter und Partikel).
- Charakter durchquert niemals Wände; nichts schwebt, es sei denn, es ist beabsichtigt.
- Für Video: gerendert mit
?clean, richtige Größe/Bildrate, Alpha überprüft, falls angefordert. - Keine Namen, Texturen oder Charaktere von Drittanbieter-Spielen irgendwo (Code, Titel, Dateinamen).