본문으로 건너뛰기

매치메이킹

Connect Base 게임 서버는 플레이어를 적절한 룸에 매칭시키는 매치메이킹 기능을 제공합니다.

기본 매치메이킹

가장 간단한 매치메이킹은 빈 자리가 있는 룸에 자동으로 참가하는 것입니다:

typescript
const game = new GameRoom({
  appId: 'YOUR_APP_ID',
  clientId: 'player_123',
  publicKey: 'cb_pk_...'
})

await game.connect()

// 사용 가능한 룸 목록 조회
const rooms = await game.listRooms()

// 빈 자리가 있는 룸 찾기
const availableRoom = rooms.find(r => r.playerCount < r.maxPlayers)

if (availableRoom) {
  // 기존 룸에 참가
  await game.joinRoom(availableRoom.id)
} else {
  // 새 룸 생성
  await game.createRoom({ maxPlayers: 10 })
}

조건 기반 매치메이킹

메타데이터를 활용하여 특정 조건에 맞는 룸을 찾을 수 있습니다:

typescript
// 게임 모드와 맵으로 필터링
const rooms = await game.listRooms()

const matchedRoom = rooms.find(room => {
  return (
    room.metadata?.gameMode === 'ranked' &&
    room.metadata?.map === 'arena' &&
    room.playerCount < room.maxPlayers
  )
})

if (matchedRoom) {
  await game.joinRoom(matchedRoom.id, { rank: 'gold' })
} else {
  await game.createRoom({
    metadata: {
      gameMode: 'ranked',
      map: 'arena'
    },
    maxPlayers: 10
  })
}

스킬 기반 매치메이킹

플레이어의 실력에 맞는 룸을 찾습니다:

typescript
function findMatchBySkill(rooms: GameRoomInfo[], playerElo: number) {
  // ELO 차이가 가장 작은 룸 찾기
  const sortedRooms = rooms
    .filter(r => r.playerCount < r.maxPlayers)
    .sort((a, b) => {
      const eloA = parseInt(a.metadata?.avgElo || '1000')
      const eloB = parseInt(b.metadata?.avgElo || '1000')
      return Math.abs(eloA - playerElo) - Math.abs(eloB - playerElo)
    })

  return sortedRooms[0]
}

const myElo = 1500
const rooms = await game.listRooms()
const matchedRoom = findMatchBySkill(rooms, myElo)

if (matchedRoom) {
  await game.joinRoom(matchedRoom.id)
}

팀 매치메이킹

팀 밸런스를 고려한 매칭:

typescript
function findTeamMatch(rooms: GameRoomInfo[]) {
  return rooms.find(room => {
    const redTeam = parseInt(room.metadata?.redTeamCount || '0')
    const blueTeam = parseInt(room.metadata?.blueTeamCount || '0')

    // 팀 인원 차이가 2 이하인 룸 찾기
    return (
      room.playerCount < room.maxPlayers &&
      Math.abs(redTeam - blueTeam) <= 2
    )
  })
}

대기열 시스템 (고급)

서버리스 함수를 활용한 매치메이킹 대기열:

typescript
// 1. 대기열에 등록 (함수 호출)
const result = await cb.functions.invoke('matchmaking-queue', {
  playerId: 'player_123',
  gameMode: 'ranked',
  elo: 1500
})

// 2. WebSocket으로 매치 결과 수신
const realtime = cb.realtime.subscribe('matchmaking', 'player_123')

realtime.on('message', (msg) => {
  if (msg.type === 'match_found') {
    const roomId = msg.data.roomId
    game.joinRoom(roomId)
  }
})

매치메이킹 플로우

1. 플레이어 매치 요청
       │
       ▼
2. 조건에 맞는 룸 검색
       │
       ├─ 룸 있음 ──▶ 참가
       │
       └─ 룸 없음 ──▶ 새 룸 생성 or 대기