매치메이킹
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 대기