Communitygithub.com

Machine

Baue eine photorealistische, physikbasierte, interaktive 3D-Simulation jeder Maschine aus einer einzigen Zeile – plus einen 20–30 Sekunden Film.

Was ist Machine?

Machine ist ein Skill für KI-Coding-Agenten (wie Claude Code, Cursor, Codex), der aus einer kurzen textuellen Beschreibung sofort eine vollständige, interaktive 3D-Simulation in einer einzigen HTML-Datei generiert. Der Skill folgt einem rigorosen Produktions-Workflow: Recherche der realen Maschine (Maße, Teileliste, Physik, Betriebspunkt), Aufbau der Szene mit Three.js, Erstellung von geschlossenen Volumenkörpern, Zuweisung physikalisch korrekter PBR-Materialien (Metalle, Lacke, Glas) und Implementierung eines numerischen Lösers, der echte Kennzahlen (Schub, Drehmoment, Drehzahl, Wirkungsgrad) berechnet. Die Simulation bietet interaktive Modi wie Explosionszeichnung, Schnittansicht mit soliden Schnittflächen, Röntgenansicht, Beschriftung, Zeitlupenfunktion und eine „Break it“-Funktion, die das Versagen der Maschine basierend auf dem Solver simuliert. Der Skill unterstützt zudem die Aufnahme eines professionellen 28-Sekunden-Films mit Kamera-Keys und Musik aus der FreePD-Bibliothek. Das Ergebnis ist eine produktionsreife, eigenständige HTML-Datei, die von der Festplatte, einem statischen Host oder in einem iframe geöffnet werden kann.

Funktioniert mit✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/WU7475/skill-backup/tree/main/machine

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Machine Skill

Du baust eine Maschine so, wie ein Produktstudio sie fotografiert und ein Ingenieur sie erklärt: das echte Objekt in Originalgröße, mit echten Materialien, auf einer sauberen Studiobühne, betrieben mit echten Gleichungen. Eine Zeile Eingabe, eine HTML-Datei Ausgabe und ein Film in einem Befehl.

Die Ausgabe ist immer:

  1. <name>.html: eine einzige eigenständige Seite (three.js 0.170 von jsDelivr, das Kit inline eingefügt). Sie öffnet sich von der Festplatte, von jedem statischen Host oder in einem iframe.
  2. Ein Film: node scripts/record.mjs <name>.html out/<name>.mp4 --music freepd:<Kategorie>/<Name>.

Öffne zuerst examples/. Jedes Beispiel wurde aus der einen Zeile am oberen Rand seiner Seite erstellt. examples/turbofan.html ist die Referenz: lies sie vollständig durch, bevor du etwas schreibst.

Der Anspruch

Stell dir den Rahmen vor, den ein Zuschauer nach drei Sekunden sieht. Er muss bereits wie ein Studio-Produktfoto der echten Maschine aussehen: korrekte Silhouette und Proportionen, Metall, das wie Metall aussieht, ein weicher Schatten auf einem Papierboden, nichts schwebt, nichts schneidet, nichts ist Platzhalter. Dann bewegt es sich, und jede Zahl auf dem Bildschirm wird berechnet.

Ein Ergebnis ist nicht fertig, solange eines dieser Kriterien zutrifft:

  • ein Teil, das ein Mechaniker erwarten würde, fehlt (keine Brennstoffdüsen in einer Brennkammer, keine Hemmung in einer Uhr, keine Ventile in einem Motor)
  • etwas schwebt, durchdringt sich oder hat eine sichtbare Naht oder Lücke an einer Verbindung
  • ein Material sieht aus wie Plastik, obwohl es Metall sein sollte, oder alles ist einheitlich grau
  • eine Zahl auf dem Bildschirm ist eingegeben statt vom Solver berechnet
  • die Schnittansicht zeigt hohle Schalen anstelle von soliden Schnittflächen
  • der erste Bild des Films ist nicht schön

Arbeitsablauf

1. Recherchiere die reale Maschine (5 Minuten, kein Code)

