Category: Amazon GameLift


Amazon GameLift 커스터마이징 가능한 매치메이킹 기능인 FlexMatch 소개

멀티 플레이어 게임의 중요한 부분 중 하나는 플레이어가 신속하고 일관되게 만족스러운 경기에 참여하도록 하는 것입니다.

Amazon GameLift는 이런 경험을 제공하기 위한 개발자들의 부담을 덜어주기 위해 효율적인 매치메이킹 시스템인FlexMatch를 제공합니다. 이 기능은 강력한 매치메이킹을 신속하게 처리하는 데 사용할 수 있는 강력한 사용자 정의 기능을 제공합니다. 당신이 게임 기획자이든 백엔드 엔지니어든 관계 없이 FlexMatch의 사용자 정의 가능한 규칙 기반 구문은 개발 과정을 단순화하고 원하는 방식으로 매치메이킹을 할 수 있도록 합니다.  또한, 관리 콘솔에서 분석과 GUI를 사용하여 여러 설정을 빠르게 실험하여 경기의 품질에 미치는 영향을 확인할 수도 있습니다. GUI를 사용하면 실험을 원하는 게임 기획자가 직접 분석 데이터에 접근 할 수 있습니다.

이 글에서는 FlexMatch가 게임 세션 대기열과 어떻게 상호 작용하는지, 유연한 규칙을 사용하여 매치메이킹 및 자동으로 게임 배치를 수행하는 방법에 대해 설명합니다. 또한 분석을 사용하여 게임 규칙을 추적하는 방법을 설명합니다. 마지막으로, 게임의 매치메이킹 과정을 더욱 커스터마이징 할 수 있는 고급 FlexMatch 설정에 대해서도 설명합니다.

매치메이킹 시스템 설계를 위한 요구 사항
매치메이킹의 과제는 얼마나 빨리 매치가 되고 그 매칭이 얼마나 최적인지의 균형을 맞추는 것입니다. 게임 개발자인 여러분들이 플레이어를 가장 잘 압니다. 어쩌면 당신의 플레이어는 가능한 한 작은 대기 시간을 원할 것입니다. 어쩌면 최선의 경기를 위해 오랜 시간을 기다릴 수도 있습니다. 아마, 매치메이킹 이런 두 가지 기준간 균형을 맞추어야 할지도 모릅니다.

플레이어들에게 일어나는 매치메이킹은 간단하게 보입니다. 개발자는 유연하고 효율적인 매치메이킹 시스템을 만들고 관리하는 것이 단순하다는 것을 알고 있습니다. 어디서부터 시작해야 할까요? 플레이어가 성공으로 간주 할 시스템을 어떻게 구축합니까? 다음은 매치메이킹 시스템 설계 시 묻는 몇 가지 질문입니다.

  1. 플레이어는 얼마나 오래 기다릴 수 있을까요? 여러분들은 게임 플레이어들의 속성을 잘 압니다. 그래서 여러분은 경기를 기다리는 그들의 의지에 대해 어떻게 생각하십니까? 어쩌면 그들은 빨리 매치하고 싶을 수도 있고, 아마도 가장 좋은 매치를 기다리고 싶을 수도 있습니다. 게임 세션 길이가 매치메이킹에 대해 어떤 의미를 가질까요? 짧은 세션의 게임의 경우 가능한 한 적은 시간 내에 가능한 한 많은 매치메이킹이 되는 방식으로 최적화 되기를 원할 것입니다. 더 긴 세션 시간을 가진 게임의 경우 플레이어는 더 나은 경기를 찾기 위해 더 오래 기다리는 것을 선호 할 수 있습니다. 여러분의 플레이어 기반은 서로 다른 요구를 가진 경쟁력 있는 캐주얼 게이머를 보유하고 있습니까? 이 경우, 빠른 매칭을 원하는 캐주얼 플레이어와 보다 균형 있고 경쟁적인 매치를 원하는 플레이어들을 위한 매치메이킹 로직을 여러 개 설정할 수 있습니다.
  2. 플레이어는 지연(latency) 시간에 얼마나 영향을 받습니까? 일반적으로 플레이어는 가능한 한 플레이어의 클라이언트와 서버 사이에서 가장 낮은 지연 시간을 원하며 동일한 낮은 지연 시간을 공유하는 플레이어와의 경기를 원합니다. 플레이어들의 지연 시간과 관련하여 그들이 허용하는 수준은 어떻습니까? 플레이어가 비슷한 지연 시간을 가진 플레이어와 더 긴 시간을 함께 기다릴 의향이 있습니까? 플레이어는 지연 시간에 관계없이 친구와 게임을 우선시합니까? 지연 시간과 관련하여 우선 순위가 다른 여러 플레이어가 있습니까? 여기서 답을 알고 있으면 플레이어를 구분하는 방법을 결정하는 데 도움이 됩니다.
  3. 플레이어의 숙련도(skill)얼마나 중요합니까? 플레이어는 게임을 재미있게 만드는 방법을 여러 가지 방법으로 정의하고 동일한 숙련도 수준을 가진 다른 플레이어와 함께 플레이 하는 것이 게임을 재미있게 유지하는 데 많은 도움이 됩니다. 비슷한 숙련도를 가진 플레이어와의 경기에 귀중한 가치를 부여합니까? 그들은 도전하는 것을 선호하고 그들이 가진 것보다 더 나은 플레이를 원하고 있습니까? 그들은 숙련도에 전혀 신경 쓰지 않고 가능한 한 빨리 매치하고 싶습니까? 플레이어의 숙련도가 당신의 매치메이킹에 어떻게 부합하는지 이해하면 생성 된 매치를 더 세분화하는 데 도움이 됩니다.
  4. 여러분의 매치메이킹은 얼마나 유연합니까? 대기 시간, 지연(latency) 시간 및 숙련도 레벨 모두가 매치메이킹에 영향을 미치므로 시스템이 얼마나 유연해야 하는지에 질문을 해야 합니다. 우선 순위를 결정하고 선택할 수 있습니까? 선택 사항이 플레이어에게 미치는 영향을 알려주는 분석 기능이 있습니까? 여러분의 시스템은 이상적인 상황에서도 게임을 찾기 위해 자동으로 매치메이킹 요구 사항을 자동으로 완화합니까? 시스템을 통해 플레이어를 분류하여 모든 사람에게 최고의 경험을 제공 할 수 있습니까?

얼마전 Amazon GameLift 및 기타 AWS 서비스를 사용하여 서버리스 매치메이킹 패턴을 만드는 방법을 설명했습니다. 이제는 FlexMatch의 강력하고 유연한 매치메이킹 기능을 통하여 다음 단계로 나아가 봅시다.

FlexMatch 사용법
표면적으로, FlexMatch는 상대적으로 단순해 보이지만 깊이와 유연성이 있습니다. FlexMatch의 기능 중 일부는 Amazon GameLift의 게임 세션 대기열에 직접 연결되어 있습니다. FlexMatch를 사용하면 선택한 기준에 따라 플레이어를 특정 항목으로 그룹화 할 수 있습니다. 그런 다음 대기열을 사용하여 모든 플레이어를 특정 플랫폼이나 특정 지역 또는 게임 모드/맵/언어에 따라 배치할 수 있습니다. FlexMatch와 대기열을 함께 사용하면 여러 지역의 플레이어들 심지어 여러 지역에서도 최적화된 저 지연(low latency)의 경험을 제공 할 수 있습니다. 대기열 기능과 함께 FlexMatch를 사용하는 방법을 더 잘 이해할 수 있도록 FlexMatch 구성부터 시작하는 예시를 살펴 보도록 하겠습니다.

세션 기반의 슈팅 대전 게임이 최소 4 명의 플레이어와 (팀당 최대 8 명의 플레이어) 동일한 팀 크기의 대전 상대를 필요로 한다고 가정 해 봅시다. 플레이어들은 경쟁적인 경기를 원하기 때문에 팀은 서로 평균 10 점 이내의 평균적인 플레이어 숙련도 점수를 가져야 합니다. 마지막으로, 플레이어가 경기를 찾기 위해 너무 오래 기다리는 것을 원하지 않으므로, 5 초 후 팀 간 50 포인트 이내의 평균 숙련도 점수와 15 초 후 팀 간 100 포인트로 규칙을 완화하려고 합니다.

다음은 위의 상황에 맞게 FlexMatch 규칙(Rule)을 구성하는 방법입니다.

{
    "name": "aliens_vs_cowboys",
    "ruleLanguageVersion": "1.0",
    "playerAttributes": [{
        "name": "skill",
        "type": "number",
        "default": 10
    }],
    "teams": [{
        "name": "cowboys",
        "maxPlayers": 8,
        "minPlayers": 4
    }, {
        "name": "aliens",
        "maxPlayers": 8,
        "minPlayers": 4
    }],
    "rules": [{
        "name": "FairTeamSkill",
        "description": "The average skill of players in each team is within 10 points from the average skill of players in the match",
        "type": "distance",
        // get skill values for players in each team and average separately to produce list of two numbers
        "measurements": [ "avg(teams[*].players.attributes[skill])" ],
        // get skill values for players in each team, flatten into a single list, and average to produce an overall average
        "referenceValue": "avg(flatten(teams[*].players.attributes[skill]))",
        "maxDistance": 10 // minDistance would achieve the opposite result
    }, {
        "name": "EqualTeamSizes",
        "description": "Only launch a game when the number of players in each team matches, e.g. 4v4, 5v5, 6v6, 7v7, 8v8",
        "type": "comparison",
        "measurements": [ "count(teams[cowboys].players)" ],
        "referenceValue": "count(teams[aliens].players)",
        "operation": "=" // other operations: !=, <, <=, >, >=
    }],
    "expansions": [{
        "target": "rules[FairTeamSkill].maxDistance",
        "steps": [{
            "waitTimeSeconds": 5,
            "value": 50
        }, {
            "waitTimeSeconds": 15,
            "value": 100
        }]
    }]
}

Figure 1 – Example FlexMatch rules syntax.

이렇게 매치메이킹을 구성한 후, 대기열을 구성하도록 합니다.

아시아의 모든 플레이어가 서로 어우러지길 원한다고 가정 해 봅시다. 이를 위해 매치메이커를 서울 (ap-northeast-2) 또는 동경(ap-northeast-1) 리전에 설치 한 다음, GameLift Fleet을 위한 대기열은 서울 (ap-northeast-2), 동경 (ap-northeast-1), 싱가포르 (ap-southeast-1) 리전에 둘 수 있습니다.  이 대기열은 플레이어 지연 시간을 사용하여 매치된 플레이어 세트가 가장 낮은 지연 시간을 갖도록 구성 될 수 있습니다. 최저 지연 시간 기반 배치 방법은 기존 블로그 글을 참고하세요.

해외 리전에서 게임을 출시할 계획이라면 추가 매치메이커와 대기열을 만들고 각 리전 또는 리전 그룹마다 다른 매치메이킹 규칙을 설정할 수 있습니다. 이 접근 방식은 전 세계 다른 리전에서 다른 버전의 게임을 출시 할 때 특히 유용합니다. 또한 플레이어의 취향에 따라 정규전 (래더 게임) 대기열과 야생전 (캐주얼 게임) 대기열로 분리 할 수도 ​​있습니다.

즉, FlexMatch는 규칙(Rule)을 사용하여 매치 조건을 조합하고 대기열 구성을 사용하여 게임 서버에 매치된 플레이어들을 배치하는 구조입니다. 또한, 대기열의 깊이에 따라 GameLift의 자동 확장 기능을 연동할 수도 있습니다. 대기열에 있는 플레이어의 수에 따라 더 빠르게 게임 서버들을 자동으로 늘이거나 줄일 수 있습니다.

