如何为多人交易卡牌游戏添加匹配机制

关键洞察

关键洞察

关键洞察

Edgegap 的 匹配系统 是一个完全托管、无限定制的匹配系统,能够最佳地将全球玩家分组——并且在您开发 TCG 游戏期间使用是免费的。

这也是我们所知的 唯一 一个具有 基于延迟的匹配规则 的匹配系统,可以为您的游戏提供理想的在线多人游戏体验,无论引擎(Unity、Unreal 等)或游戏服务(EOS、UGS、PlayFab、Heroic Labs Nakama、Braincloud 等)如何。

由于我们的匹配系统是基于参数的,因此无需编写代码。因此集成非常简单,如果需要,我们的 入门指南 会在每一步为您提供帮助。

当您的游戏上线时,由于我们的匹配系统是完全托管的,您无需处理基础设施、错误、停机、可扩展性或数据库管理。我们为您处理这一切。将您的 DevOps 工作负载减少到几乎为零。

如何将匹配系统集成到你的多人交易卡牌游戏(TCG)中

-> 本文基于 匹配系统文档。如果你遇到问题或差异,请确保参考 原始指南,因为它们更新的频率更高。

以下示例将帮助你测试核心 匹配系统玩家流程,即:

  • 在共享 托管集群上创建匹配系统实例,

  • 在你的匹配系统 配置中定义规则和设置,

  • 最后,测试玩家流程并通过我们的 API管理 玩家票据

将我们的匹配系统实现到你的游戏中有 五个步骤

  1. 第一步是 创建一个账户并使用我们的 TCG 游戏示例。 ,你(技术上)已经完成了一半!你只需要在你的游戏中集成匹配系统(见第 5 步)。

  2. 现在,你绝对不应该盲目遵循你在网上找到的 JSON 示例,因此强烈建议将上述规则调整为适合你的游戏。第二步(“探索配置”)是我们的“阅读指南”,介绍每个 匹配系统规则功能的作用(“探索配置”)。

  3. 第三步(“审查实例详情”)涵盖了你的个人特定 匹配系统,以确保它被部署并与游戏设计兼容。

  4. 第四步,顾名思义(“4. 测试票据 API”),完全是关于测试来自玩家的匹配请求是否被匹配系统接收,称为 票据

  5. 第五步(“将匹配系统集成到你的游戏中”)强调如何将匹配系统集成到你的引擎项目中。

如果你遇到故障排除挑战,我们深入的 学习中心 提供额外的故障排除提示。

1. 设置免费套餐

注册你的免费 Edgegap 账户,并导航到 匹配系统仪表板页面

从那里,首先点击 创建匹配系统 ,然后输入:

  • 匹配系统名称 - 仅供你参考,例如 quickstart-dev

  • 然后,上传以下简单示例作为你的 TCG 游戏的 JSON 配置:

{
  "version": "1.0.0",
  "max_deployment_retry_count": 3,
  "ticket_expiration_period": "5m",
  "ticket_removal_period": "1m",
  "profiles": {
    "casual-example": {
      "application": {
        "name": "my-game-server=>CHANGE-THIS-NAME-HERE",
        "version": "2024.01.30-16.23.00-UTC=>CHANGE-THIS-HERE "
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 1
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "10": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "30": {
            "beacons": {
              "difference": 50
            }
          },
          "60": {
            "league_rank": {
              "max_difference": 2
            }
          },
          "180": {
            "beacons": {
              "difference": 100,
              "max_latency": 500
            }
          }
        }
      }
    },
    "competitive-example": {
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 0
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "60": {
            "beacons": {
              "difference": 50
            }
          },
          "180": {
            "beacons": {
              "max_latency": 250
            }
          }
        }
      }
    },
    "challenger-example": {
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 0
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "180": {
            "beacons": {
              "difference": 50
            }
          },
          "240": {
            "beacons": {
              "max_latency": 250
            }
          }
        }
      }
    }
  }
}

(请注意确保更改应用程序 名称 和 版本 以匹配你的 应用程序和版本!)

如果没有出现验证错误,点击 创建并开始 ,等待过程完成。这将导致一个新的免费集群启动,与你的简单示例匹配系统。

你现在可以继续到下一步。

2. 探索配置

独特的 TCG 游戏规则

专门针对 TCG 游戏,你可以定义多个 匹配配置文件 用于游戏模式的特定规则和设置:

  • 在两个玩家之间限制排名差异以适用于更休闲的游戏,

  • 限制排名差异,只允许同等级对手参加排位赛,

  • 让玩家提供他们的地图偏好并选择适合所有人的地图,

  • 添加 中心选择 UI 以限制对手到指定的 延迟信标

  • 将 匹配延迟 限制在最大阈值内,以防止远距离玩家匹配,

  • 限制 匹配延迟 的最大差异,以最大化延迟公平性,

  • 当允许更多玩家加入时,分配更多 CPU 或内存,使用不同的 应用程序版本 ,

  • 以小组形式加入 ,用于预先创建的大厅或填补团队而不超过团队规模。

