Guía

Cómo publicar un juego HTML5 en mi sitio web: subir, incrustar y corregir

Guía práctica para una carpeta de juego estática: dónde va, cómo abrirla, cómo meterla en una página y qué revisar cuando el juego no arranca.

Polarzinho empuja una caja de juego por un tubo brillante, de un servidor a una ventana de navegador que muestra un juego de islas flotantes.

¿Cómo publicar un juego HTML5 en mi sitio web? Sube el contenido de la carpeta game/ a cualquier alojamiento que sirva archivos estáticos, deja las subcarpetas tal como vienen y abre la dirección de la carpeta en el navegador. La carpeta game/ lista para alojar, en cualquier edición de nuestro marketplace, funciona tal como está: sin PHP, base de datos, compilación ni cuenta. El hosting solo le entrega archivos al navegador del jugador.

Ese es todo el trabajo cuando sale bien. Esta guía trata de los otros días: una pantalla en blanco, errores 404, un aviso de tipo MIME, un iframe que no muestra nada. Vendemos estas plantillas, así que léela como un manual de campo de nuestros propios paquetes. Servimos copias de Gridspark y Velvet Pool desde un servidor local desechable, rompimos Gridspark a propósito de varias formas y leímos los manuales públicos de otras ediciones. Cuando un dato viene de un manual y no de nuestra prueba, lo decimos.

Qué implica de verdad alojar un juego HTML5

Un alojamiento estático guarda archivos y se los entrega al navegador cuando los pide. Nunca ejecuta el juego: lo ejecuta el navegador del jugador. Por eso los requisitos de nuestras ediciones son tan simples: un navegador actual, un alojamiento que sirva archivos estáticos por HTTP o HTTPS y nada de PHP, base de datos ni cuenta para jugar. La carpeta game/ ya viene compilada, así que publicarla no requiere npm ni compilación.

Dos límites que conviene conocer antes de empezar. Algunas ediciones tienen partes opcionales que no son estáticas: Zabum y Ricopop listan un ranking opcional que pide PHP 7.4 o superior y una carpeta con permiso de escritura, y las ediciones en TypeScript (Beep Out, Pinloop, Trimora, Twirldrop, Riffvolt, Sunset Rally, Tenguin, Mochi Monsters, Deepforge, Barricade Z y Zabum) solo necesitan Node.js si quieres editar el código fuente y recompilar; cada manual indica la versión. Velvet Pool, Puttide, Ricopop y Gridspark vienen en JavaScript puro, sin paso de compilación entre tus ediciones y los archivos que subes. Nada de eso hace falta para publicar el juego tal como se entrega. Y el alojamiento en sí no forma parte de la compra. Los términos de la tienda incluyen el alojamiento y la instalación en tu servidor entre los servicios aparte, con presupuesto antes de cualquier trabajo. El soporte cubre dudas sobre instalar y usar los archivos entregados.

Qué se sube y qué se queda en tu computadora:

  • Sube todo lo que está dentro de game/: index.html, scripts, estilos, imágenes, sonidos y fuentes.
  • Deja fuera source/ (la copia editable para desarrolladores), documentation/ (el manual) y el ZIP. El manual de Zabum señala que subir source/ por error provoca errores 404, como el de main.tsx.
  • Conserva junto a tu producto los avisos de licencias de terceros que vienen con el paquete, como piden los términos.

Ver Gridspark, la edición que usamos de ejemplo

Cómo publicar un juego HTML5 en mi sitio web: el camino corto del ZIP a la página jugable

Estos pasos siguen los capítulos de instalación de los manuales de Velvet Pool, Puttide, Gridspark y Sunset Rally, más las revisiones que añadimos después de probar. El ejemplo es Gridspark, la edición que más servimos y rompimos.

  1. Descomprime el paquete en tu computadora. Dentro verás game/ (la carpeta que publicas), source/ (la copia editable) y documentation/ (el manual).
  2. Opcional, pero barato: pruébalo en local. Abre una terminal dentro de game/, ejecuta python -m http.server 8765 y entra a http://localhost:8765/. Si ahí se juega, los archivos están bien y cualquier problema posterior es del alojamiento.
  3. Elige ahora la dirección final, por ejemplo https://tu-sitio.com/juegos/gridspark/. Una subcarpeta funciona porque las rutas dentro del juego son relativas; el manual de Gridspark sugiere public_html/games/gridspark/.
  4. Sube el contenido de game/ a esa carpeta con el administrador de archivos de tu hosting o con un cliente FTP, respetando todas las subcarpetas. El index.html debe quedar directamente dentro de la carpeta, no un nivel más abajo.
  5. Abre la dirección de la carpeta por https, con la diagonal final. En Gridspark tocas la pantalla de inicio (el navegador espera un toque o clic antes de permitir el audio) y presionas Play.
  6. Haz una jugada, recarga la página y revisa que el menú ahora ofrezca Continue. Eso demuestra que el navegador guarda el progreso para tu dirección.
  7. Pon un enlace a la carpeta desde tu sitio o incrusta el juego en una página (mira la sección del iframe, más abajo).