고급 규칙(Rule)
FlexMatch 규칙에는 플레이어 경험을 더욱 세밀하게 제어 할 수 있는 고급 기능도 있습니다. 예를 들어, 깃발 잡기 (Capture the Flag) 또는 특정 맵 종류 선호와 같은 특정 게임 모드를 선호하는 플레이어를 함께 그룹화 할 수 있습니다. 또한 플레이어 캐릭터의 여러 클래스 중 적어도 하나를 특징으로 하는 팀과의 경기를 만들 수도 있습니다. 예를 들어, 게임을 시작하기 전에 유효한 팀에게 전사가 1 명, 도적이 1 명, 마법사가 1 명 이상 필요하다고 결정할 수 있습니다. 새로운 게임 모드를 지원하기 위해 1 대 5대전과 같은 비대칭 매치메이킹을 허용 할 수도 있습니다. 간단히 말하면, FlexMatch의 다양한 옵션을 통해 세심한 컨트롤이 가능합니다.

규칙(Rule)어떻게 동작하는지 분석할 있는 기능 제공
FlexMatch 규칙을 모니터링하고 최적화하는 것은 게임 디자인을 섬세하게 조정하는 중요한 부분입니다. 규칙을 모니터링하기 위해 FlexMatch는 관리 콘솔을 통해 쉽게 액세스 할 수 있는 일련의 통계를 제공합니다. 게임을 테스트 할 때 이러한 통계 분석을 통하여 플레이어 환경의 균형을 맞출 수 있습니다. 측정할 수 있는 항목은 다음과 같습니다.

  • Match Success/Failure Rates: 예상되는 플레이어를 그룹화하여 게임에 신속하게 참여시킬 수 있는 매치메이커의 결과를 확인하세요. 매치메이커가 제안한 매치를 얼마나 잘 수용하는지 보기 위해 플레이어가 수락하거나 거절하는 비율을 추적합니다.
  • Player Demand: 현재 처리중인 매치 요청 수를 확인하십시오. 새로운 요청 및 새 플레이어의 비율을 추적하여 플레이어 수요 급등에 대한 사전 통지를 얻을 수 있습니다.
  • Time to Ticket Success: 새로운 매치를 성공적으로 생성하는 데 걸리는 평균 시간을 모니터링 합니다. 이 데이터를 사용하여 가능한 가장 최적의 매치 결과를 찾는 것과 플레이어를 게임으로 빠르게 매치하는 것 사이에서 균형을 찾는데 도움이 됩니다.
  • Matchmaking Rule Effectiveness: 매치메이커에서 개별 규칙의 성공/실패 비율을 추적합니다. 이 데이터를 사용하여 각각의 규칙을 미세 조정하여 매치메이킹 규칙을 전반적으로 최적화할 수 있습니다.

매치메이킹 규칙에 대한 세부 정보는 개발자 가이드를 참고하세요.

예를 들어, 분석 결과 매치 요청의 80 %가 시간 초과되었다고 표시되면 규칙이 너무 엄격하기 때문에 규칙을 수정해야 할 필요가 있습니다. 좋은 플레이어 경험에 대한 정의에 따라 매치메이킹에 걸리는 시간이 초과되는 (Time Out) 경우를 10% 이내로 하기를 추천드립니다. 반대로, 여러분의 매치메이킹 요청 시간 중 2% 만 시간 초과 될 수 있습니다. FlexMatch 규칙이 완벽할 수 있지만, 또 다른 문제를 가질 수 있습니다. (지루하거나 대전하기 편한 상대와 일상적인 게임만 하게 될 수도 있습니다)  그래서, 분석 기능을 사용하여 이 같은 주요 문제를 다음과 같은 방식으로 추적할 수 있습니다.

이러한 분석 데이터를 AWS Lambda에 연결하여 특정 기능을 수행하거나 통지를 받을 수도 있습니다.

규칙 완화
예제 규칙에 표시된 것처럼 매우 유용한 FlexMatch 기능 중 하나는 규칙 완화입니다. 규칙 완화를 사용하면 플레이어가 경기를 기다릴 때 플레이어 기준을 완화하는 시기와 방법을 제어 할 수 있습니다. 규칙 기반 프레임 워크에서는 직관과 어긋나게 느낄 수도 있지만 규칙을 완화하면, 매치되기 어려운 플레이어가 다음 게임으로 빠르게 진입하는 데 도움이 됩니다. 예를 들어, 숙련도 레벨의 범위 내에 있는 플레이어들만을 포함 시키길 원할 수 있습니다. 숙련도 레벨 차이는 +/- 10 포인트를 초과해서는 안되길 원하더라도 플레이어 풀에 해당 범위 내의 플레이어가 충분하지 않으면 이 규칙을 완화해야 합니다. 어쩌면 플레이어가 +/- 15 포인트로 완화한 조건을 대신 사용하기를 기대할 수도 있습니다.

또 다른 예로, 플레이어가 적어도 90 초 동안 기다린 후에 더 먼 지역의 플레이어를 검색하기 위해 규칙을 완화해야 할 수도 있습니다. 즉, 남아시아 지역의 플레이어가 동아시아 지역에 배치 될 수 있음을 의미합니다. 대기 시간은 약간 더 높을 수 있지만, 매치메이킹을 더 기다리는 대신 플레이어가 바로 게임을 시작할 수 있습니다.

궁극적으로, 이러한 상황들은 (예를 들어, 언제 얼마나 어려운 경기를 펼칠 수 있는 플레이어를 규칙을 완화해야 하는지) 여러분이 대답 할 수 있는 질문입니다. FlexMatch를 사용하면 매치 조건에 잘 맞지 않는 경우도 허용 할 수 있도록 선택할 수 있습니다.

마무리하며
FlexMatch는 게임 관리의 중요한 부분을 자동화하는 동시에 깊이 맞춤식 멀티 플레이 환경을 만드는 데 필요한 강력한 기능과 유연성을 바탕으로 매치메이킹 프레임워크를 제공합니다. 이것은 멀티 플레이어 게임 관리를 강력하고 유연하고 빠르고 비용 통제 가능하도록 합니다. FlexMatch를 시작하려면 Amazon GameLift SDK를 다운로드하고 게임을 Amazon GameLift에 업로드 한 다음 규칙 구성을 시작하세요.

이 글은 Matchmaking, Your Way: Amazon GameLift FlexMatch and Game Session Queues의 한국어 번역으로, Amazon Game Services의 구승모 엔지니어가 번역하였습니다. 저자인 Justin Miles는 Amazon GameLift 팀의 소프트웨어 엔지니어이며 지난 3 년 동안 Amazon에서 근무했습니다. 그는 펜실베니아 주립 대학을 졸업했으며 전자 상거래, 건강 관리 및 게임을 비롯한 여러 산업 분야에서 10 년을 보냈습니다. 현재 그는 Hex TCG와 젤다: 야생의 숨결을 플레이하고 있습니다. 또한 마리오, 젤다의 전설, 볼펜 슈타인의 광팬입니다.

 

Amazon GameLift를 통한 맞춤형 서버리스 매치메이킹 서비스 만들기

세션 기반의 멀티플레이어 게임에서 가장 중요한 요소의 하나는 사용자의 숙련도, 접속 속도, 위치 등의 제약에서 벗어나면서 효율적이고 지능적으로 사용자들에게 재미있고 도전할만한 게임 매치를 제공할 수 있는지 여부일 것입니다. 시스템은 이전의 모든 경기 이력을 바탕으로 안정적이고 유연하게 성공적인 멀티플레이어 경험을 제공하는 것이 목표입니다.

2017년 GDC(Game Developers Conference)에서 Chris Byskal과 Geoff Pare는 Amazon GameLift를 통하여 내구성 있는 온라인 게임을 만드는 것에 대한 세션을 진행 했었습니다. 여기에서 Chris와 Geoff는 GameLift롤 통하여 클라우드 환경에서 다양한 형태의 게임을 구성하는 과정을 단순화 할 수 있는지를 이야기했습니다. GameLift를 통하여 어떤 방법으로 수천 시간의 개발 시간을 줄이고, 유휴 서버를 줄이고, DDoS공격에서 보호하고, 그리고 매치메이킹과 자동화된 스케일링을 지원할 수 있는지를 설명했습니다.

이 블로그 글은 Chris와 Geoff의 발표에서 거론되었던 플레이어 매치 메이킹의 패턴에 대하여 좀 더 자세히 살펴보고, 그리고 게임에 따라 독자적으로 사용할 수 있는 사용자 사이의 매치메이킹 알고리즘, 그리고 사용자들을 서버에 연결할 수 있는 아키텍쳐를 살펴볼 것입니다.  덤으로, 실제 여러분의 게임에서 사용할 수 있는 사용자 정의 맞춤형 매치메이킹 코드 예제를 살펴보도록 하겠습니다.

이러한 형태의 서버리스 접근 방법은 많은 장점을 가지고 있습니다. 전통적인 환경에서 접할 수 있는 (다른 회사와 비교해서 차별화되지 않는) 통상업무 부담을 줄여줄 수 있습니다. 그리고 복잡한 백앤드의 구축을 단순화하여 게임 로직 자체에 집중 할 시간을 늘려 준다는 점이 가장 중요하다고 할 수 있습니다.

플레이어 매칭 패턴에 대하여
최근의 멀티 플레이어 게임은 크게 두가지 경향을 보이고 있습니다. 첫번째는 사용자가 직접 접속할 서버를 찾아서 선택하는 방법, 두번째는 매치 메이킹 서버를 통하여 자동으로 여러 사용자들을 연결해주는 형태입니다.

사용자가 직접 서버를 선택하는 방법은 구현하기가 상대적으로 간단합니다. 사용자에게 게임을 할 수 있는 서버의 목록을 전달하는 것이 전부입니다.

Game Server Browser Example

그림-1 : 서버 목록 찾기의 예제

만일 개발자가 이러한 형태로 구현할 경우, GameLift는 다음의 3가지 API콜을 이용하여 클라이언트에서 이러한 방법을 쉽게 구현 할 수 있는 몇 가지 방법을 제공하고 있습니다.

  • 게임 서버의 목록 취득 – GameLift는 사용자가 지정하는 검색 항목을 사용한 검색을 지원합니다. 서버 브라우징을 사용 하는 경우, 모든 게임 세션을 검색 결과로 보여주거나 현재 사용 가능한 세션만 결과로 보여줄 수가 있습니다. 더욱 자세한 사항은 해당 API문서를 참고하시면 됩니다. (Amazon GameLift SearchGameSessions() API documentation)
  • 지정한 게임에 참가 – 사용자는 자신이 속한 그룹이나 길드와 함께 특정한 게임에 참가하는 것이 가능합니다. 일단 사용자가 게임 세션을 지정하면 시스템은 그 사용자를 해당 게임에 참가 시킵니다. 만일 게임 세션에 추가로 참가 할 수 있는 여유가 있으면 GameLift가 해당 슬롯들을 선점하여 해당 정보를 전달하게 됩니다. 이러한 방법으로 사용자가 게임 세션을 선택하면, 참가 신청을 하는 순간 모든 세션이 가득 찰 수도 있게 됩니다. 좀 더 자세한 사항은 관련 문서를 참고하시기 바랍니다. (Amazon GameLift CreatePlayerSession() API Reference.)
  • 새로운 게임 시작 – GameLift는 사용자 요청에 의하여 새로운 게임 세션을 만들 수도 있습니다. 생성이 되면 해당 게임 세션은 서버 목록에서 공개적으로 검색이 될 수 있습니다. 사용자는 또한 공개되지 않는 비공개 게임 세션을 만들 수도 있습니다. 자세한 사항은 관련 문서를 참고 하시기 바랍니다. (Amazon GameLift CreateGameSession() API Reference)

