0
/devs documentation v0.0.1-beta Player identity

SDK · v0.0.1-beta

Player identity

Nickname anon del jugador con modal cross-game

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-events edge 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

DatoStorageVida
na_player_name (nickname)localStorage del browserhasta que el user limpie storage
neon_player_id (UUID anon)localStorage del browseridem
session_id (UUID per-tab)memoriahasta 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:

  1. 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 localStorage directo 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 tipo anon-XXXX en localStorage de jugafy.com cuando el visitor llega por primera vez. Cuando entrás al juego, el iframe NO tiene ese valor (cross-origin sandbox), pero getPlayerName() adentro retorna "" y ensurePlayerName() muestra el modal — el usuario lo completa y queda guardado en sessionStorage del iframe (volátil).

  2. 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/setPlayerName tambié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 con Jugafy.storage.set("my_nick", name) post-ensurePlayerName para 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 maxlength del 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_KID o pepito2k. 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 name lower-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).

Ingresá a Jugafy

Guardá tus scores, subí al leaderboard y sincronizá progreso entre dispositivos.

Contanos

Bug, idea, crítica — todo nos sirve para hacer esto mejor.