Saltar al contenido principal

Inicio rápido de juegos externos

Crea un juego que se ejecute en el portal del socio en unas 50 líneas. El protocolo completo está en el contrato v1. Aquí un pequeño módulo auxiliar evita el código repetitivo.

1. Añade el módulo auxiliar​

Crea incentia-sdk.js junto a tu index.html. Envuelve el handshake y los dos mensajes del contrato:

export function readPlayContext() {
const p = new URLSearchParams(location.search);
const sessionId = p.get('sessionId');
const playToken = p.get('playToken');
const hostOrigin = p.get('host');
return sessionId && playToken && hostOrigin ? { sessionId, playToken, hostOrigin } : null;
}

export function complete(ctx, signal, timeoutMs = 30000) {
return new Promise((resolve, reject) => {
const onMessage = (e) => {
if (e.origin !== ctx.hostOrigin) return;
if (e.data?.type !== 'incentia.outcome.v1' || e.data.sessionId !== ctx.sessionId) return;
cleanup();
resolve(e.data);
};
const timer = setTimeout(() => { cleanup(); reject(new Error('Outcome timeout')); }, timeoutMs);
const cleanup = () => { window.removeEventListener('message', onMessage); clearTimeout(timer); };
window.addEventListener('message', onMessage);
window.parent.postMessage(
{ type: 'incentia.complete.v1', sessionId: ctx.sessionId, signal }, ctx.hostOrigin);
});
}

El repositorio también incluye una versión en TypeScript (tools/external-games-sdk, paquete @incentia/games-sdk). No está publicada en un registro público, así que copia el módulo de arriba.

2. Conecta el handshake​

readPlayContext devuelve null cuando la página se abre fuera del anfitrión. En ese caso muestra una versión de pruebas.

<!doctype html>
<html>
<body>
<button id="play" disabled>Loading...</button>
<pre id="status"></pre>
<script type="module">
import { readPlayContext, complete } from './incentia-sdk.js';

const status = document.getElementById('status');
const play = document.getElementById('play');

const ctx = readPlayContext();
if (!ctx) {
status.textContent = 'No play context (open me through the host iframe)';
} else {
play.disabled = false;
play.textContent = 'Play';
play.addEventListener('click', async () => {
try {
const outcome = await complete(ctx, { score: 100 });
status.textContent = `Outcome: ${outcome.outcome}` +
(outcome.prize?.name ? ` — ${outcome.prize.name}` : '');
} catch (err) {
status.textContent = `Error: ${err.message}`;
}
});
}
</script>
</body>
</html>

Cuando el jugador pulsa el botón, el módulo envía la señal de finalización y espera a que el anfitrión devuelva el resultado.

3. Comprime y sube​

zip -r my-game.zip index.html incentia-sdk.js assets/

Sube el zip al crear o editar un juego de tipo External en el panel de administración. En Envío de un juego tienes los pasos, los tipos de archivo permitidos y los límites de tamaño.

4. Desarrolla en local​

Sirve index.html desde cualquier servidor estático. Sin los parámetros del handshake, readPlayContext devuelve null, así que puedes simular un resultado e iterar sin cuenta de IncentIA.

if (!ctx) {
play.disabled = false;
play.textContent = 'Play (dev mock)';
play.addEventListener('click', () => {
status.textContent = 'Outcome: win — Dev prize';
});
}

5. Publica actualizaciones​

Sube un zip nuevo al mismo juego. La dirección del paquete se sustituye en el mismo sitio, así que no hay versiones que gestionar ni nada que volver a suscribir. Las partidas ya registradas no guardan referencia al paquete anterior.

Siguientes pasos​