从理想条件开始,并且 扩展限制 以确保快速匹配:

  • 随着时间的推移,逐步放宽延迟限制,以便找到更多玩家,

  • 逐步增加允许的排名差异,以便找到更多玩家,

  • 在扩展最高等级(挑战者)之间增加时间,因为可用的玩家更少。

为推广比赛创建排名更高的票据,以与更强的对手匹配。

定义 单独的作弊者简介 以确保被标记的作弊者或被大量管理报告的玩家不会对排位赛中的合法玩家的体验产生负面影响。

语义版本控制

每个新版本使用 语义版本控制 清楚地传达变更的影响,通过解释格式 major.minor.patch

  • major 版本包括重大变更,需要集成审查,

  • minor 版本包括重大向后兼容的改进,

  • patch 版本包括错误修复和小的改进。

一些 部署可能会导致错误。我们尝试通过自动重试部署 up to max_deployment_retry_count 次来解决此问题(无需客户确认)。

为了确保意外的客户端崩溃或被放弃的票据不会停留并占用你的匹配系统资源,票据将在 ticket_expiration_period 后被取消,其状态将变为 已取消 ,并在 ticket_removal_period 后被永久删除。

我们的匹配逻辑核心在 匹配配置文件中进行配置。每个配置文件都是一个完全独立的匹配排队,指向需要预定义数量的 CPU 和内存(RAM)资源的 应用程序版本

匹配规则 在初始规则集中必须满足,以便将玩家分组在一起,每个规则由三个属性定义:

  • 你选择的名称,例如 - 匹配规模

  • 规则类型,也称为操作员,例如 - 玩家人数

  • 最后是操作员属性,例如 团队人数 或 团队规模

玩家人数规则

这是一个特殊规则,定义了需要多少玩家匹配以启动分配:

  • 团队人数 指的是团队数量,1 支队伍可以用于合作或自由对战模式,

  • 团队规模 指的是每个团队的 玩家人数。

我们的简单示例演示了一个包含 2 名玩家的合作游戏。

请注意,“玩家计数”规则 是必需的,并且在初始配置规则中可能仅定义一次

延迟规则

使用此规则为所有玩家提供最低的延迟。一旦客户端测量并提交其往返时间(延迟)与所有可用信标进行比较,Gen2 将只考虑在特定的 差异 延迟值内的匹配,按 延迟信标测量。这提供了一个“软”方案来拆分你的玩家基础,允许与邻近地区进行匹配,尤其是改善了人口较少地区的匹配速度。使用 max_latency以防止与远离的玩家匹配。

你现在可以继续到下一步。

我们之前的示例 信标 规则如下,初始设置为 "差异": 50, "max_latency": 200

  • Alice 和 Bob 将匹配,因为北京被抛弃(>200),其余在 | A-B | < 50:

    • Alice {蒙特利尔: 12.3, 纽瓦克: 45.6, 达拉斯: 59.9, 北京: 264.4}; 和

    • Bob {蒙特利尔: 27.3, 纽瓦克: 32.4, 达拉斯: 23.1, 北京: 252.2}。

  • Charlie 和 Dave 不会匹配,因为 | C-D | > 50 对达拉斯信标:

    • Alice {蒙特利尔: 5.7 纽瓦克: 44.2, 达拉斯: 59.5, 北京: 263.2}; 和

    • Bob {蒙特利尔: 57.8, 纽瓦克: 32.0, 达拉斯: 24.2, 北京: 272.3}。

请注意“延迟规则”在初始配置规则中只能定义一次

3. 审查实例详情

在我们的仪表板中审查你的新匹配系统的详情,一旦它初始化:

状态 表示服务健康,可能是在线、离线或错误。

  • 标识符 可以帮助 Edgegap 员工快速找到你的匹配系统,以便在需要帮助时进行故障排除。

  • 开始于 可以用于追踪最近的更新时刻。

  • 规模 对应于我们的 定价等级

  • API URL 将由游戏客户端和游戏服务器用于与 Gen2 进行通信。

  • Swagger URL 是一个我们提供的方便的 openAPI 规范 GUI,以探索 API 结构。

  • 身份验证令牌 是一个由游戏客户端和游戏服务器用于身份验证的独特秘密令牌。

要使用 API 测试你的新匹配系统, 你将需要 Swagger URL、API URL 和身份验证令牌

你现在可以继续到下一步。

4. 测试票据 API

首先, 打开你的 Swagger URL 以检测你的 openAPI 结构在 swagger GUI 中

点击“匹配系统”标题下方的 /...swagger.json URL 以打开原始 JSON 结构:

将此页面保存为文件到你的硬盘(CTRL/CMD+S)。

