Godot 4 kann seit Version 4.3 wieder zuverlässig in den Browser exportieren. Wer 2023 mit dem Web-Export gekämpft hat, sollte sich die aktuelle Version anschauen. Das Threading-Modell wurde überarbeitet, die Build-Größe ist gesunken, und auf modernen Browsern läuft die Performance brauchbar.
Dieser Artikel ist eine praktische Übersicht: was funktioniert, was nicht, und wie du den Web-Export sauber einrichtest.
Status quo: was geht in Godot 4.4+ wirklich
Der Web-Export von Godot kompiliert zu WebAssembly (WASM) und nutzt WebGL 2 als Renderer. In der aktuellen Stable (4.4) und Beta (4.7) sind die folgenden Punkte gelöst, die bis vor zwei Jahren noch Probleme gemacht haben:
- Threading. Godot nutzt jetzt SharedArrayBuffer mit den korrekten COOP/COEP-Headern. Das ist Pflicht, ohne entsprechend konfigurierten Server bricht der Export beim Start ab.
- Build-Größe. Ein leeres Godot-4.4-Projekt liefert ungefähr 35 MB komprimierter WASM-Code aus. Mit Asset-Pack-Stripping kannst du das auf etwa 25 MB reduzieren. Vergleiche das mit Unity WebGL bei rund 12-15 MB für ein Mini-Projekt: Godot ist größer, aber nicht mehr inakzeptabel.
- Audio. Web Audio funktioniert. Latenz liegt bei ~80-150 ms, was für die meisten Casual Games reicht. Für rhythmische Spiele bleibt es ein Kompromiss.
Was 2026 immer noch nicht klappt:
- 3D-Spiele mit komplexen Shadern. WebGL 2 ist nicht WebGPU. Wenn dein Spiel Compute Shader oder Forward+ Rendering nutzt, vergiss den Browser.
- Saves über Local Storage hinaus. Browser-Quotas sind unzuverlässig. Plan ein, dass Spielerdaten verloren gehen können.
- Mobile Browser auf iOS. Safari hat lange WASM-Probleme gehabt. Aktuell läuft es, aber Bug-Reports kommen häufiger als auf Desktop.
Die Server-Konfiguration: hier scheitern die meisten
Das größte Problem beim Web-Export ist nicht der Build, sondern das Hosting. Godot benötigt zwei spezifische HTTP-Header:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Ohne diese Header lädt der Browser keinen SharedArrayBuffer, und Godot bricht mit einem Threading-Fehler ab. Auf itch.io sind die Header standardmäßig gesetzt; auf einem eigenen Server musst du sie konfigurieren.
Für Nginx:
location /spiel/ {
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Opener-Policy same-origin;
}
Für Apache:
<Location "/spiel/">
Header set Cross-Origin-Embedder-Policy "require-corp"
Header set Cross-Origin-Opener-Policy "same-origin"
</Location>
GitHub Pages, Vercel und Netlify unterstützen diese Header über Konfigurationsdateien (_headers-Datei bzw. vercel.json). Cloudflare Pages braucht ein zusätzliches Worker-Skript.
Den Web-Export einrichten
Schritt 1: Im Godot-Editor unter Project > Export den Web-Export hinzufügen. Falls die Export-Templates fehlen, lade sie über Editor > Manage Export Templates herunter.
Schritt 2: Im Export-Dialog die folgenden Optionen prüfen:
- Variant: Threads (empfohlen). Singlethreaded läuft auch ohne COOP/COEP-Header, ist aber deutlich langsamer.
- VRAM Texture Compression: ETC2 für mobile Browser, BPTC/S3TC für Desktop. Beide aktivieren, wenn du beides bedienst.
- Custom HTML Shell: leer lassen, falls du keine eigene Shell hast. Die Default-Shell macht alles, was du brauchst.
Schritt 3: Export Project und einen Ordner wählen. Godot erzeugt fünf Dateien: index.html, index.js, index.wasm, index.pck (das Asset-Pack) und index.audio.worklet.js.
Schritt 4: Lokal testen mit einem CORS-fähigen Server. Der Python-Einzeiler reicht nicht, weil die Header fehlen. Stattdessen:
from http.server import SimpleHTTPRequestHandler, HTTPServer
class CrossOriginIsolatedHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
super().end_headers()
HTTPServer(('localhost', 8000), CrossOriginIsolatedHandler).serve_forever()
Speichern als serve.py, im Export-Ordner ausführen, dann http://localhost:8000 im Browser öffnen.
Performance-Tipps für den Browser
Der Browser ist nicht der Desktop. Was auf dem Editor mit 60 FPS läuft, kann im Browser auf 25 FPS einbrechen, wenn du nicht aufpasst.
1. Texturen reduzieren. WebGL 2 hat begrenzten VRAM auf mobilen Geräten. 4K-Texturen sind im Browser selten sinnvoll. Skaliere Assets auf 1024x1024 oder kleiner, wo möglich.
2. Polygon-Anzahl beobachten. Browser-WebGL ist langsamer als nativer OpenGL-Treiber. Eine 100.000-Polygon-Szene, die nativ flüssig läuft, ruckelt im Browser. Halte die sichtbare Polygon-Zahl unter 50.000.
3. Audio-Streams limitieren. Jeder gleichzeitig spielende AudioStreamPlayer kostet im Browser mehr als auf Desktop. Maximal 8-10 simultane Streams für Casual Games, weniger für Mobile.
4. _process minimieren. Jede Frame-Logik in _process kostet im Browser mehr. Nutze Signale für ereignisgesteuerte Logik statt jeden Frame zu pollen.
5. Pre-loading testen. Der Browser lädt das .pck-File komplett, bevor das Spiel startet. Bei 100 MB Assets sind das 30-60 Sekunden Wartezeit auf langsamen Verbindungen. Asset-Splitting via PCK Embedding kann helfen, ist aber mit Aufwand verbunden.
Hosting-Optionen im Vergleich
| Plattform | Setup | Bandbreite | Custom Domain | Preis |
|---|---|---|---|---|
| itch.io | 1 Klick | unbegrenzt | nein | gratis |
| GitHub Pages | mittel | 100 GB/Monat | ja | gratis |
| Vercel | mittel | 100 GB/Monat | ja | gratis Tier |
| Cloudflare Pages | hoch (Worker nötig) | unbegrenzt | ja | gratis Tier |
| Netlify | mittel | 100 GB/Monat | ja | gratis Tier |
| Eigener Server | hoch | je nach Provider | ja | variabel |
Für Game Jams und Demos: itch.io. Für eine eigene Marke mit Custom Domain und Analytics: Vercel oder Netlify. Für Produktion mit hohem Traffic: Cloudflare Pages, weil die Bandbreite nicht limitiert ist.
Fallstricke, die ich gesehen habe
iOS Safari Audio. iOS verlangt eine Nutzeraktion (Klick), bevor Audio abspielt. Wenn dein Spiel Audio im _ready() startet, hörst du auf iOS nichts. Workaround: einen "Start"-Button anzeigen, Audio erst nach dem Klick initialisieren.
Gamepad-Inputs. Der Browser-Gamepad-API ist standardisiert, aber Godot mappt nicht alle Buttons konsistent. Teste mit echten Controllern, nicht nur Tastatur-Emulation.
Memory Leaks. Lange Web-Sessions können Speicher leaken, weil die WASM-Heap nicht so aggressiv aufgeräumt wird wie der native Heap. Für Spiele unter 30 Minuten Spielzeit kein Problem; für Endless-Games solltest du den RAM-Verbrauch im DevTools-Performance-Tab überwachen.
WebGL-Kontext-Verlust. Bei Tab-Wechsel oder Mobile-Hintergrund kann der WebGL-Kontext verloren gehen. Godot fängt das in den meisten Fällen ab, aber Texturen müssen neu geladen werden. Plan ein paar Sekunden Reload-Pause ein.
Wann Web-Export sinnvoll ist und wann nicht
Sinnvoll:
- 2D-Casual-Games für Game Jams
- Demos und Trailer-Versionen, die direkt im Browser laufen
- Kleine Puzzle- und Strategiespiele
- Educational Games für den Schulkontext
Nicht sinnvoll:
- 3D-AAA-artige Projekte
- Spiele mit echten Multiplayer-Anforderungen (WebSockets gehen, aber Latenz ist höher)
- Große Open-World-Spiele
- Alles mit Compute-Shader-Bedarf
Fazit
Der Web-Export von Godot 4 ist 2026 brauchbar geworden, wenn du die Einschränkungen kennst. Die Server-Konfiguration ist die häufigste Fehlerquelle. Wenn du einmal saubere COOP/COEP-Header eingerichtet hast, wirst du nicht mehr daran scheitern.
Für Game Jams und Demos lohnt es sich. Für Vollpreis-Releases im Browser bist du wahrscheinlich besser bei Steam oder einem nativen Mobile-Build aufgehoben.
Wer mehr zur offiziellen Godot-Dokumentation auf Deutsch sucht, findet dort die meisten Web-Export-Themen ausführlich behandelt.
Top comments (0)