Schreibe in einem Kommentarblock am Anfang des Maschinen-Skripts aus deinem Wissen (und dem Internet, falls vorhanden) Folgendes auf:

  • Die realen Maße in Metern der 5 bis 10 Teile, die die Silhouette definieren (ein Turbofan: Lüfterdurchmesser 2,85 m, Länge 4,9 m, Gondel max. Durchmesser 3,44 m).
  • Die Teileliste in Montagereihenfolge, jedes mit seinem Material. Ziel: 15 bis 40 benannte Teile; wiederholte Teile (Schaufeln, Zähne, Schrauben, Spulen) zählen einzeln.
  • Die Physik, die es zum Laufen bringt, als 3 bis 6 Gleichungen, die du tatsächlich berechnen wirst, mit reellen Konstanten und dem Betriebspunkt (ein Turbofan: Brayton-Kreisprozess, Start bei N1 100 %, OPR 42, T4 1.750 K, etwa 330 kN).
  • Die eine Zahl, die einen Zuschauer interessiert: der Held (Schub, Drehmoment, Schläge pro Stunde, Durchfluss, Leistung). Sie bekommt eine große Serifen-Anzeige und einen schmalen Balken.
  • Der Eingabewert, den ein Zuschauer steuern möchte: ein Schieberegler (Schub, Windgeschwindigkeit, Drehzahl, Pumpendrehzahl, Mahlgrad).
  • Der Bruch: das Versagen, vor dem sich ein Ingenieur fürchtet, und was der Solver als Folge berechnet (Abgebrochenes Fanblatt und die Unwuchtbelastung, Ventilflattern oberhalb der Drehzahlgrenze, eine blockierte Pumpe, Überdruck). Dies muss eine berechnete Konsequenz sein, keine Animation.

2. Erstelle die Seite aus der Vorlage

Kopiere kit/template.html nach <name>.html. Sie enthält die Import-Map (festgelegt auf [email protected]), die Schriftarten, einen markierten Block, in den das Kit eingefügt wird, und die vier Abschnitte, die du ausfüllst:

const { THREE, Lab, MAT, GEO, heatGlow, clamp, lerp, approach, fmt } = window.LabKit
const lab = new Lab({ prompt, no, title, sub, size, view, cut })   // 1. das Lab
// 2. die Teile      lab.mesh(GEO..., MAT..., { name, pos, explode, xray, count })
// 3. der Solver     lab.hero(...); lab.slider(...); lab.onTick((dt, lab) => { ... lab.setHero(...) })
// 4. Bruch, erklären, Film      lab.breakIt(...); lab.how(...); lab.autoFilm(...); lab.start()

Führe direkt nach dem Kopieren node <skill dir>/scripts/inline.mjs <name>.html aus: Es fügt das Kit in den markierten Block ein, sodass die Seite eine eigenständige Datei ist, wo immer sie sich befindet (die Vorlage src="../kit/lab-kit.js" wird nur innerhalb dieses Repos aufgelöst). Schreibe dann deine Maschine im zweiten Skriptblock.

3. Geometrie: reale Volumenkörper in Originalgröße

Arbeite in Metern im eigenen Koordinatensystem der Maschine, Y nach oben, der Boden bei y = 0, es sei denn, du setzt ground. Setze size auf die längste reale Abmessung; das Kit skaliert die Anzeige so, dass jede Maschine gleich auf der Bühne sitzt, und der Maßstabsbalken zeigt die echte Größe.

  • Runde Teile (Wellen, Scheiben, Gehäuse, Düsen, Kegel, Spinner, Kolben, Lünetten): GEO.lathe([[r, y], ...]) mit einem GESCHLOSSENEN Profil. Wände: GEO.shell(profil, dicke), Rohre: GEO.tube(rAußen, rInnen, h), abgeschrägte Scheiben: GEO.disc(r, h). Ecken bleiben scharf und Kurven werden automatisch glatt schattiert.
  • Schaufeln und Leitschaufeln: GEO.rotor({ count, axis, r0, r1, chord, thick, camber, twist, pitch, sweep }) baut echte gewölbte, verwundene Tragflächen (NACA-Dicke) als geschlossene Volumenkörper und ringt sie. Verwende [root, tip]-Arrays für chord, thick und camber.
  • Zahnräder: GEO.gear({ teeth, module, width, bore, helix, spokes, rim }). Setze zwei Zahnräder im Achsabstand (z1 + z2) * module / 2 und drehe sie im umgekehrten Zähnezahlverhältnis, um eine halbe Zahnbreite versetzt.
  • Rohre, Schläuche, Kabel: GEO.pipe(points, r) (geschlossen, gedeckelt). Verlege sie entlang der Struktur von Anschluss zu Anschluss, niemals durch ein Teil hindurch.
  • Verbindungselemente: GEO.bolts(n, R, size, h) an jedem Flansch. Federn: GEO.spring(R, wire, windungen, länge). Boxen: GEO.rbox(b, h, t, r) (immer abgerundet, niemals scharf). Platten mit Löchern: GEO.extrude(shape, tiefe).
  • Massen und Trägheiten ergeben sich aus der Geometrie: GEO.volume(geo) liefert Volumen und Schwerpunkt, multipliziere mit der realen Dichte.