Una carpeta terminada de Gridspark tiene index.html, style.css, gridspark.config.js, src/ y assets/ lado a lado, y el manual pide mantenerlos juntos. Otras ediciones se organizan distinto (Velvet Pool tiene css/ y assets/ en lugar de una sola hoja de estilos), pero la regla es la misma: sube la carpeta como viene.

Por qué hacer doble clic en index.html deja la página en blanco

Las ediciones que abrimos cargan su código como módulos ES, y los navegadores se niegan a cargar módulos desde direcciones file://. Abrimos Gridspark directo desde el disco en Chromium y salió una pantalla oscura y vacía. La consola avisó que el script fue bloqueado por la política CORS, con el motivo "Cross origin requests are only supported for protocol schemes" (solo se admiten http, https y algunos esquemas más). La misma carpeta servida por un servidor local mostró la pantalla de inicio al instante. Los manuales de Velvet Pool, Puttide, Sunset Rally y Gridspark dicen lo mismo: no abras el juego desde file://.

  • No funciona: file:///C:/Users/tu-usuario/juegos/gridspark/index.html
  • Funciona: http://localhost:8765/ en un servidor de prueba local, o https://tu-sitio.com/juegos/gridspark/ en tu alojamiento.

Probamos solo en Chromium. Los manuales describen el bloqueo como algo común en los navegadores, así que cuenta con él en todos.

Incrustar el juego en una página con iframe

Para mostrar el juego dentro de una página que ya tienes, apunta un iframe a la carpeta que subiste. Esta es la etiqueta que probamos:

<iframe src="https://tu-sitio.com/juegos/gridspark/" title="Gridspark" allow="fullscreen; autoplay" width="960" height="540" style="border:0"></iframe>

  • src: la dirección completa de la carpeta, con https y la diagonal final.
  • title: un nombre corto. Los lectores de pantalla lo usan para describir el marco.
  • allow="fullscreen; autoplay": los manuales piden permitir pantalla completa y autoplay en el iframe cuando haga falta. En nuestra prueba, un marco de otra dirección sin eso tenía la pantalla completa desactivada y Gridspark simplemente ocultó su botón de pantalla completa. El atributo antiguo allowfullscreen dio el mismo resultado que allow. Un marco en la misma dirección que la página tiene pantalla completa de todos modos.
  • Sin el atributo sandbox. Solo con sandbox="allow-scripts", Gridspark ni arrancó: el marco recibe un origen nulo, el navegador bloqueó el script del propio juego y el almacenamiento local lanzó un error de seguridad. Con allow-same-origin funciona, pero MDN advierte que ese par en un marco del mismo origen quita la protección. En un juego que alojas tú, deja sandbox fuera.

Ajusta el tamaño para el celular

Una caja fija de 16:9 se ve bien en la computadora y mal en el celular. Con 390 px de ancho, un iframe con aspect-ratio 16/9 mide solo 219 px de alto, y el menú de Gridspark quedó cortado justo debajo del botón Daily challenge. Darle al marco una altura de 75svh, tres cuartas partes de la altura de la pantalla, mostró el menú completo. Tu página también necesita la etiqueta meta viewport; los seis paquetes que abrimos traen una en su propio index.html, y por eso el juego se ajusta cuando lo abres directo.

Dos pantallas de celular lado a lado, cada una con una página que muestra el menú de inicio de Gridspark dentro de un iframe: a la izquierda un marco bajo de 16:9 que corta el menú, a la derecha un marco alto que muestra el menú completo.
El mismo juego, con el mismo ancho de celular. Izquierda: iframe 16:9. Derecha: marco de 75svh de alto.

El juego funciona en su propia dirección, sin página alrededor, así que un enlace simple a esa dirección siempre es una alternativa válida.

Ver Velvet Pool, una edición 3D que se incrusta igual

WordPress y otros constructores de sitios