打开你的 Postman 应用 并登录到你的免费账户。

从上一步导入你的 swagger.json 文件:

  • 保持选中 Postman 集合 ,

  • 选择 查看导入设置 并更改设置 参数生成 为 示例

确认导入,这将导致在左侧的集合列表中出现一个新集合,标题为“匹配系统”。

查看更多操作,打开 授权 选项卡并选择:

  • 权限类型 - API 密钥

  • 密钥 - “授权

  • 值 - 在这里插入你的 身份验证令牌 值,

  • 添加到 - 头部

按一下(CTRL/CMD+S)或保存图标以 保存更改。你 Postman 选项卡中的橙色点应消失。

在你的匹配系统集合中,选择 票据 并 创建一个匹配票据,打开一个新选项卡。

选择选项卡 主体 以预览你的 玩家票据请求

注意 player_ip 设置为 null- 这将导致自动使用添加到你的请求中的 IP 地址(有关替代方案,请参见 服务器到服务器集成),

  • profile 指的是你的 匹配配置文件

  • attributes 包括你的匹配系统规则的值,在这种情况下是 延迟 规则,

    • 规则 player_count 是唯一不需要任何玩家票据中属性的规则。

注意: 请确保参考示例的 Swagger 的导入配置

点击 发送 并审查你玩家票据请求的响应:

  • id 是你的唯一匹配票据 ID,请保留此信息以便后续检查你的票据,

  • profile 确认所选择的 匹配配置文件

  • group_id 是分配给每个票据的唯一组 ID,单个玩家被表示为 1 的组,

  • player_ip 是玩家的解析公共 IP 地址,无论使用何种识别方法,

  • assignment 设置为 null 以表示该票据尚未匹配或分配给服务器,

  • created_at 提供有关玩家票据创建的时间信息,以供游戏 UI 使用,

  • status 指示票据的当前状态,所有票据均从 SEARCHING 开始(有关详细信息,请参见 匹配过程)。

通过再次点击 发送 创建第二张票据,以便我们的两名玩家匹配并启动一台服务器。

在你的匹配系统集合中,选择 {ticketId} 并 读取一个匹配票据

在上一步的响应中输入票据 ID 并单击 发送

审查你的玩家票据的更新分配:

  • 状态首先变为 MATCH_FOUND ,同时保持 assignment 设置为 null 以表明玩家已经匹配并正在分配服务器,

再次点击 发送 以检查你的票据,审查你的玩家票据的更新分配:

  • 状态变为 HOST_ASSIGNED ,而 assignment 包含被分配服务器的详细信息。

 在我们的仪表板中检查你新的部署

  • 注意每个部署都标记了所有票据 ID 和配置文件,以便于追踪。

尝试从你的游戏客户端连接到分配的服务器。

一旦你验证能够无问题连接到你的部署并完成测试, 停止你的部署 以释放你账户中的容量,以备下一个构建。

你现在可以继续到下一步。

5. 在你的游戏中集成匹配系统

Edgegap 的匹配系统集成:

  • 与 游戏客户端集成,以管理 玩家票据

  • 与 游戏服务器集成,以:

    • 处理通过其票据传递的玩家偏好,

    • 可选地支持 填充 以便在启动后添加或替换玩家。

对于 游戏客户端,我们建议在 匹配过程 中,通过游戏内 UI 向玩家提供票据状态更新,以获得最佳的玩家体验。请参见:

在 游戏客户端中,确保处理不可重试的错误:

  • HTTP 404 Not Found - 票据已被删除,

  • HTTP 500 Internal Server Error - 临时服务中断。

在 游戏服务器中,处理玩家偏好和初始服务器上下文。无需进行 API 集成:

  1. 读取 注入环境变量 (Gen2) 以获取初始玩家的匹配数据。

  2. 读取 注入环境变量 (应用程序版本) 以获取版本特定参数、设置(玩家容量)和机密信息。

  3. 读取 注入环境变量 (部署) 以获取有关部署的信息,如 IP 地址、位置等。

一旦玩家连接, 游戏服务器和游戏客户端 开始加载场景以执行同步步骤(例如选择和加载地图/场景/关卡)。我们建议一个完整的 3D 场景、一个社交 UI 大厅或一个带进度条的加载屏幕,以提示初始化正在进行。

一旦 游戏客户端 完全加载,玩家将加载/前往主游戏场景。

可选地, 游戏服务器 可以创建并管理 填充 和玩家容量(添加或替换离开的玩家)。

确保你的 部署将被正确停止 ,使用 注入 DELETE_URL,如果:

  • 没有玩家加入比赛,

  • 所有玩家已离开比赛,

  • 比赛正确结束。

恭喜你,已完成 Edgegap 匹配系统集成!如果你想了解更多内容,请在我们的 学习中心 阅读所有相关资料。

书写者

Edgegap团队