DEV Community

Cover image for Godot 4 für Web-Spiele: Export, WASM und Browser-Performance
Ziva
Ziva

Posted on Edited on

Godot 4 für Web-Spiele: Export, WASM und Browser-Performance

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: Seit 4.3 exportiert Godot standardmäßig single-threaded, und dieser Export braucht keine speziellen Server-Header mehr.

Aktualisiert am 5. November 2026: Threading-, Header- und Hosting-Angaben korrigiert und mit Godot 4.7.2 nachgetestet. Die Messwerte unten stammen aus diesem Test.

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.7 wirklich

Der Web-Export von Godot kompiliert zu WebAssembly (WASM) und nutzt WebGL 2 mit dem Compatibility-Renderer. In der aktuellen Stable-Version (Godot 4.7) gilt:

  • Threading. Seit Godot 4.3 ist der Export standardmäßig single-threaded. Er braucht weder SharedArrayBuffer noch COOP/COEP-Header und läuft auf jedem normalen Webserver. Nur wer Thread Support oder Extensions Support einschaltet, braucht SharedArrayBuffer bzw. Cross-Origin-Isolation und damit die beiden Header (siehe unten).
  • Build-Größe. Unser Test mit Godot 4.7.2 und einem kleinen 2D-Spiel: index.wasm ist 39,5 MB groß, mit gzip 10,1 MB. Fast die ganze Größe ist die Engine selbst, nicht dein Spiel.
  • Audio. Web Audio funktioniert. Für rhythmische Spiele solltest du die Latenz im Browser selbst testen.

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. Ein Export mit eingeschaltetem Thread Support oder Extensions Support benötigt zwei spezifische HTTP-Header (der Standard-Export nicht):

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Enter fullscreen mode Exit fullscreen mode

Ohne diese Header lädt der Browser keinen SharedArrayBuffer, und ein Thread-Build zeigt beim Start: "The following features required to run Godot projects on the Web are missing: Cross-Origin Isolation ... SharedArrayBuffer ...". Auf itch.io sind die Header nicht standardmäßig gesetzt: Für Thread-Builds musst du in den Embed-Optionen die experimentelle Checkbox SharedArrayBuffer support aktivieren. 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;
}
Enter fullscreen mode Exit fullscreen mode

Für Apache:

<Location "/spiel/">
    Header set Cross-Origin-Embedder-Policy "require-corp"
    Header set Cross-Origin-Opener-Policy "same-origin"
</Location>
Enter fullscreen mode Exit fullscreen mode

Netlify und Cloudflare Pages setzen Header über eine _headers-Datei. Die GitHub-Pages-Doku für github.com beschreibt keine eigenen Header; dort nimmst du den Single-Thread-Export oder aktivierst im Export-Preset Progressive Web App mit Ensure Cross Origin Isolation Headers (standardmäßig an). Das nutzt einen Service Worker; in unserem Test lief das Spiel erst nach einem Neuladen.

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 > Thread Support: aus lassen (Standard seit 4.3). Die Godot-Doku nennt den Single-Thread-Export die bevorzugte Variante für das Web. Nur einschalten, wenn eine GDExtension Threads braucht.
  • 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 4.7.2 erzeugt neun Dateien: index.html, index.js, index.wasm, index.pck (das Asset-Pack), zwei Audio-Worklets und drei Icons.

Schritt 4: Lokal testen. Ein Doppelklick auf index.html funktioniert nicht (Fehler "Failed to fetch"). Für den Standard-Export reicht python3 -m http.server. Für einen Thread-Build brauchst du einen Server mit den beiden Headern:

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()
Enter fullscreen mode Exit fullscreen mode

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

Stand 5. November 2026, laut den Seiten der Anbieter:

Plattform Grenzen Thread-Builds Preis
itch.io itch.io: max. 1.000 Dateien, 500 MB entpackt, 200 MB pro Datei itch.io: Checkbox "SharedArrayBuffer support" itch.io: gratis
GitHub Pages GitHub Pages: 1 GB pro Site, 100 GB/Monat (Soft-Limit) GitHub Pages: keine Header dokumentiert, PWA-Workaround GitHub Pages: gratis für öffentliche Repos
Cloudflare Pages Cloudflare Pages: max. 25 MiB pro Datei, also kleiner als Godots index.wasm (39,5 MB) Cloudflare Pages: _headers Cloudflare Pages: gratis Tier
Netlify Netlify: Free-Plan mit monatlichen Credits Netlify: _headers Netlify: gratis Tier
Ziva Share Web build Ziva: bis 300 MB nach Kompression, nur Godot, ohne C# Ziva: Header gesetzt, ab Godot 4.3 single-threaded Ziva: in jedem Ziva-Plan

Für Game Jams und Demos: itch.io. Für eine eigene Domain: GitHub Pages oder Netlify. Wenn du mit Ziva im Godot-Editor arbeitest, exportiert Share Web build im Chat-Menü das Spiel und gibt dir einen play.ziva.sh-Link; veröffentlichte Spiele sind dort öffentlich gelistet. Eine ausführliche, getestete Anleitung auf Englisch: How to export a Godot game to the web and share a playable link.

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)