핵심 개념
프로젝트, 키, 플레이어 세션, 그리고 모든 SDK가 결과와 오류를 보고하는 방식을 설명합니다.
코드 주석과 API 이름은 SDK와 일치하도록 영어로 유지합니다.
프로젝트와 키#
게임 하나가 프로젝트 하나입니다. 키는 프로젝트를 식별할 뿐, 플레이어를 식별하지는 않습니다.
| 자격 증명 | 사용 위치 |
|---|---|
| Base URL | 이 설치의 주소입니다. API는 /v1 아래에 있습니다. |
| Project ID | 모든 요청에 X-Project-ID로 보냅니다. 공개 값입니다. |
클라이언트 키 pk_live_… | 게임 빌드와 웹 페이지에서 X-Client-Key로 보냅니다. 공개 키이며, 로그인한 플레이어를 대신해서만 동작합니다. |
시크릿 키 sk_live_… | 자체 서버에서만 X-Secret-Key로 보냅니다. 한 번만 표시되고 해시로 저장되며, 서버 전용 엔드포인트를 사용할 수 있게 합니다. |
시크릿 키(
sk_live_…)를 게임 빌드나 웹 페이지에 절대 넣지 마세요. 플레이어에게 배포된 것은 무엇이든 읽힐 수 있습니다.플레이어와 세션#
플레이어 호출에는 액세스 토큰이 필요합니다. 로그인하면 액세스 토큰(1시간 유효)과 함께 리프레시 토큰(30일 유효)이 반환됩니다.
- SDK는 세션을 기기에 저장하고 만료되기 전에 갱신하므로, 게임을 다시 실행해도 플레이어의 로그인 상태가 유지됩니다.
- 리프레시 토큰은 사용할 때마다 교체됩니다. 이전 토큰을 재사용하면 해당 세션이 모든 곳에서 로그아웃됩니다(탈취 탐지).
- 모든 플레이어는 게스트로 시작하며, 나중에 이메일 또는 Google 계정을 연결할 수 있습니다. 게스트의 진행 상황도 함께 이전됩니다. 플레이어를 참고하세요.
예외 대신 결과#
SDK 호출은 네트워크 오류나 서버 오류가 발생해도 예외를 던지지 않습니다. 대신 ok, 값, 그리고 고정 코드·메시지·요청 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" }
}
}재시도와 속도 제한#
SDK는 네트워크 오류와 5xx 응답이 발생하면 안전한 요청을 지수 백오프로 재시도하고, 429 응답에는 Retry-After만큼 기다립니다.
- 각 프로젝트는 분당 최대 120개 요청을 보낼 수 있으며, 이를 초과하면 API가
rate_limited를 반환합니다. - 각 계정에는 플랜에 따라 달라지는 일일 요청 할당량이 있습니다(한도 참고). 이를 초과하면 00:00 UTC까지 API가
quota_exceeded를 반환합니다. - 응답에는
X-RateLimit-Limit,X-RateLimit-Remaining이 포함되며, 할당량에 가까워지면X-RateLimit-Daily-Remaining도 포함됩니다.
요청 ID와 로그#
모든 응답에는 X-Request-ID 헤더가 있고, 모든 오류에는 request_id가 포함됩니다. 프로젝트의 로그 페이지에서 이 ID를 검색하면 엔드포인트, 상태, 지연 시간, 플레이어를 확인할 수 있습니다.