Grundkonzepte
Projekte, Schlüssel, Spielersitzungen und wie jedes SDK Ergebnisse und Fehler meldet.
Codekommentare und API-Namen bleiben auf Englisch, damit sie zu den SDKs passen.
Projekte und Schlüssel#
Jedes Spiel ist ein Projekt. Seine Schlüssel identifizieren das Projekt, nicht einen Spieler.
| Zugangsdaten | Verwendung |
|---|---|
| Base URL | Die Adresse dieser Installation. Die API liegt unter /v1. |
| Project ID | Bei jeder Anfrage, als X-Project-ID. Öffentlich. |
Client-Schlüssel pk_live_… | In Spiel-Builds und Webseiten, als X-Client-Key. Öffentlich: Er kann nur im Namen angemeldeter Spieler handeln. |
Geheimer Schlüssel sk_live_… | Nur auf Ihren eigenen Servern, als X-Secret-Key. Wird einmal angezeigt und als Hash gespeichert; schaltet reine Server-Endpunkte frei. |
sk_live_…) niemals in einen Spiel-Build oder eine Webseite ein. Alles, was an Spieler ausgeliefert wird, kann ausgelesen werden.Spieler und Sitzungen#
Spieleraufrufe benötigen ein Access-Token. Bei der Anmeldung erhalten Sie eines (eine Stunde gültig) zusammen mit einem Refresh-Token (30 Tage gültig).
- Die SDKs speichern die Sitzung auf dem Gerät und erneuern sie vor Ablauf, sodass Spieler über mehrere Starts hinweg angemeldet bleiben.
- Refresh-Tokens rotieren bei jeder Verwendung. Wird ein altes erneut verwendet, wird diese Sitzung überall abgemeldet (Diebstahlerkennung).
- Jeder Spieler beginnt als Gast und kann später ein E-Mail- oder Google-Konto verknüpfen; der Fortschritt des Gasts wird übernommen. Siehe Spieler.
Ergebnisse statt Exceptions#
SDK-Aufrufe werfen bei Netzwerk- oder Serverfehlern nie eine Exception. Sie liefern ein Ergebnis mit ok, einem Wert und einem Fehler mit stabilem Code, Meldung und Anfrage-ID.
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" }
}
}Wiederholungen und Rate-Limits#
Die SDKs wiederholen sichere Anfragen bei Netzwerkfehlern und 5xx-Antworten mit exponentiellem Backoff und warten bei 429-Antworten die in Retry-After angegebene Zeit ab.
- Jedes Projekt darf bis zu 120 Anfragen pro Minute senden; darüber antwortet die API mit
rate_limited. - Jedes Konto hat ein tägliches Anfragekontingent, das vom Tarif abhängt (siehe Limits); ist es aufgebraucht, antwortet die API bis 00:00 UTC mit
quota_exceeded. - Antworten enthalten
X-RateLimit-Limit,X-RateLimit-Remainingund, kurz vor Erreichen des Kontingents,X-RateLimit-Daily-Remaining.
Anfrage-IDs und Logs#
Jede Antwort hat einen X-Request-ID-Header, und jeder Fehler enthält request_id. Suchen Sie danach auf der Seite Logs Ihres Projekts, um Endpunkt, Status, Latenz und Spieler zu sehen.