본문으로 건너뛰기

리더보드 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

MethodPath설명
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 가 룸 종료 시 점수를 계산해 호출하는 것입니다. 클라이언트가 임의 점수를 보내는 것을 막으려면:

  1. Lua 스크립트의 onAction 에서 결과 검증
  2. 룸이 끝났을 때만 결과 commit
  3. createRoom 시 scriptName 으로 활성 버전 고정 (없으면 SCRIPT_NOT_FOUND 반환)

자세한 안티치트 패턴은 안티치트 참고.