본문으로 건너뛰기

게임 (Game)

실시간 멀티플레이어 게임 API입니다. 두 가지 사용 방식을 제공합니다:

  • cb.game (GameAPI) — REST API: 룸 목록 조회, 매치메이킹 큐, 로비 관리
  • GameRoom 인스턴스 — WebSocket: 실제 게임 진행 중 상태 동기화 / 액션 / 채팅

GameRoom 생성

cb.game.createClient(config) 로 GameRoom 인스턴스를 생성합니다. appIdpublicKey 는 SDK 초기화 시 전달한 값을 사용하므로 별도로 넘기지 않아도 됩니다.

typescript
const room = cb.game.createClient({
  clientId: 'player-1',
  autoReconnect: true,
  maxReconnectAttempts: 5
})

// 이벤트 핸들러 등록 — 메서드 이름이 'on' + 이벤트명 형태
room.on('onConnect', () => console.log('게임 서버 연결됨'))
room.on('onDisconnect', (event) => console.log('연결 해제'))
room.on('onStateUpdate', (state) => console.log('상태 업데이트', state))
room.on('onPlayerJoined', (player) => console.log('입장', player))
room.on('onPlayerLeft', (player) => console.log('퇴장', player))
room.on('onChat', (msg) => console.log('채팅', msg))
room.on('onError', (err) => console.error(err))

룸 생성 / 참가 / 나가기

typescript
// 1) 먼저 WebSocket 연결을 열어야 합니다 — createClient() 는 객체만 만들고
//    실제 연결은 connect() 가 수행합니다. 이 호출이 빠지면
//    createRoom/joinRoom 이 "WebSocket is not connected" 를 던집니다.
await room.connect()

// 2) 새 룸 생성
const initialState = await room.createRoom({
  // roomId 생략 시 서버가 자동 발급
  maxPlayers: 4,
  tickRate: 64,
  metadata: { game_mode: 'deathmatch' }
})
console.log('룸 ID:', room.roomId)

// 또는 connect() 호출 시 roomId 를 같이 넘기면 연결과 동시에 입장됩니다
// await room.connect('room_xxx')

// 기존 룸 참가 (metadata 는 string→string 만 허용)
const joinedState = await room.joinRoom('room_xxx', { nickname: '홍길동' })

// 나가기 / 연결 해제
await room.leaveRoom()
room.disconnect()

게임 상태 / 액션 / 채팅

typescript
// 액션 전송 (서버가 액션을 처리해 모든 플레이어에게 브로드캐스트)
room.sendAction({
  type: 'attack',
  data: { target_id: 'player-2', damage: 50 }
})

// 상태 다시 조회 (보통 onStateUpdate 로 자동 수신됨)
const state = await room.requestState()

// 채팅
room.sendChat('안녕하세요!')

// 핑 (latency 측정)
const latencyMs = await room.ping()

룸 목록 조회 (cb.game REST)

typescript
const rooms = await cb.game.listRooms()
// 또는 특정 앱
const rooms2 = await cb.game.listRooms('app_xxx')

// 단일 룸 정보
const info = await cb.game.getRoom('room_xxx')

매치메이킹

typescript
// 매치 큐에 등록
const ticket = await cb.game.joinQueue({
  playerId: 'player-1',
  gameType: 'arena_5v5',
  rating: 1500,
  mode: 'ranked'   // 'ranked' | 'quick_play' | 'custom'
})

// 큐 상태 폴링
const status = await cb.game.getMatchStatus({ ticketId: ticket.ticketId })
if (status.roomId) {
  // 매치 성사 — 발급된 룸에 입장
  await room.joinRoom(status.roomId)
}

// 큐 취소
await cb.game.leaveQueue(ticket.ticketId)

로비

typescript
// 로비 목록
const lobbies = await cb.game.listLobbies()

// 로비 생성 (호스트)
const lobby = await cb.game.createLobby({
  playerId: 'player-1',
  displayName: '호스트',
  name: 'My Lobby',
  maxPlayers: 4,
  visibility: 'public',
  gameType: 'arena'
})

// 참가
await cb.game.joinLobby(lobby.id, 'player-2', '플레이어2')

// 준비 상태 토글
await cb.game.toggleReady(lobby.id, 'player-2', true)

// 호스트가 게임 시작 → 룸 ID 반환
const { roomId } = await cb.game.startGame(lobby.id, 'player-1')

// 호스트가 강퇴
await cb.game.kickPlayer(lobby.id, 'player-1', 'player-3')

// 나가기
await cb.game.leaveLobby(lobby.id, 'player-2')

📌 cb.game SDK 에는 별도의 리더보드 메서드가 없습니다. 점수와 순위는 cb.databasecreateData / queryData 또는 aggregate 로 직접 구현하세요. 자세한 패턴은 Game Server → 리더보드 를 참고하세요.