将 FlexMatch 添加到游戏客户端 - Amazon GameLift
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 FlexMatch 添加到游戏客户端

本主题介绍如何向游戏客户端添加 FlexMatch 对战支持。FlexMatch 可与适用于自定义游戏服务器和 实时服务器 的托管 GameLift 解决方案一起使用。

要了解有关 FlexMatch 以及如何为游戏设置自定义对战构建器的更多信息,请参阅以下主题:

要在游戏客户端上启用 FlexMatch,您需要准备您的游戏客户端项目,然后添加以下功能:

  • 请求一个或多个玩家的对战。

  • 跟踪对战请求的状态.

  • 要求玩家接受建议的对战游戏.

  • 在为新的对战创建游戏会话之后,获取玩家连接信息并加入游戏。

准备客户端服务以进行对战

我们强烈建议您的游戏客户端通过客户端游戏服务而不是直接发起对战请求。通过使用可信源,您可以更轻松地防范黑客攻击和虚假玩家数据。如果您的游戏具有会话目录服务,那么这是一个用于处理对战请求的好选项。

要准备您的客户端服务,请执行以下任务:

  • 添加 GameLift API。 您的客户端服务使用 GameLift API 中的功能,它是 AWS SDK 的一部分。请参阅 对于客户服务,了解有关 AWS SDK 的更多信息并下载最新版本。将此 SDK 添加到您的客户端服务项目。

  • 设置对战票证系统。 必须向所有对战请求分配一个唯一票证 ID。您需要一个生成唯一 IDs 并将其分配给新对战请求的机制。票证 ID 可以使用任意字符串格式,最多 128 个字符。

  • 获取对战构建器信息。 获取您计划要使用的对战配置的名称。您还需要对战构建器的必需玩家属性列表,这在对战构建器规则集中定义。

  • 获取玩家数据。 设置获取各个玩家相关数据的方法。这包括玩家 ID、玩家属性值,以及玩家可能接入游戏的各个区域的更新延迟数据。

  • (可选)启用对战回填。 确定您想要如何回填现有的匹配游戏。如果您的对战构建器将回填模式设置为“手动”,您可能需要为您的游戏添加回填支持。如果回填模式设置为“自动”,您可能需要一种为单个游戏会话关闭此模式的方法。在 使用 FlexMatch 回填现有游戏 中了解有关管理对战回填的更多信息。

请求玩家对战

将代码添加到您的客户端服务来创建和管理 FlexMatch 对战构建器的对战请求。

创建对战请求:

  • 调用 GameLift API StartMatchmaking。 每个请求都必须包含以下信息。

    对战构建器

    要用于请求的对战配置的名称。FlexMatch 将各个请求放置到指定对战构建器的池中,并将根据对战构建器的配置方式来处理请求。这包括强制施加时间限制,是否请求玩家接受匹配,在放置生成的游戏会话时使用哪个队列,等等。在 设计 FlexMatch 对战构建器 中了解有关对战构建器和规则集的更多信息。

    票证 ID

    分配给请求的唯一票证 ID。与请求相关的所有信息(包括事件和通知)都将引用票证 ID。

    玩家数据

    您要为其创建对战的玩家的列表。如果根据对战规则和延迟最低值,请求中的任意玩家不满足对战要求,则对战请求绝不会生成成功的对战。您可在一个对战请求中包括最多十位玩家。当一个请求中有多个玩家时,FlexMatch 尝试创建单个对战并将所有玩家分配到相同团队中(随机选择)。如果请求包含的玩家数太多,无法放在一个对战团队中,则对战请求失败。例如,如果您设置了对战构建器,以创建 2 对 2 对战(两个团队,每个团队两个玩家),您无法发送包含两个以上玩家的对战请求。

    注意

    一个玩家 (通过其玩家 ID 标识) 一次只能包括在一个有效对战请求中。在您为玩家创建新请求时,将自动取消任何具有相同玩家 ID 的有效对战票证。

    对于每个列出的玩家,请提供以下数据:

    • 玩家 ID – 每个玩家必须具有一个唯一的玩家 ID,该 ID 由您生成。请参阅生成玩家 ID

    • 玩家属性 – 如果所使用的对战构建器需要玩家属性,请求必须为每个玩家提供这些属性。必需的玩家属性在对战构建器的规则集中定义,同时还会指定属性的数据类型。玩家属性仅在规则集指定属性的默认值时是可选的。如果对战请求未提供所有玩家的必需玩家属性,对战请求可能永远无法成功。在构建 FlexMatch 规则集FlexMatch 规则集示例中了解有关对战构建器规则集和玩家属性的更多信息。

    • 玩家延迟 – 如果所使用的对战构建器有玩家延迟规则,请求必须报告每个玩家的延迟。玩家延迟数据是显示每个玩家的一个或多个值的列表。它表示对战构建器的队列中各个区域的玩家体验的延迟。如果请求中未包含延迟值,玩家将无法匹配,请求将失败。

检索对战请求详细信息:

  • 发送对战请求后,您可以通过调用包含请求票证 ID 的 DescribeMatchmaking 查看请求详细信息。此调用将返回请求信息,包括当前状态。成功完成请求之后,票证还将包含游戏客户端连接到对战所需的信息。