서버 검색 방식은 간단하고 사용자들이 직접 목록에서 원하는 게임을 선택할 수 있는 기회를 제공합니다. 또한 개발자들에게도 구현이 간단하다는 장점이 있습니다. 하지만 이러한 간단하고 직관적인 형태로는 사용자들에게 최적의 게임 경험을 제공 할 수 없을 수도 있습니다. 사용자의 팀/ 숙련도, 또는 기타 게임의 중요한 요소들을 고려하지 않는 매치들은 균형 잡히지 않은 일방적인 게임진행으로 참가한 모든 이들에게 즐겁지 않은 경험만 남길 수도 있습니다.

서버 검색 방식은 또한 여러분의 게임 인프라를 전체적으로 균형 잡힌 활용을 어렵게 할 수 있습니다. 왜냐하면 사용자들은 인프라의 상태를 고려할 수 없고 이로 인하여 특정 지역의 서버에 몰리는 현상을 가져올 수 있기 때문입니다. 이는 결과적으로 인프라 전반적으로 사용자 분배를 어렵게 하고, 또한 불필요하게 높은 비용을 가져다 줄 수 있습니다.

매치메이킹은 다른 접근법을 활용합니다. 사용자가 게임에 참가 요청을 하면 매치메이킹 알고리즘을 통하여 다양한 변수 – 사용자의 숙련도, 서버 레이턴시, 친구목록, 팀/ 그룹등 – 를 고려하여 매치를 선택해줍니다. 사용자들은 따라서 조금 더 자신과 비슷한 실력의 상대와 게임을 즐길 수 있습니다.

또한 이 방법은 사용자들을 게임 서버 사이에 더더욱 효율적으로 분배 할 수 있고 효율적인 세션 활용을 통하여 운영비용을 줄일 수가 있습니다. 매치메이킹의 단점은 구현이 더욱 복잡하다는 점입니다.

서버리스로 매치메이킹 시스템 만들기
매치매이킹을 사용하기로 결정하면 가장 먼저, 매치메이킹 시스템을 만들어야 합니다. 여기에서는 간단하게 서버리스로 맞춤형 메치메이킹을 어떻게 구현할 수 있는지를 살펴보도록 하겠습니다. 아래의 그림 2의 간단한 아키텍쳐를 그리고 있습니다. 이 아키텍쳐 안에는

  • 사용자 정의 변수, 또는 알고리즘을 사용한 매치메이킹 시스템
  • 게임서버 관리
  • 게임세션 관리
  • 서버 인스턴스의 오토스케일링
  • 게임 연결 흐름도

들을 보여주고 있습니다.

이 서버레스 매치메이킹 시스템은 크게 3단계로 구현되고 있습니다.

Serverless Custom Matchmaking Example Architecture

그림 2 – 서버레스로 구현한 맞춤형 매치메이킹 아키텍쳐

 

  1. 게임 참가 요청
    첫번째 단계에서 사용자는 게임 클라이언트를 통하여 게임 참가 요청을 합니다. 게임 클라이언트는 Amazon API Gateway의 엔드포인트를 호출합니다. 이 엔드포인트는 우리의 매치메이킹 로직을 실행하는 람다함수를 호출하고, 이 람다 함수는 게임리프트와 연동하여 적합한 게임 세션을 찾아줍니다. API게이트웨이는 개발자들이 API를 만들고 안전하게 관리할 수 있도록 도와주는 관리형 서비스입니다. API게이트웨이를 사용하는 것은 게임 클라이언트와 람다함수/ 게임리프트사이를 추상화 할 수 있기 때문입니다. 이는 아래와 같은 상황에 대한 유연성을 가져다 줍니다.

    • 버전관리 – 게임 클라이언트는 백앤드의 변화에 대하여 종속될 필요가 없습니다. 이는 몇가지 장점을 가지는데, 새로운 기술을 적용하기 쉬워집니다. 또한 새로운 게임리프트의 적용을 부드럽게 진행할 수 있습니다, 그리고 A-B테스팅을 쉽게 적용할 수 있습니다.
    • 운영 메트릭 확보 – API 게이트웨이와 Amazon CloudWatch를 함께 활용하여 제작하는 API의 퍼포먼스의 확인으로 매치메이킹 서비스에서 발생할 수 있는 다양한 문제들을 빨리 파악할 수 있도록 도와줍니다.
    • 보안 – API 게이트웨이와 함께 Amazon Cognito와 같은 AWS의 다양한 보안 도구를 활용하여 API의 활용을 인증을 거친 활용의 제어를 손쉽게 활용할 수 있습니다. 이를 통하여 손쉽게 구현하고 관리 할 수 있는 인증 시스템을 제공 할 수 있습니다.
  2. 게임 찾기
    두번째 단계에서 우리는 AWS람다(AWS Lambda) 함수를 활용하여 매치메이킹을 구현할 것입니다. 람다를 통하여 서버를 할당하거나 관리할 필요없이 여러분의 코드를 클라우드상에서 실행할 수 있습니다. 람다에 코드를 배포하는 것은 여러분의 코드를 단순히 업로드 하는 것으로 구현됩니다. 람다는 이후, 코드의 실행과 스케일링에 필요로 하는 여러사항들을 자동으로 관리하게 됩니다. 여러분의 코드는 또한 다양한 AWS서비스에서 호출되거나 다른 웹서비스, 앱에서 호출될 수 있습니다. 매치메이킹은 실행시간이 짧고 비교적 자주 호출 되기 때문에 이러한 환경에서 상당히 효율적인 방법일 수가 있습니다. 서버 관리는 최소한으로 유지하면서 반대로 가용성은 최대로 유지됩니다. 람다의 사용료는 호출횟 수, 그리고 각 호출에서 실행 시간 100ms당 책정됩니다. 여러분은 또한 여러 버전의 프로세스를 함께 실행할 수도 있습니다. 이를 통하여 폭 넓은 게임클라이언트와 많은 사용자들을 지원할 수도 있습니다. 이러한 점을 염두에 두고 3가지 람다 함수를 만들어보겠습니다.

    • 매치 메이킹에 들어가기 – 이 함수는 게임 클라이언트로부터의 게임 참가 요청을 처리합니다. 이 함수는 요청을 받고, 동시에 클라이언트로부터 전달되는 필요 정보를 파악합니다. 그리고 이 정보들을 아마존DynamoDB(Amazon DynamoDB)의 게임 참가 대기자 테이블에 추가합니다. 이 함수는 그리고 클라이언트에게 매치메이킹이 진행중이라고 알려줍니다. (그리고 클라이언트는 사용자에게 그 사실을 전달하게 됩니다.)
    • 메치메이커 – 이 함수는 주기적으로 실행되어 매칭할 수 있는 플레이어 그룹을 생성하고 그 그룹들이 새로운 게임 세션에 참가할 수 있도록 해줍니다. 여기에서 게임의 매치메이킹로직이 적용됩니다. 이 함수가 호출될 때마다 아까 만들었던 테이블의 대기자 사이에서 로직을 적용하여 가까운 그룹으로 분류합니다. 온전한 그룹이 만들어지면 해당 그룹은 게임 세션에 참가 가능하다고 분류됩니다. 함수는 이 정보를 아까의 DynamoDB테이블에 기록하고 종료됩니다. 아래의 그림 3에 이러한 로직에 대한 예제 코드가 있습니다.
    • 서버 접속기 – 이 함수는 정기적으로 게임 서버에 할당할 수 있는 그룹을 확인하고, 게임 세션 생성 요청을 합니다. 이는 게임리프트의 CreateGameSession API를활용합니다.
Python
def get_unmatched_players():
        table = dynamodb.Table(table_name)
        response = table.scan(
            FilterExpression=Attr('MatchStatus').eq('Open')
        )
        players = response['Items']
        
        print("Number of players watching for matches: " + str(len(players)))
        
        return players
        
def create_groups(players):
    print('Creating Groups')
    groups = list()
    
    # Sort players by skill
    players = sorted(players, key=lambda player: player['Skill'])
    
    # Group players into match sized groups
    while (len(players) >= match_size):
        new_group = {'Players': list()}
        for i in range(0, match_size):
            new_group['Players'].append(players.pop(0))
            
        groups.append(new_group)

    print("Number of groups created: " + str(len(groups)))
    
    return groups

그림 3 – 매치메이킹 로직의 파이썬 예제

게임 서버 할당을 통하여, Amazon GameLift는 알고 있는 리전의 여러 서버 Fleet들 중에서 가장 적당한 호스팅 리소스를 할당합니다. 또한 새로운 게임 세션을 생성하여 앞의 그룹을 할당할 수 있습니다.

게임리프트에서 새로운 세션 할당 요청은 (game session queue)에 할당됩니다. 따라서 우리는 하나, 또는 그 이상의 서버 Fleet를(어떤 지역에 있어도 상관없습니다) 가지고 있는 큐를 만들고, 더불어 요청에 대하여 어느정도의 시간을 쓸지를 결정하는 타임아웃 수치를 지정합니다.

할당 요청을 처리할 때, 게임리프트는 큐에 할당 되어있는 모든 Fleet 대상으로 요청에 적합한지 살펴보고 응답하게 됩니다. 만일 적합한 Fleet이 없어서 판단하지 못할 경우 타임아웃이 발생하게 됩니다. 기본적으로 게임 리프트는 큐 구성에 나열 되어있는 순서대로 Fleet들을 살펴봅니다. 이를 통하여 새로운 게임 서버 구성 요청에 대하여 각 Fleet에 대한 우선도를 지정할 수도 있습니다.

아주 낮은 지연속도가 필요로 하는 게임의 경우, 게임리프트는 지연속도 정보를 바탕으로 그룹의 모든 사용자에 대하여 가장 낮은 평균 지연을 경험할 수 있는 지역으로 할당 할 수도 있습니다.

이러한 기능을 활용하기 위해서는 우리는 클라이언트로부터 모든 지역에 대한 지연 속도 정보를 모아야 합니다. 여러 사용자로부터 지연 속도 정보를 받으면, 게임 리프트는 큐의 서버 Fleet정보를 평균 Lag이 낮은 순서로 우선 순위를 변경하게 됩니다.

이 부분에 대한 자세한 내용은 이전의 블로그 글을 참고하세요

그림 4의 코드는 게임 세션 할당 요청에 대한 예제 코드입니다. 코드의 StartGameSessionPlacement() 함수는 큐 이름을 전달 받습니다. (이 큐 이름은 큐 구성에서 지정한 것입니다.)

게임리프트는 또한 고유한 할당 ID를 필요로 합니다. 우리는 이 ID를 활용하여 요청의 상태를 추적하게 됩니다. 개발자가 할당 ID를 정의하면 되고, 단지 상호간의 고유성만 보장되면 됩니다. 아래의 예제에서는 UUID를 사용하며, 호출자에게 전달되어 이후 처리됩니다.

부가적으로, 우리의 할당 요청은 세션의 게임과 플레이어 ID를 요청할 수도 있습니다. 만일 해당 정보가 전달되면, AWS콘솔을 통하여 게임 세션들을 사용자가 보는 것처럼 확인할 수 있습니다. 이를 통하여 언제 얼마나 사용자들의 활동이 있는 지를 확인할 수가 있습니다.

새로운 게임 세션 할당은 PENDING 상태로 만들어집니다. 아래의 예제 코드는 할당 요청에 대한 응답을 표시하게 되어있습니다. 할당 요청의 결과 상태에 따라서 추후 작업도 진행할 수 있습니다. 예를 들어 만일 PENDING 응답이 전달되면, 우리는 게임 클라이언트에게 곧 세션이 시작됨을 알리고 이후의 상태 확인 상태로 들어갈 수 있습니다. 만일 할당 요청이 타임 아웃이 발생하면 다른 큐를 통하여 할당 요청을 다시 보낼 수가 있을 것입니다.

