El SDK mantiene una identidad anon del jugador (un nickname tipo “ARCADE_KID”) cross-game. Lo usás para submitScore, persistRun y para mostrar “Hola, ARCADE_KID” en tu UI. La 1ra vez que un visitante toca un juego se le muestra un modal pidiendo el nick. Después no se le pide más, en ningún juego de la plataforma.
API
getPlayerName(): string
Devuelve el nickname actual del visitante o "" si nunca lo seteó. Sync, lee de localStorage del browser (key na_player_name).
import { getPlayerName } from "/sdk/v0.0.1-beta/jugafy.js";
const nick = getPlayerName(); // "ARCADE_KID" o ""
setPlayerName(name): string
Setea el nickname (sanitiza primero). Devuelve el nick limpio guardado, o "" si el input quedó vacío post-sanitización.
import { setPlayerName } from "/sdk/v0.0.1-beta/jugafy.js";
const stored = setPlayerName(" pepito2K!! "); // "PEPITO2K!!" (max 16 chars)
ensurePlayerName(): Promise<string>
El más útil. Resuelve con el nickname:
- Si ya hay uno guardado → resuelve inmediato sin UI.
- Si no hay → inyecta un modal sobre
<body>, espera a que el user complete y resuelve con el nombre.
Llamá esto antes de cualquier submitScore. El modal tiene su propio CSS embedded (synthwave neon, no toca tus estilos), tap target 48px, autofocus, max 16 chars. Trabaja en mobile e iOS sin problemas.
import { ensurePlayerName, submitScore } from "/sdk/v0.0.1-beta/jugafy.js";
document.getElementById("game-over").addEventListener("click", async () => {
const name = await ensurePlayerName(); // muestra modal o resuelve cached
await submitScore(window.NEON_GAME, name, finalScore);
});
Si el user cancela el modal (cierra el tab), la promise queda pendiente — no rejecta. Es intencional: forzamos al user a poner un nick para que el score quede attribuído.
Idempotente: si llamás ensurePlayerName() dos veces antes de que el user complete el modal, la 2da llamada engancha la misma promise — no se abren dos modals.
sanitizeName(raw): string
Sanitiza un input arbitrario:
- Strip HTML tags (
<script>...→script...). - Strip control chars (
�a+ DEL). - Trim whitespace.
- Slice a 16 chars max.
import { sanitizeName } from "/sdk/v0.0.1-beta/jugafy.js";
sanitizeName(" <b>Hola</b> "); // "bHola/b" (no es perfecto, asume input human)
sanitizeName(`pepe\nrobot`); // "peperobot"
Útil si querés mostrar el nick en tu UI sin XSS: el.textContent = sanitizeName(name) o reusar el output de getPlayerName que ya está sanitizado.
Player ID anon (uso interno del SDK)
Además del nickname, el SDK mantiene un player_id (UUID v4) en localStorage para correlación de eventos. NO está expuesto como API pública — el dev no lo necesita en su game logic. Solo se usa internamente:
track()lo adjunta al payload para que el backend correlacione runs del mismo player.link-anon-eventsedge function lo usa para hacer backfill de eventos pre-login → post-login cuando un user se registra.
Si vos querés tu propio identificador para tu game logic, NO uses player_id directo — usá Jugafy.storage.get("my_user_id") o el nickname.
Sesión vs persistencia
| Dato | Storage | Vida |
|---|---|---|
na_player_name (nickname) | localStorage del browser | hasta que el user limpie storage |
neon_player_id (UUID anon) | localStorage del browser | idem |
session_id (UUID per-tab) | memoria | hasta que cierre/reload |
En sandbox del iframe, los localStorage.getItem que el SDK hace internamente fallan con SecurityError (try/catch absorbe). Consecuencia: en prod, el player_id y player_name se vuelven volátiles dentro del iframe del juego.
Esto está OK porque:
-
El modal de nickname se muestra UNA VEZ — pero se guarda en el localStorage del parent (
jugafy.com), no del iframe. Cross-tab y cross-juego.Wait — el modal escribe a
localStoragedirecto del iframe, que en sandbox no persiste. Entonces ¿el modal se muestra cada vez? No exactamente: la plataforma de Jugafy ya pre-stampea un nickname autogenerado tipoanon-XXXXen localStorage dejugafy.comcuando el visitor llega por primera vez. Cuando entrás al juego, el iframe NO tiene ese valor (cross-origin sandbox), perogetPlayerName()adentro retorna""yensurePlayerName()muestra el modal — el usuario lo completa y queda guardado en sessionStorage del iframe (volátil). -
Para esta versión
v0.0.1-beta, el nickname efectivamente se vuelve “por sesión de iframe” en sandbox. Si el user reload del juego, vuelve a aparecer el modal.Esto es bug conocido y planificado. Roadmap: extender el storage shim del SDK para que
getPlayerName/setPlayerNametambién routeen al parent via postMessage. Hoy NO está. Si tu juego depende mucho de identidad cross-session estable, podés guardar tú mismo el nick conJugafy.storage.set("my_nick", name)post-ensurePlayerNamepara que sobreviva reloads.const name = await ensurePlayerName(); storage.set("my_nick", name); // En el próximo reload: const cachedNick = storage.get("my_nick"); if (cachedNick) { // saltear el modal — usar cachedNick directamente }
Idioma del modal
El modal usa los strings i18n del SDK (profile.modal.title, etc.). Cae al lang activo (ES o EN) según getLang(). Si tu juego cambia de idioma con setLang("en") antes de llamar ensurePlayerName(), el modal aparece en inglés.
Si querés un modal en otro idioma o totalmente custom, no llames ensurePlayerName() — armás tu propio prompt + llamás setPlayerName(value) directo.
Caveats
- Max 16 chars del nickname. Hard cap en el sanitizer + en el
maxlengthdel input del modal. No subir. - No emojis — los emojis son chars Unicode válidos pero el rendering en leaderboards puede ser raro entre browsers/fuentes. No los bloqueamos hard, pero tu UI debería testear si los soporta.
- No espacios en el medio: el sanitizer NO los elimina (sí trimea bordes), pero la convención cross-game es nicks tipo
ARCADE_KIDopepito2k. Tu UI puede convertir input con espacios a_antes de submit si querés enforce eso. - No es único: si dos visitantes setean el mismo nick, los scores se mergean en el leaderboard (dedupe por
namelower-case). Trade-off conocido — para un sistema con “cuentas reales” (donde el nick es único) hay que migrar a la plataforma de auth de Jugafy (Supabase Auth con Google OAuth/magic link).