매치큐 Primitive
📌 2026-04-28 game v3.0 부터 서버가 관리하던 lobby/party/matchmaking 모듈은 모두 제거됐습니다. 대신
matchqueue/leaderboard/scripts3가지 primitive 와 사용자 Lua 조합으로 동일한 시나리오를 구현합니다. ELO/티어/지역/팀 균형 등 매칭 로직은 사용자가 Lua 스크립트로 작성하고, primitive 는 ticket 저장 / 조회 / 제거 만 책임집니다.
핵심 개념
queueKey: 모드/시즌별 큐 식별자 (예:ranked,casual,ranks:2026q2).ticketId: 클라이언트가 발급하는 고유 ID (충돌 회피 위해 보통 UUID).attributes: free-form Lua 매칭 후보 선별용 메타데이터 (rating, region, team_size 등).ttlSec: 0 이면 만료 없음, 양수면 해당 초 이후 자동 만료.
SDK 사용
typescript
import ConnectBase from 'connectbase-client'
const cb = new ConnectBase({ appId: '...', publicKey: 'cb_pk_...' })
// 1) 큐에 ticket 등록 — appId/queueKey/ticketId 는 [a-zA-Z0-9_-] 만 허용
const ticket = await cb.game.enqueueMatch(
cb.appId,
'ranked',
'tk_' + crypto.randomUUID(),
{ rating: 1500, region: 'asia', team_size: 5 },
60 // ttlSec
)
// 2) 큐 ticket 목록 조회 (보통 서버 Lua 가 호출)
const { tickets } = await cb.game.listMatchqueue(cb.appId, 'ranked')
// 3) 클라이언트가 매칭 취소
await cb.game.cancelMatch(cb.appId, 'ranked', ticket.ticket_id)REST API
| Method | Path | 설명 |
|---|---|---|
| POST | /v1/game/:appID/matchqueue/:queueKey/tickets | ticket 등록 |
| GET | /v1/game/:appID/matchqueue/:queueKey | ticket 목록 |
| DELETE | /v1/game/:appID/matchqueue/:queueKey/tickets/:ticketId | ticket 제거 |
모든 호출은 X-Public-Key 헤더가 필요합니다.
매칭 성사 패턴 (사용자 Lua)
primitive 는 후보 선별을 하지 않으므로 사용자가 직접 짝지어 룸 배정 + 알림 발송을 합니다. 일반적인 흐름은 다음과 같습니다.
- 룸 안에서 주기적으로
cb.game.matchqueue.list("ranked")호출 - Lua 코드로 rating 범위 / region / team_size 가 맞는 ticket 들을 그룹화
- 매칭 그룹이 만들어지면 새 룸 생성 + 각 ticket 사용자에게 broadcast
- 사용자가 룸에 join 하면 ticket 제거 (
cb.game.matchqueue.cancel)
자세한 Lua 예제는 Lua 스크립팅 와 RECIPES.md 를 참고하세요.
클라이언트 폴링 패턴
매치 성사를 클라이언트가 모르는 상황을 막기 위해 보통 다음 중 하나를 씁니다.
- WebSocket broadcast (권장): Lua 가 매칭 후
cb.realtime.publish로 룸 ID 전송 - 폴링: 클라이언트가 5초 간격으로
listMatchqueue호출하여 본인 ticket 이 사라지면 새 룸을 룸 목록에서 검색