Regeln, die es sauber halten:

  • Jedes Teil ist ein geschlossener Volumenkörper (Lathe-Profile geschlossen, Schalen mit Dicke, Rohre gedeckelt). Nur so kann die Schnittansicht solide Schnittflächen zeichnen. Offene Oberflächen erscheinen beim Schneiden hohl.
  • Nichts durchdringt sich sichtbar und nichts schwebt. Jedes Teil berührt das, was es hält (ein Flansch sitzt auf einer Fläche, eine Welle läuft in einem Lager, ein Pfosten erreicht den Boden). Überprüfe Verbindungen in Nahaufnahmen.
  • Detail, wo das Auge hinblickt: Schraubenkreise an Flanschen, Fasen, eine Lippe, ein Typenschild, Kraftstoffleitungen, ein Kabelbaum. Große ebene Flächen erhalten eine Naht, eine Bedienfeldlinie oder eine Textur-Oberfläche.
  • Gib der Maschine eine Basis: einen Ständer, eine Wiege, einen Sockel, eine Werkbank oder eine Halterung mit Füßen auf dem Boden. Maschinen schweben im echten Leben selten.
  • Budget: bis zu etwa 700k Dreiecke und 200 Meshes. Fasse wiederholte statische Teile mit GEO.merge / GEO.ring zusammen; halte bewegliche Gruppen getrennt.

4. Materialien: niemals nur ein Grau

Verwende MAT.*-Voreinstellungen; sie enthalten gemessene Reflexionsgrade, sodass Stahl, Titan, Aluminium, Messing und Kupfer nebeneinander unterschiedlich aussehen. Jede Voreinstellung akzeptiert Überschreibungen (color, roughness, clearcoat, jedes MeshPhysicalMaterial-Feld) und eine Oberfläche (Mikrorauigkeits-Textur: turned Ringe auf Drehteilen, brushed Streifen, cast Flecken, smudge, knurl).

VerwendungVoreinstellung
Wellen, Scheiben, bearbeitete TeileMAT.steel, MAT.stainless, MAT.chrome
Gehäuse, GussteileMAT.aluminium, MAT.castIron, MAT.steelDark
Schaufeln, Luft- und RaumfahrtMAT.titanium, MAT.inconel (+ heatGlow)
Beschläge, VerkabelungMAT.brass, MAT.copper, MAT.gold
Lackierte KarosserienMAT.paint({ color }), MAT.satin, MAT.anodised({ color })
PolymereMAT.plastic, MAT.rubber, MAT.carbon
Fenster, KristalleMAT.glass, MAT.sapphire, MAT.ruby, MAT.enamel
Licht, Flamme, heißes GasMAT.glow, heatGlow(material, kelvin)

Wähle eine Palette wie ein Industriedesigner: hauptsächlich Metalle und ein oder zwei lackierte Farben, höchstens ein Akzent. Heiße Teile glühen von der Temperatur des Solvers (material.userData.heat.value = T).

5. Der Solver: reelle Zahlen oder nichts