Alojar la carpeta y mostrarla en una página son dos trabajos distintos, y en WordPress cada uno usa una herramienta. Todo lo que sigue sale de la documentación y la referencia para desarrolladores de WordPress, no de haber usado WordPress nosotros.

  1. Sube la carpeta con el administrador de archivos del hosting o por FTP, dentro del árbol de carpetas del sitio (por ejemplo una carpeta juegos/ junto a las carpetas de WordPress). No por la Biblioteca de medios: el código de WordPress quita .html y .js de los tipos de archivo permitidos, a menos que el usuario tenga la capacidad unfiltered_html.
  2. Abre la dirección de la carpeta por sí sola antes de tocar cualquier página. Las reglas de Apache que WordPress documenta por defecto solo mandan la solicitud a index.php cuando no existe un archivo ni una carpeta que coincida (eso es lo que prueban las condiciones !-f y !-d), así que una carpeta subida se sirve tal cual.
  3. Agrega el iframe en un bloque de HTML personalizado. La documentación de WordPress indica que los usuarios sin la capacidad unfiltered_html, un Colaborador por ejemplo, pierden las etiquetas iframe al guardar la entrada. Si el marco desaparece después de guardar, revisa quién editó la página.

Otros constructores de sitios y CMS: no los probamos y no afirmamos nada sobre ninguno. El juego necesita lo mismo en cualquier lado, un lugar para la carpeta subida y un elemento de inserción que acepte iframes. Si un constructor no ofrece ninguno de los dos, aloja la carpeta donde haya archivos estáticos y enlaza esa dirección.

Cuando no arranca: una lista de problemas y soluciones

Abre las herramientas de desarrollo del navegador (F12 en la mayoría de los navegadores de escritorio) y mira las pestañas Consola y Red (Network) antes de cambiar nada. Cada falla de abajo deja una línea roja ahí, y el nombre del archivo suele señalar la causa.

Pantalla en blanco

Revisa en este orden: la dirección empieza con http:// o https://; la Consola no tiene líneas rojas; los nombres de archivo conservan exactamente las mayúsculas y minúsculas; y, en las ediciones 3D, WebGL2 está disponible (el manual de Velvet Pool indica activar la aceleración por hardware). Los servidores Linux tratan Game.js y game.js como dos archivos, y Windows no, así que una carpeta que funcionaba en tu PC puede fallar después de subirla. Los manuales de Velvet Pool y Zabum advierten de esto.

404 en src/main.js, fuentes o imágenes

Una parte de la carpeta no llegó, o llegó un nivel más abajo de lo debido. Lo reprodujimos subiendo solo index.html, style.css y el archivo de configuración: la pantalla quedó en blanco y la pestaña Red mostró 404 para src/main.js y para todas las fuentes. Sube las carpetas que faltan, o sube el contenido un nivel para que index.html quede en la dirección que abres. Si faltan imágenes o sonidos, o llegaron dañados, el manual de Zabum sugiere FTP en modo binario o automático, o subir un ZIP y extraerlo con el administrador de archivos del hosting. Un 404 es un archivo que falta. No es un problema de MIME.

La página sale sin estilo, con íconos gigantes

Si una regla de reescritura o de URL limpias sirve la carpeta sin la diagonal final, las rutas relativas se resuelven un nivel más arriba. Lo reprodujimos con un servidor de prueba que devuelve la página de la carpeta sin redirigir. El navegador pidió /games/style.css y /games/src/main.js en lugar de los archivos de /games/gridspark/, recibió 404 y dibujó el menú como botones crudos e íconos enormes. Enlaza la carpeta con la diagonal final, o apunta directo a index.html.

Una ventana de navegador con página blanca, botones grises sin estilo e íconos negros enormes: el menú de Gridspark sin su hoja de estilos.
Gridspark abierto en una dirección sin la diagonal final, en un servidor que no redirige: sin hoja de estilos y sin script.

Error de tipo MIME en un script de módulo

En nuestra prueba la consola mostró: Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/plain". El navegador es estricto con los scripts de módulo. Los manuales dicen que el servidor debe enviar los archivos .js con un tipo MIME de JavaScript, y .wasm como application/wasm; el manual de Sunset Rally añade .mjs. La pestaña Red muestra el Content-Type de cada archivo. En las versiones que abrimos, los módulos son archivos .js. Si agregas archivos .mjs propios y una configuración antigua de Apache no los reconoce, una línea en .htaccess lo arregla, la misma que usa nuestro propio sitio:

AddType text/javascript .mjs