Python
def start_game_placement(queue_name, group):
    print("Starting Game Session Placement")
    
    placement_id = str(uuid.uuid4())

    desiredPlayerSessions = list()

    for player in group['Players']:
        desiredPlayerSessions.append({ 
                'PlayerId':  player['PlayerId'],
                'PlayerData':  player['Skill']
        })

    response = gamelift.start_game_session_placement(
	    PlacementId=placement_id,
	    GameSessionQueueName=queue_name,
	    GameProperties=[
	        {
	            'Key': 'Skill_Level',
	            'Value': 'Highest'
	        },
	    ],
	    MaximumPlayerSessionCount=match_size,
	    GameSessionName='My Matched MP Game',
        DesiredPlayerSessions= desiredPlayerSessions
	)

    print("Game Session Status: " + response['GameSessionPlacement']['Status'])
    
    return placement_id
    
def update_players_in_group_for_match(group):
    for player in group['Players']:
        update_player(player, group['PlacementId'], 'Matched')
    
def update_player(player, placement_id, status):
    print('Updating Player with Placement Id and setting status to Matched')
    
    table = dynamodb.Table(table_name)
    
    response = table.update_item(
        Key={
            'PlayerId': player['PlayerId'],
            'StartDate': player['StartDate']
        },
        UpdateExpression="set PlacementId = :g, MatchStatus= :t",
        ExpressionAttributeValues={
            ':g': placement_id,
            ':t': status
        },
        ReturnValues="UPDATED_NEW"
    )

 

그림 4 –게임리프트의 세션 할당의 예제 파이썬 코드

  1. 게임에 접속하기
    세번째 단계에서 게임 클라이언트는 람다 함수와 게임리프트를 통하여 게임 세션에 관련한 상세한 정보를 수령합니다. 게임 클라이언트들은 이제 게임 서버에 직접 접속하여 게임을 시작할 수가 있습니다. 게임 클라이언트가 게임 서버에 직접 연결한다는 점은, 게임리프트가 게임 진행 자체에 어떠한 레이턴시도 더하지 않는다는 것을 의미합니다.

결론
멀티플레이어 게임은 계속해서 인기를 누리고 있습니다. 이러한 환경에서 성공하기 위해서는 빠르고, 부드러운 확장성과 함께 수백만 사용자들이 선호할 수 있는 높은 수준의 안정성을 지원 해야할 것입니다.

많은 멀티플레이어 게임은 개성적인 매치메이킹을 통하여 비슷한 수준의 사용자들과 함께 게임을 진행하는 최적의 경험을 제공할 수 있습니다. 많은 장르의 게임 사용자들은 자신과 유사한 수준의 상대와 수준 높은 매체메이킹을 기대하게 됩니다. 따라서 여러분의 게임의 성공을 위해서 매치메이킹은 아주 중요한 요소일 것입니다. 여기에서 거론된 서버리스 매치메이커 패턴은 여러분이 원하는 알고리즘을 활용하면서, 동시에 아마존의 게임리프트를 활용하여 여러분의 서버 리소소를 적극적으로 활용할 수 있는 가능성을 제시하고 있습니다.

게임리프트 세션 할당 기능은 위 예제에서 보여준 매치메이킹 방식을 지원하는 적합한 방법이며, 사용자에게 최고의 경험을 전달할 수 있습니다. 그리고 더불어 관리형 서비스의 하나로 게임리프트는 서버 Fleet의 유지관리를 전담하게 됩니다.