Schreibe eine kleine reine Funktion von der Eingabe und dem Zustand zu jeder Zahl, die du anzeigst, mit reellen Einheiten und reellen Konstanten. Integriere Dynamiken mit approach (Verzögerung erster Ordnung: Hochlauf, thermische Masse) oder rk4 (Federn, Hemmungen, Pendel). Treibe die Bewegung daraus ab: eine Drehzahl vom Solver dreht die Welle, ein Durchfluss vom Solver bewegt die Partikel, eine Temperatur erhitzt das Metall.

  • Ein Held: lab.hero({ label, unit, max }) dann lab.setHero(wert, { state, sub, bad }) jeden Tick. state besteht aus zwei oder drei Wörtern (Hochlauf, Start, gedrosselter Durchfluss). sub ist eine Zeile mit 2 oder 3 weiteren Zahlen.
  • Ein Schieberegler: lab.slider({ id, label, min, max, value, unit, ends }). Ein zweiter nur, wenn die Maschine ihn wirklich braucht.
  • Labels hängen an statischen Teilen an Punkten auf den Schnittebenen: lab.label(obj, 'HD-Turbine', { at: [x, y, z], value: () => '12.979 U/min' }).
  • lab.how(words, equations) füllt „Wie es berechnet wird“: das Modell in einfachen Worten und die Gleichungen wie im Code geschrieben. Sage, was vereinfacht wurde.
  • Wenn eine Bewegung zu schnell zum Sehen ist (ein Fan mit 2.700 U/min), zeige sie verlangsamt und sage dies in how („Drehung 1:60 dargestellt“). Verlangsame niemals die Zahlen.
  • Überprüfe den Betriebspunkt gegen den öffentlichen Wert, den du in Schritt 1 notiert hast. Wenn du um mehr als etwa 20 % abweichst, korrigiere das Modell, nicht die Zahl.

6. Strömung, Wärme und Effekte

  • lab.flow({ paths, count, length, color, parent }): Streifen, die entlang von Pfaden reiten, die du aus dem realen Strömungspfad baust (Luft durch einen Kanal, Blut durch eine Pumpe, Wasser durch einen Puck). Setze .speed vom Solver und .opacity von lab.state.cut, sodass sie in der Schnittansicht sichtbar sind. Färbe nach einer berechneten Größe (Temperatur, Druck).
  • lab.plume({ radius, length, dir, color: 'rocket' | 'jet', shocks }): ein Abgasstrahl mit Mach-Diamanten; setze .power vom Solver.
  • lab.sparks.emit(weltPos, n, geschwindigkeit) und lab.shed(mesh, v, w) für Brüche: Funken fallen mit Schwerkraft und prallen ab; ein abgetrenntes Teil wird zu einem starren Körper, der auf dem Boden landet.

7. Modi (das Kit erledigt sie; du richtest sie ein)

  • Explosion: Jeder lab.add/lab.mesh akzeptiert explode: [dx, dy, dz] im Rahmen des Elternobjekts (in Metern). Bewege Teile entlang ihrer Montageachse, äußere Hüllen am weitesten, und behalte den Kern an Ort und Stelle. Nichts sollte sich auf dem Weg nach draußen kreuzen.
  • Schnittansicht: cut: { a, b, center, reach } auf dem Lab. a und b sind die Richtungen des entfernten Bereichs: a = [0,0,1], b = [0,1,0] entfernt das Viertel in Richtung des Betrachters und nach oben (am besten für Teile mit einer Achse); b = a entfernt eine Hälfte. Schnittflächen werden automatisch für jeden geschlossenen Volumenkörper mit einer feinen Schraffur gezeichnet.
  • Röntgen: xray: 'shell' auf äußeren Gehäusen macht sie zu Glas mit feinen Kanten, sodass der Kern während des Betriebs sichtbar bleibt.
  • Zeitlupe, Beschriftungen, Pause sind kostenlos (Tasten S, L, Leertaste). Die interaktiven Teile sind Maus-Orbit, der Schieberegler und die Schaltflächen.
  • Break it: lab.breakIt({ label, run(lab), reset(lab) }). run ändert den Solver-Zustand (ein Blatt gelöst, ein Ventil klemmt, eine Dichtung geplatzt) und der Solver berechnet die Konsequenz. Zeige es im Helden (bad: true) und mit Funken, Trümmern oder Erschütterung.

8. Betrachte es wie ein Kritiker (erforderlich)

Rendere und LESE jedes Bild, das du erstellst. Verwende die Skripte:

