Parte: 12 — Juegos web y HTML5 · Fuente: Documentación de Godot 4 — Exporting for the Web ⏱️ Duración estimada: 75 min · Nivel: Intermedio
Godot 4 compila tu juego a WebAssembly y lo envuelve en HTML+JS para correr en el navegador. En esta clase aprenderás el flujo completo: instalar las plantillas de exportación (export templates), crear un preset Web, exportar a una carpeta y servir el resultado por HTTP. Verás por qué no basta con abrir el index.html y por qué, si tu juego usa hilos, el navegador exige las cabeceras COOP/COEP (Cross-Origin-Opener-Policy y Cross-Origin-Embedder-Policy).
También conocerás los límites reales de la exportación web: el tamaño de descarga (el runtime pesa varios MB), el audio que solo arranca tras interacción del usuario y la ausencia de ventanas nativas del sistema. Al final tendrás un proyecto Godot corriendo en http://localhost servido con las cabeceras correctas.
Al finalizar, el alumno podrá:
file://.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Plantillas de exportación | Sin ellas Godot no puede generar el binario web. |
| 2 | Preset Web y salida | Define qué archivos se producen y dónde. |
| 3 | Servir por HTTP | El WASM y los recursos no cargan bajo file://. |
| 4 | Cabeceras COOP/COEP | Habilitan SharedArrayBuffer y los hilos. |
| 5 | Tamaño de descarga | El runtime pesa; afecta el tiempo de primera carga. |
| 6 | Audio tras interacción | El navegador bloquea el audio hasta un gesto del usuario. |
| 7 | Sin ventanas nativas | Diálogos del SO y algunas APIs no existen en web. |
| 8 | Modo hilos vs sin hilos | Hilos rinden mejor pero exigen COOP/COEP y hosting compatible. |
SharedArrayBuffer.index.html generado: página que carga el WASM y arranca el juego. Clave: es el punto de entrada servido por HTTP.Necesitas Godot 4.x (versión estándar) y Python 3 para servir localmente. En Godot ve a Editor → Manage Export Templates y pulsa Download and Install para bajar las plantillas de tu versión exacta (deben coincidir con el editor). La documentación oficial está en https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html.
Como el servidor python -m http.server no envía COOP/COEP, usaremos un pequeño script de servidor propio para el modo con hilos. Ten un proyecto Godot simple listo (por ejemplo el plataformas del curso o una escena con un sprite que se mueva).
Exportarás un proyecto Godot a web y lo servirás con las cabeceras correctas.
Abre tu proyecto en Godot y asegúrate de que tiene una Main Scene definida y corre bien con F5.
Instala plantillas si no lo hiciste: Editor → Manage Export Templates → Download and Install.
Ve a Project → Export. Pulsa Add… → Web. Si aparece un aviso amarillo sobre plantillas, resuélvelo antes de seguir.
Crea una carpeta de salida web/ junto al proyecto. En el preset, en Export Path, elige web/index.html. Deja Export With Debug desmarcado para la versión final.
Pulsa Export Project (no "Export PCK"). Godot generará varios archivos en web/: index.html, index.js, index.wasm, index.pck y auxiliares.
Prueba primero el modo simple. Sirve la carpeta con Python:
cd web
python -m http.server 8000
Abre http://localhost:8000/. Si tu exportación no usa hilos, el juego cargará (una barra de progreso y luego la escena). Si usa hilos, la consola mostrará un error sobre SharedArrayBuffer: eso significa que faltan las cabeceras COOP/COEP.
Para servir con esas cabeceras, crea servidor.py fuera de web/ con este contenido:
# Servidor local que añade las cabeceras COOP/COEP requeridas por los hilos.
import http.server, socketserver
PUERTO = 8000
class Handler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
super().end_headers()
with socketserver.TCPServer(("", PUERTO), Handler) as httpd:
print(f"Sirviendo en http://localhost:{PUERTO}/ con COOP/COEP")
httpd.serve_forever()
web/ para que sirva esos archivos:cd web
python ../servidor.py
SharedArrayBuffer y la exportación con hilos arranca sin errores. Haz clic en el juego: notarás que el audio recién suena tras esa primera interacción, por la política del navegador.Ya tienes tu juego Godot corriendo en el navegador servido correctamente.
web/ y anota cuánto pesa index.wasm.python -m http.server una exportación con hilos y describe el error exacto de la consola.Exporta un proyecto Godot con al menos un objeto que se mueva por input del jugador y un sonido, sírvelo con el servidor.py que envía COOP/COEP, y confirma que corre en el navegador con audio funcional tras interacción.
Criterio de aceptación: en http://localhost:8000/ el juego carga sin errores de SharedArrayBuffer, responde al input y reproduce el sonido tras el primer clic; la consola no muestra errores rojos.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| "SharedArrayBuffer is not defined" | Faltan COOP/COEP. Sirve con servidor.py que añade ambas cabeceras. |
| Aviso amarillo "export templates" | No están instaladas o no coinciden con la versión. Instálalas desde Manage Export Templates. |
Pantalla en blanco al abrir index.html |
Abriste por file://. Sírvelo por HTTP desde la carpeta web/. |
| El audio no suena nunca | El navegador exige un gesto del usuario. Añade un clic inicial que reanude el audio. |
| Descarga muy lenta o pesada | El runtime WASM pesa. Exporta sin debug y considera comprimir/gzip en el hosting. |
❓ ¿Por qué mi exportación pesa varios MB? Incluye el motor de Godot compilado a WASM. Es normal; la versión de release sin debug es la más ligera.
❓ ¿Necesito siempre COOP/COEP? Solo si exportas con hilos. En modo sin hilos el juego funciona con un servidor HTTP simple, a costa de algo de rendimiento.
❓ ¿Puedo alojarlo en cualquier hosting? Para el modo con hilos, el hosting debe permitir enviar COOP/COEP. GitHub Pages no las envía; itch.io ofrece una opción de "SharedArrayBuffer" en la subida.
❓ ¿Funcionan todas las funciones del juego? No todas: diálogos de archivo nativos, algunas APIs del SO y ventanas múltiples no existen en web. Diseña pensando en esas ausencias.
Clase 214 - El navegador como plataforma de juegos