리더보드 Primitive
ConnectBase 게임 서버는 NATS KV 기반 sorted-score 리더보드를 primitive 로 제공합니다(FileStorage 영속화). ELO/티어 계산 같은 게임 고유 규칙은 사용자가 Lua 스크립트에서 submitScore 호출로 결과만 기록합니다.
SDK 사용
typescript
import ConnectBase from 'connectbase-client'
const cb = new ConnectBase({ appId: '...', publicKey: 'cb_pk_...' })
// 점수 제출 — mode "set" (기본, overwrite) 또는 "incr" (증감)
await cb.game.submitScore(cb.appId, 'global_elo', 'user_123', 32, 'incr')
// 상위 N명 (기본 10)
const { entries } = await cb.game.getTopScores(cb.appId, 'global_elo', 50)
// 특정 멤버 순위 + 점수
const me = await cb.game.getMemberRank(cb.appId, 'global_elo', 'user_123')
// 멤버 주변 (위 5명 + 본인 + 아래 5명)
const around = await cb.game.getRankAround(cb.appId, 'global_elo', 'user_123', 5, 5)
// 시즌 종료 등 전체 리셋
await cb.game.resetLeaderboard(cb.appId, 'global_elo')
// 계정 삭제 시 특정 멤버만 제거
await cb.game.removeFromLeaderboard(cb.appId, 'global_elo', 'user_123')REST API
| Method | Path | 설명 |
|---|---|---|
| POST | /v1/game/:appID/leaderboards/:key/scores | 점수 제출 (mode: set / incr) |
| GET | /v1/game/:appID/leaderboards/:key/top?n=10 | 상위 N명 |
| GET | /v1/game/:appID/leaderboards/:key/members/:member | 멤버 순위 |
| GET | /v1/game/:appID/leaderboards/:key/around/:member?above=5&below=5 | 멤버 주변 |
| DELETE | /v1/game/:appID/leaderboards/:key | 전체 리셋 |
| DELETE | /v1/game/:appID/leaderboards/:key/members/:member | 단일 멤버 제거 |
시즌 관리
별도 시즌 entity 가 없습니다. leaderboardKey suffix 로 분리합니다.
typescript
// 분기별 리더보드
await cb.game.submitScore(cb.appId, 'ranks:2026q2', 'user_123', 1500)
// 시즌 종료 시 키 폐기 (영속 데이터 정리)
await cb.game.resetLeaderboard(cb.appId, 'ranks:2026q1')안티치트
submitScore 는 클라이언트에서도 호출할 수 있지만, 권장 패턴은 게임 서버 Lua 가 룸 종료 시 점수를 계산해 호출하는 것입니다. 클라이언트가 임의 점수를 보내는 것을 막으려면:
- Lua 스크립트의
onAction에서 결과 검증 - 룸이 끝났을 때만 결과 commit
- createRoom 시
scriptName으로 활성 버전 고정 (없으면SCRIPT_NOT_FOUND반환)
자세한 안티치트 패턴은 안티치트 참고.