Conceitos principais
Projetos, chaves, sessões de jogadores e como cada SDK informa resultados e erros.
Comentários de código e nomes da API ficam em inglês para corresponder aos SDKs.
Projetos e chaves#
Cada jogo é um projeto. As chaves identificam o projeto, não um jogador.
| Credencial | Onde usar |
|---|---|
| Base URL | O endereço desta instalação. A API fica em /v1. |
| Project ID | Em toda requisição, como X-Project-ID. Público. |
Chave de cliente pk_live_… | Em builds do jogo e páginas web, como X-Client-Key. Pública: só pode agir em nome de jogadores conectados. |
Chave secreta sk_live_… | Somente nos seus próprios servidores, como X-Secret-Key. Exibida uma única vez e armazenada como hash; libera os endpoints exclusivos de servidor. |
sk_live_…) em uma build do jogo ou em uma página web. Tudo o que é entregue aos jogadores pode ser lido.Jogadores e sessões#
Chamadas de jogador precisam de um token de acesso. O login retorna um (válido por uma hora) junto com um refresh token (válido por 30 dias).
- Os SDKs guardam a sessão no dispositivo e a renovam antes que ela expire, então os jogadores continuam conectados de uma abertura do jogo para outra.
- Os refresh tokens são rotacionados a cada uso. Reutilizar um token antigo encerra aquela sessão em todos os dispositivos (detecção de roubo).
- Todo jogador começa como convidado e pode depois vincular um e-mail ou uma conta Google; o progresso do convidado vai junto. Veja Jogadores.
Resultados em vez de exceções#
As chamadas dos SDKs nunca lançam exceção em erros de rede ou do servidor. Elas retornam um resultado com ok, um valor e um erro com código estável, mensagem e ID da requisição.
var top = await Majacloud.Leaderboards.GetTopAsync("coins", 10);
if (top.Ok)
{
foreach (var entry in top.Value.Entries)
Debug.Log($"#{entry.Rank} {entry.PlayerName} {entry.Score}");
}
else if (top.Error.IsRetryable)
{
// Network, timeout, 5xx or rate limit: try again later
Debug.Log("Retry in " + top.Error.RetryAfterSeconds + " s");
}
else
{
Debug.LogWarning(top.Error.Code + ": " + top.Error.Message + " (" + top.Error.RequestId + ")");
}var top := await Majacloud.leaderboards.get_top("coins", 10)
if top.ok:
for entry in top.value.entries:
print("#%d %s %d" % [entry.rank, entry.player_name, entry.score])
elif top.is_retryable():
# Network, timeout, 5xx or rate limit: try again later
print("Retry in ", top.retry_after, " s")
else:
push_warning("%s: %s (%s)" % [top.error, top.message, top.request_id])const top = await mc.leaderboards.getTop('coins', { limit: 10 });
if (top.ok) {
for (const entry of top.value.entries) {
console.log(`#${entry.rank} ${entry.player_name} ${entry.score}`);
}
} else if (top.error.retryable) {
// Network, timeout, 5xx or rate limit: try again later
console.log('Retry in', top.error.retryAfter, 's');
} else {
console.warn(`${top.error.code}: ${top.error.message} (${top.error.requestId})`);
}// Success
{ "ok": true, "entries": [ … ], "total": 42 }
// Error (HTTP 4xx/5xx)
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "Project rate limit reached. Try again in a minute.",
"request_id": "6f1c2a9e-…",
"details": { "limit": 120, "window": "minute" }
}
}Novas tentativas e limites de taxa#
Os SDKs repetem requisições seguras em erros de rede e respostas 5xx, com backoff exponencial, e aguardam o fim de respostas 429 usando Retry-After.
- Cada projeto pode enviar até 120 requisições por minuto; acima disso, a API responde
rate_limited. - Cada conta tem uma cota diária de requisições que depende do plano (veja Limites); acima dela, a API responde
quota_exceededaté 00:00 UTC. - As respostas trazem
X-RateLimit-Limit,X-RateLimit-Remaininge, perto da cota,X-RateLimit-Daily-Remaining.
IDs de requisição e logs#
Toda resposta tem um cabeçalho X-Request-ID, e todo erro inclui request_id. Busque esse ID na página Logs do seu projeto para ver o endpoint, o status, a latência e o jogador.