Skip to content

sdk.complete()

Firma

sdk.complete(
score: number,
payload?: Record<string, unknown>
): Promise<EventResult>

Finaliza la sesión de juego y activa el cálculo de recompensas. El backend valida el token, aplica los límites de XP y monedas, y acredita la recompensa al estudiante. Solo puede llamarse una vez por sesión.


Parámetros

ParámetroTipoRequeridoDescripción
scorenumberPuntuación final. Debe ser un entero ≥ 0 y ≤ 10 000. El SDK trunca decimales automáticamente.
payloadobjectNoDatos adicionales de la partida (precisión, duración, modo, etc.).

Escala de puntuación

La puntuación es en la escala 0–10 000. No tiene que ser exactamente 10 000 para una partida perfecta — depende de tu mecánica:

Tipo de juegoEjemplo de puntuación
Quiz de 5 preguntas, 200 pts c/u0–1 000 (ajusta la escala)
Juego de acción con combos0–10 000
Puzzle de velocidadBasado en tiempo: max(0, 10000 - tiempo_ms / 10)

Valor de retorno

Promise<EventResult>:

interface EventResult {
event_id?: string | number | null;
reward?: {
xp: number; // XP otorgado
coins: number; // monedas otorgadas
wallet_balance: number; // saldo total de monedas tras el pago
} | null;
wallet_balance?: number;
skipped?: boolean; // true si complete() ya se había llamado antes
relayed?: boolean;
}

Ejemplos

Uso básico

const resultado = await sdk.complete(750);
if (resultado.reward) {
console.log(`+${resultado.reward.xp} XP, +${resultado.reward.coins} monedas`);
}

Con payload de métricas

const accuracy = Math.round((correctas / total) * 100);
const resultado = await sdk.complete(score, {
accuracy: accuracy, // % de aciertos
correct: correctas, // respuestas correctas
total_questions: total, // total de preguntas
max_streak: maxStreak, // racha máxima
duracion_segundos: tiempoJuego, // duración real de la partida
});

Con banner de recompensa

async function terminarPartida(scoreFinal) {
const estado = document.getElementById('estado');
estado.textContent = 'Guardando resultado...';
try {
const { reward } = await sdk.complete(scoreFinal, {
modo: modoDeJuego,
});
if (reward && (reward.xp > 0 || reward.coins > 0)) {
mostrarBannerExito(reward);
} else {
estado.textContent = 'Resultado guardado.';
}
} catch (err) {
estado.textContent = 'No se pudo guardar el resultado: ' + err.message;
}
}

Convertir puntuación de escala personalizada

Si tu juego usa una escala diferente (p.ej., 0–1000), conviértela antes de llamar a complete():

// Tu puntuación interna: 0–1000
// Escala Ecotic: 0–10000
const scoreEcotic = Math.round(tuScore * 10);
await sdk.complete(scoreEcotic);

Validaciones del SDK (lado cliente)

Antes de enviar al servidor, el SDK valida:

  • score debe ser un número finito ≥ 0. Error: "score debe ser un número ≥ 0."
  • score no puede superar 10 000. Error: "score no puede superar 10000."
  • Solo la primera llamada se envía — las siguientes retornan { skipped: true }.

Validaciones del servidor

CondiciónRespuesta
Token inválido o expirado401 → SDK solicita token nuevo automáticamente
Sesión ya completada200 con recompensa { xp: 0, coins: 0 }
Partida < 15 segundos200 con recompensa { xp: 0, coins: 0 }
Límite diario alcanzado200 con recompensa parcial o { xp: 0, coins: 0 }

Qué pasa después de complete()

Después de que el servidor responde:

  1. El SDK llama a onReward(reward) si está configurado.
  2. El SDK envía postMessage(ECOTIC_GAME_EVENT, { ... _reward: reward }) al GameCenter para que actualice la UI de misiones.
  3. Tu código recibe la promesa resuelta con EventResult.