사용자의 수요에 따라서 자동적으로 용량을 조절하고 사용한 만큼 비용을 청구하게 됩니다. 이를 통하여 사용자에게 직접 영향을 주지 않으면서 비용 관리를 할 수 있도록 도와줍니다. 게임리프트는 또한 동시에 여러 버전의 Fleet들 을 동시에 구동하고 이들 사이를 Alias를 통하여 전환할 수 있도록 해줍니다. 이를 활용하기 위해서 필요한 SDK는 게임리프트 SDK(Amazon GameLift Server SDK)입니다. 관리는 관리 콘솔(AWS Management ConsoleAWS CLI), 또는 게임리프트 API(Amazon GameLift APIs)를 통하여 진행할 수 있습니다. (C++, C#, 그리고 몇가지 다른 언어로 제공됩니다.)

게임리프트는 미지의 수요에 대하여 걱정 없이 대응할 수 있는 기반을 제공하고 있으며, 이는 여러 개발자들이 독특하고 차별화된 게임 경험 그 자체에 집중할 수 있는 환경을 제공합니다. 이 서버리스 매치케이킹 패턴은 많은 사용자가 몰리더라도 유연하고 확장 가능한 백-엔드를 제공하며 인프라에 대한 많은 관리 부담을 줄여줄 수 있습니다. 결과적으로 게임 개발자, 운영자의 부담을 줄여주고 여러분의 게임을 즐기는 고객들에게 좋은 게임 경험을 제공할 수 있습니다.

피터 챕맨(Peter Chapman)은 Amazon Gamelift, Lumberyard 팀의 솔루션스 아키텍트입니다. 그는 12년 이상의 소프트웨어 개발 및 아키텍쳐경험을 가지고 있습니다. 게이밍 뿐만 아니라 건강/ 소매 다양한 분야에서 솔루션을 디자인한 경험을 가지고 있습니다. 이 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 김성수 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon GameLift 글로벌 기반 서버 매치메이킹 기능 활용하기

지난 해 발표된 Amazon GameLift는 세션형 멀티플레어어 게임 서비스의 스케일링 문제를 쉽게 해결해주는 관리형 게임 플랫폼 서비스입니다. GameLift의 기본적인 사용법은 지난  블로그 글을 통해서 소개를 드린 바 있습니다.

Amazon GameLift가 발표된 이후, 많은 AWS 고객 분들의  기능 추가 요청 사항이 있었으며,  한국을 포함한 9개 리전에 확대 적용 되었고, 최근에는 Unity3D 및 Unreal Engine용 플러그인도 공식 출시하였습니다.  즉, Amazon Lumberyard 엔진을 포함하여 C++ 및 C# 프로그래밍 언어를 지원하는 어떠한 게임 엔진도 GameLift를 바로 적용하실 수 있습니다. (자세한 내용은 Launch: Amazon GameLift Now Supports All C++ and C# Game Engines 참고)

뿐만 아니라 지난 GDC 2017에서 GameLift의 이정표가 될 만한 기능인 글로벌 매치 메이킹(Global Matchmaking) 기능을 추가하였습니다. 이 기능은 전 세계에 흩어져 있는 각 게임 플레이어의 위치를 기반으로 가장 가까운 게임 서버를 지능적으로 선택하는 데 사용할 수 있으며, AWS 글로벌 인프라을 활용하여 플레이어에게 가능한 최저 지연 시간을 제공합니다.

지연 시간이 짧은 게임 서버를 사용할 수 없는 경우, 플레이어와 최대한 가까운 곳의 서버에 자동으로 게임 세션을 할당할 수 있도록 도와줍니다. 또한, 새로운 게임 세션이 시작되거나 신규 인스턴스가 시작되기 전까지 플레이어들이 대기열을 유지하고, 대기하고 있는 플레이어들을 지연 시간이 가장 짧은 게임 서버에 배치합니다.

AWS의 가장 큰 장점 중 하나인 광범위한 글로벌 인프라를 손쉽게 활용하여, 전 세계를 대상으로 서비스하는 세션형 멀티플레이어 게임 혹은 지역적으로 가까운 플레이어들끼리 팀을 구성하여 지연 시간이 가장 짧은 서버에 게임을 배치할 수 있는 기능을 제공함으로써 게임 플레이어들에게 좋은 게임 경험을 줄 수 있습니다. 이번 글에서는GameLift의 Matchmaking Queue기능에 대해 좀 더 구체적인 내용과 함께 어떻게 여러분의 게임 서비스에 통합 할 수 있는지에 대해 살펴봅니다.

GameLift Matchmaking Queue 생성하기
GameLift의 전역 매치메이킹 기능을 사용하기 위해서는 게임 세션 생성 요청이 대기할 수 있는 대기열(Matchmaking Queue)을 만들어야 합니다.  대기열은 GameLift 대시보드의 Queues 항목에서 “Create queue” 항목을 통해서 생성할 수 있습니다.

대기열 생성 과정은 상당히 간단합니다. Queue Name을 입력하고, (후에 Application에서 이 Queue Name을 통하여 대기열에 접근하게 됩니다.) 대기열 내에서 요청이 최대한 머무를 수 있는 시간(Queue Timeout)을 입력합니다. 그 후에 이 대기열과 연결할 GameLift Fleet(서버 집합)을 설정하면 됩니다. 서버 플릿은 리전에 관계없이 우선순위를 정하여 지정할 수 있습니다.

위의 그림은 GameLiftSeoulQueue라는 대기열로 들어오는 게임 세션 요청에 대해 3개 지역의 플릿을 연결한 예입니다. 이 예시에서는 게임 세션 생성 요청이 처리될 1순위 플릿은 도쿄 리전(ap-northeast-1)의 플릿이고, 2순위는 오레곤 리전(us-west-2), 마지막 순위는 서울리전(ap-northeast-2)의 플릿으로 설정되어 있는 것을 확인할 수 있습니다.

즉, 대기열에 연결된 플릿의 우선순위는 자유롭게 바꿀 수 있습니다. 게임 세션 생성 요청이 대기열에 도착하면, 기본적으로는 이 우선순위에 따라 게임 세션을 배치하게 됩니다. 물론, 사전에 정해진 우선순위가 아닌 플레이어의 게임 클라이언트와 각 리전과의 지연 시간 기반으로 최적의 플릿이 선택되도록 할 수도 있습니다.

추가적으로, Matchmaking Queue 또한 하나가 아니라 리전 별로 따로 만들 수 있으며 주로 어느 지역의 게임 플레이어로부터 요청을 받을지에 따라 Matchmaking Queue를 둘 리전을 자유롭게 선택하시면 됩니다. 예를 들어, 유럽 지역의 플레이어 대상으로 요청을 받을 대기열은 프랑크프루트 리전에, 아시아태평양 지역의 플레이어 대상으로는 도쿄 리전에, 북미 지역 플레이어 대상으로는 버지니아 리전에 각각 두고, 각각의 대기열로 들어온 요청에 대해 GameLift를 지원하는 모든 리전(현재 9개)의 플릿으로 정해놓은 우선순위에 따라 배치 요청을 보낼(dispatching) 수 있습니다.

GameLift Matchmaking Queue를 통한 게임 세션 생성하기
Matchmaking Queue를 통한 게임 세션 요청은 StartGameSessionPlacement API를 통해 할 수 있습니다. 이 API는 기본적으로 비동기로 동작합니다. 대기열에 게임 세션 생성을 요청한 이후 실제 게임 세션이 적절한 리전에 배치되기까지 시간이 걸리기 때문입니다. 그래서 DescribeGameSessionPlacement API를 통해서 주기적으로 게임 세션 생성이 완료되었는지 확인을 해야 합니다.

게임 세션의 배치가 완료되면 DescribeGameSessionPlacement API 응답의 Status 속성이 “FULFILLED”로 바뀝니다. 이 때, 결과의 GameSessionArn 속성에 담겨 오는 값이 바로 생성된 게임 세션의 ID입니다. 이 세션 ID를 통해서 이후 요청(플레이어 세션 생성 등)을 처리하면 됩니다.

위의 과정을 코드로 표현하면 다음과 같습니다. 전체 구현 코드는 Github을 참고하세요.

// StartGameSessionPlacement API를 통한 게임 세션 배치 요청 예
// 가독성을 위해 오류처리 부분은 생략하였습니다.

Aws::GameLift::Model::StartGameSessionPlacementRequest req;
req.SetGameSessionQueueName(“Matchmaking Queue 이름”);
req.SetMaximumPlayerSessionCount(“게임 세션내 최대 플레이어 수”);
req.SetPlacementId(“랜덤으로 생성된 Unique ID”);

auto outcome = GetAwsClient()->StartGameSessionPlacement(req);
if (outcome.IsSuccess())
{
	auto status = outcome.GetResult().GetGameSessionPlacement().GetStatus();

	if (status == Aws::GameLift::Model::GameSessionPlacementState::PENDING)
	{
			return CheckGameSessionPlacement(); // 아래 함수 정의에서 확인
	}
}

// DescribeGameSessionPlacement API를 사용하여 게임 세션 배치가 완료되었는지 확인
bool CheckGameSessionPlacement()
{
    // polling 방식으로 확인하는 예
    while (true)
	{
		Aws::GameLift::Model::DescribeGameSessionPlacementRequest req;
		req.SetPlacementId(“위의 배치 요청에서 사용된Unique ID”);
		auto outcome = GetAwsClient()->DescribeGameSessionPlacement(req);
		if (outcome.IsSuccess())
		{
			auto gs = outcome.GetResult().GetGameSessionPlacement();

                                           // 게임 세션 배치 완료 확인
			if (gs.GetStatus() == Aws::GameLift::Model::GameSessionPlacementState::FULFILLED)
			{
				auto arn = gs.GetGameSessionArn();
				
				// 게임 세션 ID를 통해 해당 게임 세션이 생성된 서버의 IP주소와 Port를 확인
				Aws::GameLift::Model::DescribeGameSessionDetailsRequest request;
				request.SetGameSessionId(arn);
				auto response = GetAwsClient()->DescribeGameSessionDetails(request);
				if (response.IsSuccess())
				{
					auto result = response.GetResult().GetGameSessionDetails();
					// IP주소 = result[0].GetGameSession().GetIpAddress();
					// Port 번호 = result[0].GetGameSession().GetPort();
					// 이후 플레이어 세션 생성을 하면 됨
                                                                        // … …
   				}
			}

		}
		Sleep(…);
	}
        // … 이하 오류처리 부분은 생략 …
}

보시다시피 GameLift Matchmaking Queue를 이용하면 비교적 간단하게 세션형 멀티플레이어 게임을 전세계 지역을 대상으로 서비스할 수 있습니다. 물론, StartGameSessionPlacement API에 몇 가지 정보만 더 주게 되면, 전세계에 흩어져 있는 플레이어 대상으로 지연 시간 기반의 최적화된 게임 세션 배치를 좀 더 효율적으로 할 수 있습니다. StartGameSessionPlacement API의 요청 구조는 다음과 같습니다.

{
   "DesiredPlayerSessions": [ 
      { 
         "PlayerData": "string",
         "PlayerId": "string"
      }
   ],
   "GameProperties": [ 
      { 
         "Key": "string",
         "Value": "string"
      }
   ],
   "GameSessionName": "string",
   "GameSessionQueueName": "string",
   "MaximumPlayerSessionCount": number,
   "PlacementId": "string",
   "PlayerLatencies": [ 
      { 
         "LatencyInMilliseconds": number,
         "PlayerId": "string",
         "RegionIdentifier": "string"
      }
   ]
}

지연 시간 기반의 배치 요청을 위해서는 크게 두 부분의 속성 값을 제공해야 합니다. 우선 “DesiredPlayerSessions” 속성값을 통하여 생성하고자 하는 플레이어 세션 정보를 입력하여야 합니다. 즉, 게임 세션 생성 요청과 동시에 플레이어 세션 생성도 한꺼번에 할 수 있다는 뜻입니다. (이 경우는 이후에 따로 CreatePlayerSessions API를 호출할 필요 없이 바로 DescribePlayerSessions API를 통해 생성된 플레이어 세션에 대한 정보를 바로 확인 할 수 있습니다.)

플레이어 세션 생성을 위한 정보 이외에 “PlayerLatencies” 속성에 해당하는 지연 시간 정보를 입력해주어야 합니다. 해당 플레이어의 ID정보(“PlayerId”)와 각 리전으로부터 지연 시간 정보(“RegionIdentifier”로부터 “LatencyInMilliseconds”만큼의 지연이 발생하는지)를 제공하면 사전에 설정된 플릿간의 우선순위를 무시하고 게임 세션에 참여하는 플레이어들의 지연 시간에 최적화된 리전 내 플릿을 선택합니다.

즉, 서비스 하고자 하는 게임의 특성에 따라 우선순위 기반 게임 세션 배치를 사용할 것인지, 지연 시간 최적화를 이용한 게임 세션 배치를 사용할 것인지 선택할 수 있습니다.

GameLift Best Practice 아키텍처
게임 세션 생성 또는 플레이어 세션 생성 요청 등에 사용되는 GameLift Client API는 AWS SDK를 통해서 사용할 수 있습니다. 게임 서비스에 있어서 이런 종류의 GameLift Client API를 게임 클라이언트에서 직접 사용하도록 하는 경우 게임 클라이언트가 GameLift API를 호출할 수 있는 권한을 갖고 있어야 합니다.

이 권한은 AWS IAM의 credentials 정보를 직접 클라이언트에 제공하여 권한을 부여할 수도 있고, Amazon Cognito와 같은 인증 서비스를 통해 제공할 수도 있습니다.  그렇지만, 일반적으로 세션형 멀티플레이어 게임을 서비스 할 때, 플레이어들이 게임에 참여하기 전에 대기할 로비(Lobby) 서버나 같이 게임 할 팀원 또는 상대를 찾도록 도와주는 매체메이킹서버를 따로 운영하게 됩니다.

이러한 경우, GameLift Client API사용을 게임 클라이언트에서 직접 수행하기 보다는 로비 서버나 매치메이킹 서버가 이 역할을 수행하게 됩니다. 즉, 게임 클라이언트는 GameLift Client API 호출을 위한 권한이나 인증 정보에 대해 전혀 몰라도 됩니다. 대신 EC2 인스턴스 위에서 운영되는 로비 서버나 매치메이킹 서버에서 직접 GameLift에 API요청을 하면 됩니다. 이때, API 요청 권한을 위한 Credentials 제공을 따로 할 필요 없이 IAM EC2 역할(Role)을 통하여 GameLift API 요청 권한을 부여하면 됩니다. GameLift를 통하여 세션형 멀티플레이어 게임을 서비스함에 있어서 Lobby/Matchmaking서버를 사용하는 일반적인 아키텍처는 다음 그림과 같습니다.

Amazon GameLift Fleet에 배포될 게임 서버에서는 GameLift Server SDK를 사용하여 GameLift 서비스와 통합할 수 있고, EC2 인스턴스 위에서 운영되는 로비나 매치메이킹 서버에서는 AWS SDK의 GameLift Client API를 통하여 GameLift 서비스에 요청하는 구조입니다.

이제 Amazon GameLift의 새로운 기능인 Matchmaking Queue를 활용함으로써, 전세계 AWS 리전에 있는 다수의 게임 서버들을 탄력적으로 활용 할 수 있습니다. 이는 지연 시간에 민감한 세션형 멀티플레이어 게임을 전세계의 플레이어 대상으로 낮은 지연 속도(low-latency) 경험을 제공할 수 있음은 물론, 게임 서비스를 제공하는 회사 입장에서도 글로벌 단위의 GameLift 스케일링 기능을 통하여 비용 효율적으로 게임 서비스를 운영할 수 있음을 의미합니다.

참고하실 글

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 구승모 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon GameLift, 서울 리전 출시

Amazon GameLift는 세션 기반 멀티플레이어 게임의 배포, 운영 및 확장을 위한 관리형 서비스입니다. 오늘 Asia Pacific (Seoul)리전을 비롯하여 5개 리전에 추가 공개되었습니다.이로서 게임 개발자들이 국내 게임 플레이어에게 낮은 지연 속도 및 더 나은 게임 경험을 제공할 수 있게 되었습니다.

201612-gamelift-seoul

Amazon GameLift는 가용성이 뛰어난 AWS의 클라우드 인프라상에 구축되었으며, Amazon Lumberyard를 사용하는 개발자는 추가적인 엔지니어링 작업 또는 선결제 비용 없이 플레이어 수요에 맞춰 고성능 게임 서버를 신속하게 확장 및 축소할 수 있습니다.

아래 자료를 통해 Amazon GameLift를 살펴 보시고, 운영 효율적인 클라이드 기반 게임 운영 플랫폼을 활용해 보시기 바랍니다.

자세히 살펴보기

발표 자료


Amazon GameLift Deep Dive – AWS 관리형 게임 플랫폼 활용하기
by 구승모 (AWS 솔루션즈아키텍트)

– AWS코리아 마케팅팀;

Amazon GameLift 시작하기

올해 초에 처음 발표된 Amazon GameLift는 세션 기반의 멀티 플레이어 게임 서비스를 손쉽게 구축하고 운영하기 쉽도록 도와주는 관리형 서비스입니다.  지난 2월 블로그 글을 통해서 Amazon Lumberyard에 기본적으로 포함된 멀티플레이어 게임 샘플을 GameLift상에서 돌려보는 방법에 대한 소개를 드린 바 있습니다.

또한 지난 9월 Gaming On AWS 행사를 통해서 Amazon GameLift Deep-dive 강연에서 GameLift에 대해 자세한 내용을 다루었습니다. 이번 글에서는 좀 더 구체적으로 여러분이 만든 게임 서버를 직접 GameLift에 올려서 사용하는 방법과 게임 클라이언트가 GameLift의 Fleet에 접근하는 방법에 대해 다루어 보도록 하겠습니다.

Amazon GameLift 복습하기
GameLift 연동 방법 설명에 앞서, GameLift의 전체적인 개념을 기술적인 관점에서 다시 한 번 정리하고 넘어가도록 하겠습니다.  온라인 게임을 서비스하기 위해서는 크게 3가지 측면에서의 준비가 필요합니다.

첫번째는 플레이어들이 직접 실행하여 게임을 즐길 수 있도록 하는 게임 클라이언트고, 두번째는 다수의 게임 클라이언트들의 접속을 받아서 멀티플레이를 중계해주는 게임 서버입니다. 세번째는 게임 클라이언트들의 인증처리뿐만 아니라 게임 서버들을 제어하고 모니터링 할 수 있도록 운영을 도와주는 게임 서비스 플랫폼입니다. 바로 이 게임 서비스 플랫폼 역할에 더하여 게임 서버들의 확장/축소(scaling)를 도와주는 것이 GameLift입니다.  (여러분들의 게임 서버를 AWS가 만들어 주는 것이 아닙니다.)

게임 서버를 호스팅 하기 위해서는 직접 개발한 게임 서버 빌드로부터 플릿을 생성하면 됩니다.  플릿을 생성하면 처음에는 초기 설정한 대수만큼의 EC2 인스턴스가 게임 서버를 호스팅하게 됩니다. (물론, 이후에는 GameLift의 Auto-scaling 기능을 통해 인스턴스 수를 자동으로 확장/축소할 수 있습니다.)

gamelift1

플릿 생성시에 하나의 EC2 인스턴스가 몇 개의 게임 서버 프로세스를 호스팅할지 정할 수 있습니다. 기본적으로 하나의 게임 서버 프로세스는 하나의 게임 세션을 맡아서 처리 합니다. 즉, 게임 서버 작성시에 하나의 게임 세션을 처리할 수 있도록 구현하면 됩니다. (참고: 현재 하나의 게임 세션당 받을 수 있는 최대 플레이어 세션 제한은 250명 입니다.) 게임 서버의 워크로드와 인스턴스 성능에 따라 다르지만 하나의 인스턴스는 적게는 수십개, 많게는 수백개의 게임 세션을 호스팅 하도록 설정하는 것이 일반적입니다.

GameLift 플릿이 게임 세션을 생성 가능한 상태인 Active상태가 되면 게임 클라이언트는 플릿에 직접 요청(게임 세션 생성, 게임 세션 내 플레이어 슬롯 예약, 게임 세션에 참여 등)할 수 있습니다. 당연히, 게임 클라이언트는 EC2인스턴스의 상태를 전혀 몰라도 됩니다. 단지, 어느 플릿에 접근하면 되는지에 대한 정보만 알면 되기 때문입니다.

Amazon GameLift SDK 사용하기
GameLift를 사용하기 위해서는 2가지 종류의 SDK를 사용하여야 합니다. 게임 서버는 GameLift 전용 Server SDK를 사용하여 통합작업을 하면 되지만 게임 클라이언트의 경우는 GameLift 전용 SDK가 따로 존재하는 것이 아니라 기본적으로 프로그래밍 언어별로 제공되는 AWS SDK를 사용하면 됩니다.

지난 블로그 글을 통해 AWS C++ SDK 사용하는 법을 소개 드린 적이 있습니다만, C++언어 뿐만 아니라 AWS SDK가 제공하는 타 언어별 SDK를 사용하셔도 됩니다. 즉, 게임 클라이언트 프레임워크의 상황에 맞게 적합한 AWS SDK를 사용하시면 됩니다.

게임 클라이언트와 게임 서버간의 통신에는 TCP 및 UDP 프로토콜을 사용하실 수 있으며, 메시지 전달을 위한 패킷은 직접 구현하시거나 기존의 유명한 데이터 직렬화 및 패킷 생성 도구인 Google Protocol BuffersMessagePack를 활용하셔도 좋습니다.

게임 클라이언트와 게임 서버, GameLift 서비스간의 API 레벨에서의 전체적인 상호 작용은 다음 그림을 참고하시기 바랍니다.

gamelift2

GameLift Server SDK통해서 게임 서버 연동하기
그럼 이제 본격적으로 여러분들의 게임 서버에 GameLift Server SDK를 연동하는 방법에 대해 알아보겠습니다. GameLift Server SDK는 C++로 작성된 게임 서버와 통합할 수 있습니다. (향후 C# 프로그래밍 언어도 지원할 예정입니다.)

지원하는 운영체제는 Windows Server 및 Amazon Linux이며, 사용하고자 하는 운영체제에 맞춰 빌드해야 합니다. Windows Server의 경우에는 Visual Studio 2013 이상, Linux의 경우에는 GCC 4.9 이상의 버전이 필요합니다. 추가로 CMAKE가 필요하며 자세한 빌드 방법에 대해서는GameLift Server SDK내에 포함된 README.md 파일을 참고하시기 바랍니다.

GameLift Server SDK 빌드가 완료되면 생성되는 라이브러리 파일(Windows의 경우 *.dll 및 *.lib, Linux의 경우에는 *.a 또는 *.so)과 GameLift Server SDK의 include 디렉토리에 포함된 헤더파일들을 게임 서버가 위치한 프로젝트로 복사하시기 바랍니다. Visual Studio의 경우에는 프로젝트 설정에서 해당 파일들의 위치를 지정해주시고, GCC를 사용하는 경우에는 Makefile 또는 CMakeLists.txt 파일을 통해 해당 라이브러리와 헤더 파일의 위치를 게임 서버 프로젝트에서 참조할 수 있게 지정해주시기 바랍니다. GameLift Server SDK가 연동된 게임 서버 프로젝트 예제를 참고하시기 바랍니다.

GameLift Server SDK에서 제공하는 게임 서버전용 API는 다음과 같으며, 여러분들이 제작하는 게임 서버에서 이 API를 호출하는 부분과 GameLift서비스가 게임 서버에게 요청하는 콜백 함수에 대한 구현을 하시면 됩니다.

  • 게임 서버가 GameLift 서비스에 요청하는 API
    • ProcessReady() – 게임 서버가 준비 되었음을 GameLift 서비스에게 알림. 이 호출이 성공적으로 완료되면 플릿 상태가 Active로 됨.
    • ActivateGameSession() – 게임 세션이 준비완료 되었음을 GameLift 서비스에게 알림. 이후에 플레이어의 접속을 받아 게임 세션에 참여 시키면 됨.
    • AcceptPlayerSession() – 접속한 게임 클라이언트가 정상적인 플레이어라면 이 API 호출을 통해 GameLift 서비스에게 알림. 이를 통해 GameLift 서비스는 플레이어가 게임 세션에 참여했음을 알게됨.
    • RemovePlayerSession() – 게임 클라이언트가 게임 세션에서 나갔을 때, 게임 서버가 GameLift 서비스에게 통보하는 API.
    • TerminateGameSession() – 게임 세션이 종료되었을 때 GameLift 서비스에게 알려서 게임 세션을 종료하도록 하는 API.
    • ProcessEnding() – 게임 서버 프로세스가 종료되었음을 알리는 API. 이 경우 GameLift 서비스가 해당 게임 서버를 종료시키고 새로운 게임 서버 프로세스를 생성하여 추후의 게임 세션 요청에 대해 준비하도록 함.
  • GameLift 서비스가 게임 서버에게 요청하는 콜백함수
    • onHealthCheck() – 주기적으로 GameLift 서비스가 게임 서버가 살아있는지 호출하는 함수로 게임 서버가 정상이라면 true를 리턴해주면 됨.
    • onStartGameSession() – 게임클라이언트가 GameLift 서비스에 게임 세션 생성을 요청하게 되면, GameLift 서비스가 게임 서버에게 이 콜백 함수를 통해 통지함. 게임 서버는 게임 세션 준비가 완료되면 ActivateGameSession() API 호출을 통해 게임 세션 준비가 완료되었음을 알리면 됨.

구체적인 사용 샘플 코드 구현을 참고하시기 바랍니다.  이런 방식으로 GameLift Server SDK를 활용한 게임 서버의 빌드가 준비되었다면 AWS CLI를 통하여 GameLift에 빌드를 올려야 합니다. 기본적으로 생성된 게임 서버 실행파일 이외에도 의존성 있는 파일들(DLL 등)이 있다면 함께 하나의 폴더 내에 모아주시기 바랍니다. 준비가 완료 되면 다음과 같은 명령어를 통해 GameLift상에 빌드를 올릴 수 있고, 업로드가 완료되면 AWS 콘솔 상에서 확인이 가능합니다.

$ aws gamelift upload-build --name “빌드 이름” --build-version “빌드 버전” --build-root “빌드가 있는 폴더” --operating-system <운영체제:  WINDOWS_2012 또는 AMAZON_LINUX>   --region <리전>

업로드된 게임 서버 빌드를 보실 수 있습니다.

gamelift3

이제 해당 빌드로부터 플릿을 생성할 수 있습니다. 빌드를 선택하고 플릿 생성하기를 진행하게 되면 몇 가지 설정을 하여야 합니다. 대표적으로 EC2 인스턴스 타입 설정, 실행파일 이름, 게임 서버 프로세스 수, 열어둘 포트 번호 및 프로토콜 등을 설정하게 됩니다. 또한 Auto-scaling 정책을 설정하게 되는데 이 정책은 플릿 생성후에 수정할 수도 있습니다. 모든 설정을 마쳤다면, 플릿을 생성하시기 바랍니다.

기본적으로 게임 클라이언트는 플릿 ID를 통해 플릿에 접근하게 됩니다. 하지만, ALIAS기능을 활용하기를 추천드립니다. ALIAS는 플릿의 ID를 바라보게 할 수 있고 이를 사용하게 되면, 게임 클라이언트는 ALIAS ID를 통해서 지정된 플릿에 접근할 수 있습니다. 만일 게임 클라이언트 수정 없이 새로운 플릿으로 접속을 유도하고 싶다면, ALIAS가 바라보는 플릿의 ID만 바꾸면 되기 때문에, 중단 없이 새로운 플릿으로 접속을 유도할 수 있습니다. (즉, ALIAS 기능을 통한 무중단 배포가 가능함을 의미합니다.)

gamelift4

AWS SDK통해서 게임 클라이언트 연동하기
게임 서버가 플릿에 올라가 있는 상황이라면, 게임 클라이언트가 플릿에 접속해서 게임 세션에 참여할 수 있습니다. GameLift 연동 가능한 게임 클라이언트 준비는 앞서 설명 드린 게임 서버 연동에 비해서는 쉬운 편입니다.  또한, 프로그래밍 언어나 프레임워크 선택도 자유로운 편입니다. 그 이유는 AWS SDK를 쓸 수 있는 환경이기만 하면 되기 때문입니다.

즉, 각 프로그래밍 언어별로 존재하는 AWS SDK를 여러분들의 게임 클라이언트에서 사용하도록 설정하면 됩니다. 게임 클라이언트 제작시 가장 많이 사용되는 프로그래밍 언어인 C++의 경우에는 얼마전 정식 버전이 발표된 AWS C++ SDK를 사용하면 되며, 자세한 사용 방법에 대해서는 지난 블로그 포스팅에서 다룬 바 있습니다. 예를 들어, 유명한 오픈소스 게임 엔진인 Cocos2d-x에 AWS C++ SDK를 연동하여 GameLift를 사용하는 샘플 프로젝트를 참고하시기 바랍니다.

GameLift 연동을 위해서 게임 클라이언트를 구현시 사용하게 되는 API는 다음과 같습니다.

  • CreateGameSession() – GameLift서비스에 게임 세션 생성을 요청하는 API. 대상 플릿ID 또는 ALIAS ID 설정하고 해당 게임 세션이 최대로 수용할 수 있는 플레이어 세션 수를 지정. 요청에 대한 응답으로 게임 세션 ID및 해당 게임 세션을 호스팅하는 게임 서버의 IP주소와 포트 번호를 받게 됨.
  • SearchGameSessions() – 이미 만들어진 게임 세션이 있다면, 조건식으로 해당 게임 세션을 찾는 API. 여러가지 조건으로 게임 세션 검색이 가능하며, 자세한 조건식 작성 방법은 API 문서에서 확인 가능. 요청에 대한 응답은 위의 CreateGameSession()과 같음.
  • CreatePlayerSession() – 참여하고자 하는 적합한 게임 세션을 찾거나 만든 후에, 플레이어 참여를 시킬 수 있도록 플레이어 세션을 생성하는 API. 요청에 대한 응답으로 플레이어 세션 ID를 발급 받게 되며, 이후에 실제 게임 서버에 접속을 요청하면 됨.

이외에도 게임 클라이언트가 사용할 수 있는 API가 있지만 대부분의 경우에는 위의 3종류 API만 사용하게 됩니다. 전체적인 API 상호 작용 과정은 아래 그림을 참고하시기 바랍니다.

gamelift5

게임 클라이언트가 요청하는 GameLift API는 그에 맞는 권한이 IAM을 통하여 부여 되어야 합니다. IAM 권한을 모든 사용자에게 부여하기 힘든 환경이라면 제3자 인증 주체(Amazon, Google, Facebook 등)와의 연방화(Federation)을 통해서 권한을 부여할 수 있습니다. 제 3자를 통한 인증이 힘든 상황이라면 Amazon Cognito UserPool을 활용(https://aws.amazon.com/ko/blogs/korea/how-to-own-user-auth-service-using-amazon-cognito/)하여 직접 인증 서비스를 구축하실 수도 있습니다.

이렇게 여러분의 게임 서버 및 게임 클라이언트를 GameLift에 연동함으로써, 게임 클라이언트는 플릿에 게임 세션을 요청하고 적합한 게임 세션을 찾은 후에 플레이어 세션 생성을 통해 게임에 참여할 수 있게 됩니다. 이제 직접 GameLift의 웹 콘솔을 통하여 서비스 상태 모니터링 및 플릿의 설정을 원하는대로 제어해 보시기 바랍니다.

필요에 따라 수동으로도 게임 서버를 호스팅하는 인스턴스의 수를 조정할 수 있으며, 게임 세션 및 플레이어 세션들의 세부 상태에 대한 확인과 제어가 가능 합니다. 이렇게 GameLift를 통하여 세션형 멀티 플레이어 게임의 서버 관리 부담을 덜어낼 수 있을 뿐만 아니라, 사용자의 상황에 맞게 플릿의 인스턴스 수가 자동으로 확장/축소 되는 기능을 통해 손쉽게 게임 서비스를 운영할 수 있습니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 구승모 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon GameLift를 시작하기 위한 기술 팁 모음

지난 2월 11일 클라우드 기반 게임 개발자에게 게임 개발을 위한 신규 Lumberyard, Amazon GameLift 및 Twitch 통합 서비스라는 반가운 소식이 있었습니다.

Amazon Lumberyard는 CryEngine에 기반한 게임 개발 엔진입니다. 소스 코드 형태로 제공되며 사용자가 직접적으로 빌드해서 원하는 게임을 만들 수 있습니다. 현재 CryEngine 3.8.1을 기본으로 AWS 서비스와 GameLift를 지원하도록 제공되고 있습니다. Lumberyard에 대한 튜토리얼 자료는 시작하기 기술 문서Amazon GameDev Tutorials를 참고하시면 됩니다.

이 글에서는 Amazon GameLift에 대한 소개와 첫 예제를 실행할 때, 발생하기 쉬운 문제들에 대한 해결 방법 등에 대해 소개하고자 합니다.

Amazon GameLift란 무엇인가?
Amazon GameLift는 세션 기반의 멀티 플레이어 게임 서비스를 위한 관리형 서비스입니다. 게임 서버를 배포, 운영, 확장하기 위해 기존 다른 AWS 서비스와 마찬가지로 관리형으로 제공되어 게임 서버를 쉽게 구현하고 관리할 수 있게 합니다.

Amazon GameLift 서비스는 클라우드에서 게임 서버를 운영할 때 생기는 어려운 점을 해소합니다. 게임 서버를 개발한 이후에 이것을 배포하고 확장성 있게 운영하는 것은 쉬운 일이 아닙니다. 일반적으로 게임 서비스를 만들면 최초로 게임이 오픈 되었을 때, 예측 할 수 없는 트래픽으로 서버가 다운되는 경우가 많습니다. 게임 서버의 다운은 매우 빠르게 알려지고, 게임 커뮤니티 내에서 좋지 않은 평판이 만들어져서 게임 서비스에 치명적이 될 소지가 많습니다. GameLift는 AWS의 클라우드 서비스를 통해 이러한 문제를 해결할 수 있습니다.

또한, 멀티 플레이어 게임에 대한 기본적인 서버 메커니즘을 제공합니다. 그간에 축적된 게임 서비스 기술 지식에 기반해서 AWS 내부 전문가들에 의해 설계 및 개발되었고, 게임 디버깅이나 플레이어들의 상태를 쉽게 파악하기 위해 다양한 게임 텔리메트리(telemetry)를 지원합니다.

뿐만 아니라, 세션형 멀티 플레이어 게임에도 적합합니다. 즉, 오랜 시간동안 세션이 유지되면서 상호 데이터가 동기화 되는 형태 보다는 일정 시간 안에 여러 사용자가 플레이하면서 상호 데이터 동기화를 할 필요가 있는 게임에 적합합니다.

Amazon GameLift에 대한 추천 게임 종류는 아래 표와 같습니다.

적합한 게임 형식 게임 예
FPS Call of Duty, Evolce
MOBA(Multiplayer Online Battle Arena)s Legue of Legends, Heroes of the Storm
Survival/Sandbox Minecraft, Ark
Racing Mario Kart, Kart Rider
Sports NBA2K, FIFA

MMO나 모바일 소셜 게임 및 전용 서버가 없는 P2P 게임 등은 적합하지 않으며, Amazon GameLift를 사용해서 개발하기 적합한 게임은 전용 서버(dedicate server) 형식 게임이라고 할 수 있습니다.

GameLift에 예제 서비스 올리기
향후에는 GameLift에 다양한 게임 엔진과도 연동한다는 계획이지만, 현재는 Lumberyard만 지원하고 있습니다. Lumberyard에는 여러 샘플 프로젝트가 포함되어 있는데 멀티플레이어 샘플 게임도 존재합니다.

예제 게임 튜토리얼을 따라 하면 손쉽게 샘플 게임을 빌드하고 GameLift로 서비스를 올려 볼 수 있습니다.

이 글에서는 튜토리얼 그 자체 보다는 샘플을 올리는 과정에서 나오는 버그라던가 실수를 방지하는 기술 팁을 살펴보도록 할 예정입니다. 먼저 기술 팁을 설명하기 앞서서 샘플 프로그램을 GameLift에 올리는 단계를 간단히 살펴보겠습니다.

  1. Lumberyard의 설치
    • Visual Studio 2013, update 4를 설치한다.
    • Lumberyard를 풀고, 3rd 파티 툴들을 모두 설치한다.
    • 예제 게임 튜토리얼대로 서버 예제를 선택한 이후에 프로젝트를 빌드한다.
    • 빌드 패키지를 구성한다 예) install.bat 등을 적절히 수정한다.
  2. 빌드된 패키지를 서버로 업로드
    • AWS CLI를 설치한다.
    • GameLift를 위한 Policy를 생성하고, AWS IAM 유저를 붙인다.
    • CLI 명령을 통해 GameLift에 빌드된 서버 패키지를 올린다.
  3. GameLift Fleet을 생성
    • Fleet이름, 서버 빌드, 인스턴스 타입을 선택한다.
    • EC2 포트 세팅을 한다.
    • 런치 패스와 런치 파라미터를 지정한다.
  4. 게임 클라이언트 생성
    • GameLiftClient.bat를 생성한다.
    • 게임 세션을 생성한다.
    • 플레이어가 게임 세션에 접근한다

흔히 발생하는 오류나 실수를 위한 기술 팁
위와 같이 GameLift에 샘플 게임을 올리는 과정에서 아래와 같은 문제가 발생할 수 있으며, 이를 위한 기술팁을 소개하고자 합니다.

Tip 1. Unicode 문제
앞서 설명한 단계 중 샘플 프로젝트를 컴파일 하는 와중에 에러가 발생하면서, 컴파일이 중단될 수 있습니다. 이것은 파일이 Unicode 파일 형식으로 저장이 되지 않아 주로 발생합니다.

에러 메시지를 보고 Visual Studio에서 해당 파일을 수정하면 됩니다. 아래는IntersectorSegment.cpp파일에 대한 수정 내역입니다.


[그림 1] 파일 인코딩 타입 변경

UTF-8 파일 타입으로 인한 오류는 게임 개발자에게 매우 익숙한 일이므로 쉽게 문제를 해결해서 다음 단계로 넘어 갈 수 있습니다.

Tip 2. Install.bat 등 배치 파일 오류
빌드 패키지를 구성할 때 흔한 오류는 배치 스크립트를 정확히 만들지 않는 것입니다. 예를 들어 Install.bat파일은 다음과 같이 설정해야 한다.

vcredist_x64.exe /q

만약 여기서 /q 옵션을 실수로 기술하지 않은 채 패키징을 하고, GameLift로 올렸다면 서버 그룹(Fleet)을 생성할 때 다음과 같은 에러 메시지가 발생합니다.

LEET STATUS changed sequentially like this: NEW  DOWNLOADING  ERROR.

배치 스크립트의 각종 오류로 인한 결과는 빌드를 GameLift로 올릴 때 발생하는 것이 아니라 서버 그룹(Fleet) 등을 생성할 때 나타날 수 있고, 또 에러 메시지가 직관적이지 않아 디버깅에 매우 어려움을 겪을 수 있습니다. 따라서, 꼭 배치 스크립트의 에러를 확인하시길 바랍니다.

Tip 3. EC2 포트설정
게임 서버 그룹(Fleet)을 생성할 때, EC2 port 에 대한 설정을 지정해야 합니다. 콘솔에서 작업할 때 포트 설정 저장이 되도록 하려면 아래 그림의 가장 오른 쪽의 작은 아이콘을 눌러서 저장을 해야 합니다.

흔히 그냥 값을 기록하면 자동으로 저장될 줄 알고 값만 넣은 다음 Initialize Fleet 버튼만 누를 수 있는데, 이렇게 되면 포트 설정이 되지 않아서 문제가 됩니다.


[그림 2] EC2 포트 설정

Fleet을 생성한 이후에는 각 설정 값을 확인 할 수 있습니다. 정확히 EC2 포트가 설정되었는지 그림 3에서 확인할 수 있습니다.


[그림 3] Fleet 의 설정 결과 확인

Tip 4. GameLiftClient.bat 수정하기
마지막으로 수정이 필요한 것은 게임 클라이언트 생성 시 GameLiftClient.bat를 생성한는 단계입니다. 튜토리얼 문서에는 아래와 같이 내용을 작성하면 된다고 했지만, 추가적으로 두 개의 정보가 더 필요합니다.

MultiplayerProjectLauncher.exe +sv_port 33435 +gamelift_endpoint gamelift.us-east-1.amazonaws.com +gamelift_aws_region us-east-1 +gamelift_fleet_id  +gamelift_aws_access_key  +gamelift_aws_secret_key  +map gameliftlobby

아래와 같이 엔드포인트와 리전 정보를 추가해 주어야 합니다.

MultiplayerProjectLauncher.exe +sv_port 33435 +gamelift_endpoint gamelift.us-east-1.amazonaws.com +gamelift_aws_region us-east-1 +gamelift_fleet_id  +gamelift_aws_access_key  +gamelift_aws_secret_key  +map gameliftlobby

배치 파일을 실행하면 아래와 같은 실행된 게임을 보실 수 있습니다.

이 글에서는 Amazon GameLift의 샘플 프로젝트를 세팅하면서 흔히 마주치게 되는 오류를 피하는 팁을 설명하였습니다. 다음에는 Amazon GameLift SDK를 이용해서 직접 클라이언트와 서버를 세팅하는 방법을 살펴보겠습니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.

게임 개발을 위한 신규 Lumberyard, Amazon GameLift 및 Twitch 통합 서비스

세계 수준의 품질 높은 게임 개발은 매우 어렵고 시간과 비용이 많이 소요됩니다. 게임 사용자들의 요구는 매우 높고, 데스크톱, 콘솔, 모바일 플랫폼 등 다양한 소셜 게임을 찾고 있습니다. 게임은 고유의 개발 및 배포 흐름에 의한 긴 개발 시간이 필요하고, 성공하기 위해서는 수십 만 또는 수백 만의 사용자가 하루 만에 사용해 보고 인기를 얻어야 합니다.

이러한 배경에서 게임 개발 과정을 사용자가 기대하는 것에 반응하도록 설계 해 나가야 합니다. 게임 개발 팀은 스토리 디자인, 게임 디자인, 물리 논리 시뮬레이션, 사운드 제작, 그래픽 디자인, 시각 효과 및 애니메이션 전문 기술을 갖춘 팀원들이 필요합니다. 게임이 인터넷 기반이라면, 높은 확장성, 유연한 온라인 스토리지, 네트워크 통신 및 관리, 보안 등 다양한 전문성을 갖출 필요도 있습니다.

18~36 개월의 시간이 걸릴 게임 개발과 창의적 제작 작업을 위해 게임 스튜디오에 있어서는 상당한 금전적 부담이 됩니다. 결과적으로 새로운 게임을 만드는 것이 쉽지 않은 상황입니다.

신규 AWS 게임 서비스
오늘 두 개의 신규 AWS 게임 서비스를 클라우드를 이용하여 크로스 플랫폼 전문 게임 개발자를 위해 공개합니다. 업계에서 널리 사용되고 있는 게임 엔진과 개발 도구를 제공하고, 여기에 AWS 서비스를 통합했습니다. 이러한 전체 패키지는 Twitch 비디오 플랫폼과 커뮤니티를 연계하고 관련 AWS 메시징 서비스, 스토리지 서비스를 이용하실 수 있습니다. 이들이 발표하는 내용입니다.

Lumberyard 전문 개발자를 위한 새로운 게임 엔진과 개발 환경입니다. CryEngine, Double Helix 및 AWS 등 새로운 기술과 증명된 기술을 함께 융합하여 게임 개발에서 낭비를 없애고 단계를 단순화 할 수 있습니다. Lumberyard 게임 엔진으로 클라우드 연결 및 3D 게임 개발을 지원하고 게임 자산의 관리 및 인공 지능(AI), 물리 시뮬레이션, 음향 등을 지원합니다. 개발 측면에서는 Lumberyard IDE에 의해 실내 및 야외 환경이나 캔버스에서 설계를 시작할 수 있습니다. 여러분이 전문 개발자라면 임베디드 콘텐츠 흐름과 리소스 파이프 라인, Photoshop, Maya, 3ds Max에서 만들어진 것을 나중에 IDE에서 가져와 편집하여 활용할 수 있습니다. 기존의 C++ 및 Visual Studio (AWS SDK for C++) 및 Flow Graph 도구와 Cloud Canvas를 사용하여 클라우드 연결 게임을 만들 수 있습니다.

Amazon GameLift 최근 많은 게임은 활성 사용자 연결 수에 따라 확장성 높은 백엔드를 사용합니다. Amazon GameLift는 Lumberyard에서 구축한 게임에서 멀티 플레이어로 연결 가능한 게임 서버와 연결 수에 따라 확장하는 방법을 제공합니다. AWS 게임 서버의 이미지를 업로드하고, 플레이어로 부터 실행 부하에 따라 확장하도록 EC2 인스턴스 그룹을 설정합니다. 이제 서버 구축, 확장, 실행 및 모니터링을 자체적으로 할 필요가 없습니다. 대신 GameLift에서 일일 활성 사용자 수(DAU)에 대해 일반 EC2 온디멘드 비용, 컴퓨팅 성능, 스토리지, 네트워크 대역폭에 사용한 만큼 지불하면 됩니다.

Twitch 통합최근 게임 사용자들은 서로 연결되어 있습니다. 게임을 하지 않는 경우에는 Twitch에서 다른 플레이어와 팬끼리 교류를 합니다. 프로와 아마추어 선수는 Twitch에서 자신의 전문 분야를 표시하고 팬을 늘리고 있습니다. 이러한 최근 상황을 기반으로 다양한 관계를 키워 강한 커뮤니티를 만들려면 Lumberyard에서 구축 된 게임과 두 가지 새로운 Twitch 기능과 연계하여 활용할 수 있습니다. Twitch ChatPlay는 Twitch 채팅 대화 속 특정 키워드에 반응할 수 있습니다. 예를 들어, 게이머가 가장 기대하는 행동을 해 주도록 채팅에서 제안 할 수 있습니다. Twitch JoinIn 채팅 채널 내에서 게이머를 멤버로 끌여 들이기 위한 알림이 있습니다.

이러한 서비스는 AWS 다른 많은 서비스처럼 독창적인 기능을 게임에서 만들 수 있도록 설계되어 있습니다. 또한, 피드백을 통한 빠른 게임 개발 방향 전환 및 사용자끼리의 연결과 오락 서비스를 제공할 수 있습니다.

고객 지원 서비스 – 각종 기술 도움말(문서 및 동영상), 전용 포럼을 포함한 고객 지원도 제공하고 있습니다. 일부 메뉴에 대해서 AWS 유상 지원도 준비하고 있습니다.

Lumberyard로 게임 개발하기
Lumberyard가 오늘 발표 주요 서비스입니다. 앞서 이야기한 대로 전문 게임 개발자로 고품질의 크로스 플랫폼 게임을 개발 할 수 있도록 디자인한 새로운 게임 엔진이며, 다음 환경을 지원합니다.

  • Windows – Vista, Windows 7, 8, and 10.
  • Console – PlayStation 4 and Xbox One.

모바일 단말이나 VR 헤드셋은 현재 확인 중이며, 몇 개월 내에 사용할 수 있습니다.

Lumberyard 개발 환경은 Windows PC 또는 노트북에서 작동합니다. 동작 속도가 빠른 쿼드 코어 프로세서, 최소 8GB의 메모리, 200GB의 디스크 여유 공간 2GB 이상의 메모리에서 Direct X 11 호환의 하이 엔드 비디오 카드가 필요합니다. Visual Studio 2013 Update 4 마이그레이션 및 Visual C ++ 재배포 패키지도 필요합니다.

Lumberyard Zip 파일은 바이너리 템플릿 자산과 편집기를 위한 구성 파일이 포함되어 있습니다. Lumberyard 게임 엔진 바이너리와 소스 코드도 포함되어 있습니다. 그대로 사용해도 괜찮고, 참조 용으로 소스 코드를 분석하여도 좋습니다. 또한, 여러분의 게임을 차별화하기 위해 다양한 맞춤형 기능을 추가해도 좋을 것입니다. Zip 파일은 런처도 포함되어 있으며, Lumberyard 및 기타 런타임 SDK 도구 및 플러그인이 제대로 설치되어 있는지 확인할 수 있습니다.

Lumberyard Editor는 개발 중인 게임을 캡슐화하거나 게임 에셋 편집에 사용할 편집 도구입니다.

Lumberyard Editor는 Asset Browser, Layer Editor, LOD Generator, Texture Browser, Material Editor, Geppetto (character and animation tools), Mannequin Editor, Flow Graph (visual programming), AI Debugger, Track View Editor, Audio Controls Editor, Terrain Editor , Terrain Texture Layers Editor, Particle Editor, Time of Day Editor, Sun Trajectory Tool, Composition Editor, Database View, UI Editor를 포함한 제품군입니다. 모두 도구 모음을 통해 화면에서 조작 할 수 있습니다.

게임에 추가 기능으로서 선택된 모듈 양식을 추가하기 위해 Gems라는 코드 패키징 시스템을 사용합니다. Gems을 활성화하면, 게임 바이너리를 자동으로 포함합니다. Lumberyard에는 AWS와 연계하기 위한 Gems도 있습니다. 그 밖에도 구름, 게임 효과, GameLift 접근, 빛, 물리 시뮬레이션, 비, 눈, 토네이도, 사용자 인터페이스, 멀티 플레이어 기능, 숲 등의 다양한 효과가 있습니다.

Flow Graph와 Cloud Canvas기반 코딩
예전에는 개발자가 C++을 기반으로 일반적인 개발 라이프 사이클(편집/컴파일/실행)을 구축하였습니다. 만약 Lumberyard를 사용하는 경우, 같은 방식으로 Lua와 Flow Graph를 사용할 수 있습니다.

Flow Graph는 복잡한 게임 로직을 코드 수정 없이 통합할 수 있는 최신 비주얼 스크립팅 시스템입니다. 게임의 설정, 소리 제어 효과 관리를 위해 기 구축 된 노드 기반 라이브러리를 사용할 수 있습니다.

Flow Graph는 노드와 링크에서 생성됩니다. 싱글 레벨은 다중 그래프를 포함하고 활성화 할 수 있습니다. 노드는 게임 엔티티나 행동을 보여줍니다. 링크는 한 노드의 결과를 다른 노드의 입력과 연결합니다. 이러한 입력은 여러 타입(Boolean, Float, Int, String, Vector)을 가집니다. 출력 포트는 어느 입력 포트에서도 연결 가능하며, (가능하다면) 자동으로 형 변환이 이루어집니다.

30개가 넘는 다양한 형태의 노드가 있으며, AWS 서비스에 접근할 수 있는 (Cloud Canvas라는) 세트가 포함되어 있습니다. Amazon Simple Queue Service (SQS)에 접근 가능한 2개의 노드와 Amazon Simple Notification Service (SNS)에 접근 가능한 4 개의 노드, Amazon DynamoDB에 Read/Write를 할 수 있는 7개의 노드, AWS Lambda 함수를 호출할 수 있는 한 개의노드, Amazon Cognito를 사용한 플레이어의 인증 정보를 관리할 수 있는 한 개 등을 포함합니다. AWS를 호출 하는 모든 게임은 Cloud Canvas를 설정하고, AWS Identity and Access Management (IAM)를 통해서만 접근 가능합니다.

Lambda 함수를 호출하는 DailyGiftLambda 사용 예:
DailyGiftLambda:

아래는 “Daily Gift”기능을 구현하기 위한 Lambda와 DynamoDB를 사용한 Flow Graph입니다.

더 자세한 추가 정보는 Lumberyard User Guide Cloud Canvas 문서를 확인하십시오.

Amazon GameLift 기반 배포
만약 제작 게임이 높은 확장성 및 클라우드 기반의 런타임 환경이 필요하다면 Amazon GameLift를 사용하시길 권해 드립니다.

개인 슈팅 게임, 서바이벌 레이스, 스포츠, MOBA(멀티 플레이 배틀 아레나) 등 사용자 간 공유 연결, 정기적 동기화 등이 필요한 다양한 종류의 게임을 서비스할 수 있습니다.

서버 측 로직를 빌드한 후에 Amazon GameLift에 업로드하면 Windows 기반 AMI (Amazon Machine Image)으로 몇 분만에 변환됩니다. AMI가 준비 있다면, Amazon GameLift 그룹을 만들고, AMI로 설정하면 백엔드 준비가 완료됩니다.

실행 중인 게임 세션은 Amazon GameLift 콘솔에서 볼 수 있습니다.

Flow Graph 코드는 Amazon GameLift Gem을 만들 수 세션 생성 및 서비스 개시를 제어 할 수 있습니다.

자세한 내용은 Amazon GameLift 문서를 참조하십시오.

Twitch 통합하기
개발한 게임에 Twitch ChatPlay과 Twitch JoinIn이라는 기능을 연계 할 수 있습니다.

아마존 플랫폼 기반으로 게임을 만들면, 지정된 Twitch 채널에 입력된 키워드를 처리 할 수​​ 있습니다. 예를 들어, 키워드로 빨강, 노랑, 파랑, 녹색, 오렌지와 보라색을 처리하는 경우는 아래와 같이 됩니다.

가격 및 서비스 지역
Lumberyard과 Amazon GameLift 오늘 부터 사용할 수 있습니다. 바로 여러분의 게임을 손쉽게 만들어 보세요.

무료로 제공되는 Lumberyard를 기반으로 독립 실행형 게임을 만들 수 있으며, Cloud Canvas에서 설정된 IAM 사용자를 사용해 AWS 서비스를 호출하거나 AWS SDK for C++를 사용 하는데만 비용이 소요됩니다. (GameLift를 사용하는 경우도 마찬가지입니다.)

Amazon GameLift는 US East (Northern Virginia) 및 US West (Oregon) 리전에서 현재 사용할 수 있습니다. 고객의 피드백에 따라 다른 리전에도 계속 확대할 예정입니다. 무료 이용 범위는 c3.large 인스턴스에서 최대 월간 125시간 (최장 1 년)까지 이용하실 수 있습니다. 그 이후에는 사용 EC2 인스턴스의 정상 가격이 적용됩니다. 인스턴스 당 EBS 스토리지는 1 개월 당 50GB의 비용이 1,000 데일리 액티브 유저 당 1개월에 USD 1.5입니다.

Jeff;

이 글은 Lumberyard + Amazon GameLift + Twitch for Games on AWS의 한국어 번역입니다.