取消对战请求:

  • 您可以随时取消对战请求,方法是使用请求的票证 ID 调用 StopMatchmaking

跟踪对战请求状态

将代码添加到客户端服务以跟踪所有对战请求的状态。跟踪状态有两种方法:事件通知和连续轮询。

在使用大量对战场景之前,您应该使用事件通知设置游戏,例如进行预生产负载测试。公开发布版中的所有游戏都应该使用通知,而不考虑容量。连续轮询方法仅适用于对战使用率较低的开发中的游戏。

事件通知

设置通知,以跟踪 GameLift 为对战过程发出的事件。您可以直接设置通知,也可以通过创建 SNS 主题或使用 Amazon EventBridge 来设置通知。有关设置通知的更多信息,请参阅设置 FlexMatch 事件通知。设置通知之后,请在客户端服务上添加侦听器以检测事件并根据需要做出响应。

在经过相当长一段时间而未通知的情况下,最好定期轮询状态更新来作为通知的备用手段。为了最大限度地减少对对战性能的影响,请务必在提交对战票证后或最后一次收到通知后,等待至少 30 秒后再轮询。

连续轮询

通过调用包含请求票证 ID 的 DescribeMatchmaking 来检索对战请求票证,包括当前状态。我们建议轮询频率不要超过每 10 秒一次。此方法仅在低容量开发场景中使用。

请求玩家接受

如果您使用的是开启了玩家接受的对战构建器,请将代码添加到您的客户端服务来管理玩家接受过程。

要求玩家接受建议的对战游戏:

  1. 检测建议的对战游戏何时需要玩家接受。 监控对战票证以检测状态更改为 REQUIRES_ACCEPTANCE 的时间。 如果您正在监控通知,则此状态的更改将触发 FlexMatch 事件 MatchmakingRequiresAcceptance

  2. 从所有玩家获取接受信息。 创建一个机制,以在对战票证中向每个玩家呈现建议的对战游戏详细信息。玩家必须能够表明他们接受或拒绝建议的对战游戏。您可以通过调用 DescribeMatchmaking 来检索对战游戏详细信息。 在对战构建器撤消建议的对战游戏之前,玩家的响应时间有限。

  3. 向 FlexMatch 报告玩家响应。 通过调用接受或拒绝的 AcceptMatch 来报告玩家响应。对战请求中的所有玩家必须接受对战游戏才能继续。

  4. 处理具有失败接受的票证。 当建议的对战游戏中的任何一个玩家拒绝对战游戏,或者未能在接受时限内响应时,请求失败。

连接到对战游戏

将代码添加到您的客户端服务以处理已成功完成的对战(状态 COMPLETED 或事件 MatchmakingSucceeded)。这包括向游戏客户端通知对战游戏的玩家和传递连接信息。

对战请求完成后,连接信息将会添加到对战票证。通过调用 DescribeMatchmaking 检索已完成的对战票证。 连接信息包括游戏会话的 IP 地址和端口,以及每个玩家 ID 的玩家会话 ID。在 GameSessionConnectionInfo 中了解更多信息。

您的游戏客户端将使用此信息直接连接到托管对战的游戏会话。已对战的游戏会话的连接请求应该包含玩家会话 ID 和玩家 ID。此数据将连接的玩家与游戏会话的对战数据相关联,其中包括团队分配 (请参阅 GameSession)。

示例对战请求

以下代码段为多个不同的对战构建器构建对战请求。如文中所述,请求必须提供所使用的对战构建器需要的玩家属性(在对战构建器的规则集中定义)。提供的属性必须使用在规则集中定义的相同的数据类型:数字 (N) 或字符串 (S)。

# Uses matchmaker for two-team game mode based on player skill level def start_matchmaking_for_cowboys_vs_aliens(config_name, ticket_id, player_id, skill, team): response = gamelift.start_matchmaking( ConfigurationName=config_name, Players=[{ "PlayerAttributes": { "skill": {"N": skill} }, "PlayerId": player_id, "Team": team }], TicketId=ticket_id) # Uses matchmaker for monster hunter game mode based on player skill level def start_matchmaking_for_players_vs_monster(config_name, ticket_id, player_id, skill, is_monster): response = gamelift.start_matchmaking( ConfigurationName=config_name, Players=[{ "PlayerAttributes": { "skill": {"N": skill}, "desiredSkillOfMonster": {"N": skill}, "wantsToBeMonster": {"N": int(is_monster)} }, "PlayerId": player_id }], TicketId=ticket_id) # Uses matchmaker for brawler game mode with latency def start_matchmaking_for_three_team_brawler(config_name, ticket_id, player_id, skill, role): response = gamelift.start_matchmaking( ConfigurationName=config_name, Players=[{ "PlayerAttributes": { "skill": {"N": skill}, "character": {"S": [role]}, }, "PlayerId": player_id, "LatencyInMs": { "us-west-2": 20} }], TicketId=ticket_id) # Uses matchmaker for multiple game modes and maps based on player experience def start_matchmaking_for_multi_map(config_name, ticket_id, player_id, skill, maps, modes): response = gamelift.start_matchmaking( ConfigurationName=config_name, Players=[{ "PlayerAttributes": { "experience": {"N": skill}, "gameMode": {"SL": modes}, "mapPreference": {"SL": maps} }, "PlayerId": player_id }], TicketId=ticket_id)