node scripts/shot.mjs <name>.html out/review.png                               # der erste Blick
node scripts/shot.mjs <name>.html out/cut.png --js "lab.toggle('cut', true); lab.toggle('labels', true)"
node scripts/shot.mjs <name>.html out/near.png --js "lab.setView({ az: 70, el: 8, dist: 0.8, target: [x, y, z] })"
node scripts/shot.mjs <name>.html out/film --film 1,4,8,12,17,22,26                 # Film-Stills

Mache mindestens vier Überprüfungsrunden. In jeder: Gesamtansicht, Schnittansicht mit Beschriftungen, Explosionsansicht, zwei Nahaufnahmen von Verbindungen und die Film-Stills. Vergleiche mit echten Produktfotos der Maschine in deiner Erinnerung: Proportionen, Teileanzahl, Materialien, wie Licht darauf fällt. Liste auf, was falsch ist, korrigiere es, rendere erneut. Höre erst auf, wenn die Liste leer ist. Das Shot-Skript gibt fps, Teileanzahl und Dreiecke aus; halte interaktive Bildraten über 30.

9. Der Film

lab.autoFilm({ runBeat, runSub, breakBeat, breakSub, sliderTo }) schreibt die standardmäßige 28-Sekunden-Geschichte aus deiner Maschine, in nummerierten Beats mit den redaktionellen Untertiteln:

  1. Ein Satz ist die gesamte Kurzbeschreibung (die Eingabezeile tippt sich selbst ein).
  2. Claude baut die Maschine (Teile fliegen in Montagereihenfolge ein, während der Zähler steigt: „84 von 3.597 Teilen“).
  3. Sie läuft (ein Cursor zieht den Schieberegler; die Heldenzahl steigt vom Solver).
  4. Schneide sie auf (Schnittkappen, Beschriftungen mit Live-Werten).
  5. Nimm sie auseinander (Explosionsansicht).
  6. Zerstöre sie (der Cursor klickt auf die Break-Schaltfläche; der Solver entscheidet, was versagt).

Es wiederholt sich: Die letzte Kamera-Position kehrt zur ersten zurück. Für einen benutzerdefinierten Film verwende lab.film('name', { len, assemble, shots, events }): Shots sind Kamera-Positionen { t, az, el, dist, target, fov }, Events sind { t, beat: ['07', 'Fetter Satz.', 'Grauer Satz.'], set: { cut: 1 }, slider: { id, to, dur }, cursor: { to: 'slider:id:0.8' | 'button:break' | [x, y], click: true }, do(lab) {} }.

Aufnahme (benötigt Node 18+, Playwright mit Chromium, ffmpeg):

node scripts/record.mjs <name>.html out/<name>.mp4 --music freepd:Classical/Easy_Lemon
node scripts/record.mjs <name>.html out/<name>-portrait.mp4 --w 1080 --h 1350

Die Seite läuft im Filmmodus (?film=1): Ihre Uhr bewegt sich nur, wenn der Rekorder sie schrittweise weiterschaltet, sodass jedes Bild vollständig und der Film bei jeder Aufnahme identisch ist. Der Rekorder schützt jeden Screenshot vor den magentafarbenen Bildern, die ein hängengebliebener GPU im Headless-Modus zurückgeben kann, und scannt den fertigen Film; er beendet sich mit einem Fehler, wenn ein Bild rosa ist. Musik von FreePD ist CC0; nenne den Track trotzdem.

Schreiben auf dem Bildschirm

Die Seite ist redaktionell, kein Dashboard: eine Eingabezeile, ein Serifen-Titel mit einem kursiven Untertitel, eine riesige Zahl mit kursiven Einheiten und einem schmalen Balken, eine Zeile mit unterstützenden Zahlen, ein Schieberegler. Schreibe wie eine gute Bildunterschrift: kurz, konkret, ohne Übertreibung, reale Einheiten mit Leerzeichen (338 kN, 1.750 K, 4.2 L/min), Tausender getrennt. Beat-Untertitel bestehen aus einem fetten Satz und einem grauen Satz.

Was du sagen solltest, wenn du es übergibst

Gib den Pfad der HTML-Datei an, den Filmbefehl, den Betriebspunkt, den der Solver im Vergleich zum öffentlichen Wert erreicht, und alles, was du vereinfacht hast. Biete die nächste Maschine an.

Verwandte Skills