Warum diese Engine
Keine Funktionsliste — die Handvoll Entscheidungen, die verändern, was Sie bauen können, und warum sie in der Praxis zählen.
Ein Modell, überall
Editor, Web-Player, Handy-App und Server führen dieselbe Szene aus: dieselben Objekte, dieselben Komponenten, dasselbe Verhalten.
Es gibt keinen Exportschritt, kein eigenes „Laufzeitformat", keine zweite Implementierung, die von der ersten abdriften könnte. Was Sie im Editor arrangiert haben, ist das, was läuft, und ein Fehler, den Sie im Player sehen, ist überall reproduzierbar.
Die praktische Folge ist langweilig und wertvoll: Dinge ändern beim Veröffentlichen nicht ihre Bedeutung.
Graphen werden zu Code, nicht zu einem Interpreter
In den meisten Werkzeugen ist ein visueller Graph Daten, die zur Laufzeit etwas Knoten für Knoten abläuft, in jedem Bild. Hier wird er einmal in ein gewöhnliches Skript kompiliert, und dieses Skript ist das, was läuft.
| Geschwindigkeit | ein Graph kostet so viel wie handgeschriebener Code, weil er Code ist |
| Einsehbar | öffnen Sie das Code-Panel und lesen Sie genau, was aus Ihrem Graphen wurde |
| Kombinierbar | ein Graph kann ein Skript aufrufen und ein Skript einen Graphen, weil beide darunter dasselbe sind |
Es gibt also keine Decke, an der Sie das visuelle Werkzeug aufgeben und in Code neu schreiben müssten. Sie legen ein Skript neben den Graphen, den Sie schon haben.
Materialien sind Graphen bis nach unten
Die eingebauten Materialtypen sind kein fester Satz mit angeschraubtem Knoteneditor. Sie sind Punkte innerhalb desselben Systems, das ein eigener Graph benutzt — ein Graph-Material ist also nicht langsamer, kein Bürger zweiter Klasse und nicht aufs Web beschränkt: Derselbe Graph kompiliert für den Browser und für den nativen Renderer auf einem Telefon.
Und was Sie nicht benutzen, kostet nichts. Physikalische Extras auf ihren Voreinstellungen werden beim Kompilieren weggefaltet, ein Material mit der Option Glas ist also genau so billig wie eines ohne.
Es funktioniert wie eine Tabellenkalkulation
Das ist die Entscheidung, auf der alles andere ruht, und am leichtesten über eine Analogie zu erklären.
In einer Tabelle ändern Sie eine Zelle, und nur die Formeln, die diese Zelle benutzen, rechnen neu. Niemand rechnet das ganze Blatt neu, und Sie drücken nie einen „Aktualisieren"-Knopf.
Die Szene arbeitet genau so. Ändern Sie die Farbe eines Objekts, reagiert nur, was die Farbe gelesen hat. Nicht das Objekt — die Farbe.
Änderung material.color
│
├─ der Renderer streicht diese Fläche neu
├─ das Inspektorfeld, das sie zeigt, aktualisiert sich
├─ die Änderung wird für Ihre Mitarbeitenden eingereiht
└─ …und sonst läuft überhaupt nichts
Was Ihnen das bringt
Nichts pollt und nichts rendert vorsorglich neu. Es gibt keinen Durchgang pro Bild, der die Welt mit einer Kopie ihrer selbst vergleicht, um zu finden, was sich bewegt hat. Ein Bild erledigt die Arbeit, die Änderungen verlangen, und eine stillstehende Szene kostet fast nichts.
Große Szenen bleiben beim Bearbeiten reaktionsschnell. Eine Timeline mit zwanzigtausend Keyframes zeichnet sich nicht neu, weil einer davon verschoben wurde: Ein Panel kann von „die Keyframes haben sich geändert" abhängen, ohne jeden einzelnen zu abonnieren. Genau dieser Unterschied hält große Projekte benutzbar.
Laden braucht keinen Ladecode. Ein System fragt nach einer Ressource und bekommt nichts zurück, wenn sie nicht da ist; trifft sie ein, läuft das System einfach erneut. Niemand schreibt Callbacks, pollt ein Bereitschafts-Flag oder behandelt den Fall „noch nicht geladen" zweimal.
Ein Änderungsstrom speist alles. Renderer, Inspektor, Rückgängig, Ihre Mitarbeitenden, die Skript-Sandbox und die Physiksimulation lesen dieselben Updates — deshalb können sie nicht auseinanderdriften oder sich darüber streiten, was die Szene enthält. Rückgängig ist kein Sonderweg; es ist eine weitere Änderung durch dieselbe Leitung.
Sie können nicht vergessen, es der Engine zu sagen. Kein „dirty markieren", kein „refresh", keine manuelle Invalidierung, an die man denken müsste. Den Wert zu schreiben ist die Benachrichtigung.
Einen Wert zu aktualisieren verschmilzt mit dem, was schon da ist, statt es zu ersetzen — alles, was zusah, bleibt an derselben Sache hängen, der es zusah. Das klingt nach einem Implementierungsdetail; es ist der Unterschied zwischen flüssiger Animation und einer Bildrate, die mit wachsender Szene einbricht.
Es ist keine Framework-Funktion — es ist das Substrat
Die Reaktivität ist ein eigenes Paket, und dasselbe steht Ihnen offen. Ein Plugin-Panel, eine Komponenten-Erweiterung und der Inspektor des Editors selbst sind damit geschrieben, eine von Ihnen geschriebene Erweiterung aktualisiert sich also aus genau demselben Grund wie die eingebauten Panels.
import { signal, computed, effect, batch } from '@was/signals';
const score = signal(0);
const label = computed(() => `Score: ${score.value}`);
effect(() => render(label.value)); // läuft nur erneut, wenn sich der Punktestand bewegt
batch(() => { score.value += 1; score.value += 1; }); // ein Update, nicht zwei
Drei Eigenschaften lohnen die Benennung, weil die meisten reaktiven Systeme eine oder zwei davon haben:
| Feingranular | Abhängigkeiten werden pro gelesenem Wert verfolgt, nicht pro Komponente. Nichts rendert „sicherheitshalber" neu. |
| Tief | ein ganzer Objektbaum wird reaktiv, position.y zu beobachten heißt also nicht, das Objekt zu beobachten |
| Billig abhängig zu sein | Sie können davon abhängen, dass sich etwas geändert hat, ohne es zu lesen — das hält eine riesige Liste davon ab, neu zu rendern, wenn ein Eintrag sich bewegt |
Das letzte klingt nebensächlich und ist der Grund, warum eine Timeline mit zwanzigtausend Keyframes bearbeitbar bleibt.
Validierung, die Sie kein Bild kostet
Jede Komponente wird durch ein Schema beschrieben, und Schemata bedeuten normalerweise eine Steuer: Irgendetwas läuft zur Laufzeit eine Beschreibung ab, Feld für Feld, jedes Mal, wenn Daten eintreffen.
Hier wird das Schema einmal in Code für genau diese Form kompiliert. Es wird nichts abgelaufen. Der Unterschied ist nicht akademisch — gemessen mit dem eigenen Benchmark dieses Projekts:
| Parsen | Zum Bundle hinzu | |
|---|---|---|
| Die übliche Bibliothek (zod) | 94,7 ns pro Operation | +267 KB minifiziert, +61 KB gzip |
| Diese (svdt) | 5,0 ns pro Operation | nichts — sie ist schon da |
Etwa neunzehnmal schneller, und für Ihre Besucher nichts zusätzlich herunterzuladen.
Das zählt, weil Validierung hier kein seltenes Ereignis ist: Sie läuft bei jeder Änderung, die zwischen Editor, Skript-Sandbox, Physiksimulation und Ihren Mitarbeitenden die Grenze überquert. Ein Aufwand pro Feld, der vernachlässigbar aussieht, wird zum Animationsbudget, sobald er tausende Male pro Sekunde geschieht.
Es ist dasselbe Paket, das Ihr eigenes Plugin für seine eigenen Daten importieren kann. → Die gemeinsamen Pakete
Schwere Arbeit bleibt außerhalb des Bildes
Zwei Dinge, die eine Browserseite sonst ins Stocken bringen, sind davon weggezogen:
- Ihre Skripte laufen isoliert von der Seite, eine langsame Schleife kann das Rendern also nicht einfrieren.
- Physik läuft neben dem Bild statt darin.
Eine Szene bleibt reaktionsschnell, während sie beschäftigt ist, statt Bilder zu verlieren, sobald Ihre Logik interessant wird.
Die Runtime verweigert Arbeit, bis sie sie braucht
Das ist der Teil, der sich für Ihre Besucher als Ladezeit zeigt.
Physik startet nicht und wird nicht heruntergeladen, solange eine Szene sie nicht wirklich braucht. Kulisse ohne bewegliche Teile zahlt nie für den Simulator — das sind Megabyte, auf die Ihre Besucher nicht warten. Die Prüfung ist lebendig: Ein mitten in der Sitzung erzeugter Ball holt die Physik für sich selbst.
Zehntausend Kopien kosten ungefähr eine. Gras, Menschenmengen, Trümmer und Partikel zeichnen in einem einzigen Aufruf. Ihre Anordnung wird aus einem Seed erzeugt statt gespeichert, kostet also nichts in der Datei, nichts im Netz und sieht für jeden Teilnehmer identisch aus.
Nichts auf Partikelebene wird je synchronisiert. Dieselben Einstellungen erzeugen überall denselben Effekt, ein aufwendiger Effekt ist im Mehrspieler also gratis.
Ein Vokabular für Verhalten
Ereignisse, Patch-Graphen und Skripte hören dieselben Auslöser — on-click bedeutet in allen
dreien dasselbe. Sie lernen einen Satz Namen und wählen dann, wie viel Code Sie schreiben wollen.
Das heißt auch: Sie können eine Interaktion als Ereignis beginnen, sie zum Patch aufrüsten, wenn sie eine Bedingung braucht, und ins Skript wechseln, wenn sie echte Logik braucht — ohne irgendetwas neu zu lernen.
Für mehr als eine Person gebaut
Zusammenarbeit ist keine aufgesetzte Funktion: Ein Space ist eine lebendige Welt, die alle darin teilen, Änderungen erscheinen also, während sie passieren, und Rückgängig arbeitet pro Person.
Dieselbe Maschinerie synchronisiert Editor, Skript-Sandbox und Physiksimulation — deshalb können sie sich nicht darüber streiten, was die Szene enthält.
Es läuft dort, wo Ihr Publikum schon ist
Ein veröffentlichtes Projekt öffnet über einen Link, im Browser, ohne dass etwas installiert werden muss. Genau darum geht es bei WebAR: kein App Store, kein Download, kein „bitte installieren Sie erst unsere App" zwischen Ihrem Besucher und dem, was Sie gemacht haben.
Von dort aus reicht dasselbe Projekt weiter, ohne neu gebaut zu werden:
| Wo | Wie es dorthin kommt |
|---|---|
| Jeder Handy-Browser | der veröffentlichte Link oder ein QR-Code — nichts zu installieren |
| iOS App Clip | öffnet über Link, QR-Code oder NFC, ohne App-Store-Installation |
| Die native App | ein nativer Renderer — siehe unten |
| Headset-Browser | derselbe veröffentlichte Link — die Runtime spricht WebXR |
| AR-Brillen und Headsets | eine native XR-Schicht für XREAL One, Quest 3 und PICO 4 — siehe unten |
| Headsets über Unity | das Unity SDK — XREAL, PICO, Apple Vision Pro, HoloLens 2, Magic Leap 2, Rokid |
Jemand richtet eine Kamera auf einen Code, und Ihr Erlebnis öffnet sich — kein Store, kein Konto, kein Warten. Apple begrenzt, wie groß ein Clip sein darf, halten Sie also die erste Szene leicht und laden Sie den Rest nach, sobald sie läuft.
Telefone funktionieren out of the box. Die gerätespezifischen Pakete — Render-Pipelines, Controller-Profile, Deployment-Vorlagen — werden pro Konto freigegeben. → Plattformunterstützung
Auf dem Telefon: native Rendergeschwindigkeit
Im Browser bekommen Sie WebGL — schnell, mit einer Decke. Die native App rendert überhaupt nicht über einen Browser: Sie benutzt auf iOS wie auf Android einen nativen Renderer, der direkt mit Metal und Vulkan spricht.
Dasselbe Projekt bekommt also das Grafikbudget einer nativen App — Echtzeitschatten, schwerere Materialien, mehr auf dem Bildschirm — ohne dass Sie eine zweite Version pflegen. Ihre Materialien kompilieren für diesen Renderer ebenso wie fürs Web, und genau das macht „dasselbe Projekt" wahr statt bloß erstrebenswert.
Nehmen Sie den Web-Build für Reichweite und die App für die Projekte, die das Bildbudget brauchen.
Brillen, nativ
Eine native XR-Schicht bringt die AR-Clip-Runtime selbst auf Brillen: dasselbe Projekt, dieselbe Szene, auf dem Gerät gerendert statt im Browser.
Sie ist als eine Schnittstelle mit austauschbaren Hersteller-Backends gebaut, ein Gerät ist also ein Backend und kein Fork der Runtime — und es geht nicht über Unity:
| Gerät | Über | Was dort funktioniert |
|---|---|---|
| XREAL One | das Hersteller-SDK | Anzeige, Kopf-Tracking, Kamera, Sitzungsaufzeichnung |
| Meta Quest 3 | OpenXR | Anzeige, Tracking, Controller, Hand-Tracking, Sitzungsaufzeichnung |
| PICO 4 | OpenXR | dasselbe, mit abgeschalteter Kamera |
Ein Backend erklärt, was es tatsächlich unterstützt, statt so zu tun. PICO hat hier keinen Kamera-Durchblick, eine Szene, die die echte Welt dahinter braucht, gehört also auf XREAL oder Quest; eine, die das nicht braucht, läuft auf allen dreien.
Über welchen davon ein Besucher auch kommt, es ist dieselbe Szene mit denselben Komponenten und demselben Verhalten. Sie pflegen keine Web-Version und keine Headset-Version.
Und es ist dort erweiterbar, wo es zählt
Eigene Schritte und Auslöser lassen sich aus einer Anwendung registrieren. Der Editor nimmt Plugins an, die Panels hinzufügen, Szenen erzeugen oder ganz neue Arten von Komponenten beisteuern. Der Knotenkatalog hat eine Notluke für den einen Fall, den er nicht abdeckt.
Jede Tabelle von Komponenten, Auslösern, Schritten und Knoten auf dieser Site wird aus der Engine selbst erzeugt. Bekommt die Engine einen Knoten, bekommt die Referenz eine Zeile — niemand muss daran denken, sie zu aktualisieren.
Weiter: Objekte und Szenen — das Modell vollständig.