La tabla de tipos de Apache 2.4.62 de nuestra máquina de pruebas ya asocia js y mjs con text/javascript y wasm con application/wasm, así que una instalación estándar no necesita la línea. Otros servidores tienen sus propias tablas; pregunta a quien administra el tuyo.

Blocked by CORS policy

Los scripts de módulo y las fuentes que se cargan desde otra dirección necesitan un encabezado Access-Control-Allow-Origin de esa dirección. En nuestra prueba, una página en un puerto no pudo cargar un script de módulo de otro puerto hasta que el segundo servidor envió el encabezado. En la práctica la solución es aburrida: mantén los archivos del juego juntos en una carpeta, en una sola dirección, que es como están armados los paquetes. No necesitas CORS para incrustar el juego con un iframe en otro sitio, porque el iframe solo carga la dirección del juego. Un error de CORS dentro de una inserción suele venir del atributo sandbox, descrito arriba.

Contenido mixto en una página https

Una página servida por https no puede cargar scripts ni iframes por http: los navegadores bloquean ambos, y MDN incluye las fuentes y las solicitudes fetch entre los tipos bloqueados. Usa https:// en el src del iframe y en cualquier dirección completa que hayas escrito. Los archivos del propio juego usan rutas relativas, así que siguen el protocolo de la dirección que abriste. Si la dirección https ni siquiera abre, activa primero el certificado en el panel de tu hosting.

El iframe dice "refused to connect"

En nuestra prueba Chromium registró esta línea, con la dirección del marco bloqueado entre las primeras comillas: Refused to display 'https://game-host.example/' in a frame because it set 'X-Frame-Options' to 'sameorigin'. El servidor que aloja el juego enviaba ese encabezado. SAMEORIGIN solo permite incrustar desde la misma dirección, y DENY nunca lo permite; una regla frame-ancestors en un encabezado Content-Security-Policy cumple una función parecida. Cambia el encabezado de la carpeta del juego, o sirve la página y el juego desde una sola dirección.

Sin audio al principio

Los navegadores bloquean el audio hasta el primer toque o clic, y por eso Gridspark abre con una pantalla de toque para empezar. Toca una vez y luego revisa el volumen y los permisos del navegador.

Ver Puttide, la edición de golf con build listo para alojar

Actualizar el juego sin servir una versión a medias

Los navegadores guardan los scripts en caché, así que después de subir archivos tú o un jugador pueden seguir viendo el juego viejo. El manual de Gridspark da la regla: haz una copia de tus ediciones, reemplaza los archivos jugables como un solo conjunto, prueba y fuerza la recarga si el hosting guarda módulos antiguos. No mezcles módulos viejos y nuevos. Un juego hecho de muchos archivos pequeños que se importan entre sí es lo peor que se puede actualizar a la mitad.

Las ediciones con service worker mantienen su propia caché. Zabum es una PWA: después de una actualización, fuerza la recarga (Ctrl o Cmd más Shift más R). Si cambiaste archivos de audio, cambia el nombre de la caché en sw.js (el ejemplo del manual pasa de zabum-v5 a zabum-v6) y sube ese archivo. Si tu sitio está detrás de una CDN, limpia también su caché. De los manuales que leímos, Zabum es la única PWA; los manuales de Velvet Pool y Puttide dicen con claridad que las suyas no son una app instalable sin conexión.

Lee el changelog antes de reemplazar archivos y guarda una copia de todo lo que hayas editado. El progreso vive en el navegador de cada jugador, no en la carpeta que subes, así que reemplazar los archivos no lo borra.

Ver Zabum, la edición PWA con ranking opcional en PHP

Dónde se guarda el progreso y qué pasa cuando se borra el navegador

Estas ediciones no tienen cuentas ni base de datos en el servidor. Los ajustes, el idioma, la partida en curso y los récords personales viven en el almacenamiento local del navegador, y nada se envía a Polar Games. El manual de Gridspark nombra las claves gridspark.standalone.v1.*; después de una jugada vimos gridspark.standalone.v1.best y gridspark.standalone.v1.save.

El menú principal de Gridspark con el botón Continue, el enlace New game, el botón Daily challenge y un récord guardado de 3,257 puntos.
En una visita posterior, el menú ofrece Continue y el récord guardado. Ambos se leen del navegador.

