Update the GameLift gem CDK application for supporting FlexMatch (#4335)

Signed-off-by: Junbo Liang <junbo@amazon.com>
This commit is contained in:
Junbo Liang
2021-10-05 11:03:53 -07:00
committed by GitHub
parent 256564a3e0
commit 430b5682b7
7 changed files with 162 additions and 37 deletions
@@ -52,6 +52,7 @@ class AWSGameLift(core.Construct):
stack_name=stack_name,
fleet_configurations=fleet_configurations,
create_game_session_queue=self.node.try_get_context('create_game_session_queue') == 'true',
flex_match=self.node.try_get_context('flex_match') == 'true',
description=f'Contains resources for the AWS GameLift Gem stack as part of the {project_name} project',
tags=tags,
env=env
@@ -0,0 +1,6 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
@@ -0,0 +1,30 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# Matchmaking rule formatted as a JSON string.
# Comments are not allowed in JSON, but most elements support a description field.
# For instructions on designing Matchmaking rule sets, please check:
# https://docs.aws.amazon.com/gamelift/latest/flexmatchguide/match-design-ruleset.html
RULE_SET_BODY = '{"ruleLanguageVersion":"1.0","teams":[{"name":"Players","maxPlayers":4,"minPlayers":2}]}'
# A flag that determines whether a match that was created with this configuration
# must be accepted by the matched players.
ACCEPTANCE_REQUIRED = False
# The maximum duration, in seconds, that a matchmaking ticket can remain in process before timing out.
# Requests that fail due to timing out can be resubmitted as needed.
REQUEST_TIMEOUT_SECONDS = 300
# The number of player slots in a match to keep open for future players.
# This parameter is not used if FlexMatchMode is set to STANDALONE.
ADDITIONAL_PLAYER_COUNT = 2
# The method used to backfill game sessions that are created with this matchmaking configuration.
# Specify MANUAL when your game manages backfill requests manually or does not use the match backfill feature.
# Specify AUTOMATIC to have GameLift create a StartMatchBackfill request whenever a game session has one or more
# open slots.
BACKFILL_MODE = 'AUTOMATIC'
@@ -0,0 +1,60 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import typing
from aws_cdk import (
core,
aws_gamelift as gamelift
)
from . import flexmatch_configurations
FLEX_MATCH_MODE = 'WITH_QUEUE'
class MatchmakingResoures:
"""
Create a matchmaking rule set and matchmaking configuration for Gamelift FlexMatch.
For more information about Gamelift FlexMatch, please check
https://docs.aws.amazon.com/gamelift/latest/flexmatchguide/match-intro.html
"""
def __init__(self, stack: core.Stack, game_session_queue_arns: typing.List[str]):
rule_set = gamelift.CfnMatchmakingRuleSet(
scope=stack,
id='MatchmakingRuleSet',
name=f'{stack.stack_name}-MatchmakingRuleSet',
rule_set_body=flexmatch_configurations.RULE_SET_BODY
)
matchmaking_configuration = gamelift.CfnMatchmakingConfiguration(
scope=stack,
id='MatchmakingConfiguration',
acceptance_required=flexmatch_configurations.ACCEPTANCE_REQUIRED,
name=f'{stack.stack_name}-MatchmakingConfiguration',
request_timeout_seconds=flexmatch_configurations.REQUEST_TIMEOUT_SECONDS,
rule_set_name=rule_set.name,
additional_player_count=flexmatch_configurations.ADDITIONAL_PLAYER_COUNT,
backfill_mode=flexmatch_configurations.BACKFILL_MODE,
flex_match_mode=FLEX_MATCH_MODE,
game_session_queue_arns=game_session_queue_arns if len(game_session_queue_arns) else None
)
matchmaking_configuration.node.add_dependency(rule_set)
# Export the matchmaking rule set and configuration names as stack outputs
core.CfnOutput(
stack,
id='MatchmakingRuleSetName',
description='Name of the matchmaking rule set',
export_name=f'{stack.stack_name}:MatchmakingRuleSet',
value=rule_set.name)
core.CfnOutput(
stack,
id='MatchmakingConfigurationName',
description='Name of the matchmaking configuration',
export_name=f'{stack.stack_name}:MatchmakingConfiguration',
value=matchmaking_configuration.name)
@@ -0,0 +1,6 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
@@ -0,0 +1,43 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import typing
from aws_cdk import (
core,
aws_gamelift as gamelift
)
class GameSessionQueueResources:
"""
Create a game session queue which fulfills game session placement requests using the fleets.
For more information about Gamelift game session queues, please check
https://docs.aws.amazon.com/gamelift/latest/developerguide/queues-intro.html
"""
def __init__(self, stack: core.Stack, destinations: typing.List):
self._game_session_queue = gamelift.CfnGameSessionQueue(
scope=stack,
id=f'{stack.stack_name}-GameLiftQueue',
name=f'{stack.stack_name}-GameLiftQueue',
destinations=[
gamelift.CfnGameSessionQueue.DestinationProperty(
destination_arn=resource_arn
) for resource_arn in destinations
]
)
# Export the game session queue name as a stack output
core.CfnOutput(
scope=stack,
id='GameSessionQueue',
description='Name of the game session queue',
export_name=f'{stack.stack_name}:GameSessionQueue',
value=self._game_session_queue.name)
@property
def game_session_queue_arn(self) -> str:
return self._game_session_queue.attr_arn
@@ -5,10 +5,13 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import typing
from aws_cdk import (
core,
aws_gamelift as gamelift
)
from aws_cdk import core
from aws_cdk import aws_gamelift as gamelift
from .flexmatch import matchmaking
from .game_session_queue import game_session_queue
class GameLiftStack(core.Stack):
@@ -19,7 +22,9 @@ class GameLiftStack(core.Stack):
"""
def __init__(self, scope: core.Construct, id_: str,
stack_name: str, fleet_configurations: dict,
create_game_session_queue: bool, **kwargs) -> None:
create_game_session_queue: bool,
flex_match: bool,
**kwargs) -> None:
super().__init__(scope, id_, **kwargs)
self._stack_name = stack_name
@@ -50,7 +55,7 @@ class GameLiftStack(core.Stack):
queue_destinations.append(destination_arn)
# Export the GameLift fleet ids as a stack output
fleets_output = core.CfnOutput(
core.CfnOutput(
self,
id='GameLiftFleets',
description='List of GameLift fleet ids',
@@ -58,17 +63,13 @@ class GameLiftStack(core.Stack):
value=','.join(fleet_ids)
)
if create_game_session_queue:
# Create a game session queue which fulfills game session placement requests using the fleets
game_session_queue = self._create_game_session_queue(queue_destinations)
game_session_queue_arns = []
if flex_match or create_game_session_queue:
queue = game_session_queue.GameSessionQueueResources(self, queue_destinations)
game_session_queue_arns.append(queue.game_session_queue_arn)
# Export the game session queue name as a stack output
game_session_queue_output = core.CfnOutput(
self,
id='GameSessionQueue',
description='Name of the game session queue',
export_name=f'{self._stack_name}:GameSessionQueue',
value=game_session_queue.name)
if flex_match:
matchmaking.MatchmakingResoures(self, game_session_queue_arns)
def _create_fleet(self, fleet_configuration: dict, identifier: int) -> gamelift.CfnFleet:
"""
@@ -155,25 +156,3 @@ class GameLiftStack(core.Stack):
)
return alias
def _create_game_session_queue(self, destinations: typing.List) -> gamelift.CfnGameSessionQueue:
"""
Create a placement queue that processes requests for new game sessions.
:param destinations: Destinations of the queue.
:return: Generated GameLift game session queue.
"""
game_session_queue = gamelift.CfnGameSessionQueue(
self,
id=f'{self._stack_name}-GameLiftQueue',
name=f'{self._stack_name}-game-session-queue',
destinations=[
gamelift.CfnGameSessionQueue.DestinationProperty(
destination_arn=resource_arn
) for resource_arn in destinations
]
)
return game_session_queue