Capítulo core de la guía Neblla — el contrato base del SDK. Imprescindible: el resto de capítulos asumen lo que hay aquí. # Neblla — core ## Qué es **La IA hace tu app en minutos. Neblla la mantiene viva durante años.** El backend y el backoffice de tu juego, tu app o tu tienda: usuarios, datos, pagos, salas multijugador en tiempo real, comunidad, IA y un panel para gestionarlo todo. **Tú escribes la app, Neblla pone todo lo que va detrás** — lo que de otro modo necesitaría un servidor propio: cuentas de usuario que valen en todas las apps Neblla, datos guardados, cobros, contenido publicado por los usuarios, amigos, IA, un backoffice y, cuando hay más de un dispositivo, salas con una autoridad clara. El multijugador es uno de esos módulos, no un requisito. Se carga con una etiqueta ` ``` Cuando la página carga, `onNeblla` se ejecuta con el SDK ya conectado. El script tag NO necesita `type="module"`. Si el SDK no puede arrancar, `onNeblla` no se ejecuta y se avisa una sola vez: define `window.onNebllaError = (detail) => { ... }` o escucha el evento DOM `neblla:error` (mismo `detail`). `detail.code` es `unreachable` (no se pudo contactar con Neblla), `not_found` (esta página no es de ninguna app: su origen no está en los dominios de la app), `refused` (la app no deja entrar a nadie nuevo ahora: `reason` es `quota_exceeded`, `storage_full`, `migrating`, `rate_limited` si esta dirección abrió demasiadas páginas en un minuto o creó demasiados invitados nuevos, o `turnstile_failed` si la app pide Turnstile y la página no lo pasó), `auth_failed` (el servidor rechazó la conexión, con `status`), `timeout` (sin login a los 15 s; el SDK sigue reintentando y `onNeblla` aún puede llegar) o `sdk_error`. Úsalo para pintar un "sin conexión — reintentar" en vez de una pantalla en blanco. Lo que tu código lanza y nadie atrapa llega a tu registro (el panel: Construir › Errores y rechazos; tu IA: `neblla_get_logs`), con su fichero y su línea: un error o una promesa rechazada en la página (`client.js` y tus otros ficheros) y lo que lanza un manejador de `lobby.js`, `gathering.js` o `room.js` en el par servidor de la sala. Es una muestra: como mucho 10 errores distintos por minuto desde cada página, y el mismo otra vez solo suma a su cuenta. No cambia nada para tu app: el error sigue saliendo en la consola como siempre. Los errores de otros orígenes (el navegador solo dice «Script error.») y los de las extensiones del navegador no se mandan. ## Estructura canónica — 6 ficheros Si la app vive alojada en Neblla, el link público apunta a `index.html`. La plantilla canónica son seis archivos; solo `index.html` es obligatorio, el resto existen si la app los necesita. Front-end (corre en el navegador): - **index.html** — markup. Carga `main.css`, `client.js` y el SDK de Neblla. - **main.css** — estilos. - **client.js** — corre en cada dispositivo conectado. Tiene acceso al DOM. El código va dentro de `window.onNeblla = (neblla) => { ... }`. Server-side (lógica aislada, sin DOM, carpeta `server/`): - **server/lobby.js** — usuarios que aún no están en partida. Matchmaking: recoger "estoy listo", agrupar, reservar sala, anunciar emparejamiento. - **server/gathering.js** — sala creada esperando a empezar. Decide *cuándo* arranca la partida (los casos comunes se configuran sin código en el panel, Funciones › Salas). - **server/room.js** — la sala en marcha. Autoridad de la sala: valida acciones, mantiene estado, anuncia cambios. Contrato de la estructura: - `index.html` referencia `main.css` y `client.js` con `` y `