El almacenamiento pertenece a la dirección (protocolo, host y puerto), no a la carpeta. Lo comprobamos de tres maneras. Una copia de Gridspark en otra carpeta de la misma dirección leyó los mismos valores guardados. El mismo juego abierto como localhost en vez de 127.0.0.1 empezó vacío, y la misma dirección en otro puerto también. El manual de Zabum añade que http y https, con www y sin www, y los subdominios tienen cada uno su propio almacenamiento.

  • Borrar los datos del sitio o las cookies elimina la partida guardada y los récords. En una ventana privada el progreso puede durar solo la sesión; el juego sigue funcionando cuando el almacenamiento está bloqueado.
  • Otro navegador u otro dispositivo empieza de cero. No hay sincronización ni cuenta para iniciar sesión.
  • Cambiar la dirección reinicia a todos: de http a https, de www a sin www, un dominio nuevo.
  • Mover el juego a otra carpeta de la misma dirección conserva el progreso, como mostró nuestra prueba con Gridspark.

Una lista de pruebas antes de compartir el enlace

  1. Abre la dirección final en los navegadores que usan tus jugadores: uno basado en Chromium (Chrome o Edge), Firefox y Safari. Nuestras pruebas corrieron solo en Chromium, así que esta es la lista que te toca ejecutar.
  2. Ábrela en un celular de verdad, primero en la dirección propia del juego y luego dentro de tu página, en las dos orientaciones.
  3. Limita la velocidad de la conexión en las herramientas de desarrollo y observa la primera carga. Gridspark, servido sin compresión desde nuestro servidor local, necesitó unos 0.5 MB y 26 solicitudes para llegar a su pantalla de inicio. Con Chromium limitado a 1.6 Mbit/s y 150 ms de latencia, la pantalla apareció en unos 3 segundos. La carpeta game/ completa pesa unos 3.4 MB en nuestra copia; Velvet Pool pesa unos 7.3 MB y Puttide unos 15 MB. Si los celulares viejos sufren, el manual de Zabum sugiere revisar que tu hosting comprima los archivos con gzip o brotli.
  4. Haz una jugada, recarga y confirma que Continue y el récord siguen ahí.
  5. Toca una vez y comprueba que el audio arranca. El silencio antes del primer toque es normal.
  6. Abre una ventana privada. El juego debe funcionar, aunque olvide el progreso al cerrarla.
  7. Lee las pestañas Consola y Red en una primera carga: ninguna línea roja, ningún 404.
  8. En una inserción, revisa que aparezca el botón de pantalla completa y que el marco sea lo bastante alto en el celular.

Preguntas frecuentes sobre cómo publicar un juego HTML5

¿Necesito PHP, una base de datos o un servidor especial para alojar un juego HTML5?

No en nuestras ediciones tal como se entregan. Son estáticas: sube la carpeta game/ a un alojamiento que sirva archivos por HTTP o HTTPS y abre la dirección. Zabum y Ricopop tienen un ranking opcional que sí pide PHP 7.4 o superior y una carpeta con permiso de escritura.

¿Puedo simplemente hacer doble clic en index.html?

No. Los navegadores bloquean los módulos del juego en file://, y la página se queda en blanco. Abre el juego por una dirección http o https, ya sea tu hosting o un servidor local de prueba como python -m http.server 8765.

¿Necesito HTTPS?

Los manuales piden usar HTTPS en el alojamiento público. El manual de Zabum dice que Añadir a la pantalla de inicio lo exige, y una página https no puede incrustar un iframe http porque el navegador lo bloquea como contenido mixto.

¿Cómo agrego el juego a una página de WordPress?

Sube la carpeta con el administrador de archivos del hosting o por FTP, abre su dirección para confirmar que se juega y luego agrega el iframe en un bloque de HTML personalizado. Los usuarios sin la capacidad unfiltered_html pierden los iframes, así que revisa el rol de quien edita la página.

¿Dónde se guarda el progreso y qué pasa si el jugador borra los datos del navegador?

En el almacenamiento local del navegador, por dirección. Borrar los datos del sitio lo elimina, otro navegador o dispositivo empieza vacío, y cambiar de dominio o alternar entre http y https lo reinicia. No hay cuentas y no se nos envía nada.

¿Polar Games aloja el juego por mí?

No. La tienda vende los archivos. El soporte cubre dudas sobre instalarlos y usarlos; el alojamiento y la instalación en tu servidor son servicios aparte, con presupuesto antes de cualquier trabajo.

Siguiente paso

Si todavía no elegiste un juego, cada página de producto lista sus requisitos, enlaza su manual y te deja jugar la demo antes de pagar. Lee primero el capítulo de instalación del manual: es la página que usarás para el trabajo de esta guía.

Ver las plantillas de juegos HTML5